[SOLVED] Prozentwert berechnen

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

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

Re: Prozentwert berechnen

Beitrag von udo1toni »

Peter Aschinger hat geschrieben: 22. Feb 2019 15:41 Und weshalb ist rrd4j nicht geeignet ?
rrd4j hat Probleme mit bestimmten Abfragen, z.B. changedSince ist so ein Fall.
Kann man da nicht ne art "Delay" einbauen, so das die Rule 120sec "hält" und dann weiter läuft ?
Nein, das geht gleich aus mehreren Gründen nicht. Zuerst mal arbeitet openHAB asynchron. Eine Rule kann beliebig oft getriggert werden und wird dann auch beliebig oft nebeneinander ausgeführt. Das "Anhalten" könnte im Extremfall dazu führen, dass gar kein Code mehr ausgeführt wird, weil alle zur Verfügung stehenden Threads von angehaltenen Rules belegt sind.
Die Rule wird ja nicht ausschließlich bei einem Wechsel der Betriebsart getriggert, sondern bei jeglicher Wertänderung. deshalb musst Du wissen, wann die Betriebsart gewechselt wurde.
Dann brauch ich keine Datenbank.
Na ja, die ist auch für andere Dinge sinnvoll. Man kann um das Problem herum programmieren, indem man die Funktion selbst implementiert:

Code: Alles auswählen

var Long lLStufe
rule "luefter geändert"
when
    Item Luefterstufe changed
then
    lLStufe = now.millis
end
In der eigentlichen Rule kannst Du dann mit

Code: Alles auswählen

if(lLStufe + 2*60*1000 < now.millis){
    //Lüfter läuft bereits mindestens 2 Minuten auf der aktuellen Stufe
}
als Abfrage arbeiten. Allerdings kannst Du dann den Trigger für Luefterstufe gleich ganz weg lassen, der bringt ja dann nichts mehr.
Bei dem ganzen geklammere wirds einem böse schwindelig. :-)
Aber nur zu Anfang, wenn man es mal verstanden hat, ist es einfach. Wenn man den Code immer schön einrückt, sieht man auf einen Blick, was wohin gehört.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
PeterA
Beiträge: 1052
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Prozentwert berechnen

Beitrag von PeterA »

[/quote]
Na ja, die ist auch für andere Dinge sinnvoll. Man kann um das Problem herum programmieren, indem man die Funktion selbst implementiert:

Code: Alles auswählen

var Long lLStufe
rule "luefter geändert"
when
    Item Luefterstufe changed
then
    lLStufe = now.millis
end
Ok, und wo muss der Code rein ? In eine extra rule ?
- OpenHab 2.4
#PWRUP

Benutzeravatar
PeterA
Beiträge: 1052
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Prozentwert berechnen

Beitrag von PeterA »

So habe ich jetzt mal die Rule eingetragen:

Code: Alles auswählen

rule "berechne Wirkungsgrad"
when
    Item Abluft changed or
    Item Zuluft changed or
    Item Aussenluft changed or
    Item Fort_Luft changed
then
    if(lLStufe + 2*60*1000 < now.millis){
    //Lüfter läuft bereits mindestens 2 Minuten auf der aktuellen Stufe
 }
{
    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;
    }
    if(!(Aussenluft.state instanceof Number)) {
        logWarn("Wirkungsgrad","Aussenluft.state not a Number: {}",Aussenluft.state)
        return;
    }
    if(!(Fort_Luft.state instanceof Number)) {
        logWarn("Wirkungsgrad","Fort_Luft.state not a Number: {}",Fort_Luft.state)
        return;
    }
    val Number Aussenluft = (Aussenluft.state as Number)
    val Number Fort_Luft = (Fort_Luft.state as Number)
    val Number nDivisor = (Abluft.state as Number) - Aussenluft //Wert fuer Berechung gem. Westaflex
    val Number nFaktor = (Zuluft.state as Number) - Aussenluft //Wert fuer Berechung gem. Westaflex
    val Number nDivisor2 = (Abluft.state as Number) - Fort_Luft
    if(nDivisor == 0) {
        logWarn("Wirkungsgrad","Aussentemperatur = Ablufttemperatur, Division durch 0!")
        Wirkungsgrad.postUpdate(NULL)
    } else
        Wirkungsgrad.postUpdate((100*nFaktor/nDivisor).intValue) //Berechung gem. Westaflex
    if(nDivisor2 == 0) {
        logWarn("Wirkungsgrad2","Ablufttemperatur = Aussentemperatur, Division durch 0!")
        Wirkungsgrad2.postUpdate(NULL)
    } else
        Wirkungsgrad2.postUpdate((100*nDivisor2/nDivisor).intValue)
 }
end
Aber dann kommt im Log das hier:

2019-02-22 18:46:31.709 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'berechne Wirkungsgrad': The name 'lLStufe' cannot be resolved to an item or type; line 8, column 8, length 7
Zuletzt geändert von PeterA am 23. Feb 2019 00:08, insgesamt 1-mal geändert.
- OpenHab 2.4
#PWRUP

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

Re: Prozentwert berechnen

Beitrag von udo1toni »

Ja, das ist eine extra Rule. Die Variablendefinition (var Long lLStufe) muss ganz zu Anfang der Rules-Datei stehen.

Und natürlich musst Du die Klammern um den auszuführenden Code setzen (das heißt, Du ersetzt den Kommentar mit dem Code, der nur ausgeführt werden soll, wenn der letzte Lüfterstufenwechsel mindestens zwei Minuten her ist)

Das gesamte Rules File sähe dann so aus (vorausgesetzt, es sind nicht noch weitere Rule vorhanden):

Code: Alles auswählen

// Beginn der Datei
// globale Variablen
var Long lLStufe

rule "luefter geändert"
when
    Item Luefterstufe changed
then
    lLStufe = now.millis
end

rule "berechne Wirkungsgrad"
when
    Item Abluft changed or
    Item Zuluft changed or
    Item Aussenluft changed or
    Item Fort_Luft changed
then
    if(lLStufe + 2*60*1000 < now.millis){
        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;
        }
        if(!(Aussenluft.state instanceof Number)) {
            logWarn("Wirkungsgrad","Aussenluft.state not a Number: {}",Aussenluft.state)
            return;
        }
        if(!(Fort_Luft.state instanceof Number)) {
            logWarn("Wirkungsgrad","Fort_Luft.state not a Number: {}",Fort_Luft.state)
            return;
        }

        val Number Aussenluft = (Aussenluft.state as Number)
        val Number Fort_Luft = (Fort_Luft.state as Number)
        val Number nDivisor = (Abluft.state as Number) - Aussenluft //Wert fuer Berechung gem. Westaflex
        val Number nFaktor = (Zuluft.state as Number) - Aussenluft //Wert fuer Berechung gem. Westaflex
        val Number nDivisor2 = (Abluft.state as Number) - Fort_Luft

        if(nDivisor == 0) {
            logWarn("Wirkungsgrad","Aussentemperatur = Ablufttemperatur, Division durch 0!")
            Wirkungsgrad.postUpdate(NULL)
        } else
            Wirkungsgrad.postUpdate((100*nFaktor/nDivisor).intValue) //Berechung gem. Westaflex
        if(nDivisor2 == 0) {
            logWarn("Wirkungsgrad2","Ablufttemperatur = Aussentemperatur, Division durch 0!")
            Wirkungsgrad2.postUpdate(NULL)
        } else
            Wirkungsgrad2.postUpdate((100*nDivisor2/nDivisor).intValue)
    }
end
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
PeterA
Beiträge: 1052
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Prozentwert berechnen

Beitrag von PeterA »

Ok, habe ich jetzt mal alles so eingetragen.
Aber dann kommt das im Log:

2019-02-22 23:29:58.015 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'berechne Wirkungsgrad': An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.LongExtensions.operator_plus(long,int) on instance: null

EDIT:
Es scheint doch zu funktionieren:

Hier Starte ich den Lüfter:
2019-02-22 23:38:38.512 [ome.event.ItemCommandEvent] - Item 'LuefterStufe' received command 1

2019-02-22 23:38:38.519 [nt.ItemStatePredictedEvent] - LuefterStufe predicted to become 1

2019-02-22 23:38:38.527 [vent.ItemStateChangedEvent] - LuefterStufe changed from 0 to 1

und erst hier beginnt die Berechnung:
2019-02-22 23:40:28.531 [vent.ItemStateChangedEvent] - Abluft changed from 18.4 to 18.5

2019-02-22 23:40:44.431 [vent.ItemStateChangedEvent] - Aussenluft changed from 7.4 to 7.3

2019-02-22 23:40:44.514 [vent.ItemStateChangedEvent] - Wirkungsgrad changed from 58 to 56

2019-02-22 23:40:44.533 [vent.ItemStateChangedEvent] - Wirkungsgrad2 changed from 82 to 83

TOP TOP TOP!

Super Vielen Dank! :D :D

Edit2:

Funktioniert doch nicht..
2019-02-22 23:50:45.647 [vent.ItemStateChangedEvent] - Wirkungsgrad2 changed from 132 to 133

2019-02-22 23:50:48.191 [vent.ItemStateChangedEvent] - RasPi_Cpu_SystemUptime changed from 17386.8 to 17387.8

2019-02-22 23:50:56.050 [vent.ItemStateChangedEvent] - Abluft changed from 16.1 to 16.0

2019-02-22 23:50:56.076 [vent.ItemStateChangedEvent] - Wirkungsgrad changed from 58 to 59

2019-02-22 23:50:56.082 [vent.ItemStateChangedEvent] - Wirkungsgrad2 changed from 133 to 134

Berechnung läuft ob wohl die Lüftung Aus ist...
- OpenHab 2.4
#PWRUP

Benutzeravatar
PeterA
Beiträge: 1052
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Prozentwert berechnen

Beitrag von PeterA »

So, wenn ich mir das Log so ansehe kann ich folgendes beobachten:
Lüfter läuft, Berechnung läuft.
Lüfter wird gestoppt, Berechnung wird gestoppt aber nach 120sec startet die Berechnung wieder. Obwohl die Lüfter aus sind.
Lüfter werden wieder gestartet, Berechnung beginnt 120sec Später....
- OpenHab 2.4
#PWRUP

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

Re: Prozentwert berechnen

Beitrag von udo1toni »

Ups. Ich hab aus Versehen die BEdingung rausgenommen, die die Lüfterstufe abfragt. Die erste Zeile müsste also so aussehen:

Code: Alles auswählen

if(lLStufe + 2*60*1000 < now.millis && Luefterstufe.state.toString != "0"){
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
PeterA
Beiträge: 1052
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Prozentwert berechnen

Beitrag von PeterA »

udo1toni hat geschrieben: 22. Feb 2019 22:26 Ja, das ist eine extra Rule. Die Variablendefinition (var Long lLStufe) muss ganz zu Anfang der Rules-Datei stehen.

Und natürlich musst Du die Klammern um den auszuführenden Code setzen (das heißt, Du ersetzt den Kommentar mit dem Code, der nur ausgeführt werden soll, wenn der letzte Lüfterstufenwechsel mindestens zwei Minuten her ist)

Das gesamte Rules File sähe dann so aus (vorausgesetzt, es sind nicht noch weitere Rule vorhanden):
Hallo Udo, was meinst Du mit "weitere Rule vorhhanden" ?
Ja es gibt noch eine Rule. Die hat aber nix mit der Berechnungsrule zu tun.
- OpenHab 2.4
#PWRUP

Benutzeravatar
PeterA
Beiträge: 1052
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Prozentwert berechnen

Beitrag von PeterA »

So , hier nun noch mal die Aktuelle Rule:
Leider haut das hier immer noch nicht so hin...
Wenn die Lüfter aus sind = LuefterStufe 0, Läuft die Berechnung weiter.

Code: Alles auswählen

// Beginn der Datei
// globale Variablen
var Long lLStufe

rule "luefter geändert"
when
    Item LuefterStufe changed
then
    lLStufe = now.millis
end

rule "berechne Wirkungsgrad"
when
    Item Abluft changed or
    Item Zuluft changed or
    Item Aussenluft changed
then
    if(lLStufe + 2*60*1000 < now.millis && LuefterStufe.state.toString != "0"){
    //Lüfter läuft bereits mindestens 2 Minuten auf der aktuellen Stufe
 }
{
    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;
    }
    if(!(Aussenluft.state instanceof Number)) {
        logWarn("Wirkungsgrad","Aussenluft.state not a Number: {}",Aussenluft.state)
        return;
    }
    val Number Aussenluft = (Aussenluft.state as Number)
    val Number nDivisor = (Abluft.state as Number) - Aussenluft //Wert fuer Berechung gem. Westaflex
    val Number nFaktor = (Zuluft.state as Number) - Aussenluft //Wert fuer Berechung gem. Westaflex
    if(nDivisor == 0) {
        logWarn("Wirkungsgrad","Aussentemperatur = Ablufttemperatur, Division durch 0!")
        Wirkungsgrad.postUpdate(NULL)
    } else
        Wirkungsgrad.postUpdate((100*nFaktor/nDivisor).intValue) //Berechung gem. Westaflex
       
 }
end
- OpenHab 2.4
#PWRUP

Benutzeravatar
peter-pan
Beiträge: 2564
Registriert: 28. Nov 2018 12:03
Answers: 25
Wohnort: Schwäbisch Gmünd

Re: Prozentwert berechnen

Beitrag von peter-pan »

Hallo Peter,
vielleicht sind da ein paar geschweifte Klammern nach dem ersten if zuviel. Deshalb werden diese Anweisungen immer ausgeführt, da sie durch die Klammerung keine Unteranweisungen der ersten Bedingung sind. Udo hatte das extra schön eingerückt, damit es visuell erkannt werden kann.
So sollte es gehen:

Code: Alles auswählen

// Beginn der Datei
// globale Variablen
var Long lLStufe

rule "luefter geändert"
when
    Item LuefterStufe changed
then
    lLStufe = now.millis
end

rule "berechne Wirkungsgrad"
when
    Item Abluft changed or
    Item Zuluft changed or
    Item Aussenluft changed
then
    if(lLStufe + 2*60*1000 < now.millis && LuefterStufe.state.toString != "0"){
    //Lüfter läuft bereits mindestens 2 Minuten auf der aktuellen Stufe

       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;
       }
       if(!(Aussenluft.state instanceof Number)) {
           logWarn("Wirkungsgrad","Aussenluft.state not a Number: {}",Aussenluft.state)
           return;
       }
       val Number Aussenluft = (Aussenluft.state as Number)
       val Number nDivisor = (Abluft.state as Number) - Aussenluft //Wert fuer Berechung gem. Westaflex
       val Number nFaktor = (Zuluft.state as Number) - Aussenluft //Wert fuer Berechung gem. Westaflex
       if(nDivisor == 0) {
           logWarn("Wirkungsgrad","Aussentemperatur = Ablufttemperatur, Division durch 0!")
           Wirkungsgrad.postUpdate(NULL)
       } else
           Wirkungsgrad.postUpdate((100*nFaktor/nDivisor).intValue) //Berechung gem. Westaflex
          
 }
end
Ich hoffe, ich hab's jetzt nicht "verschlimmbösert" :roll: ;)

Gruss - Peter
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.1.1 openhabian

Antworten