I'm been working for a while with embedded stuff and lately a lot with the Espruino javascript interpreter running on an esp8266 (it runs well on little ARM boards also). The espruino-red project is my attempt to use node-red to program/configure and operate the embedded boards.
At a high level espruino-red runs real node-red nodes on the embedded system. However, it does not run arbitrary node-red nodes on Espruino, rather a special set of nodes is used. The standard nodes (i.e. the ones you're familiar with) can be freely interconnected with the espruino-red nodes, so they really all function the same way from a user's perspective. It's just that the implementation of the embedded nodes is slightly different so they can actually run on espruino. Moreover, if you put a wire between a standard node and an espruino node the messages carried on that wire will be sent over the network, which is MQTT in the current implementation. This connectivity works between node-red and espruino-red as well as between espruino-red nodes running on different boards.
To be clear about the implementation up-front: this is a proof of concept! I built it for two primary reasons: the first is that I have been dreaming about this type of visual program composition applied to embedded systems for a long time and I want to try it out to see whether I actually like to use it in reality or whether it's just a misguided dream. The second is that doing this type of stuff in node-red without modifying node-red itself requires some ugly hacks, plus I'm not a real node.js programmer so I'm looking for feedback. The espruino-red code reaches into some internals, in particular the flows module, to grab some information it needs to function. I expect to hear that I did it all wrong and it should instead be done so and so :-). Finally, I have not paid attention to performance or efficiency: there's a lot of room for improvement!
The node-red part of the espruino-red implementation is neither tied to Espruino nor to MQTT. It just happens that espruino makes things easy because I can just use JSON messages and MQTT over wifi. I personally am looking forward to creating an implementation in Forth (!) but doing a Lua version would be rather easy as well. The MQTT portion is totally pluggable at the flow level (explained further down). For this reason I'm calling the node-red portion of all this "e-red" for "embedded-red". So think of e-red as being the overall framework that allows embedded boards to be connected to node-red and espruino-red as a specific instantiation for espruino.
Enough preliminaries, here's a very simple demo. The following flow uses a DS18B20 temperature sensor to set the blinking rate of an LED. It also provides manual overrides to fake the temperature and it has a debug node to print the blinking rate in the debug console.
All the yellow nodes run on Espruino: I can shut down node-red on my laptop and they continue running just fine. The e-red timer outputs a message at a fixed rate configured into it using the std node-red UI. The ds18b20 node reads the temperature sensor each time it receives a message and outputs the temp in degrees F. The calc rate is a simple function node with a small snippet of javascript code that converts the temperature into a blinking rate in Hz. The blinker node runs an internal timer to make an LED attached to a gpio pin blink at the rate specified by input messages.
The three grey nodes at the top are standard node-red inject nodes that override the temperature. Clicking on them injects a message into the calc rate node on espruino. The blink rate debug node is also a standard node that prints the blink rate into the node-red debug log.
This example should show how the espruino-red nodes fit very naturally into the node-red framework and how they can be interconnected at will with standard nodes. The only thing a user notices is that each e-red node has a "board" input, which is the name of the board it needs to run on. This means that it is possible to run nodes on multiple boards and interconnect them with one-another. In those cases messages are carried over MQTT as well without going through the node-red core. This screen shot shows the edit pane of the ds18b20 node, nothing special: that's the point.
I hope it's clear by now how all this differs from a firmata type of approach: the code runs on the embedded systems and new types of nodes can be added almost in the same way they're added to node red. The main difference is that in addition to the standard html and js parts each espruino-red node type needs a piece of code that runs in espruino and currently that code needs to be pre-loaded onto the board.
The communication via MQTT is exposed to the flows in a somewhat peculiar manner. The following flow (which needs to be running) interconnects node-red with espruino:
The mqtt-in node is configured to subscribe to MQTT messages destined to the core node-red and it forwards them to the espruino-red gateway, which contains the plumbing to deliver the messages to the destination nodes in node-red, i.e., this routes messages from boards to node-red The gateway also produces messages that are destined to the espruino-red boards and they are routed via the mqtt-out node, i.e. this routes messages from node-red to the boards. The queue node is a hack that's there 'cause mqtt-out drops messages when it's disconnected from the broker and that breaks things. Swapping MQTT for a different transport is mostly a matter of changing this flow. (The e-red gateway node is confusing in that messages coming in have nothing to do with messages going out, I should have used two separate nodes for the two parts.)
You can read more about the internals of espruino-red at
https://github.com/jeelabs/espruino-red which has a detailed readme. There is also a
demo.md that explains how to run a demo of the above flow on linux (no esp8266 needed). I have not done a full walk-through of the demo from scratch myself and I haven't looked up what the easiest way is to get espruino for linux, so if you want to actually play with this hit me up on gitter
https://gitter.im/jeelabs/espruino-red
Overall I'd most appreciate feedback on how this meshes with the node-red vision, if at all, and how to make it fit more naturally into node-red. The current implementation is just a few hundred lines of code, which is a testament to the flexibility of the node-red implementation!