Wie es funktioniert

Protokoll

Zwei Strecken, zwei Protokolle. JSON über MQTT mit TLS zum Server, binär über CAN zu den Modulen.

Auf dieser Seite

MQTT: Hub und Server

MQTT verbindet nur Hub und Server, dazu die Anzeigen im WLAN mit dem Server. Es läuft immer über TLS, am Port 8883 des Servers. Nachrichten sind JSON. Die Felder stehen als Schemata im Paket packages/protocol und werden auf beiden Seiten geprüft. Der Browser spricht nie MQTT, sondern HTTPS und WebSocket mit dem Backend.

Topics

Topic Richtung retained Inhalt
sb/<hub>/status Hub → Server ja online oder offline, zugleich Last Will
sb/<hub>/discovery Hub → Server ja erkannte, noch nicht übernommene Module
sb/<hub>/config Server → Hub ja Konfiguration des Hubs
sb/<hub>/<modul>/status Hub → Server ja Modulstatus mit Selbstbeschreibung
sb/<hub>/<modul>/<kanal>/state Hub → Server nein Messwert oder Zustand
sb/<hub>/<modul>/<kanal>/cmd Server → Hub nein Befehl an einen Aktor
sb/<hub>/controller/<name>/setpoint Server → Hub ja Sollwerte
sb/<hub>/controller/<name>/state Hub → Server nein was ein Regler gerade tut
sb/<hub>/event Hub → Server nein Alarme, Sicherheitsabschaltungen, Begründungen
sb/<hub>/update Server → Hub nein Hinweis auf neue Firmware, die Datei kommt per HTTPS
sb/<hub>/resource/<id>/cmd Server → Hub nein Befehl an eine Ressource, etwa „Auffüllen“
sb/<hub>/weather Server → Hub nein Wind und Böen für den Windschutz
sb/<hub>/alarms Server → Hub ja offene Alarme für die Anzeigen, zugleich Lebenszeichen des Servers
sb/<hub>/<modul>/ui Hub → Server ja was eine Anzeige am Bus gerade zeigt
sb/provision/<serial>/hello Hub → Server nein Anmeldung eines Hubs, der noch nicht übernommen ist
sb/provision/<serial>/credentials Server → Hub nein Zugangsdaten bei der Übernahme

<modul> ist die Seriennummer des Moduls. Die Busadresse vergibt der Hub, sie kann sich ändern. Die Seriennummer bleibt, deshalb hängen Verläufe an ihr. Das Hub-eigene Modul heißt hub. <kanal> ist die Kennung aus der Selbstbeschreibung, zum Beispiel temp oder out1.i.

Befehle, Konfiguration, Sollwerte, Ereignisse, Status, Wetter und Alarme gehen mit QoS 1, Messwerte und der Bildschirm der Anzeige mit QoS 0.

Online und offline

Der Keepalive ist seit 0.10.0 10 Sekunden statt 30. Der Broker trennt einen stummen Hub nach 15 Sekunden und veröffentlicht seinen Last Will: Ein Hub ohne Strom ist nach höchstens etwa 15 Sekunden offline. Ein Stromausfall schickt kein Abschiedswort. Meldet sich ein Hub nach einem Neustart wieder an, veröffentlicht der Broker sofort den Last Will der alten Verbindung, gleich danach meldet der Hub wieder online.

Ein Modul zählt beim Server nur als online, solange sein Hub online ist. Meldet der Hub offline, setzt der Server alle seine Module auf offline. Ein aufbewahrter Status eines Moduls holt es nicht zurück, bis der Hub wieder online ist.

In der anderen Richtung hört jeder Hub, der online ist, spätestens alle 40 Sekunden etwas vom Server: Ging 30 Sekunden lang nichts an ihn, schickt der Server ihm seine Alarmliste erneut, auch leer. Das verstehen alle Hub-Firmwares ab 0.4.0. Bleibt ein Hub trotzdem 80 Sekunden im autonomen Betrieb, kommt bei ihm nichts an, etwa wegen der Rechte am Broker. Der Server meldet dann „Hub empfängt nichts vom Server“.

Befehle und ihre Antwort

Jeder Befehl trägt eine eigene Kennung. Der Hub antwortet mit einem Ereignis, das sagt, ob der Befehl ausgeführt wurde, und wenn nicht, warum.

{
  "id": "e-1",
  "t": 1727430001,
  "severity": "info",
  "code": "cmd_result",
  "cmdId": "c-42",
  "ok": false,
  "cause": { "kind": "interlock", "code": "tank_low", "values": { "level": 6, "min": 10 } }
}

Ausschalten wird nie abgelehnt.

Befehle an einen Ausgang

Befehl Wirkung
set Stellwert setzen, von Hand mit Dauer
unlock Sperre freigeben
teach Normalstrom einlernen, an einem Antrieb der Kalibrierlauf
calibrate Kalibrierlauf eines Antriebs starten
mark während des Laufs: „Jetzt offen“ oder „Jetzt zu“
cancel Kalibrierlauf abbrechen, der Antrieb bleibt stehen

Das Ergebnis eines Kalibrierlaufs kommt später als eigenes Ereignis mit der Kennung des Befehls. Die Abläufe stehen unter Antriebe und Kalibrieren.

Wetter für den Windschutz

Ohne Windmodul nutzt der Hub das Wetter vom Server:

{ "t": 1727430001, "windMs": 3.4, "gustMs": 7.9, "validS": 3600 }

Die Nachricht gilt ab dem Empfang so lange, wie validS sagt. Der Hub braucht dafür keine gestellte Uhr. Sie ist nicht retained, damit ein Hub nach einem Neustart keine alte Lage für neu hält.

Einen Hub übernehmen

Geräte werden nicht konfiguriert, sondern übernommen.

Übernahme eines Hubs

  1. Eingetragene Adresse, sonst mDNS, sonst Suche im eigenen Netz nach Port 8443 und 443. Jeden Kandidaten prüft er über HTTPS: Das CA-Zertifikat muss zum Server-Schlüssel im Einrichtungscode passen. Die Netzsuche kann bis etwa drei Minuten dauern.

  2. Der Hub verbindet sich per MQTT über TLS als Einrichtungsbenutzer. Das Passwort ist der Einrichtungscode, den Admins in der Oberfläche sehen. Alle 10 Sekunden meldet er sich.

  3. Der Code allein gibt keinen Zugriff. Übernehmen muss immer ein Admin.

  4. Der Server legt im Broker einen Benutzer an, der nur die Topics dieses Hubs lesen und schreiben darf, und schickt dem Hub die Zugangsdaten.

  5. Der Hub speichert die Zugangsdaten, trennt und verbindet sich unter seiner eigenen Kennung. Er meldet Status und Selbstbeschreibung.

  6. Der Server schickt die Konfiguration. Ab jetzt kommen Messwerte.

Einrichtungscode und Server-Schlüssel

Der Einrichtungscode unter „Geräte“ hat am Ende vier weitere Gruppen, den Server-Schlüssel. Er ist aus dem CA-Zertifikat der eigenen CA des Servers berechnet. Daran erkennt der Hub seinen Server und heftet dessen CA an. Ohne Einrichtungscode mit TLS verbindet er sich mit nichts, und ein abgelehntes Zertifikat führt nie zu einer Verbindung ohne Prüfung. Den Grund zeigt der Hub im Einrichtungs-WLAN. Hat der Server ein öffentliches Zertifikat, fehlt der Server-Schlüssel, und die Server-Adresse ist Pflicht.

Nach dem Start verbindet sich ein Hub mit bekannter Adresse seit 0.10.0 sofort per MQTT über TLS, ohne vorher über HTTPS zu prüfen. Kommt in 20 Sekunden keine Verbindung zustande, prüft er die Adresse und sucht sonst weiter.

Lehnt der Broker die eigenen Zugangsdaten eines Hubs ab, etwa weil das Konto gelöscht wurde, versucht der Hub es mit wachsendem Abstand weiter. Erst nach mindestens 5 Ablehnungen über mindestens 60 Sekunden vergisst er sie und meldet sich wieder als neuer Hub.

Ein Modul übernehmen

  1. Das Modul wird an den Bus gesteckt und meldet sich beim Hub an.
  2. Der Hub fragt die Selbstbeschreibung ab, ab 0.10.0 auch, welche Sensoren das Modul erkannt hat, und nimmt das Modul in die Liste der erkannten Module auf.
  3. Der Server zeigt „Neues Modul gefunden“ mit dem Typ und dem, was erkannt wurde.
  4. Ein Admin klickt „Übernehmen“ und vergibt Namen, Zone, den Ort der Sensoren und den Modultyp.
  5. Der Server nimmt das Modul in die Konfiguration des Hubs auf.
  6. Der Hub vergibt die Busadresse. Danach kommen die Messwerte.

Nicht übernommene Module senden keine Messwerte an den Server. Der Server muss den Modultyp vorher nicht kennen, denn jedes Modul beschreibt sich selbst. Den Typ setzt der Hub ab 0.10.0 aus seiner Konfiguration; weicht er vom Vorschlag ab, startet das Modul einmal neu. Mehr unter Module.

CAN: Module und Hub

Eigenschaft Wert
Rate 250 kbit/s
Rahmen erweitert, 29 Bit Kennung, bis 8 Byte Daten
Abschluss 120 Ω an beiden Enden
Kabel vieradrig: 24 V, Masse, CAN-H, CAN-L
Byte-Reihenfolge Little Endian
Zahlen IEEE-754 float, 32 Bit

Kennung

28–26 Priorität 3 Bit 0 = höchste 25–21 Typ 5 Bit 8 Nachrichten 20–13 Absender 8 Bit 0 = Hub 12–5 Empfänger 8 Bit 255 = alle 4–0 Teilnummer 5 Bit Kanal oder Folge 29 Bit
Aufbau der 29-Bit-Kennung. Auf dem CAN-Bus gewinnt die kleinere Kennung, deshalb steht die Priorität vorn.
Bits Feld Werte
28 bis 26 Priorität 0 ist die höchste
25 bis 21 Nachrichtentyp 1 bis 8
20 bis 13 Absender 0 Hub, 1 bis 250 Modul, 254 ohne Adresse
12 bis 5 Empfänger 255 für alle
4 bis 0 Teilnummer Kanalindex oder Folgenummer

Nachrichten

Nachricht Priorität Richtung Zweck
Ereignis 0 Modul → Hub Endschalter, Überstrom, Notabschaltung
Stellbefehl 1 Hub → Modul Ausgang setzen
Lebenszeichen 2 beide Ausfallerkennung in beide Richtungen
Messwert 3 Modul → Hub regelmäßig und bei Änderung
Anmeldung 4 Modul → Hub Seriennummer und Typ, solange das Modul keine Adresse hat
Adresszuweisung 4 Hub → Modul nach der Übernahme
Beschreibung 5 beide Kanalliste, Firmware-Version
Update 7 Hub → Modul Firmware in Blöcken

Ein Messwert passt in einen Rahmen: Kanalindex, Güte, Wert als float und das Alter in 10-Millisekunden-Schritten.

Anmeldung eines Moduls

  1. Ein Modul ohne Adresse sendet alle 2 Sekunden eine Anmeldung.
  2. Der Hub merkt sich Seriennummer und Typ und fragt die Beschreibung ab.
  3. Nach der Übernahme sendet der Hub die Adresszuweisung.
  4. Das Modul speichert die Adresse dauerhaft und sendet Lebenszeichen.
  5. Nach einem Neustart meldet sich das Modul mit seiner gespeicherten Adresse. Kennt der Hub die Adresse nicht mehr, vergisst das Modul sie und meldet sich neu an.

Damit zwei neue Module nicht zur selben Zeit dieselbe Kennung senden, leitet jedes Modul Teilnummer und Versatz seines 2-Sekunden-Takts aus der eigenen Seriennummer ab.

Blockübertragung

Beschreibung und Firmware sind länger als 8 Byte und werden in Blöcken übertragen.

Rahmen Inhalt
Erster Rahmen Gesamtlänge und CRC32
Folgerahmen bis 8 Byte Nutzlast, Teilnummer 1 bis 31 umlaufend
Bestätigung alle 16 Rahmen vom Empfänger: die nächste erwartete Position

Fehlt ein Rahmen, bestätigt der Empfänger sofort die erwartete Position, und der Sender setzt dort wieder auf. Stimmt die CRC32 am Ende nicht, beginnt der Sender von vorn. Ohne Bestätigung wiederholt er nach 500 Millisekunden, höchstens fünfmal.

Selbstbeschreibung

Die Beschreibung eines Moduls ist binär. Sie nennt Modultyp, Firmware- und Hardware-Version und je Kanal Rolle, Messgröße, Messbereich, Kennung und Namen. Je Ausgang nennt sie die Art, die Sicherung und die zugehörigen Kanäle für Stellwert, Strom, Spannung und Zustand.

Je Kanal gibt es Merker: beschreibbar, geschätzt, neu startbar, braucht Kalibrierung. Den letzten setzen Füllstand und Bodenfeuchte. So bringt ein künftiger Sensor die Kalibrierpflicht selbst mit, ohne dass Hub oder Server ihn kennen müssen.

    Durchsucht alle Seiten. Die Suche läuft im Browser, nichts wird übertragen.