2
2
import time
3
3
import random
4
4
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
-
33
5
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
+
34
12
def __init__ (self , ip_list , prefix = "" ):
35
13
"""
36
14
callback - required callback class
37
15
should be of type FieldLineCallback
38
16
"""
39
- self .counter_lock = 0
40
- self .hardware_state = 0
41
17
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
+
46
23
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
47
34
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
60
39
61
40
def __enter__ (self ):
62
41
self .open ()
@@ -66,76 +45,139 @@ def __exit__(self, exc_type, exc_value, traceback):
66
45
self .close ()
67
46
68
47
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 ))
73
51
74
52
def close (self ):
75
- print ("data source shut down" )
53
+ self .is_open = False
54
+ print ("FieldLineService Close." )
55
+ print ("Disconnecting." )
76
56
77
57
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." )
83
63
84
64
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 }
87
95
88
96
def data_acquisition (self ):
89
-
97
+ sampling_period = 1 / self .sampling_frequency
98
+
90
99
start_time = time .time ()
91
- data = generate_data ()
100
+ data = self . generate_data ()
92
101
end_time = time .time ()
93
102
elapsed_time = end_time - start_time
94
- time .sleep (0.001 - elapsed_time )
103
+ time .sleep (sampling_period - elapsed_time )
95
104
end_time = time .time ()
96
105
97
106
elapsed_time = end_time - start_time
98
- elapsed_time_diff = (0.001 - elapsed_time )
107
+ elapsed_time_diff = (sampling_period - elapsed_time )
99
108
100
109
while (self .continue_data_acquisition ):
101
110
start_time = time .time ()
102
- data = generate_data ()
111
+ data = self . generate_data ()
103
112
self .callback_function (data )
104
113
end_time = time .time ()
105
114
elapsed_time = end_time - start_time
106
115
# 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 )
108
117
# 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)
109
137
110
138
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 , _ ):
118
151
"""
119
152
Start ADC from chassis
120
153
121
154
chassis_id - unique ID of chassis
122
155
"""
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
128
163
129
164
def stop_adc (self , chassis_id ):
130
165
"""
131
166
Stop ADC from chassis
132
167
133
168
chassis_id - unique ID of chassis
134
169
"""
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
+
139
181
140
182
def turn_off_sensors (self , sensor_dict ):
141
183
"""
@@ -144,8 +186,35 @@ def turn_off_sensors(self, sensor_dict):
144
186
145
187
sensor_dict - dictionary of chassis id to list of sensors ex. {0: [0,1], 1:[0,1]}
146
188
"""
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 ()
149
218
150
219
def restart_sensors (self , sensor_dict , on_next = None , on_error = None , on_completed = None ):
151
220
"""
@@ -157,11 +226,9 @@ def restart_sensors(self, sensor_dict, on_next=None, on_error=None, on_completed
157
226
on_error - callback when sensor fails a step
158
227
on_completed - callback when all sensors have either succeeded or failed
159
228
"""
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
+
165
232
166
233
def coarse_zero_sensors (self , sensor_dict , on_next = None , on_error = None , on_completed = None ):
167
234
"""
@@ -174,10 +241,7 @@ def coarse_zero_sensors(self, sensor_dict, on_next=None, on_error=None, on_compl
174
241
on_completed - callback when all sensors have either succeeded or failed
175
242
"""
176
243
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 )
181
245
182
246
def fine_zero_sensors (self , sensor_dict , on_next = None , on_error = None , on_completed = None ):
183
247
"""
@@ -190,21 +254,20 @@ def fine_zero_sensors(self, sensor_dict, on_next=None, on_error=None, on_complet
190
254
on_completed - callback when all sensors have either succeeded or failed
191
255
"""
192
256
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...' )
208
271
#
209
272
# if wave_type == FieldLineWaveType.WAVE_OFF:
210
273
# self.data_source.set_wave_off(chassis_id, sensor_id)
0 commit comments