Anzeige der Stromzählerwert um den Faktor 1.000 zu hoch

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

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

Re: Anzeige der Stromzählerwert um den Faktor 1.000 zu hoch

Beitrag von udo1toni »

Optimus#1978# hat geschrieben: 27. Apr 2024 08:13 Ich vermute, dass dies daran liegt, dass meine Zeitreihe erst am 07.02.2024 beginnt (dem Tag, an dem der optische Lesekopf für den Stromzähler installiert wurde).
Genau. openHAB hat keinen gültigen Wert für den Bezugspunkt.
Optimus#1978# hat geschrieben: 27. Apr 2024 08:13 Kann ich die Number items Energiebezug und Energieeinspeisung für den 01.01.2024 dort nachträglich manuell erfassen?
Nein, das ist so nicht vorgesehen. Und da die Daten, wenn ich mich richtig erinnere, bei Dir in rrd4j gehalten werden (das ist die "Einsteigerdroge" der Persistence ;) ), ist es auch gar nicht so einfach, überhaupt Werte innerhalb der entsprechenden Dateien zu manipulieren.

Möglichkeit 1: Du stellst auf eine (SQL) Datenbank um. Allerdings gibt es auch keinen einfachen Weg, die Daten aus rrd4j auszulesen um sie in eine Datenbank zu überführen. Es liefe auf eine Menge Handarbeit hinaus. Anschließend hast Du die Daten aber in einer Datenbank, die Du mit entsprechenden Tools leicht bearbeiten kannst - z.B. mittels Aktualisierungsabfragen.

Möglichkeit 2: Du lebst dieses Jahr damit, dass der Wert nicht angezeigt wird (ok, nicht wirklich...)

Möglichkeit 3: Du baust einen Würg-around ;)
Der Ansatz dazu wäre folgender:
  • Du hast den Zählerstand zum 1.1. (z.B. weil Du den Wert zu dem Zeitpunkt manuell abgelesen hast).
  • Außerdem hast Du den Wert vom 08.02.2024 (!) Mitternacht.
  • Du kannst also die (statische) Differenz für diesen Zeitraum von Hand bestimmen.
  • Nun stellst Du (nur für 2024) den Zeitpunkt für Jahresbeginn auf den 08.02.2024, Mitternacht:

    Code: Alles auswählen

    val ZonedDateTime start_of_year = start_of_day.withDayOfYear(39) // temporär 08.02. des Jahres
    
  • und addierst zum ermittelten Wert die Differenz, die Du ja schon bestimmt hast.
  • zum 1.1.2025 entfernst Du das Hilfskonstrukt.
Den 08.02. verwendest Du als Bezugspunkt, weil es an dem Tag um Mitternacht bereits einen Messwert gibt, am 07.02. hingegen vermutlich noch nicht. Letztlich ist es aber egal, welchen Bezugspunkt Du nutzt, es könnte auch der 26.04. sein :) wichtig ist ja nur, dass die Differenz vom Bezugspunkt bekannt ist und openHAB die Differenz zum aktuellen Tag aus der Persistence bestimmen kann.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.2.2, LXC), mit openHABian eingerichtet

Optimus#1978#
Beiträge: 32
Registriert: 6. Feb 2024 14:29
Answers: 0

Re: Anzeige der Stromzählerwert um den Faktor 1.000 zu hoch

Beitrag von Optimus#1978# »

Ich möchte den "Würg-around" (diese Schreibweise muss ich mir merken :D ) gemäß Alternative 3 realisieren.

Der Eintrag für "Energiereinspeisung / Jahr (kWh)" in den "rules" lautet nun:

Code: Alles auswählen

EnergyoutYear.postUpdate(0.001 * Energyout.deltaSince(start_of_year) as Number)
val ZonedDateTime start_of_year = start_of_day.withDayOfYear(39) // temporär 08.02. des Jahres
Da der 1. Wert in meiner Zeitreihe für den 07.02.2024 um 20.15 Uhr vorliegt, und der 39. Tag des Jahres 2024 der 08.02.2024 ist, gibt es nach meinem Verständnis für den 08.02.2024, 00:00 Uhr einen Startwert (unabhängig davon, ob ich für den 01.01. den Anfangsverbrauchswert erfasse oder nicht).

Im OpenHAB-Webinterface wird aber weiterhin der Wert "Null" angezeigt".

Was muss ich hier noch ändern?

Code: Alles auswählen

und addierst zum ermittelten Wert die Differenz, die Du ja schon bestimmt hast.
... und an welcher Stelle genau muss ich die Addition vornehmen?

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

Re: Anzeige der Stromzählerwert um den Faktor 1.000 zu hoch

Beitrag von udo1toni »

Du musst start_of_year schon vorher definieren, nicht erst, nachdem Du darauf zugreifst. außerdem musst Du natürlich noch die Differenz zwischen dem 1.1. und dem 8.2. dazu addieren. Also z.B. so: da wären in der Zeit vom 1.1. bis 8.2. 253,34 kWh angefallen.

Code: Alles auswählen

val ZonedDateTime start_of_day = now.with(LocalTime.MIDNIGHT)
val ZonedDateTime start_of_year = start_of_day.withDayOfYear(39) // temporär 08.02. des Jahres
val Number soy2feb8diff = 253.34 // kWh vom 1.1.24 bis 8.2.24
val Number eOut = (Energyout.deltaSince(start_of_year) as Number) + soy2feb8diff 
EnergyoutYear.postUpdate(0.001 * eOut)
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.2.2, LXC), mit openHABian eingerichtet

Optimus#1978#
Beiträge: 32
Registriert: 6. Feb 2024 14:29
Answers: 0

Re: Anzeige der Stromzählerwert um den Faktor 1.000 zu hoch

Beitrag von Optimus#1978# »

Leider erscheinen für die items „Energiebezug / Jahr“ und „Energieeinspeisung/ Jahr“ immer noch keine Zahlen, sondern jeweils nur die Einträge „Null“.

Zu Beginn meiner „rules“ sind zunächst mittels der Val-Funktion die Startpunkte der verschiedenen Laufzeitbänder definiert (da der Startpunkt „ZoneDateTine start_of_year“ mangels eines gültigen Zahlenwertes für den 01.01. derzeit nicht verwendet werden kann, habe ich die entsprechende Val-Funktion mit einem Doppel-Slash „//“ (vorübergehend) deaktiviert):

Code: Alles auswählen

    val ZonedDateTime zdt = ZonedDateTime.now() // jetzt
    val ZonedDateTime start_of_day = zdt.with(LocalTime.MIDNIGHT) // heute, Mitternacht
    val ZonedDateTime start_of_week = start_of_day.minusDays(start_of_day.getDayOfWeek.getValue - 1) // Erster Tag der Woche = Montag
    val ZonedDateTime start_of_month = start_of_day.withDayOfMonth(1) // Erster Tag des Monats
    //val ZonedDateTime start_of_year = start_of_day.withDayOfYear(1) // Erster Tag des Jahres
Die rules-Einträge für die items „Energiebezug / Jahr“ und „Energieeinspeisung/ Jahr sehen derzeit wie folgt aus:

Code: Alles auswählen

//  Energie pro Jahr (kWh)
	val ZonedDateTime start_of_day = now.with(LocalTime.MIDNIGHT)
	val ZonedDateTime start_of_year = start_of_day.withDayOfYear(39) // temporär 08.02. des Jahres
	val Number soy2feb8diff = 87.0 // kWh vom 1.1.24 bis 8.2.24
	val Number eOut = (Energyout.deltaSince(start_of_year) as Number) + soy2feb8diff 
	EnergyoutYear.postUpdate(0.001 * eOut)

	val ZonedDateTime start_of_day = now.with(LocalTime.MIDNIGHT)
	val ZonedDateTime start_of_year = start_of_day.withDayOfYear(39) // temporär 08.02. des Jahres
	val Number soy2feb8diff = 905.0 // kWh vom 1.1.24 bis 8.2.24
	val Number eIn = (Energyin.deltaSince(start_of_year) as Number) + soy2feb8diff 
	EnergyinYear.postUpdate(0.001 * eIn)

Für die Funktion "Val Number soyfeb8diff" habe jeweils die manuell berechneten Veränderungen der Zählerstände für den Zeitraum 01.01. bis 07.02. eingetragen. Was fehlt jetz noch?

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

Re: Anzeige der Stromzählerwert um den Faktor 1.000 zu hoch

Beitrag von udo1toni »

Du darfst eine lokale Variable / Konstante immer nur einmal definieren! Die Rule müsste also eher so aussehen:

Code: Alles auswählen

//  Energie pro Jahr (kWh)
	val ZonedDateTime start_of_day  = now.with(LocalTime.MIDNIGHT)
	val ZonedDateTime start_of_year = start_of_day.withDayOfYear(39)                      // temporär 08.02. des Jahres
	val Number soy2feb8diffOut =  87.0                                                    // kWh vom 1.1.24 bis 8.2.24
	val Number soy2feb8diffIn  = 905.0                                                    // kWh vom 1.1.24 bis 8.2.24
	val Number eOut = (Energyout.deltaSince(start_of_year) as Number) + soy2feb8diffOut
	val Number eIn  =  (Energyin.deltaSince(start_of_year) as Number) + soy2feb8diffIn 
	EnergyoutYear.postUpdate(0.001 * eOut)
	EnergyinYear.postUpdate(0.001 * eIn)
Die Werte start_of_day/week/month/year dürfen keinesfalls als globale Werte definiert werden!
Zum ersten bedeutet val, dass es sich um eine Konstante handelt.
Zum zweiten sind globale Definitionen statisch, also selbst wenn Du die Bezeichner mit var als Variablen definierst, wird sich der Wert niemals ändern. start_of_day muss sich aber täglich ändern, und damit verbunden auch die anderen Werte, sobald der Bezugspunkt weit genug gewandert ist (also z.B. für start_of_week, wenn start_of_day nicht mehr auf Sonntag, Mitternacht zeigt, sondern auf Montag, Mitternacht)
Die statischen Werte soy2feb8diffOut/In hingegen könntest Du bequem als globale Konstanten definieren, diese Werte ändern sich ja nicht.
By the way... soy -> startOfYear; 2 -> two -> to; feb -> February; 8 -> der achte; diff -> difference, Du kannst natürlich beliebige Namen für die Konstanten verwenden, mir ist nur auf die Schnelle nix gescheites eingefallen...

Ach so... Falls es mit dem 8. Februar nicht klappen will, kannst Du natürlich auch z.B. den 1. März nutzen (61. Tag im Jahr 2024) oder auch einen beliebigen anderen Tag im Jahr, Du musst lediglich Kenntnis vom genauen Zählerstand zu dem Datum haben (kannst Du aus der Persistence auslesen, Stichwort .historicState()) um die korrekte Differenz zu dem Zählerstand zu bestimmen. der Wert muss über die Persistence auslesbar sein, denn das ist ja der Bezugspunkt, den deltaSince() nutzt.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.2.2, LXC), mit openHABian eingerichtet

Optimus#1978#
Beiträge: 32
Registriert: 6. Feb 2024 14:29
Answers: 0

Re: Anzeige der Stromzählerwert um den Faktor 1.000 zu hoch

Beitrag von Optimus#1978# »

Ich habe den rules-Eintrag, wie oben angegeben, geändert. Leider kein Erfolg.

Dann habe ich das Start-Datum auf den 01.03.2024 verlegt (also auf Tag 61 des Jahres) und Verbrauch bzw. Einspeisung für den Zeitraum 01.01. bis 29.02. manuell ermittelt und eingegeben:

Code: Alles auswählen

//  Energie pro Jahr (kWh)
	val ZonedDateTime start_of_day  = now.with(LocalTime.MIDNIGHT)
	val ZonedDateTime start_of_year = start_of_day.withDayOfYear(61)                      // temporär 01.03. des Jahres
	val Number startOfYear3march1diffOut = 166.0                                          // kWh-Einspeisung vom 01.01.2024 bis 08.02.2024
	val Number startOfYear3march1diffIn  = 1189.0                                         // kWh-Bezug vom 01.01.2024 bis 08.02.2024
	val Number eOut = (Energyout.deltaSince(start_of_year) as Number) + startOfYear3march1diffOut
	val Number eIn  =  (Energyin.deltaSince(start_of_year) as Number) + startOfYear3march1diffIn 
	EnergyoutYear.postUpdate(0.001 * eOut)
	EnergyinYear.postUpdate(0.001 * eIn)
	
Es bleibt bei den Null-Ergebnissen.

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

Re: Anzeige der Stromzählerwert um den Faktor 1.000 zu hoch

Beitrag von udo1toni »

Dann müssen wir jetzt halt loggen, was da passiert.
ergänze die Rule bitte mal:

Code: Alles auswählen

//  Energie pro Jahr (kWh)
	val ZonedDateTime start_of_day  = now.with(LocalTime.MIDNIGHT)
	val ZonedDateTime start_of_year = start_of_day.withDayOfYear(61)                      // temporär 01.03. des Jahres
        logInfo("energy","start_of_year {}", start_of_year)
	val Number startOfYear3march1diffOut = 166.0                                          // kWh-Einspeisung vom 01.01.2024 bis 08.02.2024
	val Number startOfYear3march1diffIn  = 1189.0                                         // kWh-Bezug vom 01.01.2024 bis 08.02.2024
        logInfo("energy","In {} Out {}", startOfYear3march1diffIn, startOfYear3march1diffOut)
        // Achtung: Nachfolgend zwei Variablen... var, nicht val
	var Number eOut = (Energyout.deltaSince(start_of_year) as Number) 
	var Number eIn  =  (Energyin.deltaSince(start_of_year) as Number)
        logInfo("energy","In {} Out {} seit 1.3.", eIn, eOut)
        eOut = eOut + startOfYear3march1diffOut
        eIn  = eIn  + startOfYear3march1diffIn
        logInfo("energy","In {} Out {} seit 1.1.", eIn, eOut)
	EnergyoutYear.postUpdate(0.001 * eOut)
	EnergyinYear.postUpdate(0.001 * eIn)
	
Dies sollte bei jedem Auslösen der Rule zu drei Zeilen im Log führen, die die jeweiligen Werte beinhalten. Ich habe die Rule noch etwas abgeändert, um auch die Werte aus der Persistence zu sehen.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.2.2, LXC), mit openHABian eingerichtet

Optimus#1978#
Beiträge: 32
Registriert: 6. Feb 2024 14:29
Answers: 0

Re: Anzeige der Stromzählerwert um den Faktor 1.000 zu hoch

Beitrag von Optimus#1978# »

Mit folgenden Modifikationen in der rules-Beschreibung ist es endlich gelungen, dass auch die Werte für den Stromverbrauch und die Stromeinspeisung für das laufende Jahres in OpenHAB angezeigt werden:

1. Für den abweichenden Stichtag 01.03. wurde statt des Befehls „val ZonedDateTime start_of_year…“ der Befehl „val ZonedDateTime start_of_data … „ verwendet.

2. Der Befehl “var Number eOut = (Energyout.deltaSince(start_of_year) as Number)” wurde durch “var Number eOut = (Energyout.deltaSince(start_of_data) as Number)” ersetzt.

3. Der Befehl “var Number eIn = (Energyout.deltaSince(start_of_year) as Number)” wurde durch “var Number eIn = (Energyout.deltaSince(start_of_data) as Number)” ersetzt.

Da mein Zweirichtungszähler die Werte in Wh und in nicht kWh anliefert, mussten zusätzlich die manuellen Werte des Zeitraums 01.01. bis 29.02. um den Faktor 1.000 erhöht eingetragen werden, also z.B. nicht 166, sondern 166000.

Zusätzlich wurde jetzt noch eine Abfrage eingebaut, dass die Ermittlung auf der Grundlage des abweichenden Startdatums nur dann vorgenommen wird, wenn für den Zeitpunkt „start_of_year“ nur der Eintrag „Null“ vorhanden ist, ansonsten wird der normale Befehl „Energyin.deltaSince(start_of_year) as Number“ bzw. „Energyin.deltaSince(start_of_year) as Number“ verwendet. Durch diese Erweiterung muss ich Anfang 2025 keine Anpassung der rules mehr vornehmen.

Der Code lautet nun:

Code: Alles auswählen

//  Energie pro Jahr (kWh)
if (Energyin.deltaSince(start_of_year) !== null) {
EnergyinYear.postUpdate(0.001 * Energyin.deltaSince(start_of_year) as Number)
EnergyoutYear.postUpdate(0.001 * Energyout.deltaSince(start_of_year) as Number)
} else {

val ZonedDateTime start_of_data = start_of_day.withDayOfYear(61)                      // temporär 01.03. des Jahres
val Number startOfYear3march1diffOut = 166000.0                                          // kWh-Einspeisung vom 01.01.2024 bis 29.02.2024
val Number startOfYear3march1diffIn  = 1189000.0                                         // kWh-Bezug vom 01.01.2024 bis 29.02.2024
// Achtung: Nachfolgend zwei Variablen... var, nicht val
var Number eOut = (Energyout.deltaSince(start_of_data) as Number)
var Number eIn  =  (Energyin.deltaSince(start_of_data) as Number)
eOut = eOut + startOfYear3march1diffOut
eIn  = eIn  + startOfYear3march1diffIn
EnergyoutYear.postUpdate(0.001 * eOut)
EnergyinYear.postUpdate(0.001 * eIn)
}

Antworten