Transmit weather stats from DHT22 using MQTT on micropython

In my previous article about DHT22 sensor, I had used arduino based programming to collect and transmit weather stats over MQTT. But that time I was wondering, how can I make it flexible by having WiFi, sensor and MQTT parameters configurable.

Now, with micropython, I can prepare a simple json config file having all parameters and use them in main.py code.

For better understanding, let us pick a sensor, say DHT22 weather sensor. We will read WiFi SSID, password, sensor pin number and MQTT broker IP, user, pass, port from following config.json file.


{
   "wifi": { "username": "SSID", "password": "WiFi Password" },
   "mqtt": { "broker": "Broker IP host", "mqttuser": "username", "mqttpass": "password", "mqttport": port, "mqttclient": "Your Client ID name"},
   "sensors": {
                "dht22": { "topic": "weather", "Pin": 4, "wait": 600 }
              },
   "location": {"city": "ggn"}
}

Above config file is read in main.py and values are parsed for various parameters. Here is the code of main.py


import machine
import json
import time

with open('config.json') as cfg:
  cfgdata = json.load(cfg)

def connectWiFi():
    import network
    username = cfgdata.get('wifi').get('username')
    password = cfgdata.get('wifi').get('password')

    sta_if = network.WLAN(network.STA_IF)
    if not sta_if.isconnected():
        print('connecting to network...')
        sta_if.active(True)
        sta_if.connect(username, password)
        while not sta_if.isconnected():
            pass
    print('network config:', sta_if.ifconfig())

def mqttpublish(topic, message):
    from umqtt.simple import MQTTClient
    broker = cfgdata.get('mqtt').get('broker')
    mqttuser = cfgdata.get('mqtt').get('mqttuser')
    mqttpass = cfgdata.get('mqtt').get('mqttpass')
    mqttport = cfgdata.get('mqtt').get('mqttport')
    mqttclientID = cfgdata.get('mqtt').get('mqttclient')
    client = MQTTClient(mqttclientID, broker, port=mqttport, user=mqttuser, password=mqttpass)
    client.connect()
    print("sending....", topic, json.dumps(message))
    client.publish(topic, json.dumps(message))

def dht22(location):
    import dht
    DHTPin = cfgdata.get('sensors').get('dht22').get('Pin')
    DHTtopic = cfgdata.get('sensors').get('dht22').get('topic')
    DHTdata = dht.DHT22(machine.Pin(DHTPin))
    DHTdata.measure()
    temp, humidity = DHTdata.temperature(), DHTdata.humidity()
    #weatherdata = "temperature": temp, "humidity": humidity, "location": location}
    weatherdata = {"tags": {"location": location}, "fields": {"temperature": temp, "humidity": humidity}}
    wait = cfgdata.get('sensors').get('dht22').get('wait')
    return(DHTtopic, weatherdata, wait)

while True:
    location = cfgdata.get('location').get('city')
    connectWiFi()
    topic, message, wait = dht22(location)
    mqttpublish(topic, message)
    time.sleep(wait)

Upload config.json and main.py on ESP8266 board


ampy --port /dev/ttyUSB0 --baud 115200 put main.py
ampy --port /dev/ttyUSB0 --baud 115200 put config.json

Reboot ESP8266 controller and to witness results, use any MQTT subscriber like following. Publishing data in json will simplify parsing job at subscriber end.


 mosquitto_sub -h 192.168.0.23 -p 1883 -t "weather" -u iotuser -P iotpass
{"humidity": 78.9, "temperature": 21.9, "location": "ggn"}
{"humidity": 78.7, "temperature": 21.8, "location": "ggn"}