---
# System prepended metadata

title: 'Temp&humidity w/ TIG-stack + MQTT-broker @ docker compose '
tags: ['Student: Robin kron @ rk222vm']

---

This is a basic temperature and humidity device connected to a MQTT-server running in the same docker compose container as the TIG-stack.

The MQTT-server recieves measurements from the device, sends it to telegraf, telegraf sends it to influx and finally, grafana uses the data from influx to visualise it in a graph.


Time estimate: 24h


# Objective
I choose this project with the only reason being it included many new technical aspects on the software point of view, it doesnt really fill any real-use-purpose for me, this project was more about to get a good overview of a fullstack IoT project.


# Material

| Product            | Price |
|:------- |:-----:   |
|Rasberry Pi Pico W  |109 SEK |
|DHT11               |49 SEK  |
|Breadboard          |49 SEK  |
|Jumperwires (30pcs) |49 SEK  |
|**Total**           |**256 SEK**|


Not a complicated set of hardware.
A Pico W mounted to the breadboard, some jumpercables to connect to the DHT11 sensor. 


# Complete setup tutorial

## Flashing the Pico W
To make the Pico W ready for use we have to flash it `(Install a firmware)`.

1. Connect the micro-USB to the Pico
2. Press & hold the BOOTSEL-button mounted on top of the Pico 
3. While still holding the BOOTSEL-button, connect the other end of the usb to your computer and then release the button
4. Open up the device `RPI-RP2`
5. Go to [this](https://micropython.org/resources/firmware/rp2-pico-w-20230426-v1.20.0.uf2) page and download the latest version of firmware
6. Drag the file in to the RPI-RP2 device. `the window should close`
7. Done :tada: 

## IDE & Extension

Now lets cover the steps to setup the work environment with VScode, Node.js & Pymakr extension

1. Download and install [VScode](https://code.visualstudio.com/download)
2. Download and install [Node.js](https://nodejs.org/en)
3. Start VScode and head to the extensions tab on the left, search for Pymakr and click install.
![](https://hackmd.io/_uploads/SJQjdTCdh.jpg)
4. There should now be a new tab in left sidemenu, click on it and then `Create project` 
![](https://hackmd.io/_uploads/SkvbopAu3.jpg)
5. Create a new folder and click `Use this folder`.
6. A new window in the top should appear asking for project name, enter preferred name
7. Click `empty`
8. Select your Pico W device
9. Done :tada: 


## Uploading code to Pico

1. Click the Lightning icon to connect the Pico
2. Click the cloud with an up-arrow in it
3. Click on `...` to the rigth of the other icons
4. Select `Hard reset device` and then press the lightningicon again to connect the device. the device should automaticly run the program.




# Putting everything together
The setup is as basic as it gets

![](https://hackmd.io/_uploads/SkSJK00O2.jpg)

# Platform

The plattform is based on the TIG-stack, and a local MQTT-broker, they are all included in the docker compose setup and can therefore is very handy to start up.

Lets go through the different parts of this stack.

## Telegraf
Telegraf is the data collector and processor, Telegraf connects to the broker and subscribes to a topic. When it gets a message it formats it to preferred format and sends it to the database `Influxdb`
## Influxdb
Influxdb is a timeseries database, wich means it it specialized to store and manage timestamped data and 
continuously changing data, wich makes this a perfect choise for logging and comparing data based on time.
## Grafana
Grafana is a webapplication for data monitoring, with Grafana you can setup advanced data-visualization graphs and webhooks based on the data it monitors.
## Eclipse-mosquitto
Eclipse-mosquitto is a open-source message broker that uses the MQTT-protocol, making it a strong candidate for the IoT ecosystem

## Stack visualization

![](https://hackmd.io/_uploads/S1eZb-yK2.jpg)


# The code
```mermaid
graph LR

Connect-wifi --> Connect-MQTT --> Measuring --> Sending
```

## Connecting to wifi
Some improvements can be made here, like a timeout functionality on the connect attempts, or a limit amount of retries.
```python=1
from credentials import wifi
import network

def connectWifi():
    from time import sleep
    wlan = network.WLAN(network.STA_IF)
    
    if not wlan.isconnected():
        print('connecting to network...')
        wlan.active(True)
        wlan.connect(wifi["SSID"], wifi["PW"])
        print('Waiting for connection...', end='')
    
        while not wlan.isconnected() and wlan.status() >= 0:
            print('.', end='')
            sleep(1)
  
    ip = wlan.ifconfig()[0]
    print('\nConnected on {}'.format(ip))

try:
    connectWifi()
except Exception as err:
    print('Could not connect to {}. Error: {}'
          .format(wifi["SSID"], err))

```

## Connecting to MQTT-broker "telegraf.conf"
```python=1
[agent]
flush_interval = "15s"
interval = "15s"

[[inputs.mqtt_consumer]]
name_override = "mqtt-broker"
servers = ["mqtt://172.19.0.3:1883"]
qos = 0
connection_timeout = "30s"
topics = [ "devices" ]
client_id = "mosquitto"
data_format = "json"


[[outputs.influxdb]]
database = "influxdb"
urls = [ "http://influxdb:8086" ]
username = "influx"
password = "influx"

```

:::warning
:warning:

Since the MQTT-broker is running on the same container as the TIG-stack you need to get the ip from the MQTT-container within the docker-compose network.

Inspect docker compose network:
>$ docker network inspect <project-name_network-name> 
:::


## Main function
Here we define the client and using a imported function ive made to handle and displaying connection to the MQTT-broker `mqttConnect()` at line 17 returns a boolean to be used in the while conditional.
```python=1
import dht
import ubinascii
from time import sleep
import json
from machine import Pin, unique_id
from umqttsimple import MQTTClient
from mqttConnect import mqttConnect

def main():

    tempSensor = dht.DHT11(Pin(0))

    CLIENT_ID = ubinascii.hexlify('Temp-and-humid')
    MQTT_IP = '192.168.1.6'

    mqttClient = MQTTClient(CLIENT_ID, MQTT_IP, keepalive=60)
    connectedToBroker = mqttConnect(mqttClient)

    while connectedToBroker:

        try:
            tempSensor.measure()
            temperature = tempSensor.temperature()
            humidity = tempSensor.humidity()
            print('Temperature is {} degrees Celsius and Humidity is {}%'
                  .format(temperature, humidity))

            payload = {
                "device": CLIENT_ID,
                "Temp": temperature,
                "Humid":humidity,
                }
            mqttClient.publish(b'devices', json.dumps(payload))
            sleep(3)

        except KeyboardInterrupt as e:
            print('Interrupted \n Error: ', e)

if __name__ == '__main__':
    main()   

```
:::info
:information_source: Tips regarding ip here, 0.0.0.0/localhost wont work, you will have to get the networkadapter ip 

windows > cmd
> $ ipconfig /all

It has to be the same as you are using on your computer

:::

## mqttConnect()
This is the function used in the main() at line 17. It simply gives feedback on successful connection and attempts to connect 3 times before returning false.
```python=1
def mqttConnect(mqttClient):
    print('Connecting to MQTT server')
    for i in range(3):
        try:
            mqttClient.connect()
            print('connected to MQTT broker')
            return True
        
        except Exception as e:
            if i < 3:
                print('Connection failed, retrying: {}/3'.format(i+1))
            else:
                print('Connection failed on all attempts.. \n Error: ', e)
                return False
```



# Transmitting the data / connectivity

Im using wifi for simplicity in this case and the data from the sensor is being sent every 3seconds as a json object that has been serialized to bytes with `json.dumps()`, serialized to bytes because i use the mqtt-protocol.

this gets sent to the MQTT-broker to the topic `devices` and data is stored and queried with reference with the client-name

# Presenting the data
Grafana had plenty of options data visualization, i settled with a simple temp-meter and a graph showing both temp and humidity in the same graph.The the database gets fresh data every 15seconds.


here you can clearly see the two times i melted the sensor protection with my lighter... 2times...

![](https://hackmd.io/_uploads/S1-Q27xt2.jpg)



# Finalizing the design
I learned so much doing this project and overall i think i the endresult is acceptable, there is some parts i wish i had the time to learn and improve, like authentication in the MQTT-broker and webhooks for example. 

I spent quite alot of time trying to integrate the MQTT-broker in the same docker compose setup, wich lead me to researching of the `docker network`, so i learned alot of networking overall doing that, since my knowledge of networks was about 0% from the start.

This is the overview of my workspace with the majority of the project in the picture, its been fun, and messy.

![](https://hackmd.io/_uploads/H11exNeF2.jpg)
