mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-20 01:06:04 +00:00
Heating_Control
- some changes to deal with summertime - bugfix in SetAlltemps() Random_Timer - a big new Version - a new method to deal with InternalTimer WeekdayTimer_Define - some minor changes git-svn-id: https://svn.fhem.de/fhem/trunk@5555 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
c2ae236304
commit
1dea0d333c
@ -106,7 +106,7 @@ sub Heating_Control_Define($$)
|
|||||||
$language = $hash->{LANGUAGE};
|
$language = $hash->{LANGUAGE};
|
||||||
|
|
||||||
# test if device is defined
|
# test if device is defined
|
||||||
# return "invalid Device, given Device <$device> not found" if(!$defs{$device});
|
Log3 $hash, 3, "[$name] invalid device, <$device> not found" if(!$defs{$device});
|
||||||
|
|
||||||
#fuer den modify Altlasten bereinigen
|
#fuer den modify Altlasten bereinigen
|
||||||
delete($hash->{TIME_AS_PERL}) if($hash->{TIME_AS_PERL});
|
delete($hash->{TIME_AS_PERL}) if($hash->{TIME_AS_PERL});
|
||||||
@ -301,7 +301,8 @@ sub Heating_Control_UpdatePerlTime_TimerSet($) {
|
|||||||
################################################################################
|
################################################################################
|
||||||
sub Heating_Control_UpdatePerlTime($) {
|
sub Heating_Control_UpdatePerlTime($) {
|
||||||
my ($myHash) = @_;
|
my ($myHash) = @_;
|
||||||
my $hash = $myHash->{HASH};
|
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
|
||||||
|
return if (!defined($hash));
|
||||||
|
|
||||||
if (defined($hash->{TIME_AS_PERL})) {
|
if (defined($hash->{TIME_AS_PERL})) {
|
||||||
$hash->{PERLTIMEUPDATEMODE} = 1;
|
$hash->{PERLTIMEUPDATEMODE} = 1;
|
||||||
@ -311,13 +312,14 @@ sub Heating_Control_UpdatePerlTime($) {
|
|||||||
########################################################################
|
########################################################################
|
||||||
sub Heating_Control_Update($) {
|
sub Heating_Control_Update($) {
|
||||||
my ($myHash) = @_;
|
my ($myHash) = @_;
|
||||||
my $hash = $myHash->{HASH};
|
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
|
||||||
|
return if (!defined($hash));
|
||||||
|
|
||||||
my $mod = "[".$hash->{NAME} ."] "; ###
|
my $mod = "[".$hash->{NAME} ."] "; ###
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $now = time() + 5; # garantiert > als die eingestellte Schlatzeit
|
my $now = time() + 5; # garantiert > als die eingestellte Schlatzeit
|
||||||
|
|
||||||
# Fenserkontakte abfragen - wenn einer im Status closed, dann Schaltung um 60 Sekunden verzögern
|
# Fenserkontakte abfragen - wenn einer im Status closed, dann Schaltung um 60 Sekunden verzögern
|
||||||
if (Heating_Control_FensterOffen($hash)) {
|
if (Heating_Control_FensterOffen($hash)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -383,7 +385,8 @@ sub Heating_Control_FensterOffen ($) {
|
|||||||
if (!defined($hash->{VERZOEGRUNG})) {
|
if (!defined($hash->{VERZOEGRUNG})) {
|
||||||
Log3 $hash, 3, "$mod switch of $hash->{DEVICE} delayed - windowsensor '$fk' Reading '$reading' is '$windowStatus'";
|
Log3 $hash, 3, "$mod switch of $hash->{DEVICE} delayed - windowsensor '$fk' Reading '$reading' is '$windowStatus'";
|
||||||
}
|
}
|
||||||
InternalTimer (time()+60, "$hash->{TYPE}_Update", $hash, 0);
|
myRemoveInternalTimer("Update", $hash);
|
||||||
|
myInternalTimer ("Update", time()+60, "$hash->{TYPE}_Update", $hash, 0);
|
||||||
$hash->{VERZOEGRUNG} = 1;
|
$hash->{VERZOEGRUNG} = 1;
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@ -406,7 +409,7 @@ sub Heating_Control_akt_next_param($$) {
|
|||||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($now);
|
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($now);
|
||||||
|
|
||||||
my ($nextParam, $next, $nextSwitch, $nowSwitch, $newParam) = (0,0,0,0,0);
|
my ($nextParam, $next, $nextSwitch, $nowSwitch, $newParam) = (0,0,0,0,0);
|
||||||
# aktuellen und nächsten Schaltzeitpunkt ermitteln.
|
# aktuellen und nächsten Schaltzeitpunkt ermitteln.
|
||||||
my $startIdx;
|
my $startIdx;
|
||||||
for (my $d=-1; $d>=-7; $d--) {
|
for (my $d=-1; $d>=-7; $d--) {
|
||||||
my $wd = ($d+$wday) % 7;
|
my $wd = ($d+$wday) % 7;
|
||||||
@ -423,8 +426,9 @@ sub Heating_Control_akt_next_param($$) {
|
|||||||
|
|
||||||
# Tagediff + Sekunden des Tages addieren
|
# Tagediff + Sekunden des Tages addieren
|
||||||
my @t = split(/:/, $st); # HH MM SS
|
my @t = split(/:/, $st); # HH MM SS
|
||||||
my $secondsToSwitch = $d*24*3600 + 3600*($t[0] - $hour) + 60*($t[1] - $min) + $t[2] - $sec;
|
#my $secondsToSwitch = $d*24*3600 + 3600*($t[0] - $hour) + 60*($t[1] - $min) + $t[2] - $sec;
|
||||||
my $next = $now + $secondsToSwitch;
|
my $next = zeitErmitteln ($now, $t[0], $t[1], $t[2], $d);
|
||||||
|
my $secondsToSwitch = $next - $now;
|
||||||
|
|
||||||
if ($secondsToSwitch<=10 && $secondsToSwitch>=-20) {
|
if ($secondsToSwitch<=10 && $secondsToSwitch>=-20) {
|
||||||
Log3 $hash, 4, $mod."Jetzt:".strftime('%d.%m.%Y %H:%M:%S',localtime($now))." -> Next: ".strftime('%d.%m.%Y %H:%M:%S',localtime($next))." -> Param: $hash->{helper}{SWITCHINGTIME}{$wd}{$st} ".$secondsToSwitch;
|
Log3 $hash, 4, $mod."Jetzt:".strftime('%d.%m.%Y %H:%M:%S',localtime($now))." -> Next: ".strftime('%d.%m.%Y %H:%M:%S',localtime($next))." -> Param: $hash->{helper}{SWITCHINGTIME}{$wd}{$st} ".$secondsToSwitch;
|
||||||
@ -443,7 +447,10 @@ sub Heating_Control_akt_next_param($$) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$nextSwitch += Heating_Control_DSTOffset($hash, $now, $nextSwitch);
|
if ($now > $nextSwitch) {
|
||||||
|
$nextSwitch = max ($now+60,$nextSwitch);
|
||||||
|
Log 3, "nextSwitch-+60----------->" . strftime("%d.%m.%Y %H:%M:%S",localtime($nextSwitch));
|
||||||
|
}
|
||||||
return ($nowSwitch,$nextSwitch,$newParam,$nextParam);
|
return ($nowSwitch,$nextSwitch,$newParam,$nextParam);
|
||||||
}
|
}
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -474,7 +481,7 @@ sub Heating_Control_Device_Schalten($$$$) {
|
|||||||
my $disabled_txt = $disabled ? " " : " not";
|
my $disabled_txt = $disabled ? " " : " not";
|
||||||
Log3 $hash, 4, $mod . "is$disabled_txt disabled";
|
Log3 $hash, 4, $mod . "is$disabled_txt disabled";
|
||||||
|
|
||||||
#Kommando ausführen
|
#Kommando ausführen
|
||||||
my $secondsSinceSwitch = $nowSwitch - $now;
|
my $secondsSinceSwitch = $nowSwitch - $now;
|
||||||
|
|
||||||
if ($hash->{PERLTIMEUPDATEMODE} == 1) {
|
if ($hash->{PERLTIMEUPDATEMODE} == 1) {
|
||||||
@ -484,11 +491,11 @@ sub Heating_Control_Device_Schalten($$$$) {
|
|||||||
|
|
||||||
if (defined $hash->{helper}{COMMAND} || ($nowSwitch gt "" && $aktParam ne $newParam )) {
|
if (defined $hash->{helper}{COMMAND} || ($nowSwitch gt "" && $aktParam ne $newParam )) {
|
||||||
if (!$setModifier && $secondsSinceSwitch < -60) {
|
if (!$setModifier && $secondsSinceSwitch < -60) {
|
||||||
Log3 $hash, 5, $mod."no switch in the yesterdays because of the devices type($defs{$hash->{DEVICE}}->{NAME} is not a heating).";
|
Log3 $hash, 5, $mod."no switch in the yesterdays because of the devices type($hash->{DEVICE}is not a heating).";
|
||||||
} else {
|
} else {
|
||||||
if ($command && !$disabled) {
|
if ($command && !$disabled) {
|
||||||
$newParam =~ s/:/ /g;
|
$newParam =~ s/:/ /g;
|
||||||
#$command =~ s/@/$hash->{DEVICE}/g; # übernimmt EvalSpecials()
|
#$command =~ s/@/$hash->{DEVICE}/g; # übernimmt EvalSpecials()
|
||||||
#$command =~ s/%/$newParam/g; #
|
#$command =~ s/%/$newParam/g; #
|
||||||
|
|
||||||
$command = SemicolonEscape($command);
|
$command = SemicolonEscape($command);
|
||||||
@ -524,6 +531,8 @@ sub isHeizung($) {
|
|||||||
|
|
||||||
my $dHash = $defs{$hash->{DEVICE}}; ###
|
my $dHash = $defs{$hash->{DEVICE}}; ###
|
||||||
my $dType = $dHash->{TYPE};
|
my $dType = $dHash->{TYPE};
|
||||||
|
return "" if (!defined($dType));
|
||||||
|
|
||||||
my $setModifier = $setmodifiers{$dType};
|
my $setModifier = $setmodifiers{$dType};
|
||||||
$setModifier = "" if (!defined($setModifier));
|
$setModifier = "" if (!defined($setModifier));
|
||||||
if (ref($setModifier)) {
|
if (ref($setModifier)) {
|
||||||
@ -556,40 +565,23 @@ sub Heating_Control_SetAllTemps() { # {Heating_Control_SetAllTemps()}
|
|||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Heating_Control_Update($hash);
|
|
||||||
|
my $myHash->{HASH}=$hash;
|
||||||
|
Heating_Control_Update($myHash);
|
||||||
Log3 undef, 3, "Heating_Control_Update() for $hash->{NAME} done!";
|
Log3 undef, 3, "Heating_Control_Update() for $hash->{NAME} done!";
|
||||||
}
|
}
|
||||||
Log3 undef, 3, "Heating_Control_SetAllTemps() done!";
|
Log3 undef, 3, "Heating_Control_SetAllTemps() done!";
|
||||||
}
|
}
|
||||||
########################################################################
|
########################################################################
|
||||||
sub Heating_Control_DSTOffset($$$) {
|
sub zeitErmitteln ($$$$$) {
|
||||||
my ($hash,$t1,$t2)= @_;
|
my ($now, $hour, $min, $sec, $days) = @_;
|
||||||
|
|
||||||
my @lt1 = localtime($t1);
|
my @jetzt_arr = localtime($now);
|
||||||
my @lt2 = localtime($t2);
|
#Stunden Minuten Sekunden
|
||||||
|
$jetzt_arr[2] = $hour; $jetzt_arr[1] = $min; $jetzt_arr[0] = $sec;
|
||||||
my $offset =0;
|
$jetzt_arr[3] += $days;
|
||||||
return $offset if ($lt1[8] == $lt2[8]);
|
my $next = timelocal_nocheck(@jetzt_arr);
|
||||||
|
return $next;
|
||||||
if ($lt1[8] == 0 && $lt2[8] == 1 ) {
|
|
||||||
my $daylightSavingTime = monatsLetzerSonntag (timelocal_nocheck(0,0,2,31,2,$lt2[5])); # Maerz
|
|
||||||
$offset = -min(($t2 - $daylightSavingTime),3600);
|
|
||||||
} else {
|
|
||||||
#my $daylightSavingTime = monatsLetzerSonntag (timelocal_nocheck(0,0,2,30,9,$lt2[5])); # Oktober
|
|
||||||
$offset = 3600;
|
|
||||||
}
|
|
||||||
Log3 $hash, 4, "[$hash->{NAME}] correction daylightSavingtime $offset seconds";
|
|
||||||
return $offset;
|
|
||||||
}
|
|
||||||
########################################################################
|
|
||||||
sub monatsLetzerSonntag ($) {
|
|
||||||
my ($monatsLetzer)= @_;
|
|
||||||
|
|
||||||
my @lmonatsLetzer = localtime($monatsLetzer);
|
|
||||||
my $daysSiceLastSunday = $lmonatsLetzer[6]; # Tage seit Sonntag
|
|
||||||
my $monatsLetzerSunday = $monatsLetzer -$daysSiceLastSunday*24*3600+3600; # letzen Oktobersonntag ermittlen.
|
|
||||||
|
|
||||||
return $monatsLetzerSunday
|
|
||||||
}
|
}
|
||||||
########################################################################
|
########################################################################
|
||||||
sub SortNumber {
|
sub SortNumber {
|
||||||
@ -655,7 +647,6 @@ sub SortNumber {
|
|||||||
by well-known Block with {}.<br>
|
by well-known Block with {}.<br>
|
||||||
Note: if a command is defined only this command are executed. In case of executing
|
Note: if a command is defined only this command are executed. In case of executing
|
||||||
a "set desired-temp" command, you must define it explicitly.<br>
|
a "set desired-temp" command, you must define it explicitly.<br>
|
||||||
|
|
||||||
The following parameter are replaced:<br>
|
The following parameter are replaced:<br>
|
||||||
<ol>
|
<ol>
|
||||||
<li>@ => the device to switch</li>
|
<li>@ => the device to switch</li>
|
||||||
@ -690,7 +681,7 @@ sub SortNumber {
|
|||||||
|
|
||||||
If you want to have set all Heating_Controls their current value (after a temperature lowering phase holidays)
|
If you want to have set all Heating_Controls their current value (after a temperature lowering phase holidays)
|
||||||
you can call the function <b> Heating_Control_SetAllTemps ()</b>.
|
you can call the function <b> Heating_Control_SetAllTemps ()</b>.
|
||||||
This call can be automatically coupled to a dummy by notify:
|
This call can be automatically coupled to a dummy by notify:
|
||||||
<code>define HeizStatus2 notify Heating:. * {Heating_Control_SetAllTemps ()}</code>
|
<code>define HeizStatus2 notify Heating:. * {Heating_Control_SetAllTemps ()}</code>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -19,11 +19,6 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
# define t1 RandomTimer *23:01:10 Zirkulation 23:02:10 100; attr t1 verbose 5;
|
|
||||||
# define t2 RandomTimer *23:01:20 Zirkulation 23:03:20 100; attr t2 verbose 5;
|
|
||||||
# define t3 RandomTimer *23:01:30 Zirkulation 23:04:30 100; attr t3 verbose 5;
|
|
||||||
# define t4 RandomTimer *23:01:40 Zirkulation 23:02:40 100; attr t4 verbose 5;
|
|
||||||
#
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# 10.09.2013 Svenson : disable direct if attribute changed, add state disabled;
|
# 10.09.2013 Svenson : disable direct if attribute changed, add state disabled;
|
||||||
# randomtimer run every day if attribut runonce 0 (default is 1)
|
# randomtimer run every day if attribut runonce 0 (default is 1)
|
||||||
@ -36,6 +31,9 @@ use warnings;
|
|||||||
use IO::Socket;
|
use IO::Socket;
|
||||||
use Time::HiRes qw(gettimeofday);
|
use Time::HiRes qw(gettimeofday);
|
||||||
|
|
||||||
|
sub RandomTimer_stopTimeReached($);
|
||||||
|
sub schaltZeitenErmitteln ($$);
|
||||||
|
|
||||||
sub RandomTimer_Initialize($)
|
sub RandomTimer_Initialize($)
|
||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
@ -46,20 +44,17 @@ sub RandomTimer_Initialize($)
|
|||||||
$hash->{AttrList} = "onCmd offCmd switchmode disable:0,1 disableCond runonce:0,1 keepDeviceAlive ".
|
$hash->{AttrList} = "onCmd offCmd switchmode disable:0,1 disableCond runonce:0,1 keepDeviceAlive ".
|
||||||
$readingFnAttributes;
|
$readingFnAttributes;
|
||||||
}
|
}
|
||||||
#
|
########################################################################
|
||||||
#
|
|
||||||
#
|
|
||||||
sub RandomTimer_Undef($$) {
|
sub RandomTimer_Undef($$) {
|
||||||
|
|
||||||
my ($hash, $arg) = @_;
|
my ($hash, $arg) = @_;
|
||||||
|
|
||||||
RemoveInternalTimer($hash);
|
myRemoveInternalTimer("SetTimer", $hash);
|
||||||
|
myRemoveInternalTimer("Exec", $hash);
|
||||||
delete $modules{RandomTimer}{defptr}{$hash->{NAME}};
|
delete $modules{RandomTimer}{defptr}{$hash->{NAME}};
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
#
|
########################################################################
|
||||||
#
|
|
||||||
#
|
|
||||||
sub RandomTimer_Define($$)
|
sub RandomTimer_Define($$)
|
||||||
{
|
{
|
||||||
my ($hash, $def) = @_;
|
my ($hash, $def) = @_;
|
||||||
@ -73,7 +68,9 @@ sub RandomTimer_Define($$)
|
|||||||
|
|
||||||
return "Wrong timespec_start <$timespec_start>, use \"[+][*]<time or func>\""
|
return "Wrong timespec_start <$timespec_start>, use \"[+][*]<time or func>\""
|
||||||
if($timespec_start !~ m/^(\+)?(\*)?(.*)$/i);
|
if($timespec_start !~ m/^(\+)?(\*)?(.*)$/i);
|
||||||
|
|
||||||
my ($rel, $rep, $tspec) = ($1, $2, $3);
|
my ($rel, $rep, $tspec) = ($1, $2, $3);
|
||||||
|
|
||||||
my ($err, $hr, $min, $sec, $fn) = GetTimeSpec($tspec);
|
my ($err, $hr, $min, $sec, $fn) = GetTimeSpec($tspec);
|
||||||
return $err if($err);
|
return $err if($err);
|
||||||
|
|
||||||
@ -102,172 +99,138 @@ sub RandomTimer_Define($$)
|
|||||||
$hash->{S_REL} = $srel;
|
$hash->{S_REL} = $srel;
|
||||||
$hash->{COMMAND} = "off";
|
$hash->{COMMAND} = "off";
|
||||||
|
|
||||||
delete $hash->{STARTTIME};
|
#???
|
||||||
delete $hash->{ABSCHALTZEIT};
|
|
||||||
|
|
||||||
$modules{RandomTimer}{defptr}{$hash->{NAME}} = $hash;
|
$modules{RandomTimer}{defptr}{$hash->{NAME}} = $hash;
|
||||||
RandomTimer_ExecRepeater($hash);
|
|
||||||
|
myRemoveInternalTimer("SetTimer", $hash);
|
||||||
|
myInternalTimer ("SetTimer", time()+1, "RandomTimer_SetTimer", $hash, 0);
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
|
|
||||||
}
|
}
|
||||||
#
|
########################################################################
|
||||||
#
|
sub RandomTimer_SetTimer($)
|
||||||
#
|
|
||||||
sub RandomTimer_ExecRepeater($)
|
|
||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($myHash) = @_;
|
||||||
my $timespec_start = $hash->{TIMESPEC_START};
|
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
|
||||||
|
return if (!defined($hash));
|
||||||
return "Wrong timespec_start <$timespec_start>, use \"[+][*]<time or func>\""
|
|
||||||
if($timespec_start !~ m/^(\+)?(\*)?(.*)$/i);
|
|
||||||
my ($rel, $rep, $tspec) = ($1, $2, $3);
|
|
||||||
|
|
||||||
my ($err, $thour, $tmin, $tsec, $fn);
|
|
||||||
if (!defined $hash->{STARTTIME}) {
|
|
||||||
($err, $thour, $tmin, $tsec, $fn) = GetTimeSpec($tspec);
|
|
||||||
return $err if($err);
|
|
||||||
$hash->{STARTTIME} = sprintf ("%2d:%02d:%02d", $thour, $tmin, $tsec);
|
|
||||||
} else {
|
|
||||||
($thour, $tmin, $tsec) = split(/:/, $hash->{STARTTIME});
|
|
||||||
}
|
|
||||||
|
|
||||||
my $now = time();
|
my $now = time();
|
||||||
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($now);
|
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($now);
|
||||||
|
|
||||||
my $stopTime = abschaltUhrZeitErmitteln($hash);
|
schaltZeitenErmitteln($hash, $now);
|
||||||
my ($shour, $smin, $ssec) = split(/:/, $stopTime);
|
|
||||||
|
|
||||||
my $timeToStart = $now + 3600*($thour-$hour) + 60*($tmin-$min) + ($tsec-$sec);
|
Log3 $hash, 4, "[".$hash->{NAME}."]" . " timings for RandomTimer on $hash->{DEVICE}: "
|
||||||
my $timeToStop = $now + 3600*($shour-$hour) + 60*($smin-$min) + ($ssec-$sec);
|
. strftime("%H:%M:%S(%d)",localtime($hash->{startTime})) . " - "
|
||||||
$timeToStop += 24*3600 if ($timeToStart>=$timeToStop);
|
. strftime("%H:%M:%S(%d)",localtime($hash->{stopTime}));
|
||||||
$hash->{STATE} = strftime("%H:%M:%S",localtime($timeToStart));
|
|
||||||
|
|
||||||
my $timeToExec;
|
my $secToMidnight = 24*3600 -(3600*$hour + 60*$min + $sec);
|
||||||
my $function = "RandomTimer_ExecRepeater";
|
|
||||||
if ($now > $timeToStop) {
|
|
||||||
|
|
||||||
my $midnight = $now + 24*3600 -(3600*$hour + 60*$min + $sec);
|
my $setExecTime = max($now+1, $hash->{startTime});
|
||||||
$timeToExec = max ($timeToStop, $midnight) + 5*60;
|
myRemoveInternalTimer("Exec", $hash);
|
||||||
delete $hash->{STARTTIME};
|
myInternalTimer ("Exec", $setExecTime, "RandomTimer_Exec", $hash, 0);
|
||||||
|
|
||||||
} else {
|
if ($hash->{REP} gt "") {
|
||||||
if ($now < $timeToStart) {
|
my $setTimerTime = max($now+$secToMidnight, $hash->{stopTime}) + 60;
|
||||||
$timeToExec = $timeToStart;
|
myRemoveInternalTimer("SetTimer", $hash);
|
||||||
} else {
|
myInternalTimer ("SetTimer", $setTimerTime, "RandomTimer_SetTimer", $hash, 0);
|
||||||
$timeToExec = $now + 1;
|
|
||||||
$function = "RandomTimer_Exec";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
########################################################################
|
||||||
|
sub RandomTimer_Exec($) {
|
||||||
|
my ($myHash) = @_;
|
||||||
|
#my $hash = $myHash->{HASH};
|
||||||
|
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
|
||||||
|
return if (!defined($hash));
|
||||||
|
|
||||||
Log3 $hash, 4, "[".$hash->{NAME}. "]"." Next timer ".strftime("%d.%m.%Y %H:%M:%S",localtime($timeToExec));
|
# Wenn aktiv aber disabled, dann timer abschalten, Meldung ausgeben.
|
||||||
|
my $active = RandomTimer_isAktiv($hash);
|
||||||
|
my $disabled = RandomTimer_disable($hash);
|
||||||
|
my $stopTimeReached = RandomTimer_stopTimeReached($hash);
|
||||||
|
|
||||||
delete $hash->{ABSCHALTZEIT};
|
if ($active) {
|
||||||
RemoveInternalTimer($hash);
|
# wenn temporär ausgeschaltet
|
||||||
InternalTimer ($timeToExec, $function, $hash, 0);
|
if ($disabled) {
|
||||||
|
Log3 $hash, 3, "[".$hash->{NAME}. "] RandomTimer for $hash->{DEVICE} going down";
|
||||||
|
RandomTimer_down($hash);
|
||||||
|
$hash->{active} = 0;
|
||||||
|
$hash->{STATE} = "disabled";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
# Wenn aktiv und Abschaltzeit erreicht, dann Gerät ausschalten, Meldung ausgeben und Timer schließen
|
||||||
|
if ($stopTimeReached) {
|
||||||
|
Log3 $hash, 3, "[".$hash->{NAME}."] RandomTimer for $hash->{DEVICE} going down";
|
||||||
|
RandomTimer_device_off($hash);
|
||||||
|
RandomTimer_down($hash);
|
||||||
|
$hash->{active} = 0;
|
||||||
|
if ( AttrVal($hash->{NAME}, "runonce", -1) eq 1 ) {
|
||||||
|
Log 3, "[".$hash->{NAME}. "]" ."runonceMode";
|
||||||
|
fhem ("delete $hash->{NAME}") ;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else { # !active
|
||||||
|
if ($disabled) {
|
||||||
|
Log3 $hash, 4, "[".$hash->{NAME}. "] RandomTimer on $hash->{DEVICE} timer disabled - no start";
|
||||||
|
$hash->{STATE} = "disabled";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($stopTimeReached) {
|
||||||
|
Log3 $hash, 3, "[".$hash->{NAME}."] defintion after stopTime";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log3 $hash, 3, "[".$hash->{NAME}."]"." starting RandomTimer on $hash->{DEVICE}: "
|
||||||
|
. strftime("%H:%M:%S(%d)",localtime($hash->{startTime})) . " - "
|
||||||
|
. strftime("%H:%M:%S(%d)",localtime($hash->{stopTime}));
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash->{active} = 1;
|
||||||
|
|
||||||
|
RandomTimer_device_toggle($hash);
|
||||||
|
|
||||||
|
my $nextSwitch = time() + getSecsToNextAbschaltTest($hash);
|
||||||
|
|
||||||
|
myRemoveInternalTimer("Exec", $hash);
|
||||||
|
myInternalTimer ("Exec", $nextSwitch, "RandomTimer_Exec", $hash, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
#
|
########################################################################
|
||||||
#
|
sub RandomTimer_stopTimeReached($) {
|
||||||
#
|
my ($hash) = @_;
|
||||||
sub RandomTimer_Exec($)
|
return ( time()>$hash->{stopTime} );
|
||||||
{
|
}
|
||||||
|
########################################################################
|
||||||
|
sub RandomTimer_isAktiv ($) {
|
||||||
|
my ($hash) = @_;
|
||||||
|
return $hash->{active};
|
||||||
|
}
|
||||||
|
########################################################################
|
||||||
|
sub RandomTimer_down($) {
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
|
|
||||||
my $now1 = time();
|
$hash->{COMMAND} = AttrVal($hash->{NAME}, "keepDeviceAlive", 0) ? "on" : "off";
|
||||||
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($now1);
|
$hash->{STATE} = "down";
|
||||||
|
fhem ("set $hash->{DEVICE} $hash->{COMMAND}");
|
||||||
my $now = sprintf ("%04d:%03d:%02d:%02d:%02d",$year+1900,$yday,$hour,$min,$sec);
|
}
|
||||||
|
########################################################################
|
||||||
if (RandomTimer_disable($hash)) {
|
sub RandomTimer_device_off($) {
|
||||||
if (defined $hash->{ABSCHALTZEIT}) {
|
my ($hash) = @_;
|
||||||
|
|
||||||
$hash->{COMMAND} = AttrVal($hash->{NAME}, "keepDeviceAlive", 0) ? "on" : "off";
|
$hash->{COMMAND} = AttrVal($hash->{NAME}, "keepDeviceAlive", 0) ? "on" : "off";
|
||||||
$hash->{STATE} = "off";
|
$hash->{STATE} = "off";
|
||||||
fhem ("set $hash->{DEVICE} $hash->{COMMAND}");
|
|
||||||
Log3 $hash, 3, "[".$hash->{NAME}. "]" . " $hash->{DEVICE} disabled - going down ...";
|
|
||||||
delete $hash->{ABSCHALTZEIT};
|
|
||||||
} else {
|
|
||||||
Log3 $hash, 4, "[".$hash->{NAME}. "]" . " $hash->{DEVICE} timer disabled - no start";
|
|
||||||
}
|
}
|
||||||
if ($hash->{REP} gt "") {
|
########################################################################
|
||||||
my $midnight = $now1 + 24*3600 - (3600*$hour + 60*$min + $sec);
|
|
||||||
Log3 $hash, 4, "[".$hash->{NAME}. "]"." Next Timer ".strftime("%d.%m.%Y %H:%M:%S",localtime($midnight));
|
|
||||||
InternalTimer($midnight, "RandomTimer_ExecRepeater_verzoegert", $hash, 0);
|
|
||||||
} else {
|
|
||||||
$hash->{COMMAND} = "off";
|
|
||||||
$hash->{STATE} = "disabled";
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!defined $hash->{ABSCHALTZEIT}) {
|
|
||||||
$hash->{ABSCHALTZEIT} = abschaltZeitErmitteln($hash);
|
|
||||||
if ($now ge $hash->{ABSCHALTZEIT}) {
|
|
||||||
$hash->{COMMAND} = "off";
|
|
||||||
$hash->{STATE} = "off";
|
|
||||||
delete $hash->{STARTTIME};
|
|
||||||
delete $hash->{ABSCHALTZEIT};
|
|
||||||
if ($hash->{REP} gt "") {
|
|
||||||
RandomTimer_ExecRepeater($hash);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($now ge $hash->{ABSCHALTZEIT}) {
|
|
||||||
Log3 $hash, 3, "[".$hash->{NAME}."]"." $hash->{DEVICE} going down ...";
|
|
||||||
$hash->{COMMAND} = AttrVal($hash->{NAME}, "keepDeviceAlive", 0) ? "on" : "off";
|
|
||||||
$hash->{STATE} = "off";
|
|
||||||
fhem ("set $hash->{DEVICE} $hash->{COMMAND}");
|
|
||||||
delete $hash->{ABSCHALTZEIT};
|
|
||||||
|
|
||||||
if ($hash->{REP} gt "") {
|
|
||||||
RandomTimer_ExecRepeater($hash);
|
|
||||||
} else {
|
|
||||||
if ( AttrVal($hash->{NAME}, "runonce", 1) == 1 )
|
|
||||||
{ fhem ("delete $hash->{NAME}") ;}
|
|
||||||
else
|
|
||||||
{ RandomTimer_ExecRepeater($hash);}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
toggleDevice($hash);
|
|
||||||
my $secsToNextAbschaltTest = getSecsToNextAbschaltTest($hash);
|
|
||||||
InternalTimer(gettimeofday()+$secsToNextAbschaltTest, "RandomTimer_Exec", $hash, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
sub RandomTimer_Attr($$$) {
|
sub RandomTimer_Attr($$$) {
|
||||||
my ($cmd, $name, $attrName, $attrVal) = @_;
|
my ($cmd, $name, $attrName, $attrVal) = @_;
|
||||||
|
|
||||||
if( $attrName eq "disable" ) {
|
if( $attrName eq "disable" || $attrName eq "disableCmd" ) {
|
||||||
my $hash = $defs{$name};
|
|
||||||
if( $cmd eq "set" && $attrVal ne "0" ) {
|
|
||||||
$attr{$name}{$attrName} = 1;
|
|
||||||
$hash->{STATE} = "disabled";
|
|
||||||
RemoveInternalTimer($hash);
|
|
||||||
} else {
|
|
||||||
$attr{$name}{$attrName} = 0;
|
|
||||||
$hash->{STATE} = "off";
|
|
||||||
RandomTimer_ExecRepeater($hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
sub RandomTimer_ExecRepeater_verzoegert($)
|
|
||||||
{
|
|
||||||
my ($hash) = @_;
|
|
||||||
|
|
||||||
if ($hash->{REP} gt "") {
|
my $hash = $defs{$name};
|
||||||
RandomTimer_ExecRepeater($hash);
|
myRemoveInternalTimer("SetTimer", $hash);
|
||||||
|
myInternalTimer ("SetTimer", time()+1, "RandomTimer_SetTimer", $hash, 0);
|
||||||
}
|
}
|
||||||
|
return undef;
|
||||||
}
|
}
|
||||||
#
|
########################################################################
|
||||||
#
|
|
||||||
#
|
|
||||||
sub getSecsToNextAbschaltTest($)
|
sub getSecsToNextAbschaltTest($)
|
||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
@ -279,32 +242,86 @@ sub getSecsToNextAbschaltTest($)
|
|||||||
|
|
||||||
return $nextSecs;
|
return $nextSecs;
|
||||||
}
|
}
|
||||||
#
|
########################################################################
|
||||||
#
|
sub schaltZeitenErmitteln ($$) {
|
||||||
#
|
my ($hash,$now) = @_;
|
||||||
sub abschaltZeitErmitteln ($) {
|
|
||||||
my ($hash) = @_;
|
|
||||||
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
|
|
||||||
|
|
||||||
my $uebertragDay = 0;
|
startZeitErmitteln($hash, $now);
|
||||||
my $uebertragYear = 0;
|
stopZeitErmitteln ($hash, $now);
|
||||||
|
|
||||||
my $stoptime = abschaltUhrZeitErmitteln($hash);
|
$hash->{STATE} = strftime("%H:%M:%S",localtime($hash->{startTime}));
|
||||||
my $starttime = $hash->{STARTTIME};
|
|
||||||
|
|
||||||
if ($stoptime lt $starttime) {
|
|
||||||
$uebertragDay = 1;
|
|
||||||
if ($mday = 31 && $yday>=365) {
|
|
||||||
$uebertragYear = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (sprintf ("%04d:%03d:%5s",$year+1900+$uebertragYear,$yday+$uebertragDay,$stoptime));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#
|
########################################################################
|
||||||
#
|
sub zeitBerechnen ($$$$) {
|
||||||
#
|
my ($now, $hour, $min, $sec) = @_;
|
||||||
sub abschaltUhrZeitErmitteln ($)
|
|
||||||
|
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 addDays ($$) {
|
||||||
|
my ($now, $days) = @_;
|
||||||
|
|
||||||
|
my @jetzt_arr = localtime($now);
|
||||||
|
$jetzt_arr[3] += $days;
|
||||||
|
my $next = timelocal_nocheck(@jetzt_arr);
|
||||||
|
return $next;
|
||||||
|
|
||||||
|
}
|
||||||
|
########################################################################
|
||||||
|
sub startZeitErmitteln ($$) {
|
||||||
|
my ($hash,$now) = @_;
|
||||||
|
|
||||||
|
my $timespec_start = $hash->{TIMESPEC_START};
|
||||||
|
|
||||||
|
return "Wrong timespec_start <$timespec_start>, use \"[+][*]<time or func>\""
|
||||||
|
if($timespec_start !~ m/^(\+)?(\*)?(.*)$/i);
|
||||||
|
my ($rel, $rep, $tspec) = ($1, $2, $3);
|
||||||
|
|
||||||
|
my ($err, $hour, $min, $sec, $fn) = GetTimeSpec($tspec);
|
||||||
|
return $err if($err);
|
||||||
|
|
||||||
|
my $startTime;
|
||||||
|
if($rel) {
|
||||||
|
$startTime = $now + 3600* $hour + 60* $min + $sec;
|
||||||
|
} else {
|
||||||
|
$startTime = zeitBerechnen($now, $hour, $min, $sec);
|
||||||
|
}
|
||||||
|
$hash->{startTime} = $startTime;
|
||||||
|
$hash->{STARTTIME} = strftime("%d.%m.%Y %H:%M:%S",localtime($startTime));
|
||||||
|
}
|
||||||
|
########################################################################
|
||||||
|
sub stopZeitErmitteln ($$) {
|
||||||
|
my ($hash,$now) = @_;
|
||||||
|
|
||||||
|
my $timespec_stop = $hash->{TIMESPEC_STOP};
|
||||||
|
|
||||||
|
return "Wrong timespec_stop <$timespec_stop>, use \"[+][*]<time or func>\""
|
||||||
|
if($timespec_stop !~ m/^(\+)?(\*)?(.*)$/i);
|
||||||
|
my ($rel, $rep, $tspec) = ($1, $2, $3);
|
||||||
|
|
||||||
|
my ($err, $hour, $min, $sec, $fn) = GetTimeSpec($tspec);
|
||||||
|
return $err if($err);
|
||||||
|
|
||||||
|
my $stopTime;
|
||||||
|
if($rel) {
|
||||||
|
$stopTime = $hash->{startTime} + 3600* $hour + 60* $min + $sec;
|
||||||
|
} else {
|
||||||
|
$stopTime = zeitBerechnen($now, $hour, $min, $sec);
|
||||||
|
}
|
||||||
|
if ($hash->{startTime} > $stopTime) {
|
||||||
|
$stopTime = addDays($stopTime, 1);
|
||||||
|
}
|
||||||
|
$hash->{stopTime} = $stopTime;
|
||||||
|
$hash->{STOPTIME} = strftime("%d.%m.%Y %H:%M:%S",localtime($stopTime));
|
||||||
|
|
||||||
|
}
|
||||||
|
########################################################################
|
||||||
|
sub schaltzeitenErmitteln ($)
|
||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
my($sec,$min,$hour)=localtime(time);
|
my($sec,$min,$hour)=localtime(time);
|
||||||
@ -328,10 +345,8 @@ sub abschaltUhrZeitErmitteln ($)
|
|||||||
my $timeToStop_st = sprintf ("%02d:%02d:%2d", $h,$m,$s );
|
my $timeToStop_st = sprintf ("%02d:%02d:%2d", $h,$m,$s );
|
||||||
return ($timeToStop_st);
|
return ($timeToStop_st);
|
||||||
}
|
}
|
||||||
#
|
########################################################################
|
||||||
#
|
sub RandomTimer_device_toggle ($)
|
||||||
#
|
|
||||||
sub toggleDevice ($)
|
|
||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
get_switchmode($hash);
|
get_switchmode($hash);
|
||||||
@ -359,9 +374,7 @@ sub toggleDevice ($)
|
|||||||
}
|
}
|
||||||
$hash->{STATE} = $hash->{COMMAND};
|
$hash->{STATE} = $hash->{COMMAND};
|
||||||
}
|
}
|
||||||
#
|
########################################################################
|
||||||
#
|
|
||||||
#
|
|
||||||
sub get_switchmode ($) {
|
sub get_switchmode ($) {
|
||||||
|
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
@ -382,8 +395,8 @@ sub get_switchmode ($) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
########################################################################
|
||||||
sub RandomTimer_disable($) {
|
sub RandomTimer_disable($) {
|
||||||
|
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
|
|
||||||
my $disable = AttrVal($hash->{NAME}, "disable", 0 );
|
my $disable = AttrVal($hash->{NAME}, "disable", 0 );
|
||||||
@ -391,13 +404,14 @@ sub RandomTimer_disable($) {
|
|||||||
$disable = $disable || eval ($disableCond);
|
$disable = $disable || eval ($disableCond);
|
||||||
return $disable;
|
return $disable;
|
||||||
}
|
}
|
||||||
#
|
########################################################################
|
||||||
sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
|
sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
|
||||||
|
|
||||||
foreach my $hc ( sort keys %{$modules{RandomTimer}{defptr}} ) {
|
foreach my $hc ( sort keys %{$modules{RandomTimer}{defptr}} ) {
|
||||||
my $hash = $modules{RandomTimer}{defptr}{$hc};
|
my $hash = $modules{RandomTimer}{defptr}{$hc};
|
||||||
|
|
||||||
RandomTimer_ExecRepeater($hash);
|
my $myHash->{HASH}=$hash;
|
||||||
|
RandomTimer_Exec($myHash);
|
||||||
Log3 undef, 3, "RandomTimer_Wakeup() for $hash->{NAME} done!";
|
Log3 undef, 3, "RandomTimer_Wakeup() for $hash->{NAME} done!";
|
||||||
}
|
}
|
||||||
Log3 undef, 3, "RandomTimer_Wakeup() done!";
|
Log3 undef, 3, "RandomTimer_Wakeup() done!";
|
||||||
@ -405,7 +419,6 @@ sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
|
|||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
=begin html
|
=begin html
|
||||||
|
|
||||||
@ -464,15 +477,16 @@ sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- -------------------------------------------------------------------------- -->
|
<!-- -------------------------------------------------------------------------- -->
|
||||||
<!-- Set ------------------------------------------------------------------- -->
|
<!-- Set ------------------------------------------------------------------ -->
|
||||||
<!-- -------------------------------------------------------------------------- -->
|
<!-- -------------------------------------------------------------------------- -->
|
||||||
<a name="RandomTimerSet"></a>
|
<a name="RandomTimerSet"></a>
|
||||||
<h3>Set</h3>
|
<h3>Set</h3>
|
||||||
<ul>
|
<ul>
|
||||||
N/A
|
N/A
|
||||||
</ul>
|
</ul>
|
||||||
<!-- -------------------------------------------------------------------------- -->
|
<!-- ----------------------------- -->
|
||||||
<!-- Get ------------------------------------------------------------------- -->
|
<!-- Get ------------------------- -->
|
||||||
|
<!-- Get ------------------------------------------------------------------ -->
|
||||||
<!-- -------------------------------------------------------------------------- -->
|
<!-- -------------------------------------------------------------------------- -->
|
||||||
<a name="RandomTimerGet"></a>
|
<a name="RandomTimerGet"></a>
|
||||||
<h3>Get</h3>
|
<h3>Get</h3>
|
||||||
@ -534,6 +548,5 @@ sub RandomTimer_Wakeup() { # {RandomTimer_Wakeup()}
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
=end html
|
=end html
|
||||||
=cut
|
=cut
|
@ -65,7 +65,6 @@ sub WeekdayTimer_Undef($$){
|
|||||||
|
|
||||||
sub WeekdayTimer_UpdatePerlTime($) {
|
sub WeekdayTimer_UpdatePerlTime($) {
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
|
|
||||||
Heating_Control_UpdatePerlTime($hash);
|
Heating_Control_UpdatePerlTime($hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +84,8 @@ sub WeekdayTimer_SetAllParms() { # {WeekdayTimer_SetAllParms()}
|
|||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WeekdayTimer_Update($hash);
|
my $myHash->{HASH}=$hash;
|
||||||
|
WeekdayTimer_Update($myHash);
|
||||||
Log3 undef, 3, "WeekdayTimer_Update() for $hash->{NAME} done!";
|
Log3 undef, 3, "WeekdayTimer_Update() for $hash->{NAME} done!";
|
||||||
}
|
}
|
||||||
Log3 undef, 3, "WeekdayTimer_SetAllParms() done!";
|
Log3 undef, 3, "WeekdayTimer_SetAllParms() done!";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user