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
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
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.
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
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
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
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
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.
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
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
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
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
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