REGENMENGE - Zeit in Sekunden - InfluxDB

Für welche Projekte verwendet Ihr OpenHAB? Was habt Ihr automatisiert? Stellt eure Projekte hier vor.

Moderatoren: Cyrelian, seppy

Antworten
merlindata
Beiträge: 33
Registriert: 24. Jan 2020 08:15
Answers: 1
Wohnort: Wien

REGENMENGE - Zeit in Sekunden - InfluxDB

Beitrag von merlindata »

Hallo Leute,

seit 3 Stunden versuche ich mich an einer (dachte ich zumindest) einfachen Rule...

Ich habe mir einen Regensensor (3D Druck & ESP) mit Wippe gebaut, der bei jeden Wechsel einen Zähler hochzählt und mittels InfluxDB persistiert wird.

Nun brauch ich aber noch die Zeit in Sekunden (zwischen zwei Wechsel) um mir die Wassermenge auszurechnen und da stehe ich gerade richtig auf dem Schlauch :(

Hier mal die Rule (OH 3.4.4), für Hilfe wäre ich sehr dankbar.

Code: Alles auswählen

rule "REGENSENSOR-- Regenmengensensor"
when 
    Item MQTT_RegenSWITCH changed 
then
    if (MQTT_RegenSWITCH.state == ON) {
       if (MQTT_RegenCount.state === NULL) { MQTT_RegenCount.postUpdate(1)}    // zum Initialisieren
           
		MQTT_RegenCount.postUpdate((MQTT_RegenCount.state as Number) +1)       // Zähler für L

		var Number REGEN_WIPPE = 6                               // Inhalt der Wippe in ml
		var Number REGEN_FLAECHE = 0.0063617                     // Fläche des Sensors umgerechnet in m² 
		var Number REGEN_X = ((REGEN_WIPPE/1000)/REGEN_FLAECHE)  // = L/m²
		
		var REGEN_LASTUPDATE = MQTT_RegenCount.lastUpdate("influxdb") // Lt. Doku -> Returns the last timestamp a given Item was persisted
		var REGEN_TIME = (REGEN_LASTUPDATE - ZonedDateTime.now())
		
		logInfo("INFO","REGEN_X " + REGEN_X ) 
		logInfo("INFO","REGEN_LASTUPDATE " + REGEN_LASTUPDATE ) 
		logInfo("INFO","REGEN_TIME " + REGEN_TIME ) 
    }
end
LG Merlin
von merlindata » 6. Dez 2023 18:39
Lieber udo1toni

Vielen Dank für deine Hilfe.

Der Fehler meiner Rule lag aber dann doch hier:

Code: Alles auswählen

var REGEN_TIME = (REGEN_LASTUPDATE - ZonedDateTime.now())
und so hat es schlussendlich funktioniert:

Code: Alles auswählen

var REGEN_LASTUPDATE = MQTT_RegenCount.lastUpdate("influxdb")                         // Zeitstempel aus DB
var REGEN_TIME = Duration.between (REGEN_LASTUPDATE, ZonedDateTime.now()).toSeconds() // Differenz in Sekunden
Das mit den lokalen Variablen war mir nicht so bewußt, erklärt aber einiges was ich jetzt noch in anderen Rules ändern werde! :D

Nochmals VIELEN DANK!

LG Merlin
Gehe zur vollständigen Antwort

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

Re: REGENMENGE - Zeit in Sekunden - InfluxDB

Beitrag von udo1toni »

Vermutlich liefert lastUpdate DateTimeType zurück, nicht ZonedDateTime.
Mein Gegnvorschlag für die Rule:

Code: Alles auswählen

rule "Regenmengensensor auswerten"
when 
    Item MQTT_RegenSWITCH changed 
then
    if(newState != ON)
        return;

    var counter = 1
    if((MQTT_RegenCount.state instanceof Number))
        counter = (MQTT_RegenCount.state as Number) + 1            // Zähler für L
    MQTT_RegenCount.postUpdate(counter)

    val Number REGEN_WIPPE = 0.006                                // Inhalt der Wippe in l
    val Number REGEN_FLAECHE = 0.0063617                          // Fläche des Sensors umgerechnet in m²
    val Number REGEN_X = (REGEN_WIPPE/REGEN_FLAECHE)              // = L/m²

    var REGEN_LASTUPDATE = (MQTT_RegenCount.lastUpdate("influxdb") as DateTimeType).getZonedDateTime() // Lt. Doku -> Returns the last timestamp a given Item was persisted
    var REGEN_TIME = (REGEN_LASTUPDATE - ZonedDateTime.now())

    logInfo("rainsensor","REGEN_X {}", REGEN_X ) 
    logInfo("rainsensor","REGEN_LASTUPDATE {}", REGEN_LASTUPDATE ) 
    logInfo("rainsensor","REGEN_TIME {}", REGEN_TIME ) 
end
Erst mal der frühe Return falls der Switch nicht ON ist. Einfacher wäre natürlich, als Trigger

Code: Alles auswählen

    Item MQTT_RegenSWITCH changed from OFF to ON
zu setzen ;)
Bitte NIEMALS ein Item als Variable innerhalb einer Rule missbrauchen. openHAB arbeitet asynchron, das heißt, postUpdate wird als Befehl ausgeführt und die Rule wird unmittelbar weiterverarbeitet, es wird nicht abgewartet, bis der Befehl ausgeführt wurde. Im Zweifel versucht die Rule, den Itemwert zu erhöhen bevor die Variable einen gültigen Inhalt hat. Stattdessen bitte immer eine lokale Variable nutzen, das ist die saubere Variante, die auch sicherstellt, dass der Wert nicht während eines Rule Durchlaufs verändert wird.
Die Variablennamen sind übrigens nicht Stylekonform, in openHAB wird allgemein mit CamelCase gearbeitet. Bei lokalen Variablen möchte ich dazu raten, lieber kurze Variablennamen zu verwenden, der Kontext ist ja durch die Rule selbst gegeben.

Wie erwähnt gehe ich davon aus, dass DateTimeType zurückgeliefert wird, was nicht direkt mit JavaTime verrechnet werden kann. Stattdessen müssen wird den Datentyp erst konvertieren wie gezeigt.

logInfo() erwartet zwei Strings als Parameter, wobei der erste String der Loggername ist (bzw. der letzte Teil des Loggernamens). INFO ist denkbar schlecht geeignet, zumal logInfo dies ohnehin IMMER in die Logzeile schreibt - es handelt sich also um eine nutzlose Information. Die Logbefehle können über den Loggernamen on-the-fly ein- und ausgeschaltet werden, es lohnt sich also, pro Rule (oder pro Funktion) einen kurzen Loggernamen zu kreieren.
Die Loggernamen sind hierarchisch organisiert, alle log-Befehle aus Rules heraus loggen unter dem Namen org.openhab.core.model.script.*, wobei das * der Teil im ersten String ist. Man kann hier auch selbst mit . weitere Ebenen einfügen, wenn man möchte. tiefere Hierarchien erben die übergeordnete Einstellung des Log Levels.
Außerdem beherrschen die log-Befehle die Substitution incl. Typumwandlung, diese ist grundsätzlich dem Verketten von Strings vorzuziehen.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

merlindata
Beiträge: 33
Registriert: 24. Jan 2020 08:15
Answers: 1
Wohnort: Wien

[GELÖST] REGENMENGE - Zeit in Sekunden - InfluxDB

Beitrag von merlindata »

Lieber udo1toni

Vielen Dank für deine Hilfe.

Der Fehler meiner Rule lag aber dann doch hier:

Code: Alles auswählen

var REGEN_TIME = (REGEN_LASTUPDATE - ZonedDateTime.now())
und so hat es schlussendlich funktioniert:

Code: Alles auswählen

var REGEN_LASTUPDATE = MQTT_RegenCount.lastUpdate("influxdb")                         // Zeitstempel aus DB
var REGEN_TIME = Duration.between (REGEN_LASTUPDATE, ZonedDateTime.now()).toSeconds() // Differenz in Sekunden
Das mit den lokalen Variablen war mir nicht so bewußt, erklärt aber einiges was ich jetzt noch in anderen Rules ändern werde! :D

Nochmals VIELEN DANK!

LG Merlin

Antworten