My RuuviTag Setup in 2022

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:

  id: mqtt_client
    - mac_address: XX:XX:XX:XX:XX:XX
        - lambda: |-
            const size_t CAPACITY = JSON_ARRAY_SIZE(3);
            StaticJsonDocument<CAPACITY> doc;
            JsonArray aoa =<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.


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:

You've successfully subscribed to Tobias Brunner aka tobru
Great! Next, complete checkout to get full access to all premium content.
Error! Could not sign up. invalid link.
Welcome back! You've successfully signed in.
Error! Could not sign in. Please try again.
Success! Your account is fully activated, you now have access to all content.
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.