String Formatieren - Sonderzeichen

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Cali
Beiträge: 9
Registriert: 27. Sep 2019 10:59

String Formatieren - Sonderzeichen

Beitrag von Cali »

Hallo Zusammen,

ich habe eine Regel erstellt, die mehrere Items zusammen fasst und als einen String über MQTT ausgibt, aber ich beiße mir grade die Zähne an der Formatierung des Strings aus, ansonsten funktioniert alles wie gewünscht.

Erstmal die Regel selbst:

Code: Alles auswählen

rule "Summary_Naehrloesung"
when
    Item Hydroponik_01_Send_Summary_Naehrloesung changed from 0 to 1
then
    var Number w1 = (Hydroponik_01_Set_Woche.state as DecimalType).floatValue
    var Number l1 = (Hydroponik_01_Set_Naehrloesung_01.state as Number).floatValue
    var Number l2 = (Hydroponik_01_Set_Naehrloesung_02.state as Number).floatValue
    var Number l3 = (Hydroponik_01_Set_Naehrloesung_03.state as Number).floatValue

    var String Ausgabe = String::format ("{Woche : %.0f , Nährlösung 1 : %.1f , Nährlösung 2 : %.1f , Nährlösung 3 : %.1f}", w1, l1, l2, l3 )

    Hydroponik_01_Summary_Naehrloesung.postUpdate(Ausgabe) 
    logInfo('rules', 'Ausgabe' + Hydroponik_01_Summary_Naehrloesung)
    
    sendCommand(Hydroponik_01_Send_Summary_Naehrloesung, 0 )
    sendCommand(Hydroponik_01_Send_Summary_Naehrloesung_AnzeigeInSitemap, 0 )
 
    val mqttActions = getActions("mqtt","mqtt:broker:MyBroker")
    mqttActions.publishMQTT("Hydroponik_01/Summary_Naehrloesung", Hydroponik_01_Summary_Naehrloesung.state.toString, true)
end
Entscheidend ist die entstehung des Strings, der an der folgenden Stelle zusammengesetzt wird:

var String Ausgabe = String::format ("{Woche : %.0f , Nährlösung_1 : %.1f , Nährlösung_2 : %.1f , Nährlösung_3 : %.1f}", w1, l1, l2, l3 )

Ich möchte gerne erreichen, das die Ausgabe über MQTT dann so aussieht:

{"Woche":"1","Nährlösung_1":"2.5","Nährlösung_2":"2.5","Nährlösung_3":"2.5",}

Doch ich komme einfach nicht darauf, wie ich die Sonderzeichen in einem String setzen muss, gibt es da eine Möglichkeit / Übersicht ?

Ich habe mich dabei an die MQTT Ausgabe Formatierung von Tasmota orientiert, daher der Wunsch.

Vielen Dank für die Mühe

Viele Grüße

Cali
von udo1toni » 22. Jan 2023 16:27
Puh, lass mich mal so sagen... das wird hässlich. Und String::format ist mutmaßlich nicht optimal dafür geeignet. Sinnvoller wäre es also, die vier Werte direkt als Strings anzulegen und diese dann einzubauen:

Code: Alles auswählen

rule "Summary_Naehrloesung"
when
    Item Hydroponik_01_Send_Summary_Naehrloesung changed from 0 to 1
then
    val strW1 = ((Hydroponik_01_Set_Woche.state as DecimalType) + 0.5).intValue.toString
    val strL1 = String.format("%.1f",(Hydroponik_01_Set_Naehrloesung_01.state as Number).floatValue)
    val strL2 = String.format("%.1f",(Hydroponik_01_Set_Naehrloesung_02.state as Number).floatValue)
    val strL3 = String.format("%.1f",(Hydroponik_01_Set_Naehrloesung_03.state as Number).floatValue)

    var strAusgabe = '{"Woche":"' + strW1 + '","Nährlösung_1":"' + strL1 + '","Nährlösung_2":"' + strL2 + '","Nährlösung_3":"' + strL3 +'",}"'

    Hydroponik_01_Summary_Naehrloesung.postUpdate(strAusgabe) 
    logInfo("rules", "Ausgabe:{}", Hydroponik_01_Summary_Naehrloesung.state)
    
    Hydroponik_01_Send_Summary_Naehrloesung.sendCommand(0)
    Hydroponik_01_Send_Summary_Naehrloesung_AnzeigeInSitemap.sendCommand(0)
 
    val mqttActions = getActions("mqtt","mqtt:broker:MyBroker")
    mqttActions.publishMQTT("Hydroponik_01/Summary_Naehrloesung", strAusgabe, true)
end
Achte darauf, niemals innerhalb einer Rule ein Item zu setzen und direkt danach den Status dieses Items zu verwenden. openHAB arbeitet asynchron, das heißt, es gibt keinen garantierten Zustand des Items, es könnte noch der alte Zustand sein, genauso gut wie der neue.

Falls strAusgabe so nicht funktioniert, kannst Du auch mit Escaping arbeiten:

Code: Alles auswählen

    var strAusgabe = "{\"Woche\":\"" + strW1 + "\",\"Nährlösung_1\":\"" + strL1 + "\",\"Nährlösung_2\":\"" + strL2 + "\",\"Nährlösung_3\":\"" + strL3 +"\",}\""
Eigentlich sollten beide Varianten funktionieren :)
Gehe zur vollständigen Antwort

Benutzeravatar
udo1toni
Beiträge: 13864
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: String Formatieren - Sonderzeichen

Beitrag von udo1toni »

Puh, lass mich mal so sagen... das wird hässlich. Und String::format ist mutmaßlich nicht optimal dafür geeignet. Sinnvoller wäre es also, die vier Werte direkt als Strings anzulegen und diese dann einzubauen:

Code: Alles auswählen

rule "Summary_Naehrloesung"
when
    Item Hydroponik_01_Send_Summary_Naehrloesung changed from 0 to 1
then
    val strW1 = ((Hydroponik_01_Set_Woche.state as DecimalType) + 0.5).intValue.toString
    val strL1 = String.format("%.1f",(Hydroponik_01_Set_Naehrloesung_01.state as Number).floatValue)
    val strL2 = String.format("%.1f",(Hydroponik_01_Set_Naehrloesung_02.state as Number).floatValue)
    val strL3 = String.format("%.1f",(Hydroponik_01_Set_Naehrloesung_03.state as Number).floatValue)

    var strAusgabe = '{"Woche":"' + strW1 + '","Nährlösung_1":"' + strL1 + '","Nährlösung_2":"' + strL2 + '","Nährlösung_3":"' + strL3 +'",}"'

    Hydroponik_01_Summary_Naehrloesung.postUpdate(strAusgabe) 
    logInfo("rules", "Ausgabe:{}", Hydroponik_01_Summary_Naehrloesung.state)
    
    Hydroponik_01_Send_Summary_Naehrloesung.sendCommand(0)
    Hydroponik_01_Send_Summary_Naehrloesung_AnzeigeInSitemap.sendCommand(0)
 
    val mqttActions = getActions("mqtt","mqtt:broker:MyBroker")
    mqttActions.publishMQTT("Hydroponik_01/Summary_Naehrloesung", strAusgabe, true)
end
Achte darauf, niemals innerhalb einer Rule ein Item zu setzen und direkt danach den Status dieses Items zu verwenden. openHAB arbeitet asynchron, das heißt, es gibt keinen garantierten Zustand des Items, es könnte noch der alte Zustand sein, genauso gut wie der neue.

Falls strAusgabe so nicht funktioniert, kannst Du auch mit Escaping arbeiten:

Code: Alles auswählen

    var strAusgabe = "{\"Woche\":\"" + strW1 + "\",\"Nährlösung_1\":\"" + strL1 + "\",\"Nährlösung_2\":\"" + strL2 + "\",\"Nährlösung_3\":\"" + strL3 +"\",}\""
Eigentlich sollten beide Varianten funktionieren :)
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Cali
Beiträge: 9
Registriert: 27. Sep 2019 10:59

Re: String Formatieren - Sonderzeichen

Beitrag von Cali »

Vielen Herzlichen Dank Udo für die Super Schnelle und sehr Hilfreiche Antwort, es hatte auf Anhieb funktioniert und ich war so versunken beim weiter machen, das ich vergessen hab mich zu bedanken.

Das openHAB asynchron habe ich schon oft gemerkt, das ist manchmal gar nicht so einfach, dann doch das gewünschte ergebniss zu bekommen, aber bisher klappt alles wie gewünscht.

Viele Grüße

Cali

Benutzeravatar
udo1toni
Beiträge: 13864
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: String Formatieren - Sonderzeichen

Beitrag von udo1toni »

Cali hat geschrieben: 27. Jan 2023 23:26 Vielen Herzlichen Dank Udo für die Super Schnelle und sehr Hilfreiche Antwort, es hatte auf Anhieb funktioniert und ich war so versunken beim weiter machen, das ich vergessen hab mich zu bedanken.
Nicht vergessen, nur etwas verzögert :)
Cali hat geschrieben: 27. Jan 2023 23:26 Das openHAB asynchron habe ich schon oft gemerkt, das ist manchmal gar nicht so einfach, dann doch das gewünschte ergebniss zu bekommen
Die Variablen sind nicht asynchron, wenn man also einen Wert über eine Variable berechnet, kann man immer sicher sein, dass dieser Wert stimmt (es sei denn, man verändert ihn dann im Laufe der Rule noch mal).
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Cali
Beiträge: 9
Registriert: 27. Sep 2019 10:59

Re: String Formatieren - Sonderzeichen

Beitrag von Cali »

Hallo zusammen,

leider muss ich das Thema noch mal Aufgreifen, Ich kann nicht sagen ob es mein Fehler ist oder es an dem Update auf die 3.4.1 liegt, was ich heute gemacht habe, jedenfalls haben meine MQTT Ausgaben der float Zahlen plötzlich ein Komma statt einem Punkt als Trennzeichen...

Ich habe nun folgende MQTT Ausgabe:

Code: Alles auswählen

{"Woche": 4,"Nährlösung_1": 2,0,"Nährlösung_2": 2,0,"Nährlösung_3": 2,0}
Ich war der Meinung, das es damals korrekt mit Punkt Angezeigt wurde oder ich habe das einfach übersehen? Leider bin ich mir da jetzt grade vollkommen unsicher muss ich gestehen...

Das einzige was ich damals noch verändert hatte, das war die Formatierung noch etwas anzupassen, der String wird jetzt wie folgt zusammen gesetzt:

Code: Alles auswählen

    var strAusgabe = '{"Woche": ' + strW1 + ',"Nährlösung_1": ' + strL1 + ',"Nährlösung_2": ' + strL2 + ',"Nährlösung_3": ' + strL3 +'}'
ansonsten habe ich nichts verändert.

Viele Grüße und danke für die Mühe.

Cali

Benutzeravatar
udo1toni
Beiträge: 13864
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: String Formatieren - Sonderzeichen

Beitrag von udo1toni »

Das hieße, dass String.format() nun die Zahlenschreibweise lokalisiert hat. Ungeprüft: Probiere bitte mal

Code: Alles auswählen

    val strL1 = String.format(Locale.US, "%,.1f",(Hydroponik_01_Set_Naehrloesung_01.state as Number).floatValue)
    val strL2 = String.format(Locale.US, "%,.1f",(Hydroponik_01_Set_Naehrloesung_02.state as Number).floatValue)
    val strL3 = String.format(Locale.US, "%,.1f",(Hydroponik_01_Set_Naehrloesung_03.state as Number).floatValue)
Eventuell wäre noch ein log der Werte interessant, um es direkt nachvollziehen zu können, also nach Definition der lokalen Konstanten:

Code: Alles auswählen

logInfo("nutrifier","strL1: {} strL2: {} strL3: {}",strL1,strL2,strL3)
So sollte bei jedem Aufruf der Rule der konkrete Wert im Log erscheinen.

Achtung: %,.1f ist korrekt. Das Komma weist darauf hin, dass die Lokalisierung beachtet werden muss.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Cali
Beiträge: 9
Registriert: 27. Sep 2019 10:59

Re: String Formatieren - Sonderzeichen

Beitrag von Cali »

Vielen Dank für deine super schnelle Antwort udo,

leider gibt es noch ein Problem, ich bekomme als Fehlermeldung:

Code: Alles auswählen

2023-02-13 11:04:24.114 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'summary-33' failed: The name 'Locale' cannot be resolved to an item or type; line 742, column 31, length 6 in summary
Er kann dadurch auch nicht die logInfo ausgeben.

Benutzeravatar
udo1toni
Beiträge: 13864
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: String Formatieren - Sonderzeichen

Beitrag von udo1toni »

Ich hab's ja befürchtet...

dann hilft nur die brachiale Variante...

Code: Alles auswählen

    val strL1 = String.format("%.1f",(Hydroponik_01_Set_Naehrloesung_01.state as Number).floatValue).replace(",",".")
    val strL2 = String.format("%.1f",(Hydroponik_01_Set_Naehrloesung_02.state as Number).floatValue).replace(",",".")
    val strL3 = String.format("%.1f",(Hydroponik_01_Set_Naehrloesung_03.state as Number).floatValue).replace(",",".")
Also ein Komma wird durch einen Punkt ersetzt.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Antworten