In part 1, I was building a light sensor, but now it’s morphed into a multi-sensor
Running against my recent terrible Aliexpress streak, the remaining bits actually arrived. Here’s the items I’ve used to build a great little multi-sensor that pumps data into Home Assistant:
|Main Board||Wemos Mini D1 (probably a clone). ESP8266 chip with integrated Wifi||US$3.30|
|Luminosity Sensor||TLS2561 I²C module||US$1.11|
|Temp/Pressure/Humidity Sensor||Bosch BME280 I²C module||US$3.97|
It’s a little surprising that the triple sensor is the most expensive part of the whole thing, but Bosch make nice electronics, and the BME280 is the current pick of the crop for these sorts of sensors. Probably total overkill for my use case. If you don’t care about air pressure and you wanted to save a dollar* you could get away with a DHT22.
*I bet you complain about $1.99 iPhone games too.
First: procrastinate. I finally managed to find a use for this little multi-storage case I had lying around. Because it was cheaper to buy components in 5s and 10s, I now have a veritable caché of components. I just wish I had a label printer.
It’s ok, I know you want to be me.
Here’s what the three components look like plugged together:
It’s nice that the pinouts for the TLS2561 and the BME280 line up with each other, so they can share columns on the breadboard and hook up tidily.
On the Wemos board, the pinouts connect like this:
|ESP8266 pin||Labelled board pin||I²C Usage|
If you wire everything up like that, then the libraries I reference will work fine. In fact anything that uses
Wire.h to talk I2C will work without having to redefine the pins used.
I’m using Platformio via the Atom editor to build code for this device. Platformio’s library management makes it almost trivially simple to talk to these devices. A quick search turned up several libraries for each of the sensors. This is what I used:
Both libraries have working example code that I used to prove that everything was wired up properly and spitting out debug data via the serial monitor. There’s some optional intricacies regarding configuration of the sensors for optimal accuracy/power balance, but the default settings seemed to work perfectly fine for me.
I would note though that I didn’t have much luck with the Adafruit sensor libraries. They worked fine on Arduino, but failed to work for me on the ESP8266. Probably caused by different pin configurations that a bit of debugging would fix, but the libraries above worked perfectly well for me, so being the lazy person I am, I used them instead.
There’s a few ways to do get data from Internet of Shit devices, but the canonical approach for plumbing IoT things together is MQTT. If you’ve never heard of it, don’t worry: neither had I until I started exploring home automation. MQTT is a nice, compact publish-subscribe protocol (I believe the kids call it pubsub), most commonly implemented using Mosquitto running on Linux.
You can publish data to MQTT by simply spitting messages at “topics”. Topics don’t need to exist, you can just create them on the fly. For example you can send the temperature value
22.4 from the command line into MQTT like this:
mosquitto_pub -h my.mqtt.servername -t 'some/random/topic/temperature' -m '22.4'
If you’re using Home Assistant, it comes with a built-in MQTT server, which is perfectly nice. However, because I’m a masochistic completionist, I’ve got a
docker-compose system already running a bunch of important stuff (ahem, home videos) on my own server, so it was straightforward to set up a “proper” Mosquitto server using the official Eclipse container:
Ingesting Data into Home Assistant
This bit is super easy (I keep saying stuff is easy, but this part really is). Home Assistant has a built-in MQTT component that can create
switches from MQTT topics.
Given the above example, where we pushed a value into
some/random/topic/temperature, we could turn that into a temperature
sensor in Home Assistant with a teeny bit of yaml:
From there, Home Assistant takes care of keeping track of any new values that appear on that topic in MQTT. It’ll create nice graphs, and you can drive automation off the values of this sensor. All pretty neat really. So the trick is to get the ESP8266 to publish data to MQTT.
You could write code in your sketch to make direct HTTP calls to MQTT containing the relevant topics and data, but that would be dumb. Ask yourself the important questions, like: what are you going to do when you have a fleet of 40 multi-sensors reporting humidity at 10 second intervals from every cupboard in your home? You’re not building home automation for ants.
Homie is a really great library that you can use with Platformio to quickly create configurable firmware to run on your ESP8266. It has some of the best documentation I’ve seen for an open source IoT project, and a well-documented “convention” that it adheres to.
One gotcha: don’t use the Platformio library manager to install Homie, because (as of writing) you’ll end up with the 1.5.0 branch. Instead download the zip of the
develop branch and install that. The 2.0.0 branch is significantly improved from 1.5.0. I’m sure the 2.0.0 branch will be available to install directly sometime, but for now the zip is the only way to get it.
With Homie running on your ESP8266, you can send custom configuration json over the air (yes, you heard me: through the goddamn air). This means you can load the same code on every one of your 40 cupboard humidity sensors, then send custom config to give each one a unique name and the wifi access details. Neat! Now you’re going to have to assign an entire new DHCP subnet for your homies.
If you’ve done any Arduino/ESP “hello world” code, then you can use Homie. It introduces a
setupHandler() and a
loopHandler() where you write your code, and pretty much all I did was to lift the sample code for the TSL2561 and BME280 libraries, create some
HomieNode objects, and set their values in the
loopHandler(). The result, when I request the
homie topic from my MQTT server looks like this:
Sweet as! You can see amongst all that ceremony, there are a few lines that look exactly like what Home Assistant is looking for:
Hooking it all up, I end up with some sweet, sweet sensor data rolling into Home Assistant.
Tune in next time when I annoy the shit out of my family by automating the lights based on luminosity data.
My Terrible Code
Don’t copy this.