Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronous PySCXML

I'm currently looking into idioms and libraries for Python helping me with state machine design for a control task.

I've found good suggestions in this other SO question: Python state-machine design. Among the answers, PySCXML was suggested which allows to interpret State Chart XML files.

I'm concerned with the following sentences from PySCXML's readme:

you can use the send method of the StateMachine instance to send events to your statemachine [...] Of course, you'll have to do the send from a different thread

Does this mean I cannot have the state machine processing run synchronously?

As I'm imagining the use of PySCXML with my control task:

  1. Read in inputs
  2. Translate inputs to abstract input variables in state machine domain
  3. Send variables to PySCXML state machine instance
  4. PySCXML state machine instance calculates new state, and sets abstract output variables
  5. Translate abstract output variables to outputs
  6. Write out outputs
  7. Sleep until next

(If this is possible at all with PySCXML. This would allow me to completely separate the whole sequencing logic into an SCXML file.) I'd need all steps to be processed in order, especially 4. would not be allowed to run asynchronously.

like image 568
fabb Avatar asked May 07 '26 16:05

fabb


1 Answers

What you're trying to do is quite possible. Although it's true that this won't work:

xml = '''\
<scxml version="1.0" datamodel="python">
    <state id="s1">
        <transition event="e" target="f" />
    </state>
    <final id="f" />
</scxml>
    '''
sm = Statemachine(xml)
sm.start()
# never runs
sm.send("e")

instead, do this:

xml = '''\
<scxml version="1.0" datamodel="python">
    <state id="s1">
        <transition event="e" target="f" />
    </state>
    <final id="f" />
</scxml>
'''
sm = Statemachine(xml)
sm.start_threaded()
sm.send("e")

that runs the maineventloop of the statemachine in a greenlet of its own, freeing you to interact with it in the main thread. sm.send('e') will will block until the statemachine has entered a stable state (i.e until it's waiting for further external events).

like image 146
Johan Roxendal Avatar answered May 09 '26 07:05

Johan Roxendal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!