Hallo,
ich würde gerne die 8 Schaltausgänge meiner HM-MOD-RE-8 überwachen, da sie gerne mal auf einem set_on oder set_on-for-timer hängen bleiben.
Natürlich könnte ich jeweils 8 watchdog-Devices definieren, aber vielleicht ginge das auch mit einem DOIF.
Prinzipiell läuft das DOIF.
Aber stimmt der Code so?
Oder laufe ich da in Probleme rein, wenn mehrere Aufrufe gleichzeitig kommen?
defmod diWatchdogVentile DOIF subs {\
sub diWatchdog_Timer () {\
my ($Device,$Event)=split /;;/, "@_";;\
::Log 1, "diWatchdog_Timer: abgelaufen :$Device,$Event:";;\
}\
}\
{["T.\.*Ventil_.*:^set_on-for-timer.*"];;\
# $SELF, $DEVICE, $EVENT, $EVENTS\
set_Reading("$SELF_Event_$DEVICE","$EVENT");;\
my $addSec=::AttrVal("$SELF","SetOnOff_TimeOut","10");;\
::InternalTimer(gettimeofday() + $addSec,"DOIF::diWatchdog_Timer","$DEVICE;;$EVENT");;\
::Log 1, "diWatchdog: set_on-for-timer erkannt, Timer gestartet";;;;\
}\
\
init {\
# deleteReading("")\
::Log 1, "diWatchdog: im init";;;;\
}
Kann sich das bitte mal jemand anschauen und mir Tipps geben?
Oder wie kann man das sicher(er) lösen?
Man könnte mit einem Template auch für jedes zu überwachende Device und jeden Kanal eine Timer-Funktion definieren.
Aber ist das notwendig?
Danke im Voraus
lg, Gerhard
Wenn es funktioniert, dann ist ja alles gut.
Das sollte auch mit einem Einzeiler funktionieren:
defmod diWatchdogVentile DOIF {["T.\.*Ventil_.*:^set_on-for-timer.*"];set_Exec ("$device $event",AttrVal("$SELF","SetOnOff_TimeOut","10"),"Log 1, 'diWatchdog_Timer: abgelaufen :$device, $event:'")}
siehe: https://wiki.fhem.de/wiki/DOIF/Perl-Modus#Timer_setzen:_set_Exec.28.29
Hallo,
Nach urlaubsbedingter Abwesenheit habe ich nun damit wieder herumprobiert und den Befehl set_Exec eingebaut.
Ich habe also ein DOIF mit einem subs im Def-Block und dort die sub ,,diWatchdog_Timer" definiert.
Beim set_Exec wollte ich die Funktion dann als ,,DOIF::diWatchdog_Timer" übergeben.
Es kommt allerdings immer die Warnung:
warning. condition c01: (Do you need to predeclare timer?)
Wie kann ich eine Funktion aus sub an set_Exec übergeben?
Oder geht es nur mit perl-Funktionen aus z.B. 99_myUtils.pm?
Danke, lg, Gerhard
Die Infos sind mir zu ungenau, da musst du ein konkretes List liefern.
Danke für Deine unermüdliche Hilfe.
hier das list:
defmod diWatchdogVentile DOIF subs {\
sub diWatchdog_Timer {\
my ($Device,$Event)=split /;;/, "@_";;\
my $actState=::ReadingsVal($Device,"state","unknown");;\
\
set_Reading("$Device"."_set_oft_abgelaufen","$Event,$actState");;\
if($actState =~ /set_/) {\
set_Reading("$Device"."_set_oft_abgelaufen_neu","$Event,$actState");;\
fhem("set $Device $Event");;\
} else {\
set_Reading("$SELF_Event_"."$Device"."_$actState","$actState");;\
}\
}\
}\
{["^T.\.Ventil_.*:^set_on-for-timer.*"];;\
set_Reading("$DEVICE"."_set_oft","$EVENT");;\
my $addSec=::AttrVal("$SELF","TimeOut_SetOnOff","10");;\
set_Exec("$DEVICE"."_set_oft",$addSec,"DOIF::diWatchdog_Timer","$DEVICE;;$EVENT");;\
}
attr diWatchdogVentile group Hilfsmodule
attr diWatchdogVentile room Bewässerung
Lg, Gerhard
Was mir auffällt sind die Parameter der Funktion.
Wenn du Parameter separat angeben willst, dann muss du eine Referenz auf diese angeben, sonst wird der vierte Parameter als condition angesehen.
Du kannst aber gleich die Parameter mit der Funktion angeben:
set_Exec("$DEVICE"."_set_oft",$addSec,"DOIF::diWatchdog_Timer('$device','$event')";
statt $DEVICE kannst du auch gleich $device angeben, das ist eine echte Perlvariable.
in di_Watchdog_Timer dann einfach:
my ($Device,$Event)=@_;
Hallo Damian,
Vielen Dank. So klappt es ohne Probleme.
Lg, Gerhard