Seite 1 von 1

String Formatieren - Sonderzeichen

Verfasst: 22. Jan 2023 11:24
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

Re: String Formatieren - Sonderzeichen

Verfasst: 22. Jan 2023 16:27
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 :)

Re: String Formatieren - Sonderzeichen

Verfasst: 27. Jan 2023 23:26
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

Re: String Formatieren - Sonderzeichen

Verfasst: 28. Jan 2023 03:28
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).

Re: String Formatieren - Sonderzeichen

Verfasst: 13. Feb 2023 08:42
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

Re: String Formatieren - Sonderzeichen

Verfasst: 13. Feb 2023 10:22
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.

Re: String Formatieren - Sonderzeichen

Verfasst: 13. Feb 2023 11:05
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.

Re: String Formatieren - Sonderzeichen

Verfasst: 13. Feb 2023 16:51
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.