Forum: Haus & Smart Home MBus Stromzähler und openHAB3


von Klaus C. (Gast)


Lesenswert?

Hallo,

ich habe einen MBus-Stromzähler über einen MBus-Serial Adapter an einen 
Rasperry Pi (Zero) angeschlossen.
Mit libmbus (https://github.com/rscada/libmbus) kann ich den Zähler 
auslesen.
1
mbus-serial-request-data -b 2400 /dev/ttyAMA0 0
2
<?xml version="1.0" encoding="ISO-8859-1"?>
3
<MBusData>
4
5
    <SlaveInformation>
6
        <Id>........</Id>
7
        <Manufacturer>ELT</Manufacturer>
8
        <Version>1</Version>
9
        <ProductName></ProductName>
10
        <Medium>Electricity</Medium>
11
        <AccessNumber>1</AccessNumber>
12
        <Status>04</Status>
13
        <Signature>0000</Signature>
14
    </SlaveInformation>
15
16
    <DataRecord id="0">
17
        <Function>Instantaneous value</Function>
18
        <StorageNumber>0</StorageNumber>
19
        <Tariff>1</Tariff>
20
        <Device>0</Device>
21
        <Unit>Energy (10 Wh)</Unit>
22
        <Value>0</Value>
23
        <Timestamp>2022-01-23T10:39:34Z</Timestamp>
24
    </DataRecord>
25
...

Auf einem anderen Computer läuft openHAB3 und ich möchte gerne die Daten 
des ausgelesenen Stromzählers hier darstellen.
Wie könnte ich ein "Interface" zwischen dem Rasberry Pi Zero, welcher 
den Stromzähler mit libmbus auslesen kann, und dem openHAB3 auf dem 
anderen Computer herstellen?

von Klaus C. (Gast)


Lesenswert?

die Daten auf den openHAB3 Computer zu bekommen klappt mit ser2net.

Wie aber kann ich die Daten der XML-Ausgabe am elegantesten in openHab3 
einbinden.

Wie würdet ihr das machen?

von Sebastian L. (sebastian_l72)


Lesenswert?


von Klaus C. (Gast)


Lesenswert?

Sebastian L. schrieb:
> st https://www.openhab.org/docs/configuration/persistence.html bekannt?

Nicht wirklich, bin ziemlich unerfahren was openHAB3 angeht.
"openHAB can store data over time; this is known as persistence. The 
data may be retrieved at a later time, for example to restore your 
system after startup, or to prepare graphs for display on a UI."

Bin mir jetzt nicht im Klaren, wie ich die XML-Ausgabe eines lokalen 
Linux-Befehls in die persistence Datenbank bekomme.
Vielleicht kann mir einer einen Hinweis geben.

von Klaus C. (Gast)


Lesenswert?

Ginge es nicht eher hiermit?
[[https://www.openhab.org/addons/transformations/exec/]]

von Klaus C. (Gast)


Lesenswert?

Sebastian L. schrieb:
> Ist https://www.openhab.org/docs/configuration/persistence.html bekannt?

@Sebastian L.
Was möchtest Du mir damit sagen?

von N. M. (mani)


Lesenswert?

Klaus C. schrieb:
> Ginge es nicht eher hiermit?
> [[https://www.openhab.org/addons/transformations/exec/]]

Wohl eher https://www.openhab.org/addons/transformations/xpath/

Der Raspi könnte es natürlich auch von XML in JSON konvertieren und an 
den MQTT Broker in Openhab senden (falls vorhanden). Wobei du dann auch 
https://www.openhab.org/addons/transformations/jsonpath/ benötigst.
Das wird allerdings vermutlich öfter benötigt je nach dem was du alles 
einbinden möchtest.

von Klaus C. (Gast)


Lesenswert?

N. M. schrieb:
> Wohl eher https://www.openhab.org/addons/transformations/xpath/

Das klingt interressant.
Wie ich schon schrieb, ist openHAB3 relativ neu für mich.
Ich habe mich also in die Console eingeloggt und 
openhab-transformation-xpath installiert.
1
openhab> feature:install openhab-transformation-xpath
Auf dem Raspi wo openhabian installiert ist, kann ich mit dem Befehl
1
$ mbus-tcp-request-data  IP-ADRESSE  PORT 0
den Energiezähler abfragen. Die Ausgabe ist z.B.
1
<?xml version="1.0" encoding="ISO-8859-1"?>
2
<MBusData>
3
4
    <SlaveInformation>
5
        <Id>12345678</Id>
6
        <Manufacturer>ELT</Manufacturer>
7
        <Version>1</Version>
8
        <ProductName></ProductName>
9
        <Medium>Electricity</Medium>
10
        <AccessNumber>39</AccessNumber>
11
        <Status>04</Status>
12
        <Signature>0000</Signature>
13
    </SlaveInformation>
14
15
    <DataRecord id="0">
16
        <Function>Instantaneous value</Function>
17
        <StorageNumber>0</StorageNumber>
18
        <Tariff>1</Tariff>
19
        <Device>0</Device>
20
        <Unit>Energy (10 Wh)</Unit>
21
        <Value>17</Value>
22
        <Timestamp>2022-01-24T18:32:16Z</Timestamp>
23
    </DataRecord>
24
...und so weiter bis Data Record id="19"
Wie muss ich jetzt vorgehen um die obige XML-Ausgabe mit dem "XPath 
Transformation Service" auszuwerten?
Dabei ist mir nur die grobe Vorgehensweise wichtig und keine 
Detailangaben.
Aus der Beschreibung auf der Webseite werde ich nicht so richtig schlau.
Muss ich die Ausgabe von "mbus-tcp-request-data" mit einem Webserver 
bereitstellen und dann ein Binding installieren, was den Webinhalt 
aufruft oder kann ich die Ausgabe von "mbus-tcp-request-data" mit einem 
anderen Binding einlesen. Wie ist der grundlegende Ablauf?
Ich möchte z.B. unter anderem "Value" in 'DataRecord id="0"' auslesen. 
Das ist der Zählerstand.

Hoffe es kann hier einer helfen.

von N. M. (mani)


Lesenswert?

Mir ist dein Aufbau nicht klar nach diesen Aussagen.
Was für Geräte sind den nun wie angeschlossen und wer sendet was wohin?

Klaus C. schrieb:
> Auf einem anderen Computer läuft openHAB3

Klaus C. schrieb:
> Auf dem Raspi wo openhabian installiert ist

von Klaus C. (Gast)


Lesenswert?

Ursprüngliches Problem waren die verschiedenen getrennten Standorte des 
Abfragegerätes (ein Raspi), wo der Energiezähler angeschlossen ist, und 
des openHAB3 Computers (openhabian auf einem anderen Raspi). Ich musste 
eine Lösung finden um die Daten überhaupt über das Netzwerk zum openHAB3 
Raspi zu bekommen.
Das habe ich mit ser2net gelöst, was mir einfach die serielle 
Schnittstelle, wo der M-Bus Energiezähler über einen Wandler 
angeschlossen ist, an einen Port innerhalb meines Netzwerkes 
weiterleitet.
Damit kann ich direkt vom openHAB3 Raspi mit dem Befehl 
"mbus-tcp-request-data" den Energiezähler über das Netzwerk abfragen.
Dieses Problem der räumlichen Trennung habe ich gelöst.

Mein Problem nun ist aber die Ausgabe von "mbus-tcp-request-data" in 
openHAB3 einzulesen und auszuwerten. Das kann alles direkt auf dem 
openHAB3 Raspi geschehen.

von Klaus C. (Gast)


Lesenswert?

Nach meinem Verständnis müsste ich das Exec Binding installieren und 
damit in Intervallen die executable "mbus-tcp-request-data" aufrufen.
Das Ergebnis der Ausgabe kann ich mit dem Exec Binding dann wohl mit 
xpath-transformation-service transformen um an die Werte der XML-Ausgabe 
zu gelangen.

von Klaus C. (Gast)


Lesenswert?

Habe Folgendes versucht:
1
example.things:
2
Thing exec:command:mbusmain [command="/usr/local/bin/mbus-tcp-request-data  192.168.2.3 3001 0", interval=15, timeout=5]
3
4
example.items
5
String    MBusRaw                             "[%s]"                                                 (Indoor)    ["Point"]    {channel="exec:command:mbusmain:output"}

Dann in Pages ein Label List Item angelegt mit Bezug auf MBusRaw.
Leider wird nur NULL angezeigt. Es scheint, das command wird gar nicht 
ausgeführt und füllt damit nicht den output.

von Klaus C. (Gast)


Lesenswert?

Die executable war nicht in der whitelist 
(/etc/openhab/misc/exec.whitelist)

Nun wird schonmal die "Rohausgabe" angezeigt, soll heißen die komplette 
XML-Ausgabe.
Es ist jetzt noch erforderlich die gewünschten Werte zu extrahieren.

von Klaus C. (Gast)


Lesenswert?

Zum Test möchte ich die Id aus der XML-Ausgabe auslesen.
Mein Item:
1
String    MBusId                              "[XPATH(/*[name()='MBusData']/*[name()='SlaveInformation']/*[name()='Id']/):%s]"    (Indoor)    ["Point"]    {channel="exec:command:mbusmain:output"}
wobei {channel="exec:command:mbusmain:output"} den gesamten XML-Output 
von "/usr/local/bin/mbus-tcp-request-data" enthält (siehe oben)

Der String MBusId enthält weiterhin den gesamten XML-Output.
Was mache ich falsch?

von Klaus C. (Gast)


Lesenswert?

' on item 'MBusId' with pattern 
'XPATH(/*[name()='MBusData']/*[name()='SlaveInformation']/*[name()='Id'] 
/):%s':  transformation throws exceptions

von N. M. (mani)


Lesenswert?

Klaus C. schrieb:
> Der String MBusId enthält weiterhin den gesamten XML-Output.
> Was mache ich falsch?

Poste Mal den genauen XML Output.
Oder lass es Mal in einem online Validator überprüfen.
Damit du weißt ob es am XML liegt oder an deiner Transformation.

von Klaus C. (Gast)


Lesenswert?

Zur Fehlersuche habe ich das Beispiel auf der Webseite nachgebaut.
[[https://www.openhab.org/addons/transformations/xpath/]]
Der Output der aufgerufenen executable gibt jetzt NUR die xml wie auf 
der Webseite zu sehen aus. Die komplette XML ist unten in der Logausgabe 
zu sehen.

Das openHAB Logfile (openhab> log:tail) spuckt das hier aus
1
14:54:54.693 [WARN ] [se.internal.SseItemStatesEventBuilder] - Failed transforming the state '<?xml version="1.0" encoding="UTF-8"?>
2
<PTZStatus version="2.0" >
3
    <AbsoluteHigh>
4
        <elevation>0</elevation>
5
        <azimuth>450</azimuth>
6
        <absoluteZoom>10</absoluteZoom>
7
    </AbsoluteHigh>
8
</PTZStatus>' on item 'MBusId' with pattern 'XPATH(/*[name()='PTZStatus']/*[name()='AbsoluteHigh']/*[name()='azimuth']/):%s °C': transformation throws exceptions
Das Item ist hier:
1
String    MBusId                              "Temperature [XPATH(/*[name()='PTZStatus']/*[name()='AbsoluteHigh']/*[name()='azimuth']/):%s °C]"    (Indoor)    ["Point"]    {channel="exec:command:mbusmain:output"}

von MaN (Gast)


Lesenswert?

Hm, ich habe es bei mir auch mal versucht indem ich das Beispiel 
nachgebaut habe. Bei mir kam die XML halt nicht über eine Textdatei, 
sondern ich hab es per REST Api einfach reingepostet.
Gleicher Fehler wie bei dir (Exception).

Mein letzter Versuch war dann noch im XML-Header ein
standalone="yes"
hinzuzufügen.
Damit hat er das Beispiel dann gefressen.

von Sebastian L. (sebastian_l72)


Lesenswert?

Klaus C. schrieb:
> Sebastian L. schrieb:
>> Ist https://www.openhab.org/docs/configuration/persistence.html bekannt?
>
> @Sebastian L.
> Was möchtest Du mir damit sagen?

Das wenn du die laufend ausgelesen Daten in Zeitreihen darstellens 
willst, du zunächst Zeitreihen erstellen musst. Also die Daten in eine 
Datenbank schieben.
Wie du das machst ist abhängig davon welche Datenbank du nutzen willst. 
Dazu stand im ersten Post nix.
Wie du das darstellen willst, hast du auch nicht erwähnt.
Kurzum: Die Glaskugel war sehr sehr nebelig.

von Klaus C. (Gast)


Lesenswert?

MaN schrieb:
> Bei mir kam die XML halt nicht über eine Textdatei,
> sondern ich hab es per REST Api einfach reingepostet.
> Gleicher Fehler wie bei dir (Exception).
>
> Mein letzter Versuch war dann noch im XML-Header ein
> standalone="yes"
> hinzuzufügen.

Kannst Du bitte die genaue Befehlszeile, wie Du es mit der RESTApi 
reingepostet hast und den gesamten modifizierten XML-Header mitteilen.
Bei mir funktioniert es nicht, wenn ich standalone="yes" im Header 
hinzufüge. Der gleiche Fehler.

von MaN (Gast)


Lesenswert?

Als erstes habe ich 2 Items angelegt. Den channel habe ich weggelassen 
da ich keinen richtigen Input habe und ich das mit den Dateien nicht 
nachbauen wollte.
1
String  Temperature_xml "Temperature [XPATH(/*[name()='PTZStatus']/*[name()='AbsoluteHigh']/*[name()='azimuth']/):%s °C]"
2
Number  Temperature "Temperature [%.1f °C]"

Das erste Item dient sozusagen als Platzhalter für den kompletten XML 
String und als Event Trigger. Der 2. ist dafür da um das eigentliche 
Resultat (XML-Tag) zu speichern.

Dann habe ich die Rule kopiert. Den "qualifizierten" Teil (Namespace) 
habe ich entfernt und die Variable richtig geändert. Das Beispiel 
verwendet am Schluss glaube ich eine Variable die es nicht gibt.
1
rule "Convert XML to Item Type Number"
2
  when
3
    Item Temperature_xml changed
4
  then
5
    // use the transformation service to retrieve the value
6
    // Simple
7
    val mytest = transform("XPATH", "/*[name()='PTZStatus']
8
                                     /*[name()='AbsoluteHigh']
9
                                     /*[name()='azimuth']
10
                                     /text()", 
11
                                    Temperature_xml.state.toString )
12
13
    // post the new value to the Number Item
14
    Temperature.postUpdate( mytest.toString )
15
end

Danach bin ich über die OpenHab Site zu den Entwickler-Tools gewechselt:
Entwickler Tools --> Api Explorer.
Da kannst Du dann über items --> get/post/put --> items/{itemname} die 
XML Daten an das Item Temperature_xml posten.

Bei jedem Post wird dann das Item Temperature_xml geändert. Das löst das 
Event in der Rule aus und in der Rule wird es konvertiert auf das 
eigentliche Temperature Item.

von MaN (Gast)


Lesenswert?

Achso und XML wie gesagt mit neuem Header (mit standalone="yes"):
1
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
<PTZStatus version="2.0" >
3
  <AbsoluteHigh>
4
    <elevation>0</elevation>
5
    <azimuth>451</azimuth>
6
    <absoluteZoom>10</absoluteZoom>
7
  </AbsoluteHigh>
8
</PTZStatus>

von Johannes E. (johannes_e788)


Lesenswert?

Hallo Claus,
Ich habe ähnliches vor und würde mich für dein Hardware-Setup 
interessieren.
Kannst du einmal berichten, welche Komponenten Du wie verwendest?
Vg,
Johannes

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.