-or- Learning to listen to your Arduinos...
I'm an Arduino enthusiast. By that I mean I freakin' love Arduinos. There is so much you can do with them. You want to convert an old PS/2 keyboard over to USB? The ProMicro has you covered. You want a cheap temperature sensor? The nano paired with a cheap temp probe can do that. You want to turn something on and off? Swap that temp probe out for an inexpensive relay and you're golden.
Easy enough, but how do you get those temperature readings off of that sensor? Should you leave your laptop plugged into the controller and just walk by occasionally and check it? That doesn't seem very useful. What if you're on vacation and need to turn off that lamp you accidentally left on? What you need is network communication.
Most Arduinos (there are exceptions, we'll look at those in a minute) can't really talk on the same WiFi network that your laptop gets endless Facebook feeds from. In fact, by default, they can only speak over the serial lines on pins 0 and 1. We can still use that though. The NRF24L01+ is a very inexpensive radio that can enable an Arduino to talk to other Arduinos over a mesh network. A sort of IoAT (Internet of Arduino Things? I'm still working on the name part.) All in all the mesh network can handle 3,125 nodes on a single channel. I'd like to see WiFi do that!
It does this by using a tree topology where you have one "base" and up to 5 leaves, each of those five leaves can have 5 leaves and so on until you get 5 total layers deep. This allows namespace for exactly 3,125 devices. The creator of the library explains it well in the documentation.
All this is well and good, but my laptop can't speak rf24. Neither can yours. We need to translate that into something a little more universal. To get a good overview, I'll explain my use case. There are countless use cases for this setup but this one is mine.
- Motion/Temperature sensor in kitchen monitoring freezer temps and room activity.
- HomeAssistant reacting to this information in meaningful ways: adjusting lights and sending alerts.
The problem is that HomeAssistant runs on a standard server, on a standard network. It doesn't speak rf24. The Arduino has no LAN connection and only speaks rf24. We need a translator. We need more than that. We need a translator and a way to send these translated messages back and forth.
What we need is a pub/sub. No, that isn't some beer of the month club. Publish/Subscribe, very creative, I know. A pub/sub simply acts as a community bulletin board. Some things post to it, other things can read from it, most things do both. It's really very social; a sort of Twitter for our IoAT (that name is growing on me). I use Mosquitto (MQTT Client/Broker) for this purpose because it's free, and binaries are available for pretty much any platform you can think of making it really simple to install. Like
sudo apt-get install mosquitto kinda simple. HomeAssistant integrates with MQTT out of the box so that side is good, that puts us back to the whole rf24 mess.
So to really simplify it, the Arduinos live on the rf24 network while the MQTT broker lives on the LAN. Additionally, the two protocols are not directly compatible. Clearly, the only solution is some sort of super-Arduino that can talk on the LAN and rf24, and speaks both protocols. Enter the NodeMCU. The NodeMCU is a special kind of Arduino, no doubt. In addition to all the normal Arduino goodness, it has a WiFi card strapped to its back. More accurately, it is a WiFi card with a simplified Arduino on board. Chicken? Egg? I'm not sure anymore. It does get us where we need to go though. We can teach it to speak both protocols and give it hardware for both networks. So our new network map looks something like this:
Temp/Motion Sensor --rf24--> NodeMCU --WiFi--> MQTT Broker --LAN--> HomeAssistant
It works in reverse as well, HomeAssistant can send a command to turn on/off a relay through the MQTT broker to the NodeMCU which hands it off to the responsible Arduino controlling the relay. Life is good.