PRTG Pluggit

In meinen gut gedämmten Haus mit einer Luftwechselrate unter 0,7 ist eine kontrollierte Wohnraumlüftung (KWL) natürlich zwingend erforderlich. Bei mir macht das ein Lüftungsgerät von Pluggit (Avent P 310), welches natürlich einige Daten misst, z.B. 4x Temperatur und mit den passenden Sensoren auch noch Luftfeuchte, CO2 etc. Die Anzeige am Gerät selbst beschränkt sich aber auf 4 LEDs für die Lüfter-Stufe, und eine Fehler-LED. Ansonsten gibt es noch vier Tasten. Hinten gibt es aber einen Rs485-Ausgang und einen Ethernet-Ausgang. Das wäre dann doch mal ein Ansatz die Daten in PRTG zu übernehmen. Die "Fernsteuerung" von Pluggit habe ich nicht und eine Recherche im Internet ergibt einen Preis um 200€. Da ist ein billiges Tablet und die passende App günstiger.

IOS PluggApp https://itunes.apple.com/DE/app/id698715680 (6,99€)

Android PluggApp Free https://play.google.com/store/apps/details?id=net.ektos.uvc&hl=de (0€)

Wobei ein billiges vorhandenes altes Android Tablet und die Software vielleicht sogar mehr Sinn macht. Mich hat aber neben dem "Bastelgedanken" schon interessiert, wie sich die Daten über die Zeit verändern. Und da in de Box natürlich kein Datenlogger ist, habe ich PRTG mal schnell um einen Pluggit-Sensor erweitert.

Anscheinend gibt es auch kein einfaches Web Interface sondern der Ethernet-Anschluss ist wohl wirklich nur ein Modbus-Seriell (RS485) auf Ethernet-Umsetzer.

Recherche im Internet

Es ist gar nicht so einfach weitergehende Informationen zu finden, denn die API scheint nicht wirklich offen gelegt zu sein. Ich sehe in der Fritz!Box natürlich die vergebe IP-Adresse und auf einen "PING" reagiert das Lüftungsgerät auch. Aber auf 80/443 ist keine Verbindung zu erreichen. Aber der per TCP erreichbare Port 502 (MODBUS) dürfte ein Zugang sein. Dazu gibt es sogar eine Beschreibung von Pluggit:

Pluggit UVp Controller
http://www.pluggit.com/fileserver/files/1413/609560454939420/21_08_2015_pluggit_uvc_controller_modbus_tcp_ip.pdf
Anscheinend passen diese Werte bei meinem AVENT 310 mit der neuen Firmware besser

Vorabversion der "Pluggit Controller Modbus Registers Table"
http://www.pluggit.com/fileserver/files/1413/609560454939420/21_10_2013_modbus_addresses.pdf
Mittlerweile veraltet

Mir reicht es aber, wenn ich einfach nur Sensoren auslese. Ich muss nicht gleich die Anlage umsteuern oder konfigurieren. Dafür bietet Pluggit ja schon alleine ein Programm (iFlow) an.

Modbus und TCP

Ok, wenn es keinen Browser, kein SNMP, keine REST-Api o.ä. gibt, dann muss eben ModBUS angesprochen werden. Bei einem "TELNET" auf Port 502 habe ich eine Verbindung bekommen und "wirre Zeichen". Das passt aber, denn Modbus ist eigentlich ein serielles Protokolle mit Bytes und keine Text oder XML-Strukturen. Also muss ich mit PowerShell o.ä. anfangen, diesen Weg selbst zu programmieren. Auch hier seht erst mal Einlesen auf der Agenda.

Aus dem PDF von Pluggit habe ich folgendes extrahiert:

  • Zielport: 502/TCP
    Das ist der Standard ModBUS Port und erst mal nicht überraschend
  • Befehl: Read holding registers (0x03);
    Ich will nur lesen, also sende ich ein 0x03
  • Register auslesen
    Als Check würde ich folgende Register anfordern
    • 40113-40141  Temperaturen T1-T5
    • eventuell später weitere, z.B. Betriebszustand und Alarmzustand, Filterlebensdauer etc
  • Alles in 32bit
    Beim Modbus scheint 16Bit eher Standard zu sein aber das Pluggit liefert immer 32bit werte, d.h. ein Registerwert setzt sich aus zwei aufeinanderfolgende Register zusammen

Pluggit stellt die Android-App kostenfrei zur Verfügung, so dass ich diese einfach nutzen und mit WireShark mitschneiden konnte: Zuerst hat mich interessiert, wie die App denn das Gerät findet. Die Methode war einfacher als erwartet. Die App scannt einfach alle IP-Adressen im gleichen Subnetz ab um dann erst Port 7 und dann Port 502 anzusprechen.

Und dann wird auch schon direkt "Modbus/TCP" gesprochen, was von WireShark auch decodiert wird. Mit einem Filter auf "mbtcp" sieht man dann alle Anfragen:

Neben der ursprünglich erwarteten Übermittlung des Function Code, Reference Number und Workcount fehlt hier komplett die SlaveID aber auch die CRC-Prüfsumme, die bei Modbus normalerweise mitkommt. Dafür kommt der Modbus/TCP Overhead dazu, dass eine Transaktionsnummer und die Länge hochgezählt wird. Das sollten wir ja auch hinbekommen. Der Modbus-Chip trägt als VendorID übrigens "Dantherm"(https://www.dantherm.com/de/ ?) die auch mit Lüftungen etwas zu tun haben.

Sicherheit ?
Eigentlich ist der klassische Modbus schon allein elektrisch ein geschlossenes System. Klemmt man aber einen Modbus/TCP-Host an ein Haus-LAN, dann sollte man nicht erwarten, dass hier eine erweiterte Sicherheit vorhanden ist. Ich habe nirgends ein Kennwort gesehen und selbst wenn, wäre es unverschlüsselt. Im "Home-Bereich" kann man darüber hinwegsehen. Aber bitte nicht bei kritischen Systemen.

Pluggit per PowerShell abfragen

Ich habe das Skript einfach gehalten und einfach die Pakete gesendet, 1Sek gewartet und dann die Daten auf einen Schwung eingelesen. Mehr als ein paar Byte sollten es nicht sein, so dass ein Buffer von 1024 Byte immer ausreichen sollte. Nutzen Sie dieses Sample bitte nicht als Vorlage für einen TCP-Zugriff mit großen Datenmengen. Da sollten Sie schon in einer Schleife den Buffer bis zum Ende lesen.

Da ich einfach einen 1024byte Buffer als Rückgabe definiert habe, ist aber genug platz um die ersten 100 Register zu laden. Hier der Request:

Die Antwort war dann schon interessant, denn wenn man genau hinschaut, sieht man hier z.B. den "Device-Name" wie er mir auch in der Android App angezeigt wird.

Man muss nur die Buchstaben etwas verdrehen, das aus einem "eVtnlitaoi nnuti" ein "Ventitation nuti" wird. Zählt man dann Zellen ab, dann ergibt sich

Feld Modbus Feld Wert Bedeutung

00

 

03

Function Code

01

 

c8 = 200dez

200 Bytes folgen. Da das aber nur ein 8bit wert ist, sollte man wohl nicht mehr als 256 Bytes auf einmal abfragen !

02/03

40001

c4 e0

Funktion unbekannt

04/05

40002

50 b8

Funktion unbekannt

06/07
08/09

40003
40005

37 c3 02 00

Systeminformation, d.h. was ist alles installiert

10/11
12/13
14/15
16/17

40005
40006
40007
40008

 

Seriennummer

18/19
20/21
22/23
24/25
26/27
28/29
30/31
32/33

40009
40011
40013
40015
40017
40019
40021
40023

 

Das ist der Systemname, der etwas kniffliger sortiert ist

34/35/36/37

40025

 

Firmware Version

266/267

40133

 

Temperatur T1 Außenluft eingehend vor dem Wärmetauscher

268/269

40135

 

Temperatur T2 Zuluft zu den Auslässen in den Räumen

270/271

40137

 

Temperatur T3 Abluft von den Räumen zum Lüftungsgerät

272/273

40139

 

Temperatur T4 Fortluft nach draußen nach dem Wärmetauscher

Bei Modbus ist ein Register per Default immer 16bit, also zwei Bytes. Pluggit verwendet für die Werte aber immer 32bit, also 4 Byte. Daher sind immer zwei Modbus Register zu kombinieren. Die Startposition und Länge beim Modbus-Request bezieht sich also auf die Register (also immer 2 Byte) um also die Temperatur T1 zu erhalten, muss man die Modbus-Felder 40133 und 40135 abfragen. Die Felder beginnen bei 40001, also muss man als Startwert 132 eintragen und einen WordCount 2. Pluggit packt die Temperatur in 32bit-Zahlen, also zwei Modbus Register. Ich nutzt aber 8 als Wordcount, damit ich auf einen Schwung gleich T1 bis T4 bekomme

Die Antwort darauf sieht dann wie folgt aus:

Ich habe zwar nur 8 Werte angefordert aber mit Header etc., sind es insgesamt 25 Bytes. Nun steht da leider nicht die Temperatur als "String" drin, sondern als 2 Byte-Wert, den man erst noch mal konvertieren muss. Pluggit hat in seinem PDF zum Modbus ein Bild:

Damit ist zwar die Reihenfolge und Wertigkeit der Bits und Bytes beschrieben und dass immer 4 Bytes zusammen gehören. Aber abgesehen davon, dass die Modbus Adresse 40089 laut der anderen Tabelle gar nicht die Temperatur enthält, ergibt sich hieraus nicht wie die Bits zu interpretieren sind. Allerdings ist der Typ" Float" bekannt und Es gibt mit der IEEE 754 eine Beschreibung, wie Computer solche Floats intern als Bits speichern.

Mit C++ könnte man nun einfach die vier Bytes als "Float" ansprechen und hätte den Wert. Bei einem Single ist das höchste Bit das Vorzeichen, die nächsten 8 Bits sind der Exponent und die verbliebenen 23 Bits dann der Wert. Solche direkten Speicherzugriffe sind im Managed Code aber verpönt und dafür gibt es entsprechende Methoden zur Konvertierung.

In meinem Fall habe ich für jede Temperatur erst einmal 4 Byte bzw. 32bit, die ich in die richtige "Reihenfolge" bringen muss, um dann diese zu konvertieren. Ich habe bei einer Abfrage die folgende Zahlenreihe bekommen. Die habe ich dann über dem IEE754-Konverter (http://www.h-schmidt.net/FloatConverter/IEEE754.html) als Hex-Werte eingegeben und erhalten:

ModbusWerte High Bit in IEEE753 Dezimalumrechnung Anzeige in App Wert

 25 107 65 42

65 42

10.625

11 Grad Frischluft von draussen

T1

126 113 65 158

65 158

19.75

20 Grad Zuluft zu den Räumen

T2

 94 102 65 171

65 171

21.375

21 Grad Abluft aus den Räumen

T3

123 228 65 71

65 71

12,4

11 Grad Abluft nach draussen

T4

Damit war zumindest schon mal klar, dass ich die richtigen Eingangswerte habe und die zweite Zahl das höhere Bit ist. also muss ich bei der Berechnung die Bytes vertauschen, dass der zweite Wert vor dem ersten Wert ist. Aber auch dann musste man noch "Little-Endian/BigEndian" betrachten und das gesamte Array noch mal "drehen". Aus den in der Reihenfolge 1-2-3-4 gelieferten Bytes muss erst ein Array aus Byte 2-1-4-3 erstellt und dann dem Converter zugeführt werden. bzw. in PowerShell startet ein Array bei 0. für die Abfrage selbst habe ich dann einfach wieder eine TcpClient-Class aus dem .NET-Framework genutzt.

Ich habe diese Schritte absichtlich "einfach" und unabhängig von anderen Libraries gehalten. Es gibt aber wohl auch Modbus/TCP Libraries, die sicher interessant sind, wenn viele Geräte mit unterschiedlichsten Sensoren einzulesen sind.

PRTG-Sensor

Nachdem ich die Zahlen letztlich ermittelt habe, konnte ich dann auch den PRTG-Custom Sensor dafür bauen.

Hinweis
Das ist wirklich ein "schneller" Code. Ich hätte die Konfiguration sicher auch in eine CSV/XML-Datei auslagern können und über Parameter dann schon einen generischen Modbus-Sensor zusammen bauen können. Ich habe aber nur genau ein Gerät mit vier Werten.

Das Skript ist sehr überschaubar und erwartet als Parameter einfach die IP-Adresse des Pluggit-Geräts. Sie können diese Information über die PRTG-Parameter übergeben oder direkt im Skript ändern.

prtg-pluggit.20160107.ps1.txt
Bitte das Script nach dem Download in das Verzeichnis "C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML" ablegen und "entsperren", da es als "Aus dem Internet" sonst nicht vertrauenswürdig zur Ausführung genutzt wird.

Im Gegensatz zu der App habe ich mit dem PRTG-Sensor natürlich nicht das schöne Bild mit dem Haus und den Kreuzwärmetauscher und kann auch keine Aktionen ausführen. Aber ich nutze die App nicht wirklich, da die Lüftung einfach im Hintergrund vor sich hin werkelt. Und die PRTG-Abfrage schließt die Nutzung der App ja nicht aus. Bis zu drei TCP-Connections kann das Pluggit-System bedienen.

Mein aktueller Sensor kann aktuell nur die vier Temperaturen auslesen und in PRTG anzeigen lassen. Zudem läuft der Sensor noch nicht lange, so dass das Beispielbild nicht viel zeigt.

Man kann aber schon sehen, dass die Temperatur der Außenluft über den Tag hinweg wechselt. Aber auch die beiden Innentemperaturen (T2/T3) zeigen eine, wenngleich niedrigere, Schwankung. Die kleinen Hügel gegen 09:00pm am 1.Mai zeigen eine Temperaturerhöhung in der Abluft, verursacht durch die Dusche bei T2, T3 und T4. Nur die Zuluft hat das systembedingt nicht verändert. Ich bin gespannt, wie in einigen Wochen und Monaten sich die Ausgaben entwickeln und was man aus den Daten extrahieren kann.

Update

Mittlerweile gibt es von Pluggit eine aktualisierte Version der ModBusTCP-Beschreibung. Ich habe daher den Code etwas erweitert, um die Aufrufe mehrerer Parameter zu trennen und damit frei adressieren zu können. In dem Zuge wurde auch der Converter für die Daten erweitert, da ich nun nicht mehr nur 4 FLOAT-Werte umsetzen muss, sondern auch IN32, INT16, Strings u.a. verarbeiten will. Einige Werte müssen dazu vorher "gedreht" werden, d.h. 1-2-3-4 wird zu 4-3-2-1 oder paarweise getauscht werden, d.h. 1-2-3-4 wird 2-1-4-3 oder auch beides. Das alles ist nun in einer Funktion abgelegt.

Aufgabe Aufruf Ergebnis

Seriennummer abfragen

modbusread $remoteHost $port 40005 8 uint64 flip

1406201332822

Systemname

modbusread $remoteHost $port 40009 32 string flip

Ventilation unit

Firmware Version

modbusread $remoteHost $port 40025 2

2 40

Systemzeit abfragen

modbusread $remoteHost $port 40109 4 time

Dienstag, 6. Jan 2016 23:26:57

Drehzahl von Lüfter 1

modbusread $remoteHost $port 40101 4 float

2200,5

Drehzahl von Lüfter 2

modbusread $remoteHost $port 40103 4 float

2160,5

Filterlebenszeit in Tagen

modbusread $remoteHost $port 40555 4 uint32 flip

274

Das sind nur ein paar Testaufrufe, mit denen ich die Funktionen verifiziert habe.

Leider fehlt dem Lüftungsgerät ein echter Luftmengenmesser. Anhand der Drehzahl alleine lässt sich eher nicht ermitteln, wie viele Kubikmeter Luft ausgewechselt wurde. Daher macht auch eine Berechnung eines Wirkungsgrades anhand der Temperaturdifferenzen so nicht viel Sinn.

Monitoring von Außen

Um den Stromverbrauch zu ermitteln, habe ich die  Versorgung über ein Edimax SP2101W hergestellt, welcher die Leistung des Geräts misst. Man kann gut sehen, dass auch von extern zumindest ermittelt werden kann, wann welche Stufe wohl aktiv ist.

Das Avent P130 braucht bei mir ca. 52W auf Stufe 2 und 25W auf Stufe 1

Weiterentwicklung

Aktuell hat mein Lüftungsgerät nur diese vier Temperatursensoren. Das Avent P310 Wohnraumlüftungsgerät kann noch mit Sensoren für Luftgüte und Feuchtigkeit ausgestattet werden. Die sind bei mir (noch) nicht eingebaut und daher auch nicht abzufragen. Auch Luftdruck und Menge etc. wären interessante Daten um vielleicht sogar offene Fenster zu erkennen. Ohne Luftmenge und Feuchtigkeit kann aus den Temperaturdifferenzen nicht der Wirkungsgrad ermittelt werden. Aber auch ohne zusätzliche Sensoren möchte ich zumindest das aktuelle Programm und den Fehlerstatus auslesen.

Dann würde ich aber doch langsam dazu umschwenken jeden Wert einzelne zu holen und eine umfangreichere Konverter-Funktion einzubauen, was dann letztlich  zu einem generischen Modbus-Sensor führen wird, bei dem man den Kanalnamen mit dem Modbus Feld und einer Inhaltskonvertierung als Konfigurationsdatei erstellt und ein generischer Sensor über Parameter gesteuert wird. Vielleicht nehme ich mir später noch mal die Zeit dazu. Denkbar wäre dann natürlich auch eine "Selbstkonfiguration", indem das Gerät per IP-Subnetzscan nach einem kompatiblen Modbus/TCP-Device sucht. Aber vielleicht will ich das lieber doch nicht. Insgeheim wünsche ich mir schon einen "Read Only"-Schalter am Gerät, um Umkonfigurationen zu blockieren.

Das Gerät hat auf der Rückseite auch einen klassischen RS485/Modbus-Anschluss. Vielleicht baue ich basierend RaspberryPI, Arduino o.ä. doch noch mal eine WebBox.

Pluggit IFlow

Der Vollständigkeit halber sei noch erwähnt, dass es auch von der Firma Pluggit eine Software "iFlow" zur Konfiguration des Lüftungsgeräts gibt. Allerdings kann es nicht über TCP arbeiten, sondern erwartet einen direkten Anschluss am lokalen PC. Über diese Software kann man wunderbar die aktuellen Parameter der Geräts auslesen. für den Lesezugriff als Benutzer benötigen Sie kein Kennwort. Es gibt aber durchaus noch eine "Installer" und "Admin"-Ebene, die in dem Programm dann erweiterte Funktionen freischaltet. Sie sollten aber wissen, was Sie damit dann auch anstellen.

Benutzer: *leer*
Installer: 1234
Admin: DAH1234

Weitere Links