Seite 3 von 4

Re: Gas-Zählerstand in manuell in openHab eingeben

Verfasst: 21. Feb 2024 22:20
von peter-pan
Ich habe nicht den Variablenwert "var Letzter_abgelesener_Zaehlerstand = 1495.70" gemeint, sondern den Wert des Items "Gaszaehler_Stand".

Das wird in der IF-Bedingung abgefragt. Wenn der Wert in diesem Item grösser als der Variablen-Wert ist, dann wird das Item natürlich nicht mehr auf den Variablenwert zurückgesetzt, sondern immer weiter hochgezählt:

Code: Alles auswählen

Gaszaehler_Heute.postUpdate(Gaszaehler_Heute.state as DecimalType + Einheit)
Gaszaehler_Stand.postUpdate(Gaszaehler_Stand.state as DecimalType + Einheit)
Ich könnte mir vorstellen, dass dieser Wert auf deinem Produktivsystem auch schon grösser als 16520.57 war.

Deshalb jetzt die zweite Regel. Da kannst du den Variablenwert bestimmen. Der wird dann einfach in das Item eingepflegt und die erste Regel zählt dann wieder, wie gehabt, bei Änderung des Trigger-Items.

Edit: Trigger-Item war GASZahler_GASZahler ;)

Re: Gas-Zählerstand in manuell in openHab eingeben

Verfasst: 25. Feb 2024 12:03
von Locke
das Testsystem ist jetzt openHAB4.1.1
peter-pan hat geschrieben: 20. Feb 2024 14:22 Wenn's klappt gib Bescheid, wenn's nicht klappt auch.
Hi Peter,
ich habe es mit Deiner Änderung getestet und es funktioniert.
Aber so wie Du gesagt hast nur wenn der eingegebene Wert größer ist als der Aktuelle.
udo1toni hat geschrieben: 20. Feb 2024 00:09 Die einfachste Möglichkeit wäre vermutlich, ein Item zu definieren und den Zählerstand einzugeben, nicht als globale Variable, sondern über die UI.
In der Main UI gibt es sogar ganz reguläre Widgets für die Eingabe von Zahlenwerten.
wollte jetzt noch Udo's Variante probieren, aber ich finde kein Widget für die Eingabe von Zahlenwerten, vielleicht bin ich ja blind oder ich suche an der falschen Stelle.
Ich bin auf "Einstellungen" --> "Automation" --> Widgets for the Main UI gegangen und finde dort das Keypad, damit kann ich aber keinen . oder , bei der Eingabe machen.
Habe ich etwas falsch verstanden ?

Re: Gas-Zählerstand in manuell in openHab eingeben

Verfasst: 25. Feb 2024 12:43
von udo1toni
Es handelt sich um die Input Card, die direkt mit dabei ist. Du musst den Input type auf number und den Input Mode auf decimal einstellen.

Code: Alles auswählen

component: oh-input-card
config:
  item: myNumber
  title: Eine Zahl
  name: Wert
  type: number
  inputmode: decimal
  sendButton: true
Die Knöpfe zum schrittweisen verstellen des Wertes kannst Du bei der Eingabe ignorieren. Den send Button brauchst Du, um den Wert zu speichern.

Re: Gas-Zählerstand in manuell in openHab eingeben

Verfasst: 25. Feb 2024 13:26
von Locke
udo1toni hat geschrieben: 20. Feb 2024 00:09
Locke hat geschrieben: 19. Feb 2024 20:59 Welche möglichkeit gibt es den Zählerstand anders anzupassen ?
Die einfachste Möglichkeit wäre vermutlich, ein Item zu definieren und den Zählerstand einzugeben, nicht als globale Variable, sondern über die UI.
In der Main UI gibt es sogar ganz reguläre Widgets für die Eingabe von Zahlenwerten.
Das Item wäre im Zweifel persistiert, hätte also auch nach einem Systemneustart sofort den letzten bekannten Wert.

Ich würde die Rule auch leicht anders gestalten. Hier mal noch die Version mit globaler Variable, aber umgestaltet:

Code: Alles auswählen

var    nCountTotalread = 1495.70                   // Letzte Ablesung
val            Einheit = 0.01                      // m³ pro Puls
val      Gaspreis_Jahr = 200.1                     // € pro Jahr
val       Gaspreis_Tag = 54.82191780821918         // ct pro Tag
val       Gaspreis_kWh = 19.269                    // ct pro kWh
val     Gaspreis_zZahl = 0.9645                    // z Zahl
val Gaspreis_Brennwert = 10.293                    // Brennwert

rule "Increment Gas Meter"
when
    Item DummySchalter_TestSchalter changed from OFF to ON
then
    var nCountToday = 0.0
    if(Gaszaehler_Heute.state instanceof Number)
        nCountToday = Gaszaehler_Heute.state as Number

    var nCountTotal = 0.0
    if(Gaszaehler_Stand.state instanceof Number)
        nCountTotal = Gaszaehler_Stand.state as Number

    if(nCountTotal < nCountTotalread) {
        logInfo("counter","Zählerstand {} geringer als Start Offset {}, setze letzen bekannten Zählerstand", nCountTotal, nCountTotalread) 
        nCountTotal = nCountTotalread
    }
    nCountToday += Einheit
    nCountTotal += Einheit
    Gaszaehler_Heute.postUpdate(nCountToday)
    Gaszaehler_Stand.postUpdate(nCountTotal)
    var Faktor = Gaspreis_zZahl * Gaspreis_Brennwert * Gaspreis_kWh 
    Gaskosten_Heute.postUpdate((nCountToday * Faktor + Gaspreis_Tag) / 100) 
end
Hi Udo,
den Zählerstand kann ich anpassen über die Input Card, wenn ich dann ein Test mache (Impulse) bekomme ich Log den Fehler (habe mir erlaubt die Regel Udo zu nennen um nicht ganz durcheinander zu kommen ;) )

läuft jetzt auf System 4 (Testsystem), Raspberry Pi 4, 2GB RAM, openHAB 4.1.1

Code: Alles auswählen

[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Udo_GAS-1' failed: An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.DoubleExtensions.operator_lessThan(double,double) on instance: null in Udo_GAS

Re: Gas-Zählerstand in manuell in openHab eingeben

Verfasst: 25. Feb 2024 14:28
von udo1toni
Du hast die Rules miteinander vermischt...

Code: Alles auswählen

val            Einheit = 0.01                      // m³ pro Puls
val      Gaspreis_Jahr = 200.1                     // € pro Jahr
val       Gaspreis_Tag = 54.82191780821918         // ct pro Tag
val       Gaspreis_kWh = 19.269                    // ct pro kWh
val     Gaspreis_zZahl = 0.9645                    // z Zahl
val Gaspreis_Brennwert = 10.293                    // Brennwert

rule "Increment Gas Meter"
when
    Item DummySchalter_TestSchalter changed from OFF to ON
then
    var nCountTotal = 0.0
    var nCountToday = 0.0
    var      Faktor = Gaspreis_zZahl * Gaspreis_Brennwert * Gaspreis_kWh 

    if(Gaszaehler_Stand.state instanceof Number)
        nCountTotal = Gaszaehler_Stand.state as Number

    nCountTotal += Einheit
    Gaszaehler_Stand.postUpdate(nCountTotal)
    Thread.sleep(300)
    nCountToday = Gaszaehler_Stand.deltaSince(now.with(LocalTime.MIDNIGHT))
    Gaszaehler_Heute.postUpdate(nCountToday)
    Gaskosten_Heute.postUpdate((nCountToday * Faktor + Gaspreis_Tag) / 100) 
end
wäre die richtige Rule.

Re: Gas-Zählerstand in manuell in openHab eingeben

Verfasst: 25. Feb 2024 17:11
von Locke
udo1toni hat geschrieben: 25. Feb 2024 14:28 Du hast die Rules miteinander vermischt...

Code: Alles auswählen

val            Einheit = 0.01                      // m³ pro Puls
val      Gaspreis_Jahr = 200.1                     // € pro Jahr
val       Gaspreis_Tag = 54.82191780821918         // ct pro Tag
val       Gaspreis_kWh = 19.269                    // ct pro kWh
val     Gaspreis_zZahl = 0.9645                    // z Zahl
val Gaspreis_Brennwert = 10.293                    // Brennwert

rule "Increment Gas Meter"
when
    Item DummySchalter_TestSchalter changed from OFF to ON
then
    var nCountTotal = 0.0
    var nCountToday = 0.0
    var      Faktor = Gaspreis_zZahl * Gaspreis_Brennwert * Gaspreis_kWh 

    if(Gaszaehler_Stand.state instanceof Number)
        nCountTotal = Gaszaehler_Stand.state as Number

    nCountTotal += Einheit
    Gaszaehler_Stand.postUpdate(nCountTotal)
    Thread.sleep(300)
    nCountToday = Gaszaehler_Stand.deltaSince(now.with(LocalTime.MIDNIGHT))
    Gaszaehler_Heute.postUpdate(nCountToday)
    Gaskosten_Heute.postUpdate((nCountToday * Faktor + Gaspreis_Tag) / 100) 
end
wäre die richtige Rule.
ich habe jetzt die Rule genommen wie Du sagst, leider ist der Fehler immer noch.

Code: Alles auswählen

[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Udo_GAS-1' failed: An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.DoubleExtensions.operator_lessThan(double,double) on instance: null in Udo_GAS
das war auch noch im Log

Code: Alles auswählen

[INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'Udo_GAS.rules'
[INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'Udo_GAS.rules', using it anyway:
Cannot reference the field 'Gaszaehler_Stand' before it is defined

Re: Gas-Zählerstand in manuell in openHab eingeben

Verfasst: 25. Feb 2024 19:15
von udo1toni
Gaszaehler_Stand ist das Item, welches den Zählerstand enthält, das muss schon existieren :)

Re: Gas-Zählerstand in manuell in openHab eingeben

Verfasst: 25. Feb 2024 19:53
von Locke
Ja, es existiert ja auch. Ich kann den Zählerstand dort ablesen oder anpassen mit der Input Card.
Mit der Rule von Peter funktioniert es ja auch.
Würde es auch gern mit Deinem Vorschlag probieren, komme aber im Moment nicht weiter.

Re: Gas-Zählerstand in manuell in openHab eingeben

Verfasst: 25. Feb 2024 19:59
von udo1toni
Dann hast Du in der Datei noch andere Rules drin stehen. Die Meldung

Code: Alles auswählen

Cannot reference the field 'Gaszaehler_Stand' before it is defined
besagt jedenfalls, dass die Rule Engine Gaszaehler_Stand nicht als Item wahrnimmt. Innerhalb der Rule gibt es aber nur Referenzen auf Gaszaehler_Stand.state - und natürlich die Methode Gaszaehler_Stand.postUpdate(). Das kann also nicht sein.

Re: Gas-Zählerstand in manuell in openHab eingeben

Verfasst: 26. Feb 2024 11:32
von peter-pan
...also; die Art wie Udo an das Thema ran gegangen ist, ist die mit den Möglichkeiten aus OH3/OH4 (Widgets). Mein Herangehensweise ist dagegen noch "oldschool", basierend auf der ursprünglichen Regel (OH2).

Aber noch mal von Anfang!
Unter OH2.5 hattest du damals ein Rule gepostet, mit der du einen Wert (erstmalig - Gaszaehler_Stand.postUpdate(Letzter_abgelesener_Zaehlerstand))setzen wolltest und danach sollte dieser Wert "fix" sein

Code: Alles auswählen

 if (Gaszaehler_Stand.state != NULL && Gaszaehler_Stand.state <= Letzter_abgelesener_Zaehlerstand) {
        Gaszaehler_Stand.postUpdate(Letzter_abgelesener_Zaehlerstand)  } 
und die Regel sollte beim Triggern diesen Wert immer wieder erhöhen
(var Einheit = 0.01)
. Und das hat ja auch schon funktioniert.

Deshalb habe ich eine zweite Regel vorgeschlagen, die basierend auf der "globalen Variablen"
(var Letzter_abgelesener_Zaehlerstand = 1495.70)
diesen Wert wieder in dein Item "Gaszaehler_Stand" setzt.

Wenn ich dich aber jetzt richtig verstehe, brauchst(willst) du die Prüfung auf den "letzten abgelesenen Zählerstand" gar nicht. Dann kann man diese Bedingung (s.o.) auch weglassen und mit der eleganten Lösung von Udo den Wert einfach direkt in das Item "Gaszaehler_Stand" per Widget setzen.

Der Yaml-Code wäre dann mit deinem Item:

Code: Alles auswählen

component: oh-input-card
config:
  item: Gaszaehler_Stand
  title: Eine Zahl
  name: Wert
  type: number
  inputmode: decimal
  sendButton: true
slots: null
und sieht so aus:
widget.jpg
Die Fehlermeldung...

Code: Alles auswählen

2024-02-26 11:12:46.645 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'test_zaehler_udo-1' failed: An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.DoubleExtensions.operator_plus(double,double) on instance: null in test_zaehler_udo
habe ich beim Ausführen der Regel auch bekommen und diese noch etwas angepasst (Deklaration der Variablen in der Rule-Typ):

Code: Alles auswählen

val            Einheit = 0.01                      // m³ pro Puls
val      Gaspreis_Jahr = 200.1                     // € pro Jahr
val       Gaspreis_Tag = 54.82191780821918         // ct pro Tag
val       Gaspreis_kWh = 19.269                    // ct pro kWh
val     Gaspreis_zZahl = 0.9645                    // z Zahl
val Gaspreis_Brennwert = 10.293                    // Brennwert

rule "Increment Gas Meter"
when
    Item Dummy_4 changed from OFF to ON
then
    var Number nCountTotal = 0.0
    var Number nCountToday = 0.0
    var Number     Faktor = Gaspreis_zZahl * Gaspreis_Brennwert * Gaspreis_kWh 

    if(Gaszaehler_Stand.state instanceof Number)
        nCountTotal = Gaszaehler_Stand.state as Number

    nCountTotal += Einheit
    Gaszaehler_Stand.postUpdate(nCountTotal)
    Thread.sleep(300)
    nCountToday = Gaszaehler_Stand.deltaSince(now.with(LocalTime.MIDNIGHT))
    Gaszaehler_Heute.postUpdate(nCountToday)
    Gaskosten_Heute.postUpdate((nCountToday * Faktor + Gaspreis_Tag) / 100) 
end
Dann hat's geklappt, "wie geschnitten Brot" :lol: