Real-Time Web Interface to MQTT using Socket.io and Node.js

Real-Time Web Interface to MQTT using Socket.io and Node.js

First, all credit for this tutorial goes to Robert Hekkers Blog.  I've altered it slightly to pick up newer versions of the various javascript libraries.

If you've followed along with my earlier post, you now have MQTT running on your Raspberry Pi, and an Arduino IoT client that can publish and subscribe to MQTT packets.  The next step is developing a real-time web interface that can control your MQTT network.

Why Socket.io and Node.js?
Web browsers typically operate by pulling data from a server when you click on a link.  Servers don't usually keep an open connection to the browsers it has serviced, so if some event happens on the server side, the server cannot push that event to your browser, unless you refresh the page.

That's where Socket.io comes in handy.  Socket.io maintains an open connection between the server and the browser, which enables the server to push updates to the browser as they happen.  This is useful so you can see changes to your IoT network as they happen, and not have to wait for a page refresh.

Step 1: Setup a Web Server on your Raspberry Pi
sudo apt-get install apache2 -y
hostname -I
Now test your web server by using a web browser to navigate to your Raspberry Pi's web address










Step 2: Get Socket.IO, Node.js and the MQTT client
wget http://node-arm.herokuapp.com/node_latest_armhf.deb
sudo dpkg -i node_latest_armhf.deb
sudo apt-get install npm

cd /var/www
sudo npm install mqtt
sudo npm install socket.io


Step 3: Test Your Node.js and MQTT client
create the file /var/www/mqtt_test.js
DATA HOSTED WITH ♥ BY PASTEBIN.COM - DOWNLOAD RAW - SEE ORIGINAL
  1. var mqtt    = require('mqtt');
  2. var client  = mqtt.connect('mqtt://test.mosquitto.org');
  3.  
  4. client.on('connect', function () {
  5.     client.subscribe('presence');
  6.     client.publish('presence', 'Hello mqtt');
  7. });
  8.  
  9. client.on('message', function (topic, message) {
  10.   // message is Buffer
  11.     console.log(message.toString());
  12.     client.end();
  13. });
node mqtt_test.js
Then change the server URL from test.mosquitto.org to your Rpi's IP address
node mqtt_test.js

Step 4: Get Thomas Reynolds' iOS Style Jquery Checkboxes
cd ~/
wget https://github.com/tdreyno/iphone-style-checkboxes/archive/v1.zip
unzip v1.zip
cd iphone-style-checkboxes-1
sudo cp -pr jquery /var/www
sudo cp -pr images /var/www
sudo cp style.css /var/www


Step 5: Create a Node.js script to link Socket.io to MQTT
create the file /var/www/pusher.js
DATA HOSTED WITH ♥ BY PASTEBIN.COM - DOWNLOAD RAW - SEE ORIGINAL
  1. /* Pusher.js
  2. Server side node.js script that services real-time websocket requests
  3. Allows websocket connections to subscribe and publish to MQTT topics
  4. */
  5.  
  6. var sys = require('sys');
  7. var net = require('net');
  8. var mqtt = require('mqtt');
  9.  
  10. // create a socket object that listens on port 5000
  11. var io = require('socket.io').listen(5000);
  12.  
  13. // create an mqtt client object and connect to the mqtt broker
  14. var client = mqtt.connect('mqtt://192.168.1.116');
  15.  
  16. io.sockets.on('connection', function (socket) {
  17.     // socket connection indicates what mqtt topic to subscribe to in data.topic
  18.     socket.on('subscribe', function (data) {
  19.         console.log('Subscribing to '+data.topic);
  20.         socket.join(data.topic);
  21.         client.subscribe(data.topic);
  22.     });
  23.     // when socket connection publishes a message, forward that message
  24.     // the the mqtt broker
  25.     socket.on('publish', function (data) {
  26.         console.log('Publishing to '+data.topic);
  27.         client.publish(data.topic,data.payload);
  28.     });
  29. });
  30.  
  31. // listen to messages coming from the mqtt broker
  32. client.on('message', function (topic, payload, packet) {
  33.     console.log(topic+'='+payload);
  34.     io.sockets.emit('mqtt',{'topic':String(topic),
  35.                             'payload':String(payload)});
  36. });
node pusher.js &

Step 6: Create your web page
create the file /var/www/iot_demo.html
DATA HOSTED WITH ♥ BY PASTEBIN.COM - DOWNLOAD RAW - SEE ORIGINAL
  1. <html lang="en">
  2. <head>
  3. <meta charset="UTF-8">
  4. <h1>Real Time</h1>
  5. <script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
  6. <scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  7. <script src="jquery/iphone-style-checkboxes.js"></script>
  8. <link rel="stylesheet" href="style.css">
  9. <script>
  10.   $(document).ready(function() {
  11.         $(':checkbox').iphoneStyle({
  12.             onChange: function(elem,val) {
  13.                 if (val) {
  14.                     socket.emit('publish', {topic:"led",payload:"on"});
  15.                 } else {
  16.                     socket.emit('publish', {topic:"led",payload:"off"});
  17.                 }
  18.             }
  19.         });
  20.     });
  21. </script>
  22. <script>
  23.   var socket = io.connect('192.168.1.116:5000');
  24.   socket.on('connect', function () {
  25.     socket.on('mqtt', function (msg) {
  26.       console.log(msg.topic+' '+msg.payload);
  27.       if (msg.payload == "off") {
  28.         if ($('input[name=led]').is(':checked')) {
  29.           $('input[name=led]').prop('checked',false).change();
  30.         }
  31.       }
  32.       if (msg.payload == "on") {
  33.         if (!$('input[name=led]').is(':checked')) {
  34.           $('input[name=led]').prop('checked',true).change();
  35.         }
  36.       }
  37.     });
  38.     socket.emit('subscribe',{topic:'led'});
  39.   });
  40. </script>
  41. </head>
  42.  
  43. <body>
  44.   <div class='table'>
  45.     <table>
  46.       <tr>
  47.         <td style='vertical-align: middle !important;'>
  48.           LED:
  49.         </td>
  50.         <td>
  51.           <input name="led" checked='checked' class='yesno'type='checkbox' />
  52.         </td>
  53.       </tr>
  54.     </table>
  55.   </div>
  56. </body>
  57. </html>

Step 7: Test your real-time web interface
mosquitto_sub -t "led"
browse to http://your_rpi_ip_address/iot_demo.html
toggle the checkbox, and you should see messages on your MQTT network Now open multiple browsers and try toggling the checkbox

Comments

  1. Hi Decode. Thank you for sharing, I am trying to do it for months, but no success. Do u have a video or more screenshots with more details or github with that project.

    ReplyDelete
  2. Nice work, your blog is concept oriented ,kindly share more blogs like this
    Node JS Online training
    Node JS training in Hyderabad

    ReplyDelete
  3. Hello... two years later but here's a question... for Steps 2 thru 6, shouldn't the activity take place in /var/www/html (instead of /var/www)...? Otherwise, the iot_demo.html file isn't in the /var/www/html directory and you will not be able to access it via a web browser.

    ReplyDelete

Post a Comment

Popular posts from this blog

Customize radio buttons and checkboxes with CSS sprites

Script For Login, Logout and View Using PHP, MySQL and Bootstrap