Skip to content

State Machine

A finite state machine is a simplistic and intuitive constraint on the execution of properties and actions. Usage of a state machine must be optional depending on the complexity of the use case as it can lead to unintended side effects or dead locks if the device enters a wrong state.

API possibilities include:

  • specify the list of allowed states, initial state and the writable properties and invokable actions for each state
  • read state as a property and push state change events
  • introspection of actions or properties executable in a given state
  • specify transition callbacks when the state changes

An example could be as follows:

class Spectrometer(Thing):

    class States(StrEnum):
        DISCONNECTED = "DISCONNECTED"
        ON = "ON"
        FAULT = "FAULT"
        MEASURING = "MEASURING"
        ALARM = "ALARM"
        SIMULATION = "SIMULATION"

    state_machine = StateMachine(
        states=states,
        initial_state=states.DISCONNECTED,
        push_state_change_event=True,
        DISCONNECTED=[connect, serial_number, simulate],
        ON=[
            # actions
            start_acquisition, start_acquisition_single, disconnect, simulate,
            # properties (writeProperty)
            integration_time, trigger_mode, background_correction, nonlinearity_correction
        ],
        MEASURING=[stop_acquisition],
        FAULT=[stop_acquisition, reset_fault],
        SIMULATION=[stop_simulation]
    )

    def start_acquisition(self, max_count = None):
        # write acquisition start logic here
        self.state_machine.current_state = self.states.MEASURING

    def stop_acquisition(self):
        # write acquisition stop logic here
        self.state_machine.current_state = self.states.ON