This is a brief description of the hexabus state machines as they are implemented in the current development branch.
Set of states, set of transitions, you know the drill...
Conditions, value-dependent transitions and date/time-dependent transitions (only usable when datetime-service is enabled) are stored in seperate areas in the eeprom, and there are data structures for conditions and transitions defined in state_machine.h
Each transition has a condition index, giving the index in the array of conditions in the eeprom. This is intended to save some memory since transitions sharing the same conditions can just point to the same entry in the array. It also has a number of state indices: fromState, the state the machine has to be in in order for the transition to be applicable, goodState and badState (described below). Furthermore, it stores an endpoint ID and a data data structure (a data structure named data, see https://github.com/mysmartgrid/hexabus/issues/38). This is the Action of this transition.
Every transition has an action (set endpoint to value), a goodState and a badState. When the transition is executed, endpoint_write is called with the endpoint ID and the value. If it succeeds (returns 0), the machine goes into the goodState. If it fails (returns something !=0), the machine goes to the badState.
The condition data structure describes the conditions: They consist of a source IP, a source endpoint ID, an operator and a constant (value) to compare with.
All value dependent transitions are checked (and executed when indicated) every time a value broadcast is reveived. The first matching transition is executed.
The operators are =, <=, >=, <, >, != encoded into a 8 bit integer value as defined in state_machine.h
To execute a transition, source IP and source EID have to match. The operator and constant are evaluated, and the transition is executed accordingly.
All date/time-dependent transitions are checked (and execuded if applicable) periodically (every 5 seconds).
The data/time conditions are checked a bit differently. Source IP and EID do not matter since the conditions are checked against the internal clock provided by datetime-service. The operators are used in a different way, as well. op is an 8-bit value. Bits 0..6 are used to denote the different fields of the datetime structure. When a bit is set to 1, the corresponding field is checked: 0x01 stands for hour, 0x02 for minute, 0x04 for second, and so on. (The first bit that matches is used, so setting multiple bits is not useful.) Bit number 7 (0x80) is the operator: The selected field of the date/time struct in the condition is compared to the current date/time. If the bit number 7 is set to 1, the condition evaluates to true if the corresponding field in the current date/time is greater or equal to that in the conditions. When the bit number 7 is set to 0, < is used as the operator.
The state machine keeps track of how long it has remained in its current state by means of a variable called inStateSince and a timestamp provided by the datetime-service (counting seconds since the device was booted up). When a transition stored in the date/time transition table uses the HXB_DTYPE_TIMESTAMP datatype, it is a timestamp transition. The 32bit value it carries is checked against the number of seconds the state-machine has remanined in the fromState. If the op is 0x80 (bit 7 set, all others 0) (this was meant as a means of implementing different operators, but none except >= were deemed useful), the transition is executed iff the machine has remained in the current state for at leas the number of seconds indicated by the condition's value field.
Sometimes a Hexabus device can experience an unexpected reboot, e.g. because of a power outage in a part of a Hexabus network. The state machine running on this device is then reset to its "init" state. There are cases in which you may want other state machines to also reset then, e.g. when you have a single state machine in your Hexabus Compiler program which spans multiple physical Hexabus devices.
This behaviour is modeled by the state machine auto reset mechanism:
Each device knows its state machine ID.
This ID can be found in the Hexabus Assembler program for the device, in the line starting with
machine in the beginning of the file.
The ID is a 128-bit number.
When a Hexabus device cold-reboots, it sends out this machine ID on endpoint 12.
All Hexabus devices which have the same state machine ID now reset their state machine into the init state.
If you use the Hexabus Compiler, the state machine IDs are automatically generated (MD5sum of the state machine name), so you don't have to worry about them. When you run multiple Hexabus Compiler programs on the same Hexabus network, please make sure that each state machine name is unique, otherwise some state machines might share the same state machine ID which can lead to undesired effects.
If you program your devices with the Hexabus Assembler, you can use any non-zero 128-bit number (in Hexadecimal form) as a state machine ID.
If you don't want to make use of the auto-reset mechanism, just use state machine ID 0.
A state machine ID
0 disables the auto-reset mechanism for this state machine.
It is never broadcast on endpoint 12 and the state machine doesn't reset if any broadcast on EP 12 is received.