There are plenty of tutorials on installing and running an IoT server stack on Raspberry Pi, but why not on my old Fujitsu Futro S900. With 4 GB RAM and a 120 GB SSD inside it should do it easily.
Got some data? Well, you see, it needs a way to be transported, stored and displayed. For each step, you need a specific solution.
Step 1: Collecting and Sending Data
I'm using an ESP32 microcontroller, connected with a Bosch BME280 to gather temperature, humidity and atmospheric pressure. At a specific interval, all the readings are transmitted to a message broker (Mosquitto) using MQTT.
Step 2: Storing the Data
Now we need a way to read the MQTT messages from the broker and store them in a database. Enter Node-Red. A Node-Red flow is listening for these messages and stores them in a time series database: InfluxDB.
Step 3: Display & Interpret the Data
Grafana is a multi-platform open source analytics and interactive visualization web application. It provides charts, graphs, and alerts for the web when connected to supported data sources. Using the InfluxDB data sources, populated by Node-Red, we can display some nice graphs, and finally "see" the data.
Docker IoT Server Stack
As for everything server related, I'm using a linux base: Ubuntu Server. For the rest, the setup was a breeze using the docker-compose builder created by Graham Garner.
After everything was installed and configured, the data is now nicely presented by Grafana in a dashboard.
Things to keep in mind
The amount of data collected from devices can be huge. So, depending on your needs, you can implement retention policies in InfluxDB. For example, I'm injecting weather data with a 10 minutes resolution. But I think that after a week I will only need to have hourly values. And keep it for a period of one year. For this, retention policies should be implemented, along a "continuous query" that will downsample the data. Here's for example what I'm using for my weather database:
CREATE RETENTION POLICY "one_week" ON "weather" DURATION 7d REPLICATION 1 DEFAULT CREATE RETENTION POLICY "a_year" ON "weather" DURATION 52w REPLICATION 1 CREATE CONTINUOUS QUERY "cq_1h" ON "weather" BEGIN SELECT mean("tempc") AS "mean_temperature", mean("humidity") AS "mean_humidity", mean("pressure") AS "mean_pressure" INTO "a_year"."downsampled_data" FROM "weather" GROUP BY time(1h) END
As always: have fun building things!