[gelöst] DOIF und userreadings mit setreading setzen?

Begonnen von gestein, 02 August 2020, 00:06:44

Vorheriges Thema - Nächstes Thema

gestein

Hallo,

ich scheitere leider gerade an der Definition eines DOIFs, das sich die Temperaturwerte zu jeder vollen Stunde in einem userreading merken soll.
Dazu habe ich folgendes definiert:
defmod di_AverageTemperatur DOIF {([+:00]);; my $myHour = ($hour<10)? "0".$hour:$hour;;\
my $cmd="setreading di_AverageTemperatur hourly_Temperatur_".$myHour." ".ReadingsVal("OZW772","Aussentemperatur","-99");;\
Log 1, "di_AverageTemperatur: $cmd";;\
fhem($cmd);;\
}\

attr di_AverageTemperatur room 0_Testing
attr di_AverageTemperatur userReadings hourly_Temperatur_00 hourly_Temperatur_01 hourly_Temperatur_02 hourly_Temperatur_03 hourly_Temperatur_04 hourly_Temperatur_05 hourly_Temperatur_06 hourly_Temperatur_07 hourly_Temperatur_08 hourly_Temperatur_09 hourly_Temperatur_10 hourly_Temperatur_11 hourly_Temperatur_12 hourly_Temperatur_13 hourly_Temperatur_14 hourly_Temperatur_15 hourly_Temperatur_16 hourly_Temperatur_17 hourly_Temperatur_18 hourly_Temperatur_19 hourly_Temperatur_20 hourly_Temperatur_21 hourly_Temperatur_22 hourly_Temperatur_23
attr di_AverageTemperatur verbose 5

Ich habe sogar die 24 userreadings definiert, wobei das anscheinend gar nicht notwendig wäre.

Mein Problem ist nun, dass die userreadings durch den "fhem"-Aufruf nicht gesetzt werden.
Es kommt keine Fehlermeldung, nichts.
Im Log sehe ich, dass das "setreading" richtig ist. Dort steht z.B.:
2020.08.02 00:00:01.078 1: di_AverageTemperatur: setreading di_AverageTemperatur hourly_Temperatur_00 24.5

Wenn ich den Befehl aus dem Log in die Befehlszeile von fhem kopiere und dann ausführe, wird das entsprechende Reading richtig gesetzt.

Hätte da vielleicht jemand einen Tipp für mich. Was mache ich falsch?
Danke im Voraus
lg, Gerhard

Otto123

Hallo Gerhard,

such mal so in der Google Suche: site:forum.fhem.de setreading deep recursion

Da findest Du eine paar Threads zu dem Thema.

Also: setreading eines Readings im Code von dem Device welches aufgerufen wird, wird mW verhindert.

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

amenomade

#2
Die gesettet Readings triggern aber nichts im DOIF. Ich sehe keinen Grund für eine deep recursion. (EDIT: das setreading ist nicht in der Definition des userReadings, sondern in einem Ausführungsteil des DOIFs)

Bei mir geht diese Definition des DOIFs ohne Probleme.
Vielleicht mit einem "list" des DOIFs würde man weiteres sehen.
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

MadMax-FHEM

Allerdings sind die userReadings ja kompletter Unfug...

@gestein: userReadings sind NICHT eine Aufzählung von ReadingNamen die man gerne hätte weil man sie z.B. per setreading setzen möchte! Man kann Readings per setreading einfach so setzen (abgesehen von "deep recursion")... userReadings ist ganz anders gedacht: es gibt Events vom Device wo das userReadings definiert ist/sind. Dann wird nach passender RegEx "geschaut" und wenn eine passende userReadings-Definition "trifft" wird der userReadings-Teil "berechnet" und das dazu gehörige Reading angelegt usw. https://wiki.fhem.de/wiki/UserReadings

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

amenomade

Zitat von: MadMax-FHEM am 02 August 2020, 00:51:13
Allerdings sind die userReadings ja kompletter Unfug...

Klar, dieses Attribut sollte entfernt werden. Das ist aber mMn nicht die Ursache des Problems
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

MadMax-FHEM

Zitat von: amenomade am 02 August 2020, 00:55:39
Klar, dieses Attribut sollte entfernt werden. Das ist aber mMn nicht die Ursache des Problems

Jep, war auch nicht so gemeint...
...nur als Hinweis (generell und für die Zukunft)... ;)

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

gestein

Guten Morgen,

Die userreadings habe ich gleich mal gelöscht. Deren genaue Anwendung muss ich mir wohl doch nochmal genauer anschauen.
Hier ein List des DIOFs:
Internals:
   DEF        {([+:00]); my $myHour = ($hour<10)? "0".$hour:$hour;
my $cmd="setreading di_AverageTemperatur hourly_Temperatur_".$myHour." ".ReadingsVal("OZW772","Aussentemperatur","-99");
Log 1, "di_AverageTemperatur: $cmd";
fhem($cmd);
}

   FUUID      5f25c761-f33f-0b7a-ae10-c259acf7291d40cf
   FVERSION   98_DOIF.pm:0.224280/2020-07-18
   MODEL      Perl
   NAME       di_AverageTemperatur
   NOTIFYDEV  global
   NR         1810
   NTFY_ORDER 50-di_AverageTemperatur
   STATE      cmd_1
   TYPE       DOIF
   VERSION    22428 2020-07-18 20:32:08
   READINGS:
     2020-08-02 00:00:51   block_01        executed
     2020-08-01 23:36:50   hourly_Temperatur_22 25.2
     2020-08-01 23:37:19   hourly_Temperatur_23 25.1
     2020-08-02 00:00:43   mode            enabled
     2020-08-01 22:14:06   state           cmd_1
     2020-08-02 00:00:43   timer_01_c01    03.08.2020 00:00:00
   Regex:
     accu:
   condition:
     0          (::DOIF_time_once($hash,0,$wday)); my $myHour = ($hour<10)? "0".$hour:$hour;
my $cmd="setreading di_AverageTemperatur hourly_Temperatur_".$myHour." ".ReadingsVal("OZW772","Aussentemperatur","-99");
Log 1, "di_AverageTemperatur: $cmd";
fhem($cmd);

   days:
   helper:
     DEVFILTER  ^global$
     NOTIFYDEV  global
     globalinit 1
     last_timer 1
     sleeptimer -1
     bm:
       DOIF_Attr:
         cnt        1
         dmx        -1000
         dtot       0
         dtotcnt    0
         mTS        02.08. 07:40:31
         max        0.0460619926452637
         tot        0.0460619926452637
         mAr:
           del
           di_AverageTemperatur
           userReadings
       DOIF_Get:
         cnt        5
         dmx        -1000
         dtot       0
         dtotcnt    0
         mTS        02.08. 00:00:56
         max        2.50339508056641e-05
         tot        7.36713409423828e-05
         mAr:
           HASH(0x8e836c8)
           di_AverageTemperatur
           ?
       DOIF_Notify:
         cnt        19
         dmx        -1000
         dtot       0
         dtotcnt    0
         mTS        02.08. 07:32:37
         max        0.000100135803222656
         tot        0.00166440010070801
         mAr:
           HASH(0x8e836c8)
           HASH(0x118c628)
       DOIF_Set:
         cnt        15
         dmx        -1000
         dtot       0
         dtotcnt    0
         mTS        02.08. 00:00:51
         max        0.00336122512817383
         tot        0.00491857528686523
         mAr:
           HASH(0x8e836c8)
           di_AverageTemperatur
           block_01
   intervalfunc:
   localtime:
     0          1596405600
   perlblock:
     0          block_01
   realtime:
     0          00:00:00
   time:
     0          +:00
   timeCond:
     0          0
   timer:
     0          0
   timers:
     0           0
   triggertime:
     1596405600:
       localtime  1596405600
       hash:
   uiTable:
Attributes:
   room       0_Testing
   verbose    5


Heute morgen habe ich gesehen, dass die Funktion kein einziges Mal zur vollen Stunde aufgerufen wurde.
Wahrscheinlich weil ich kein "do always" definiert hatte.
Allerdings kommt in der Attribut-Liste kein "do" vor und wenn ich es direkt in die Befehlszeile eingebe, kommt eine Fehlermeldung:
attr di_AverageTemperatur do always
di_AverageTemperatur: unknown attribute do. Type 'attr di_AverageTemperatur ?' for a detailed list.


Also habe ich das Device wieder gelöscht und neu angelegt - selber Effekt.
Auch meine Definition vom ersten Beitrag habe ich versucht und dabei gleich das "attr di_AverageTemperatur do always" mit benutzt - wieder der Fehler.
Nach einigem Herumprobieren mit der Definition habe ich dann ein "defmod di_AverageTemperatur DOIF (1) (1)" benutzt.
Da ging das Setzen des Attributs "do" auf einmal.
Danach habe ich in die "Def" des Devices einfach meinen Code kopiert und nun klappt es.

Auch alle DOIF-Attribute sind wieder da.

Danke für Eure Hilfe!
lg, Gerhard

Damian

Zitat von: gestein am 02 August 2020, 08:17:29
Guten Morgen,

Die userreadings habe ich gleich mal gelöscht. Deren genaue Anwendung muss ich mir wohl doch nochmal genauer anschauen.
Hier ein List des DIOFs:
Internals:
   DEF        {([+:00]); my $myHour = ($hour<10)? "0".$hour:$hour;
my $cmd="setreading di_AverageTemperatur hourly_Temperatur_".$myHour." ".ReadingsVal("OZW772","Aussentemperatur","-99");
Log 1, "di_AverageTemperatur: $cmd";
fhem($cmd);
}

   FUUID      5f25c761-f33f-0b7a-ae10-c259acf7291d40cf
   FVERSION   98_DOIF.pm:0.224280/2020-07-18
   MODEL      Perl
   NAME       di_AverageTemperatur
   NOTIFYDEV  global
   NR         1810
   NTFY_ORDER 50-di_AverageTemperatur
   STATE      cmd_1
   TYPE       DOIF
   VERSION    22428 2020-07-18 20:32:08
   READINGS:
     2020-08-02 00:00:51   block_01        executed
     2020-08-01 23:36:50   hourly_Temperatur_22 25.2
     2020-08-01 23:37:19   hourly_Temperatur_23 25.1
     2020-08-02 00:00:43   mode            enabled
     2020-08-01 22:14:06   state           cmd_1
     2020-08-02 00:00:43   timer_01_c01    03.08.2020 00:00:00
   Regex:
     accu:
   condition:
     0          (::DOIF_time_once($hash,0,$wday)); my $myHour = ($hour<10)? "0".$hour:$hour;
my $cmd="setreading di_AverageTemperatur hourly_Temperatur_".$myHour." ".ReadingsVal("OZW772","Aussentemperatur","-99");
Log 1, "di_AverageTemperatur: $cmd";
fhem($cmd);

   days:
   helper:
     DEVFILTER  ^global$
     NOTIFYDEV  global
     globalinit 1
     last_timer 1
     sleeptimer -1
     bm:
       DOIF_Attr:
         cnt        1
         dmx        -1000
         dtot       0
         dtotcnt    0
         mTS        02.08. 07:40:31
         max        0.0460619926452637
         tot        0.0460619926452637
         mAr:
           del
           di_AverageTemperatur
           userReadings
       DOIF_Get:
         cnt        5
         dmx        -1000
         dtot       0
         dtotcnt    0
         mTS        02.08. 00:00:56
         max        2.50339508056641e-05
         tot        7.36713409423828e-05
         mAr:
           HASH(0x8e836c8)
           di_AverageTemperatur
           ?
       DOIF_Notify:
         cnt        19
         dmx        -1000
         dtot       0
         dtotcnt    0
         mTS        02.08. 07:32:37
         max        0.000100135803222656
         tot        0.00166440010070801
         mAr:
           HASH(0x8e836c8)
           HASH(0x118c628)
       DOIF_Set:
         cnt        15
         dmx        -1000
         dtot       0
         dtotcnt    0
         mTS        02.08. 00:00:51
         max        0.00336122512817383
         tot        0.00491857528686523
         mAr:
           HASH(0x8e836c8)
           di_AverageTemperatur
           block_01
   intervalfunc:
   localtime:
     0          1596405600
   perlblock:
     0          block_01
   realtime:
     0          00:00:00
   time:
     0          +:00
   timeCond:
     0          0
   timer:
     0          0
   timers:
     0           0
   triggertime:
     1596405600:
       localtime  1596405600
       hash:
   uiTable:
Attributes:
   room       0_Testing
   verbose    5


Heute morgen habe ich gesehen, dass die Funktion kein einziges Mal zur vollen Stunde aufgerufen wurde.
Wahrscheinlich weil ich kein "do always" definiert hatte.
Allerdings kommt in der Attribut-Liste kein "do" vor und wenn ich es direkt in die Befehlszeile eingebe, kommt eine Fehlermeldung:
attr di_AverageTemperatur do always
di_AverageTemperatur: unknown attribute do. Type 'attr di_AverageTemperatur ?' for a detailed list.


Also habe ich das Device wieder gelöscht und neu angelegt - selber Effekt.
Auch meine Definition vom ersten Beitrag habe ich versucht und dabei gleich das "attr di_AverageTemperatur do always" mit benutzt - wieder der Fehler.
Nach einigem Herumprobieren mit der Definition habe ich dann ein "defmod di_AverageTemperatur DOIF (1) (1)" benutzt.
Da ging das Setzen des Attributs "do" auf einmal.
Danach habe ich in die "Def" des Devices einfach meinen Code kopiert und nun klappt es.

Auch alle DOIF-Attribute sind wieder da.

Danke für Eure Hilfe!
lg, Gerhard

Deine Definition ist im Perl-Modus. In diesem Modus gibt es nur wenige Attribute.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

gestein

Hallo,

Ich verstehe.
Wenn das DOIF im perl-Modus ist und die Attribute nur eingeschränkt zur Verfügung stehen, ist dann z.B. Das ,,do" immer auf ,,always"?

Lg, Gerhard

Damian

Zitat von: gestein am 02 August 2020, 10:09:54
Hallo,

Ich verstehe.
Wenn das DOIF im perl-Modus ist und die Attribute nur eingeschränkt zur Verfügung stehen, ist dann z.B. Das ,,do" immer auf ,,always"?

Lg, Gerhard

ja
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

gestein

Hallo,

der Code läuft nun anscheinend problemlos.
Damit habe ich nun die Temperaturen zu den vollen Stunden und rechne gleichzeitig auch den aktuellen Mittelwert der letzten 3 Stunden.
Daher hier meine Lösung dafür:
defmod di_AverageTemperatur DOIF {([+[1]:00]);;;; my $myHour = ($hour<10)? "0".$hour:$hour;;\
my $actTemp = ReadingsVal("OZW772","Aussentemperatur","-99");;\
my $cmd="setreading di_AverageTemperatur hourly_Temperatur_".$myHour." ".$actTemp;;\
Log 1, "di_AverageTemperatur: $cmd";;\
fhem($cmd);;\
\
my $actTemp1 = ReadingsVal("di_AverageTemperatur","hourly_Temperatur_". (($myHour-1)%24),$actTemp);;\
my $actTemp2 = ReadingsVal("di_AverageTemperatur","hourly_Temperatur_". (($myHour-2)%24),$actTemp1);;\
my $avTemp_3 = ($actTemp+$actTemp1+$actTemp2)/3;;\
\
$cmd="setreading di_AverageTemperatur av_Temperatur_3 ".$avTemp_3;;\
Log 1, "di_AverageTemperatur: $cmd";;\
fhem($cmd);;\
}
attr di_AverageTemperatur do always
attr di_AverageTemperatur group Steuerung
attr di_AverageTemperatur room Bewässerung,Wetter


Danke an alle für die Hilfe!
lg, Gerhard

Damian

Zitat von: gestein am 03 August 2020, 10:03:01
Hallo,

der Code läuft nun anscheinend problemlos.
Damit habe ich nun die Temperaturen zu den vollen Stunden und rechne gleichzeitig auch den aktuellen Mittelwert der letzten 3 Stunden.
Daher hier meine Lösung dafür:
defmod di_AverageTemperatur DOIF {([+[1]:00]);;;; my $myHour = ($hour<10)? "0".$hour:$hour;;\
my $actTemp = ReadingsVal("OZW772","Aussentemperatur","-99");;\
my $cmd="setreading di_AverageTemperatur hourly_Temperatur_".$myHour." ".$actTemp;;\
Log 1, "di_AverageTemperatur: $cmd";;\
fhem($cmd);;\
\
my $actTemp1 = ReadingsVal("di_AverageTemperatur","hourly_Temperatur_". (($myHour-1)%24),$actTemp);;\
my $actTemp2 = ReadingsVal("di_AverageTemperatur","hourly_Temperatur_". (($myHour-2)%24),$actTemp1);;\
my $avTemp_3 = ($actTemp+$actTemp1+$actTemp2)/3;;\
\
$cmd="setreading di_AverageTemperatur av_Temperatur_3 ".$avTemp_3;;\
Log 1, "di_AverageTemperatur: $cmd";;\
fhem($cmd);;\
}
attr di_AverageTemperatur do always
attr di_AverageTemperatur group Steuerung
attr di_AverageTemperatur room Bewässerung,Wetter


Danke an alle für die Hilfe!
lg, Gerhard

Da du es im Perl-Modus definiert hast, kannst du vieles kürzer und damit eleganter machen:

1) attribut do always löschen
2) statt setreading für eigene Readings Perlfunktion set_Reading benutzen:

statt:

fhem("setreading di_AverageTemperatur hourly_Temperatur_".$myHour." ".$actTemp);

ohne Events
set_Reading(hourly_Temperatur_".$myHour,$actTemp);

mit Events
set_Reading(hourly_Temperatur_".$myHour,$actTemp,1);

das überlebt im Gegensatz zu deiner Lösung nicht nur das Umbenennen des Devices, sondern ist auch performanter (insb. ohne Events) und braucht damit weniger Systemlast

3) statt ReadingsVal für eigene Reading Perlfunktion get_Reading benutzen:

statt:

ReadingsVal("di_AverageTemperatur","hourly_Temperatur_". (($myHour-1)%24),$actTemp);


get_Reading("hourly_Temperatur_". (($myHour-1)%24),$actTemp);

siehe: https://fhem.de/commandref_DE.html#DOIF_Spezifische_Perl-Funktionen_im_Perl-Modus
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

gestein

Hallo Damian,

vielen herzlichen Dank für die Hinweise.
Mit DOIF hast Du ein unglaubliches Tool geschaffen.

Die Änderungen baue ich gerne ein und poste dann meinen neuen Code.
lg, Gerhard