I'm a little worried the author (Lee) may have a particular PoV and perhaps this wasn't the best resource to learn from?
I'm building an automated environmentally monitored +. controlled mushroom fruiting chamber. V1 I got by just with very basic state machines but I'm trying to take it up a notch in sophistication and do it the "right " way.
I'm in the process of writing a golang library, if you're interested in seeing some raw development (IE, I'm in the middle of designing dev UX, and the guts of the lib have yet to be implemented).
You may also consider n8n for your uses. As workflow management goes, it is quite robust.
For embedded work, I honestly don't know. I do know that golang can be transpiled into C (https://tinygo.org/) and tinygo + qmuntal/stateless might work really well for your use-case.
Here's an example I had Claude throw together for states/substates for a door with a lock
https://mermaidchart.com/play?utm_source=mermaid_live_editor...
Wow. That's a lot of link. Here's the raw chart:
stateDiagram-v2
[*] --> Closed
state Closed {
[*] --> Locked
Locked --> Unlocked: unlock / disengageBolt()
Unlocked --> Locked: lock / engageBolt()
}
Closed --> Open: open [unlocked] / swing()
Open --> Closed: close / checkSensors()
note right of Closed
Composite state with
two substates
end note
note left of Open
Simple state
end note
Locked: entry / engageBolt()
Unlocked: entry / disengageBolt()
Open: entry / startTimer()
Open: exit / stopTimer()
The syntax in the text labels is written the same way the Harel paper proposes: <State>: <entry/exit> / <action>()I definitely don't need super sophisticated functionality, but I'm trying learn a little more about formal system specification, modeling and verification like in https://mitpress.mit.edu/9780262548922/principles-of-cyber-p... and https://ptolemy.berkeley.edu/books/leeseshia/ while I'm working on this project(it might be a stretch, i'm trying to pack a lot of outcomes into one project in finite time).
I want to be able to do things like prove certain bad states are unreachable or that a certain state of the system will eventually be reached, stuff like that. I'm intrigued by the idea of analyzing/enumerating traces and the dynamical systems perspectives of trajectories through state space (background in physics- statistical mechanics).
My thinking is that the more formal and precise I am with specifying the state machine to begin with, the easier the analyses/modeling will be. I'm following a configuration-driven approach where the whole system is specified/composed from YAML/JSON, so I was planning in this iteration to come up with like a pydantic model to specify state machine behavior.
I'll have to think about testing methods more. There are a few things I would want to know about a single FSM: does it exit (various exit states, either error final state or valid final state), are there unreachable states, does it loop in places it shouldn't, does it enter states it shouldn't for a given stimuli (Events + Guards are the params for this test). I think there's also a place for event fuzzing to try and break the machine.
[0] https://www.linkedin.com/pulse/verification-testing-fsms-too...
Since then, I sometimes do manual implementations in code. For example, the Swift code of an iOS app I wrote has an ASCII art diagram of a hierarchical Statechart, for making the UI and NFC event handling solid (despite SwiftUI quirks and inconsistent docs at the time).
I am ok-but-not-great programmer, hence trying this project to get better. It seems like I should learn UML proper and this book looks like a good way to start; my "architecture" diagrams are pretty laughable. I bounce between trying to be formal and learn what "proper architecture diagrams" are vs. thinking I'm spending way too much time not coding.
I'm on a dirty and probably not-so-great hybrid of timer + event (mqtt) right now. I really want to try fully event-driven but it's a big change and I'm not very familiar with what it would entail. My original goal with this project was to implement MPC from scratch. V0 was mostly learning esp32 stuff and very basic bang-bang and timer control + FSMs that probably matched no formal specification. I've finished(or at least froze) the V1 microcontroller am starting the basic control/"driver" layer now, which is FSM based, so this reference is perfect timing. Thanks again!
UML is a standardisation of a bunch of different techniques for drawing pictures about systems. Drawing pictures can be useful for thinking about things, especially if you're a visual thinker. But statecharts are really the star of the show I think, they represent something that is easier to understand as a picture (hygraph) than as code.
I think there might be room to add `any` and `all` guards that take many guards as arguments.
The other thing I've been pondering is the apparent similarity between ASTs and the sort of graph a statechart forms. If we compress state and chart into a single object, now you have states that can have parents and children (the semantics of what is an active state would vary with your node type, IE compound or parallel). Then your edges would the transitions between nodes.
The semantics of the whole thing starts to look vaguely like there's a programming language that could emerge if the intermediate representation is hammered out well enough.
To help people not have write the charts by hand, we built a DSL (originally in python, then in Kotlin), to author robot behaviors that then compiled down to SCXML. Conditions on guards were written in a tiny expression language we wrote, enabling you to look at various signals from the hardware and software at runtime and make decisions based off them.
The nice part of this setup was that it opened up a path for doing more formal analysis on the behavior. E.g. you could easily find "terminal" states that you could enter but not leave. You can also imagine things like checking things like which states in a parallel or in concurrently running machines, aren't allowed to be active, and verifying there is no path in the state graph that allowed that to occur. There were other nice properties as well, like getting a graphical visualization of your program state "for free"
It was definitely a more constrained model than a "full featured" programming language, but for our use case, controlling machines in a reliable way, it worked out very well!