This article is about monitoring some IoT devices (e.g. a CO2 sensor) with a combination of [Mosquitto](https://mosquitto.org/) (a MQTT broker), [Telegraf](https://www.influxdata.com/time-series-platform/telegraf/) (a metric collector), [InfluxDB](https://www.influxdata.com/) (a time-series database) and [Grafana](grafana.com/) (for displaying everything nicely).
All mentioned services should run on a server that can be reached from the monitoring device(s) and your PC where you want to check the data. We will use MASH (see below) to deploy the services.
In the end this will enable you to get to something like this:
![A screenshot of a grafana dashboard. It shows one panel with temperature and humindity values over an hour, one panel showing CO2 data and one showing energy consumption](/uploads/monitoring-iot-devices-with-MASH/grafana_screenshot1.png)
While writing, I decided to split this into two parts. Part 1 will set up our server infrastructure, Part 2 will show how to integrate some real sensors.
MASH is short for "Mother of all self-hosting". It's a collection of [ansible](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/ansible.md) roles, tied together by a playbook that can help deploy and maintain a large number of services. It was inspired by the [matrix-docker-ansible-deploy](https://github.com/spantaleev/matrix-docker-ansible-deploy/) follows the same philosophy and is maintained partly by the same people.
MASH includes services like
* Nextcloud
* Authentik
* Gitea
* Peertube
* Funkwhale
and more than 50 others at time of writing this blogpost ([List of all supported services](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md)).
The motivation for this playbook is to have all services run in docker, be as configurable as possible, while maintaining easy upgrades and reproducible deployments.
In the end we will have a IoT device that sends data to a MQTT topic on the MQTT broker Mosquitto. Telegraf will listen to this topic and write this into InfluxDB. When you want to have a look at the data, you can access Grafan which will query InfluxDB.
By following this guide we will set up some services which will be reachable from via web interface (Grafana and InfluxDB) while others will not (Telegraf, Mosquitto). We will set a domain name for the server itself, one for Grafana and one for InfluxDB. This allows you to move services more easily. Feel free to adjust the setup to your needs (but don't forget to change tha `_hostname` variables accordingly later).
Setting up the services will require three steps. The first will set up the general server with Mosquitto and Influxdb. Then we configure mosquitto and influxdb and use this to set up Telegraf and Grafana.
Before installing and each time you update the playbook in the future, you will need to update the Ansible roles in this playbook by running `just roles`. `just roles` is a shortcut to download the latest Ansible roles. If you don't have `just`, you can also manually run the `roles` commands seen in the `justfile` (this gets tedious fast).
To install you should can `just install-all`. That's it.
Congratulations! You installed your first services and can now visit influxdb.example.com and login with the credentials you set above!
## Configuring Mosquitto and InfluxDB
**Mosquitto**
To configure mosquitto you only need to set up users. I would recommend to set up seperate users for telegraf and your IoT devices as you might want to restrict the IoT users permissions (not covered here).
Setting up mosquitto users can be done `just run-tags mosquitto-add-user --extra-vars=username=<username> --extra-vars=password=<password>`. For the setting to take effect, you must restart the container. To do that you can use `just start-group mosquitto`.
**InfluxDB**
Log in on influxdb.example.com with the credentials you configured in your `vars.yml`.
We will now create a configuration that will automatically be read by telegraf.
Got to `Load Data -> Telegraf` and press `Create configuration`. Choose the bucket monitoring and search for the MQTT consumer as data source.
Add the following replace the `[[inputs.mqtt_consumer]]` with the following configuration (and make sure that you replace the example values).
Now got to `Setup Instructions` and copy the `INFLUX_TOKEN`. It will only show once! Also copy the config URL. You will need both in the following step.
## Setting up Telegraf and Grafana
You now have everything for the last step: Setting up Telegraf and grafana. We did not do this in the first step as wee needed the access tokes/configuration link which we have now. Therefore you should now add two new sections to your `vars.yml`.
This will fake a temperature sensor and publish the results to the MQTT topic sensors/temperature. To make sure the MQTT broker works correctly you can subscribe with
Now let's display this data in Grafana. Add a new dashboard and then use `Add->Visualization`.
![Screenshot of the grafana interface with numbers indicating where to click for the following sentence](/uploads/monitoring-iot-devices-with-MASH/grafana_new_query.jpeg)
In the panel select InfluxDB as datasource (1+2) put in the folowing query (3).
I know this seems like a lot of effort to get a few numbers to display a few numbers nicely. On the other hands, once set up this setup can do a lot of stuff, from monitoring, to alerting. Upgrades should be taken care of by MASH, check out how to do that [here](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/maintenance-upgrading-services.md). Also setting up more services is a breeze. Either check the [list of existing services](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md), or add a new role to the playbook. If you don't know how, I am happy to help!