Python und MQTT

Wie jeder weiss ist IOT (Internet of Things) das neue heisse Ding. Jeder Kuehlschrank muss smart werden und da muss man natuerlich mithalten. Vor einiger Zeit habe ich mir ein paar ESP Entwicklerboards gekauft um damit zu spielen und basteln. In der naechsten Zeit moechte ich ein bisschen dokumentieren, was man alles machen kann.

Das Geraet mit dem ich arbeite ist dieses Thermometer. Eine Voraussetzung ist ein funktionierender MQTT Server, was ich hier aber nicht erklaeren werde.

Paho-MQTT

Der erste Schritt ist das lesen von Nachrichten von dem MQTT Server. Eine gute Bibliothek ist Paho MQTT, die sehr viel vereinfacht.

virtualenv venv
source venv/bin/activate
pip install paho-mqtt

Das einfachste Beispiel um Nachrichten auszugeben ist hier erklaert:

#!/usr/bin/env python

import paho.mqtt.client as mqtt

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    #client.subscribe("#") # All messages
    client.subscribe("your/workgroup/")

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.payload))

client = mqtt.Client()
client.username_pw_set('username', 'password')
client.on_connect = on_connect
client.on_message = on_message

client.connect("server_ip", 1883, 60)

# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()

Mit der Funktion kann man schon gut pruefen ob alles funktioniert. Wenn man mit den Rohdaten arbeiten will ist das etwas umstaendlich.

Eine Idee die ich hatte war alles in einen Thread zu packen und die Messwerte in eine Queue zu speichern. Die Callback Funktion on_message() muss dann alle Werte in der Queue ablegen:

import queue

temperature_queue = queue.Queue()

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    temperature_queue.put(msg)

Der Endlosloop wird in einem Thread aufgemacht:

import threading

temperature_thread = threading.Thread(target=client.loop_forever)
temperature_thread.start()

Die Werte kann man dann aus der Queue auslesen:

import json

message = temperature_queue.get()
payload = message.payload.decode()
temperature = json.loads(payload)['temperature']
print(temperature)

Wenn man jetzt schon die Werte hat, koennte man sie auf einer HTML Seite rendern oder als API zur Verfuegung stellen. Darueber werde ich in einem anderen Blogpost schreiben.