Jetzt wird es langsam interessant, denn nun sollen Daten aus dem MQTT zum Ansteuern von LEDs und dem LCD-Display dienen und Taster am Arduino sollen entsprechend im MQTT signalisiert werden. Basierend auf meinen vorherigen Versuchen habe ich also in Python mit smbus und dem „Display-Treiber“ begonnen ein Schnittstellen-Modul zu schreiben. Für die Kommunikation mit dem MQTT-Broker kommt Bibliothek paho-mqtt zum Einsatz.
Anpassung der lcddisplay.py und i2c_lib.py
Da es mich schon zu Beginn störte, dass die Display-Beleuchtung immer eingeschaltet ist, habe ich mir mal den „LCD-Treiber“ (lcddriver.py) genauer angeschaut. Dort werden im Wesentlichen Byte-Konstanten definiert und es folgt eine Umsetzung der Daten in Byte-Folgen und die Adressierung für das Display.
Dieses Skript greift wiederum auf ein weiteres Skript im Paket zu (i2c_lib.py), dass eine Handvoll smbus-Funktionen in einer Klasse wrappt und die Device-Adresse des Displays festlegt. Erst hatte ich überlegt das Skript komplett rauszuwerfen, habe mich dann aber dazu entschlossen diesen Wrapper zu erweitern, um Fehler bei der I2C-Kommunikation abzufangen und Retrys und Timeouts zu realisieren. Mit ein paar weiteren Anpassungen für die Adressierung beliebiger Slaves ist es nun mein I2C-Busmaster geworden.
Im Display-Script habe ich auch noch ein paar Dinge umgebaut, so dass nun neben der Adressierung aufgrund der Änderung im I2C-Wrapper auch die Hintergrundbeleuchtung gesteuert werden kann.
Abfragen der Eingänge, setzen der Ausgänge und Anzeigen auf dem LCD
Nachdem die Verbindung zu den beiden I2C-Slaves (Display und Arduino) steht, wird eine LED angesteuert, wenn das Skript in der Main-Loop angekommen ist und auf dem Display erstmal die Uhrzeit angezeigt. Mit erstaunlich wenigen Befehlen werden zyklisch die Eingänge am Arduino abgefragt und in lokale Variablen geschrieben.
Den Broker kontaktieren
Mit dem Paket paho-mqtt gestaltet sich auch die Kommunikation mit dem MQTT-Broker recht einfach. Ich lasse mein Schnittstellen-Skript eine Nachricht an den Broker senden, wenn es Einsatzbereit ist und mache einen subscribe auf ein paar Topics, die derzeit von der Node-RED-Pseudo-BMZ mit Daten befüllt werden.
Im ersten Schritt lasse ich eine LED als Alarmsignal leuchten und schreibe die vom MQTT kommende Alarmmeldung aufs Display. Im Ruhezustand erzeugt die Node-RED-BMZ eine Ausgabe der aktuellen Uhrzeit.
Im zweiten Schritt sende ich Nachrichten an den Broker, wenn bestimmte Tasten am Arduino gedrückt werden. Die weitere Verarbeitung läuft dann allein im Node-RED.
Test mit MCP23017
Nachdem ich mich bei meiner Kommunikation zwischen Pi und Arduino an der Ansteuerung des MCP23017 orientiert habe, war es nun Zeit den Arduino eben durch den Portexpander zu ersetzen. Im Python musste ich noch den Befehl zur Initialisierung der Ein-Ausgänge hinzufügen, da ich diese im Arduino hardcoded hatten.
Nach Umstecken des I2C, der LEDs und Taster auf den MCP und Neustart des Skriptes funktionierte dieser sofort wie erwartet. Damit war die I2C-Schnittstelle für Display und ein paar erste LEDs und Taster funktional. Eine weitere Ausdehnung auf alle LEDs und Taster am FBF und FAT macht ohne entsprechende Hardware noch keinen Sinn, aber wo ein Portexpander funktioniert, funktionieren auch zwei 😉
Das Interface-Skript (nodebma_interface.py)
Das soeben gebaute Python-Interface zwischen MQTT und I2C kommt nun in eine screen-Session und wird als systemd-Service angelegt.
Da ich ein Freund von Textausgaben auf der Konsole bin, nutze ich gerne screen, um bei Bedarf einfach mal schauen zu können, was mein Skript gerade so macht. Natürlich könnte ich auch ein Logging in eine Datei machen – vielleicht baue ich das noch mal um.
und wie immer noch ein Link dazu
paho-mqtt für Python | Webseite