Connecting a MOSS bot to external devices and open data feeds using Node-RED
The other day I was reading Simen's story about joining up his Raspberry Pi with Minecraft and arduino-based sensors/servos using Node-RED and wondered how it would work with MOSS.
MOSS is a great system for quickly creating small robot platforms and Node-RED is platform for quickly prototyping integration solutions between internet enabled devices and data sources. Joining them up is actually very easy.
Although there isn't yet a publised API for MOSS, if you use the Scratch extension for MOSS, you can actually get an HTTP (RESTish) interface to the bluetooth block which is dead simple to use from Node-RED.
Step 0: Create a MOSS bot with the bluetooth brain block
Start with a simple bot that has:
- Extended Battery
- Double Brain
- Something that can be controlled
- The Pivot is good to get started but you could also use a Motor
Step 1: Install the MOSS Scratch Extension
Go and grab the Moss Scratch extension application. This app creates a little webserver which communicates between the MOSS bluetooth block and a running Scratch instance using HTTP.
We'll be using Node-RED to communicate with that HTTP server instead of Scratch. Actually, you can use this technique to control your MOSS bot with anything that speaks HTTP.
Follow the quickstart guide for the Scratch extension app. You don't need to actually start Scratch. Just get a connection between the MOSS Scratch app and your bluetooth block.
Once you have the 2nd picture above, then you're ready to go.
The extension app runs on port 41585 and you can check the connection already if you like with curl.
Step 2: Install Node-RED
Node-RED is a Node.js application so you'll need to have that installed already. There are plenty of guides online for install Node.js. You can then install Node-RED using the simple npm method. Adafruit has a nice tutorial for installing both on a Raspberry Pi.Start Node-RED and bring up the editor in a browser window.
Step 3: Create a Flow to control MOSS from HTTP
From the Input section, add an InjectFrom the Functions section, add an HTTP Request node.
From the Output section, add a Debug.
Join the three together.
(The image shows a second set of icons which repeats the flow to move the bot to the original position again. You can also add them).
Double click the first HTTP node to bring up the properties.
The URL to control the pivot uses the following template:
http://machine:41858/set_face_value/<btooth_face>/<value>
My bot has face #2 from the brain connected to Data In for the Pivot.
The MOSS getting started page explains that pivots and motors (as well as sensors) use values as a percentage.
The default position for the pivot is 50, so for the first test we'll set it to 40. So set the URL to
http://localhost:41858/set_face_value/2/40
You can repeat the process on the 2nd HTTP Node to set the Pivot back to 50
http://localhost:41858/set_face_value/2/50
That's it. Click on the left part of the Inject Nodes and the MOSS bot should nod its face up and down.
(click the img to get to the full video) |
Step 4: More interesting example - the-train-is-here-bot
The nodding bot is pretty simple but you can achieve the same results just by putting the url direct into your browser or curl. The nice part about Node-RED is how quickly you can integrate with other devices and data sources because Node-RED handles all the plumbing code. So, a bit more interesting example: a bot that will let me know when the train is at the local station.
The Oslo public transport system offers a public API for its travel information. Both timetables and realtime travel information. I'll make a quick flow that will check the realtime information at my local trainstation and get the same bot to look up and point to the trainstation if the arrival time of the next train is under 5 minutes.
First I used the APIs to find the ID of my stop so I can contruct the URL to get the info about arriving trains
http://reis.trafikanten.no/reisrest/realtime/getrealtimedata/3011510
Now to create a flow that will
- use an inject to trigger a http request
- pass the result to a JSON node that will convert to javascript
- send the new payload to a javascript function that will select the first arriving train and determine how long until it arrives
- if the time of the next train is less the 5 minutes, call an http request that will lift the bot's face
- otherwise set it the bot back to rest
- The Inject node can be configured to trigger on a schedule but I'll just do it manually for this demo.
- "get arrival info" returns a pile of JSON which is passed through the json node and onto the javascript function.
- The "find next arrival" has multiple outputs (described in the Node-RED docs) which allows it to send a true or a null to the http request nodes that will control the bot. A null wont trigger the request but any other value will.
- If the train will arrive within 5 minutes then the http request to lift the bot face is triggered
- The 3rd output sends the next train arrival time, plus the time difference in minutes to the debug node
(click img for the video) |
Its not very clear with the video resolution, but you can see the debug messages show that while the time difference is over 5 mins, the bot keeps its face lowered. But once it arrival time is under 5 mins then it looks up. You could easily make a fancier solution such as the bot running to the door when the train is nearby.
The nice part is how easy it is to wire everything together. The hardest part was the juggling of Date objects between javascript and JSON. Everything else took about 10 minutes.
Next Steps
That's it. There are plenty of places to take this:- support sensor information from MOSS to Node-RED
- create pre-configured Node-RED nodes for MOSS so that they are easier to integrate into flows
- create a Node-RED app which communicates directly with the bluetooth block without going through the MOSS Scratch Extension
- use sensors connected to an Arduino og RaspberryPi to control a moss-bot (or vice-versa)
- etc, etc
Thank you so much for this article it was super informative. One quick question...
ReplyDeleteHave you been able to run commands like get_face_value over http?
My set_face_value url commands work great, but when I run a get_face_value command there is no response from the server.
No worries. Glad it was useful.
ReplyDeleteIts been a little while since I played with it, but I'm pretty sure I could get_face_value ok. It only works for the sensors, not for the motor connectors.
If you start the scratch helper then you can use curl from the command line to check if its working
E.g:
> curl -v http://localhost:41585/get_face_value/2