diff --git a/fhem/FHEM/93_PWMR.pm b/fhem/FHEM/93_PWMR.pm index 16e58c06c..37742b051 100644 --- a/fhem/FHEM/93_PWMR.pm +++ b/fhem/FHEM/93_PWMR.pm @@ -55,7 +55,12 @@ # 11.02.19 GA add redesign of maxOffTime # 21.01.20 GA fix remove default tempRule if only tempRule1 or tempRule2 is defined # 28.12.20 GA fix reset maxOffTimeApply to 0 if heating is needed (decision depends on calculation model) - +# 20.01.21 GA fix remove DoTrigger; +# the below due to hints from phys1 +# fix prevent parallel InternalTimer calls +# fix remove attribute loglevel +# fix reading actorState to correct when non default regex is used +# add clear PID helper structure when PWM or PWMR object gets disabled # module for PWM (Pulse Width Modulation) calculation # this module defines a room for calculation @@ -127,7 +132,7 @@ PWMR_Initialize($) $hash->{UndefFn} = "PWMR_Undef"; $hash->{AttrFn} = "PWMR_Attr"; - $hash->{AttrList} = "disable:1,0 loglevel:0,1,2,3,4,5 ". + $hash->{AttrList} = "disable:1,0 ". "frostProtect:0,1 ". "autoCalcTemp:0,1 ". "desiredTempFrom ". @@ -294,14 +299,31 @@ PWMR_CalcDesiredTemp($) my $offset = ((((int($min/ 5)) +1 ) * 5 ) - $min) * 60; #Log3 ($hash, 4, "offset $min -> ".int($min / 5)." $offset ".($offset / 60)); + RemoveInternalTimer($hash, "PWMR_CalcDesiredTemp"); InternalTimer($n + $offset, "PWMR_CalcDesiredTemp", $hash, 0); } else { + RemoveInternalTimer($hash, "PWMR_CalcDesiredTemp"); InternalTimer(gettimeofday()+$hash->{INTERVAL}, "PWMR_CalcDesiredTemp", $hash, 0); #Log3 ($hash, 4, "interval not 300"); } } + # as suggested by phys1 + # If this device or the IODevice have been disabled, the actor state + # and the I- and D-Buffer are no longer valid and have to be reset + my $iodev = $hash->{IODev}; + my $IODev_Disabled = (defined($iodev->{NAME})&&IsDevice($iodev->{NAME},"PWM")&&IsDisabled($iodev->{NAME}))? 1:0; + if (IsDisabled($name) || $IODev_Disabled) { + readingsSingleUpdate ($hash, "actorState", "unknown", 1); # forces PWMR_ReadRoom to read actorState from device when enabled again + if ($hash->{c_PID_useit} != 0) { + delete ($hash->{helper}{PID_I_previousTemps}) if (defined (($hash->{helper}{PID_I_previousTemps}))); + delete ($hash->{helper}{PID_D_previousTemps}) if (defined (($hash->{helper}{PID_D_previousTemps}))); + $hash->{helper}{PID_I_previousTemps} = [] if ($hash->{c_PID_useit} == 1); + $hash->{helper}{PID_D_previousTemps} = []; + } + } + if (defined($hash->{READINGS}{"desired-temp-until"})) { if ($hash->{READINGS}{"desired-temp-until"}{VAL} ne "no" ) { @@ -334,8 +356,6 @@ PWMR_CalcDesiredTemp($) #$hash->{READINGS}{"desired-tem"}{TIME} = TimeNow(); #$hash->{READINGS}{"desired-temp"}{VAL} = $hash->{c_tempFrostProtect}; - #push @{$hash->{CHANGED}}, "desired-temp $hash->{c_tempFrostProtect}"; - #DoTrigger($name, undef); #$hash->{STATE} = "FrostProtect"; readingsSingleUpdate ($hash, "state", "FrostProtect", 1); @@ -380,7 +400,6 @@ PWMR_CalcDesiredTemp($) readingsSingleUpdate ($hash, "state", "Manual", 1); } - #DoTrigger($name, undef); return undef; } @@ -409,7 +428,6 @@ PWMR_Get($@) return "unknown get value, valid is status"; } $hash->{LOCAL} = 1; - RemoveInternalTimer($hash); my $v = PWMR_CalcDesiredTemp($hash); delete $hash->{LOCAL}; @@ -513,8 +531,6 @@ PWMR_Set($@) #$hash->{READINGS}{$cmd}{VAL} = $val; - #push @{$hash->{CHANGED}}, "$cmd: $val"; - #DoTrigger($hash, undef); return undef } @@ -875,6 +891,7 @@ PWMR_Define($$) } if($hash->{INTERVAL}) { + RemoveInternalTimer($hash, "PWMR_CalcDesiredTemp"); InternalTimer(gettimeofday()+10, "PWMR_CalcDesiredTemp", $hash, 0); } return undef; @@ -935,14 +952,12 @@ PWMR_SetRoom(@) if (!defined($ret)) { # sucessfull Log3 ($room, 2, "PWMR_SetRoom $room->{NAME}: set $room->{actor} $newState"); - #$room->{actorState} = $newState; - readingsBulkUpdate ($room, "actorState", $newState); readingsBulkUpdate ($room, "lastswitch", time()); readingsEndUpdate($room, 1); - push @{$room->{CHANGED}}, "actor $newState"; - DoTrigger($name, undef); + #push @{$room->{CHANGED}}, "actor $newState"; + #DoTrigger($name, undef); } else { Log3 ($room, 2, "PWMR_SetRoom $name: set $room->{actor} $newState failed ($ret)"); @@ -995,29 +1010,23 @@ PWMR_ReadRoom(@) if (defined($room->{actor})) { + my $a_regexp_on = $room->{a_regexp_on}; + # starting from 26.01.2013 -> try to read act status .. (may also be invalid if struct) if ($defs{$room->{actor}}->{TYPE} eq "RBRelais") { - $actorV = $defs{$room->{actor}}->{STATE}; + #$actorV = $defs{$room->{actor}}->{STATE}; + $actorV = ($defs{$room->{actor}}->{STATE} =~ /^$a_regexp_on$/) ? "on" : "off"; $room->{READINGS}{actorState}{VAL} = $actorV; } elsif (defined($defs{$room->{actor}}->{STATE})) { - $actorV = $defs{$room->{actor}}->{STATE}; + $actorV = ($defs{$room->{actor}}->{STATE} =~ /^$a_regexp_on$/) ? "on" : "off"; $room->{READINGS}{actorState}{VAL} = $actorV if ($room->{READINGS}{actorState}{VAL} eq "unknown"); } elsif (defined($defs{$room->{actor}}->{READINGS}{state}{VAL})) { - $actorV = $room->{READINGS}{actorState}{VAL}; + $actorV = ($defs{$room->{actor}}->{STATE} =~ /^$a_regexp_on$/) ? "on" : "off"; $room->{READINGS}{actorState}{VAL} = $actorV if ($room->{READINGS}{actorState}{VAL} eq "unknown"); } else { #$actorV = $room->{actorState}; $actorV = $room->{READINGS}{actorState}{VAL}; } - - #my $actorVOrg = $actorV; - - my $a_regexp_on = $room->{a_regexp_on}; - if ($actorV =~ /^$a_regexp_on$/) { - $actorV = "on"; - } else { - $actorV = "off"; - } #Log3 ($room, 2, "$name actorV $actorV org($actorVOrg) regexp($a_regexp_on)"); }