2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 09:16:53 +00:00

98_WeekdayTimer, 98_Heating_Control: bugfixing in startup of timer and Heating_Control_SetAllTemps() and WeekdayTimer_SetAllParms(). Another fix in setting active/inactive .

git-svn-id: https://svn.fhem.de/fhem/trunk@9712 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
dietmar63 2015-10-28 22:18:48 +00:00
parent f39b401e65
commit d9f55fdb75

View File

@ -145,7 +145,7 @@ sub WeekdayTimer_Define($$) {
my $conditionOrCommand = join (" ", @a); my $conditionOrCommand = join (" ", @a);
# test if device is defined # test if device is defined
Log3 ($hash, 3, "[$name] invalid device, <$device> not found") if(!$defs{$device}); Log3 ($hash, 3, "[$name] device <$device> in fhem not defined, but accepted") if(!$defs{$device});
# wenn keine switchintime angegeben ist, dann Fehler # wenn keine switchintime angegeben ist, dann Fehler
Log3 ($hash, 3, "[$name] no valid Switchingtime found in <$conditionOrCommand>, check first parameter") if (@switchingtimes == 0); Log3 ($hash, 3, "[$name] no valid Switchingtime found in <$conditionOrCommand>, check first parameter") if (@switchingtimes == 0);
@ -156,7 +156,7 @@ sub WeekdayTimer_Define($$) {
$hash->{STILLDONETIME} = 0; $hash->{STILLDONETIME} = 0;
$hash->{SWITCHINGTIMES} = \@switchingtimes; $hash->{SWITCHINGTIMES} = \@switchingtimes;
$attr{$name}{verbose} = 5 if (!defined $attr{$name}{verbose} && $name =~ m/^tst.*/ ); $attr{$name}{verbose} = 5 if (!defined $attr{$name}{verbose} && $name =~ m/^tst.*/ );
#$attr{$name}{verbose} = 4; $defs{$device}{STILLDONETIME} = 0 if($defs{$device});
$modules{$hash->{TYPE}}{defptr}{$hash->{NAME}} = $hash; $modules{$hash->{TYPE}}{defptr}{$hash->{NAME}} = $hash;
@ -166,9 +166,7 @@ sub WeekdayTimer_Define($$) {
$hash->{COMMAND} = $conditionOrCommand; $hash->{COMMAND} = $conditionOrCommand;
} }
#WeekdayTimer_DeleteTimer($hash); am Anfang dieser Routine
WeekdayTimer_Profile ($hash); WeekdayTimer_Profile ($hash);
#WeekdayTimer_SetTimer ($hash); # per timer - nach init
InternalTimer(time(), "$hash->{TYPE}_SetTimer", $hash, 0); InternalTimer(time(), "$hash->{TYPE}_SetTimer", $hash, 0);
WeekdayTimer_SetTimerForMidnightUpdate( { HASH => $hash} ); WeekdayTimer_SetTimerForMidnightUpdate( { HASH => $hash} );
@ -187,27 +185,33 @@ sub WeekdayTimer_Profile($) {
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time()); my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time());
my $now = time(); my $now = time();
# ------------------------------------------------------------------------------ # ---- Zeitpunkte den Tagen zuordnen -----------------------------------
my $idx = 0;
foreach my $st (@{$hash->{SWITCHINGTIMES}}) { foreach my $st (@{$hash->{SWITCHINGTIMES}}) {
my ($tage,$time,$parameter) = WeekdayTimer_SwitchingTime ($hash, $st); my ($tage,$time,$parameter) = WeekdayTimer_SwitchingTime ($hash, $st);
$idx++;
foreach my $d (@{$tage}) { foreach my $d (@{$tage}) {
my @listeDerTage = ($d); my @listeDerTage = ($d);
push (@listeDerTage, (0, 6) ) if ($d==7); push (@listeDerTage, (0, 6) ) if ($d==7); # sa,so ($we)
push (@listeDerTage, (1..5) ) if ($d==8); push (@listeDerTage, (1..5) ) if ($d==8); # mo-fr
# alle Tage prüfen hash anlegen mit d>1, d=>0
# wenn 0, dann nur auf Feiertag prüfen
map { my $day = $_; map { my $day = $_;
my $dayOfEchteZeit = $day; my $dayOfEchteZeit = $day;
$dayOfEchteZeit = ($wday>=1&&$wday<=5) ? 6 : $wday if ($day==7); # ggf. Samstag $wday ~~ [1..5] $dayOfEchteZeit = ($wday>=1&&$wday<=5) ? 6 : $wday if ($day==7); # ggf. Samstag $wday ~~ [1..5]
$dayOfEchteZeit = ($wday==0||$wday==6) ? 1 : $wday if ($day==8); # ggf. Montag $wday ~~ [0, 6] $dayOfEchteZeit = ($wday==0||$wday==6) ? 1 : $wday if ($day==8); # ggf. Montag $wday ~~ [0, 6]
my $echtZeit = WeekdayTimer_EchteZeit($hash, $dayOfEchteZeit, $time); my $echtZeit = WeekdayTimer_EchteZeit($hash, $dayOfEchteZeit, $time);
$hash->{profile}{$day}{$echtZeit} = $parameter; $hash->{profile} {$day}{$echtZeit} = $parameter;
$hash->{profile_IDX}{$day}{$echtZeit} = $idx;
} @listeDerTage; } @listeDerTage;
} }
} }
# ------------------------------------------------------------------------------ # ---- Zeitpunkte des aktuellen Tages mit EPOCH ermitteln --------------
my $idx = 0; $idx = 0;
foreach my $st (@{$hash->{SWITCHINGTIMES}}) { foreach my $st (@{$hash->{SWITCHINGTIMES}}) {
my ($tage,$time,$parameter) = WeekdayTimer_SwitchingTime ($hash, $st); my ($tage,$time,$parameter) = WeekdayTimer_SwitchingTime ($hash, $st);
my $echtZeit = WeekdayTimer_EchteZeit ($hash, $wday, $time); my $echtZeit = WeekdayTimer_EchteZeit ($hash, $wday, $time);
@ -219,7 +223,7 @@ sub WeekdayTimer_Profile($) {
$hash->{profil}{$idx}{EPOCH} = WeekdayTimer_zeitErmitteln ($now, $stunde, $minute, $sekunde, 0); $hash->{profil}{$idx}{EPOCH} = WeekdayTimer_zeitErmitteln ($now, $stunde, $minute, $sekunde, 0);
$hash->{profil}{$idx}{TAGE} = $tage; $hash->{profil}{$idx}{TAGE} = $tage;
} }
# ------------------------------------------------------------------------------ # ---- Texte Readings aufbauen -----------------------------------------
Log3 $hash, 4, "[$hash->{NAME}] " . sunrise_abs() . " " . sunset_abs() . " " . $longDays{$language}[$wday]; Log3 $hash, 4, "[$hash->{NAME}] " . sunrise_abs() . " " . sunset_abs() . " " . $longDays{$language}[$wday];
foreach my $d (sort keys %{$hash->{profile}}) { foreach my $d (sort keys %{$hash->{profile}}) {
my $profiltext = ""; my $profiltext = "";
@ -232,7 +236,9 @@ sub WeekdayTimer_Profile($) {
Log3 $hash, 4, "[$hash->{NAME}] $profiltext ($profilKey)"; Log3 $hash, 4, "[$hash->{NAME}] $profiltext ($profilKey)";
} }
# Log 3, $hash->{NAME} ."--->\n". Dumper $hash->{profile}; #Log 3, $hash->{NAME} ."--->\n". Dumper $hash->{profile};
#Log 3, $hash->{NAME} ."--->\n". Dumper $hash->{profile_IDX};
# für logProxy umhaengen # für logProxy umhaengen
$hash->{helper}{SWITCHINGTIME} = $hash->{profile}; $hash->{helper}{SWITCHINGTIME} = $hash->{profile};
delete $hash->{profile}; delete $hash->{profile};
@ -435,11 +441,12 @@ sub WeekdayTimer_SetTimerForMidnightUpdate($) {
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 $secToMidnight = 24*3600 -(3600*$hour + 60*$min + $sec) + 5;
#my $secToMidnight = + 01*60; my $midnightPlus5Seconds = WeekdayTimer_zeitErmitteln ($now, 0, 0, 5, 1);
#Log3 $hash, 3, "midnightPlus5Seconds------------>".FmtDateTime($midnightPlus5Seconds);
myRemoveInternalTimer("SetTimerOfDay", $hash); myRemoveInternalTimer("SetTimerOfDay", $hash);
myInternalTimer ("SetTimerOfDay", $now+$secToMidnight, "$hash->{TYPE}_SetTimerOfDay", $hash, 0); myInternalTimer ("SetTimerOfDay", $midnightPlus5Seconds, "$hash->{TYPE}_SetTimerOfDay", $hash, 0);
} }
################################################################################ ################################################################################
@ -493,8 +500,8 @@ sub WeekdayTimer_SetTimer($) {
my $secondsToSwitch = $timToSwitch - $now; my $secondsToSwitch = $timToSwitch - $now;
my $isActiveTimer = WeekdayTimer_isAnActiveTimer ($hash, $tage, $para); my $isActiveTimer = WeekdayTimer_isAnActiveTimer ($hash, $tage, $para);
readingsSingleUpdate ($hash, "state", "active", 1) readingsSingleUpdate ($hash, "state", "active", 1)
if (!defined $hash->{SETTIMERATMIDNIGHT} && $isActiveTimer); if (!defined $hash->{SETTIMERATMIDNIGHT} && $isActiveTimer);
if ($secondsToSwitch>-5) { if ($secondsToSwitch>-5) {
Log3 $hash, 4, "[$name] setTimer - timer seems to be active today: ".join("",@$tage)."|$time|$para" if($isActiveTimer); Log3 $hash, 4, "[$name] setTimer - timer seems to be active today: ".join("",@$tage)."|$time|$para" if($isActiveTimer);
@ -506,20 +513,19 @@ sub WeekdayTimer_SetTimer($) {
return; return;
} }
my ($idx,$aktTime,$aktParameter,$nextTime,$nextParameter) = my ($aktIdx,$aktTime,$aktParameter,$nextTime,$nextParameter) =
WeekdayTimer_searchAktNext($hash, time()+5); WeekdayTimer_searchAktNext($hash, time()+5);
readingsSingleUpdate ($hash, "nextUpdate", FmtDateTime($nextTime), 1); readingsSingleUpdate ($hash, "nextUpdate", FmtDateTime($nextTime), 1);
readingsSingleUpdate ($hash, "nextValue", $nextParameter, 1); readingsSingleUpdate ($hash, "nextValue", $nextParameter, 1);
if ($switchInThePast) { if ($switchInThePast) {
# Fenserkontakte abfragen - wenn einer im Status closed, dann Schaltung um 60 Sekunden verzögern # Fensterkontakte abfragen - wenn einer im Status closed, dann Schaltung um 60 Sekunden verzögern
if (WeekdayTimer_FensterOffen($hash, $aktParameter, $idx)) { if (WeekdayTimer_FensterOffen($hash, $aktParameter, $aktIdx)) {
return; return;
} }
#Log3 $hash, 3, "$hash->{NAME} idx-past----------->$idx $aktParameter " . FmtDateTime($aktTime); myInternalTimer ("$aktIdx", $aktTime, "$hash->{TYPE}_Update", $hash, 0);
myInternalTimer ("$idx", $aktTime, "$hash->{TYPE}_Update", $hash, 0);
my $active = 1; my $active = 1;
if (defined $hash->{CONDITION}) { if (defined $hash->{CONDITION}) {
$active = AnalyzeCommandChain(undef, "{".$hash->{CONDITION}."}"); $active = AnalyzeCommandChain(undef, "{".$hash->{CONDITION}."}");
@ -535,42 +541,39 @@ sub WeekdayTimer_searchAktNext($$) {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($now); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($now);
#Log3 $hash, 3, "[$name] such--->".FmtDateTime($now); #Log3 $hash, 3, "[$name] such--->".FmtDateTime($now);
my ($nextTag, $nextTime, $nextParameter); my ($oldTag, $oldTime, $oldPara , $oldIdx);
my ($aktTag, $aktTime, $aktParameter); my ($nextTag, $nextTime, $nextPara, $nextIdx);
my $language = $hash->{LANGUAGE}; my $language = $hash->{LANGUAGE};
my %shortDays = %{$hash->{shortDays}};
my @realativeWdays = ($wday..6,0..$wday-1,$wday..6,0..6); my @realativeWdays = ($wday..6,0..$wday-1,$wday..6,0..6);
#Log3 $hash, 3, "[$name] wdays @realativeWdays";
my $oldIdx = 0;
for (my $i=0;$i<=$#realativeWdays;$i++) { for (my $i=0;$i<=$#realativeWdays;$i++) {
my $relativeDay = $i-7; my $relativeDay = $i-7;
my $relWday = $realativeWdays[$i]; my $relWday = $realativeWdays[$i];
#Log3 $hash, 3, "[$name] $i relWday $relWday $relativeDay";
my $idx = 0;
foreach my $time (sort keys %{$hash->{helper}{SWITCHINGTIME}{$relWday}}) { foreach my $time (sort keys %{$hash->{helper}{SWITCHINGTIME}{$relWday}}) {
my ($stunde, $minute, $sekunde) = split (":",$time);
$idx++; $oldTime = $nextTime;
#Log3 $hash, 3, "$idx------------>$relativeDay $idx $oldIdx $time"; $oldPara = $nextPara;
my ($stunde, $minute, $sekunde) = split (":",$time); $oldIdx = $nextIdx;
my $epoch = WeekdayTimer_zeitErmitteln ($now, $stunde, $minute, $sekunde, $relativeDay); $oldTag = $nextTag;
#Log3 $hash, 3, "[$name] $time---->".FmtDateTime($epoch); $nextTime = WeekdayTimer_zeitErmitteln ($now, $stunde, $minute, $sekunde, $relativeDay);
$nextPara = $hash->{helper}{SWITCHINGTIME}{$relWday}{$time};
if ($epoch >= $now) { $nextIdx = $hash->{profile_IDX}{$relWday}{$time};
$nextTag = $relWday; $nextTag = $relWday;
$nextTime = $epoch;
$nextParameter = $hash->{helper}{SWITCHINGTIME}{$relWday}{$time}; #Log3 $hash, 3, $shortDays{$language}[$nextTag]." ".FmtDateTime($nextTime)." ".$nextPara." ".$nextIdx;
Log3 $hash, 4, "[$name] akt: ".FmtDateTime($aktTime) ."(".$hash->{shortDays}{$language}[$aktTag]. ") -->> $aktParameter";
Log3 $hash, 4, "[$name] next: ".FmtDateTime($nextTime)."(".$hash->{shortDays}{$language}[$nextTag].") -->> $nextParameter"; if ($nextTime >= $now) {
return ($oldIdx, $aktTime, $aktParameter, $nextTime, $nextParameter); #Log3 $hash, 3, "oldIdx------------->$oldIdx";
#Log3 $hash, 3, "oldTime------------>".FmtDateTime($oldTime);
#Log3 $hash, 3, "oldPara------------>$oldPara";
return ($oldIdx, $oldTime, $oldPara, $nextTime, $nextPara);
} }
$oldIdx = $idx;
$aktTag = $relWday;
$aktTime = $epoch;
$aktParameter = $hash->{helper}{SWITCHINGTIME}{$relWday}{$time};
} }
} }
return (undef,undef,undef,undef); return (undef,undef,undef,undef);
@ -585,7 +588,7 @@ sub WeekdayTimer_Update($) {
my ($myHash) = @_; my ($myHash) = @_;
my $hash = myGetHashIndirekt($myHash, (caller(0))[3]); my $hash = myGetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash)); return if (!defined($hash));
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $idx = $myHash->{MODIFIER}; my $idx = $myHash->{MODIFIER};
my $now = time(); my $now = time();
@ -615,16 +618,34 @@ sub WeekdayTimer_Update($) {
my $activeTimer = WeekdayTimer_isAnActiveTimer ($hash, $tage, $newParam); my $activeTimer = WeekdayTimer_isAnActiveTimer ($hash, $tage, $newParam);
Log3 $hash, 4, "[$name] Update - timer seems to be active today: ".join("",@$tage)."|$time|$newParam" if($activeTimer); Log3 $hash, 4, "[$name] Update - timer seems to be active today: ".join("",@$tage)."|$time|$newParam" if($activeTimer);
my ($indx, $aktTime, $aktParameter, $nextTime, $nextParameter) = my ($aktIdx, $aktTime, $aktParameter, $nextTime, $nextParameter) =
WeekdayTimer_searchAktNext($hash, time()+5); WeekdayTimer_searchAktNext($hash, time()+5);
my $device = $hash->{DEVICE};
my $disabled = AttrVal($hash->{NAME}, "disable", 0);
if ($activeTimer && !$disabled && $defs{$device}) {
#my $sollZeit = $myHash->{TIME};
#Log3 $hash, 3, "[$name] $idx ". FmtDateTime($defs{$device}{STILLDONETIME}) . " " . $newParam . " " . join("",@$tage);
#Log3 $hash, 3, "[$name] $idx ". FmtDateTime($sollZeit) . " " . $newParam . " " . join("",@$tage);
#$defs{$device}{STILLDONETIME} = 0 if (!defined($defs{$device}{STILLDONETIME}));
#if ($defs{$device}{STILLDONETIME} <= $sollZeit ) {
# $defs{$device}{STILLDONETIME} = $sollZeit;
#} else {
# Log3 $hash, 3, "[$name:$time] Timer ".FmtDateTime($sollZeit)." overwritten by " . FmtDateTime($defs{$device}{STILLDONETIME});
# return;
#}
}
# ggf. Device schalten # ggf. Device schalten
WeekdayTimer_Device_Schalten($hash, $newParam, $tage) if($activeTimer); WeekdayTimer_Device_Schalten($hash, $newParam, $tage) if($activeTimer);
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
readingsBulkUpdate ($hash, "nextUpdate", FmtDateTime($nextTime)); readingsBulkUpdate ($hash, "nextUpdate", FmtDateTime($nextTime));
readingsBulkUpdate ($hash, "nextValue", $nextParameter); readingsBulkUpdate ($hash, "nextValue", $nextParameter);
readingsBulkUpdate ($hash, "state", $activeTimer ? $newParam : "inactive" ); readingsBulkUpdate ($hash, "state", $newParam ) if($activeTimer);
readingsEndUpdate ($hash, defined($hash->{LOCAL} ? 0 : 1)); readingsEndUpdate ($hash, defined($hash->{LOCAL} ? 0 : 1));
return 1; return 1;