mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-07 16:59:18 +00:00
98_Randomtimer: Clean up Code; Correct Commandref
git-svn-id: https://svn.fhem.de/fhem/trunk@16826 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
478ffa0a60
commit
b340464c51
@ -1,49 +1,70 @@
|
||||
# Id ##########################################################################
|
||||
# $Id$
|
||||
##############################################################################
|
||||
|
||||
# copyright ###################################################################
|
||||
#
|
||||
# 98_RandomTimer_Initialize.pm
|
||||
# written by Dietmar Ortmann
|
||||
# Maintained by igami since 02-2018
|
||||
# 98_RandomTimer.pm
|
||||
#
|
||||
# This file is part of fhem.
|
||||
# written by Dietmar Ortmann
|
||||
# Maintained by igami since 02-2018
|
||||
#
|
||||
# Fhem is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
# This file is part of FHEM.
|
||||
#
|
||||
# Fhem is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# FHEM is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
||||
# FHEM is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
##############################################################################
|
||||
# 10.09.2013 Svenson : disable direct if attribute changed, add state disabled;
|
||||
# randomtimer run every day if attribut runonce 0 (default is 1)
|
||||
#
|
||||
##############################################################################
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with FHEM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# packages ####################################################################
|
||||
package main;
|
||||
use strict;
|
||||
use warnings;
|
||||
no if $] >= 5.017011, warnings => 'experimental::smartmatch';
|
||||
use Time::HiRes qw(gettimeofday);
|
||||
use Time::Local 'timelocal_nocheck';
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
no if $] >= 5.017011, warnings => 'experimental::smartmatch';
|
||||
# forward declarations ########################################################
|
||||
sub RandomTimer_Initialize($);
|
||||
|
||||
# use IO::Socket;
|
||||
use Time::HiRes qw(gettimeofday);
|
||||
use Time::Local 'timelocal_nocheck';
|
||||
sub RandomTimer_Define($$);
|
||||
sub RandomTimer_Undef($$);
|
||||
sub RandomTimer_Attr($$$);
|
||||
|
||||
sub RandomTimer_stopTimeReached($);
|
||||
sub RandomTimer_addDays ($$);
|
||||
sub RandomTimer_device_switch ($);
|
||||
sub RandomTimer_device_toggle ($);
|
||||
sub RandomTimer_down($);
|
||||
sub RandomTimer_Exec($);
|
||||
sub RandomTimer_getSecsToNextAbschaltTest($);
|
||||
sub RandomTimer_isAktive ($);
|
||||
sub RandomTimer_isDisabled($);
|
||||
sub RandomTimer_schaltZeitenErmitteln ($$);
|
||||
sub RandomTimer_setActive($$);
|
||||
sub RandomTimer_setState($);
|
||||
sub RandomTimer_setSwitchmode ($$);
|
||||
sub RandomTimer_SetTimer($);
|
||||
sub RandomTimer_startZeitErmitteln ($$);
|
||||
sub RandomTimer_stopTimeReached($);
|
||||
sub RandomTimer_stopZeitErmitteln ($$);
|
||||
sub RandomTimer_Wakeup();
|
||||
sub RandomTimer_zeitBerechnen ($$$$);
|
||||
|
||||
sub RandomTimer_Initialize($)
|
||||
{
|
||||
# initialize ##################################################################
|
||||
sub RandomTimer_Initialize($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
if(!$modules{Twilight}{LOADED} && -f "$attr{global}{modpath}/FHEM/59_Twilight.pm") {
|
||||
if(
|
||||
!$modules{Twilight}{LOADED} &&
|
||||
-f "$attr{global}{modpath}/FHEM/59_Twilight.pm"
|
||||
) {
|
||||
my $ret = CommandReload(undef, "59_Twilight");
|
||||
Log3 undef, 1, $ret if($ret);
|
||||
}
|
||||
@ -51,22 +72,13 @@ sub RandomTimer_Initialize($)
|
||||
$hash->{DefFn} = "RandomTimer_Define";
|
||||
$hash->{UndefFn} = "RandomTimer_Undef";
|
||||
$hash->{AttrFn} = "RandomTimer_Attr";
|
||||
$hash->{AttrList} = "onCmd offCmd switchmode disable:0,1 disableCond runonce:0,1 keepDeviceAlive forceStoptimeSameDay ".
|
||||
$hash->{AttrList} = "onCmd offCmd switchmode disable:0,1 disableCond ".
|
||||
"runonce:0,1 keepDeviceAlive forceStoptimeSameDay ".
|
||||
$readingFnAttributes;
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_Undef($$) {
|
||||
|
||||
my ($hash, $arg) = @_;
|
||||
|
||||
myRemoveInternalTimer("SetTimer", $hash);
|
||||
myRemoveInternalTimer("Exec", $hash);
|
||||
delete $modules{RandomTimer}{defptr}{$hash->{NAME}};
|
||||
return undef;
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_Define($$)
|
||||
{
|
||||
# regular Fn ##################################################################
|
||||
sub RandomTimer_Define($$) {
|
||||
my ($hash, $def) = @_;
|
||||
|
||||
RemoveInternalTimer($hash);
|
||||
@ -118,45 +130,93 @@ sub RandomTimer_Define($$)
|
||||
|
||||
return undef;
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_SetTimer($) {
|
||||
my ($myHash) = @_;
|
||||
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
|
||||
return if (!defined($hash));
|
||||
|
||||
my $now = time();
|
||||
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($now);
|
||||
sub RandomTimer_Undef($$) {
|
||||
|
||||
RandomTimer_setActive($hash, 0);
|
||||
RandomTimer_schaltZeitenErmitteln($hash, $now);
|
||||
RandomTimer_setState($hash);
|
||||
my ($hash, $arg) = @_;
|
||||
|
||||
Log3 $hash, 4, "[".$hash->{NAME}."]" . " timings RandomTimer on $hash->{DEVICE}: "
|
||||
. strftime("%H:%M:%S(%d)",localtime($hash->{helper}{startTime})) . " - "
|
||||
. strftime("%H:%M:%S(%d)",localtime($hash->{helper}{stopTime}));
|
||||
|
||||
my $secToMidnight = 24*3600 -(3600*$hour + 60*$min + $sec);
|
||||
|
||||
my $setExecTime = max($now, $hash->{helper}{startTime});
|
||||
myRemoveInternalTimer("SetTimer", $hash);
|
||||
myRemoveInternalTimer("Exec", $hash);
|
||||
myInternalTimer ("Exec", $setExecTime, "RandomTimer_Exec", $hash, 0);
|
||||
|
||||
if ($hash->{helper}{REP} gt "") {
|
||||
my $setTimerTime = max($now+$secToMidnight + 15,
|
||||
$hash->{helper}{stopTime}) + $hash->{helper}{TIMETOSWITCH}+15;
|
||||
myRemoveInternalTimer("SetTimer", $hash);
|
||||
myInternalTimer ("SetTimer", $setTimerTime, "RandomTimer_SetTimer", $hash, 0);
|
||||
}
|
||||
delete $modules{RandomTimer}{defptr}{$hash->{NAME}};
|
||||
return undef;
|
||||
}
|
||||
########################################################################
|
||||
# define Test RandomTimer +00:00:05 Brunnen +00:05:00 60 ;
|
||||
# attr Test room RandomTimerX ;
|
||||
# attr Test verbose 5 ;
|
||||
# define ds at +00:00:30 attr Test disable 1 ;
|
||||
#
|
||||
# delete RT_Test; define RT_Test RandomTimer *22:00:00 Brunnen 23:00:00 300
|
||||
# set RT_Test disable 0
|
||||
# delete RT_Test
|
||||
|
||||
sub RandomTimer_Attr($$$) {
|
||||
my ($cmd, $name, $attrName, $attrVal) = @_;
|
||||
|
||||
my $hash = $defs{$name};
|
||||
|
||||
if( $attrName ~~ ["switchmode"] ) {
|
||||
RandomTimer_setSwitchmode($hash, $attrVal);
|
||||
}
|
||||
|
||||
if( $attrName ~~ ["disable","disableCond"] ) {
|
||||
|
||||
# Schaltung vorziehen, damit bei einem disable abgeschaltet wird.
|
||||
myRemoveInternalTimer("Exec", $hash);
|
||||
myInternalTimer ("Exec", time()+1, "RandomTimer_Exec", $hash, 0);
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
# module Fn ###################################################################
|
||||
sub RandomTimer_addDays ($$) {
|
||||
my ($now, $days) = @_;
|
||||
|
||||
my @jetzt_arr = localtime($now);
|
||||
$jetzt_arr[3] += $days;
|
||||
my $next = timelocal_nocheck(@jetzt_arr);
|
||||
return $next;
|
||||
|
||||
}
|
||||
|
||||
sub RandomTimer_device_switch ($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
my $command = "set @ $hash->{COMMAND}";
|
||||
if ($hash->{COMMAND} eq "on") {
|
||||
$command = AttrVal($hash->{NAME}, "onCmd", $command);
|
||||
} else {
|
||||
$command = AttrVal($hash->{NAME}, "offCmd", $command);
|
||||
}
|
||||
$command =~ s/@/$hash->{DEVICE}/g;
|
||||
$command = SemicolonEscape($command);
|
||||
Log3 $hash, 4, "[".$hash->{NAME}. "]"." command: $command";
|
||||
|
||||
my $ret = AnalyzeCommandChain(undef, $command);
|
||||
Log3 ($hash, 3, "[$hash->{NAME}] ERROR: " . $ret . " SENDING " . $command) if($ret);
|
||||
#Log3 $hash, 3, "[$hash->{NAME}] Value($hash->{COMMAND})=".Value($hash->{DEVICE});
|
||||
#$hash->{"$hash->{COMMAND}Value"} = Value($hash->{DEVICE});
|
||||
}
|
||||
|
||||
sub RandomTimer_device_toggle ($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
my $status = Value($hash->{DEVICE});
|
||||
if ($status ne "on" && $status ne "off" ) {
|
||||
Log3 $hash, 3, "[".$hash->{NAME}."]"." result of function Value($hash->{DEVICE}) must be 'on' or 'off'";
|
||||
}
|
||||
|
||||
my $sigma = ($status eq "on")
|
||||
? $hash->{helper}{SIGMAWHENON}
|
||||
: $hash->{helper}{SIGMAWHENOFF};
|
||||
|
||||
my $zufall = int(rand(1000));
|
||||
Log3 $hash, 4, "[".$hash->{NAME}."]"." IstZustand:$status sigmaWhen-$status:$sigma random:$zufall<$sigma=>" . (($zufall < $sigma)?"true":"false");
|
||||
|
||||
if ($zufall < $sigma ) {
|
||||
$hash->{COMMAND} = ($status eq "on") ? "off" : "on";
|
||||
RandomTimer_device_switch($hash);
|
||||
}
|
||||
}
|
||||
|
||||
sub RandomTimer_down($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{COMMAND} = AttrVal($hash->{NAME}, "keepDeviceAlive", 0) ? "on" : "off";
|
||||
RandomTimer_device_switch($hash);
|
||||
}
|
||||
|
||||
sub RandomTimer_Exec($) {
|
||||
my ($myHash) = @_;
|
||||
|
||||
@ -228,31 +288,62 @@ sub RandomTimer_Exec($) {
|
||||
myInternalTimer ("Exec", $nextSwitch, "RandomTimer_Exec", $hash, 0);
|
||||
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_stopTimeReached($) {
|
||||
my ($hash) = @_;
|
||||
return ( time()>$hash->{helper}{stopTime} );
|
||||
|
||||
sub RandomTimer_getSecsToNextAbschaltTest($) {
|
||||
my ($hash) = @_;
|
||||
my $intervall = $hash->{helper}{TIMETOSWITCH};
|
||||
|
||||
my $proz = 10;
|
||||
my $delta = $intervall * $proz/100;
|
||||
my $nextSecs = $intervall - $delta/2 + int(rand($delta));
|
||||
|
||||
return $nextSecs;
|
||||
}
|
||||
########################################################################
|
||||
|
||||
sub RandomTimer_isAktive ($) {
|
||||
my ($hash) = @_;
|
||||
return defined ($hash->{helper}{active}) ? $hash->{helper}{active} : 0;
|
||||
}
|
||||
|
||||
sub RandomTimer_isDisabled($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
my $disable = AttrVal($hash->{NAME}, "disable", 0 );
|
||||
return $disable if($disable);
|
||||
|
||||
my $disableCond = AttrVal($hash->{NAME}, "disableCond", "nf" );
|
||||
if ($disableCond eq "nf") {
|
||||
return 0;
|
||||
} else {
|
||||
$disable = eval ($disableCond);
|
||||
if ($@) {
|
||||
$@ =~ s/\n/ /g;
|
||||
Log3 ($hash, 3, "[$hash->{NAME}] ERROR: " . $@ . " EVALUATING " . $disableCond);
|
||||
}
|
||||
return $disable;
|
||||
}
|
||||
}
|
||||
|
||||
sub RandomTimer_schaltZeitenErmitteln ($$) {
|
||||
my ($hash,$now) = @_;
|
||||
|
||||
RandomTimer_startZeitErmitteln($hash, $now);
|
||||
RandomTimer_stopZeitErmitteln ($hash, $now);
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate ($hash, "Startzeit", FmtDateTime($hash->{helper}{startTime}));
|
||||
readingsBulkUpdate ($hash, "Stoppzeit", FmtDateTime($hash->{helper}{stopTime}));
|
||||
readingsEndUpdate ($hash, defined($hash->{LOCAL} ? 0 : 1));
|
||||
|
||||
}
|
||||
|
||||
sub RandomTimer_setActive($$) {
|
||||
my ($hash, $value) = @_;
|
||||
$hash->{helper}{active} = $value;
|
||||
my $trigger = (RandomTimer_isDisabled($hash)) ? 0 : 1;
|
||||
readingsSingleUpdate ($hash, "active", $value, $trigger);
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_isAktive ($) {
|
||||
my ($hash) = @_;
|
||||
return defined ($hash->{helper}{active}) ? $hash->{helper}{active} : 0;
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_down($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{COMMAND} = AttrVal($hash->{NAME}, "keepDeviceAlive", 0) ? "on" : "off";
|
||||
RandomTimer_device_switch($hash);
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_setState($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
@ -265,25 +356,7 @@ sub RandomTimer_setState($) {
|
||||
}
|
||||
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_Attr($$$) {
|
||||
my ($cmd, $name, $attrName, $attrVal) = @_;
|
||||
|
||||
my $hash = $defs{$name};
|
||||
|
||||
if( $attrName ~~ ["switchmode"] ) {
|
||||
RandomTimer_setSwitchmode($hash, $attrVal);
|
||||
}
|
||||
|
||||
if( $attrName ~~ ["disable","disableCond"] ) {
|
||||
|
||||
# Schaltung vorziehen, damit bei einem disable abgeschaltet wird.
|
||||
myRemoveInternalTimer("Exec", $hash);
|
||||
myInternalTimer ("Exec", time()+1, "RandomTimer_Exec", $hash, 0);
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_setSwitchmode ($$) {
|
||||
|
||||
my ($hash, $attrVal) = @_;
|
||||
@ -300,52 +373,37 @@ sub RandomTimer_setSwitchmode ($$) {
|
||||
$attr{$hash->{NAME}}{switchmode} = $attrVal;
|
||||
}
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_getSecsToNextAbschaltTest($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $intervall = $hash->{helper}{TIMETOSWITCH};
|
||||
|
||||
my $proz = 10;
|
||||
my $delta = $intervall * $proz/100;
|
||||
my $nextSecs = $intervall - $delta/2 + int(rand($delta));
|
||||
sub RandomTimer_SetTimer($) {
|
||||
my ($myHash) = @_;
|
||||
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
|
||||
return if (!defined($hash));
|
||||
|
||||
return $nextSecs;
|
||||
my $now = time();
|
||||
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($now);
|
||||
|
||||
RandomTimer_setActive($hash, 0);
|
||||
RandomTimer_schaltZeitenErmitteln($hash, $now);
|
||||
RandomTimer_setState($hash);
|
||||
|
||||
Log3 $hash, 4, "[".$hash->{NAME}."]" . " timings RandomTimer on $hash->{DEVICE}: "
|
||||
. strftime("%H:%M:%S(%d)",localtime($hash->{helper}{startTime})) . " - "
|
||||
. strftime("%H:%M:%S(%d)",localtime($hash->{helper}{stopTime}));
|
||||
|
||||
my $secToMidnight = 24*3600 -(3600*$hour + 60*$min + $sec);
|
||||
|
||||
my $setExecTime = max($now, $hash->{helper}{startTime});
|
||||
myRemoveInternalTimer("Exec", $hash);
|
||||
myInternalTimer ("Exec", $setExecTime, "RandomTimer_Exec", $hash, 0);
|
||||
|
||||
if ($hash->{helper}{REP} gt "") {
|
||||
my $setTimerTime = max($now+$secToMidnight + 15,
|
||||
$hash->{helper}{stopTime}) + $hash->{helper}{TIMETOSWITCH}+15;
|
||||
myRemoveInternalTimer("SetTimer", $hash);
|
||||
myInternalTimer ("SetTimer", $setTimerTime, "RandomTimer_SetTimer", $hash, 0);
|
||||
}
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_schaltZeitenErmitteln ($$) {
|
||||
my ($hash,$now) = @_;
|
||||
|
||||
RandomTimer_startZeitErmitteln($hash, $now);
|
||||
RandomTimer_stopZeitErmitteln ($hash, $now);
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate ($hash, "Startzeit", FmtDateTime($hash->{helper}{startTime}));
|
||||
readingsBulkUpdate ($hash, "Stoppzeit", FmtDateTime($hash->{helper}{stopTime}));
|
||||
readingsEndUpdate ($hash, defined($hash->{LOCAL} ? 0 : 1));
|
||||
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_zeitBerechnen ($$$$) {
|
||||
my ($now, $hour, $min, $sec) = @_;
|
||||
|
||||
my @jetzt_arr = localtime($now);
|
||||
#Stunden Minuten Sekunden
|
||||
$jetzt_arr[2] = $hour; $jetzt_arr[1] = $min; $jetzt_arr[0] = $sec;
|
||||
my $next = timelocal_nocheck(@jetzt_arr);
|
||||
return $next;
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_addDays ($$) {
|
||||
my ($now, $days) = @_;
|
||||
|
||||
my @jetzt_arr = localtime($now);
|
||||
$jetzt_arr[3] += $days;
|
||||
my $next = timelocal_nocheck(@jetzt_arr);
|
||||
return $next;
|
||||
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_startZeitErmitteln ($$) {
|
||||
my ($hash,$now) = @_;
|
||||
|
||||
@ -367,7 +425,12 @@ sub RandomTimer_startZeitErmitteln ($$) {
|
||||
$hash->{helper}{startTime} = $startTime;
|
||||
$hash->{helper}{STARTTIME} = strftime("%d.%m.%Y %H:%M:%S",localtime($startTime));
|
||||
}
|
||||
########################################################################
|
||||
|
||||
sub RandomTimer_stopTimeReached($) {
|
||||
my ($hash) = @_;
|
||||
return ( time()>$hash->{helper}{stopTime} );
|
||||
}
|
||||
|
||||
sub RandomTimer_stopZeitErmitteln ($$) {
|
||||
my ($hash,$now) = @_;
|
||||
|
||||
@ -396,66 +459,7 @@ sub RandomTimer_stopZeitErmitteln ($$) {
|
||||
$hash->{helper}{STOPTIME} = strftime("%d.%m.%Y %H:%M:%S",localtime($stopTime));
|
||||
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_device_toggle ($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
my $status = Value($hash->{DEVICE});
|
||||
if ($status ne "on" && $status ne "off" ) {
|
||||
Log3 $hash, 3, "[".$hash->{NAME}."]"." result of function Value($hash->{DEVICE}) must be 'on' or 'off'";
|
||||
}
|
||||
|
||||
my $sigma = ($status eq "on")
|
||||
? $hash->{helper}{SIGMAWHENON}
|
||||
: $hash->{helper}{SIGMAWHENOFF};
|
||||
|
||||
my $zufall = int(rand(1000));
|
||||
Log3 $hash, 4, "[".$hash->{NAME}."]"." IstZustand:$status sigmaWhen-$status:$sigma random:$zufall<$sigma=>" . (($zufall < $sigma)?"true":"false");
|
||||
|
||||
if ($zufall < $sigma ) {
|
||||
$hash->{COMMAND} = ($status eq "on") ? "off" : "on";
|
||||
RandomTimer_device_switch($hash);
|
||||
}
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_device_switch ($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
my $command = "set @ $hash->{COMMAND}";
|
||||
if ($hash->{COMMAND} eq "on") {
|
||||
$command = AttrVal($hash->{NAME}, "onCmd", $command);
|
||||
} else {
|
||||
$command = AttrVal($hash->{NAME}, "offCmd", $command);
|
||||
}
|
||||
$command =~ s/@/$hash->{DEVICE}/g;
|
||||
$command = SemicolonEscape($command);
|
||||
Log3 $hash, 4, "[".$hash->{NAME}. "]"." command: $command";
|
||||
|
||||
my $ret = AnalyzeCommandChain(undef, $command);
|
||||
Log3 ($hash, 3, "[$hash->{NAME}] ERROR: " . $ret . " SENDING " . $command) if($ret);
|
||||
#Log3 $hash, 3, "[$hash->{NAME}] Value($hash->{COMMAND})=".Value($hash->{DEVICE});
|
||||
#$hash->{"$hash->{COMMAND}Value"} = Value($hash->{DEVICE});
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_isDisabled($) {
|
||||
my ($hash) = @_;
|
||||
|
||||
my $disable = AttrVal($hash->{NAME}, "disable", 0 );
|
||||
return $disable if($disable);
|
||||
|
||||
my $disableCond = AttrVal($hash->{NAME}, "disableCond", "nf" );
|
||||
if ($disableCond eq "nf") {
|
||||
return 0;
|
||||
} else {
|
||||
$disable = eval ($disableCond);
|
||||
if ($@) {
|
||||
$@ =~ s/\n/ /g;
|
||||
Log3 ($hash, 3, "[$hash->{NAME}] ERROR: " . $@ . " EVALUATING " . $disableCond);
|
||||
}
|
||||
return $disable;
|
||||
}
|
||||
}
|
||||
########################################################################
|
||||
sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
|
||||
|
||||
foreach my $hc ( sort keys %{$modules{RandomTimer}{defptr}} ) {
|
||||
@ -468,150 +472,163 @@ sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
|
||||
Log3 undef, 3, "RandomTimer_Wakeup() done!";
|
||||
}
|
||||
|
||||
sub RandomTimer_zeitBerechnen ($$$$) {
|
||||
my ($now, $hour, $min, $sec) = @_;
|
||||
|
||||
my @jetzt_arr = localtime($now);
|
||||
#Stunden Minuten Sekunden
|
||||
$jetzt_arr[2] = $hour; $jetzt_arr[1] = $min; $jetzt_arr[0] = $sec;
|
||||
my $next = timelocal_nocheck(@jetzt_arr);
|
||||
return $next;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
# commandref ##################################################################
|
||||
=pod
|
||||
=item device
|
||||
=item helper
|
||||
=item summary imitates the random switch functionality of a timer clock (FS20 ZSU)
|
||||
=item summary_DE bildet die Zufallsfunktion einer Zeitschaltuhr nach
|
||||
|
||||
=begin html
|
||||
|
||||
<a name="RandomTimer"></a>
|
||||
<h1>RandomTimer</h1>
|
||||
<h2>Define</h2>
|
||||
<ul>
|
||||
<code><font size="+2">define <name> RandomTimer <timespec_start> <device> <timespec_stop> [<timeToSwitch>]</font></code><br>
|
||||
<br>
|
||||
Defines a device, that imitates the random switch functionality of a timer clock, like a <b>FS20 ZSU</b>.
|
||||
The idea to create it, came from the problem, that is was always a little bit tricky to install a timer clock before
|
||||
holiday: finding the manual, testing it the days before and three different timer clocks with three different manuals - a horror.<br>
|
||||
By using it in conjunction with a dummy and a <a href="#disableCond">disableCond</a>, I'm able to switch the always defined timer on every weekend easily from all over the world.
|
||||
<br><br>
|
||||
<h3>Descrition</h3>
|
||||
a RandomTimer device starts at timespec_start switching device. Every (timeToSwitch
|
||||
seconds +-10%) it trys to switch device on/off. The switching period stops when the
|
||||
next time to switch is greater than timespec_stop.
|
||||
<br><br>
|
||||
</ul>
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<b>timespec_start</b>
|
||||
<br>
|
||||
The parameter <b>timespec_start</b> defines the start time of the timer with format: HH:MM:SS.
|
||||
It can be a Perlfunction as known from the <a href="#at">at</a> timespec .
|
||||
<br><br>
|
||||
<b>device</b>
|
||||
<br>
|
||||
The parameter <b>device</b> defines the fhem device that should be switched.
|
||||
<br><br>
|
||||
<b>timespec_stop</b>
|
||||
<br>
|
||||
The parameter <b>timespec_stop</b> defines the stop time of the timer with format: HH:MM:SS.
|
||||
It can be a Perlfunction as known from the timespec <a href="#at">at</a> .
|
||||
<br><br>
|
||||
<b>timeToSwitch</b>
|
||||
<br>
|
||||
The parameter <b>timeToSwitch</b> defines the time in seconds between two on/off switches.
|
||||
<br><br>
|
||||
</ul>
|
||||
<h3>Examples</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<code>define ZufallsTimerTisch RandomTimer *{sunset_abs()} StehlampeTisch +03:00:00 500</code><br>
|
||||
defines a timer that starts at sunset an ends 3 hous later. The timer trys to switch every 500 seconds(+-10%).
|
||||
</li><br><br>
|
||||
<li>
|
||||
<code>define ZufallsTimerTisch RandomTimer *{sunset_abs()} StehlampeTisch *{sunset_abs(3*3600)} 480</code><br>
|
||||
defines a timer that starts at sunset and stops after sunset + 3 hours. The timer trys to switch every 480 seconds(+-10%).
|
||||
</li><br><br>
|
||||
<li>
|
||||
<code>define ZufallsTimerTisch RandomTimer *{sunset_abs()} StehlampeTisch 22:30:00 300</code><br>
|
||||
defines a timer that starts at sunset an ends at 22:30. The timer trys to switch every 300 seconds(+-10%).
|
||||
</li><br><br>
|
||||
</ul>
|
||||
|
||||
<!-- -------------------------------------------------------------------------- -->
|
||||
<!-- Set ------------------------------------------------------------------ -->
|
||||
<!-- -------------------------------------------------------------------------- -->
|
||||
<a name="RandomTimerSet"></a>
|
||||
<h3>Set</h3>
|
||||
<h3>RandomTimer</h3>
|
||||
<div>
|
||||
<ul>
|
||||
N/A
|
||||
<a name="RandomTimerdefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>
|
||||
define <name> RandomTimer <timespec_start> <device> <timespec_stop> [<timeToSwitch>]
|
||||
</code>
|
||||
<br>
|
||||
Defines a device, that imitates the random switch functionality of a timer clock, like a <b>FS20 ZSU</b>. The idea to create it, came from the problem, that is was always a little bit tricky to install a timer clock before holiday: finding the manual, testing it the days before and three different timer clocks with three different manuals - a horror.<br>
|
||||
By using it in conjunction with a dummy and a disableCond, I'm able to switch the always defined timer on every weekend easily from all over the world.<br>
|
||||
<br>
|
||||
<b>Descrition</b>
|
||||
<ul>
|
||||
a RandomTimer device starts at timespec_start switching device. Every (timeToSwitch seconds +-10%) it trys to switch device on/off. The switching period stops when the next time to switch is greater than timespec_stop.
|
||||
</ul>
|
||||
<br>
|
||||
<b>Parameter</b>
|
||||
<ul>
|
||||
<li>
|
||||
<code>timespec_start</code><br>
|
||||
The parameter <b>timespec_start</b> defines the start time of the timer with format: HH:MM:SS. It can be a Perlfunction as known from the <a href="#at">at</a> timespec.
|
||||
</li><br>
|
||||
<li>
|
||||
<code>device</code><br>
|
||||
The parameter <b>device</b> defines the fhem device that should be switched.
|
||||
</li><br>
|
||||
<li>
|
||||
<code>timespec_stop</code><br>
|
||||
The parameter <b>timespec_stop</b> defines the stop time of the timer with format: HH:MM:SS. It can be a Perlfunction as known from the timespec <a href="#at">at</a>.
|
||||
</li><br>
|
||||
<li>
|
||||
<code>timeToSwitch</code><br>
|
||||
The parameter <b>timeToSwitch</b> defines the time in seconds between two on/off switches.
|
||||
</li>
|
||||
</ul>
|
||||
<br>
|
||||
<b>Examples</b>
|
||||
<ul>
|
||||
<li>
|
||||
<code>
|
||||
define ZufallsTimerTisch RandomTimer *{sunset_abs()} StehlampeTisch +03:00:00 500
|
||||
</code><br>
|
||||
defines a timer that starts at sunset an ends 3 hous later. The timer trys to switch every 500 seconds(+-10%).
|
||||
</li><br>
|
||||
<li>
|
||||
<code>
|
||||
define ZufallsTimerTisch RandomTimer *{sunset_abs()} StehlampeTisch *{sunset_abs(3*3600)} 480
|
||||
</code><br>
|
||||
defines a timer that starts at sunset and stops after sunset + 3 hours. The timer trys to switch every 480 seconds(+-10%).
|
||||
</li><br>
|
||||
<li>
|
||||
<code>
|
||||
define ZufallsTimerTisch RandomTimer *{sunset_abs()} StehlampeTisch 22:30:00 300
|
||||
</code><br>
|
||||
defines a timer that starts at sunset an ends at 22:30. The timer trys to switch every 300 seconds(+-10%).
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
<a name="RandomTimerAttributes"></a>
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
<li>
|
||||
<code>disableCond</code><br>
|
||||
The default behavior of a RandomTimer is, that it works. To set the Randomtimer out of work, you can specify in the disableCond attibute a condition in perlcode that must evaluate to true. The Condition must be put into round brackets. The best way is to define a function in 99_utils.<br>
|
||||
<br>
|
||||
<b>Examples</b>
|
||||
<ul>
|
||||
<li><code>
|
||||
attr ZufallsTimerZ disableCond (!isVerreist())
|
||||
</code></li>
|
||||
<li><code>
|
||||
attr ZufallsTimerZ disableCond (Value("presenceDummy") eq "present")
|
||||
</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<code>keepDeviceAlive</code><br>
|
||||
The default behavior of a RandomTimer is, that it shuts down the device after stoptime is reached. The <b>keepDeviceAlive</b> attribute changes the behavior. If set, the device status is not changed when the stoptime is reached.<br>
|
||||
<br>
|
||||
<b>Examples</b>
|
||||
<ul>
|
||||
<li><code>attr ZufallsTimerZ keepDeviceAlive</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<code>onCmd, offCmd</code><br>
|
||||
Setting the on-/offCmd changes the command sent to the device. Standard is: "set <device> on". The device can be specified by a @.<br>
|
||||
<br>
|
||||
<b>Examples</b>
|
||||
<ul>
|
||||
<li><code>
|
||||
attr Timer oncmd {fhem("set @ on-for-timer 14")}
|
||||
</code></li>
|
||||
<li><code>
|
||||
attr Timer offCmd {fhem("set @ off 16")}
|
||||
</code></li>
|
||||
<li><code>
|
||||
attr Timer oncmd set @ on-for-timer 12
|
||||
</code></li>
|
||||
<li><code>
|
||||
attr Timer offCmd set @ off 12
|
||||
</code></li>
|
||||
</ul>
|
||||
the decision to switch on or off depends on the state of the device and is evaluated by the funktion Value(<device>). Value() must evaluate one of the values "on" or "off". The behavior of devices that do not evaluate one of those values can be corrected by defining a stateFormat:<br>
|
||||
<code>
|
||||
attr stateFormat EDIPlug_01 {(ReadingsVal("EDIPlug_01","state","nF") =~ m/(ON|on)/i) ? "on" : "off" }
|
||||
</code><br>
|
||||
if a devices Value() funktion does not evalute to on or off(like WLAN-Steckdose von Edimax) you get the message:<br>
|
||||
<code>
|
||||
[EDIPlug] result of function Value(EDIPlug_01) must be 'on' or 'off'
|
||||
</code>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<a href="#readingFnAttributes">
|
||||
<u><code>readingFnAttributes</code></u>
|
||||
</a>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<code>switchmode</code><br>
|
||||
Setting the switchmode you can influence the behavior of switching on/off. The parameter has the Format 999/999 and the default ist 800/200. The values are in "per mill". The first parameter sets the value of the probability that the device will be switched on when the device is off. The second parameter sets the value of the probability that the device will be switched off when the device is off.<br>
|
||||
<br>
|
||||
<b>Examples</b>
|
||||
<ul>
|
||||
<li><code>attr ZufallsTimerZ switchmode 400/400</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
<!-- ----------------------------- -->
|
||||
<!-- Get ------------------------- -->
|
||||
<!-- Get ------------------------------------------------------------------ -->
|
||||
<!-- -------------------------------------------------------------------------- -->
|
||||
<a name="RandomTimerGet"></a>
|
||||
<h3>Get</h3>
|
||||
<ul>
|
||||
N/A
|
||||
</ul>
|
||||
<!-- -------------------------------------------------------------------------- -->
|
||||
<!-- Attributes --------------------------------------------------------------- -->
|
||||
<!-- -------------------------------------------------------------------------- -->
|
||||
<a name="RandomTimerAttributes"></a>
|
||||
<h3>Attributes</h3>
|
||||
<ul>
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
|
||||
<li><a name="disableCond">disableCond</a><br>
|
||||
The default behavior of a RandomTimer is, that it works.
|
||||
To set the Randomtimer out of work, you can specify in the disableCond attibute a condition in perlcode that must evaluate to true.
|
||||
The Condition must be put into round brackets. The best way is to define
|
||||
a function in 99_utils.
|
||||
<br>
|
||||
<b>Examples</b>
|
||||
<pre>
|
||||
attr ZufallsTimerZ disableCond (!isVerreist())
|
||||
attr ZufallsTimerZ disableCond (Value("presenceDummy") ne "present")
|
||||
</pre>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<li><a name="keepDeviceAlive">keepDeviceAlive</a><br>
|
||||
The default behavior of a RandomTimer is, that it shuts down the device after stoptime is reached.
|
||||
The <b>keepDeviceAlive</b> attribute changes the behavior. If set, the device status is not changed when the stoptime is reached.
|
||||
<br>
|
||||
<b>Example</b>
|
||||
<pre>
|
||||
attr ZufallsTimerZ keepDeviceAlive
|
||||
</pre>
|
||||
</li>
|
||||
|
||||
<li><a name="onOffCmd">onCmd, offCmd</a><br>
|
||||
Setting the on-/offCmd changes the command sent to the device. Standard is: "set <device> on".
|
||||
The device can be specified by a @.
|
||||
<br>
|
||||
<b>Examples</b>
|
||||
<pre>
|
||||
attr Timer oncmd {fhem("set @ on-for-timer 14")}
|
||||
attr Timer offCmd {fhem("set @ off 16")}
|
||||
attr Timer oncmd set @ on-for-timer 12
|
||||
attr Timer offCmd set @ off 12
|
||||
</pre>
|
||||
</li>
|
||||
|
||||
the decision to switch on or off depends on the state of the device and is evaluated by the funktion Value(<device>). Value() must
|
||||
evaluate one of the values "on" or "off". The behavior of devices that do not evaluate one of those values can be corrected by defining a statFormat:
|
||||
<pre>
|
||||
attr stateFormat EDIPlug_01 {(ReadingsVal("EDIPlug_01","state","nF") =~ m/(ON|on)/i) ? "on" : "off" }
|
||||
</pre>
|
||||
if a devices Value() funktion does not evalute to on or off(like WLAN-Steckdose von Edimax) you get the message:
|
||||
<pre>
|
||||
[EDIPlug] result of function Value(EDIPlug_01) must be 'on' or 'off'
|
||||
</pre>
|
||||
|
||||
|
||||
<li><a name="switchmode">switchmode</a><br>
|
||||
Setting the switchmode you can influence the behavior of switching on/off.
|
||||
The parameter has the Format 999/999 and the default ist 800/200. The values are in "per mill".
|
||||
The first parameter sets the value of the probability that the device will be switched on when the device is off.
|
||||
The second parameter sets the value of the probability that the device will be switched off when the device is off.
|
||||
<b>Examples</b>
|
||||
<pre>
|
||||
attr ZufallsTimerZ switchmode 400/400
|
||||
</pre>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
=end html
|
||||
=cut
|
||||
|
Loading…
x
Reference in New Issue
Block a user