FHEM > Anfängerfragen

[Gelöst] Mittelwert mehrerer Devicereadings erzeugen und weiterreichen

(1/3) > >>

Mad-at:
Hallo!

Habe gerade ein Brett vorm Kopf, vielleicht kann ja jemand helfen.
Ich möchte den Mittelwert des Temperaturreadings mehrer Temperaturdevices bilden um diesen dann über MQTT2 an meine Heizung zu senden.

Mit dem Temperaturreading eines Devices funktioniert das Ganze. Aber dann war ich "superschlau" und habe versucht den Mittelwert mit einem kanibalisierten DOIF zu errechnen. Das an sich funktioniert ebenfalls, ist aber nicht mittels RegExp fürs notify auslesbar.
Nächster Versuch: ein Dummydevice das alle Readings mittels Notify gefüttert bekommt und dann als UserReadings Wert den Mittelwert errechnet. Ein bisschen durch die Brust ins Auge, könnte aber funktionieren. Denkste. Nächstes Problem: die Readings meiner KNX Devices lassen sich entweder nicht mit notify auslesen oder nicht mit set oder setreading schreiben.


--- Code: ---Internals:
   DEF        Temperatur_EG_Esszimmer:state:.* setreading Mitteltemperatur EGDecketemperatur $EVTPART1
   FUUID      61a39f44-f33f-db1a-e3a7-5c3673b978d4e200
   NAME       Temperatur_EG_EsszimmerDecke_toMitteltemperatur
   NOTIFYDEV  Temperatur_EG_Esszimmer
   NR         100
   NTFY_ORDER 50-Temperatur_EG_EsszimmerDecke_toMitteltemperatur
   REGEXP     Temperatur_EG_Esszimmer:state:.*
   STATE      2021-11-28 17:02:27
   TRIGGERTIME 1638115347.07679
   TYPE       notify
   Helper:
     DBLOG:
       state:
         DBLogging:
           TIME       1638115617.02407
           VALUE      active
   READINGS:
     2021-11-28 17:06:57   state           active
Attributes:

--- Ende Code ---

Edit: Ich sollte vielleicht erwähnen, dass es mit LaCrosse Devices sehr gut klappt. Nur spezielle bei den KNX Devices geht es nicht


--- Code: ---Internals:
   DEF        Esszimmer:temperature:.* setreading Mitteltemperatur Esszimmertemperatur $EVTPART1
   FUUID      61a39d91-f33f-db1a-88e1-ebb9285c6a41936f
   NAME       LaCrosseEsszimmer_toMitteltemperatur
   NOTIFYDEV  Esszimmer
   NR         96
   NTFY_ORDER 50-LaCrosseEsszimmer_toMitteltemperatur
   REGEXP     Esszimmer:temperature:.*
   STATE      2021-11-28 18:00:47
   TRIGGERTIME 1638118847.61745
   TYPE       notify
   READINGS:
     2021-11-28 16:24:52   state           active
Attributes:

--- Ende Code ---


Ein mit dem Eventmonitor angelegtes Notify setzt gleich ganz den aktuellen Reading Wert

--- Code: ---defmod Temperatur_EG_Esszimmer_notify_1 notify Temperatur_EG_Esszimmer:21.06 {}

--- Ende Code ---
Führt mich auch nicht weiter.

Also alles ein wenig wirr. Ich wäre dankbar wenn mich jemand an die Hand nehmen könnte und mich in die richtige Richtung drehen würde. Ich glaub ich seh vor lauter Bäumen keinen Wald...

Mad-at:
OK, einen großen Schritt weiter - vielleicht hilft es jemand anderem
Um Werte aus KNX mit Notify an ein Dummy Device weiterzugeben braucht es folgendes Notify:


--- Code: ---defmod Temperatur_EG_EsszimmerDecke_toMitteltemperatur notify Temperatur_EG_Esszimmer:getG1:.* setreading Mitteltemperatur EGDecketemperatur $EVTPART1

--- Ende Code ---

Mad-at:
So, nun geht's auch mit Mittelwert im Dummy Berechnen:


--- Code: ---Internals:
   DEF       
   FUUID      61a39d91-f33f-db1a-dbab-db8aa41977e5c757
   NAME       Mitteltemperatur
   NR         93
   STATE      21.0 °C
   TYPE       dummy
   Helper:
     DBLOG:
       EGDecketemperatur:
         DBLogging:
           TIME       1638125849.44105
           VALUE      21.08
       EGGlastastertemperatur:
         DBLogging:
           TIME       1638126048.43081
           VALUE      20.70
       Esszimmertemperatur:
         DBLogging:
           TIME       1638126081.73458
           VALUE      21.1
       Mitteltemperatur:
         DBLogging:
           TIME       1638126081.73458
           VALUE      20.96
       state:
         DBLogging:
           TIME       1638114761.22285
           VALUE      EGDecketemperatur
   OLDREADINGS:
   READINGS:
     2021-11-28 19:57:29   EGDecketemperatur 21.08
     2021-11-28 20:00:48   EGGlastastertemperatur 20.70
     2021-11-28 20:01:21   Esszimmertemperatur 21.1
     2021-11-28 20:01:21   Mitteltemperatur 20.96
Attributes:
   reading01Name Zeit
   reading01Regex localtime("time":"([\d]+))
   reading02Name Esszimmertemperatur
   reading02Regex value":([\d\.-]+)
   reading03Name EGGlastastertemperatur
   reading03Regex value":([\d\.-]+)
   reading04Name EGDecketemperatur
   reading05Name Mitteltemperatur
   reading05Regex value":([\d\.-]+)
   stateFormat {sprintf("%.1f °C", ReadingsVal("$name","Mitteltemperatur",0))}
   userReadings Mitteltemperatur { (ReadingsVal("Mitteltemperatur","Esszimmertemperatur", 0) + ReadingsVal("Mitteltemperatur","EGGlastastertemperatur", 0) + ReadingsVal("Mitteltemperatur","EGDecketemperatur", 0) )/3 }
   userattr   reading01Name reading01Regex reading02Name reading02Regex reading03Name reading03Regex reading04Name reading04Regex reading05Name reading05Regex

--- Ende Code ---

Device schaut so aus:

--- Code: ---defmod Mitteltemperatur dummy
attr Mitteltemperatur userattr reading01Name reading01Regex reading02Name reading02Regex reading03Name reading03Regex reading04Name reading04Regex reading05Name reading05Regex
attr Mitteltemperatur reading01Name Zeit
attr Mitteltemperatur reading01Regex localtime("time":"([\d]+))
attr Mitteltemperatur reading02Name Esszimmertemperatur
attr Mitteltemperatur reading02Regex value":([\d\.-]+)
attr Mitteltemperatur reading03Name EGGlastastertemperatur
attr Mitteltemperatur reading03Regex value":([\d\.-]+)
attr Mitteltemperatur reading04Name EGDecketemperatur
attr Mitteltemperatur reading05Name Mitteltemperatur
attr Mitteltemperatur reading05Regex value":([\d\.-]+)
attr Mitteltemperatur stateFormat {sprintf("%.1f °C", ReadingsVal("$name","Mitteltemperatur",0))}
attr Mitteltemperatur userReadings Mitteltemperatur { (ReadingsVal("Mitteltemperatur","Esszimmertemperatur", 0) + ReadingsVal("Mitteltemperatur","EGGlastastertemperatur", 0) + ReadingsVal("Mitteltemperatur","EGDecketemperatur", 0) )/3 }

--- Ende Code ---

Das erzeugt, anders als das DOIF auch jedesmal ein Regexp auslesbares event dass dann mittels Notify weiterverarbeitet werden kann.
Weiterleitung mit


--- Code: ---defmod LaCrosseToMQTT_Innentemp notify Mitteltemperatur:Mitteltemperatur:.* set Innentemp_MQTT temperature $EVTPART1

--- Ende Code ---
Nicht etwa setreading, sonst funktioniert es dann mit dem MQTT Publishing nicht.

Vielleicht hilfts ja wem...

Gisbert:
Hallo Mad-at,

schön, dass du eine Lösung gefunden hast, die funktioniert. Sie scheint mir nur reichlich kompliziert.

Ich hab mal versucht Mittelwerte (geht aber auch gut für die Suche nach Minimal- oder Maximalwerten) von verschiedenen Readings zu erhalten. Dazu habe ich eine Funktion in 99_myUtils.pm reingesetzt:

--- Code: ---sub av_cloudCover() {
    my $avcloudCover="";
    my $avdev="";
    my $anzahl=1;
    foreach my $device (qw(Leverkusen.DarkSky Leverkusen.OpenWeatherMap)) {
        my $cloudCover = ReadingsNum($device, "cloudCover", 0);
        my $age = ReadingsAge($device, "cloudCover", 0);
        if($age <= 1800) {
            $avcloudCover=($avcloudCover*($anzahl-1)+$cloudCover)/$anzahl;
            $avdev=$device;
            $anzahl=$anzahl+1;
            }
        }
    return $avcloudCover;
}
--- Ende Code ---

Mit dieser Funktion kann in einem beliebigen Device ein userReadings erstellt werden:

--- Code: ---attr <device> userReadings Mittelwert {av_cloudCover()}
--- Ende Code ---

Den Code müsstest du natürlich anpassen, ich glaube das Prinzip sollte klar sein. Damit keine Uraltwerte in den Mittelwert eingehen, habe ich das ReadingsAge abgefragt, musst du natürlich auch nach deinen Bedürfnissen anpassen.

Viele​ Grüße​ Gisbert​

Damian:
Das sieht mir alles unnötig umständlich aus.

Mit dem Zweizeiler


--- Code: ---defmod durchschnitt DOIF ##
attr durchschnitt state [#average:"^(Esszimmer|Zimmer2|Zimmer3)":"^temperature"]
--- Ende Code ---

bekommst du im Status des Devices die Durchschnittstemperatur von allen angegebenen Zimmern, sobald der erste Sensor seine Temperatur sendet.

Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln