StateMachineImpl
- Namespace
- ZAux
- Extends
- Inherited Properties
- Inherited Methods
- Implements
FUNCTION_BLOCK ABSTRACT StateMachineImpl EXTENDS ZCore.ManagedObject IMPLEMENTS ZCore.IHaltable, ZCore.IManagedObject, ZCore.IBootable, ZCore.IObject, ZCore.IError (
[output] State : ObjectState)
This functionblock contains the business logic to operate a finite-state machine, which is a mathematical model of computation. It is an abstract machine that can be in exactly one of a finite number of states at a given time. The StateMachine can change one state to another via a transition, which can be triggered by the TransitionAsync method.
In this implementation, each state can be associated with a Sequence, which is executed once the statemachine is in this given state until the sequence reports that its execution is finished successfully or its execution failed. In both cases, the statemachine triggers a transition to the state that is configured by the abstract FinalState method that has to be implemented by any actual statemachine implementations (e.g. UnitStateMachineImpl). The state that is defined in this method has to be an allowed transition for the statemachine, which in turn can be set-up by implementing the IsTransitionAllowed method.
For notifications about state changes, you can set up a listener processor. This sequence is designed to be invoked at specific points during the state machine's execution, providing hooks for additional actions and error handling. The listener sequence is called before the actual state sequence is executed, allowing you to perform any necessary pre-processing or setup. After the state sequence has completed, the listener sequence is called again to handle any post-processing or cleanup tasks. In the event of an error occurring in either the state sequence or the listener sequence itself, the listener sequence is invoked to manage the error condition. The listener sequence can remain active over several cycles, providing ongoing monitoring and intervention as needed. However, it can also be aborted if necessary. Aborting a listener sequence has the same effect as if an error occurred in the actual state sequence, triggering the state machine's fault reaction mechanisms. When an error is detected, the listener sequence is called once to address the error state. This invocation is immediate and stops further listener actions, allowing the state machine to proceed with its configured fault reaction. This ensures that error handling is prompt and consistent, aligning with the overall error management strategy. By setting up a listener sequence, you can create a robust mechanism for state change notifications and error handling within the state machine. This approach provides flexibility and control, enabling you to implement custom logic before and after state transitions and to handle errors effectively.
Implementations of actual statemachines (e.g. UnitStateMachineImpl should use an enumeration to define the finite number of states that the statemachine is working with (e.g. UnitStateMachineImpl, extending from this object and implementing the abstract methods defined in this class. The most notible methods to implement and their purpose are as follows.
IsTransitionAlloweddefines the states that are possible to transition into for each individual state.FinalStatedefines the state that should be automatically transitioned to once the sequence that is optionally mapped to a state is not busy anymore.Errorcan be used to test if the statemachine is in an actual error state. This is useful for statemachines that implement automatic recovering from sequence errors, to define a specific state that is an actual, unrecoverable error for this statemachine.StateDecodedallows to map a state enumeration to strings, which are then used for logging. In the State Enumeration0has the special meaning of an invalid state, which is not assignable. StateMachineImpl will transition into this special state if the implementation of the statemachine is incorrect (e.g. the transition to FinalState returnsFALSEin IsTransitionAllowed.
Constructor
FB_init
METHOD FB_init (
[input] bInitRetains : BOOL,
[input] bInCopyCode : BOOL,
[input] parent : ZCore.IManagedObject) : BOOL
The constructor of a ManagedObject takes a parent as parameter, which is then notified about the creation of this instance.
Inputs
bInitRetainsBOOLif TRUE, the retain variables are initialized (warm start / cold start)
bInCopyCodeBOOLif TRUE, the instance afterwards gets moved into the copy code (online change)
parentIManagedObjectInterface to the ManagedObject that is the parent of this object
Returns
- BOOL
Properties
Busy
PROPERTY Busy : BOOL
Similarily to the object implementation of Busy, this property
returns TRUE, if the statemachine is currently working or idle. StateMachines are busy if they are in a valid state and have a
sequence associated with it.
Property Value
- BOOL
Error
PROPERTY ABSTRACT Error : BOOL
Can be used to test if the statemachine is in an actual error state. This is useful for statemachines that implement automatic recovering from sequence errors, to define a specific state that is an actual, unrecoverable error for this statemachine. So notably, a sequence may be in an error state, but this doesn't been that the statemachine is in an error state.
This property has to be implemented by every actual statemachine implementation that extends from StateMachineImpl. For an example, see UnitStateMachineImpl.
Property Value
- BOOL
Halted
PROPERTY Halted : BOOL
The object ended its cyclic method prematurely. Use this property to test, if the object corresponded successfully correctly to a halt command (usually issued by a CancellationToken).
The statemachine halted and is in a resumable state, which means that the halted sequenced configured milestones
Property Value
- BOOL
Halting
PROPERTY Halting : BOOL
The object is currently prematurely ending its cyclic method. Use this property to test, if the object corresponded correctly to a halt command (usually issued by a CancellationToken). Use the result to appropriately react. Sequences that should be halted, but do not support a dedicated halting mechanism, should either be waited for with a timeout or stopped.
Property Value
- BOOL
ListenerProcessor
PROPERTY PROTECTED ABSTRACT ListenerProcessor : REFERENCE TO StateMachineListenerProcessor
The AllListenerSequence property defines the listener sequence which is invoked before and after any actual state sequence. Additionally, it is called once after an error occurs in either the state sequence or the listener sequence. Implementing this property allows custom state machines to define sequences of listeners that perform actions before and after state transitions, and to handle errors uniformly.
This method has to be implemented by every actual statemachine implementation that extends from StateMachineImpl. For an example, see UnitStateMachineImpl.
Property Value
- REFERENCE TO StateMachineListenerProcessor
Methods
Cyclic
METHOD Cyclic ()
This method is called cyclically by the parent or an object manager. It takes care of starting, executing and (auto)transitioning Sequence.
- A transition from one state to another can be externally requested.
- If this transition is allowed this method takes care of starting the sequence that has been optionally mapped to the new state. If necessary an already running sequence is interrupted.
- (optional for mapped sequences) Once the sequence is not busy anymore, the final state method is used to automatically transition into the state that is defined in this method.
Additionally for every state change, which includes starting and exiting, the listener that has has been optionally set, is informed.
Note that this method is performance optimized to handle state changes in 1 PLC cycle.
EnsureRunSequenceAsync
METHOD PRIVATE EnsureRunSequenceAsync (
[input] sequence : ZCore.ISequence)
Helper method, which runs the cyclic of the active sequence (either the actual state sequence or the listener sequence)
Inputs
sequenceISequence
FinalState
METHOD ABSTRACT FinalState (
[input] step : StateMachineStep,
[input] statemachineState : INT) : INT
Defines the state that should be automatically transitioned to, once the sequence that is
optionally mapped to a state is not busy anymore. The internalState that is passed as a parameter
is used to determine if the sequence failed with an error or finished successfully, respectively.
The parameter statemachineState contains the state that the statemachine is currently in.
This method has to be implemented by every actual statemachine implementation that extends from StateMachineImpl. For an example, see UnitStateMachineImpl.
Inputs
stepStateMachineStepstatemachineStateINT
Returns
- INT
IsTransitionAllowed
METHOD ABSTRACT IsTransitionAllowed (
[input] fromState : INT,
[input] toState : INT) : BOOL
Defines the states that are possible to transition into for each individual state.
This method has to be implemented by every actual statemachine implementation that extends from StateMachineImpl. For an example, see UnitStateMachineImpl.
Inputs
fromStateINTusually an enumeration containing all states of this statemachine
toStateINTusually an enumeration containing all states of this statemachine
Returns
- BOOL
SetLogger
METHOD SetLogger (
[input] logger : ZCore.ILogger)
Use this function to enable logging for this statemachine instance. If logging is
enabled, every state change (failing, succeeding) is written to the logger.
For logger=0, logging is deactivated.
Inputs
loggerILogger
SetName
METHOD SetName (
[input] name : ZCore.ZString)
This method can be used to give a name to the statemachine instance, which is useful if logging is used.
Inputs
nameZString
SetState
METHOD SetState (
[input] state : INT) : BOOL
This method can be used to force the statemachine into a specific state. In contrast to TransitionAsync the change is abruptly and will not stop an optionally already running sequence.
This method should only be used to set the initial state of the statemachine and not for controlling a sequential flow. For the later purpose, TransitionAsync should be used, which performs a "clean" transition from one state to another.
Inputs
Returns
- BOOL
SetStateSequence
METHOD SetStateSequence (
[input] stateIndex : INT,
[input] sequence : ZCore.ISequence,
[input] flags : WORD)
If a state is associtated with a sequence the Cyclic method of the statemachine
takes care of executing this sequence until the sequence is not busy. Then the FinalState
method is used to automatically transition into the state that is configured there.
Note
stateIndex has to be greater than 0 and equal or smaller than MaxStates.
While the statemachine is in a state that has an associated sequence, the statemachine is regared as Busy.
The parameter flags is free to use by every actual StateMachine implementation.
Inputs
stateIndexINTusually an enumeration containing all states of this statemachine
sequenceISequenceflagsWORD
StateDecoded
METHOD ABSTRACT StateDecoded (
[input] state : INT) : ZCore.ZString
Allows to map a state enumeration to strings, which are then used for logging.
This method has to be implemented by every actual statemachine implementation that extends from StateMachineImpl. For an example, see UnitStateMachineImpl.
Inputs
Returns
StateIndex
METHOD StateIndex () : INT
This method returns the current state that the statemachine is in.
Please note that the method name State is already occupied by Object that this implementation is extending from.
Returns
- INT
TransitionAsync
METHOD TransitionAsync (
[input] startToken : ZCore.IStartToken,
[input] state : INT) : BOOL
This method is used to perform a "clean" transition from the current state of the statemachine
to state, but only if the transition is allowed.
The state change is not performed instantly, but only in the next call of the Cyclic method, which is usually automatically called by an object manager or the parent of this object.
Inputs
startTokenIStartTokenstateINTusually an enumeration containing all states of this statemachine
Returns
- BOOL