Seite 4 von 5

Re: Shelly Pro 3 EM "saldierend"

Verfasst: 27. Jul 2023 20:27
von udo1toni
Im Grunde kann jede Persistence sekundengenau persistieren, MapDB kann allerdings nur den aktuellen Wert halten und rrd4j kann nur einen Wert pro Minute speichern, halt den letzten, der rein kommt. Kann auch sein, dass ein Mittelwert aus dem letzten und dem aktuellen Wert gebildet wird, wenn der letzte Wert weniger als eine Minute alt ist, da müsste man mal bei rrd4j schauen, wie das realisiert ist.

Letztlich wird es auf InfluxDB oder MariaDB rauslaufen, wobei InfluxDB wesentlich schneller ist, schließlich ist InfluxDB auf Messreihen spezialisiert.

Re: Shelly Pro 3 EM "saldierend"

Verfasst: 27. Jul 2023 20:56
von PeterA
Ok dann also InfluxDB als Persistenz installieren und das Item damit persistieren ?
Und wie sage ich dann in der Rule das für dieses Item nur diese Persistenz verwendet werden soll?

EDIT:
Und waren sie wieder die Probleme :)
Kann nicht downgeloadet werden weil es den dl Pfad nicht mehr gibt....

Re: Shelly Pro 3 EM "saldierend"

Verfasst: 27. Jul 2023 21:42
von udo1toni
Du bist halt mit OH2.4 auf dem Abstellgleis.

Du kannst die aktuelle Version InfluxDB 2.7 nicht nutzen, weil openHAB2.4 das nicht unterstützt. Allerdings kannst Du die Pakete für 1.8 noch manuell runter laden. Zu finden unter https://portal.influxdata.com/downloads/ (dort musst Du auf der Seite ziemlich weit nach unten Scrollen, bis zu "Are you interested in InfluxDB 1.x Open Source?" - Nein, es gibt keinen Link zu diesem Abschnitt). Du wählst Deine Plattform aus :) und kopierst die angezeigten Befehle in ein Editor Fenster. Von dort aus kopierst Du jeweils einen der beiden Befehle und lässt ihn auf der Zielplattform ausführen. Der Link zur Doku ist auch direkt daneben.

OOOODER: Du stellst endlich Dein System auf openHAB3 (ups, zu spät... openHAB4) um. Kurzfristig mag das Arbeit machen, langfristig wirst Du es nicht bereuen. Echt.
Dieser Schritt sollte eine hohe Priorität genießen (höher als eine Anzeige der unentgeltlich eingespeisten Energiemenge - die ärgert Dich nur).
Ich habe mein Produktivsystem auch über einen langen Zeitraum nicht umgestellt - und ich habe den Schritt nach openHAB4 auch noch vor mir - aber ich bin auf 3.4.4 und hänge also nur drei Tage hinterher, nicht 4 Jahre.

Re: Shelly Pro 3 EM "saldierend"

Verfasst: 27. Jul 2023 22:00
von PeterA
Amen!

... erst mal werde ich mich etwas weiter Südlich dem Thema "Innenkühlung mit San Miguel" widmen.

Danach wirds dann wohl wirklich Zeit.

Gruß

Re: Shelly Pro 3 EM "saldierend"

Verfasst: 28. Jul 2023 07:13
von PeterA
Da die SanMiguels noch nicht kalt genug sind :-) lässt mir das noch keine Ruhe.

Also ich habe das Item "em0_total_act_power" mal mit MabDB persistiert.
Aber die rrdj4 Fehlermeldung kommt immer noch....

Und in der Zwischenzeit habe ich mir mal eine andere Rule zusammen gesucht welche keine Fehler wirft.

Code: Alles auswählen

var Number lastUpdateTime = 0
var Number lastEnergyValue = 0
var Number totalNegativeEnergyKWh = 0

rule "Berechne kWh-Verbrauch bei negativem Watt-Item"
when
    Item em0_total_act_power changed
then
    val Number currentTime = now.millis
    val Number currentEnergyValue = em0_total_act_power.state as Number

    if (currentEnergyValue >= 0) {
        // Falls der aktuelle Energie_shelly_phasen_sumverbrauch positiv oder 0 ist, beende die Regel
        return;
    }

    if (lastUpdateTime == 0) {
        // Setze die letzte Aktualisierungszeit und den Wert
        lastUpdateTime = currentTime
        lastEnergyValue = currentEnergyValue
    } else {
        // Berechne die Zeitdifferenz in Sekunden
        val Number timeDiffSeconds = (currentTime - lastUpdateTime) / 1000

        // Berechne die Energie_shelly_phasen_sumverbrauchsdifferenz in Watt-Sekunden (Joule)
        val Number energyDiffJoules = (currentEnergyValue - lastEnergyValue) * timeDiffSeconds

        // Konvertiere die Energie_shelly_phasen_sumverbrauchsdifferenz von Joule in Kilowattstunden (kWh)
        val Number energyDiffKWh = energyDiffJoules / (1000 * 3600)

        // Addiere den negativen Energie_shelly_phasen_sum verbrauch zum Gesamtwert
        totalNegativeEnergyKWh = totalNegativeEnergyKWh + energyDiffKWh

        // Aktualisiere das Energie_shelly_phasen_sum-Item mit dem kumulierten Wert
        Energie_shelly_phasen_sum.postUpdate(totalNegativeEnergyKWh)

        // Setze die letzte Aktualisierungszeit und den Wert für die nächste Iteration
        lastUpdateTime = currentTime
        lastEnergyValue = currentEnergyValue
    }
end

Re: Shelly Pro 3 EM "saldierend"

Verfasst: 28. Jul 2023 15:43
von PeterA
Hab in der Zwischenzeit viel gesucht und vermutlich kann rrd4j "previousState" nicht.
Aber " historicState()" könnte funktionieren.

https://community.openhab.org/t/rrd4j-p ... r/140997/6

Oder mit "previousState.toString"

https://community.openhab.org/t/datetim ... /140722/16

Werde ich dann mal Testen.

Re: Shelly Pro 3 EM "saldierend"

Verfasst: 28. Jul 2023 18:21
von udo1toni
Doch, rrd4j kann sehr wohl mit .previousState umgehen, definitiv. Und das hat auch schon mit openHAB1 funktioniert, hab ich selbst genutzt.

MapDB nutzt Dir aber nichts (hab ich auch so geschrieben...), weil MapDB nur den aktuellen Wert persistiert, nicht den letzten.
Wenn Du auf einen anderen als den Default Persistence Service zugreifen willst, musst Du diesen in der Konfiguration explizit anführen.

Deine Rule wird nicht korrekt funktionieren, denn die Abbruchbedingung bezieht sich auf die aktuelle Leistung, nicht auf die zuletzt anliegende Leistung. Wenn also der letzte gemessene Wert meinetwegen -1000 ist :) und der nächste gemessene Wert eine Minute später 1 ist, dann wird die Minute mit 60.000 Ws nicht gezählt.

Ich muss vielleicht auch noch mal darauf hinweisen, dass es einen fundamentalen Unterschied zwischen .previousState und previousState gibt.
Ersteres ist Teil der Persistence und steht nur zur Verfügung, wenn das Item mit einer passenden Persistence versehen ist.
Letzteres ist eine implizite Variable, die in jeder Rule zur Verfügung steht, die mit changed getriggert wurde.
Ersteres enthält ein HistoricItem, man muss also noch entscheiden, ob man .state oder .getTimestamp geliefert bekommen möchte (den Zeitpunkt zu dem der Wert gespeichert wurde) Außerdem muss man entscheiden, ob man die letzte Aktualisierung oder die letzte Wertänderung sehen möchte.
Letzteres stellt immer den letzten vom aktuellen Wert verschiedenen Status dar (eben weil die Rule ja auf changed getriggert hat)

Die Abstände zwischen zwei Messwerten kannst Du aber durchaus bestimmen, indem Du Dir Zeitstempel merkst und die Differenz bildest.
Ob Du einen Wert in einer Number Variablen speicherst und dort addierst oder das über ein Item erledigst, ist egal.
In beiden Fällen wirst Du durch die Verwendung von kWh statt Ws Genauigkeit einbüßen.
Mindestens müsstest Du also totalNegativeEnergyKWh als Double definieren (das gilt aber auch für energyDiffKWh)

Hier:

Code: Alles auswählen

(currentEnergyValue - lastEnergyValue)
hast Du Dich vertan, denn currentEnergyValue und lastEnergyValue enthalten keine Energiemenge, sondern die aktuelle und die zuletzt gemessene Leistung. Du darfst da keine Differenz bilden. Aber den Wert musst Du auch nicht über eine globale Variable bestimmen, wie oben erklärt kannst Du dafür die implizite Variable previousState verwenden, die funktioniert selbst wenn gar keine Persistence im System installiert ist.

Re: Shelly Pro 3 EM "saldierend"

Verfasst: 28. Jul 2023 21:15
von PeterA
Diese Zeile:

Code: Alles auswählen

val nSec  = ((now().toInstant.toEpochMilli - dtTS.toInstant.toEpochMilli) / 1000).floatValue
wirft diesen Fehler hier:

Code: Alles auswählen

'toEpochMilli' is not a member of 'org.joda.time.Instant'; line 151, column 19, length 28
Das hängt doch damit zusammen das joda.time (ich muss da immer an den Meister Joda denken :) in OH3 verwendet wird.
In OH 2.X ist das ja noch java ?

Re: Shelly Pro 3 EM "saldierend"

Verfasst: 28. Jul 2023 22:28
von udo1toni
Ach, so ein Käse...Ja, natürlich.

Ausgehend von Deiner Rule hier mal ein Gegenvorschlag:

Code: Alles auswählen

var Long   lUpdateTime            = null
var Number nTotalWattseconds = 0

rule "Berechne kWh-Verbrauch bei negativem Watt-Item"
when
    Item em0_total_act_power changed
then
    var nLastPower = 0
    if(previousState instanceof Number)
        nLastPower = (previousState as Number).floatValue

    if(lUpdateTime !== null && nLastPower < 0) {                         // Zeitstempel gültig und Leistung negativ?
        val nDiffSec = (now.millis - lUpdateTime) / 1000                 // Berechne die Zeitdifferenz in Sekunden
        val nDiffJoule = nLastPower * nDiffSec                           // Berechne die Energie in Watt-Sekunden (Joule)
        nTotalWattseconds = nTotalWattseconds - nDiffJoule               // Addiere den negativen Energiewert zum Gesamtwert

        Energie_shelly_phasen_sum.postUpdate(nTotalWattseconds/3600000)  // Aktualisiere das Energie_shelly_phasen_sum-Item mit dem kumulierten Wert (in kWh)
    }
    lUpdateTime  = now.millis                                            // Setze die letzte Aktualisierungszeit
end

Re: Shelly Pro 3 EM "saldierend"

Verfasst: 28. Jul 2023 22:43
von PeterA
Ok

hab die Rule mal so aktiviert allerdings, da ja jetzt nix mehr vom Balkon kommt, auf Positiven Wert prüfe

Code: Alles auswählen

var Long   lUpdateTime       = null
var Number nTotalWattseconds = 0

rule "Berechne kWh-Verbrauch bei negativem Watt-Item"
when
    Item em0_total_act_power changed
then
    var nLastPower = 0
    if(previousState instanceof Number)
        nLastPower = (previousState as Number).floatValue

    if(lUpdateTime !== null && nLastPower > 0) {                         // Zeitstempel gültig und Leistung negativ?
        val nDiffSec = (now.millis - lUpdateTime) / 1000                 // Berechne die Zeitdifferenz in Sekunden
        val nDiffJoule = nLastPower * nDiffSec                           // Berechne die Energie in Watt-Sekunden (Joule)
        nTotalWattseconds = nTotalWattseconds - nDiffJoule               // Addiere den negativen Energiewert zum Gesamtwert

        Energie_shelly_phasen_sum.postUpdate(nTotalWattseconds/3600000)  // Aktualisiere das Energie_shelly_phasen_sum-Item mit dem kumulierten Wert (in kWh)
    }
    lUpdateTime  = now.millis                                            // Setze die letzte Aktualisierungszeit
end
Und da kommt nun diese Meldung im Log:

Code: Alles auswählen

Rule 'Berechne kWh-Verbrauch bei negativem Watt-Item': An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.IntegerExtensions.operator_greaterThan(int,int) on instance: null