22import time
33import 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-
335class 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)
0 commit comments