steval steval - 5 days ago 5
Python Question

Is it possible to create HierarchicalGraphMachine from HierarchicalMachine derived model instance using transitions

I have a model class like

class MyModel(HierarchicalMachine):
Machine.__init__(self, states=self.states, transitions=self.transitions,
initial='EstablishingWsConnection')
...


which works fine.

Now I would like to create a HierarchicalGraphMachine from my model like

model = MyModel()
GraphMachine = mfact.get_predefined(graph=True, nested=True)
grMachine =self.GraphMachine(
send_event=False,
auto_transitions=False,
title="BootNotificationStates",
show_conditions=True)
hgm = HierarchicalGraphMachine(model, grMachine)

hgm.model.show_graph('mystate.png')


results in
mystate.png

Is it possible to reuse my model instance for drawings?

Thx,

val

Answer

A GraphMachine is not what mfact.get_predefined(graph=True, nested=True) will give you. That would be mfact.get_predefined(graph=True). What you call GraphMachine here, is already HierarchicalGraphMachine.

To get this straight, you may create an HierarchicalGraphMachine like in the following snippet.

from transitions import Machine
from transitions.extensions import MachineFactory

myStates = ['walking', 'running']
myTransitions = [ { 'trigger': 'accelerate', 'source': 'walking', 'dest': 'running' } ]

graphNestedMachineClass = MachineFactory.get_predefined(
    graph=True, nested=True)
hierarchicalGraphMachine = graphNestedMachineClass(
    states=myStates, transitions=myTransitions, initial='walking')

If you want to embed any type of a Machine inside a HierarchicalGraphMachine and use a model, you can add the following code to the above snippet.

class MyModel(object):
    pass

myModel = MyModel()

moreStates = [
    'waiting',
    {'name': 'moving', 'children': hierarchicalGraphMachine }
]
moreTransitions = [
    { 'trigger': 'wait', 'source': '*', 'dest': 'waiting'},
    {'trigger': 'move', 'source': 'waiting', 'dest': 'moving_walking'}
]

parentHierarchicalGraphMachine = graphNestedMachineClass(
    model=myModel, states=moreStates, transitions=moreTransitions, initial='waiting')

Now you can transit between states like so:

print myModel.state  # prints 'waiting'
myModel.move()
print myModel.state  # prints 'move_walking'
myModel.accelerate()
print myModel.state  # prints 'move_running'
myModel.wait()
print myModel.state  # prints 'waiting'

And you could use e.g. myModel.graph.draw('mystate.png', prog='dot') to generate a state diagram like the following one.

mystate.png

For further details, please consider having a look into the source code of the transitions factory.py, located in the transition/extension path of the transitions repository. And also have a look at the very good README.md in the top directory of the very same repository.

The transitions repository is available via GitHub at https://github.com/tyarkoni/transitions.