Wednesday, February 18, 2015

Developing NodeRed Nodes: Some Extra-Hidden Stuff

While I'm just getting into the glamorous world of webapps (middleware for life!), the adjoining planet of the Internet of Things (IoT) is starting to also gain more satellites.  If you don't know about this wonderful place, it's the name for a system of interconnected devices over a network.  Since most of these devices previously were non-network enabled, like your thermostat or your personal drone, now you can have a lot more control over how things interact and operate.  For example, when you arrive home, the temperature of your house automatically goes up to help with saving energy.  Check out this article series from Make for some more detail.

"Alright, cool, the IoT is pretty nifty," you're saying, "and I can see where it'd be useful.  Where can I get in on this action?"  Good thing you asked because.... IBM has this pretty awesome framework specifically built for the IoT called NodeRed.  Basically you can virtually wire different endpoints from a variety of different sources to create a "flow" of information leading to action.  Some people have done some pretty amazing stuff with NodeRed like weather prediction linked to lights, and live-tweeting a marathon.  There's a huge community out there with a ton of different flows, nodes, helpful hints, and tutorials.  Pretty much the only thing holding you back is getting it on your computer.  Or spinning an app up on IBM BlueMix!

It even works with Raspberry Pi.  Normally, I'm fixing you an actual pie, but just like a different citrus fruit + vodka makes a different drink, we're going the tech route today.  Mix one up and follow along.

Digging into NodeRed - httpAdmin & httpNode

Armed with some knowledge and a drink of any variety (Coffee + Developers = Code), you're ready to go off and innovate!  Before long you might find you want to create your own nodes to supplement what's currently available.  There is so much extra customization you can do before a message could ever touch your node.  One of the most powerful things is running custom scripts when you open and close the node in the html editor.  NodeRed's own documentation has some good descriptions on how to make a custom node.  Highly highly suggest checking checking that out.

However!  As I definitely learned from dojo, source code reveals a bunch of other fun features that can 100% improve your custom node.  The above doc covers details from the javascript and html files.  Since pretty much everything in the .html file is enclosed in a script tag, you could use straight up javascript for custom behavior, but why would you want to miss out on all the node.js support packages sitting right over in the .js file?

Digging through the inner bowels of NodeRed, you'll find the only real thing linking the 2 source files is registering them through the NodeRed main service.  Sidebar: hand tracing NodeRed's startup flow is actually really interesting, if you're willing to peer down the rabbit hole.  However, the main NodeRed process runs 2 express servers under the covers: one for admin work (httpAdmin) and the other for general use (httpNode).  A common use for httpAdmin is validation when signing into an external server.  Check out the twitter or mqtt node for a great use of this in action.
From twitter.html, using jquery:
 $.getJSON('credentials/twitter-credentials/'+twitterConfigNodeId,function(data) {
From twitter.js, using httpAdmin:
RED.httpAdmin.get('/twitter-credentials/:id/auth/callback', function(req, res, next){
Cool, but you just want to access all the powers of Node, you can use httpNode to create urls that you can access from your html file.  I use ajax for synchronous connections.  You define the urls just as you would in express.  My use case required me to prepopulate a drop down menu with information I could only get from a remote CouchDB server.  Now, Node has some pretty awesome packages for CouchDB, so I want to do the work there and display the returned info  You can pretty much do the same thing!
Using ajax:
            url: "/kafka/getTypes",
            type: 'get',
            async: false,
            success: function(data) {
                availTopics = data;
So in my .js file (surpise surprise I'm working on something with Kafka!) I defined a route through the node. 
Using js:
RED.httpNode.get('/kafka/getTypes', function(req, res, next){
... //add node goodness through here
//send the information out through the response!
Only 1 place refers to the httpAdmin and httpNode that I can find.  Note: they might release something soon; crossing fingers it's more detailed than what I've provided here!  Go forth and develop!