Loxone Config – Modbus synchron lesen – Zusammenfassung, Dokumentation und Verbesserungen

Die Informationen dieser mehrteiligen Reihe mit einer Lösung zum synchronen Auslesen von vielen Registern über Modbus-TCP in der Loxone Config sind doch etwas über die Beiträge verstreut. Sie bedürfen einer Zusammenführung und Konsolidierung. Und genau das gibts in diesem Artikel: eine Gesamtdokumentation bisheriger und neuer Funktionalitäten und die aktuellsten, verbesserten Sourcen zum Download.

Teil 1 dieser Reihe hatte sich noch damit beschäftigt mittels Loxone-Bordmitteln bis zu 64 zusammenhängende/gleichzeitig gelesene Bits zu verarbeiten und daraus entweder 2 oder 4 Werte herauszurechnen und anzuzeigen. Ab Teil 2 war der Lösungsansatz dann vollständig picoC basiert und ging weit über 64 Bit hinaus. Die Gesamtlösung wird nun nachstehend zusammengefasst und dokumentiert.

Die Kurzfassung lautet: Mit dem Einsatz dieser Lösung kann man größere Mengen aufeinanderfolgender Register(maximal 252 Byte) synchron/blockweise lesen und beliebige bis zu 26 Werte anzeigen, unabhängig von deren Datentypen. Die aktuellsten Sourcen hierzu finden sich am Ende dieses Artikels.

Nun zur Langfassung… 🙂

Wozu das Ganze, was sind die Anwendungsmöglichkeiten?

  1. Am offensichtlichsten und meistdiskutiertesten ist mit Sicherheit das Thema mit den Skalierungsfaktoren. Werden Werte asynchron zu deren Skalierungsfaktoren gelesen, kann es zu temporären Ausreißern führen. Datenerfassung, Zählerbausteine, Grafiken, Statistiken – allesamt betroffen.
  2. Auch manche fachliche Werte müssen zeitgleich gelesen werden, um vernünftige Berechnungen oder Auswertungen machen zu können. Sie ergeben nur mit den korrekten Pendants Sinn. Ich gehe jetzt nicht darauf ein, aber einige Begriffe hierzu wären: Verlustleistungen, Wirkungsgrade, Phasenleistungen, Volt/Amp/Watt, Umwandlungswerte AC/DC etc..
  3. Viele Einzelabfragen belasten das Device zudem mehr als einige wenige Abfragen, im Idealfall vielleicht sogar nur eine einzige.


Voraussetzungen

Die hier beschriebene Lösung kann über Modbus-TCP Adressbereiche am Stück/blockweise/synchron auslesen. Hat man also eine Startadresse, dann werden davon ausgehend eine Menge an definierten Bytes gelesen. Unterstützt werden Modbus

  1. Read Holding Registers (03)
  2. Read Coils (01)

Der gelesene Adressbereich muss also zusammenhängend sein, darf keine reservierten Bereiche enthalten(führt zu Auslesefehlern) und darf in Summe maximal 252 Bytes groß sein(Modbusspezifikation).

Und was kann die Lösung nun?

Mit Blick auf das nachstehende Bild, zunächst eine allgemeine Erklärung. Details finden sich dann in den Beispielen weiter unten.

Von links nach rechts: Ein Textgenerator-Baustein enthält die Konfiguration und wird an die Eingangskanäle eines Loxone Config-Programmbausteins angeschlossen. Dieser liest per Modbus-TCP Daten und zeigt diese an. Reichen die Ausgabekanäle nicht, so gibt er den Rest weiter an den zweiten Baustein.

Noch ein paar Details zum Textgenerator-Bausteins(Tr-Eingang aktivieren! 🙂 ):

  • IP-Adresse und Port (und ggfls. Modbus Id)
    • Wird nach dem Port nichts mehr angegeben, so wird DeviceId 1 angenommen. Eine andere ModbusId würde kommasepariert angegeben werden. Mit einer Id von 3 also z.B. 192.168.1.10:502,3
  • Startadresse in Hex-Format. Hier gibts im Internet diverse Rechner zum Umrechnen von Dezimal nach Hex.
  • Datentyp-Angaben(darauf wird in den Beispielen eingegangen)
  • Angabe, in welchem Format das Device antwortet: Big-Endian(=1) oder Little-Endian(=0)

Wer die visuelle Konfiguration nicht mag/braucht, kann das ganze auch direkt im Code einstellen. Gleich die ersten Zeilen sind dafür gedacht, dort dokumentiert und trivial zu verstehen.

Noch ein paar Erläuterungen zum linken Programm-Baustein mit picoC Code: Dieser liest alle 10 Sekunden(einstellbar) per Modbus-TCP Daten und zeigt diese dann auch an(O1 bis O13). Bei mehr als 13 Ausgabewerten wird ein Hex-String an den rechten Programmbaustein weiter- und dort ausgegeben. Sofern man maximal 13 Ausgabewerte hat, wird der rechte Baustein natürlich nicht benötigt. Mit beiden Bausteinen zusammen hätte man also 26 Ausgabekanäle. Das müssen aber nicht zwangsweise 26 zusammenhängende Adressen vom Start weg sein. Wie das?

Es gibt da noch einen eingeführten Pseudodatentypen IGNORE16. Man kann also z.B. einen Bereich mit 40 Werten auslesen, aber gezielt Werte ausblenden bzw. anzeigen. Damit verschwendet man keine wertvollen Ausgabekanäle. Eine Erläuterung hierzu findet sich im ersten Beispiel.

Generell werden drei verschiedene Arten des Auslesens unterstützt:

  • Numerische Datentypen
  • Strings
  • Coils (also Bit-Register)

Die Datentypen im Detail:
0 = IGNORE16
1 = UINT16
2 = INT16
3 = UINT32
4 = INT32
5 = FLOAT16
6 = FLOAT32
7 = STRING16
8 = STRING32
9 = COIL

Die folgenden ersten beiden Beispiele sind mit einem SolarEdge Wechelrichter umgesetzt, das letzte Coil-Beispiel mit einer Wärmepumpe.



Beispiel 1 – 25 numerische Werte synchron auslesen und anzeigen

Auf die allgemeine Konfiguration im Textgenerator-Baustein wurde bereits eingegangen. Deshalb die Konzentration auf die Datentyp-Konfiguration. Diese Variante ist anwendbar für die Datentypen 1 bis 6 aus der Liste:


Der interessante Punkt des Bildes ist nun der folgende:

Startend bei der Hex-Adresse 9CFE, dezimal 40190, werden 31 Werte ausgelesen, aber nur 25 angezeigt:

  • 5 Werte vom Datentyp „2“(INT16)
  • 4 Werte mit Pseudodatentyp „0“(IGNORE16)
  • 5 Werte vom Datentyp „2“(INT16)
  • 2 Werte mit Pseudodatentyp „0“(IGNORE16)
  • 15 Werte vom Datentyp „2“(INT16)

Die numerischen Datentypen 1 bis 6 aus der Liste können beliebig vermischt werden. Man kann also FLOAT, INT mit 16 oder 32 Bit in beliebiger Reihenfolge gleichzeitig abgreifen, sofern diese in einem zusammenhängenden Adressblock auf dem Device verfügbar sind.

IGNORE16 sorgt dafür, dass zwar 2 Byte gelesen, aber nicht angezeigt werden. Würde man also z.B. einen FLOAT32 Wert „überspringen“ wollen, so würde man 2×0 angeben. Entsprechend beim Ignorieren von z.B. zwei FLOAT32 und einem UINT16 Wert dann 5×0.

Sinnvollerweise hat man natürlich eine passende Dokumentation der Register neben sich…

Wird das Ganze dann auf den Miniserver übertragen und das Programm beginnt zu laufen, werden je nach Stand folgende drei Informationen im linken Hauptbaustein angezeigt.


1) Lesen der Bytes über Modbus-TCP

Aktives schicken der Anfrage und Lesen der Ergebnisbytes.


2) Verarbeitung der empfangenen Daten

Zur besseren Übersicht, wird die Anzahl an empfangenen Bytes vom Device ausgegeben. Zieht man davon 9 Bytes Metadaten ab, dann erhält man die Anzahl an Bytes, die der eigenen Angabe an Datentypen entsprechen sollte.


3) Wartezustand und Statusinformationen

Nach der Verarbeitung wird „Reading ok“ ausgegeben und die Werte werden auf den Ausgabekanälen angezeigt, samt deren passenden Registeradressen wie im Bild dargestellt. Gerade beim Überspringen von Adressen zur Kontrolle hilfreich.



Beispiel 2 – Auslesen und Anzeigen von 4 Werten vom Datentyp String

Liest man String-Datentypen aus, so werden diese am Ausgang „Txt2“ des linken Programm-Bausteins gesammelt ausgegeben. Sie dienen ohnehin nur zur Info und so viele Textausgänge gäbe es auch gar nicht.

Hierfür wird ein Textgenerator-Baustein mit einer anderen Startadresse(hier 9CBB) erstellt und angeschlossen. Hier im Beispiel ist es eine Mischung aus STRING16 und STRING32 Datentypen. Und ein UINT16 wird ebenfalls noch angezeigt.



Beispiel 3 – 13 Coils synchron auslesen und anzeigen

Coils sind Bit-Register und von daher anders zu behandeln. Die Anzeige sollte deshalb nicht mit „normalen“ Registern vermischt werden. Wenn z.B. 9 Coils gelesen werden, dann sind hierfür 2 Byte an Daten notwendig, wobei vom zweiten Byte dann nur das erste Bit relevant ist.

Mit diesem Wissen nun zum Beispiel mit 13 Coils. Die Ausgabe an den Kanälen erfolgt so, dass jeweils ein Byte an einen Ausgang gelegt und ein Loxone Binärdekoder angeschlossen wird. Sieht im Ergebnis dann folgendermaßen aus:

Ich lese hier startend bei der Registeradresse 80 (in Hex 0050) also 13 Coils(Datentypwert 9) synchron aus und lasse diese anzeigen. Die Ergebnisse sind im Screenshot von oben nach unten zu lesen. Das erste Bit entspricht also dem Wert von Register 80, das nächste 81 usw..


Wer mag – die Sourcen

Für den linken Programm-Baustein mit der Modbus-Connection nachstehend der picoC-Code.

Für den rechten Programm-Baustein wird ein Decodier- und Anzeigecode benötigt. Nachstehend zum Download.



Feedback ist natürlich jederzeit willkommen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert