def test_create_state(self): sm = StateMachine('test') new_state = sm.create_state('new state') self.assertIsInstance(new_state, State) self.assertEqual('new state', new_state.name) self.assertEqual(new_state, sm.states['new state'])
def test_create_state_with_custom_class(self): class CustomStateClass(State): def __init__(self, name, machine, arg0, arg1): super(CustomStateClass, self).__init__(name, machine) self.arg0 = arg0 self.arg1 = arg1 sm = StateMachine('test') new_state = sm.create_state('new state', CustomStateClass, 0, arg1=1) self.assertIsInstance(new_state, CustomStateClass) self.assertEqual('new state', new_state.name) self.assertEqual(0, new_state.arg0) self.assertEqual(1, new_state.arg1) self.assertEqual(new_state, sm.states['new state'])
def __prepare_state_machines(self): with open(self.__config_file__, "r") as f: config = json.load(f) base_path = config["base_path"] default_folder = config["state_machines"]["base_path"] max_len = config["state_machines"]["max_identifier_length"] for _type, filename in config["state_machines"]["filenames"].items(): try: ml = max_len if _type in ['id'] else MAX_SEQUENCE_LENGTH self.__state_machines__[_type] = StateMachine.read_file(f"{base_path}\{default_folder}\{filename}", ml) # print(_type + ' ' + filename) except Exception as e: pass
def test_notify_with_PseudoState(self): sm = StateMachine('test machine') src = sm.create_state('src') ps = sm.create_state('ps', PseudoState) tgt = sm.create_state('tgt') src.add_transition_to(ps) ps.add_transition_to(tgt) sm.set_state(src) # Test1 e = Event() sm.notify(e) self.assertEqual(tgt, sm.current_state)
def test_self_transition(self): def store_var(event, state): state.machine.vars['v1'] = 1 sm = StateMachine() s = sm.create_state('s1') s.add_transition_to(s, 'tick', action=store_var) sm.initial_state = s sm.initialise() e = Event('tick') sm.notify(e) self.assertEqual(1, s.machine.vars['v1'])
def __init__(self, config): super().__init__(config['controller_queue']) self.power_supply_driver = config['power_supply_driver'] self.magnet_temperature_driver = config['magnet_temperature_driver'] self.hall_sensor_driver = config['hall_sensor_driver'] self.persistent_heater_switch_temperature_channel = config[ 'persistent_heater_switch_temperature_channel'] self.magnet_temperature_channel = config['magnet_temperature_channel'] self.magnet_safe_temperatures = np.array( json.loads(config['magnet_safe_temperatures'])).reshape((-1, 2)) self.magnet_safe_temperatures_interp = interp1d( self.magnet_safe_temperatures[:, 0], self.magnet_safe_temperatures[:, 1]) print(self.magnet_safe_temperatures) self.magnet_temperature = Measurement() self.field = Measurement() self.persistent_mode_heater_switch_temperature = Measurement() self.state_machine = StateMachine(self, StateInitialize) self.run_client_thread() self.run_server_thread()
def test_add_state(self): state = MagicMock() state.name = 'test_state' sm = StateMachine('test machine') sm.add_state(state) self.assertEqual(state, sm.states['test_state']) with self.assertRaises(StateMachineException): sm.add_state(state)
def test_notify_simple(self): ''' A simple example of using a state machine ''' sm = StateMachine('state machine 1') src = sm.create_state('src') tgt = sm.create_state('tgt') src.add_transition_to(tgt) sm.initial_state = src sm.initialise() evt = Event() # TEST sm.notify(evt) # VERIFY self.assertEqual(tgt, sm.current_state)
def test_notify_with_PseudoState_can_store_vars(self): ''' Test that on_start can store data in vars. ''' def on_start(event, state): state.vars['payload'] = event.payload sm = StateMachine('test machine') src = sm.create_state('src') ps = sm.create_state('ps', PseudoState) src.add_transition_to(ps) ps.on_start = on_start sm.set_state(src) # Test1 e = Event('test', 'payload') sm.notify(e) #self.assertEqual(tgt, sm.current_state) self.assertEqual('payload', ps.vars['payload'])
def __init__(self, name, machine): State.__init__(self, name, machine) StateMachine.__init__(self, name)
def test_notify_splits_streams_correctly(self): sm = StateMachine('test machine') src = sm.create_state('src') tgt1 = sm.create_state('tgt1') tgt2 = sm.create_state('tgt2') src.add_transition_to(tgt1, 'stream1') src.add_transition_to(tgt2, 'stream2') # Test1 sm.set_state(src) sm.notify(Event('stream1')) self.assertEqual(tgt1, sm.current_state) # Test2 sm.set_state(src) sm.notify(Event('stream2')) self.assertEqual(tgt2, sm.current_state) # Test3 sm.set_state(src) sm.notify(Event()) self.assertEqual(src, sm.current_state)
def test_set_state_by_name(self): sm = StateMachine() s1 = sm.create_state('s1') s2 = sm.create_state('s2', PseudoState) s3 = sm.create_state('s3', CompositeState) sm.set_state_by_name('s1') self.assertEqual(s1, sm.current_state) sm.set_state_by_name('s2') self.assertEqual(s2, sm.current_state) sm.set_state_by_name('s3') self.assertEqual(s3, sm.current_state)
def test_inter_machine_communication(self): ''' Create two state machines - server - client client listens to server using register_observer when server sends a data event, client gets notified. ''' def send_data(event, state): state.logger.info('Server sending data') e = Event('data', 'hello world') state.notify_observers(e) server = StateMachine() server_state = server.create_state('do something') server_state.on_run = send_data server.initial_state = server_state server.initialise() def handle_data(event, state): state.logger.info('Received data %s', event.payload) state.vars['call_count'] += 1 client = StateMachine() server.register_observer('data', client) client_state = client.create_state('wait for data') client_state.on_run = handle_data client_state.vars['call_count'] = 0 client.initial_state = client_state client.initialise() # Test e = Event('tick') server.notify(e) # Verify self.assertEqual(1, client_state.vars['call_count']) # Test Again! server.notify(e) self.assertEqual(2, client_state.vars['call_count'])
def setUp(self): self.factory_controller = DummyFactoryController() self.sm = StateMachine() self.s_ini = StateInitializing(self.factory_controller)
class TestStateMachine(unittest.TestCase): def setUp(self): self.factory_controller = DummyFactoryController() self.sm = StateMachine() self.s_ini = StateInitializing(self.factory_controller) #self.s_fil_o1 = StateFillingO1() #self.s_warming_watter = StateWarmingWater() def test_no_states(self): with self.assertRaises(InitializationError): self.sm.run() def test_no_end_state(self): self.sm.add_state("name", "handler", end_state=False) self.sm.set_start("name") with self.assertRaises(InitializationError): self.sm.run() def test_state_initializing(self): self.sm.add_state(STATES.INITIALIZING, self.s_ini, end_state=False) self.sm.add_state(STATES.FILLING_01, DummyEndState(), end_state=True) self.sm.set_start(STATES.INITIALIZING) self.sm.run()
from state_machine.state_machine import StateMachine import utils regular_user_prompt = "$ " super_user_prompt = "# " state_machine = StateMachine() print(utils.beginning_message) print() print() def user_choice(choice): if choice == "cd door_to_house": state_machine.enter_house() elif choice == "cd door_to_outside_house": state_machine.leave_house() elif choice == "cd door_to_bedroom": state_machine.enter_bedroom() elif choice == "cd door_to_leave_bedroom": state_machine.leave_bedroom() elif choice == "cd door_to_studyroom":
class MagnetController(ControllerComponent): def __init__(self, config): super().__init__(config['controller_queue']) self.power_supply_driver = config['power_supply_driver'] self.magnet_temperature_driver = config['magnet_temperature_driver'] self.hall_sensor_driver = config['hall_sensor_driver'] self.persistent_heater_switch_temperature_channel = config[ 'persistent_heater_switch_temperature_channel'] self.magnet_temperature_channel = config['magnet_temperature_channel'] self.magnet_safe_temperatures = np.array( json.loads(config['magnet_safe_temperatures'])).reshape((-1, 2)) self.magnet_safe_temperatures_interp = interp1d( self.magnet_safe_temperatures[:, 0], self.magnet_safe_temperatures[:, 1]) print(self.magnet_safe_temperatures) self.magnet_temperature = Measurement() self.field = Measurement() self.persistent_mode_heater_switch_temperature = Measurement() self.state_machine = StateMachine(self, StateInitialize) self.run_client_thread() self.run_server_thread() def send_message_and_get_reply(self, queue, command): self.send_direct_message(queue, json.dumps({"CMD": command})) return self.wait_for_response() def wait_for_response(self): while self.server_response is None: pass response = json.loads(self.server_response.decode('utf-8')) self.server_response = None return response def get_magnet_temperature(self): val = self.send_message_and_get_reply( self.magnet_temperature_driver, LS218Driver.GetKelvinReading.raw_command( [self.magnet_temperature_channel]))[0] self.magnet_temperature.t0 = val['t0'] self.magnet_temperature.t1 = val['t1'] self.magnet_temperature.value = val['result'] def safe_temperature(self): self.get_magnet_temperature() self.get_field() if self.field.value: pass def get_field(self): val = self.send_message_and_get_reply( self.power_supply_driver, SMSPowerSupplyDriver.GetOutput.raw_command(['T']))[0] self.field.t0 = val['t0'] self.field.t1 = val['t1'] self.field.value = val['result'] def get_mid(self): return self.send_message_and_get_reply( self.power_supply_driver, SMSPowerSupplyDriver.GetMid.raw_command(['A'])) def set_setpoint(self, setpoint): return self.send_message_and_get_reply( self.power_supply_driver, SMSPowerSupplyDriver.SetSetpoint.raw_command([setpoint, 'T'])) def set_ramp_rate(self, ramp_rate): return self.send_message_and_get_reply( self.power_supply_driver, SMSPowerSupplyDriver.SetRampRate.raw_command([ramp_rate, 'T'])) def ramp(self, ramp_status): self.state_machine.condition = ['stop_ramp', 'start_ramp'][int(ramp_status)] def set_persistent_mode_heater_switch(self, on_off): # On = 1, Off = 0 self.send_message_and_get_reply( self.power_supply_driver, SMSPowerSupplyDriver.SetPersistentHeaterStatus.raw_command( [on_off])) def get_persistent_mode_heater_switch_temperature(self): val = self.send_message_and_get_reply( self.magnet_temperature_driver, LS218Driver.GetKelvinReading.raw_command( [self.persistent_heater_switch_temperature_channel]))[0] self.persistent_mode_heater_switch_temperature.t0 = val['t0'] self.persistent_mode_heater_switch_temperature.t1 = val['t1'] self.persistent_mode_heater_switch_temperature.value = val['result'] return self.persistent_mode_heater_switch_temperature.value def process_message(self, message): commands = message['CMD'] results = [] errors = [] try: for command in commands.split(';'): result, error = self.execute_command(command) errors.append(error if error is not None else "") results.append(result if result is not None else "") except AttributeError: logger.exception("Received message with improper format") return results def run_state_machine(self): self.state_machine.run() class GetField(QueryCommand): cmd = "GetField" arguments = "" @classmethod def execute(cls, controller, cmd, pars): return controller.field.value class GetMagnetTemperature(QueryCommand): cmd = "GetMagnetTemperature" arguments = "" @classmethod def execute(cls, controller, cmd, pars): return controller.magnet_temperature.value class SetSetpoint(WriteCommand): cmd = "SetSetpoint" arguments = "{}" @classmethod def execute(cls, controller, cmd, pars): return controller.set_setpoint(*pars) class SetRampRate(WriteCommand): cmd = "SetRampRate" arguments = "{}" @classmethod def execute(cls, controller, cmd, pars): return controller.set_ramp_rate(*pars) class Ramp(WriteCommand): cmd = "Ramp" arguments = "{}" @classmethod def execute(cls, controller, cmd, pars): return controller.ramp(*pars) class GetPersistentHeaterTemperature(QueryCommand): cmd = "GetPersistentHeaterTemperature" arguments = "" @classmethod def execute(cls, controller, cmd, pars): return controller.persistent_mode_heater_switch_temperature.value
def test_notify_with_PseudoState_can_make_choice(self): ''' Test that pseudo choice can make a choice using on_start result ''' def on_start(event, state): state.vars['payload'] = event.payload sm = StateMachine('test machine') src = sm.create_state('src') ps = sm.create_state('ps', PseudoState) tgt1 = sm.create_state('tgt1') tgt2 = sm.create_state('tgt2') src.add_transition_to(ps) ps.on_start = on_start guard1 = lambda evt, st: st.vars['payload'] == 'tgt1' ps.add_transition_to(tgt1, guard=guard1) guard2 = lambda evt, st: st.vars['payload'] == 'tgt2' ps.add_transition_to(tgt2, guard=guard2) # Test1 sm.set_state(src) e = Event('test', 'tgt1') sm.notify(e) self.assertEqual(tgt1, sm.current_state) # Test2 sm.set_state(src) e = Event('test', 'tgt2') sm.notify(e) self.assertEqual(tgt2, sm.current_state)
def test___init__(self): sm = StateMachine('test machine') self.assertIsInstance(sm, StateMachine)