Now that I have an automated city, its time to connect it to other systems. I need to design an architecture that easily allows me to build a dashboard, a prototype environment, and allow other sensor systems to easily communicate with each other. I’ve already leveraged web sockets and RESTful APIs but all that was hosted on the Raspberry Pi for the IoL city. I want something more scalable!
I discovered PubNub and it makes this a really easy process. By using this cloud based solution, I can think of all communication as “messages” that devices and applications can subscribe to, like a chat room, to do “Things”.
I then signed up for a free PubNub account to get things connected. Once I understood how it all works, I used Node-RED to prototype a dashboard and see what other web APIs I could leverage to do interesting things with my city.
From here I can easily build in a Twitter or SMS notification for certain activities, like using the motion detector from the energy saver project to double as a security system. I also have a number of ESP8266 WiFi micro controllers that could be used for sensors that communicate over the new messaging channel.
Architecture
Here is the basic topology for my new system. With PubNub at the centre, each project can communicate yet be independent of one another.
PubNub
PubNub is free to get started and has great documentation. There are a number of SDKs for easily integrating this service in all sorts of environments. I’ve only scratched the surface with its capabilities so I’m looking forward to exploring what else can be done with it.
First an account needs to be created. This will provide you with the various API keys and a console to work with the message streams. You can have up to 100 devices and send a million messages a month with the free version, so its perfect for experimenting with.
Then it’s time to implement the code. Since I’ve been working with NodeJS for the IoL City projects, I will need to add the PubNub Node.JS SDK and NPM to my project.
<code>npm install pubnub --save</code>
Then add this type of code to the server file to accept and publish PubNub messages. There are three basic components to this: Initialize API, Subscribe to a channel and Publish to a channel.
Initialize API
<span class="pl-k">var</span> pubnub <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">"</span>pubnub<span class="pl-pds">"</span></span>)({ ssl <span class="pl-k">:</span> <span class="pl-c1">true</span>, <span class="pl-c">// <- enable TLS Tunneling over TCP</span> publish_key <span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>demo<span class="pl-pds">"</span></span>, subscribe_key <span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>demo<span class="pl-pds">"</span></span> });
Subscribe
pubnub.subscribe({ channel <span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>my_channel<span class="pl-pds">"</span></span>, <span class="pl-en">callback</span> <span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">message</span>) { <span class="pl-en">console</span>.<span class="pl-c1">log</span>( <span class="pl-s"><span class="pl-pds">"</span> > <span class="pl-pds">"</span></span>, message ); } });
Publish
<span class="pl-k">var</span> message <span class="pl-k">=</span> { <span class="pl-s"><span class="pl-pds">"</span>some<span class="pl-pds">"</span></span> <span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>data<span class="pl-pds">"</span></span> }; pubnub.publish({ channel <span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>my_channel<span class="pl-pds">'</span></span>, message <span class="pl-k">:</span> message, <span class="pl-en">callback</span> <span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">e</span>) { <span class="pl-en">console</span>.<span class="pl-c1">log</span>( <span class="pl-s"><span class="pl-pds">"</span>SUCCESS!<span class="pl-pds">"</span></span>, e ); }, <span class="pl-en">error</span> <span class="pl-k">:</span> <span class="pl-k">function</span>(<span class="pl-smi">e</span>) { <span class="pl-en">console</span>.<span class="pl-c1">log</span>( <span class="pl-s"><span class="pl-pds">"</span>FAILED! RETRY PUBLISH!<span class="pl-pds">"</span></span>, e ); } });
Code
Using all of my previous project examples, I have created two primary files. A server file and a circuit file, that will run on a RaspberryPi using NodeJS and have a few connected Arduino boards running the IoL City.
The circuit file now includes all the projects covered so far and possibly more. I had to adjust how I declared devices in my Johhny-Five code. The “Boards” class constructor adds more parameters to assign devices to specific microcontrollers and their GPIOs.
I also created a multipurpose server file that will support Pubnub messages,Primus websockets and Express RESTful API commands. I then forked a child-process to launch and communicate with the circuit file. If I want to re-use this server file with other projects, I just need to change the circuit file reference.
Server
Circuit
Testing is easy with the PubNub Debug Console. Typing in a command should tell the circuit what to do and messages should start being exchanged.
Node-RED
The developers over at IBM have created a visual flow based programming tool for connecting the Internet of Things. Node-RED is a NodeJS application that’s easy to use and can provide a fun way of experimenting without a lot of coding. Effectively, you just select an import source which sends a message object, where the payload contains the important data (msg.payload). Next you manipulate the data with a function node (JavaScript) or built-in logic node. Finally, the message object gets passed to an output node. The most basic output is the debug, but it could be a Tweet or a PubNub message.
Watch this video for a 5 minute overview.
First you need to install Node-RED. My RaspberryPi is running TheThingBox image, which preinstalls Node-RED with some extra tools like WiFi configurations. I also installed Node-RED on my Macbook and an AWS Ubuntu server.
sudo npm install node-red
Then install the PubNub Node-RED package. Note that the node-red folder is hidden by default.
cd .node-red sudo npm install node-red-contrib-pubnub --save
<span class="s1">[/Users/iol/.node-red ] $ node-red restart </span><span class="s1">Welcome to Node-RED </span><span class="s1">=================== </span><span class="s1">27 Oct 22:21:24 - [info] Node-RED version: v0.10.10 </span><span class="s1">27 Oct 22:21:24 - [info] Node.js<span class="Apple-converted-space"> </span>version: v0.10.26 </span><span class="s1">27 Oct 22:21:24 - [info] Loading palette nodes </span><span class="s1">27 Oct 22:21:26 - [warn] ------------------------------------------ </span><span class="s1">27 Oct 22:21:26 - [warn] Failed to register 1 node type </span><span class="s1">27 Oct 22:21:26 - [warn] Run with -v for details </span><span class="s1">27 Oct 22:21:26 - [warn] ------------------------------------------ </span><span class="s1">27 Oct 22:21:26 - [info] Settings file<span class="Apple-converted-space"> </span>: ./settings </span><span class="s1">27 Oct 22:21:26 - [info] User Directory : /Users/cory.guynn/.node-red </span><span class="s1">27 Oct 22:21:26 - [info] Flows file <span class="Apple-converted-space"> </span>: /Users/cory.guynn/.node-red/restart </span><span class="s1">27 Oct 22:21:26 - [info] Server now running at http://127.0.0.1:1880/ </span><span class="s1">27 Oct 22:21:26 - [info] Creating new flows file </span><span class="s1">27 Oct 22:21:26 - [info] Starting flows </span><span class="s1">27 Oct 22:21:26 - [info] Started flows</span>
I’ve created this flow which can easily be cloned by copying the text and pasting using the Import option from the corner menu.
Drag the PubNub input node into the screen. Double click on it and enter the required API keys.
Drag the debug output node into the screen and connect the two nodes by pulling a connection wire.
Now you should be able to type a message on the PubNub debug console and see those messages appear in the Node-RED debug window.
Finally, drag in a PubNub output node and configure it with the API details. Connect all the nodes, Deploy and test by pushing the inject node. You should see the message in the debug window and the PubNub console. The disco lights will have turned on as well!
Final Product
Here are some images of the IoL City using a Node-RED dashboard and a Bootstrap + JQuery version I’m working on.
From here it’s easy to add more buttons for each of the circuit commands.
I connected the Twitter node so I could turn on the disco lights if somebody Tweets about InternetOfLego.com.
I then created a flow to send a Tweet if the motion detector in my city is triggered. It’s an easy test of a security system concept.
As a fun experiment, I used the PubNub SDK for browser side JavaScript to connect my blog to the IoL City. When somebody visits www.InternetOfLego.com a small script triggers disco lights!
Now the IoL City is connected and the disco is bumping!
Source Code
Github – complete project, work in progress
Gist – sample files
Node-RED – sample flow
the original post is from http://www.internetoflego.com/connecting-it-all-together-pubnub-and-node-red/
Leave a Reply
You must be logged in to post a comment.