Files
hpr_website/www/eps/hpr2173/hpr2173_full_shownotes.html

185 lines
21 KiB
HTML
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<meta name="author" content="Dave Morriss">
<title>Driving a Blinkt! as an IoT device (HPR Show 2173)</title>
<style type="text/css">code{white-space: pre;}</style>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link rel="stylesheet" href="http://hackerpublicradio.org/css/hpr.css">
</head>
<body id="home">
<div id="container" class="shadow">
<header>
<h1 class="title">Driving a Blinkt! as an IoT device (HPR Show 2173)</h1>
<h2 class="author">Dave Morriss</h2>
<hr/>
</header>
<main id="maincontent">
<article>
<header>
<h1>Table of Contents</h1>
<nav id="TOC">
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#making-an-led-indicator">Making an LED Indicator</a><ul>
<li><a href="#pictures-of-the-pi-zero">Pictures of the Pi Zero</a></li>
</ul></li>
<li><a href="#experimenting-with-the-blinkt">Experimenting with the <em>Blinkt!</em></a></li>
<li><a href="#a-note-about-pi-security">A note about Pi security</a></li>
<li><a href="#communicating-with-the-pi-zero">Communicating with the Pi Zero</a><ul>
<li><a href="#what-mqtt-does">What MQTT does</a></li>
<li><a href="#my-first-version-listener-script">My first version listener script</a></li>
<li><a href="#my-first-publisher">My first publisher</a></li>
<li><a href="#the-next-version-listener-script">The next version listener script</a></li>
</ul></li>
<li><a href="#other-ways-im-using-the-notification-system">Other ways Im using the notification system</a><ul>
<li><a href="#new-hpr-shows">New HPR shows</a></li>
<li><a href="#mail-notification">Mail notification</a></li>
<li><a href="#planned-irc-notifier">Planned IRC notifier</a></li>
</ul></li>
<li><a href="#using-mqtt-with-the-blinkstick">Using MQTT with the <em>BlinkStick</em></a></li>
<li><a href="#conclusion">Conclusion</a></li>
<li><a href="#links">Links</a></li>
</ul>
</nav>
</header>
<h2 id="introduction">Introduction</h2>
<p>I managed to buy a Raspberry Pi Zero when they first came out in December 2015. This was not easy since they were very scarce. I also bought a first-generation case from <a href="https://shop.pimoroni.com/" title="Pimoroni Ltd">Pimoroni</a> and some 40-pin headers. With the Zero this header is not pre-installed and its necessary to solder it onto the Pi yourself.</p>
<p>I have had various project ideas for this Pi Zero, but had not decided on one until recently. Within the last month or two Pimoroni produced a device called the <a href="https://shop.pimoroni.com/products/blinkt" title="Blinkt!"><em>Blinkt!</em></a> which has eight APA102 RGB LEDs and attaches to the GPIO header. This costs £5, just a little more than the Zero itself.</p>
<p>My plan was to combine the two and turn them into a status indicator for various things going on that needed my attention.</p>
<h2 id="making-an-led-indicator">Making an LED Indicator</h2>
<p>The plan was to mount the Zero inside something where the LEDs could be clearly seen and to label them in some way so that the significance of their signal could be easily determined.</p>
<p>I found a small but fairly deep picture frame in IKEA in their <a href="http://www.ikea.com/gb/en/catalog/products/70078335/#/40214202" title="IKEA RIBBA">RIBBA</a> range and decided to use that. The one I picked up has external dimensions 12.5cm by 17.4cm and is 3.4cm deep. The internal size is 10cm by 15cm. It has a silvered finish. There is a piece of glass in it and behind that is a piece of hardboard<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a> with fixtures for hanging the frame or standing it on a flat surface.</p>
<p>I wanted to mount the Zero behind the hardboard, drilling holes in it to allow the lights to shine through. The Zero in its case was to be held on with new longer nylon bolts. As mentioned, the case is the early Pimoroni model and as a consequence the nylon bolts are M2.5 20mm, not an easy size to find. The later cases use M3 bolts.</p>
<p>I made a design in <a href="https://inkscape.org/en/" title="Inkscape">Inkscape</a> which would act as a template for drilling the holes and could be placed in the finished frame to label each of the lights. The original plan was to use the paper the design was printed on to act as a light diffuser, since the LEDs are quite bright, and to provide space for the legends.</p>
<p>Getting everything in just the right position in the template turned out to be quite difficult, but I learned much more about Inkscape than I knew before while I was doing it.</p>
<p>The <a href="hpr2173_blinkt_legends.svg" title="Inkscape diagram for my picture frame">Inkscape SVG file</a> is included with this show in case you want to use it (be aware that it contains a hidden layer I used to line things up).</p>
<h3 id="pictures-of-the-pi-zero">Pictures of the Pi Zero</h3>
<p><img src="hpr2173_img_01.png" alt="Pi Zero with Blinkt!" /><br />
<em>Pi Zero in a case, with Blinkt!, LED 6 on</em></p>
<p><img src="hpr2173_img_02.png" alt="Side view of Pi Zero upside down with Blinkt!" /><br />
<em>Pi Zero with Blinkt! fixed to the hardboard</em></p>
<p><img src="hpr2173_img_03.png" alt="Pi Zero mounted to picture frame backing" /><br />
<em>Pi Zero with wireless dongle bolted to picture frame backing</em></p>
<p><img src="hpr2173_img_04.png" alt="Front of backing plate" /><br />
<em>Front of backing plate (with not very well aligned holes)</em></p>
<p><img src="hpr2173_img_05.png" alt="Pi Zero on backing plate in frame" /><br />
<em>Pi Zero on backing plate, with power cable, mounted in the RIBBA frame</em></p>
<p><img src="hpr2173_img_06.png" alt="Front view of finished frame" /><br />
<em>Front view of finished frame</em></p>
<h2 id="experimenting-with-the-blinkt">Experimenting with the <em>Blinkt!</em></h2>
<p>As usual with products from Pimoroni there are lots of great hints and tips on how to use them. The <em>Blinkt!</em> is probably best driven from Python, and there is a library to make it easier, which can be installed from the <a href="http://learn.pimoroni.com/tutorial/sandyj/getting-started-with-blinkt" title="Getting started with Blinkt!">Pimoroni site</a>.</p>
<p>Within the repository on <a href="https://github.com/pimoroni/blinkt" title="Pimoroni GitHub repository">GitHub</a> there are many example Python scripts, most of which I tried out. These are a great resource for developing your own code, especially if (like me) youre not experienced with Python.</p>
<h2 id="a-note-about-pi-security">A note about Pi security</h2>
<p>I have never been happy about leaving my Raspberry Pis with the default “<code>pi</code>” username and “<code>raspberry</code>” password. Quite a few tools assume that you have done this. Also, its assumed that the <code>pi</code> account is enabled to run <code>sudo</code> without a password.</p>
<p>I normally disable the <code>pi</code> account and/or change its password. I also remove it from the <code>/etc/sudoers</code> (use <code>visudo</code> to do this).</p>
<p>I normally create a <code>dave</code> account with a complex password (generated with <code>KeePassX</code>), and give it <code>sudo</code> access, with a password.</p>
<p>When using the <em>Blinkt!</em> it is assumed that every script accessing the GPIO needs to run as <code>root</code>. The <em>Blinkt!</em> is attached to the GPIO of course. The GPIO device driver uses file system files under the directory <code>/sys/class/gpio/</code> and these are owned by user <code>root</code> and group <code>gpio</code>.</p>
<p>I searched for ways in which I could access the GPIO without prefixing every command with <code>sudo</code> (and typing the password). I didnt find a clear answer, but I had dealt with a similar situation when making one of my Pis a printer and scanner driver, so I tried giving my account <code>dave</code> membership of the <code>gpio</code> group:</p>
<pre><code>sudo usermod -G gpio dave</code></pre>
<p>This was the answer, and after that the need to use <code>sudo</code> had disappeared.</p>
<p>I would much prefer that this was standard practice and was well documented. Learning how to use the Raspberry Pi should also include learning some basic security practices I believe.</p>
<p>Note that user <code>pi</code> also has <code>gpio</code> group membership:</p>
<pre><code>$ id pi | fold
uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),20(dialout),24(cdrom),27(sudo),
29(audio),44(video),46(plugdev),60(games),100(users),101(input),108(netdev),999(
spi),998(i2c),997(gpio)</code></pre>
<p>I used the “<code>fold</code>” command (pre-installed in Raspbian) to wrap the long line to its default width of 80 characters in this example. I did this for these notes.</p>
<h2 id="communicating-with-the-pi-zero">Communicating with the Pi Zero</h2>
<p>So, knowing that I could control the <em>Blinkt!</em> with scripts on the Pi Zero, I next wanted to come up with a way to control it remotely. I was reluctant to design a communications infrastructure, write my own listener and make it accept remote commands, so I looked for alternatives.</p>
<p>My first point of reference was a queuing system called <a href="http://zeromq.org/" title="ZeroMQ"><em>ZeroMQ</em></a> which I had heard about from various places, and recently on the <a href="https://changelog.com/podcast/" title="The Changelog"><em>Changelog</em></a> podcast. As I looked into this it seemed like overkill for this project.</p>
<p>I next looked at <a href="https://en.wikipedia.org/wiki/MQTT" title="Wikipedia article on MQTT"><em>MQTT</em></a> which is much more lightweight. I remembered I had been to a talk on this at OggCamp 2012 given by <a href="http://www.slideshare.net/andypiper/lightweightmessaging-oc2011" title="Oggcamp 2010 Talk on MQTT">Andy Piper</a>, and recalled mention of a system called <em>Mosquitto</em> in relation to this. This protocol (amongst others?) is being used in <em>The Internet of Things</em> apparently.</p>
<p>I soon found that I could install the <code>mosquitto</code> server and clients on the Pi Zero with very little trouble:</p>
<pre><code>sudo apt-get install mosquitto mosquitto-clients</code></pre>
<p>This gave me the <em>Mosquitto</em> server and some clients. The server was set up to run at boot time without any intervention on my part, and can be controlled as <code>root</code> with the <code>service</code> command. The clients consist of the commands <code>mosquitto_sub</code> and <code>mosquitto_pub</code>.</p>
<h3 id="what-mqtt-does">What MQTT does</h3>
<p>The design of MQTT is based around a <a href="https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern" title="Publish-subscribe pattern"><em>publish/subscribe</em></a> or “<em>pub/sub</em>” model. This requires a <em>message broker</em> whose job is to pass messages from <em>publisher</em> to <em>subscriber</em>. It knows which messages to send where by filtering them based on an attribute called the <em>topic</em>.</p>
<p>A publisher might be a temperature sensor or a doorbell sending a message in response to an event, and a subscriber might be a heating system, or an audio or visual alert system receiving the message and performing an action. Thus the temperature sensor controls the room temperature and the doorbell makes a sound or flashes a light.</p>
<p>The Mosquitto broker is the server mentioned earlier, and the commands <code>mosquitto_pub</code> and <code>mosquitto_sub</code> are examples of a publisher and a subscriber interface.</p>
<p>A Python library <code>paho-mqtt</code> exists to allow scripts to be written to interface with this system. This can be installed thus:</p>
<pre><code>sudo pip install paho-mqtt</code></pre>
<p>Pimoroni provide an example script in their <code>blinkt</code> repository called <a href="https://github.com/pimoroni/blinkt/blob/master/examples/mqtt.py" title="Pimoroni&#39;s mqtt.py script"><code>mqtt.py</code></a> which demonstrates the use of this library.</p>
<h3 id="my-first-version-listener-script">My first version listener script</h3>
<p>I slightly modified the <code>mqtt.py</code> script from Pimoroni to do what I wanted.</p>
<p>I renamed it <a href="hpr2173_blinkt_client.py" title="My modified Blinkt! client"><code>blinkt_client.py</code></a> and modified it to connect to <code>localhost</code> where the Mosquitto broker is running. It is an MQTT subscriber so it needs to spend its time listening for messages. I left the topic as <code>pimoroni/blinkt</code> and used the standard port 1883.</p>
<p>The script is most simply run in the background, so I added a <code>crontab</code> entry which starts it up when the Pi is rebooted:</p>
<pre><code>@reboot $HOME/blinkt_client.py&amp;</code></pre>
<p>This script uses the original Pimoroni design and expects messages of two forms (text extracted from <code>mqtt.py</code>):</p>
<pre><code>rgb,&lt;pixel&gt;,&lt;r&gt;,&lt;g&gt;,&lt;b&gt; - Set a single pixel to an RGB colour. Example: rgb,1,255,0,255
clr - Clear Blinkt!</code></pre>
<p>If the <em>pixel</em> value is * then all pixels are set to the chosen RGB value.</p>
<h3 id="my-first-publisher">My first publisher</h3>
<p>For the first publisher using this system I imported a pair of scripts I had been running on my desktop machine to help with the moderation of comments on the HPR website. This pair consists of a Bash script which is run every 15 minutes from <code>cron</code>, called <a href="" title="Bash script looking for comments and telling the Blinkt!"><code>cronjob_comments</code></a>. It runs a Perl script called <code>scrape_comments</code> which scrapes a page on the HPR website to detect if there are any new comments which require attention<a href="#fn2" class="footnoteRef" id="fnref2"><sup>2</sup></a>. If the Perl script finds anything it tells the Bash script, which uses the following command:</p>
<pre><code>mosquitto_pub -t pimoroni/blinkt -m &quot;rgb,$LED,255,255,0&quot;</code></pre>
<p>This sends a message to the MQTT broker on the same machine with the <code>pimoroni/blinkt</code> topic. The message payload causes the pixel identified by <code>$LED</code> to turn on with a sort of yellowish colour (RGB #FFFF00).</p>
<p>If there is no work to do then the equivalent command is:</p>
<pre><code>mosquitto_pub -t pimoroni/blinkt -m &quot;rgb,$LED,0,0,0&quot;</code></pre>
<p>This turns the pixel off.</p>
<h3 id="the-next-version-listener-script">The next version listener script</h3>
<p>At the time of recording I have not completed this. I want the next version to offer a similar interface but Id also like to be able to blink an LED and change colour briefly and revert to the previous colour. Once I have finished this I might do another HPR show about it.</p>
<h2 id="other-ways-im-using-the-notification-system">Other ways Im using the notification system</h2>
<p>Aside from the local web scraper plus notification already described I have a few other functions running and more planned.</p>
<h3 id="new-hpr-shows">New HPR shows</h3>
<p>I have a web scraper running on my main desktop system, which I described in HPR show # 1971 about my <em>BlinkStick</em>. This lights the <em>BlinkStick</em> red when new shows have been sent in to HPR and alerts me to process the show notes. When the processing is done the checking script (which runs every 30 minutes) notices and clears the light.</p>
<p>I added the <em>Blinkt!</em> display to this script. I installed <em>Mosquitto</em> on the desktop and use the <code>mosquitto_pub</code> command to tell the Zero to make LED 0 red, and turn it off at the same time as the <em>BlinkStick</em>. I will probably stop using the <em>BlinkStick</em> for this task in due course.</p>
<h3 id="mail-notification">Mail notification</h3>
<p>I use <em>Thunderbird</em> to handle my mail on my desktop machine. I have several POP and IMAP mail accounts and use a large number of filters to move incoming mail into folders (or the SPAM bucket). I use a Thunderbird add-on called <a href="https://addons.mozilla.org/en-GB/thunderbird/addon/mailbox-alert/" title="Mailbox Alert add-on for Thunderbird"><em>Mailbox Alert</em></a> to alert me to mail that needs particular attention. This tool can perform various actions when mail arrives in a folder. I use a range of sounds from <em>Freesound.org</em> (many of which I have edited) for several folders.</p>
<p>The <em>Mailbox Alert</em> tool can also run a script. I have written a very simple one which uses <code>mosquitto_pub</code> to make LED 6 green. At the moment this only happens when I get email from my son.</p>
<p>Turning off the mail alert LED is a problem. I want to be able to do this when the message that turned it on has been read. I have written a Perl script which can scan a mail folder (which is a file in <em>mbox</em> format) for unread messages, and I am experimenting with running this from cron. Its not a lightweight process, so I dont want to run it too frequently. This is very much a work in progress.</p>
<h3 id="planned-irc-notifier">Planned IRC notifier</h3>
<p>I use <em>weechat</em> with IRC. This program has a powerful plugin capability. I am looking at the possibility of writing a plugin which will alert me to an IRC message by turning on an LED on the <em>Blinkt!</em>. This is just an idea at the moment.</p>
<h2 id="using-mqtt-with-the-blinkstick">Using MQTT with the <em>BlinkStick</em></h2>
<p>As I have said I installed <em>Mosquitto</em> on my workstation. I wrote another listener (based on an <a href="https://github.com/arvydas/blinkstick-python/wiki/Example%3A-MQTT" title="Blinkstick MQTT page">example</a> on the <em>BlinkStick</em> website) which registers with the local message broker and drives the <em>BlinkStick</em>. I am using this as a development platform for my experiments in Python scripting. It required some work to bring up to date since it was written in 2013.</p>
<p>I am using this set-up in conjunction with the Pi Zero. Every 30 minutes the Zero runs a script under the control of <code>cron</code> which calls <code>mosquitto_pub</code> and tells the <em>BlinkStick</em> listener to flash the LED. This was because the Zero had been disappearing from the home WiFi network and I wanted reassurance that it was still alive!</p>
<h2 id="conclusion">Conclusion</h2>
<p>I have very little interest in the <em>Internet of Things</em> when it requires access to a remote server to turn my lights on. However, Im excited about the possibilities when I have full control over all of the components. I have found that MQTT in the shape of <em>Mosquitto</em> is simple to set up and use and has great potential for building communicating systems.</p>
<p>I have to admit that its slightly eerie if I have to get up in the night and I see the “New HPR comments” LED glowing brightly in the dark! Its also quite cool though.</p>
<p>The various bits of code demonstrated here are not yet available on a Git repository. It is planned to release them at some point in the future.</p>
<p>Around the time I started messing with this project Jezra was also building an <a href="http://www.jezra.net/blog/orb" title="Jezra&#39;s Orb project">MQTT project</a>. He is a much more experienced Python programmer than I am so checking out his blog might be worth your while.</p>
<h2 id="links">Links</h2>
<ul>
<li><a href="https://www.raspberrypi.org/products/pi-zero/">Raspberry Pi Zero</a></li>
<li><a href="https://shop.pimoroni.com/">Pimoroni Ltd</a></li>
<li><a href="https://shop.pimoroni.com/products/blinkt">The <em>Blinkt!</em> add-on from Pimoroni</a></li>
<li><a href="http://learn.pimoroni.com/tutorial/sandyj/getting-started-with-blinkt">Pimoronis documentation “<em>Getting Started with Blinkt!</em></a></li>
<li><a href="https://github.com/pimoroni/blinkt">The GitHub repository for <em>Blinkt!</em></a></li>
<li><a href="http://www.ikea.com/gb/en/catalog/products/70078335/#/40214202">The <em>RIBBA</em> picture frame from IKEA</a></li>
<li><a href="https://inkscape.org/en/"><em>Inkscape</em> vector graphics editor</a></li>
<li><em>MQTT</em> (<em>Message Queuing Telemetry Transport</em>):
<ul>
<li><a href="https://en.wikipedia.org/wiki/MQTT">Wikipedia article on <em>MQTT</em></a></li>
<li><a href="https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern">Wikipedia article on the <em>Publish-subscribe pattern</em></a></li>
</ul></li>
<li><a href="https://github.com/arvydas/blinkstick-python/wiki/Example%3A-MQTT"><em>BlinkStick</em> MQTT page</a></li>
<li><a href="https://addons.mozilla.org/en-GB/thunderbird/addon/mailbox-alert/"><em>Mailbox Alert</em> add-on for <em>Thunderbird</em></a></li>
<li><a href="http://www.jezra.net/blog/orb">Jezras Orb project</a></li>
<li>Resources:
<ul>
<li><a href="hpr2173_blinkt_legends.svg">My Inkscape template “<code>blinkt_legends.svg</code></a></li>
<li><a href="hpr2173_blinkt_client.py">My first primitive listener script “<code>blinkt_client.py</code></a></li>
<li><a href="hpr2173_cronjob_comments">My cron script for checking comments “<code>cronjob_comments</code></a></li>
</ul></li>
</ul>
<!--
vim: syntax=markdown:ts=8:sw=4:ai:et:tw=78:fo=tcqn:fdm=marker
-->
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p>Apparently what is known as <em>hardboard</em> in the UK is called <em>high-density fiberboard</em> in the USA.<a href="#fnref1"></a></p></li>
<li id="fn2"><p>I collect information about the comment status from the <a href="http://hackerpublicradio.org/stats.php">stats page</a><a href="#fnref2"></a></p></li>
</ol>
</section>
</article>
</main>
</div>
</body>
</html>