Seite 1 von 5
[SOLVED] Prozentwert berechnen
Verfasst: 11. Feb 2019 17:50
von PeterA
Hallo zusammen,
aus unserer Lüftungsanlage lese ich zwei Temperaturwerte aus.
Die sind dann als Number Item verfügbar.
Jetzt möchte ich folgende Formel Rechnen:
100/temp1xtemp2=ergebins
Also zb: 100/18,5x14,5=78,37% (Der Wirkungsgrad zwischen temp1 und temp2)
Ich habe schon gelesen dass das mit Rules funktioniert.
Wer würde mir ein Beispiel aufzeigen?
Und wie funktioniert das im Openhab?
Jetzt schon mal vielen Dank
Re: Prozentwert berechnen
Verfasst: 11. Feb 2019 18:37
von udo1toni
Nehmen wir drei Items an:
Code: Alles auswählen
Number Temp1 "Temperatur 1 [%.1f °C]" ...
Number Temp2 "Temperatur 2 [%.1f °C]" ...
Number efficiency "Wirkungsgrad [%d %%]"
Dazu passende Rule:
Code: Alles auswählen
rule "calculate efficiency"
when
Item Temp1 changed or
Item Temp2 changed
then
if(!(Temp1.state instanceof Number)) {
logWarn("efficiency","Temp1.state not a Number: {}",Temp1.state)
return;
}
if(!(Temp2.state instanceof Number)) {
logWarn("efficiency","Temp2.state not a Number: {}",Temp2.state)
return;
}
if((Temp1.state as Number) == 0) {
logWarn("efficiency","Temp1.state 0. Can't devide by 0!")
return;
}
efficiency.postUpdate((100/(Temp1.state as Number)*(Temp2.state as Number)).intValue)
end
Die eigentliche Berechnung ist simpel (die letzte Zeile), das Problem sind die verschiedenen Möglichkeiten, die zu einem Fehler führen könnten. Dazu sind die drei if-Konditionen. Da man gerne wissen möchte, warum der Wert nicht aktualisiert wird, gibt es für jeden Fall die entsprechende Meldung. Zuerst wird geprüft, ob eines der beiden Number Items keine Zahl enthält (es wurde noch keine Temperatur geladen oder der Fühler lieferte einen ungültigen Wert, so dass das Binding den Inhalt des Items auf NULL setzt). Im Fehlerfall wird dies gemeldet und die Rule beendet.
Falls beide Items eine Zahl enthalten, wird für den Divisor überprüft, ob er 0 ist. Ist zwar prinzipiell unwahrscheinlich, man möchte das aber trotzdem ausschließen.
Die Begrenzung der Zahl auf Integer ist wichtig, da sonst die Anzeige des Wertes nicht funktionieren wird.
Vermutlich müsste man die beiden Temperaturen eigentlich auf Kelvin umrechnen (+273,15), bevor man die eigentliche Berechnung durchführt:
Code: Alles auswählen
rule "calculate efficiency"
when
Item Temp1 changed or
Item Temp2 changed
then
if(!(Temp1.state instanceof Number)) {
logWarn("efficiency","Temp1.state not a Number: {}",Temp1.state)
return;
}
if(!(Temp2.state instanceof Number)) {
logWarn("efficiency","Temp2.state not a Number: {}",Temp2.state)
return;
}
val Number nDivisor = 273,15 + (Temp1.state as Number)
val Number nFaktor = 273,15 + (Temp2.state as Number)
efficiency.postUpdate((100/nDivisor*nFaktor).intValue)
end
Prinzipiell muss man hier keine Konstanten verwenden, es erhöht aber die Lesbarkeit

Re: Prozentwert berechnen
Verfasst: 11. Feb 2019 19:08
von PeterA
Oha, vielen Dank für die ausführlichen Vorschläge für den Code. Jetzt bleibt nur noch die Frage wie ich das dem Openhab beibringe. Vermutlich muss die Rules Datei in den Rules Ordner, aber wie rufe ich das ganze auf?
Leider habe ich bisher nur mit PaperUi und Habpanel gearbeitet.
Wahrscheinlich brauche ich für das Ergebnis auch noch ein Item?
Grüße
Edit:
Wenn ich das richtig verstanden habe lege ich mir im PaperUi ein "effiency" Item an. Und passe die Namen der Temperatur items an. Wenn alles klappt müsste im efficency item dad Ergebnis der Berechnung stehen?
Re: Prozentwert berechnen
Verfasst: 11. Feb 2019 23:42
von udo1toni
Das Ergebnis landet im 3. Item. Die Schreibweise der Items ist natürlich die in einer Items Datei, das Item kann aber genauso gut über Paper UI erstellt werden. In der Rule siehst Du in der letzten Zeile (naja, die vorletzte, end ist die letzte Zeile) die Zuweisung des Wertes. Ein Item kann nur mit Methoden oder Actions angesteuert werden. Item.postUpdate() bedeutet, dass der Status des Items gesetzt wird. Item.sendCommand() bedeutet, einen Befehl an das Item zu senden. Befehle werden z.B. auch an verlinkte Addons weitergeleitet.
Rules gehören in eine *.rules Datei in den Ordner <openhabconf>/rules/ wobei <openhabconf> abhängig davon ist, wie openHAB installiert wurde. Die korrekten Pfade kannst Du im Zweifel in der Doku finden, oder Du verrätst welches System Du nutzt
Rules werden getriggert. Der Trigger steht im when-Teil der Rule. Falls sich eines der beiden Items ändert (genauer natürlich der Status der Items), wird die Rule unverzüglich ausgeführt.
Re: Prozentwert berechnen
Verfasst: 12. Feb 2019 00:20
von PeterA
Oh ich vergaß... Raspberry mit Openhabian
Re: Prozentwert berechnen
Verfasst: 12. Feb 2019 00:34
von udo1toni
Ah. Dann passt das ja. Die Text Konfiguration befindet sich unter /etc/openhab2/, entsprechend musst Du für die Rule eine Datei
/etc/openhab2/rules/my.rules
anlegen (natürlich kannst Du statt my auch einen anderen Namen nehmen, aber Speicherort und Dateiendung sind verpflichtend exakt so.
Re: Prozentwert berechnen
Verfasst: 12. Feb 2019 06:49
von PeterA
Da fällt mir noch ein, das die Berechnung nur Erfolgen soll wenn die Lüftungsanlage auch in Betrieb ist.
Dafür gibt es ein ReadHoldWrite Register.
LuefterStufe habe ich das genannt. Dieses kann 0,1,2,3 sein.
Also müsste noch eine zusätzliche when Bedingung in die Regel oder ?
In etwa "when LuefterStufe is not 0"....
Re: Prozentwert berechnen
Verfasst: 12. Feb 2019 16:02
von udo1toni
Die Bedingung muss in den then-Teil der Rule. Die Rule triggert bei Wertänderung, anschließend überprüfst Du, ob die Anlage in Betrieb ist, und führst nur dann den Rest des Codes aus.
Der When-Teil der Rule ist eine Auflistung von Triggern, hier stehen keine Bedingungen!
Du kannst die erste Bedingung (instanceof...) als Beispiel nehmen und einfach vorne dran hängen. Dort fragst Du Dein Item ab:
Code: Alles auswählen
if(LuefterBetrieb.state.toString != "0" && LuefterBetrieb.state != NULL)
Dann allerdings muss um den restlichen Code ein { } um zu kennzeichnen, dass dieser Code als Block zu betrachten ist. Das ist dann quasi ein Befehl, nur ausgeführt wird, wenn die Bedingung zutrifft.
Warum habe ich nun plötzlich mit state.toString den Status als String gewandelt, statt ihn als Zahl zu betrachten? Weil openHAB eine nullPointerExeption schmeißt, falls man versucht, NULL als Number zu casten. Man müsste also im Zweifel wie im schon vorhandenen Code das .state zuerst darauf prüfen, ob es auch vom Typ Number ist.
Re: Prozentwert berechnen
Verfasst: 12. Feb 2019 19:51
von PeterA
Also, so hab ich es jetzt in meiner wirkungsgrad.rules stehen:
Code: Alles auswählen
rule "berechne Wirkungsgrad"
when
Item Abluft changed or
Item Zuluft changed
then
if(LuefterStufe.state.toString != "0" && LuefterStufe.state != NULL)
{if(!(Abluft.state instanceof Number)) {
logWarn("Wirkungsgrad","Abluft.state not a Number: {}",Abluft.state)
return;
}
if(!(Zuluft.state instanceof Number)) {
logWarn("Wirkungsgrad","Zuluft.state not a Number: {}",Zuluft.state)
return;
}
val Number nDivisor = 273,15 + (Abluft.state as Number)
val Number nFaktor = 273,15 + (Zuluft.state as Number)
Wirkungsgrad.postUpdate((100/nDivisor*nFaktor).intValue)
}
end
Aber im Log kommt das:
2019-02-12 21:17:04.426 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'calcutate.rules' has errors, therefore ignoring it: [15,30]: mismatched input ',' expecting '}'
[16,29]: mismatched input ',' expecting 'end'
Re: Prozentwert berechnen
Verfasst: 12. Feb 2019 22:14
von PeterA
Gefunden....die Kommas bei der Kevin Zahl müssen Punkte sein.
Aber berechnet wird nix.....