I'm a big fan of RuuviTags since a long time. The first article I wrote about them is dated back to 2017: RuuviTag with C.H.I.P - BLE - Node-RED - InfluxDB and Grafana. It's seldom that I stick for such a long time with the same gadget, that means something. In the meantime I have over 18 RuuviTags deployed on many places and the setup has changed quite drastically since 2017. In this article I'll show you how I use them today.
Ruuvi Gateway
Finally, a viable BLE gateway exists, the Ruuvi Gateway. I pre-ordered one as soon as it was available and received it a few months ago.
The Ruuvi Gateway is connected to the local Mosquitto MQTT broker, publishing the measurements there. Then RuuviBridge picks them up, processes them and stores the data in an InfluxDB 2 timeseries database. All of this is running on my little Kubernetes K3s machine.
I only own one official Ruuvi Gateway, but I wanted to have the same process on other places, that's why I use some alternatives on different places.
Ruuvi Go Gateway
The companion project to RuuviBridge is ruuvi-go-gateway, which behaves the same as the actual Ruuvi Gateway. It listens for BLE advertisements from RuuviTags and publishes them on a MQTT topic, in the same format as the Ruuvi Gateway. Then again RuuviBridge picks the data up.
I'm running that on a Raspberry Pi Zero W and I'm alway pleased how good the reach of it is. Seems to have a good Bluetooth antenna on it.
ESP32 with ESPHome Gateway
As a third option and as always "because I can" I'm using an ESP32 microcontroller with Esphome to receive advertisements, prepare them in the same format as the Ruuvi Gateway and let it process using RuuviBridge. This was a bit tricky to get working, but in the end it works and looks like that:
mqtt:
broker: mqtt.example.com
id: mqtt_client
esp32_ble_tracker:
on_ble_advertise:
- mac_address: XX:XX:XX:XX:XX:XX
then:
- lambda: |-
const size_t CAPACITY = JSON_ARRAY_SIZE(3);
StaticJsonDocument<CAPACITY> doc;
JsonArray aoa = doc.to<JsonArray>();
std::string preamble = "0201061BFF9904";
std::string rawdata = format_hex(x.get_manufacturer_datas()[0].data); for (auto & c: rawdata) c = toupper(c);
ESP_LOGD("ruuvi_raw", "%s%s", preamble.c_str(), rawdata.c_str());
id(mqtt_client).publish_json("ruuvi/YY:YY:YY:YY:YY:YY/ZZ:ZZ:ZZ:ZZ:ZZ:ZZ", [=](JsonObject root) {
root["gw_mac"] = "YY:YY:YY:YY:YY:YY";
root["rssi"] = x.get_rssi();;
root["aoa"] = aoa;
root["gwts"] = "1641452707";
root["ts"] = "1641452707";
root["data"] = preamble + rawdata;
root["coords"] = "";
});
It's pretty hacky, but hey, it just works.
RuuviTags via LoRaWAN
This had to happen as well, LoRaWAN is something I'm fascinated in as well. Thanks to an already existing little project, I was able to send RuuviTag measurements over LoRaWAN with a LoPy microcontroller to The Things Network.
Outlook
The next thing to deploy is a RuuviTag Pro on my camper. And I want to further work on the LoRaWAN idea, which would allow me to deploy RuuviTags in more remote places, powered by the solar cells.
One last thing
My Grafana is open, feel free to have a look around: graphs.tbrnt.ch.