(Gelöst) RegEx bei HTTPMOD

Begonnen von is2late, 09 Mai 2020, 09:32:33

Vorheriges Thema - Nächstes Thema

is2late

Guten Morgen,

ich versuche seit Stunden, folgende Nuss zu knacken:

Ein HTTPMOD bringt folgende Liste (Ausschnitt):
{"area": 1, "zone": 50, "type": 54, "type_f": "{D_TYPE_54}", "name": "Aussen",
"cond": "", "cond_ok": "1", "battery": "", "battery_ok": "1",
"tamper": "", "tamper_ok": "1", "bypass": 0, "rssi": "{WEB_MSG_WEAK} 3",
"resp_mode": [0,0,0,0,0,0], "ammeter": "0", "ver": "",
"bypass_tamper": 0,
"sid": "ZS:0ddf01", "su": 1, "alarm_status": "", "status_ex": "0", "hue": "-1", "sat": "-1", "ctemp": "-1", "hue_cmode": "-1", "hue_cie_x": "-1", "hue_cie_y": "-1", "hue_color_cap": "0", "nuki": "-1", "shutter_turn": 0,"status": "{WEB_MSG_TS_DEGREE} 22.22 {WEB_MSG_RH_HUMIDITY} 36"},
{"area": 1, "zone": 49, "type": 54, "type_f": "{D_TYPE_54}", "name": "Tiefkühlschrank",
"cond": "", "cond_ok": "1", "battery": "", "battery_ok": "1",
"tamper": "", "tamper_ok": "1", "bypass": 0, "rssi": "{WEB_MSG_GOOD} 5",
"resp_mode": [0,0,0,0,0,0], "ammeter": "0", "ver": "RH3052",
"bypass_tamper": 0,
"sid": "ZS:109f01", "su": 1, "alarm_status": "", "status_ex": "0", "hue": "-1", "sat": "-1", "ctemp": "-1", "hue_cmode": "-1", "hue_cie_x": "-1", "hue_cie_y": "-1", "hue_color_cap": "0", "nuki": "-1", "shutter_turn": 0,"status": "{WEB_MSG_TS_DEGREE} -15.02 {WEB_MSG_RH_HUMIDITY} 68"},
{"area": 1, "zone": 8, "type": 22, "type_f": "{D_TYPE_22}", "name": "Statusanzeige Haustür",
"cond": "", "cond_ok": "1", "battery": "", "battery_ok": "1",
"tamper": "", "tamper_ok": "1", "bypass": 0, "rssi": "{WEB_MSG_STRONG} 6",
"resp_mode": [0,5,5,5,5,0], "ammeter": "0", "ver": "SSL_00.00.03.04TC",
"bypass_tamper": 0,
"sid": "ZS:395001", "su": 1, "alarm_status": "", "status_ex": "0", "hue": "-1", "sat": "-1", "ctemp": "-1", "hue_cmode": "-1", "hue_cie_x": "-1", "hue_cie_y": "-1", "hue_color_cap": "0", "nuki": "-1", "shutter_turn": 0,"status": ""},
{"area": 1, "zone": 51, "type": 54, "type_f": "{D_TYPE_54}", "name": "Innen",
"cond": "", "cond_ok": "1", "battery": "", "battery_ok": "1",
"tamper": "", "tamper_ok": "1", "bypass": 0, "rssi": "{WEB_MSG_GOOD} 4",
"resp_mode": [0,0,0,0,0,0], "ammeter": "0", "ver": "RH3052",
"bypass_tamper": 0,
"sid": "ZS:7ca301", "su": 1, "alarm_status": "", "status_ex": "0", "hue": "-1", "sat": "-1", "ctemp": "-1", "hue_cmode": "-1", "hue_cie_x": "-1", "hue_cie_y": "-1", "hue_color_cap": "0", "nuki": "-1", "shutter_turn": 0,"status": "{WEB_MSG_TS_DEGREE} 22.26 {WEB_MSG_RH_HUMIDITY} 36"},


Aus dieser Liste möchte ich gern sechs Werte auslesen, nämlich für jeden der drei Sensoren "Aussen", "Tiefkühlschrank" und"Innen" Temperatur und Luftfeuchte (DEGREE und HUMIDITY). Das Attribut
attr Temperaturen reading01Name AussenTemp
attr Temperaturen reading01Regex (?s)(Aussen)+.*({WEB_MSG_TS_DEGREE})([^ }]*) +.*

findet nur die letzte Temperatur in der Liste, nämlich die vom Sensor "Innen". Um das zu vermeiden, ist sozusagen als Stopp zusätzlich die Sid des nächsten Datensatzes angegeben. Das ist wohl nicht besonders elegant und hat den Nachteil, dass der Stoppunkt sich verschiebt, wenn ein anderer Datensatz dazwischen rutscht, funktioniert grundsätzlich aber. Das Attribut lautet dann also:
attr Temperaturen reading01Name AussenTemp
attr Temperaturen reading01Regex (?s)(Aussen)+.*({WEB_MSG_TS_DEGREE})([^ }]*) +.*("sid": "ZS:109f01")


Jetzt zu meinem Problem:

Zwar werden die Temperaturen, nicht jedoch die Luftfeuchte ausgelesen. Hier scheint ein Fehler in der RegEx zu liegen, den ich nicht finde. Analog der Temperatursuche habe ich probiert:
attr Temperaturen reading02Name AussenFeucht
attr Temperaturen reading02Regex (?s)(Aussen)+.*({WEB_MSG_RH_HUMIDITY})([^ }]*) +.*("sid": "ZS:109f01")

In der RAW findet sich dazu gar kein setstate. Das Reading für alle sechs Werte lautet
AussenTemp-1
Aussen
2020-05-09 08:15:01
AussenTemp-2
{WEB_MSG_TS_DEGREE}
2020-05-09 08:15:01
AussenTemp-3
19.3
2020-05-09 08:15:01
AussenTemp-4
"sid": "ZS:109f01"
2020-05-09 08:15:01
InnenTemp-1
Innen
2020-05-09 08:15:01
InnenTemp-2
{WEB_MSG_TS_DEGREE}
2020-05-09 08:15:01
InnenTemp-3
23.06
2020-05-09 08:15:01
InnenTemp-4
"sid": "ZS:b17901"
2020-05-09 08:15:01
TiefkühlschrankTemp-1
Tiefkühlschrank
2020-05-09 08:15:01
TiefkühlschrankTemp-2
{WEB_MSG_TS_DEGREE}
2020-05-09 08:15:01
TiefkühlschrankTemp-3
-17.18
2020-05-09 08:15:01
TiefkühlschrankTemp-4
"sid": "ZS:395001"
2020-05-09 08:15:01

Ich krieg die Luftfeuchtewerte also nicht zu fassen. Bei Regex101.com habe ich viel herumprobiert, finde aber keine Lösung.
Kann mir ein Kundiger helfen?

Vielen Dank im Voraus,
Ingo





Pi4, Tahoma Jalousien, Hue, Echo, Sonos, Lupusec XT3, FritzBox

xenos1984

.* ist "greedy", nimmt also so viele Zeichen wie möglich, damit die Regex noch "passt" - deshalb überspringt es alle Temperaturwerte bis auf den letzten. Statt also .* und die folgende Sid zu benutzen, macht also die non-greedy Variante .*? mehr Sinn.

is2late

Hm, danke xenos1984, probiere ich aus. Wäre klasse, wenn die Sid als Stopp entfallen könnte.

Hast Du auch eine Idee bzgl des Luftfeuchtewertes?

LG
Pi4, Tahoma Jalousien, Hue, Echo, Sonos, Lupusec XT3, FritzBox

ch.eick

Moin,
das ist doch JSON, das kann Fhem doch komplett in readings umsetzen, sofern ich mich erinnere.
Gruß Christian

Gesendet von meinem SM-G930F mit Tapatalk

RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

is2late

das ist doch JSON, das kann Fhem doch komplett in readings umsetzen, sofern ich mich erinnere.
Schon, aber das führt leider zu "Verschiebeproblemen bei geänderter Reihenfolge, wenn irgendwo (nicht nur zwischen den Temperaturfühlern) Gerät hinzugefügt", wie hier in #3 unter dargelegt.
https://forum.fhem.de/index.php/topic,91828.0.html
Pi4, Tahoma Jalousien, Hue, Echo, Sonos, Lupusec XT3, FritzBox

SCMP77

#5
Zitat von: is2late am 09 Mai 2020, 09:32:33
findet nur die letzte Temperatur in der Liste, nämlich die vom Sensor "Innen". Um das zu vermeiden, ist sozusagen als Stopp zusätzlich die Sid des nächsten Datensatzes angegeben. Das ist wohl nicht besonders elegant und hat den Nachteil, dass der Stoppunkt sich verschiebt, wenn ein anderer Datensatz dazwischen rutscht, funktioniert grundsätzlich aber. Das Attribut lautet dann also:

Es ist nicht nur nicht besonders elegant, sondern ein Performancefresser. Mit .* findest Du erstmal immer den nachfolgenden letzten Match. Wenn Du das dann mit der sid erweiterst, mag das funktionieren, aber der Regex-Algorithmus muss dann von hinten wieder nach vorne arbeiten, weil Du im String schon viel zu weit bist. Und das kostet Zeit.

Wenn Du anstelle von .* den Ausdruck .*? verwendest, dann bist Du aus meiner Sicht genau an der richtigen Stelle. Evtl. löst sich dann auch automatisch das andere Problem.


PS: Xenos war schneller, mein Beitrag ist aber etwas ausfühlicher, daher lass ich ihn mal stehen.
Raspberry Pi 3 Model B mit Rasbian, SolvisMax, AVM DECT 200, Sonoff mit Tasmota geflasht

is2late

Vielen Dank,

xenos1984 und SCMP77, Ihr habt völlig Recht. Mit .*? wird der richtige Sensor gefunden, ohne dass die Sid als Stopp herangezogen werden muss. Klasse! Das Problem des Verschiebens des Stopps ist damit gelöst. Die RAw sieht jetzt so aus:

attr Temperaturen userattr reading01Name reading01Regex reading02Name reading02Regex reading03Name reading03Regex reading04Name reading04Regex reading05Name reading05Regex reading06Name reading06Regex
attr Temperaturen enableControlSet 1
attr Temperaturen event-on-change-reading AussenTemp, AussenFeucht, InnenTemp, InnenFeucht, TiefkühlschrankTemp, TiefkühlschrankFeucht
attr Temperaturen reading01Name AussenTemp
attr Temperaturen reading01Regex (?s)(Aussen)+.*?({WEB_MSG_TS_DEGREE})([^ }]*) +.*
attr Temperaturen reading02Name AussenFeucht
attr Temperaturen reading02Regex (?s)(Aussen)+.*({WEB_MSG_RH_HUMIDITY})([^ }]*) +.*
attr Temperaturen reading03Name TiefkühlschrankTemp
attr Temperaturen reading03Regex (?s)(Tiefkühlschrank)+.*?({WEB_MSG_TS_DEGREE})([^ }]*) +.*
attr Temperaturen reading04Name TiefkühlschrankFeucht
attr Temperaturen reading04Regex (?s)(Tiefkühlschrank)+.*({WEB_MSG_RH_HUMIDITY})([^ }]*) +.*
attr Temperaturen reading05Name InnenTemp
attr Temperaturen reading05Regex (?s)(Innen)+.*?({WEB_MSG_TS_DEGREE})([^ }]*) +.*
attr Temperaturen reading06Name InnenFeucht
attr Temperaturen reading06Regex (?s)(Innen)+.*?({WEB_MSG_RH_HUMIDITY})([^ }]*) +.*
attr Temperaturen room Temperaturen


Das andere Problem besteht leider weiterhin, dh die Luftfeuchtewerte werden nicht gefunden. ACHTUNG: Die entscheidenden Werte stehen in der jeweils letzten Zeile der Ausgabe ("sid....) ganz rechts!
in der regEx steckt irgendwo ein Fehler drin:
attr Temperaturen reading06Regex (?s)(Innen)+.*?({WEB_MSG_RH_HUMIDITY})([^ }]*) +.*

Kann es damit zusammenhängen, dass beide pro Sensor auszulesende Werte unter demselben "Etikett" (status) stehen?
"status": "{WEB_MSG_TS_DEGREE} -15.02 {WEB_MSG_RH_HUMIDITY} 68"}
Pi4, Tahoma Jalousien, Hue, Echo, Sonos, Lupusec XT3, FritzBox

is2late

#7
Oh,Oh...hab versäumt, mit der Sid auch das "+.*" wegzunehmen. Jetzt klappt es! Herzlichen Dank für Eure Hilfe!
Pi4, Tahoma Jalousien, Hue, Echo, Sonos, Lupusec XT3, FritzBox