Guardian States

Guardian states are class definitions that inherit from the GuardState base class. A GuardState has two methods, that are overridden to program the state behavior:

class DAMPED(GuardState):

    # main method executed once
    def main(self):
        ...

    # run method executed in a loop
    def run(self):
        ...

The methods can execute any arbitrary code you like.

state execution model

Below is a simplistic overview of the state execution model:

state = system.STATE2()

init = True
while True:
    if init:
        method = state.main
        init = False
    else:
        method = state.run

    status = method()

    if status:
        break

The first iteration of the loop executes the main() method, whereas subsequent iterations execute the run() method. If either method returns True, or a str name of different state, the state is considered “done”, and guardian will then proceed in it’s path through the graph.

The GuardState class

class guardian.GuardState(logfunc=None)

Guardian system state machine state.

Execution model:

This type of state is known as a “Moore” state: the primary action is executed when the state is entered (main() method).

The main() method is executed once upon entering the state, after which the run() method is executed in a loop. The return values of both methods are interpreted the same, as follows:

If the return value of either method is True, the state will “complete” (status: DONE). If the state is not the requested state the system will immediately transition to the target state. If the state is equal to the requested state the run method will be executed.

If the return value is a string it will be interpreted as a state name and the system will transition immediately to the new state. This is known as a “jump” transition.

If the return value is None or False, the run() method is executed. NOTE: if unspecified, functions return None by default.

State properties (user specified):

request: indicates whether or not this state is requestable by the user. Default: True

goto: if True will cause edges to be added to this state from all states in the system graph. Default: False

index: numeric index for state. must be a positive definite number. If not specified, a negative index will be automatically assigned.

State objects:

timer: TimerManager object, used to count down a specified amount of time.

>>> self.timer['foo'] = 3
>>> self.timer['foo']
False
>>> time.sleep(3)
>>> self.timer['foo']
True

The environment of state method execution includes a couple of additional “built-in” functions:

log: write to state the system logger:

>>> log("doing something")

ezca: Ezca EPICS channel access:

>>> ezca['A'] = 3
request = True

Is this state “requestable”.

goto = False

Is this a “goto” state.

If specified as :type int, the value will be used as the edge weight for all goto edges to this state.

redirect = True

Can this state be “redirected”.

If False the state is “protected” and redirects away from this state are ignored while the state is returning False.

main()

state MAIN method.

This method is executed once immediately upon entering state.

See “Execution model” above for more info.

run()

state RUN method.

This method is executed in a loop if the main() method returns False or None.

See “Execution model” above for more info.