Seite 1 von 2

SOLVED - Sting auswerten und in Stücken wieder zusammensetzen

Verfasst: 29. Apr 2022 12:27
von Florian.Reinartz
Moin in die Runden,
ich habe wieder ein Problem.
Mein Buderus KM200 Binding gibt die Fehlermeldungen als String aber nicht wirklich im JSON-Format raus.
Der String sieht so aus:

2022-04-24T01:42:28 act:A dcd:H07 ccd:1017 orig:8 cat:R fc:18 dlv:8

Wichtig sind für mich:

act:A
-> String Buderus_Stoerung_Klasse.postUpdate("A")

und:

dcd:H07
CCD:1017
-> String Buderus_Stoerung_Code.postUpdate("H07-1017")

Vielleicht kann man die DateTime Variable auch noch irgendwo raus ziehen.

Mein Ansatz wäre:
vor den String -> {"Time":"
an Stelle jeder Leertaste -> ","
und statt der Doppelpunkte -> ":"
Am Ende dann noch -> "}

Würde dass so funktionieren?

Danke und Gruß
Florian

Re: Sting auswerten und in Stücken wiedee zusammensetzen

Verfasst: 29. Apr 2022 16:13
von peter-pan
Ich hab mich mal auf das Herauslösen der drei Werte beschränkt (ohne Datum). Ich denke nicht, dass du mit einem JSON, so wie du es machen willst weiter kommst, bzw. es wahrscheinlich doch ein bisschen schwieriger wäre.

In meinem Beispiel splitte ich einfach den String (2 mal) und extrahiere den entsprechenden Wert. Dabei gehe ich davon aus, dass die Werte auch immer in dieser Reihenfolge kommen und natürlich auch immer alle !!!

Die Regel dazu würde dann etwa so aussehen:

Code: Alles auswählen

rule "split String"

when
  Item Dummy_4 changed to ON
then
 val testString = "2022-04-24T01:42:28 act:A dcd:H07 ccd:1017 orig:8 cat:R fc:18 dlv:8"
 val v_act = (testString.split(' ').get(1)).split(':').get(1)
 val v_dcd = (testString.split(' ').get(2)).split(':').get(1)
 val v_ccd = (testString.split(' ').get(3)).split(':').get(1)
 logInfo("split String", "v_act ist {}", v_act)
 logInfo("split String", "v_dcd ist {}", v_dcd)
 logInfo("split String", "v_ccd ist {}", v_ccd)
end


Das Ergebnis im Logger:

Code: Alles auswählen

2022-04-29 15:59:52.936 [INFO ] [enhab.core.model.script.split String] - v_act ist A
2022-04-29 15:59:52.938 [INFO ] [enhab.core.model.script.split String] - v_dcd ist H07
2022-04-29 15:59:52.940 [INFO ] [enhab.core.model.script.split String] - v_ccd ist 1017
Den Code musst du natürlich noch ergänzen um die Werte abzuspeichern bzw. auch entsprechende Items vorher anlegen.

Die Regel selber, ist eine DSL-Regel, die in Textform erstellt und abgespeichert wird.

Re: Sting auswerten und in Stücken wiedee zusammensetzen

Verfasst: 30. Apr 2022 00:49
von udo1toni
ja, das liefert die Werte, aber ist natürlich nicht besonders flexibel. Der Ansatz ist aber schon mal eine gute Grundlage.

Ich würde hier aber eher zu REGEX greifen. Allerdings muss man hier etwas aufpassen, weil das openHAB REGEX leider den vollen String liefert, falls die Expression nicht matcht. z.B.

Code: Alles auswählen

var testString = "2022-04-24T01:42:28 act:A dcd:H07 ccd:1017 orig:8 cat:R fc:18 dlv:8"
testString = testString + " "
val v_act  = transform("REGEX",".*act:(\S*) .*",testString)
val v_dcd  = transform("REGEX",".*dcd:(\S*) .*",testString)
val v_ccd  = transform("REGEX",".*ccd:(\S*) .*",testString)
val v_orig = transform("REGEX",".*orig:(\S*) .*",testString)
val v_cat  = transform("REGEX",".*cat:(\S*) .*",testString)
val v_fc   = transform("REGEX",".*fc:(\S*) .*",testString)
val v_dlv  = transform("REGEX",".*dlv:(\S*) .*",testString)
Unter der Voraussetzung, dass der String immer exakt gleich aufgebaut ist, kann man natürlich auch an den Leerzeichen splitten und die Teilstrings anschließend wiederum an den Doppelpunkten splitten:

Code: Alles auswählen

val testString = "2022-04-24T01:42:28 act:A dcd:H07 ccd:1017 orig:8 cat:R fc:18 dlv:8"
val buffer = testString.split(" ")
buffer.filter[j,i|i>0 && j.contains(":")].forEach[k | 
    val myName = k.split(":").get(0)
    val myVal  = k.split(":").get(1)
    // Anhand von myName entscheiden, wo myVal hin muss
]
Bei beiden Varianten ist es egal, in welcher Reihenfolge die Werte auftauchen. Auch die Länge der werte kann beliebig ausfallen. \S sind alle Zeichen, die keine Wheitspaces sind. Weil testString nicht mit einem Leerzeichen endet, würde der code den letzten Wert nicht finden, deshalb muss zunächst noch ein Leerzeichen ergänzt werden (2. Zeile).
Das zweite Beispiel ist eleganter, dafür muss man aber noch weiteren Code bauen. i ist der Index der Liste. Das 0te Element ist Datum und Uhrzeit. Da die Uhrzeit auch Doppelpunkte enthält, muss das erste Element übersprungen werden.
Dennoch kann es interessant sein, wenn man ein Array zum Speichern nimmt. Man speichert dann einfach die Name-Wert-Paare als Paar im Array ab und arbeitet bei der Auswertung direkt mit dem Array.

Re: Sting auswerten und in Stücken wiedee zusammensetzen

Verfasst: 1. Mai 2022 11:59
von Florian.Reinartz
Moin Zusammen,
erst mal vielen Dank für die Ansätze.
Leider bekomme ich gleich beim erstenm Ansatz folgende Fehlermeldung:

Error during the execution of rule 'Buderus Störung auswerten': 'split' is not a member of 'org.eclipse.smarthome.core.library.items.StringItem'; line 11, column 28, length 37

Muss ich evtl. noch eine Bibliothek importieren?
Danke und Gruß
Flo

Re: Sting auswerten und in Stücken wieder zusammensetzen

Verfasst: 1. Mai 2022 12:54
von udo1toni
Du musst Item.state.toString als Quelle nutzen, also Item.state.toString.split(...)...

Allerdings möchte ich empfehlen, lieber Item.state.toString in einem String Objekt zu speichern und dann dieses zu verwenden (siehe oben...)

Re: Sting auswerten und in Stücken wieder zusammensetzen

Verfasst: 1. Mai 2022 13:14
von Florian.Reinartz
...super, jetzt läuft es ;-)
Danke

Re: SOLVED - Sting auswerten und in Stücken wieder zusammensetzen

Verfasst: 1. Mai 2022 21:27
von Florian.Reinartz
Das ist nun meine Lösung:

Rules:

Code: Alles auswählen

rule "Buderus Störung auswerten"
  when
        Item Buderus_notifications_error changed or
        Item Buderus_notifications_nbrErrors changed or
        Item Buderus_notifications_Text changed
  then
        //Buderus_notifications_Text.postUpdate("2022-04-24T01:42:28 act:A dcd:H07 ccd:1017 orig:8 cat:R fc:18 dlv:8")
        val buderus_act = (Buderus_notifications_Text.state.toString.split(' ').get(1)).split(':').get(1)
        val buderus_dcd = (Buderus_notifications_Text.state.toString.split(' ').get(2)).split(':').get(1)
        val buderus_ccd = (Buderus_notifications_Text.state.toString.split(' ').get(3)).split(':').get(1)
        //logInfo("split String", "buderus_act ist {}", buderus_act)
        //logInfo("split String", "buderus_dcd ist {}", buderus_dcd)
        //logInfo("split String", "buderus_ccd ist {}", buderus_ccd)
        Buderus_Stoerung_Klasse.postUpdate(buderus_act)
        Buderus_Stoerung_Code.postUpdate(buderus_dcd + "-" + buderus_ccd)
        if(Buderus_notifications_nbrErrors.state >= 1)
        {
            Buderus_Stoerung_Bit.sendCommand(ON)                                //Um das Item in der sitemap ein- bzw. auszublenden
        }
        else
        {
            Buderus_Stoerung_Bit.sendCommand(OFF)                              //Um das Item in der sitemap ein- bzw. auszublenden
        }
 end
Items:

Code: Alles auswählen

Number      Buderus_notifications_nbrErrors                                     "notifications_nbrErrors"                                                                                                                                                   {channel="km200:notification:456099396:notifications:nbrErrors"}
String      Buderus_notifications_Text                                          "notifications_Text [%s]"                                                                                                                                                   {channel="km200:notification:456099396:notifications:errorString"}
Number      Buderus_notifications_error                                         "notifications_error"                                                                                                                                                       {channel="km200:notification:456099396:notifications:error"}
String      Buderus_Stoerung_Klasse                                             "Störungsklasse [MAP(buderus_stoerung.map):%s]"                                 <settings>
String      Buderus_Stoerung_Code                                               "Störungscode [MAP(buderus_stoerung.map):%s]"                                   <settings>
Switch      Buderus_Stoerung_Bit                                                "Störung Ja/Nein [%s]"
Und die entsprechende MAP (enthält alle Buderus Fehler !!!
MAP:
(siehe Anhang)

Re: SOLVED - Sting auswerten und in Stücken wieder zusammensetzen

Verfasst: 2. Mai 2022 09:59
von peter-pan
Das ist ja toll. Aber ich würde mir doch noch mal die zweite Lösung von Udo anschauen, die sieht wesentlich professioneller, flexibler und eleganter aus.

Hat sich das "DateTime"-Problem erledigt ?

Re: SOLVED - Sting auswerten und in Stücken wieder zusammensetzen

Verfasst: 26. Nov 2022 00:48
von mad-mike
Florian.Reinartz hat geschrieben: 1. Mai 2022 21:27 Das ist nun meine Lösung:

Rules:

Code: Alles auswählen

rule "Buderus Störung auswerten"
  when
        Item Buderus_notifications_error changed or
        Item Buderus_notifications_nbrErrors changed or
        Item Buderus_notifications_Text changed
  then
        //Buderus_notifications_Text.postUpdate("2022-04-24T01:42:28 act:A dcd:H07 ccd:1017 orig:8 cat:R fc:18 dlv:8")
        val buderus_act = (Buderus_notifications_Text.state.toString.split(' ').get(1)).split(':').get(1)
        val buderus_dcd = (Buderus_notifications_Text.state.toString.split(' ').get(2)).split(':').get(1)
        val buderus_ccd = (Buderus_notifications_Text.state.toString.split(' ').get(3)).split(':').get(1)
        //logInfo("split String", "buderus_act ist {}", buderus_act)
        //logInfo("split String", "buderus_dcd ist {}", buderus_dcd)
        //logInfo("split String", "buderus_ccd ist {}", buderus_ccd)
        Buderus_Stoerung_Klasse.postUpdate(buderus_act)
        Buderus_Stoerung_Code.postUpdate(buderus_dcd + "-" + buderus_ccd)
        if(Buderus_notifications_nbrErrors.state >= 1)
        {
            Buderus_Stoerung_Bit.sendCommand(ON)                                //Um das Item in der sitemap ein- bzw. auszublenden
        }
        else
        {
            Buderus_Stoerung_Bit.sendCommand(OFF)                              //Um das Item in der sitemap ein- bzw. auszublenden
        }
 end
Items:

Code: Alles auswählen

Number      Buderus_notifications_nbrErrors                                     "notifications_nbrErrors"                                                                                                                                                   {channel="km200:notification:456099396:notifications:nbrErrors"}
String      Buderus_notifications_Text                                          "notifications_Text [%s]"                                                                                                                                                   {channel="km200:notification:456099396:notifications:errorString"}
Number      Buderus_notifications_error                                         "notifications_error"                                                                                                                                                       {channel="km200:notification:456099396:notifications:error"}
String      Buderus_Stoerung_Klasse                                             "Störungsklasse [MAP(buderus_stoerung.map):%s]"                                 <settings>
String      Buderus_Stoerung_Code                                               "Störungscode [MAP(buderus_stoerung.map):%s]"                                   <settings>
Switch      Buderus_Stoerung_Bit                                                "Störung Ja/Nein [%s]"
Und die entsprechende MAP (enthält alle Buderus Fehler !!!
MAP:
(siehe Anhang)
Moin.

Exakt diese Rule habe ich gesucht danke dafür. Werde diese noch als Push up fürs Smartphone erweitern.

Aber:

Was kann ich mit dieser MAP datei im Detail machen??

Also ich habe nun die obere Rule bei mir eingefügt, und funktionierte Sofort...
Wo muss ich diese MAP Speichern?

Stehen dann die Fehler im Klartext??

Danke und Gruss

Re: SOLVED - Sting auswerten und in Stücken wieder zusammensetzen

Verfasst: 26. Nov 2022 11:39
von peter-pan
...unter $OPENHAB_CONF/transform (vermutlich = /etc/openhab/transform)

Code: Alles auswählen

hab3@oh3ssd:~ $ ls -alF $OPENHAB_CONF/transform
insgesamt 76
drwxrwxr-x  2 openhab openhab 4096  8. Nov 23:00 ./
drwxrwxr-x 16 openhab openhab 4096 23. Dez 2021  ../
-rw-rw-r--  1 openhab openhab   35 17. Sep 18:34 ajar.map
-rw-rw-r--  1 openhab openhab 1426  9. Aug 11:56 astroDE.map
-rw-rw-r--  1 openhab openhab  117 27. Sep 2018  battery.map
-rw-rw-r--  1 openhab openhab   14  7. Feb 2021  cross.map
-rw-rw-r--  1 openhab openhab  322 26. Sep 11:59 de.map
-rw-rw-r--  1 openhab openhab  108  5. Okt 2021  div.map
-rw-rw-r--  1 openhab openhab   81  2. Jun 2021  en.map
-rw-rw-r--  1 openhab openhab  122 12. Okt 2018  fritz.map
-rw-rw-r--  1 openhab openhab   56 10. Mai 2022  milli.js
-rw-rw-r--  1 openhab openhab   91 17. Jan 2021  reachable.map
-rw-rw-r--  1 openhab openhab  282 21. Dez 2020  readme.txt
-rw-rw-r--  1 openhab openhab  100 12. Jul 2018  tech.map
-rw-rw-r--  1 openhab openhab 3349 24. Aug 2020  test1.json
-rw-rw-r--  1 openhab openhab  219 19. Sep 2020  test2.json
-rw-rw-r--  1 openhab openhab  418 13. Nov 2021  test.json
-rw-rw-r--  1 openhab openhab 1374 25. Sep 2018  weather_de.map
-rw-rw-r--  1 openhab openhab  524 11. Feb 2020  wind.scale
hab3@oh3ssd:~ $
Ja die stehen dann da im Klartext, wenn die Map-Datei richtig aufgebaut ist (bzw. lesbar).