diff --git a/fhem/FHEM/98_DOIF.pm b/fhem/FHEM/98_DOIF.pm
index 449b4e25a..592f4fbab 100644
--- a/fhem/FHEM/98_DOIF.pm
+++ b/fhem/FHEM/98_DOIF.pm
@@ -22,7 +22,6 @@ package main;
use strict;
use warnings;
use Color;
-use vars qw($FW_wname); # Web instance name
sub DOIF_cmd ($$$$);
sub DOIF_Notify ($$);
@@ -69,6 +68,7 @@ sub DOIF_Initialize($)
my ($hash) = @_;
$hash->{DefFn} = "DOIF_Define";
$hash->{SetFn} = "DOIF_Set";
+ $hash->{GetFn} = "DOIF_Get";
$hash->{UndefFn} = "DOIF_Undef";
$hash->{AttrFn} = "DOIF_Attr";
$hash->{NotifyFn} = "DOIF_Notify";
@@ -80,7 +80,7 @@ sub DOIF_Initialize($)
$data{FWEXT}{DOIF}{SCRIPT} = "doif.js";
- $hash->{AttrList} = "disable:0,1 loglevel:0,1,2,3,4,5,6 wait do:always,resetwait cmdState state initialize repeatsame repeatcmd waitsame waitdel cmdpause timerWithWait:1,0 notexist selftrigger:wait,all timerevent:1,0 checkReadingEvent:1,0 addStateEvent:1,0 checkall:event,timer,all weekdays setList:textField-long readingList DOIF_Readings:textField-long uiTable:textField-long ".$readingFnAttributes;
+ $hash->{AttrList} = "disable:0,1 loglevel:0,1,2,3,4,5,6 wait do:always,resetwait cmdState startup state initialize repeatsame repeatcmd waitsame waitdel cmdpause timerWithWait:1,0 notexist selftrigger:wait,all timerevent:1,0 checkReadingEvent:1,0 addStateEvent:1,0 checkall:event,timer,all weekdays setList:textField-long readingList DOIF_Readings:textField-long uiTable:textField-long ".$readingFnAttributes;
}
# uiTable
@@ -486,10 +486,12 @@ sub DOIF_RegisterEvalAll
for (my $m=0;$m < scalar keys %{$hash->{$table}{table}{$i}{$k}{$l}};$m++) {
if (defined $hash->{$table}{table}{$i}{$k}{$l}{$m}){
my $value= eval ($hash->{$table}{table}{$i}{$k}{$l}{$m});
- if (defined $hash->{$table}{shownodevicelink} and !$hash->{$table}{shownodevicelink} and defined $defs{$value}) {
- $ret.="$value";
- } else {
- $ret.=$value;
+ if (defined ($value)) {
+ if (defined $defs{$value} and (!defined $hash->{$table}{shownodevicelink} or !$hash->{$table}{shownodevicelink})) {
+ $ret.="$value";
+ } else {
+ $ret.=$value;
+ }
}
}
}
@@ -501,24 +503,10 @@ sub DOIF_RegisterEvalAll
}
$ret .= "\n"; # if ($table eq "uiTable");
- # my $jsh = "";
- # $ret .= $jsh.$jsc.$jsf if ($jsc);
#$hash->{$table}{deftable}=$ret;
return $ret;
}
-# sub DOIF_summaryFn ($$$$) {
- # my ($FW_wname, $d, $room, $pageHash) = @_;
- # my $hash = $defs{$d};
- # return ($hash->{$table}{shownostate} ? "" : undef);
-# }
-
sub DOIF_tablePopUp {
my ($pn,$d,$icon,$table) = @_;
$table = $table ? $table : "uiTable";
@@ -684,8 +672,7 @@ sub SplitDoIf($$)
if (defined $tailBlock) {
while ($tailBlock ne "") {
($cmd,$tailBlock,$err)=GetCommandDoIf($separator,$tailBlock);
- #return (@commands,$err) if ($err);
- push(@commands,$cmd);
+ push(@commands,$cmd) if (defined $cmd);
}
}
return(@commands);
@@ -2107,9 +2094,9 @@ sub CheckRegexpDoIf
return undef;
}
-sub DOIF_Trigger ($$)
+sub DOIF_Trigger
{
- my ($hash,$device)= @_;
+ my ($hash,$device,$checkall)= @_;
my $timerNr=-1;
my $ret;
my $err;
@@ -2148,7 +2135,7 @@ sub DOIF_Trigger ($$)
$hash->{helper}{event}=$event;
} else { #event
if (!defined CheckRegexpDoIf($hash,"cond", $device,$i,$hash->{helper}{triggerEvents},1)) {
- if (AttrVal($pn, "checkall", 0) !~ "1|all|event") {
+ if (AttrVal($pn, "checkall", 0) !~ "1|all|event" and !defined $checkall) {
next if (!defined ($hash->{devices}{$i}));
next if ($hash->{devices}{$i} !~ / $device /);
next if (AttrVal($pn, "checkReadingEvent", 0) and !CheckReadingDoIf ($hash->{readings}{$i},$hash->{helper}{triggerEventsState}) and (defined $hash->{internals}{$i} ? $hash->{internals}{$i} !~ / $device:.+ /:1))
@@ -2226,6 +2213,21 @@ DOIF_Notify($$)
}
}
+ if (AttrVal($pn,"initialize",0) and !AttrVal($pn,"disable",0)) {
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate ($hash,"state",AttrVal($pn,"initialize",0));
+ readingsBulkUpdate ($hash,"cmd_nr","0");
+ readingsBulkUpdate ($hash,"cmd",0);
+ readingsEndUpdate($hash, 0);
+ }
+
+ my $startup=AttrVal($pn, "startup", 0);
+ if ($startup and !AttrVal($pn,"disable",0)) {
+ $startup =~ s/\$SELF/$pn/g;
+ my ($cmd,$err)=ParseCommandsDoIf($hash,$startup,1);
+ Log3 ($pn,3,"$pn: error in startup: $err") if ($err);
+ }
+
my $uiTable=AttrVal($pn, "uiTable", 0);
if ($uiTable){
my $err=DOIF_uiTable_def($hash,$uiTable,"uiTable");
@@ -2237,14 +2239,6 @@ DOIF_Notify($$)
my $err=DOIF_uiTable_def($hash,$uiState,"uiState");
Log3 ($pn,3,"$pn: error in uiState: $err") if ($err);
}
-
- if (AttrVal($pn,"initialize",0) and !AttrVal($pn,"disable",0)) {
- readingsBeginUpdate($hash);
- readingsBulkUpdate ($hash,"state",AttrVal($pn,"initialize",0));
- readingsBulkUpdate ($hash,"cmd_nr","0");
- readingsBulkUpdate ($hash,"cmd",0);
- readingsEndUpdate($hash, 0);
- }
}
return "" if (!$hash->{helper}{globalinit});
@@ -2745,6 +2739,7 @@ CmdDoIf($$)
readingsBeginUpdate($hash);
readingsBulkUpdate($hash,"cmd",0);
readingsBulkUpdate($hash,"state","initialized");
+ readingsBulkUpdate ($hash,"mode","enabled");
readingsEndUpdate($hash, 1);
$hash->{helper}{globalinit}=1;
}
@@ -2853,7 +2848,10 @@ DOIF_Attr(@)
} elsif($a[0] eq "set" and $a[2] eq "disable" and $a[3] eq "1") {
DOIF_delTimer($hash);
DOIF_delAll ($hash);
- readingsSingleUpdate ($hash,"state","deactivated",1);
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate ($hash, "state", "deactivated");
+ readingsBulkUpdate ($hash, "mode", "deactivated");
+ readingsEndUpdate ($hash, 1);
} elsif($a[0] eq "set" && $a[2] eq "state") {
delete $hash->{Regex}{"STATE"};
my ($block,$err)=ReplaceAllReadingsDoIf($hash,$a[3],-2,0);
@@ -2888,6 +2886,11 @@ DOIF_Attr(@)
#my $table=$a[2];
delete ($hash->{Regex}{$a[2]});
delete ($hash->{$a[2]});
+ } elsif($a[0] eq "set" && $a[2] eq "startup") {
+ my ($cmd,$err)=ParseCommandsDoIf($hash,$a[3],0);
+ if ($err) {
+ return ("error in startup $a[3], $err");
+ }
}
return undef;
}
@@ -2922,7 +2925,7 @@ DOIF_Set($@)
readingsBulkUpdate($hash, "mode", "disabled");
readingsEndUpdate ($hash, 1);
} elsif ($arg eq "initialize" ) {
- delete ($defs{$hash->{NAME}}{READINGS}{mode});
+ readingsSingleUpdate ($hash,"mode","enabled",1);
delete ($defs{$hash->{NAME}}{READINGS}{cmd_nr});
delete ($defs{$hash->{NAME}}{READINGS}{cmd});
delete ($defs{$hash->{NAME}}{READINGS}{cmd_seqnr});
@@ -2932,7 +2935,9 @@ DOIF_Set($@)
#delete ($defs{$hash->{NAME}}{READINGS}{mode});
readingsSingleUpdate ($hash,"state",ReadingsVal($pn,"last_cmd",""),0) if (ReadingsVal($pn,"last_cmd","") ne "");
delete ($defs{$hash->{NAME}}{READINGS}{last_cmd});
- readingsSingleUpdate ($hash,"mode","enable",1)
+ readingsSingleUpdate ($hash,"mode","enabled",1)
+ } elsif ($arg eq "checkall" ) {
+ DOIF_Trigger ($hash,$pn,1);
} elsif ($arg =~ /^cmd_(.*)/ ) {
if (ReadingsVal($pn,"mode","") ne "disabled") {
if ($hash->{helper}{sleeptimer} != -1) {
@@ -2955,7 +2960,7 @@ DOIF_Set($@)
$cmdList.="cmd_".($i+1).":noArg ";
#$cmdList.=EvalCmdStateDoIf($hash,$cmdSubState[0]).":noArg " if defined ($cmdState[$i]);
}
- return "unknown argument ? for $pn, choose one of disable:noArg initialize:noArg enable:noArg $cmdList $setList";
+ return "unknown argument ? for $pn, choose one of disable:noArg initialize:noArg enable:noArg checkall:noArg $cmdList $setList";
} else {
my @rl = split(" ", AttrVal($pn, "readingList", ""));
my $doRet;
@@ -2989,6 +2994,20 @@ DOIF_Set($@)
return $ret;
}
+sub
+DOIF_Get($@)
+{
+ my ($hash, @a) = @_;
+ my $pn = $a[0];
+ return "$pn: get needs at least one parameter" if(@a < 2);
+ my $arg= $a[1];
+ if( $arg eq "html" ) {
+ return DOIF_RegisterEvalAll($hash,$pn,"uiTable");
+ }
+
+ return undef;
+}
+
1;
@@ -3143,7 +3162,7 @@ Eine ausführliche Erläuterung der obigen Anwendungsbeispiele kann hier nachgel
[NEU] Erzeugen berechneter Readings
Vorbelegung des Status mit Initialisierung nach dem Neustart mit dem Attribut initialize
Deaktivieren des Moduls
- Bedingungslose Ausführen von Befehlszweigen
+ Bedingungslose Ausführen von Befehlszweigen
Initialisieren des Moduls
Weitere Anwendungsbeispiele
Zu beachten
@@ -3176,6 +3195,7 @@ Eine ausführliche Erläuterung der obigen Anwendungsbeispiele kann hier nachgel
selftrigger
readingList
setList
+ startup
state
timerevent
timerWithWait
@@ -3186,6 +3206,20 @@ Eine ausführliche Erläuterung der obigen Anwendungsbeispiele kann hier nachgel
weekdays
readingFnAttributes
+
+ Set Befehle
+
attr <DOIF-Modul> startup <FHEM-Befehl oder Perl-Befehl in geschweiften Klammern mit DOIF-Syntax>
attr di_test startup set $SELF cmd_1
attr di_test startup set $SELF checkall
attr di_test startup sleep 60;set lamp1 off;set lamp2 off
attr di_test startup {myfunction()},set lamp1 on,set lamp2 on
set <DOIF-modul> disable
geschehen.
-Hierbei bleiben alle Timer aktiv, sie werden aktualisiert - das Modul bleibt im Takt, allerding werden keine Befehle ausgeführt.
-Das Modul braucht mehr Rechenzeit, als wenn es komplett über das Attribut deaktiviert wird. In beiden Fällen bleibt der Zustand nach dem Neustart erhalten, das Modul bleibt deaktiviert.checkall
werden wie beim gleichnamigen Attribut alle DOIF-Bedingung überprüft, sobald eine Bedingung als wahr geprüft ist, wird das dazugehörige Kommando ausgeführt.
+Zu beachten ist, dass nur der erste wahre DOIF-Zweig ausgeführt wird und dass nur Zustandsabfragen sowie Zeitintervalle sinnvoll überprüft werden können.
+Ereignisabfragen sowie Zeitpunkt-Definitionen, sind zum Zeitpunkt der checkall-Abfrage normalerweise nicht wahr.attr di_test startup set $SELF checkall
disable
wird ein DOIF-Modul inaktiviert. Hierbei bleiben alle Timer aktiv, sie werden aktualisiert - das Modul bleibt im Takt, allerdings werden keine Befehle ausgeführt.
+Das Modul braucht mehr Rechenzeit, als wenn es komplett über das Attribut disable
deaktiviert wird. Ein inaktiver Zustand bleibt nach dem Neustart erhalten.
+Ein inaktives Modul kann über set-Befehle enable
bzw. initialize
wieder aktiviert werden.enable
wird ein inaktives DOIF-Modul wieder aktiviert. Im Gegensatz zum set-Befehl initialize
wird der letzte Zustand vor der Inaktivierung des Moduls wieder hergestellt.set <DOIF-modul> initialize
wird ein mit set <DOIF-modul> disable
deaktiviertes Modul wieder aktiviert.
-Das Kommando set <DOIF-modul> initialize
kann auch dazu genutzt werden ein aktives Modul zu initialisiert,
-in diesem Falle wird der letzte Zustand des Moduls gelöscht, damit wird ein Zustandswechsel herbeigeführt, der nächste Trigger führt zur Ausführung.initialize
wird ein DOIF-Modul initialisiert. Ein inaktives DOIF-Modul wieder aktiviert.
+Im Gegensatz zum set-Befehl enable
wird der letzte Zustand des Moduls gelöscht, damit wird ein Zustandswechsel herbeigeführt, der nächste Trigger führt zur Ausführung eines wahren DOIF-Zweiges.
+Diese Eigenschaft kann auch dazu genutzt werden, ein bereits aktives Modul zu initialisieren.set <DOIF-modul> cmd_<nr>
lässt sich ein Befehlszweig (cmd_1, cmd_2, usw.) bedingunglos ausführen. set <name> disable
set <name> checkall
set <name> disable
set <name> initialize
set <name> initialize
set <name> enable
set <name> enable
set <name> cmd_<nr>
set <name> cmd_<nr>