2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-01 07:19:24 +00:00
fhem-mirror/fhem/FHEM/SetExtensions.pm
2015-05-17 13:19:09 +00:00

165 lines
4.5 KiB
Perl

##############################################
# $Id$
package main;
use strict;
use warnings;
sub SetExtensions($$@);
sub SetExtensionsFn($);
sub
SetExtensions($$@)
{
my ($hash, $list, $name, $cmd, @a) = @_;
return "Unknown argument $cmd, choose one of " if(!$list);
my %se_list = (
"on-for-timer" => 1,
"off-for-timer" => 1,
"on-till" => 1,
"off-till" => 1,
"blink" => 2,
"intervals" => 0,
"toggle" => 0
);
my $hasOn = ($list =~ m/\bon\b/);
my $hasOff = ($list =~ m/\boff\b/);
my $value = Value($name);
my $em = AttrVal($name, "eventMap", undef);
if($em) {
if(!$hasOn || !$hasOff) {
$hasOn = ($em =~ m/:on\b/) if(!$hasOn);
$hasOff = ($em =~ m/:off\b/) if(!$hasOff);
}
# Following is fix for P#1: /B0:on/on-for-timer 300:5Min/
# $cmd = ReplaceEventMap($name, $cmd, 1) if($cmd ne "?");
# Has problem with P#2 (Forum #28855): /on-for-timer 300:5Min/on:Ein/
# Workaround for P#1 /on-for-timer 300:5Min/on-for-timer:on-for-timer/B0:on/
(undef,$value) = ReplaceEventMap($name, [$name, $value], 0) if($cmd ne "?");
}
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";
}
my $cmd1 = ($cmd =~ m/on.*/ ? "on" : "off");
my $cmd2 = ($cmd =~ m/on.*/ ? "off" : "on");
my $param = $a[0];
if($cmd eq "on-for-timer" || $cmd eq "off-for-timer") {
RemoveInternalTimer("SE $name $cmd");
return "$cmd requires a number as argument" if($param !~ m/^\d*\.?\d*$/);
if($param) {
DoSet($name, $cmd1);
InternalTimer(gettimeofday()+$param,"SetExtensionsFn","SE $name $cmd",0);
}
} elsif($cmd eq "on-till" || $cmd eq "off-till") {
my ($err, $hr, $min, $sec, $fn) = GetTimeSpec($param);
return "$cmd: $err" if($err);
my $at = $name . "_till";
CommandDelete(undef, $at) if($defs{$at});
my @lt = localtime;
my $hms_till = sprintf("%02d:%02d:%02d", $hr, $min, $sec);
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 "";
}
DoSet($name, $cmd1);
CommandDefine(undef, "$at at $hms_till set $name $cmd2");
} elsif($cmd eq "blink") {
my $p2 = $a[1];
delete($hash->{SE_BLINKPARAM});
return "$cmd requires 2 numbers as argument"
if($param !~ m/^\d+$/ || $p2 !~ m/^\d*\d?\d*$/);
if($param) {
DoSet($name, "on-for-timer", $p2);
$param--;
if($param) {
$hash->{SE_BLINKPARAM} = "$param $p2";
InternalTimer(gettimeofday()+2*$p2,"SetExtensionsFn","SE $name $cmd",0);
}
}
} elsif($cmd eq "intervals") {
my $at0 = "${name}_till";
my $at1 = "${name}_intervalFrom",
my $at2 = "${name}_intervalNext";
CommandDelete(undef, $at0) if($defs{$at0});
CommandDelete(undef, $at1) if($defs{$at1});
CommandDelete(undef, $at2) if($defs{$at2});
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 {
CommandDefine(undef, "$at1 at $from set $name on-till $till");
}
if(@a) {
my $rest = join(" ", @a);
my ($from, $till) = split("-", shift @a);
CommandDefine(undef, "$at2 at $from set $name intervals $rest");
}
}
} elsif($cmd eq "toggle") {
DoSet($name, $value =~ m/^on/ ? "off" : "on");
}
return undef;
}
sub
SetExtensionsFn($)
{
my (undef, $name, $cmd) = split(" ", shift, 3);
return if(!defined($defs{$name}));
if($cmd eq "on-for-timer") {
DoSet($name, "off");
} elsif($cmd eq "off-for-timer") {
DoSet($name, "on");
} elsif($cmd eq "blink" && $defs{$name}{SE_BLINKPARAM}) {
DoSet($name, "blink", split(" ", $defs{$name}{SE_BLINKPARAM}, 2));
}
}
1;