2013-01-27 21:30:41 +00:00
|
|
|
##############################################
|
2013-07-13 11:21:18 +00:00
|
|
|
# $Id$
|
2013-01-27 21:30:41 +00:00
|
|
|
|
|
|
|
package main;
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
sub SetExtensions($$@);
|
|
|
|
sub SetExtensionsFn($);
|
|
|
|
|
2016-05-08 14:25:39 +00:00
|
|
|
sub
|
|
|
|
SetExtensionsCancel($)
|
|
|
|
{
|
|
|
|
my ($hash) = @_;
|
2016-05-24 17:56:05 +00:00
|
|
|
$hash = $defs{$hash} if( ref($hash) ne 'HASH' );
|
2016-05-08 14:25:39 +00:00
|
|
|
|
|
|
|
return undef if( !$hash );
|
2016-11-29 20:40:24 +00:00
|
|
|
return undef if( $hash->{InSetExtensions} );
|
2016-05-08 14:25:39 +00:00
|
|
|
my $name = $hash->{NAME};
|
|
|
|
|
2016-11-29 20:40:24 +00:00
|
|
|
if($hash->{TIMED_OnOff}) { # on-for-timer, blink
|
|
|
|
my $cmd = $hash->{TIMED_OnOff}{CMD};
|
|
|
|
RemoveInternalTimer("SE $name $cmd");
|
|
|
|
delete $hash->{TIMED_OnOff};
|
|
|
|
}
|
2016-05-08 14:25:39 +00:00
|
|
|
|
2016-11-29 20:40:24 +00:00
|
|
|
for my $sfx ("_till", "_intervalFrom", "_intervalNext") {
|
|
|
|
CommandDelete(undef, $name.$sfx) if($defs{$name.$sfx});
|
|
|
|
}
|
2016-05-08 14:25:39 +00:00
|
|
|
return undef;
|
|
|
|
}
|
|
|
|
|
2016-11-29 20:40:24 +00:00
|
|
|
sub
|
|
|
|
SE_DoSet(@)
|
|
|
|
{
|
|
|
|
my $hash = $defs{$_[0]};
|
|
|
|
$hash->{InSetExtensions} = 1;
|
2017-01-02 19:51:46 +00:00
|
|
|
AnalyzeCommand($hash->{CL}, "set ".join(" ", @_)); # cmdalias (Forum #63896)
|
2016-11-29 20:40:24 +00:00
|
|
|
delete $hash->{InSetExtensions};
|
|
|
|
}
|
|
|
|
|
2013-01-27 21:30:41 +00:00
|
|
|
sub
|
|
|
|
SetExtensions($$@)
|
|
|
|
{
|
|
|
|
my ($hash, $list, $name, $cmd, @a) = @_;
|
|
|
|
|
2015-05-17 13:19:09 +00:00
|
|
|
return "Unknown argument $cmd, choose one of " if(!$list);
|
|
|
|
|
2013-01-27 21:30:41 +00:00
|
|
|
my %se_list = (
|
2015-10-09 13:13:11 +00:00
|
|
|
"on-for-timer" => 1,
|
|
|
|
"off-for-timer" => 1,
|
|
|
|
"on-till" => 1,
|
|
|
|
"off-till" => 1,
|
|
|
|
"on-till-overnight" => 1,
|
|
|
|
"off-till-overnight"=> 1,
|
2016-11-29 20:40:24 +00:00
|
|
|
"blink" => 0,
|
2015-10-09 13:13:11 +00:00
|
|
|
"intervals" => 0,
|
|
|
|
"toggle" => 0
|
2013-01-27 21:30:41 +00:00
|
|
|
);
|
|
|
|
|
2015-09-19 12:00:19 +00:00
|
|
|
my $hasOn = ($list =~ m/(^| )on\b/);
|
|
|
|
my $hasOff = ($list =~ m/(^| )off\b/);
|
2018-04-08 09:44:42 +00:00
|
|
|
my $eventMap = AttrVal($name, "eventMap", undef);
|
2018-02-18 11:59:09 +00:00
|
|
|
|
2018-04-08 09:44:42 +00:00
|
|
|
if((!$hasOn || !$hasOff) && $eventMap) {
|
2018-02-18 11:59:09 +00:00
|
|
|
if(!$hasOn) {
|
|
|
|
my (undef,$value) = ReplaceEventMap($name, [$name, "on"], 0);
|
|
|
|
$hasOn = ($value ne "on");
|
|
|
|
}
|
|
|
|
if(!$hasOff) {
|
|
|
|
my (undef,$value) = ReplaceEventMap($name, [$name, "off"], 0);
|
|
|
|
$hasOff = ($value ne "off");
|
2013-01-27 21:30:41 +00:00
|
|
|
}
|
|
|
|
}
|
2018-02-18 11:59:09 +00:00
|
|
|
|
2013-01-27 21:30:41 +00:00
|
|
|
if(!$hasOn || !$hasOff) { # No extension
|
|
|
|
return "Unknown argument $cmd, choose one of $list";
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!defined($se_list{$cmd})) {
|
|
|
|
# Add only "new" commands
|
|
|
|
my @mylist = grep { $list !~ m/\b$_\b/ } keys %se_list;
|
|
|
|
return "Unknown argument $cmd, choose one of $list " .
|
|
|
|
join(" ", @mylist);
|
|
|
|
}
|
|
|
|
if($se_list{$cmd} && $se_list{$cmd} != int(@a)) {
|
|
|
|
return "$cmd requires $se_list{$cmd} parameter";
|
|
|
|
}
|
|
|
|
|
2016-11-29 20:40:24 +00:00
|
|
|
SetExtensionsCancel($hash);
|
2015-10-09 13:13:11 +00:00
|
|
|
my $cmd1 = ($cmd =~ m/^on.*/ ? "on" : "off");
|
|
|
|
my $cmd2 = ($cmd =~ m/^on.*/ ? "off" : "on");
|
2013-01-27 21:30:41 +00:00
|
|
|
my $param = $a[0];
|
|
|
|
|
2016-11-29 20:40:24 +00:00
|
|
|
|
2013-01-27 21:30:41 +00:00
|
|
|
if($cmd eq "on-for-timer" || $cmd eq "off-for-timer") {
|
|
|
|
return "$cmd requires a number as argument" if($param !~ m/^\d*\.?\d*$/);
|
|
|
|
|
|
|
|
if($param) {
|
2016-05-08 14:28:55 +00:00
|
|
|
$hash->{TIMED_OnOff} = {
|
2016-11-29 20:40:24 +00:00
|
|
|
START=>time(), START_FMT=>TimeNow(), DURATION=>$param,
|
|
|
|
CMD=>$cmd, NEXTCMD=>$cmd2
|
2016-05-08 14:25:39 +00:00
|
|
|
};
|
2016-11-29 20:40:24 +00:00
|
|
|
SE_DoSet($name, $cmd1);
|
2013-01-27 21:30:41 +00:00
|
|
|
InternalTimer(gettimeofday()+$param,"SetExtensionsFn","SE $name $cmd",0);
|
|
|
|
}
|
|
|
|
|
2015-10-09 13:13:11 +00:00
|
|
|
} elsif($cmd =~ m/^(on|off)-till/) {
|
2013-01-27 21:30:41 +00:00
|
|
|
my ($err, $hr, $min, $sec, $fn) = GetTimeSpec($param);
|
|
|
|
return "$cmd: $err" if($err);
|
|
|
|
|
|
|
|
my $hms_till = sprintf("%02d:%02d:%02d", $hr, $min, $sec);
|
2015-10-09 13:13:11 +00:00
|
|
|
if($cmd =~ m/-till$/) {
|
|
|
|
my @lt = localtime;
|
|
|
|
my $hms_now = sprintf("%02d:%02d:%02d", $lt[2], $lt[1], $lt[0]);
|
|
|
|
if($hms_now ge $hms_till) {
|
|
|
|
Log3 $hash, 4,
|
|
|
|
"$cmd: won't switch as now ($hms_now) is later than $hms_till";
|
|
|
|
return "";
|
|
|
|
}
|
2013-01-27 21:30:41 +00:00
|
|
|
}
|
2016-11-29 20:40:24 +00:00
|
|
|
SE_DoSet($name, $cmd1);
|
|
|
|
CommandDefine(undef, "${name}_till at $hms_till set $name $cmd2");
|
2013-01-27 21:30:41 +00:00
|
|
|
|
|
|
|
} elsif($cmd eq "blink") {
|
|
|
|
my $p2 = $a[1];
|
|
|
|
return "$cmd requires 2 numbers as argument"
|
2016-11-29 20:40:24 +00:00
|
|
|
if($param !~ m/^\d+$/ || $p2 !~ m/^\d*\.?\d*$/);
|
2013-01-27 21:30:41 +00:00
|
|
|
|
|
|
|
if($param) {
|
2016-11-29 20:40:24 +00:00
|
|
|
SE_DoSet($name, $a[2] ? "off" : "on");
|
|
|
|
$param-- if($a[2]);
|
2013-01-27 21:30:41 +00:00
|
|
|
if($param) {
|
2016-11-29 20:40:24 +00:00
|
|
|
$hash->{TIMED_OnOff} = {
|
|
|
|
START=>time(), START_FMT=>TimeNow(), DURATION=>$param,
|
|
|
|
CMD=>$cmd, NEXTCMD=>"$cmd $param $p2 ".($a[2] ? "0" : "1")
|
|
|
|
};
|
|
|
|
InternalTimer(gettimeofday()+$p2, "SetExtensionsFn","SE $name $cmd",0);
|
2013-01-27 21:30:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} elsif($cmd eq "intervals") {
|
|
|
|
|
|
|
|
my $intSpec = shift(@a);
|
|
|
|
if($intSpec) {
|
|
|
|
my ($from, $till) = split("-", $intSpec);
|
|
|
|
|
|
|
|
my ($err, $hr, $min, $sec, $fn) = GetTimeSpec($from);
|
|
|
|
return "$cmd: $err" if($err);
|
|
|
|
my @lt = localtime;
|
|
|
|
my $hms_from = sprintf("%02d:%02d:%02d", $hr, $min, $sec);
|
|
|
|
my $hms_now = sprintf("%02d:%02d:%02d", $lt[2], $lt[1], $lt[0]);
|
|
|
|
|
|
|
|
if($hms_from le $hms_now) { # By slight delays at will schedule tomorrow.
|
|
|
|
SetExtensions($hash, $list, $name, "on-till", $till);
|
|
|
|
|
|
|
|
} else {
|
2016-11-29 20:40:24 +00:00
|
|
|
CommandDefine(undef,
|
|
|
|
"${name}_intervalFrom at $from set $name on-till $till");
|
2013-01-27 21:30:41 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(@a) {
|
|
|
|
my $rest = join(" ", @a);
|
|
|
|
my ($from, $till) = split("-", shift @a);
|
2016-11-29 20:40:24 +00:00
|
|
|
CommandDefine(undef,
|
|
|
|
"${name}_intervalNext at $from set $name intervals $rest");
|
2013-01-27 21:30:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-21 14:19:50 +00:00
|
|
|
} elsif($cmd eq "toggle") {
|
2018-02-18 11:59:09 +00:00
|
|
|
my $value = Value($name);
|
2018-04-08 09:44:42 +00:00
|
|
|
(undef,$value) = ReplaceEventMap($name, [$name, $value], 0) if($eventMap);
|
|
|
|
|
2016-02-15 17:42:13 +00:00
|
|
|
$value = ($1==0 ? "off" : "on") if($value =~ m/dim (\d+)/); # Forum #49391
|
2016-11-29 20:40:24 +00:00
|
|
|
SE_DoSet($name, $value =~ m/^on/ ? "off" : "on");
|
2014-09-21 14:19:50 +00:00
|
|
|
|
2013-01-27 21:30:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return undef;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub
|
|
|
|
SetExtensionsFn($)
|
|
|
|
{
|
|
|
|
my (undef, $name, $cmd) = split(" ", shift, 3);
|
2016-05-08 14:25:39 +00:00
|
|
|
my $hash = $defs{$name};
|
2016-11-29 20:40:24 +00:00
|
|
|
return if(!$hash || !$hash->{TIMED_OnOff});
|
2013-01-27 21:30:41 +00:00
|
|
|
|
2016-11-29 20:40:24 +00:00
|
|
|
my $nextcmd = $hash->{TIMED_OnOff}{NEXTCMD};
|
2016-05-08 14:28:55 +00:00
|
|
|
delete $hash->{TIMED_OnOff};
|
2016-11-29 20:40:24 +00:00
|
|
|
SE_DoSet($name, split(" ",$nextcmd));
|
2013-01-27 21:30:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
1;
|