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)