MTBlog Marcus' Technology Blog

Using state charts and finite state-machines in node-red

I have been using node-red running on a raspberry pi 3 for two years now in order to control my custom cloudless smart-home system. While this node.js based software package allows for easy drag&click programming of message based flows it always bugged me that it is quite user-unfriendly to create systems that keep track of their state and react to external events. It is exactly where state machines should come into play.

While there are some node-red extension packages available, such as

none of those had the functionality or user experience I had in mind.

After I had found the very well documented, flexible and well maintained node.js package xstate that intrinsically offers, at least as far as I can tell, all the functionality needed for modeling OMG UML conform state-machines, I was motivated to write my own node-red extension package.

One huge point for me is state-machine visualization. Because state-machines have a strict form it is possible to take a state-machine design and express it in a picture. This gives you an overview of all the functionality of such a machine at a glance and allows you to quickly comprehend what is going on. I had to try lots of available packages such as

  • dagre-d3 - uses dagre for layouting which is a rewrite of graphviz
  • cytoscape with different layouting extensions such as cose-bilkent. One (failed) try to render a state-machine is shown below. I couldn’t get the labels to work correctly without spending too much time on the cytoscape implementation code.
  • mxGraph (not really open-source)
  • webcola - development seems to have stopped

but all had some disadvantages, mainly in layouting nested graphs or considering label sizes for layouting. I was ready to give up the search and start developing my own package until I found the excellent state-machine-cat 😺 node.js package that currently utilizes viz.js (a port to node.js of the 1991 graphviz) as its layouting and rendering core. This offered all the functions I had in mind (well, except for the one I mentioned in issue #116 - I had to incorporate a nasty workaround) and on top of that is very well documented and easy to use.

Here is a comparison of the output from state-machine-cat versus cytoscape (that I hacked together):

state-machine-cat render
Render of state machine with state-machine-cat

cytoscape render using the cose-bilkent layouting
One (failed) try to render state machine with cytoscape

State-machine-cat is pretty nifty, isn’t it?

How it works

Are you still there? Excellent! Install the node-red package simply by searching node-red-contrib-xstate-machine in the palette manager.

Alternatively you can run the command

npm install node-red-contrib-xstate-machine

in your node-red settings folder (usually ~/.node-red)

To get you started check out the documentation over at npmjs. If you want to contribute to the project, have a look at github. I’m always happy about input and suggestions.

comments powered by Disqus