[Tutorial] Daten zwischen mehreren Raspis live austauschen und in einem Cockpit anzeigen

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Wenn Ihr mir einige Tage Zeit gebt, dann entsteht hier ein Tutorial, wie man (Meß-) Daten verschiedener Raspberry Pis über Netzwerk in Ectzeit austauscht, Aktionen auslöen kann und das ganze noch in einem schönen Cockpit darstellen kann, sowie natuerlich auch damit Stuern kann.

    Das gibt es alles schon unter den Stichworten MQTT und Node Red. Ich möchte aber einen etwas anderen Weg aufzeigen, der schneller und zuverlässiger sein sollte. Hierzu wird das Cockpit nicht(!) in einem Browser dargestellt, sondern in einem Fenster einer Applikation, die sogenannte Dashboards darstellen kann.

    Zusätzlich kann man natuerlich auch andere Darstellungs-App verwenden, insbesondere auch auf einem Android-Smartphone. Hierauf wollte ich hier auch eingehen.

    Was wird benötigt?

    1. einen oder besser meherer Raspberry Pis im selben (lokalen) Netzwerk,

    2. gerne meherer MQTT Kompatible Smart-Home Komponenten

    3. einen Raspberry Pi oder Linux PC mit angeschlossenem Bildschirm und Maus.

    Voraussetzungen

    1. Raspbian version ab "stretch". Wer einen älteren Pi hat, (so wie ich auch "weezy") bei dem geht es auch, aber es treten zusatzschwierigkeiten auf, auf die ich hier im Einzelnen nicht eingehen will. Auf den aktuelleren Modellen sollte alles genau so wie hier beschrieben laufen.

    2. Etwas Erfahrung mit dem compilieren und installieren von Programmen, die man von github bekommt.

    Etwas zum Konzept

    Das ganze soll so funktionieren:

    1. Ein Raspberry Pi muss als Zentrale fungieren, Auf ihm wird ein sogenannter MQTT broker installiert. Der läuft dann dort permanent.

    2. Ein (anderer oder derselbe) Raspberry Pi oder linux Laptop wird für die Cockpit-Darstellung benötigt. Dort sollte eine Maus und ein Bildschirm dran sein.

    3. Weitere Raspberry Pis (oder auch Smat-Home geräte) im selben Netzwerk werden daten liefern. Z.B von einem Temperatursensor, Feinstaubsensor oder

    was auch immer ihr mit de Raspberry Pis bereits jetzt schon messt. Ausserdem kann man auf den Raspberry Pis empfänger für Kommandos installieren, die Aktionen auslösen können, also GPIO-Ausgänge schalten, pythn scripte starten oder was auch immer. Außerdem, und das finde ich besonders spannend, kann man verteilt auf einen oder beliebig viele Raspberry Pis sogenannte Regelmaschinen installieren (rule-engines), welche live-Berechnungen ausführen, also die Messwerte gleich nach ihrer Entstehen weiterverarbeiten können. Das tolle daran ist, dass die Berechnungen sehr komplex sein dürfen, denn selbst wenn die Daten von einem schwächlichen Smart-Home-Gerätchen kommen, kann die Verarbeitung dann auf einem Raspberry Pi geschehen, der vergleichsweise sehr leistungsstark ist.

    Vorfreude:

    Damit es nicht zu langweilig wird, hier ein paar Leistungsdaten von was da so entstehen soll:

    * Daten können mit bis zu 20Hz auf dem Cockpit dargestellt werden, also ruckelfrei.

    * Die CPU-Belastung ist ziemlich niedrig, ein Raspberry Pi kann also ziemlich viele solcher Daten verarbeiten.

    * Netzwerkleistung wird kaum benötigt (jedenfalls wenn nur Zahlen und keine Videobilder übertragen werden sollen.

    * Das Ganze kann beliebig ausgeweitet werden auf mehr Rechner, auf entfernte Server im Internet, auf das Smatphone etc.

    * Man kann mehrer Cockpits auf vielen Rechnern darstellen, wobei garantiert ist, dass alle Cockpits zu jeder Zeit und immer sofort dasselbe anzeigen. Bewegt man auf einem Cockpit mit der Maus einen Scaler (simuliertes Potentiometer) dann bewegt sich dieser Schieber auf den Cockpits der anderen Rechnern wie von Geisterhand.

    Geschmacksachen

    Es gibt auch eine Besonderheit, die einige vielleicht als Nachteil ansehen: Die Gestaltung des Cockpits geschieht nicht mit einem Grafikprogramm sondern per Textdateien, die mit einem Texteditor bearbeitet werden müssen. Obwohl das sehr simpel gehtm ist es doch etwas fummelig, die einzelnen Koordinaten als Zahlen einzugeben, bis alles mal passt. Einen Cockpit-Designer hat noch keiner dafür geschrieben, und das, finde ich, ist auch die Stärke von anderen ähnlichen Lösungen wir "node red" et. al. Rule-engines muessen ebenfalls in Text-Dateien definiert werden, eigentlich programmiert, aber da es sich nur um wenige Zeilen handelt ist programmieren hier eigentlich etwas zu viel gesagt. Für mich war das aber ein Feature, denn ich arbeite gerne mit der Console und mag eigentlich interaktive Progamme, wo man alles zusammenklicken muss nicht so gerne. Oft sind die unnötig kompliziert zu verstehen und benutzen Javascript oder laufen im WEBbrauser, was sie sehr langsam macht, speziell auf einem alten raspberry Pi ist es quälend langsam.

    Soll ich weitermachen mit dem Tutorial? Hier eine Vorschau:

    1. So installiert man den mosquitto broker.

    2. So kann man Daten senden und empfangen

    3. So installiert man das Cockpit "MQTT-Hyperdash" auf einem Raspberry Pi

    4. So laüft auch was unter Android

    5. Ein commander zum absetzen von shell kommandos

    6. Eine kleine Regelmaschine für den ANfang

    7. Jetzt ein konkretes Beispiel.

    2 Mal editiert, zuletzt von wend (7. Januar 2020 um 21:38)

  • [Tutorial] Daten zwischen mehreren Raspis live austauschen und in einem Cockpit anzeigen? Schau mal ob du hier fündig wirst!

  • Moin wend,

    liest sich gut.

    Mögen die Spiele beginnen...

    73 de Bernd

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"
    Vielleicht trifft man sich in der RPi-Plauderecke.
    Linux ist zum Lernen da, je mehr man lernt um so besser versteht man es.

  • Ok, fangen wir für heute mit dem Broker an.

    Die Zentrale startklar machen

    Heute geht es darum, einen Raspberry Pi als Zentrale einzurichten. Dieser Raspberry Pi solle 24/7 durchlaufen können, ansonsten gibt es kaum Bedingungen, die erfüllt werden müssen. Man kann übrigens alles hier beschriebene auch auf einem Ubuntu Linux PC tun. Der Raspberry Pi, jedenfalls die alten Modelle B+, haben aber den Vorteil, daß sie viel weniger Strom verbrauchen.

    Wenn also eine Zentrale ausgewählt wurde und im Netzwerk erreichbar ist (nehmen wir an unter dem Rechnernamen "zentrale"), dann loggt Euch dort ein und installiert folgende Pakete:

    Code
    sudo apt-get install mosquitto mosquitto-clients

    Das ist schon alles. Auf den anderen Raspberry-Pis, die nicht zentrale sind, installiert bitte:

    Code
    sudo apt-get install mosquitto-clients

    Also nicht(!) das Paket mosquitto. Mosquitto ist der Broker, und der braucht nur auf einem Raspberry Pi installiert zu werden, auf den anderen Rechnern werden mit mosquitto-clients im wesendlichen nur die beiden Programme "mosquitto_sub" und "mosquitto_pub" installiert.

    Der mosquitto-Broker läft nach der Installation automatisch. Noch ein Hinweis: ohne weitere Konfiguration erlaubt der Broker Zugriffe von allen Rechnern aus. Das sollte in einem Heim-Netz hinter dem Router nicht so ein Problem sein, wenn aber das Netzwerk nach außen sichtbar ist, dann sollte man sich etwas mit der Absicherung beschäftigen, die aber nicht Teil dieses Tutorials ist. (Tipp: Zur Absicherung gehören Username und Passwort, ggf. sogar Transportverschlüsselung.)

    Um zu prüfen, ob der Broker auch läuft, öffnet mal zwei Terminals, jeweil auf irgendeinem Raspberry-Pi im Netz.

    In einem Terminal lasst ihr

    Code
    mosquitto_sub -h zentrale -t TEST

    laufen und in dem anderen gebt mal ein

    Code
    mosquitto_pub -h zentrale -t TEST -m "Hallo" -r

    "Hallo" sollte dann im ersten Fenster angekommen sein. zentrale ist natuerlich Euer Zentralrechner, der ja auch anders heissen kann, und TEST ist der Name eines sogenannten Topics. Unter dem werden dann die Mitteilungen ("Hallo") versendet. Hier könnt Ihr etwas rumspielen, andere Namen verwenden. Man verwendet üblicherweise auch Namen mit "/" drin, wie bei Filenamen. Groß- und Kleinschreibung wird unterschieden.

    Das Flag "-r" ist noch bemerkenswert. Wenn das verwendet wird, dann merkt sich der Broker die letzte Nachricht. Ein Mosquitto_sub bekommt die dann gleich beim Start, auch wenn noch kein anderes mosquitto_pub irgendwas auf dem Topic sendet.

    Mosquitto_sub und mosquitto_pub hauen noch keinen vom Hocker, deshalb installieren wir als nächstes das Cockpit (auch Armaturenbrett genannt, dashboard).

    Einmal editiert, zuletzt von wend (8. Januar 2020 um 09:26)

  • Das Cockpit klar machen

    Hier muss ein wenig kleinteiliger installiert werden, da es keine fertigen Pakete mit apt-get install gibt, jedenfalls nicht für alles. Also müssen wir bei einigen Sachen die Repositories von github clonen und dann die Software von dort compilieren und installieren. Das ist eigentlich nicht schwierig, man gibt immer nur "make" und "sudo make install" ein, aber es kann doch mal was zwischendurch schief gehen, und dann braucht man etwa Geduld, aber für die Mutigen, fangen wir an:

    Loggt Euch auf dem Rechner ein, der einen Bildschirm und Maus dran hat. Hier installieren wir nun die Cockpit-Anwendung.

    Vorbeitung

    Wir müssen einige Pakete installieren:

    Code
    sudo apt-get install git gitk libgtk2.0-dev 
    sudo apt-get install libsdl-gfx1.2-dev libsdl1.2-dev libsdl-ttf2.0-dev
    sudo apt-get install libssl-dev
    sudo apt-get install ttf-mscorefonts-installer

    Das sollte eigentlich auf einem Raspbian stretch flüssig funktionieren (da hab ich das gerade selbst gemacht).

    Als nächstes müssen wir Software von github clonen:

    Hierzu geht bitte in ein Arbeitsverzeichnis Eurer Wahl. Ich nehme /home/pi.

    Code
    git clone https://github.com/eclipse/paho.mqtt.c.git
    git clone https://github.com/kollokollo/MQTT-Hyperdash.git

    Dann geht in das Verzeichnis paho-mqtt.c und führt aus:

    Code
    make
    sudo make install

    Bei mir kommt zwar eine Fehlermeldung bei make install, es hat dennoch (ausreichend) funktioniert für das folgende. Wenn schon bei "make" Fehlermeldungen kommen, dann müßt Ihr da erstmal genauer hingucken, bei meinem alten Raspiban weezy war das der Fall. (Hinweis, dort muss alles noch mit der Realtime-library verlinkt werden "-lrt"). Aber für aktuellere Raspberrys sollte es so funktionieren.

    Geht wieder raus aus dem Verzeichnis und in das andere Verzeichnis:

    Code
    cd MQTT-Hyperdash/src
    make
    sudo make install

    Also hier im wesendlichen das Gleiche. Es sollten keine Fehlermeldungen auftreten, Warnungen können ignoriert werden. Lasst die Quellverzeichnisse, insbesondere MQTTHyperdash ertsmal noch auf dem Raspberry, die brachen wir noch späeter.

    Cockpit starten

    Wir wollen sehen, ob alles geklappt hat. Hierzu geht bitte in das Verzeichnis

    Code
    cd MQTT-Hyperdash/dashboards

    Und editiert da das File "test.dash": In der Zeile, die mit BROKER beginnt, ersetzt bitte "localhost" durch "zentrale", oder wie auch immer Euer Zentralrechner heißt. Also:

    Spoiler anzeigen

    # Global settings and default values

    #

    BROKER: URL="tcp://zentrale:1883"

    PANEL: TITLE="Button Test Dashboard" W=512 H=400 FGC=$ffffffff BGC=$000040ff

    [....] rest vom file

    Was der ganze Rest in dem File bedeutet, das sehen wir noch. Wenn Ihr das File wieder gespeichert habt, gebt mal von einem Desktop aus in einem Termin-Fenster ein:

    Code
    cd MQTT-Hyperdash/dashboards/
    hyperdash test.dash &

    Jetzt sollte sich ein Fenster öffnen mit einem Schieber und ein paar Buttons. Die kann man klicken und mit der Maus bewegen. Am Anfang ist der Scheber vielleicht nocht nicht aktiv, weil noch kein TOPIC dazu auf dem Broker existiert, mit dem ersten Klick ensteht das aber.

    Um etwas zu staunen, müsstet Ihr dasselbe Cockpit auch mal auf einem anderen Rechner installieren und starten.

    Notfalls könnt Ihr einfach "hyperdash" mit der modifizierten "test.dash" auf demselben Rechner noch ein zweites mal starten.

    Alle Schieber bewegen sich immer gleichzeitig!

    Hat bis hierher alles geklappt?

    Um noch etwas zu verstehen, lasst mal mosquitto_sub (wie oben aber) auf Topic "TESTT" laufen, und bedient dann den Schieber.

  • Hier noch etwas Hintergrund insbesondere zu dem Cockpit. (Für die ganz eiligen, die Englisch verstehen können: Im Verzeichnis MQTT-Hyperdash/doc befindet sich eine Kurzbeschreibung des .dash Dateiformats https://github.com/kollokollo/MQT…-file-format.md .)

    Wenn Ihr bis hierher gefolgt seid, dann habt Ihr eine Anwendung auf dem Raspberry-Pi mit Bildschirm und Maus installiert, die Cockpits, welche in Text-Files, den sogenannten .dash Dateien, definiert sind, in einem grafischen interaktiven Fenster darstellt und die Nutzereingaben entgegennimmt. Diese Nutzereingaben werden dann in Werte für MQTT-Topics übersetzt und an den Broker geschickt (ähnlich wie mit mosquitto_pub, nur schneller). Wenn sich die Inhalte der Topics, die im Fenster dargestellt werden, ändern, dann sendet der Broker Mitteilungen an mqtthyperdash (so wie an mosquitto_sub), der dann an der entsprechenden Stelle im Fenster z.B. die Zahl ändert oder den Zeiger eines METER Instruments.

    Das ist eigentlich schon alles, was da passiert. Das soll natürlich superschnell gehen, und ich finde, das tut es auch.

    Das einzige, was man nun tun muß, ist, ein .dash file für seine Wünsche zu erstellen. Das macht man mit einem Text-Editor. Hier kann man von den mitgelieferten Beispiel-dash Dateien Passagen kopieren, dann hat man was für den Anfang. Die TOPIC-Namen müssen angepaßt werden und die Broker-URL, wie wir das ja oben schon gemacht haben.

    Der Aufbau einer .dash Datei ist sehr simpel:

    Jede Zeile enthält ein Element oder ein Kommentar. Kommenrtarzeilen beginnen mit "#" und werden von mqtthyperdash ignoriert. Wenn man ein Element über meherer Zeilen definieren will, weil sonst die Zeile zu lang würde und es nicht schön aussieht, dann kann man als letztes Zeichen einer Zeile ein Backslash setzen "\", dann wird die nächste Zeile logisch angehängt.

    In jeder Zeile, die ein Element definiert, gibt es einen Doppelpunkt: Vor dem Doppelpunkt steht der Element Typ, und dahiner eine Liste mit Variablen und Werten, die man setzen möchte. Also z.B.

    Code
    BOX: x=10 y=20 w=30 h=40 FGC=$ffffffff

    Hier gibt es einen kleinen Fallstrick: vor und hinter den "=" Zeichen darf kein Leerzeichen stehen, und vor dem Doppelpunkt auch nicht.

    Ihr ahnt es schon, obiges Element ist ein einfacher Rahmen, dessen obere linke Ecke bei den Koodinaten (10,20) steht und der 30 Pixel breit und 40 Pixel hoch ist. Die Y-Koordinate ist oben im Fenster 0 und nach unten hin ansteigend. FGC bezeichnet die Farbe, in diesem Fall, "weiss+nichttransparent". Hinter dem Dollarzeichen steht eine Hexadezimale Zahl deren ersten beiden Zuffern den Rot-Anteil, dann Gruen, dann Blau definiert. Die letzen beiden Ziffern bezeichnen den Transparenzgrad: 00 = unsichtbar, total transparent, ff=nicht transparent. Rot wäre also $ff0000ff und rot, etwas durchscheinend: $ff000080.

    Es gibt noch weitere triviale Elemente wie CIRCLE, PBOX, LINE usw. Diese schaut am besten im Beschreibungsfile im doc/ Verzeichnis nach.

    Interessanter wird es, wenn wir einen Button machen wollen. Es gibt nämlcih kein Element BUTTON.

    Das wäre ja zu einfach (und auch zu unflexibel!)

    Deshalb muß man ein wenig die Philosophie hier verstehen: Ein Button besteht aus meherern Basis-Elementen: Eine gefüllte Box mit Farbe, ein Text für die Beschriftung, ein Rahmen, der das Kolicken/Drücken optisch anzeigt und ein unsichtbares Element, welches definiert, welches Topic beim Klick welchen Wert bekommen soll. Das sient dann im .dash File so aus:

    Code
    PBOX:        x=40 y=100 w=50 h=30 bgc=$444444ff
    TEXT:        x=45 y=100 w=30 h=30 TEXT="AN" fgc=$00ff00ff FONT="Arial"
    TOPICINAREA: x=40 y=100 w=50 h=30 TOPIC="TEST" VALUE="ON"
    FRAMELABEL:  x=40 y=100 w=50 h=30 TOPIC="TEST" MATCH="ON"

    Warum jetzt so kompliziert für einen einfachen Button?

    Nun, man kann den Button statt mit Text auch mit einem Piktogramm beschriften. (Das geht mit "BITMAP"), oder man kann den Button ohne Rahmen machen oder nur einen unsichtbaren Bereich definieren, woraufhin was passiert, wenn man da hineinklickt. Das ist ganz der Kreativität des Nutzers überlassen. Man kann in den Button auch ein aktives Element (zum Beispiel eine wechselnde Beschriftung) reintun, also eines, was sich ändert, wenn sich ein Topic-Inhalt ändert etc.

    Noch interessanter ist es, wenn man einen zweiten Button macht, welcher automatisch mit dem ersten verbunden ist, wenn man dasselbe TOPIC verwendet:

    Code
    PBOX:        x=140 y=100 w=50 h=30 bgc=$444444ff
    TEXT:        x=145 y=100 w=30 h=30 TEXT="AUS" fgc=$ff0000ff FONT="Arial"
    TOPICINAREA: x=140 y=100 w=50 h=30 TOPIC="TEST" VALUE="OFF"
    FRAMELABEL:  x=140 y=100 w=50 h=30 TOPIC="TEST" MATCH="OFF"

    Die beiden Buttons fungieren nun als ON/OFF Schalterkombination, als sogenannte radio-Buttons. Die in das TOPIC entweder ON oder OFF reinschreiben, jenachdem was geklickt ist, aber nun noch besser, die auch anzeigen, welcher Wert geade vorherrscht, nämlich wenn es OFF ist, erscheint der OFF-Button gedrückt, und bei ON der ON-Button. Simpel aber genial, oder?

    Ich will noch sagen, daß es für die Buttons noch TICKER-Funktion gibt, es gibt weiterhin: DASH (Weiteres dash File in einem neuen Fenster öffnen), SHELLCMD (Ein Shell-Kommando ausführen, wenn geklickt wird). Damit kann man schon ein schönes Cockpit mit mehereren Fenstern machen.

    Wollt Ihr die anderen Elemente selbst erkunden?

    Es gibt TOPICSTRING und TOPICNUMBER um den Inhalt eines Topics als Text darzustellen.

    HBAR und VBAR um den Inhalt (eine Zahl) als Balken darzustellen.

    METER (macht ein Tachoartiges Zeigerinstrument)

    HMETER und VMETER EIne Anzeige wie im Raumschiff (Siehe Apollo 13 oder Star Treck).

    PLOT für die Anzeige von Multi-Zahlen im Topic als Grafik.

    Als Eingaben kann man TOPICINAREA, TOPICINSTRING oder TOPICINNUMBER verwenden, oder komfortabler auch HSCALER und VSCALER oder TICKER.

    Erwähnenswert finde ich aber noch folgende ELEMENTE:

    FRAMELABEL, BITMAPLABEL und TEXTLABEL: Man kann eine Liste mit Inhalten angeben, bei denen bestimmt Bitmaps oder Texte angezeigt werden sollen, oder bei dem der Rahmen "gedrückt" dargestellt werden soll. Framelabel kam oben schon vor, dehalb hier nochmal BITMAPLABEL:

    Code
    BITMAPLABEL: x=390 y=10 TOPIC=BATTERY_FILL \ 
      BITMAP[0]="0|Battery0|$ffffffff" \
      BITMAP[1]="1|Battery1|$ffffffff" \
      BITMAP[2]="2|Battery2|$ffffffff" \
      BITMAP[3]="3|Battery3|$ffffffff" \
      BITMAP[4]="4|Battery4|$ffffffff" \
      BGC=$000040ff

    Hiermit wird ein Batteriesymbol erzeugt, was von "Batterie leer" bis "Batterie voll" verschiedene Bitmaps anzeigt, Diese sind im Wesendlichen ein Batteriesymbol, was verschiende Balken fur Füllstand hat. Das TOPIC "BATTERY_FILL" sollte den Inhalt "0", "1", "2", "3" oder "4" haben. Der Inhalt kommt z.B. von einer Batterie-Füllstandsmessung.

    Oder man kann die Farbe wechseln lassen:

    Code
    BITMAPLABEL: x=470 y=210 BGC=$000040ff TOPIC=LADE_STATUS \
      BITMAP[0]="1|SmallCircle|$00ff00ff" \
      BITMAP[1]="0|SmallCircle|$ff0000ff" 

    "1" wird dann zu einem grünen Kreis, eine "0" zu einem roten. Oder ein Symbol erscheint oder bleibt unsichtbar etc...

    Damit kann man schon ziemlich viel machen. Ich finde: so gut wie alles, was ein gutes User-Interface ausmacht...

    Noch ein Hinweis: Wer neue Bitmaps erzeugt hat: Diese sollten ins Verzeichnis

    /usr/share/hyperdash/bitmaps

    damit sie auch gefunden werden.

    Die Zeichensätze, welche für Texte verwendbar sind, findet man in

    /usr/share/fonts/truetype/msttcorefonts

    Man kann den Filenamen (ohne die Endung .ttf) verwenden.

    .dash files sollten, wenn sie von anderen Cockpit-Fenstern aus aufgerufen werden können sollen, in das Verzeichnis:

    /usr/share/hyperdash/dashboards

    installiert werden.

    2 Mal editiert, zuletzt von wend (12. Januar 2020 um 11:37)

  • Geht das auch mit Android?

    Ja, aber nicht so schön flexibel. Es ist praktisch, sich die TOPICs vom MQTT-Broker auch mit dem Smartphone anzeigen zu lassen, wenn es sich im gleichen (Heim-)Netz befindet.

    Hierzu verwende ich die App "MQTT Dash". Die kann man vom Play-Store installieren.

    Wenn man die öffnet, kann mit mit "+" ein neues Cockpit ertstellen. Man trägt bei Address den Broker ein, also "zentrale", vergibt noch einen Namen, alles andere kann man erstmal so lassen. Daraufhin entsteht in der Liste ein neues Cockpit, welches man aufrufen kann, aber noch keine Daten anzeigt. Diese muß man dan mit "+" hinzufügen. Es gibt verschiedene Typen zur auswahl (Button, Textanzeige). Es ist ziemlich einfach und kann nicht so vieles, ist aber super schnell eingerichtet und somit durchaus brauchbar. Es werden natürlich dieselben TOPIC-Namen verwendet wie auch auf den Raspberry Pis (Achtung: Gross/Kleinschreibung).

    Braucht Ihr noch mehr Anleitung? Ich hab die App in Nullkommanix verstanden und benutzt.

  • Zurück zu unserem Raspberry Pi Smart-Home Verbund. (Ja, nichts anderes verbirgt sich unter dem Begriff Smart-Home, oder manchmal auch IoT (=Internet of Things) genannt. Nur, daß wir bei unserer selbstgebauten Lösung natürlich keine Daten an irgendwen außerhalb unseres Heimnetzwerkes versenden. (Nicht, daß das nicht auch gehen würde....).

    Regelmaschinen

    Ja, Ihr wollt das, Ihr braucht das!

    Nehmen wir unser Beispiel von oben, wo eine Batteriefüllstandsanzeige realisiert werden soll. Dafür muß ein Topic z.B. "BATTERY_FILL" die Werte 0,1,2,3,4 annehmen, aber wo bekommen wir die her?

    Angenommen, unsere Batteriemessung produziert ein Topic "BATTERY_VOLTAGE", und darin stehen dann Zahlen von 10.0 V bis 13.5 V für einen Bleiakku oder 3.0 bis 4.2 V für eine Lithium-Zelle. Wie machen wir daraus eine Füllstandzahl 0,1,2,3,4.

    Nun, mit einer Regelmaschine!

    Eine Regelmschine ist ein normales Programm (excecutable) welches auf einem der Raspberry Pis gestartet werden kann und dann völlig autark im Hintergrund arbeitet. Man kann diese Regelmaschinen z.b. in der crontab mit @reboot automatisch starten und dann vergessen....

    Für tiefergehende Erläuterungen kann man das hier lesen (auf englisch):

    https://github.com/kollokollo/MQT…engine-howto.md

    Aber wie machen? Nun im MQTT-Hyperdash Verzeichnis, von wo aus wir die Cockpit-Anwendung compiliert und installiert haben, ist alles schon vorbereitet, so dass man nicht mehr viel programmieren muss.

    Erstellt dort im Verzeichnis MQTT-Hyperdash/src/ eine Datei "batteryengine.rule" mit folgendem Inhalt:

    Wenn das File gespeichert ist, dann macht ein

    Code
    make batteryengine

    Und es entsteht das File batteryengine, was man irgendwohin kopieren kann (z.B. in /home/pi/bin/) und von dort starten kann:

    Code
    /home/pi/bin/batteryengine &

    Und -- wie könnte es anders sein -- nun habt Ihr ein Topic BATTERY_FILL mit den zugehörigen Werten 0 1 2 3 4. Zusätzlich noch ein Topic BATTERY_FILLPERCENT mit dem Füllstand in Prozent (0 bis 100).

    Übrigens hab ich angenommen, dass es sich bei BATTRY_VOLT um die Spannungsmessung einer 3.6V LithiumZelle handelt. Noch Fragen ?

    Der zusätzliche Topic BATTERY/ACTIVITY zählt übrigens von 0 bis 3 immer wieder im Sekundenrhytmus. Wozu? Nun damit man erkennen kann, ob die Regelmaschine noch läuft. Macht ein Bitmaplabel dran, der ein sich drehendes Rad (Bitmaps Disc1 bis Disc4) zeigt oder sonst eine andere Animation für das Cockpit. Macht Sinn.

    2 Mal editiert, zuletzt von wend (13. Januar 2020 um 15:16)

  • Steuerkommandos absetzen und Aktion auslösen

    Jetzt haben wir soweit alles beschrieben, ausser, woher die Messadaten eigentlich kommen, und wie sie dann in ein TOPIC im Broker erscheinen.

    Fangen wir mit einem einfachen Fall an: Man klickt einen Button im Cockpit und auf einem entfernten raspberry Pi soll eine Aktion ausgelöst werden. Für den Cockpit-Teil haben wir oben ja schon zwei Buttons ON/OFF ertstellt. Diese schreiben in das TOPIC "TESTT" die Werte ON oder OFF rein.

    Auf einem entfernten Pi soll jetzt ein Empfaenger laufen, der daraufin was schaltet.

    Man könte dafür nun mosquitto_sub verwenden und die Ausgabe in andere Shell-Scripten oder python-Scripte umleiten. Das ist auch gar keine schlechte Idee und ich würde das auch empfehlen. Man kann dafür mosquitto_sub über eine Pipe mit einem anderen Script verbinden:

    Code
    mosquitto_sub -h localhost -t "TEST" | myscript.py &

    myscript.py kann nun Zeilenweise von stdin lesen und die Zeile dann jeweils auswerten.

    Es gibt aber noch einen anderen Ansatz, den ich hier vorstellen will:

    Einen Commander. Dies ist eine -- Regelmaschine. Und da wir ja schon wissen, wie man die macht,

    können wir ein entsprechende .rule file vorbereiten, welches auf Änderungen eines Topics lauscht und dann je nach Topic Inhalt verschiedne Shell-Kommandos ausfürt.

    Hier gibt es bei MQTT-Hyperdas/src ein file "commander.rule" welches man entsprechend eigener Wünsche modifizieren kann, uns zwar:

    1. BROKER anpassen

    Code
    #define BROKER "tcp://zentrale:1883"

    2. Eindeutigen namen vergeben:

    Code
    #define CLIENT "Mein-super-Commander"

    3. ACTIVITY_TOPIC kann man so lassen.

    4. Die Topics HOME/SOLAR/LADE/CMD_DC und HOME/SOLAR/LADE/CMD_SC auf seine eigenen Topic Namen ändern. Der erste Topic Name sollte nur Zahlen beinhalten, wärend der Zweite Zeichenketten haben kann. Man kann auch nur einen von beiden verwenden. In diesem Beispiel verwenden wir CMD_nummer und CMD_string:

    Code
      {PARM_IN|PARM_TRIGGER|PARM_ISNUMBER,"CMD_number",0,0,NULL},
      {PARM_IN|PARM_TRIGGER,              "CMD_string",0,0,NULL}

    5. Die Shellcommandos definieren, sowie zugehörige Zeichenketten fuer CMD_string. Hier als beispiel wird ein python script verwendet, welches eine Steckdose einschaltet. Das heisst bei Euch sicher anders, also anpassen! Es wird dann bei "ON" das erste SHellcommando ausgefuehrt und bei "OFF" das zweite. Man kann hier problemlos noch beliebig viele andere match / shellcmd kombinationen definieren... Einfach mit in die beiden Arrays zwischen { } einfügen.

    Code
    static char *match[]={"ON","OFF"};
    static char *shellcmd[]={
      "python /home/pi/433mHz.py 1 1",
      "python /home/pi/433mHz.py 1 0"
    };

    Das wars eigentlich schon, den Rest kan man so lassen. Die Shell-Scripte können über CMD_number auch mit einer Zahl ausgelöst werden (0 oder 1). Ansonsten geht es weiter wie oben bei der Regelmaschine, also

    Code
    make commander


    und man erhält das File "commander" zum irgendwo starten und vergessen.

    2 Mal editiert, zuletzt von wend (8. Januar 2020 um 13:25)

  • Letztes Thema:

    Meßwerte erfassen und zum Broker senden

    Ihr ahnt es schon, das einfachste ist, das einfach mit mosquitto_pub zu machen. Für Messwerte, die einmal pro Minute oder bis zu einmal pro Sekunde erhoben werden, ist das ausreichend schnell. Wenn man mit 10 Hz oder 20 Hz Daten absetzen möchte, dann muss man es anders machen, aber wer macht das schon? Also gucken wir uns den einfachen Fall an.

    Nehmen wir an, wir hätten einen Sensor (im Beispiel ein Drucksensor), welcher mit

    Code
    sudo python pressure.py

    den aktuellen Luftdruckwert auf die Konsole schreibt: also so

    Code
    pi@raspberry1:/home/pi>sudo python pressure.py
    1018.72998047
    pi@raspberry1:/home/pi>

    dann kann man das ganze ganz einfach in mosquitto_pub rein-pipen:

    Code
    mosquitto_pub -h localhost -t "LUFTDRUCK" -r -m `sudo python pressure.py`

    Die umgedrehten Hochkommata sind hier wichtig! Schon fertig. Wenn man nun jede minute den Luftdruck messen und an den Broker senden will, dann am einfachsten mit einem cronjob, der dieses Kommando dann jede Minute ausführt.

    Wer python programmieren kann, der findet auch direkte mqtt-Anbindungen, wo man im python programm direkt die Werte "publish"en kann. Aber da bin ich nicht so fit, und das soll jemand anderes erläutern. Auf diese Weise kann man dann auch mehr als einen Wert pro Minute messen und versenden.

    Wer C programmieren kann, der wird sich vielleicht für die spezielle Regelmaschine "sysmeasure.rule" interessieren, die mit dem MQTT-Hyperdash paket kommt...

    Ich wollte stattsdessen den Ausblick geben, dass es MQTT libraries auch für Arduino bzw für NodeMCU gibt, mit dem man dann kleine Smart-Home Geräte realisiern kann, die die Daten an den Broker auf zentrale senden.

    Alles in Allem behält man dann mit dem Cockpit immer den Überblick über die Datenlage auf netten grafischen Cockpit-Armaturenbrettern. Und da die vorgestellte Cockpit-Software noch nicht so lange existiert, kann man für die Zukunft noch Verbesserungen oder Erweiterungen erwarten. Jedenfalls ist alles Open-Source.

    Wer lieber eine andere Cockpit-Software einsetzen möchte, der hat zudem noch die Auswahl. Hier ist eine Sammlung von Alternativen: https://www.hivemq.com/blog/seven-best-mqtt-client-tools/

    Keine fand ich allerdings so einfach zu installieren wie die oben vorgestellte.

    Einmal editiert, zuletzt von wend (12. Januar 2020 um 11:40)

  • MQTT in shell-scripten benutzen

    Ich gehe hier auf besonderen Wunsch hin nochmal auf die Verwendung von MQTT in Shell-Skripten ein.

    Eingentlich ist das Absenden von Daten ganz einfach mit:

    Code
    a="Hallo"
    mosquitto_pub -h zentrale -t TEST -m $a -r

    aus dem Shell Skript heraus möglich. Die Variable a kann man dabei vorher mit was auch immer füllen.

    Das Empfangen von Daten ist aber auch genauso leicht möglich, folgende Zeilen holen den letzen Wert aus dem Topic ab, soweit einer existiert, bzw. wenn nicht, wartet bis einer kommt:

    Code
    a=`mosquitto_sub -h zentrale -t "LUFTDRUCK" -C 1`
    
    echo "Luftdruck: " $a "hPa"

    Die Programme mosquitto_pub und mosquitto_sub sind allerdings etwas langsam, weil jeweils eine Verbindung zum Broker aufgebaut wird, dann wird ein Wert empfangen oder gesendet und schließlich wird die Verbindung wieder beendet. Besser wäre es, die Verbindung offenzulassen, da der Verbindungsauf- bzw. abbau immer Zeit kostet. Aber bei 1 Wert / Minute bis 1 Wert pro Sekunde ist das kein Problem.

  • MQTT ans Limit bringen

    Also langsame Datennahme kann jeder, was aber, wenn man Meßwerte mit sagen wir mal 20 Hz nehmen (und verarbeiten und anzeigen) möchte? Geht das dann auch mit MQTT?

    Ja! -- Jedoch nicht unbedingt mehr mit den Shell-Tools mosquitto-pub und mosquitto-pub. Auch python kommt irgendwann an die Grenzen. Deshalb wollte ich noch kurz aufzeigen, wie man das mit den hier schon benutzen Framework für Regelmaschinen macht. Die sind nämlich alle in C programmiert bzw. zu programmieren, und das ist schon ziemlich schnell so, ich würde fast sagen, es ist kaum schneller machbar.

    Wenn Ihr das MQTT-hyperdash-Verzeichnis

    Code
    cd MQTT-Hyperdash/src/

    noch vorliegen habt, dann schaut Euch mal die Regelmaschine "sysmeasure.rule" an. Es handelt sich um eine spezielle Regelmaschine, die die Systemlast des Rechners mißt und an den Broker versendet, auf dem sie läuft. Nochmal zur Erinerung: mit

    Code
    make sysmeasure

    wird die compiliert und mit

    Code
    ./sysmeasure --prefix LOCALHOST &

    könnte sie auf dem zentralen Raspberry Pi gestartet werden. Sie arbeitet dann fast unmerklich im Hintergrund und mißt laufend die Systemlast, den benutzen RAM-Speicher und den Füllgrad der Speicherkarte des Raspberrys.

    Wenn Ihr in dem Dashboard MQTT-Hyperdash/dashboards/sysmeasure.dash noch den richtigen Broker eintragt (zentrale statt localhost), dann könnt Ihr die Daten auch live anschauen mit:

    Code
    cd MQTT-Hyperdash/src
    ./hyperdash ../dashboards/sysmeasure.dash &

    Das sieht dann etwa so aus:

    Das Rädchen oben rechst sollte sich drehen, dann hat alles funktioniert.

    So, jetzt nochmal zurück zum Thema, es soll also besonders schnell funktionieren. In der Normalversion, die mitgeliefert wird, ist die Update-rate aber nur eines pro Sekunde.

    Das können wir aber ändern:

    Dazu machen wir erstmal eine Kopie von sysmeasure.rule

    Code
    cd MQTT-Hyperdash/src
    cp sysmeasure.rule sysmeasure-fast.rule

    und nun modifizieren wir sysmeasure-fast.rule etwas:

    ganz unten im File steht "default_measure_loop(NULL);". Das löschen wir, und ersetzen es durch:

    Spoiler anzeigen

    static int cnt=0;

    char buffer[64];

    STRING a;

    a.pointer=buffer;

    /* publisg ACTivity_dm */

    snprintf(buffer,sizeof(buffer),"%d",cnt);

    a.len=strlen(a.pointer);

    char *topic=make_topic(ACTIVITY_TOPIC);

    mqtt_publish(topic,a,0,1);

    free(topic);

    cnt++;

    if(cnt>=4) cnt=0;

    usleep(100000);

    Danach machen wir entsprechend:

    Code
    make sysmeasure-fast
    killall sysmeasure
    sysmeasure-fast --prefix LOCALHOST &

    Und siehe da, die gesamte Messung geht nun auch mit 10 Hz. Und zwar, ohne dass der Raspberry Pi merklich beeinträchtig oder langsamer wird. Wer es noch schneller mag: Statt usleep(100000); geht auch usleep(50000); Die Zahl sind Mikrosekunden. Also 20 Hz. Mehr macht eigentlich keinen SInn, da man schneller nicht gucken kann. Aber aus Datennahmesicht wäre es natuerlich möglich....

    Ich finde das ziemlich beeindruckend....

    So ansonsten bin ich nun mit dem Tutorial einigermassen am Ende angekommen... Ich hoffe, es war nützlich. Viel Spass damit. ....

  • Hier noch einige Ergänzungen:

    Liste von Topics eines Brokers abrufen

    Wie kann man eine Liste bekommen aller Topics, die ein MQTT Broker vorhält?

    Nun hierfür gibt es das tool mqtt-list-topics (im Paket MQTT-Hyperdash enthalten), welches die Topics auflistet.

    Allerding werden nur topics aufgelistet, die auch aktuell dem Broker bekannt sind, und schonmal einen Wert bekommen hatten. Eigentlich logisch.

    Also das geht so:

    Code
    mqtt-list-topics --broker zentrale

    Und wer das ganze lieber als Alphabetisch sortierte Liste ansehen will, geht

    Code
    mqtt-list-topics --broker zentrale | sort

    FInde ich ganz nützlich.

    Dashboards für Faule

    Und noch eine Funktion: Wenn mann hyperdash auf dem Rechner startet, auf dem auch der mosquitto-broker läuft,

    dann bekommt man die Möglichkeit, aus allen verfügbaten Topics auf dem Browser ein generisches Cockpit zu machen, bei dem alle Topics erreichbar und bedienbar sind.

    Die sehen natürlich nicht so schön aus, aber man kann die erzeugten .dash files ja gut als Vorlage für eigene schönere

    Kreationen verwenden.

    Hierzu also aus dem Startmenu des Desktops des Raspberry Pis unter "Entwicklung" --> "MQTT Hyperdash" starten, oder von der Konsole:

    Code
    hyperdash &

    Es öffnet sich dann ein Startfenster. Auf dem ist der Knopf "create local dasboard tree" von Interesse.

    Einmal klicken bitte. Dann kann der Button "Generic Dashboards" benutzt werden. Er führt nun zu allen auf dem Broker verfügbaren Topics. Praktisch !

    Ach so: Die erzeugten Files liegen anschliessend im Verzeichnis /home/pi/.hyperdash/dashboards/

  • Ich habe gestern noch was interessantes entdeckt: Den öffentlichen MQTT broker http://test.mosquitto.org . Den kann man einfach so benutzen (wenn man nicht erwartet, dass es für andere Zwecke als zum Testen ist). Und mit diesem Broker ist es mir gelungen, die Daten aus meinem Heimnetz heraus auf mein Smartphone zu bringen und dort anzuzeigen. Umgekehrt funktioniert es natürlich auch.

    Ihr müsst als Broker einfach:

    Code
    tcp://test.mosquitto.org:1883

    angeben. Dann braucht Ihr nicht mal eine Zentrale zuhause. Ein Nachteil hats allerdings: Alles was ihr darüber sendet ist quasi öffentlich einsehbar. Also Achtung bei den Daten.

  • Hm, vielleicht habe ich einige etwas abgeschreckt. Textfiles mit einem Text-Editor bearbeiten ist wohl nicht jedermanns Sache. Aber da darf ich vieleicht verraten, dass es auch einen grafischen Editor für die Dashfile gibt. Sieht etwa so aus wie in dieser Kurzanleitung https://github.com/kollokollo/MQT…-user-manual.md

    Allerdings finde ich, man lernt so nicht, wie es letztlich funktioniert. Und Drag & Drop Programmierung ist einfach nicht meine Sache.

  • Und hier nach einer langen Zeit vielleicht noch ein nützlicher Hinweis für die, die einen Arduino zusammen mit dem Raspberry Pi betreiben:

    In der neuesten Version von MQTT-Hyperdash liegt nun auch ein Tool bei, namens mqtt2serial.

    Dieses kleine Tool kann auf dem Raspberry gestartet werden und dann im Hintergrund weiterlaufen. Es verbindet sich mit einem Arduino, der per USB an dem Raspberry Pi angeschlossen ist, und übernimmt dessen Ausgabe und gibt sie als MQTT Meldungen weiter, und umgekehrt, leitet alle MQTT Messages an den Arduino. Der Witz dabei ist, dass man auf dem Arduino selbst keine MQTT-Library braucht (und bei so einem einfachen Arduino Nano geht das ja auch kaum, wegen des eingeschränkten Speichers und der nicht-vorhandenen Netzwerkschnittstelle). Eine simple Ausgabe mit Serial.println() reicht. Finde ich ganz nützlich. Das macht die Arduino-Anbindung viel leichter.

    Also so gehts: Das könnte ein Teil des Arduino-Sketches sein:

    Hier wird eine Zählervariable als MQTT-Parameter (TOPIC "COUNTER_DM") ausgegeben. Man erkennt, dass die Ausgabe folgendes Format haben muss:

    1 Zeile mit: "MQTT:<topic>=<message>"

    Auf dem Raspberry muss man dafür dann folgende Zeile ein ein Terminal eingeben (oder als Cron-Job aktivieren)

    Code
    mqtt2serial --broker tcp://zentrale:1883 --prefix "ARDUINO" --device /dev/ttyUSB0 --baudrate 115200 

    Die meisten Parameter sollten sich selbst erklären, wie --broker und --baudrate

    Mit --device wird das USB-tty device angegeben, welches beim RaspBerry Pi auftaucht, wenn man den Arduino per USB-Kabel anstöpselt. Das kann auch schonmal anders heißen, z.b. /dev/ttyUSB1 oder mit einer anderen fortlaufenden Nummer. Hier wäre evtl. darauf zu achten, daß es für den User "pi" les- und schreibbar ist. Aber das gilt ja immer, wenn man einen Arduino anstöpselt und bedienen will. Für Fortgeschrittene empfehle ich dabei "udev-rules". Die können das erleichtern. Aber das soll hier nicht Thema sein.

    Mit --prefix wird der Zweig des MQTT-Topc-Baumes definiert, der an den Arduino weitergeleitet werden soll, also alles, was mit ARDUINO/ beginnt.

    Das TOPIC "COUNTER_DM" von der Arduino-Ausgabe wird dann auf dem MQTT-Broker als "ARDUINO/COUNTER_DM" gehandelt. Und wenn über MQTT irgendwas unter ARDUINO/ empfangen wird, also z.B. "ARDUINO/CMD_DC", dann wird es als "CMD_DC" and den angeschlossenen Arduino gesendet.

    Das wars auch schon.

    Ein Sketch zum empfangen auf dem Arduino kann etwa so aussehen:

    (ich hab dabei das beiliegende Beispiel verwendet und vereinfacht).

    Einmal editiert, zuletzt von wend (12. Januar 2021 um 10:02)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!