Hausbus2

Aus RaumZeitLabor Wiki

Diese Seite dient dazu, den Nachfolger des Hausbus zu designen. Wer mithelfen möchte, möge sich zunächst des http://en.wikipedia.org/wiki/Second_System_Effect bewusst machen und Änderungen dann mit sECuRE besprechen :).

Hausbus in a Nutshell

  • Wurde in Q3 2010 hauptsächlich von sECuRE gebastelt, nach Idee/Vorschlägen von Scytale und anderen
  • verwendet RS485 (etwas aufgebohrte serielle Schnittstelle) zur Kommunikation (2 Adern) in Patchkabeln, zwei Adern zur Stromversorgung
  • Busmaster kontrolliert, wer wann spricht und schickt das ganze via Ethernet an die Firebox
  • Firebox stellt eine Schnittstelle (HTTP) zur Verfügung um zu lesen und zu senden. Derzeit läuft auf der Blackbox z.B. der Pin-Validator, der vom Pinpad liest und zum Pinpad den Entsperr-Befehl sendet. Weiterhin läuft auf der Firebox das SSH-Aufschließ-Script.
  • Teilnehmer sind Mikrocontroller, z.B. ATmega644p.
  • Derzeit existiert nur der Pinpad-Controller, angedacht sind Heizungssteuerung (in naher Zukunft), Temperatursensoren (Proof-of-concept vorhanden), Lichtsteuerung (Status unklar), evtl. Stromzähler (statt Flukso), evtl. Kassenterminal (?)

Probleme mit dem derzeitigen Hausbus

  • Verkabelung erfolgt (derzeit noch garnicht, aber prinzipiell) mit Stichleitungen von einem großen Bus. Das ist sehr bescheuert und sternförmige Verkabelung deutlich besser/flexibler/stabiler.
  • Datenübertragung ist/war fummelig. RS485 stabil zu kriegen hat uns einiges an Zeit gekostet. Ich bin von der Stabilität nicht überzeugt. Gelegentlich gehen derzeit immernoch Pakete verloren. Insbesondere wenn man an den Parametern dreht: Wenn man den Busmaster schneller macht, steigt der Paketverlust.
  • Stromversorgung ist ein Gebiet, auf dem sich viele nicht (genug?) auskennen, um einen stabilen Betrieb sicherzustellen. Wenn wir am Busmaster etwas ändern, haben die Geräte währenddessen keinen Strom. Wenn ein Gerät kaputtgeht, könnten andere darunter leiden.
  • Busmaster ist ein Mikrocontroller (Programmieren schwierig/zeitaufwändig), daher ist das Scheduling sehr primitiv. Durch Master/Slave-Funktionsweise ist das ein Single-Point-of-Failure.
  • Ethernet-Schnittstelle des Busmasters ist teilweise instabil (ENC28J60), wurde auch auf der Mailingliste dargelegt. Derzeit funktioniert es (einen Großteil der Zeit), aber hängt sich manchmal auf. Wir benutzen den NPM um den Busmaster zu powercyclen wenn das passiert.
  • Library/Code-Organisation ist schwierig für C/Mikrocontroller-Projekte, so haben wir z.B. derzeit ein Folder firmware-pinpad im rzl-hausbus Repository (damit wir ../lib verwenden können), was eigentlich getrennte Projekte sind.
  • Durch den Missbrauch von Patchkabeln ist unklar, welche Buchsen im RZL für Hausbus und welche für Ethernet genutzt werden (klar, kann man labeln). Statt die Anzahl an Geräten durch einen Switch erhöhen zu können, scheidet das bei Hausbus-Buchsen aus!

Alternativ-Vorschlag

Statt ein Bussystem mit Mikrocontrollern zu betreiben, würde ich gerne Geräte wie das Raspberry Pi (~700 MHz ARM Linux, <1 W Stromverbrauch, Ethernet, Strom via USB, kostet ca. 25 €) verwenden und einfach Ethernet nutzen. Die derzeitigen Kosten sind etwas unter 10 € für einen "großen" Hausbus-Teilnehmer. Im Vergleich zum Raspberry Pi ist der Zeitaufwand zum Programmieren / Basteln allerdings deutlich höher.

Die Idee hinter dem Hausbus war, dass die Teilnehmer miteinander sprechen können und nicht jeder sein eigenes Süppchen kocht. Um das zu fördern, schlage ich ein Konzept (und eine Library) vor, mit der man mit sehr wenig Aufwand Geräte im RZL betreiben kann, die miteinander interagieren und stabil laufen.

Konzept

  • Jeder Teilnehmer wird eigens mit Strom versorgt (5V USB), Netzteile dafür sind nicht teuer. Powercyclen ist einfach möglich, Stromversorgung funktioniert weiterhin, wenn andere Geräte explodieren.
  • Jeder Teilnehmer ist via Ethernet mit dem RZL-Netz (oder einem eigenen Netz, welches aus dem RZL erreichbar ist) verbunden. Dadurch können wir die im RZL vorhandene Ethernet-Infrastruktur nutzen und haben keinerlei Probleme auf der physikalischen Ebene.
  • Jeder Teilnehmer kann entweder via DHCP ins Netz (schnelle Experimente) oder eine statische IP konfigurieren (Registration via Wiki, wie gehabt).
  • Jeder Teilnehmer benutzt DNS (evtl. periodisch nach /etc/hosts gesynced als backup?) um andere Teilnehmer zu finden. Umkonfiguration erfordern damit keine Firmware-Updates anderer Teilnehmer.
  • Jeder Teilnehmer bietet seine Funktionalität und State via HTTP/JSON an (mit einem gemeinsamen Grundschema). Client/Server-Libraries für HTTP/JSON gibt es für jede Programmiersprache.
  • Es gibt einen Teilnehmer, der Logging/Monitoring bereitstellt. Weiterhin kann er (nach entsprechender Konfiguration) State abfragen und abspeichern (z.B. Temperaturwerte, Falscheingaben am Pinpad, …).

Beispiel: HTTP-API des Pinpad-Controller

GET /_/state (allgemein)

Ruft den kompletten state ab (z.B. für den Logging-Teilnehmer).

Antwort:

   {"pinpad.door": "locked",
    "pinpad.lastsync": 1321819942,
    "pinpad.wrongpins": 3,
    "pinpad.msg": "Willkommen im RZL"}

GET /_/state/pinpad.door (allgemein)

Ruft einen einzigen Wert ab (z.B. wenn ein anderer Teilnehmer den State monitored, in diesem Fall z.B. das Jail um den Status auf der Website zu haben).

Antwort:

   {"pinpad.door": "locked"}

POST /_/state (allgemein, ggf. authentifizierung nötig)

Request:

   {"pinpad.msg": "Offen ab 19:00"}

POST /_/reboot (allgemein, authentifizierung nötig)

POST /unlock_door (spezifisch, authentifizierung nötig)

POST /lock_door (spezifisch, authentifizierung nötig)

Beispiel: Code im Pinpad

   # Angenommen der Status ist in $sensor
   if ($sensor == 0) {
       rb_set_state("pinpad.door", "locked");
   } else {
       rb_set_state("pinpad.door", "open");
   }
   # Bei Falscheingabe
   rb_inc_state("pinpad.wrongpins");
   # LCD bespielen
   if (rb_get_state("pinpad.msg") != $old_msg) {
       update_lcd(rb_get_state("pinpad.msg"));
       $old_msg = rb_get_state("pinpad.msg");
   }

Umsetzung

sECuRE hat einen funktionierenden Raspberry Pi. Cross-kompilierte Go-Programme laufen darauf.

Angepeilte Milestones:

  1. Eigenes Image fürs Raspberry Pi bauen (read-only), welches sich stabil via DHCP ins Netz klemmt und via IPv4 + IPv6 ansprechbar ist. iptables sollte vorhanden sein.
  2. Kommunikation via UART mit dem (neuen) Pinpad-Frontend implementieren.
  3. Kommunikation mit dem Hometec+0x implementieren.
  4. tuerstatusd ersetzen, pin-sync implementieren

Die oben erklärte HTTP-API habe ich in einer Go-Library (und Beispiel) umgesetzt: https://github.com/raumzeitlabor/hausbus2-go

tiefpunkt arbeitet an einer Implementierung des Hausbus2 in Python: https://github.com/raumzeitlabor/hausbus2-python

Sicherheit

Bisher ist ja noch nicht so ganz klar, wie das Sicherheitskonzept aussieht.

Vorschlag:

  • HTTP erst gar nicht unterstützen, sondern nur via HTTPS arbeiten (vermeidet Fehler und ist weniger Aufwand)
  • Bei Aktionen (z.b. Tür öffnen/schließen) nur via HTTPS und Authentifizierung zulassen. Das würde aber natürlich auf Dauer problematisch, da man am Ende nicht mehr weiß, welches Gerät wo Zugriff hat - bisher keine Lösung.

Events

  • Bisher gibt es keine Möglichkeit, auf "Events" zu lauschen. Das soll geändert werden.
  • Beispielsweise gibt es das Event "Raum wird geschlossen". Irgendein Hausbus2-Teilnehmer könnte auf dieses Event horchen und somit den Raumstatus setzen sowie das Licht ausschalten.
  • Events erfordern Multicasting, z.b. auf IP-Ebene.

Message Queues

Das bisherige Konzept sieht ein Pull-Prinzip vor. Ein Teilnehmer, der über Events oder Sensorwerte benachrichtigt werden möchte, muss aktiv Geräte pollen, um den aktuellen Status zu erfahren, und somit eine eventuelle Änderung mitzubekommen.

Nachteile:

  • Geräte müssen bekannt sein, nachträgliches Hinzufügen ist nur schwierig möglich.
  • Polling ist doof.

Alternative: Eine Message Queue.

Nach einigen Überlegungen wurde MQTT als Protokoll ausgewählt. Gründe für die Auswahl:

  • Lightweight
  • Leicht zu implementieren, Libraries für viele Sprachen
  • Last-Will-Funktion
  • Inaktive Devices bekommen Meldungen an sie, sofern gewünscht, vom Broker gecacht und später nachgereicht.
  • Authentifizierung, etc. möglich.

Die Hausbus2 Python-Library unterstützt bereits MQTT.

Wichtige Topics:

  • /device/<devicename>/system
    Systemdaten des Geräts, automatisch bereitgestellt durch die verwendete Library
  • /device/<devicename>/temperature
    Temperatur-Sensor-Daten, falls sie anfallen.
  • /monitor
    Topic für den Last Will,

Angebundene Geräte

tiefpunkt.vm.rzl

  • Hostet den MQTT-Broker (mosquitto)
  • hausbus2-exporters. Exportieren Sensordaten zu aktuell Cosm und OpenTSDB

Heizungssteuerung (heizung.rzl)

  • Temperatursensoren
  • Fensterstatus