fhem.pl: add sleep with id / cancel (Forum #44747)
git-svn-id: svn://svn.code.sf.net/p/fhem/code/trunk@10024 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
@@ -38,6 +38,7 @@
|
|||||||
<a href="#attr">attr</a>
|
<a href="#attr">attr</a>
|
||||||
<a href="#backup">backup</a>
|
<a href="#backup">backup</a>
|
||||||
<a href="#CULflash">CULflash</a>
|
<a href="#CULflash">CULflash</a>
|
||||||
|
<a href="#cancel">cancel</a>
|
||||||
<a href="#cmdalias">cmdalias</a>
|
<a href="#cmdalias">cmdalias</a>
|
||||||
<a href="#configdb">configdb</a>
|
<a href="#configdb">configdb</a>
|
||||||
<a href="#copy">copy</a>
|
<a href="#copy">copy</a>
|
||||||
@@ -732,6 +733,15 @@ The following local attributes are used by a wider range of devices:
|
|||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<a name="cancel"></a>
|
||||||
|
<h3>cancel</h3>
|
||||||
|
<ul>
|
||||||
|
<code>cancel [<id> [quiet]]</code>
|
||||||
|
<br><br>
|
||||||
|
Cancels a named <a href="#sleep">sleep</a>.
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
<a name="define"></a>
|
<a name="define"></a>
|
||||||
<h3>define</h3>
|
<h3>define</h3>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -1250,13 +1260,16 @@ The following local attributes are used by a wider range of devices:
|
|||||||
<a name="sleep"></a>
|
<a name="sleep"></a>
|
||||||
<h3>sleep</h3>
|
<h3>sleep</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<code>sleep <sec> [quiet]</code>
|
<code>sleep <sec> [<id>] [quiet]</code>
|
||||||
<br><br>
|
<br><br>
|
||||||
sleep followed by another command is comparable to a nameless <a
|
sleep followed by another command is comparable to a nameless <a
|
||||||
href="#at">at</a>, it executes the following commands after waiting the
|
href="#at">at</a>, it executes the following commands after waiting the
|
||||||
specified time. The unit is seconds, with millisecond accuracy, as you can
|
specified time. The unit is seconds, with millisecond accuracy, as you can
|
||||||
specify decimal places.<br><br>
|
specify decimal places.<br><br>
|
||||||
|
|
||||||
|
A sleep with an <id< will replace a sleep with the same <id<
|
||||||
|
and can be canceled by <a href="#cancel">cancel</a>.
|
||||||
|
|
||||||
When called in a notify/at/etc, then nonempty return values of the following
|
When called in a notify/at/etc, then nonempty return values of the following
|
||||||
commands are logged to the global logfile with loglevel 2.<br> If quiet is
|
commands are logged to the global logfile with loglevel 2.<br> If quiet is
|
||||||
specified, then skip this logging.
|
specified, then skip this logging.
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
<a href="#attr">attr</a>
|
<a href="#attr">attr</a>
|
||||||
<a href="#backup">backup</a>
|
<a href="#backup">backup</a>
|
||||||
<a href="#CULflash">CULflash</a>
|
<a href="#CULflash">CULflash</a>
|
||||||
|
<a href="#cancel">cancel</a>
|
||||||
<a href="#cmdalias">cmdalias</a>
|
<a href="#cmdalias">cmdalias</a>
|
||||||
<a href="#configdb">configdb</a>
|
<a href="#configdb">configdb</a>
|
||||||
<a href="#copy">copy</a>
|
<a href="#copy">copy</a>
|
||||||
@@ -761,6 +762,14 @@ Die folgenden lokalen Attribute werden von mehreren Geräten verwendet:
|
|||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<a name="cancel"></a>
|
||||||
|
<h3>cancel</h3>
|
||||||
|
<ul>
|
||||||
|
<code>cancel [<id> [quiet]]</code>
|
||||||
|
<br><br>
|
||||||
|
Entfernt ein benanntes <a href="#sleep">sleep</a>.
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
<a name="define"></a>
|
<a name="define"></a>
|
||||||
<h3>define</h3>
|
<h3>define</h3>
|
||||||
@@ -1336,6 +1345,9 @@ Die folgenden lokalen Attribute werden von mehreren Geräten verwendet:
|
|||||||
Sekunde, Millisekunden genau, da man Nachkommastellen spezifizieren
|
Sekunde, Millisekunden genau, da man Nachkommastellen spezifizieren
|
||||||
kann.<br><br>
|
kann.<br><br>
|
||||||
|
|
||||||
|
Ein sleep mit einer <id< ersetzt ein sleep mit der gleichen <id<
|
||||||
|
and can mit <a href="#cancel">cancel</a> entfernt werden.
|
||||||
|
|
||||||
Falls sleep in at/notify/etc aufgerufen wurde, und die nachfolgenden
|
Falls sleep in at/notify/etc aufgerufen wurde, und die nachfolgenden
|
||||||
Kommandos einen nicht leeren Text zurückgeliefert haben, dann wird
|
Kommandos einen nicht leeren Text zurückgeliefert haben, dann wird
|
||||||
dieser Text mit loglevel 2 protokolliert.<br>
|
dieser Text mit loglevel 2 protokolliert.<br>
|
||||||
|
|||||||
49
fhem/fhem.pl
49
fhem/fhem.pl
@@ -127,6 +127,7 @@ sub setReadingsVal($$$$);
|
|||||||
sub utf8ToLatin1($);
|
sub utf8ToLatin1($);
|
||||||
|
|
||||||
sub CommandAttr($$);
|
sub CommandAttr($$);
|
||||||
|
sub CommandCancel($$);
|
||||||
sub CommandDefaultAttr($$);
|
sub CommandDefaultAttr($$);
|
||||||
sub CommandDefine($$);
|
sub CommandDefine($$);
|
||||||
sub CommandDefMod($$);
|
sub CommandDefMod($$);
|
||||||
@@ -240,6 +241,7 @@ my $wbName = ".WRITEBUFFER"; # Buffer-name for delayed writing via select
|
|||||||
my %comments; # Comments from the include files
|
my %comments; # Comments from the include files
|
||||||
my %duplicate; # Pool of received msg for multi-fhz/cul setups
|
my %duplicate; # Pool of received msg for multi-fhz/cul setups
|
||||||
my @cmdList; # Remaining commands in a chain. Used by sleep
|
my @cmdList; # Remaining commands in a chain. Used by sleep
|
||||||
|
my %sleepers; # list of sleepers
|
||||||
|
|
||||||
$init_done = 0;
|
$init_done = 0;
|
||||||
$lastDefChange = 0;
|
$lastDefChange = 0;
|
||||||
@@ -307,6 +309,8 @@ $readingFnAttributes = "event-on-change-reading event-on-update-reading ".
|
|||||||
"?" => { ReplacedBy => "help" },
|
"?" => { ReplacedBy => "help" },
|
||||||
"attr" => { Fn=>"CommandAttr",
|
"attr" => { Fn=>"CommandAttr",
|
||||||
Hlp=>"<devspec> <attrname> [<attrval>],set attribute for <devspec>"},
|
Hlp=>"<devspec> <attrname> [<attrval>],set attribute for <devspec>"},
|
||||||
|
"cancel" => { Fn=>"CommandCancel",
|
||||||
|
Hlp=>"[<id> [quiet]],list sleepers, cancel sleeper with <id>" },
|
||||||
"createlog"=> { ModuleName => "autocreate" },
|
"createlog"=> { ModuleName => "autocreate" },
|
||||||
"define" => { Fn=>"CommandDefine",
|
"define" => { Fn=>"CommandDefine",
|
||||||
Hlp=>"<name> <type> <options>,define a device" },
|
Hlp=>"<name> <type> <options>,define a device" },
|
||||||
@@ -361,7 +365,7 @@ $readingFnAttributes = "event-on-change-reading event-on-update-reading ".
|
|||||||
"shutdown"=> { Fn=>"CommandShutdown",
|
"shutdown"=> { Fn=>"CommandShutdown",
|
||||||
Hlp=>"[restart],terminate the server" },
|
Hlp=>"[restart],terminate the server" },
|
||||||
"sleep" => { Fn=>"CommandSleep",
|
"sleep" => { Fn=>"CommandSleep",
|
||||||
Hlp=>"<sec> [quiet],sleep for sec, 3 decimal places" },
|
Hlp=>"<sec> [<id>] [quiet],sleep for sec, 3 decimal places" },
|
||||||
"trigger" => { Fn=>"CommandTrigger",
|
"trigger" => { Fn=>"CommandTrigger",
|
||||||
Hlp=>"<devspec> <state>,trigger notify command" },
|
Hlp=>"<devspec> <state>,trigger notify command" },
|
||||||
"update" => {
|
"update" => {
|
||||||
@@ -2625,28 +2629,65 @@ sub
|
|||||||
WakeUpFn($)
|
WakeUpFn($)
|
||||||
{
|
{
|
||||||
my $h = shift;
|
my $h = shift;
|
||||||
|
delete $sleepers{$h->{id}} if( $h->{id} );
|
||||||
|
|
||||||
$evalSpecials = $h->{evalSpecials};
|
$evalSpecials = $h->{evalSpecials};
|
||||||
my $ret = AnalyzeCommandChain(undef, $h->{cmd});
|
my $ret = AnalyzeCommandChain(undef, $h->{cmd});
|
||||||
Log 2, "After sleep: $ret" if($ret && !$h->{quiet});
|
Log 2, "After sleep: $ret" if($ret && !$h->{quiet});
|
||||||
}
|
}
|
||||||
|
sub
|
||||||
|
CommandCancel($$)
|
||||||
|
{
|
||||||
|
my ($cl, $param) = @_;
|
||||||
|
my ($id, $quiet) = split(" ", $param, 3);
|
||||||
|
return "Last parameter must be quiet" if($quiet && $quiet ne "quiet");
|
||||||
|
|
||||||
|
if( !$id ) {
|
||||||
|
my $ret;
|
||||||
|
foreach $id (keys %sleepers) {
|
||||||
|
$ret .= "\n" if( $ret );
|
||||||
|
$ret .= sprintf( "%-10s %s", $id, $sleepers{$id}->{cmd} );
|
||||||
|
}
|
||||||
|
$ret = "no pending sleeps" if( !$ret );
|
||||||
|
return $ret;
|
||||||
|
|
||||||
|
} elsif( my $h = $sleepers{$id} ) {
|
||||||
|
RemoveInternalTimer( $h );
|
||||||
|
delete $sleepers{$h->{id}};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return "no such id: $id" if( !$quiet );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
sub
|
sub
|
||||||
CommandSleep($$)
|
CommandSleep($$)
|
||||||
{
|
{
|
||||||
my ($cl, $param) = @_;
|
my ($cl, $param) = @_;
|
||||||
my ($sec, $quiet) = split(" ", $param);
|
my ($sec, $id, $quiet) = split(" ", $param, 3);
|
||||||
|
if( $id && $id eq 'quiet' ) {
|
||||||
|
$quiet = $id;
|
||||||
|
$id = undef;
|
||||||
|
}
|
||||||
|
|
||||||
return "Argument missing" if(!defined($sec));
|
return "Argument missing" if(!defined($sec));
|
||||||
return "Cannot interpret $sec as seconds" if($sec !~ m/^[0-9\.]+$/);
|
return "Cannot interpret $sec as seconds" if($sec !~ m/^[0-9\.]+$/);
|
||||||
return "Second parameter must be quiet" if($quiet && $quiet ne "quiet");
|
return "Last parameter must be quiet" if($quiet && $quiet ne "quiet");
|
||||||
|
|
||||||
Log 4, "sleeping for $sec";
|
Log 4, "sleeping for $sec";
|
||||||
|
|
||||||
if(@cmdList && $sec && $init_done) {
|
if(@cmdList && $sec && $init_done) {
|
||||||
my %h = (cmd => join(";", @cmdList),
|
my %h = (cmd => join(";", @cmdList),
|
||||||
evalSpecials => $evalSpecials,
|
evalSpecials => $evalSpecials,
|
||||||
quiet => $quiet);
|
quiet => $quiet,
|
||||||
|
id => $id);
|
||||||
|
if( $id ) {
|
||||||
|
RemoveInternalTimer( $sleepers{$id} ) if( $sleepers{$id} );
|
||||||
|
$sleepers{$id} = \%h;
|
||||||
|
}
|
||||||
InternalTimer(gettimeofday()+$sec, "WakeUpFn", \%h, 0);
|
InternalTimer(gettimeofday()+$sec, "WakeUpFn", \%h, 0);
|
||||||
@cmdList=();
|
@cmdList=();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user