Minimal MQTT: Control And Clients

So you’ve built a central server and filled your house with WiFi-connected nodes all speaking to each other using the MQTT protocol. In short, you’ve got the machine-to-machine side of things entirely squared away. Now it’s time to bring the humans into the loop! We’re going to explore a couple graphical user interfaces.

You could build a physical knob and/or LED display for every little aspect of your entire system, but honestly, this is where GUIs really shine. In this installment of Minimal MQTT, we’re going to look at human-friendly ways of consuming and producing data to interact with your connected sensors, switches, and displays. There are a ton of frameworks out there that use MQTT to build something like this, but we’re going to cut out the middle-man and go straight for some GUI MQTT clients.

mqtt.dotThe minimal system we’ve built out so far has a temperature/humidity sensor publishing its data to the home/outdoors/temperature and home/outdoors/humidity topics every ten seconds. (This is unrealistic, but fun to watch it update so frequently.) Last time, because I wanted to implement a subscriber in NodeMCU, we also had a color LED device that subscribed to home/outdoors/temperature and displayed the temperature.

If you dug around through the display node code from last time, you may have also noticed that it subscribed to a home/outdoors/status topic and turned the LED that displays the temperature on and off accordingly. So that’s what we’ve got to play with so far: two channels of data, and one control channel that turns our display LED on or off.

Cellphone Apps

The easiest way to tap into this data is through your cellphone. At least for the Android platform, there are a handful of free apps that will let you directly publish and subscribe to an MQTT broker (or brokers). In the last installment, we sent temperature data from one of our nodes to the server using the home/outdoors/temperature topic. We want to have this value, and possibly even its history, displayed on our phone with minimal hassle. And we’d like to be able to control appliances (here, the LED acts as a simple stand-in) that are hooked up to the MQTT broker as well.

MQTT Dashboard

mqtt_dashI installed and uninstalled around ten MQTT apps for Android. Of them, the most satisfying by far is MQTT Dashboard, which lets you define custom actions for a few GUI elements, including text, button, switch, color-pickers, and more. The ability to configure a button or a slider to send configurable numeric or text data is fantastic. Almost all the other MQTT client apps let you type an entry in, but having to repeatedly type “off” on a cell phone’s keyboard is nobody’s idea of convenient.

For subscribed topics, the app asks you whether the data is numeric, and if so it will graph it over time when you double-click a field, which is a nice feature to have for free. Similarly, the app retains a history of the last non-numeric values that you can scroll through. And you have per-topic QoS levels should you choose to use them. Winner.

You can also subscribe to multiple topics. So in addition to keeping track of your house, you can also subscribe to hackaday/titles at test.mosquitto.org to keep up with the latest news here.

There’s actually relatively little to say about this app. It just works.

IoT Switch

screen20The other app that I liked is the open-source IoT Switch, although not because it really does anything fancy, but because it’s a minimalistic example of a native Android application that can send and receive from an MQTT server. On the other hand, if you just need four quick on-off switches, you’re set. (But note that they’re sending a one-byte code where the four button states are each represented by one bit. It’s not human-readable, but it’s machine-friendly for some machines.)

I’d love to know more about this app and its development. Here is the GitHub. Anyone out there from the Chiang Mai Hackerspace want to write up a tutorial?

Honorable Mentions

Nothing is perfect, of course, and that goes for the other apps I tried out. MyMQTT has a nice enough subscribe interface, but to publish you have to re-type the message, and worse, the topic name, over and over again. MQTTClient has the same flaws, except at least it allows you to save previously sent messages, so you only have to type “on” and “off” once. But if you wanted to, say, dim a lightbulb or pick an RGB color, you’d be sad again. IOT Manager looks great, but is very specifically targeted at the home automation market and requires a detailed configuration step that runs counter to the spirit of this series — making stuff work and staying flexible at first.

I didn’t get a chance to try out the iOS apps, but they look to all share the same flaws as the honorable mentions — text-heavy entry methods that make poor substitutes for pushbuttons. That said, MQTT Inspector looks good for debugging purposes.

Javascript, Websockets, and MQTT

paho_logo_400If a pre-cooked application for your smartphone isn’t flexible enough for you, the next step is to write one yourself. This is a tiny bit more advanced, but it’s such a powerful option that you should consider it. Because this method uses a Javascript MQTT client, you can embed it in an HTML page, which means that it will run the same on your desktop or your cell phone, or anything else that can render a webpage.

Adding buttons to your MQTT project is almost as easy as writing the HTML code for a new button. How elaborate or simple you make the interface is then just a matter of web coding. There are two prerequisites for taking the HTML-based MQTT path: tweaking our MQTT server to use Websockets, and coding up the webpage / application. Let’s get to work.

Websockets Support

If you followed the Raspberry Pi MQTT broker install instructions, you’ll have a recent version of the Mosquitto MQTT broker installed that’s already got Websockets support compiled in. If you’re a masochist and handy with re-compiling software, you can follow this guide.

Next, you need to configure Mosquitto to use a particular port for MQTT over Websockets. To do so, just create a file in the /etc/mosquitto/conf.d/ directory with a plausible but arbitrary name (sudo nano /etc/mosquitto/conf.d/websockets.conf), and add the following:

listener 9001
protocol websockets

listener 1883
protocol mqtt

Then issue the command sudo /etc/init.d/mosquitto restart and you should be set. If your version of Mosquitto doesn’t support Websockets, you’ll get a message like “Websockets support not available” at this point. If not, all went well and we can move on to the webpage.

MQTT.js

cropped_shot_2016-05-23-235624Head over to my GitHub MQTT-Javascript demo and download everything. Before you point a browser at the included index.html file, you’ll want to customize the included button_test.js file to match your MQTT server, Websockets port, and the names of the temperature and status topics if you changed them, or simply want to display something else. Then open index.html in a browser and you should see live data from your temperature MQTT stream coming across.

The HTML part of the setup is kept deliberately very simple. It just prints out the contents of the weather feeds and provides a button that toggles the home/outdoors/status channel between “on” and “off”. If you’re not used to client-side Javascript, this works by building up a placeholder webpage, and then loading and running the code at the bottom of the page.

The connect() function in button_test.js starts the ball rolling, and once it receives some data, it finds the headline <h3> elements by their id and then replaces their default text with the new values that it’s received from the MQTT server. All the rest of the work happens in your browser as it runs the code in button_test.js and the included Paho MQTT Javascript client code.

javascript4Structurally, the code here isn’t too dissimilar from the NodeMCU code we wrote last time. There’s a connect() function that builds up an MQTT client object and registers some callback functions with it that execute when we get new data and so on. Most of the magic happens in the onMessageArrived() function. The led_toggle() function is called when you press the button on the webpage.

One last little detail: the Javascript creates a random ID when it connects to the MQTT server, and this means that you can connect from multiple web browser instances using the same code, but you won’t get the advantages of persistence because the ID is re-calculated each time the page is refreshed.

I’m by no means a good Javascript coder, but I know the basics and was able to cobble this demo together from this client demo code and the documentation. Making it look good, and extending it to encompass your whole system of devices is up to you.

Also note that this webpage is entirely static — it’s all client-side Javascript with no need for a webserver. That means that you can copy these files to your cell phone, for instance, and open them up directly in your browser. All the work is done between the Javascript code and the MQTT broker.

Or if you’re feeling fancy, you can host it on the same Raspberry Pi that’s serving as your MQTT server. This option can involve a lot of configuration, and is outside of the scope of this article, but can also be as easy as downloading Apache and moving the sample code directory into the /var/www/html directory. Then everyone in the house can turn the lights on or off by accessing the same webpage. (This is just fine inside your WLAN, but don’t configure an outward-facing webserver on your Raspberry Pi without reading up a bit about security.)

Conclusion

The two options I’ve presented here, an MQTT-client app for your phone and custom HTML/Javascript both directly subscribe to the MQTT broker, and are in that sense on equal footing with the “things” that you’re using as sensor, display, or control nodes. The beauty of this approach is that everything is trivially interoperable, with MQTT providing the common communication protocol. When your cellphone app updates a topic to turn a light on, not only will the light get the message, but any other clients that are subscribed to that topic will get instantly updated.

The downside of this approach is that it can quickly turn into a patchwork. MQTT only provides you with the channels over which to communicate — what your devices are saying, and how you interpret that, is entirely up to you. If you use “on” and “off” in one topic, don’t use 1 and 0 in another topic, or it’ll end in tears.

But if this series has shown you anything, I hope that it’s how simple it can be to get data flowing between your DIY (and other) gadgets, and now to a phone screen or webpage where you can control and display it all. In the next, and final, installment, we’ll tackle some of the hard(er) stuff. Namely, the security options for when you want to extend the reach of your MQTT system outside of your own home WLAN, power management on the ESP8266 side of things, and some server-side applications that can bring some real intelligence to your smart home.

10 thoughts on “Minimal MQTT: Control And Clients

  1. Nice article, You should mention mqttwarn from jpmens (his blog is just fabulous for mqtt), it convert mqtt data to à lot of format influxdb, json, owntrack, … Influxdb + Grafana is an easy way to see data.

    1. Speaking of Node-Red, there is an http UI node that lets you add buttons, text, sliders, etc. to make a very customizable web ui. Just started using it but wish there was a way to use this in android as home screen widget. Tried a couple different webpage -> widged android apps that claim to let you do just this but no luck yet : /

      http://flows.nodered.org/node/node-red-contrib-ui

      For graphing sensor output like temperature, I have been using this. You can even set it up to show historical data from a database while it continues to add live datapoints at the same time. It’s pretty sweet!

      http://flows.nodered.org/node/node-red-contrib-graphs

  2. Does any one know of a more evolved FOSS project that is like http://www.speechpipe.com/ I’m not particularly interested in the Windows end of it but the idea of having an Android speech to MQTT message function, and the corresponding reader client would be very handy. No GUI, all speech based for hands off environments. The end goal being to hook and AI onto the MQTT broker so that it could listen to your questions or commands and reply with speech for the information requested, or to confirm an action succeeded. Initially the AI would be simple and just take your comment stream and repost correctly formatted messages on the appropriate channel for you. “Blah blah blah, blah… blah” –> channel(1).message, channel(2).message, channel(3).message etc. Then later aggregating multiple subscriptions and formatting them so that when they are republished to your talker channel you hear them on your text to speech interface. i.e. “Listener” –> multiple messages on multiple channels, with transforms, and multiple messages on multiple channels to a single channel, with transforms –> “Speaker”.

  3. I’m a big fan of home-assistant.io It allows you to connect a lot of things to mqtt and present them on a decent web page (which looks good on a phone) There is also work on an iphone app right now.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.