def test_remote_coordinator(control_setting_name): # wait before #while not is_port_in_use(rpc.default_port): # time.sleep(1) coordinator = get_coordinator(single_process=False, sim_mode=True) #TODO need to wait for rpc client start? #time.sleep(1) coordinator.start() #while not coordinator.is_running(): # pass t = time.time() v = random.randint(10, 100) v_min = v - 5 v_max = v + 5 # TODO: add test for test reference # TODO: test racing condition c = ControlSetting(name=control_setting_name, value=v, min_value=v_min, max_value=v_max, timestamp=t) coordinator.set_control(c) c_read = coordinator.get_control(control_setting_name) assert c_read.name == c.name assert c_read.value == c.value assert c_read.min_value == c.min_value assert c_read.max_value == c.max_value assert c_read.timestamp == c.timestamp
def test_local_coordinator(control_setting_name): coordinator = get_coordinator(single_process=True, sim_mode=True) coordinator.start() while not coordinator.is_running(): pass t = time.time() v = random.randint(10, 100) v_min = v - 5 v_max = v + 5 # TODO: add test for test reference c = ControlSetting(name=control_setting_name, value=v, min_value=v_min, max_value=v_max, timestamp=t) coordinator.set_control(c) c_read = coordinator.get_control(control_setting_name) assert c_read.name == c.name assert c_read.value == c.value assert c_read.min_value == c.min_value assert c_read.max_value == c.max_value assert c_read.timestamp == c.timestamp
def test_control_settings(control_setting_name): ''' This test set_controls and get_controls Set and read a all five variables, make sure that they are identical. ''' Controller = get_control_module(sim_mode=True) Controller.start() Controller.stop() v = random.randint(10, 100) v_min = random.randint(10, 100) v_max = random.randint(10, 100) t = time.time() c_set = ControlSetting(name=control_setting_name, value=v, min_value=v_min, max_value=v_max, timestamp=t) Controller.set_control(c_set) c_get = Controller.get_control(control_setting_name) assert c_get.name == c_set.name assert c_get.value == c_set.value assert c_get.min_value == c_set.min_value assert c_get.max_value == c_set.max_value assert c_get.timestamp == c_set.timestamp
def __init__(self): super(ControlModuleMock, self).__init__() self.control_setting = {name: ControlSetting(name, -1, -1, -1, -1) for name in (ValueName.PIP, ValueName.PIP_TIME, ValueName.PEEP, ValueName.BREATHS_PER_MINUTE, ValueName.INSPIRATION_TIME_SEC)} self._running = threading.Event()
def get_control(self, control_setting_name: ValueName) -> ControlSetting: ''' Gets values of the COPY of the control settings. ''' self._lock.acquire() if control_setting_name == ValueName.PIP: return_value = ControlSetting(control_setting_name, self.COPY_SET_PIP, self.COPY_PIP_min, self.COPY_PIP_max, self.COPY_PIP_lastset) elif control_setting_name == ValueName.PIP_TIME: return_value = ControlSetting( control_setting_name, self.COPY_SET_PIP_TIME, self.COPY_PIP_time_min, self.COPY_PIP_time_max, self.COPY_PIP_time_lastset, ) elif control_setting_name == ValueName.PEEP: return_value = ControlSetting(control_setting_name, self.COPY_SET_PEEP, self.COPY_PEEP_min, self.COPY_PEEP_max, self.COPY_PEEP_lastset) elif control_setting_name == ValueName.BREATHS_PER_MINUTE: return_value = ControlSetting(control_setting_name, self.COPY_SET_BPM, self.COPY_bpm_min, self.COPY_bpm_max, self.COPY_bpm_lastset) elif control_setting_name == ValueName.INSPIRATION_TIME_SEC: return_value = ControlSetting(control_setting_name, self.COPY_SET_I_PHASE, self.COPY_I_phase_min, self.COPY_I_phase_max, self.COPY_I_phase_lastset) else: raise KeyError("You cannot set the variabe: " + str(control_setting_name)) self._lock.release() return return_value
def set_value(self, new_value, value_name=None): """ set value in the test thread """ # get sender ID if value_name is None: value_name = self.sender().objectName() control_object = ControlSetting(name=getattr(ValueName, value_name), value=new_value, min_value = self.CONTROL[value_name]['safe_range'][0], max_value = self.CONTROL[value_name]['safe_range'][1], timestamp = time.time()) self.coordinator.set_control(control_object)
def test_control_dynamical(control_type): ''' This tests whether the controller is controlling pressure as intended. Start controller, set control values, measure whether actually there. ''' Controller = get_control_module(sim_mode=True) if control_type == "PID": Controller.do_pid_control() Controller.do_pid_control() Inspiration_CI = 0.4 else: Controller.do_state_control() Controller.do_state_control() Inspiration_CI = 0.8 # State control is not that precise, slightly wider confidence regions. vals_start = Controller.get_sensors() v_peep = random.randint(5, 10) command = ControlSetting(name=ValueName.PEEP, value=v_peep, min_value=v_peep - 2, max_value=v_peep + 2, timestamp=time.time()) Controller.set_control(command) v_pip = random.randint(15, 30) command = ControlSetting(name=ValueName.PIP, value=v_pip, min_value=v_pip - 2, max_value=v_pip + 2, timestamp=time.time()) Controller.set_control(command) v_bpm = random.randint(6, 20) command = ControlSetting(name=ValueName.BREATHS_PER_MINUTE, value=v_bpm, min_value=v_bpm - 1, max_value=v_bpm + 1, timestamp=time.time()) Controller.set_control(command) v_iphase = (0.3 + np.random.random() * 0.5) * 60 / v_bpm command = ControlSetting(name=ValueName.INSPIRATION_TIME_SEC, value=v_iphase, min_value=v_iphase - 1, max_value=v_iphase + 1, timestamp=time.time()) Controller.set_control(command) Controller.start() time.sleep(0.1) vals_start = Controller.get_sensors() time.sleep(30) # Let this run for half a minute Controller.stop() # consecutive stops should be ignored Controller.stop() Controller.stop() vals_stop = Controller.get_sensors() assert ( vals_stop.loop_counter - vals_start.loop_counter ) > 100 # In 20s, this program should go through a good couple of loops assert np.abs(vals_stop.peep - v_peep) < 3 # PIP error correct within 3 cmH2O assert np.abs(vals_stop.pip - v_pip) < 3 # PIP error correct within 3 cmH2O assert np.abs(vals_stop.breaths_per_minute - v_bpm) < 3 # Breaths per minute correct within 3 bpm assert np.abs( vals_stop.inspiration_time_sec - v_iphase) < Inspiration_CI # Inspiration time correct within 0.3 sec # Test whether get_sensors() return the right values COPY_peep = Controller.COPY_sensor_values.peep COPY_pip = Controller.COPY_sensor_values.pip COPY_fio2 = Controller.COPY_sensor_values.fio2 COPY_temp = Controller.COPY_sensor_values.temp COPY_humidity = Controller.COPY_sensor_values.humidity COPY_pressure = Controller.COPY_sensor_values.pressure COPY_vte = Controller.COPY_sensor_values.vte COPY_bpm = Controller.COPY_sensor_values.breaths_per_minute COPY_Iinsp = Controller.COPY_sensor_values.inspiration_time_sec COPY_tt = Controller.COPY_sensor_values.timestamp COPY_lc = Controller.COPY_sensor_values.loop_counter assert COPY_peep == vals_stop.peep assert COPY_pip == vals_stop.pip assert COPY_fio2 == vals_stop.fio2 assert COPY_temp == vals_stop.temp assert COPY_humidity == vals_stop.humidity assert COPY_pressure == vals_stop.pressure assert COPY_vte == vals_stop.vte assert COPY_bpm == vals_stop.breaths_per_minute assert COPY_Iinsp == vals_stop.inspiration_time_sec assert COPY_tt == vals_stop.timestamp assert COPY_lc == vals_stop.loop_counter hb1 = Controller.heartbeat() assert hb1 > 0 # Test the heartbeat assert np.abs( hb1 - COPY_lc ) <= Controller._NUMBER_CONTROLL_LOOPS_UNTIL_UPDATE # true heart-beat should be close to the sensor loop counter
def test_alarm(): ''' This is a function to test the alarm functions. It triggers a series of alarms, that remain active for a while, and then are deactivated. ''' Controller = get_control_module(sim_mode=True) Controller.start() time.sleep(1) for t in np.arange(0, 30, 0.05): ### Make a cascade of changes that will not trigger alarms if t == 0: command = ControlSetting(name=ValueName.BREATHS_PER_MINUTE, value=17, min_value=0, max_value=30, timestamp=time.time()) Controller.set_control(command) command = ControlSetting(name=ValueName.INSPIRATION_TIME_SEC, value=1.5, min_value=0, max_value=2, timestamp=time.time()) Controller.set_control(command) if t == 3: command = ControlSetting(name=ValueName.PIP, value=25, min_value=0, max_value=30, timestamp=time.time()) Controller.set_control(command) if t == 6: command = ControlSetting(name=ValueName.PEEP, value=10, min_value=0, max_value=20, timestamp=time.time()) Controller.set_control(command) ### Make a cascade of changes to trigger four alarms if t == 8: # trigger a PIP alarm command = ControlSetting(name=ValueName.PIP, value=25, min_value=0, max_value=5, timestamp=time.time()) Controller.set_control(command) if t == 23: #resolve the PIP alarm command = ControlSetting(name=ValueName.PIP, value=25, min_value=0, max_value=30, timestamp=time.time()) Controller.set_control(command) if (t > 8 + (60 / 17)) and (t < 23): #Test whether it is active activealarms = Controller.get_active_alarms() assert len(activealarms.keys()) >= 1 assert 'PIP' in activealarms.keys() if t == 12: # trigger a PEEP alarm command = ControlSetting(name=ValueName.PEEP, value=10, min_value=0, max_value=5, timestamp=time.time()) Controller.set_control(command) if t == 23: # resolve it command = ControlSetting(name=ValueName.PEEP, value=10, min_value=0, max_value=20, timestamp=time.time()) Controller.set_control(command) if (t > 12 + (60 / 17)) and (t < 23): activealarms = Controller.get_active_alarms() assert len(activealarms.keys()) >= 1 assert 'PEEP' in activealarms.keys() if t == 15: # trigger a BPM alarm command = ControlSetting(name=ValueName.BREATHS_PER_MINUTE, value=17, min_value=0, max_value=5, timestamp=time.time()) Controller.set_control(command) if t == 20: # resolve it command = ControlSetting(name=ValueName.BREATHS_PER_MINUTE, value=17, min_value=0, max_value=20, timestamp=time.time()) Controller.set_control(command) if (t > 15 + (60 / 17)) and (t < 20): activealarms = Controller.get_active_alarms() assert len(activealarms.keys()) >= 1 assert 'BREATHS_PER_MINUTE' in activealarms.keys() if t == 17: # Trigger a INSPIRATION_TIME_SEC alarm command = ControlSetting(name=ValueName.INSPIRATION_TIME_SEC, value=1.5, min_value=0, max_value=1, timestamp=time.time()) Controller.set_control(command) if t == 22: # resolve it command = ControlSetting(name=ValueName.INSPIRATION_TIME_SEC, value=1.5, min_value=0, max_value=3, timestamp=time.time()) Controller.set_control(command) if (t > 17 + (60 / 17)) and (t < 22): activealarms = Controller.get_active_alarms() assert len(activealarms.keys()) >= 1 assert 'I_PHASE' in activealarms.keys() time.sleep(0.05) Controller.stop() #Check that the duration of the four alarms was correct sv = Controller.get_sensors() logged_alarms = Controller.get_logged_alarms() for a in logged_alarms: print(a.alarm_name) assert not a.is_active alarm_duration = a.alarm_end_time - a.alarm_start_time if a.alarm_name == 'PEEP': assert alarm_duration < (1 + np.ceil( sv.breaths_per_minute * 11 / 60)) * 60 / sv.breaths_per_minute if a.alarm_name == 'BREATHS_PER_MINUTE': assert alarm_duration < (1 + np.ceil( sv.breaths_per_minute * 5 / 60)) * 60 / sv.breaths_per_minute if a.alarm_name == 'I_PHASE': assert alarm_duration < (1 + np.ceil( sv.breaths_per_minute * 5 / 60)) * 60 / sv.breaths_per_minute if a.alarm_name == "PIP": assert alarm_duration < (1 + np.ceil( sv.breaths_per_minute * 15 / 60)) * 60 / sv.breaths_per_minute # And that they have been resolved/logged correctly assert len(Controller.get_active_alarms()) == 0 assert len(Controller.get_logged_alarms()) >= 4 assert len(Controller.get_alarms()) >= 4 waveformlist_1 = Controller.get_past_waveforms( ) #This also should work fine waveformlist_2 = Controller.get_past_waveforms() assert len([s for s in waveformlist_1 if s is not None]) > len([ s for s in waveformlist_2 if s is not None ]) #Test: calling the past_waveforms clears ring buffer.