Skip to content

Commit 79b6c9b

Browse files
committed
finish fieldline mock api
1 parent 83fc668 commit 79b6c9b

File tree

3 files changed

+177
-133
lines changed

3 files changed

+177
-133
lines changed

resources/mne_scan/plugins/fieldline/fieldline_api_mock/fieldline_service.py

+169-106
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,40 @@
22
import time
33
import random
44

5-
6-
def generate_data():
7-
timestamp = 179331926
8-
num_sensors_per_chassis = 16
9-
num_chassis = 2
10-
11-
data_frames = {}
12-
13-
data_values = [91599] + \
14-
[round(random.normalvariate(0, 1000))
15-
for _ in range(1, num_sensors_per_chassis * num_chassis + 1)]
16-
17-
chassis_labels = [0] + [num for num in range(0, num_chassis) for _ in range(num_sensors_per_chassis)]
18-
sensor_labels = [0] + (list(range(1, num_sensors_per_chassis + 1))) * num_chassis
19-
data_type_labels = [0] + ([50] * num_sensors_per_chassis * num_chassis)
20-
global_labels = [f'{chassis_label:02}:{sensor_label:02}:{data_type:02}'
21-
for chassis_label, sensor_label, data_type in zip(chassis_labels, sensor_labels, data_type_labels)]
22-
23-
for global_l, data_i, sensor_l, chassis_l, data_type_l in \
24-
zip(global_labels, data_values, sensor_labels, chassis_labels, data_type_labels):
25-
data_frames[global_l] = \
26-
{'data': data_i, 'sensor': f'{chassis_l:02}:{sensor_l:02}', 'sensor_id': sensor_l, 'data_type': data_type_l}
27-
28-
29-
# data_frames = []
30-
return {'timestamp': timestamp, 'data_frames': data_frames}
31-
32-
335
class FieldLineService:
6+
class SensorApi:
7+
def __init__(self):
8+
self.sleep_mean = 1
9+
self.sleep_var = .2
10+
self.prob_success = 0.9
11+
3412
def __init__(self, ip_list, prefix=""):
3513
"""
3614
callback - required callback class
3715
should be of type FieldLineCallback
3816
"""
39-
self.counter_lock = 0
40-
self.hardware_state = 0
4117
print("Initializing FieldLine Service")
42-
self.prefix = "prefix"
43-
self.data_source = None
44-
# interfaces = netifaces.interfaces()
45-
self.network_interfaces = []
18+
self.is_open = False
19+
20+
self.num_sensors_per_chassis = 16
21+
self.num_chassis = 2
22+
4623
self.ip_list = ip_list
24+
self.num_chassis = len(self.ip_list)
25+
# print("IP list: " + str(self.ip_list))
26+
27+
self.sensors = {i: list(range(1, self.num_sensors_per_chassis + 1)) for i in range(0, self.num_chassis) }
28+
self.sensor_api = self.SensorApi()
29+
30+
self.data_random_mean = 0
31+
self.data_random_var = 1000
32+
self.sampling_frequency = 1000
33+
self.callback_function = self.callback_function_default
4734
self.continue_data_acquisition = False
48-
self.data_acquisition_thread = None
49-
# for i in interfaces:
50-
# print("interface %s" % i)
51-
# if i.startswith('lo'):
52-
# continue
53-
# iface = netifaces.ifaddresses(i).get(netifaces.AF_INET)
54-
# if iface is not None:
55-
# for j in iface:
56-
# ip_addr = j['addr']
57-
# print("address %s" % ip_addr)
58-
# self.network_interfaces.append(ip_addr)
59-
# print("network interfaces: %s" % self.network_interfaces)
35+
self.data_acquisition_thread = threading.Thread(target=self.data_acquisition)
36+
37+
def callback_function_default(self, _):
38+
pass
6039

6140
def __enter__(self):
6241
self.open()
@@ -66,76 +45,139 @@ def __exit__(self, exc_type, exc_value, traceback):
6645
self.close()
6746

6847
def open(self):
69-
print("connecting to devices in ip_list: " + str(self.ip_list))
70-
print("connecting to devices")
71-
print("start monitor")
72-
print("start data source")
48+
self.is_open = True
49+
print("FieldLineService Open")
50+
print("Connecting to devices in ip_list: " + str(self.ip_list))
7351

7452
def close(self):
75-
print("data source shut down")
53+
self.is_open = False
54+
print("FieldLineService Close.")
55+
print("Disconnecting.")
7656

7757
def load_sensors(self):
78-
print("loading sensors")
79-
# return self.data_source.load_sensors()
80-
self.list_of_sensors = {i: list(range(1, 16 + 1)) for i in range(0, 1 + 1)}
81-
82-
return self.list_of_sensors
58+
if self.is_open:
59+
print("Loading sensors.")
60+
return self.sensors
61+
else:
62+
print("Fieldline service closed.")
8363

8464
def get_chassis_list(self):
85-
print("get chassis list")
86-
# return self.data_source.get_chassis_list()
65+
if self.is_open:
66+
print("Get chassis list")
67+
return list(range(0, len(self.ip_list)))
68+
else:
69+
print("Fieldline service closed.")
70+
return None
71+
72+
def generate_data(self):
73+
timestamp = int(time.time())
74+
75+
data_frames = {}
76+
77+
num_sensors = sum(len(sensor_list) for sensor_list in self.sensors.values())
78+
79+
data_values = [91599] + [round(random.normalvariate(self.data_random_mean, self.data_random_var))
80+
for _ in range(1, num_sensors + 1)]
81+
82+
chassis_labels = [0] + [chassis for chassis, sensors in self.sensors.items() for _ in sensors]
83+
sensor_labels = [0] + [sensor for sensor_list in self.sensors.values() for sensor in sensor_list]
84+
85+
data_type_labels = [0] + ([50] * num_sensors)
86+
global_labels = [f'{chassis_label:02}:{sensor_label:02}:{data_type:02}'
87+
for chassis_label, sensor_label, data_type in zip(chassis_labels, sensor_labels, data_type_labels)]
88+
89+
for global_l, data_i, sensor_l, chassis_l, data_type_l in \
90+
zip(global_labels, data_values, sensor_labels, chassis_labels, data_type_labels):
91+
data_frames[global_l] = \
92+
{'data': data_i, 'sensor': f'{chassis_l:02}:{sensor_l:02}', 'sensor_id': sensor_l, 'data_type': data_type_l}
93+
94+
return {'timestamp': timestamp, 'data_frames': data_frames}
8795

8896
def data_acquisition(self):
89-
97+
sampling_period = 1/self.sampling_frequency
98+
9099
start_time = time.time()
91-
data = generate_data()
100+
data = self.generate_data()
92101
end_time = time.time()
93102
elapsed_time = end_time - start_time
94-
time.sleep(0.001 - elapsed_time)
103+
time.sleep(sampling_period - elapsed_time)
95104
end_time = time.time()
96105

97106
elapsed_time = end_time - start_time
98-
elapsed_time_diff = (0.001 - elapsed_time)
107+
elapsed_time_diff = (sampling_period - elapsed_time)
99108

100109
while(self.continue_data_acquisition):
101110
start_time = time.time()
102-
data = generate_data()
111+
data = self.generate_data()
103112
self.callback_function(data)
104113
end_time = time.time()
105114
elapsed_time = end_time - start_time
106115
# time_to_sleep = max(0, .001 - elapsed_time)
107-
time.sleep(0.001 + elapsed_time_diff - 0.5 * elapsed_time)
116+
time.sleep(sampling_period + elapsed_time_diff - 0.6 * elapsed_time)
108117
# print(f"elapsed_time: {elapsed_time:04}")
118+
# start_time = time.time()
119+
# end_time = time.time()
120+
# time_meas = end_time - start_time
121+
#
122+
# start_time = time.time()
123+
# data = self.generate_data()
124+
# self.callback_function(data)
125+
# time.sleep(sampling_period)
126+
# end_time = time.time()
127+
#
128+
# time_diff = end_time - start_time - sampling_period - time_meas
129+
# time_to_sleep_adjusted = sampling_period - 1.5 * time_diff
130+
# time_to_sleep_final = 0 if time_to_sleep_adjusted < 0 else time_to_sleep_adjusted
131+
# print(time_to_sleep_final)
132+
#
133+
# while(self.continue_data_acquisition):
134+
# data = self.generate_data()
135+
# self.callback_function(data)
136+
# time.sleep(time_to_sleep_final)
109137

110138
def read_data(self, data_callback=None):
111-
if(data_callback is not None):
112-
print(f"read_data defined. Callback set to : {data_callback.__name__}")
113-
self.callback_function = data_callback
114-
# self.data_source.read_data(data_callback=data_callback)
115-
116-
117-
def start_adc(self, chassis_id):
139+
if self.is_open:
140+
if(data_callback is not None):
141+
self.callback_function = data_callback
142+
print(f"Data callback set to: {data_callback.__name__}.")
143+
else:
144+
self.callback_function = self.callback_function_default
145+
print(f'Data callback disabled.')
146+
else:
147+
print("Fieldline service closed.")
148+
return None
149+
150+
def start_adc(self, _):
118151
"""
119152
Start ADC from chassis
120153
121154
chassis_id - unique ID of chassis
122155
"""
123-
print("start adc")
124-
self.continue_data_acquisition = True
125-
self.data_acquisition_thread = threading.Thread(target=self.data_acquisition)
126-
self.data_acquisition_thread.start()
127-
# self.data_source.start_adc(chassis_id)
156+
if self.is_open:
157+
self.continue_data_acquisition = True
158+
self.data_acquisition_thread.start()
159+
print("Starting data acquisition.")
160+
else:
161+
print("Fieldline service closed.")
162+
return None
128163

129164
def stop_adc(self, chassis_id):
130165
"""
131166
Stop ADC from chassis
132167
133168
chassis_id - unique ID of chassis
134169
"""
135-
print("stop adc")
136-
self.continue_data_acquisition = False
137-
self.data_acquisition_thread.join(timeout=5)
138-
# self.data_source.stop_adc(chassis_id)
170+
if self.is_open:
171+
self.continue_data_acquisition = False
172+
if self.data_acquisition_thread.is_alive():
173+
self.data_acquisition_thread.join(timeout=5)
174+
print("Stopping data acquisition.")
175+
else:
176+
print("Data acquisition running.")
177+
else:
178+
print("Fieldline service closed.")
179+
return None
180+
139181

140182
def turn_off_sensors(self, sensor_dict):
141183
"""
@@ -144,8 +186,35 @@ def turn_off_sensors(self, sensor_dict):
144186
145187
sensor_dict - dictionary of chassis id to list of sensors ex. {0: [0,1], 1:[0,1]}
146188
"""
147-
print("turn off sensors")
148-
# self.data_source.send_logic_command(sensor_dict, proto.LogicMessage.LOGIC_SENSOR_OFF)
189+
print("Turning off sensors.")
190+
191+
def sensors_api(self, sensor_dict, on_next=None, on_error=None, on_completed=None):
192+
def sensor_thread(chassis_id: int, sensor_id: int):
193+
sleep_time = random.normalvariate(self.sensor_api.sleep_mean, self.sensor_api.sleep_var)
194+
if sleep_time <= 0:
195+
sleep_time = 0.1
196+
time.sleep(sleep_time)
197+
result = random.random()
198+
if result <= self.sensor_api.prob_success:
199+
if on_next:
200+
on_next(chassis_id, sensor_id)
201+
else:
202+
codes = [117, 31337, 2626]
203+
if on_error:
204+
on_error(chassis_id, sensor_id, random.choice(codes))
205+
206+
threads = []
207+
for chassis_id, sensor_ids in sensor_dict.items():
208+
for sensor_id in sensor_ids:
209+
t = threading.Thread(target=sensor_thread, args=(chassis_id, sensor_id))
210+
t.start()
211+
threads.append(t)
212+
213+
for t in threads:
214+
t.join()
215+
216+
if on_completed:
217+
on_completed()
149218

150219
def restart_sensors(self, sensor_dict, on_next=None, on_error=None, on_completed=None):
151220
"""
@@ -157,11 +226,9 @@ def restart_sensors(self, sensor_dict, on_next=None, on_error=None, on_completed
157226
on_error - callback when sensor fails a step
158227
on_completed - callback when all sensors have either succeeded or failed
159228
"""
160-
print("restart sensors")
161-
time.sleep(.3)
162-
on_completed()
163-
# self.data_source.set_callbacks(on_next=on_next, on_error=on_error, on_completed=on_completed)
164-
# self.data_source.send_logic_command(sensor_dict, proto.LogicMessage.LOGIC_SENSOR_RESTART)
229+
print("Restarting sensors.")
230+
self.sensors_api(sensor_dict, on_next, on_error, on_completed)
231+
165232

166233
def coarse_zero_sensors(self, sensor_dict, on_next=None, on_error=None, on_completed=None):
167234
"""
@@ -174,10 +241,7 @@ def coarse_zero_sensors(self, sensor_dict, on_next=None, on_error=None, on_compl
174241
on_completed - callback when all sensors have either succeeded or failed
175242
"""
176243
print("coarse zero sensor")
177-
time.sleep(.3)
178-
on_completed()
179-
# self.data_source.set_callbacks(on_next=on_next, on_error=on_error, on_completed=on_completed)
180-
# self.data_source.send_logic_command(sensor_dict, proto.LogicMessage.LOGIC_SENSOR_COARSE_ZERO)
244+
self.sensors_api(sensor_dict, on_next, on_error, on_completed)
181245

182246
def fine_zero_sensors(self, sensor_dict, on_next=None, on_error=None, on_completed=None):
183247
"""
@@ -190,21 +254,20 @@ def fine_zero_sensors(self, sensor_dict, on_next=None, on_error=None, on_complet
190254
on_completed - callback when all sensors have either succeeded or failed
191255
"""
192256
print("fine zero sensors")
193-
time.sleep(.3)
194-
on_completed()
195-
# self.data_source.set_callbacks(on_next=on_next, on_error=on_error, on_completed=on_completed)
196-
# self.data_source.send_logic_command(sensor_dict, proto.LogicMessage.LOGIC_SENSOR_FINE_ZERO)
197-
198-
# def set_bz_wave(self, chassis_id, sensor_id, wave_type, freq=None, amplitude=None):
199-
# """
200-
# Apply a known magnetic field to the BZ coil (e.g. sine wave)
201-
#
202-
# chassis_id - unique ID of chassis
203-
# sensor_id - unique ID of sensor
204-
# wave_type - FieldLineWaveType (WAVE_OFF, WAVE_RAMP, WAVE_SINE)
205-
# freq - frequency of wave
206-
# amplitude - amplitude of wave (nT)
207-
# """
257+
self.sensors_api(sensor_dict, on_next, on_error, on_completed)
258+
259+
def set_bz_wave(self, chassis_id, sensor_id, wave_type, freq=None, amplitude=None):
260+
"""
261+
Apply a known magnetic field to the BZ coil (e.g. sine wave)
262+
263+
chassis_id - unique ID of chassis
264+
sensor_id - unique ID of sensor
265+
wave_type - FieldLineWaveType (WAVE_OFF, WAVE_RAMP, WAVE_SINE)
266+
freq - frequency of wave
267+
amplitude - amplitude of wave (nT)
268+
"""
269+
print('Setting bz wave')
270+
print('UuuUUUuuuuu...')
208271
#
209272
# if wave_type == FieldLineWaveType.WAVE_OFF:
210273
# self.data_source.set_wave_off(chassis_id, sensor_id)
+1-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""This is my super module"""
22
import sys
3-
from fieldline_api_mock.fieldline_service import FieldLineService
3+
from fieldline_api_mock.fieldline_service import FieldLineService
44
import time
55

66
for path in sys.path:
@@ -12,17 +12,4 @@
1212

1313
ip_list = ["8.8.8.8", "9.9.9.9"]
1414

15-
# fl = FieldLineService(["8.8.8.8", "9.9.9.9"])
16-
# with FieldLineService(ip_list) as service:
17-
# done = False
18-
# # Get dict of all the sensors
19-
# sensors = service.load_sensors()
20-
# print(f"Got sensors: {sensors}")
21-
# # Make sure closed loop is set
22-
# service.set_closed_loop(True)
23-
# print("Doing sensor restart")
24-
# # Do the restart
25-
# service.restart_sensors(sensors, on_next=lambda c_id, s_id: print(f'sensor {c_id}:{s_id} finished restart'), on_error=lambda c_id, s_id, err: print(f'sensor {c_id}:{s_id} failed with {hex(err)}'), on_completed=lambda: call_done())
26-
# while not done:
27-
# time.sleep(0.5)
2815

0 commit comments

Comments
 (0)