diff --git a/fhem/FHEM/98_Heating_Control.pm b/fhem/FHEM/98_Heating_Control.pm index 44cb48224..2bce7e445 100644 --- a/fhem/FHEM/98_Heating_Control.pm +++ b/fhem/FHEM/98_Heating_Control.pm @@ -45,7 +45,7 @@ sub Heating_Control_Initialize($) $hash->{GetFn} = "Heating_Control_Get"; $hash->{AttrFn} = "Heating_Control_Attr"; $hash->{UpdFn} = "Heating_Control_Update"; - $hash->{AttrList}= "disable:0,1 windowSensor ". + $hash->{AttrList}= "disable:0,1 delayedExecutionCond windowSensor ". $readingFnAttributes; } ################################################################################ @@ -340,11 +340,6 @@ sub Heating_Control_Update($) { my $name = $hash->{NAME}; my $now = time() + 5; # garantiert > als die eingestellte Schlatzeit - # Fenserkontakte abfragen - wenn einer im Status closed, dann Schaltung um 60 Sekunden verzögern - if (Heating_Control_FensterOffen($hash)) { - return; - } - # Schaltparameter ermitteln my ($nowSwitch,$nextSwitch,$newParam,$nextParam) = Heating_Control_akt_next_param($now, $hash); @@ -355,6 +350,11 @@ sub Heating_Control_Update($) { Log3 $hash, 4, $mod .strftime('Next switch %d.%m.%Y %H:%M:%S',localtime($nextSwitch)); + # Fenserkontakte abfragen - wenn einer im Status closed, dann Schaltung um 60 Sekunden verzögern + if (Heating_Control_FensterOffen($hash, $nowSwitch, $newParam)) { + return; + } + # Timer und Readings setzen. myRemoveInternalTimer("Update", $hash); myInternalTimer ("Update", $nextSwitch, "$hash->{TYPE}_Update", $hash, 0); @@ -373,41 +373,78 @@ sub Heating_Control_Update($) { return 1; } ######################################################################## -sub Heating_Control_FensterOffen ($) { - my ($hash) = @_; - my $mod = "[".$hash->{NAME} ."]"; ### +sub Heating_Control_FensterOffen ($$$) { + my ($hash, $tim, $event) = @_; + my $mod = "[".$hash->{NAME} ."]"; + + my $verzoegerteAusfuehrungCond = AttrVal($hash->{NAME}, "delayedExecutionCond", "0"); - my %contacts = ( "CUL_FHTTK" => { "READING" => "Window", "STATUS" => "(Open)" }, - "CUL_HM" => { "READING" => "state", "STATUS" => "(open|tilted)", "model" => 1 }, - "MAX" => { "READING" => "state", "STATUS" => "(open)" }); + my %specials= ( + "%HEATING_CONTROL" => $hash->{NAME}, + "%WEEKDAYTIMER" => $hash->{NAME}, + "%TIME" => $tim, + "%NAME" => $hash->{DEVICE}, + "%EVENT" => $event + ); + $verzoegerteAusfuehrungCond = EvalSpecials($verzoegerteAusfuehrungCond, %specials); + my $verzoegerteAusfuehrung = eval($verzoegerteAusfuehrungCond); + + if ($verzoegerteAusfuehrung) { + if (!defined($hash->{VERZOEGRUNG})) { + Log3 $hash, 3, "$mod switch of $hash->{DEVICE} delayed - $verzoegerteAusfuehrungCond is TRUE"; + } + myRemoveInternalTimer("Update", $hash); + myInternalTimer ("Update", time()+60, "$hash->{TYPE}_Update", $hash, 0); + $hash->{VERZOEGRUNG} = 1; + return 1 + } + + my %contacts = ( "CUL_FHTTK" => { "READING" => "Window", "STATUS" => "(Open)", "MODEL" => "r" }, + "CUL_HM" => { "READING" => "state", "STATUS" => "(open|tilted)", "MODEL" => "r" }, + "MAX" => { "READING" => "state", "STATUS" => "(open)", "MODEL" => "r" }, + "WeekdayTimer" => { "READING" => "delayedExecution","STATUS" => "^1\$", "MODEL" => "a" }, + "Heating_Control" => { "READING" => "delayedExecution","STATUS" => "^1\$", "MODEL" => "a" } + ); - my $fensterKontakte = AttrVal($hash->{NAME}, "windowSensor", ""); - Log3 $hash, 5, "$mod list of windowsenors found: '$fensterKontakte'"; + my $fensterKontakte = AttrVal($hash->{NAME}, "windowSensor", "")." ".$hash->{NAME}; + $fensterKontakte =~ s/^\s+//; + $fensterKontakte =~ s/\s+$//; + + Log3 $hash, 5, "$mod list of senors found: '$fensterKontakte'"; if ($fensterKontakte ne "" ) { - my @kontakte = split(/ /, $fensterKontakte); + my @kontakte = split("[ \t]+", $fensterKontakte); foreach my $fk (@kontakte) { if(!$defs{$fk}) { - Log3 $hash, 3, "$mod Window sensor <$fk> not found - check name."; + Log3 $hash, 3, "$mod sensor <$fk> not found - check name."; } else { my $fk_hash = $defs{$fk}; my $fk_typ = $fk_hash->{TYPE}; if (!defined($contacts{$fk_typ})) { Log3 $hash, 3, "$mod TYPE '$fk_typ' of $fk not yet supported, $fk ignored - inform maintainer"; } else { + my $reading = $contacts{$fk_typ}{READING}; my $statusReg = $contacts{$fk_typ}{STATUS}; - my $windowStatus = ReadingsVal($fk,$reading,"nF"); + my $model = $contacts{$fk_typ}{MODEL}; + + my $windowStatus; + if ($model eq "r") { ### Reading, sonst Attribut + $windowStatus = ReadingsVal($fk,$reading,"nF"); + }else{ + $windowStatus = AttrVal ($fk,$reading,"nF"); + } + if ($windowStatus eq "nF") { - Log3 $hash, 3, "$mod READING '$reading' of $fk not found, $fk ignored - inform maintainer"; + Log3 $hash, 3, "$mod Reading/Attribute '$reading' of $fk not found, $fk ignored - inform maintainer" if ($model eq "r"); } else { - Log3 $hash, 5, "$mod windowsensor '$fk' Reading '$reading' is '$windowStatus'"; + Log3 $hash, 5, "$mod sensor '$fk' Reading/Attribute '$reading' is '$windowStatus'"; if ($windowStatus =~ m/^$statusReg$/g) { 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 - sensor '$fk' Reading/Attribute '$reading' is '$windowStatus'"; } - myRemoveInternalTimer("Update", $hash); - myInternalTimer ("Update", time()+60, "$hash->{TYPE}_Update", $hash, 0); + myRemoveInternalTimer("Update", $hash); + myInternalTimer ("Update", time()+60, "$hash->{TYPE}_Update", $hash, 0); $hash->{VERZOEGRUNG} = 1; return 1 } @@ -512,7 +549,7 @@ sub Heating_Control_Device_Schalten($$$$) { if (defined $hash->{helper}{COMMAND} || ($nowSwitch gt "" && $aktParam ne $newParam )) { if (!$setModifier && $secondsSinceSwitch < -60) { - Log3 $hash, 5, $mod."no switch in the yesterdays because of the devices type($hash->{DEVICE}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 { if ($command && !$disabled) { $newParam =~ s/:/ /g; @@ -564,14 +601,12 @@ sub Heating_Control_isHeizung($) { my $dHash = $defs{$hash->{DEVICE}}; ### my $dType = $dHash->{TYPE}; return "" if (!defined($dType)); - Log3 $hash, 5, "dType------------>$dType"; my $setModifier = $setmodifiers{$dType}; $setModifier = "" if (!defined($setModifier)); if (ref($setModifier)) { my $subTypeReading = $setmodifiers{$dType}{subTypeReading}; - Log3 $hash, 5, "subTypeReading------------>$subTypeReading"; my $model; if ($subTypeReading eq "type" ) { @@ -777,6 +812,29 @@ sub SortNumber { Attributes
+ attr hc delayedExecutionCond isDelayed("%HEATING_CONTROL","%WEEKDAYTIMER","%TIME","%NAME","%EVENT") ++ the parameters %HEATING_CONTROL(timer name) %TIME %NAME(device name) %EVENT are replaced at runtime by the correct value. + +
+ sub isDelayed($$$$$) { + my($hc, $wdt, $tim, $nam, $event ) = @_; + + my $theSunIsStillshining = ... + + return ($tim eq "16:30" && $theSunIsStillshining) ; + } ++
+ attr wd delayedExecutionCond isDelayed("%HEATING_CONTROL","%WEEKDAYTIMER","%TIME","%NAME","%EVENT") ++ Die Parameter %HEATING_CONTROL(timer Name) %TIME %NAME(device Name) %EVENT werden zur Laufzeit durch die echten Werte ersetzt. + +
+ sub isDelayed($$$$$) { + my($hc, $wdt, $tim, $nam, $event ) = @_; + + my $theSunIsStillshining = ... + + return ($tim eq "16:30" && $theSunIsStillshining) ; + } ++
+ attr wd delayedExecutionCond isDelayed("%HEATING_CONTROL","%WEEKDAYTIMER","%TIME","%NAME","%EVENT") ++ the parameter %WEEKDAYTIMER(timer name) %TIME %NAME(device name) %EVENT are replaced at runtime by the correct value. + +
+ sub isDelayed($$$$$) { + my($hc, $wdt, $tim, $nam, $event ) = @_; + + my $theSunIsStillshining = ... + + return ($tim eq "16:30" && $theSunIsStillshining) ; + } ++