mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-20 19:36:02 +00:00
94_PWM.pm : add Attribute valveProtectIdlePeriod, implementiert Ventilschutz nach n Tagen
git-svn-id: https://svn.fhem.de/fhem/trunk@11781 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
1344193092
commit
473eb70940
@ -29,6 +29,8 @@
|
|||||||
# 27.01.16 GA add attribute desiredTempFrom to take desiredTemp from another object
|
# 27.01.16 GA add attribute desiredTempFrom to take desiredTemp from another object
|
||||||
# 04.02.16 GA add DLookBackCnt, buffer holding previouse temperatures used for PID D-Part calculation
|
# 04.02.16 GA add DLookBackCnt, buffer holding previouse temperatures used for PID D-Part calculation
|
||||||
# 08.02.16 GA add ILookBackCnt, buffer holding previouse temperatures used for PID I-Part calculation
|
# 08.02.16 GA add ILookBackCnt, buffer holding previouse temperatures used for PID I-Part calculation
|
||||||
|
# 08.02.16 GA add valueFormat attribute
|
||||||
|
# 29.06.16 GA add "set frostProtect on|off"
|
||||||
|
|
||||||
|
|
||||||
# module for PWM (Pulse Width Modulation) calculation
|
# module for PWM (Pulse Width Modulation) calculation
|
||||||
@ -88,6 +90,7 @@ sub PWMR_SetRoom(@);
|
|||||||
sub PWMR_ReadRoom(@);
|
sub PWMR_ReadRoom(@);
|
||||||
sub PWMR_Attr(@);
|
sub PWMR_Attr(@);
|
||||||
sub PWMR_Boost(@);
|
sub PWMR_Boost(@);
|
||||||
|
sub PWMR_valueFormat(@);
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
sub
|
sub
|
||||||
@ -115,6 +118,7 @@ PWMR_Initialize($)
|
|||||||
"tempRule3 ".
|
"tempRule3 ".
|
||||||
"tempRule4 ".
|
"tempRule4 ".
|
||||||
"tempRule5 ".
|
"tempRule5 ".
|
||||||
|
"valueFormat:textField-long ".
|
||||||
"";
|
"";
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -366,7 +370,7 @@ PWMR_Set($@)
|
|||||||
$valList .= ",30.0";
|
$valList .= ",30.0";
|
||||||
#my $u = "Unknown argument $a[1], choose one of factor actor:off,on desired-temp:knob,min:6,max:26,step:0.5,linecap:round interval manualTempDuration:slider,60,60,600";
|
#my $u = "Unknown argument $a[1], choose one of factor actor:off,on desired-temp:knob,min:6,max:26,step:0.5,linecap:round interval manualTempDuration:slider,60,60,600";
|
||||||
#my $u = "Unknown argument $a[1], choose one of factor actor:off,on desired-temp:uzsuDropDown:$valList interval manualTempDuration:slider,60,60,600";
|
#my $u = "Unknown argument $a[1], choose one of factor actor:off,on desired-temp:uzsuDropDown:$valList interval manualTempDuration:slider,60,60,600";
|
||||||
my $u = "Unknown argument $a[1], choose one of factor actor:off,on desired-temp:$valList interval manualTempDuration:slider,60,60,600";
|
my $u = "Unknown argument $a[1], choose one of factor actor:off,on desired-temp:$valList interval manualTempDuration:slider,60,60,600 frostProtect:off,on";
|
||||||
|
|
||||||
$valList = "slider,6,0.5,30,0.5";
|
$valList = "slider,6,0.5,30,0.5";
|
||||||
|
|
||||||
@ -441,6 +445,24 @@ PWMR_Set($@)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##############
|
||||||
|
# frostProtect
|
||||||
|
|
||||||
|
if ( $cmd eq "frostProtect" ) {
|
||||||
|
my $val = $a[2];
|
||||||
|
if ( $val eq "on" ) {
|
||||||
|
$hash->{c_frostProtect} = 1;
|
||||||
|
$attr{$name}{frostProtect} = 1;
|
||||||
|
return undef;
|
||||||
|
} elsif ( $val eq "off" ) {
|
||||||
|
$hash->{c_frostProtect} = 0;
|
||||||
|
$attr{$name}{frostProtect} = 0;
|
||||||
|
return undef;
|
||||||
|
} else {
|
||||||
|
return "Unknow argument for $cmd, choose on|off";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
##############
|
##############
|
||||||
# others
|
# others
|
||||||
|
|
||||||
@ -814,6 +836,8 @@ PWMR_ReadRoom(@)
|
|||||||
$temperaturT = $defs{$sensor}->{READINGS}{$reading}{TIME};
|
$temperaturT = $defs{$sensor}->{READINGS}{$reading}{TIME};
|
||||||
|
|
||||||
$temperaturV =~ s/$t_regexp/$1/;
|
$temperaturV =~ s/$t_regexp/$1/;
|
||||||
|
|
||||||
|
$temperaturV = PWMR_valueFormat ($room, "temperature", $temperaturV);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($room->{actor})
|
if ($room->{actor})
|
||||||
@ -1163,6 +1187,11 @@ PWMR_Attr(@)
|
|||||||
$hash->{STATE} = "Calculating";
|
$hash->{STATE} = "Calculating";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($attr eq "valueFormat" and defined ($hash->{helper}{$attr})) {
|
||||||
|
delete ($hash->{helper}{$attr});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!defined($val)) {
|
if (!defined($val)) {
|
||||||
@ -1240,6 +1269,32 @@ PWMR_Attr(@)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($attr eq "valueFormat") {
|
||||||
|
my $attrVal = $val;
|
||||||
|
if( $attrVal =~ m/^{.*}$/s && $attrVal =~ m/=>/ && $attrVal !~ m/\$/ ) {
|
||||||
|
my $av = eval $attrVal;
|
||||||
|
if( $@ ) {
|
||||||
|
Log3 ($hash->{NAME}, 3, $hash->{NAME} ." $attr: ". $@);
|
||||||
|
} else {
|
||||||
|
$attrVal = $av if( ref($av) eq "HASH" );
|
||||||
|
}
|
||||||
|
$hash->{helper}{$attr} = $attrVal;
|
||||||
|
|
||||||
|
foreach my $key (keys $hash->{helper}{$attr}) {
|
||||||
|
Log3 ($hash->{NAME}, 3, $hash->{NAME} ." $key ".$hash->{helper}{$attr}{$key});
|
||||||
|
}
|
||||||
|
|
||||||
|
#return "$attr set to $attrVal";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
# if valueFormat is not verified sucessfully ... the helper is deleted (=not used)
|
||||||
|
delete $hash->{helper}{$attr};
|
||||||
|
}
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1311,6 +1366,27 @@ PWMR_Boost(@)
|
|||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
PWMR_valueFormat(@)
|
||||||
|
{
|
||||||
|
my ($hash, $reading, $value) = @_;
|
||||||
|
|
||||||
|
return $value unless (defined ($reading));
|
||||||
|
|
||||||
|
if (ref($hash->{helper}{valueFormat}) eq 'HASH')
|
||||||
|
{
|
||||||
|
|
||||||
|
if (exists($hash->{helper}{valueFormat}->{$reading})) {
|
||||||
|
|
||||||
|
my $vf = $hash->{helper}{valueFormat}->{$reading};
|
||||||
|
return sprintf ("$vf", $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
@ -1418,6 +1494,11 @@ PWMR_Boost(@)
|
|||||||
Temporary change <i>INTERVAL</i> which defines how often <i>desired-temp</i> is calculated in autoCalcMode. Default is 300 seconds (5:00 Minutes).
|
Temporary change <i>INTERVAL</i> which defines how often <i>desired-temp</i> is calculated in autoCalcMode. Default is 300 seconds (5:00 Minutes).
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
|
<li>frostProtect<br>
|
||||||
|
Sets attribute frostProtect to 1 (on) or 0 (off).
|
||||||
|
</li><br>
|
||||||
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@ -1479,6 +1560,12 @@ PWMR_Boost(@)
|
|||||||
Calculation of desired-temp is (like when using tempRules) based on the interval specified for this device (default is 300 seconds).
|
Calculation of desired-temp is (like when using tempRules) based on the interval specified for this device (default is 300 seconds).
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
|
<li>valueFormat<br>
|
||||||
|
Defines a map to format values within PWMR.<br>
|
||||||
|
The following reading can be formated using syntax of sprinf: temperature
|
||||||
|
<br>
|
||||||
|
Example: { "temperature" => "%0.2f" }
|
||||||
|
</li><br>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
# 30.11.15 GA add new followUpTime can now delay switching of OverallHeatingSwitch from "on" to "off"
|
# 30.11.15 GA add new followUpTime can now delay switching of OverallHeatingSwitch from "on" to "off"
|
||||||
# 26.01.16 GA fix don't call AssignIoPort
|
# 26.01.16 GA fix don't call AssignIoPort
|
||||||
# 26.01.16 GA fix IODev from PWMR object is now a reference to PWM object
|
# 26.01.16 GA fix IODev from PWMR object is now a reference to PWM object
|
||||||
|
# 29.06.16 GA add attribute valveProtectIdlePeriod
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
# $Id:
|
# $Id:
|
||||||
@ -66,8 +67,9 @@ PWM_Initialize($)
|
|||||||
$hash->{SetFn} = "PWM_Set";
|
$hash->{SetFn} = "PWM_Set";
|
||||||
$hash->{DefFn} = "PWM_Define";
|
$hash->{DefFn} = "PWM_Define";
|
||||||
$hash->{UndefFn} = "PWM_Undef";
|
$hash->{UndefFn} = "PWM_Undef";
|
||||||
|
$hash->{AttrFn} = "PWM_Attr";
|
||||||
|
|
||||||
$hash->{AttrList} = "event-on-change-reading";
|
$hash->{AttrList} = "event-on-change-reading valveProtectIdlePeriod";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +84,7 @@ PWM_Calculate($)
|
|||||||
my %RoomsToSwitchOff = ();
|
my %RoomsToSwitchOff = ();
|
||||||
my %RoomsToStayOn = ();
|
my %RoomsToStayOn = ();
|
||||||
my %RoomsToStayOff = ();
|
my %RoomsToStayOff = ();
|
||||||
|
my %RoomsValveProtect = ();
|
||||||
my %RoomsPulses = ();
|
my %RoomsPulses = ();
|
||||||
my $roomsActive = 0;
|
my $roomsActive = 0;
|
||||||
my $newpulseSum = 0;
|
my $newpulseSum = 0;
|
||||||
@ -119,16 +122,23 @@ PWM_Calculate($)
|
|||||||
# calculate room
|
# calculate room
|
||||||
# $newstate is "" if state is unchanged
|
# $newstate is "" if state is unchanged
|
||||||
# $newstate is "on" or "off" if state changes
|
# $newstate is "on" or "off" if state changes
|
||||||
|
# $newstate may be "on_vp" or "off_vp" if valve protection is active
|
||||||
my ($newstate, $newpulse, $cycletime, $oldstate) = PWM_CalcRoom($hash, $defs{$d});
|
my ($newstate, $newpulse, $cycletime, $oldstate) = PWM_CalcRoom($hash, $defs{$d});
|
||||||
|
|
||||||
$defs{$d}->{READINGS}{oldpulse}{TIME} = TimeNow();
|
$defs{$d}->{READINGS}{oldpulse}{TIME} = TimeNow();
|
||||||
$defs{$d}->{READINGS}{oldpulse}{VAL} = $newpulse;
|
$defs{$d}->{READINGS}{oldpulse}{VAL} = $newpulse;
|
||||||
|
|
||||||
my $onoff = $newpulse * $cycletime;
|
my $onoff = $newpulse * $cycletime;
|
||||||
if ($newstate eq "off") {
|
if ($newstate =~ "off.*") {
|
||||||
$onoff = (1 - $newpulse) * $cycletime
|
$onoff = (1 - $newpulse) * $cycletime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($newstate eq "on_vp") {
|
||||||
|
$RoomsValveProtect{$d} = "on";
|
||||||
|
} elsif ($newstate eq "off_vp") {
|
||||||
|
$RoomsValveProtect{$d} = "off";
|
||||||
|
}
|
||||||
|
|
||||||
$wkey = $name."_".$d;
|
$wkey = $name."_".$d;
|
||||||
if (defined ($roomsWaitOffset{$wkey})) {
|
if (defined ($roomsWaitOffset{$wkey})) {
|
||||||
$newpulse += $roomsWaitOffset{$wkey};
|
$newpulse += $roomsWaitOffset{$wkey};
|
||||||
@ -144,7 +154,7 @@ PWM_Calculate($)
|
|||||||
|
|
||||||
# $newstate ne "" -> state changed "on" -> "off" or "off" -> "on"
|
# $newstate ne "" -> state changed "on" -> "off" or "off" -> "on"
|
||||||
if ((int($hash->{MINONOFFTIME}) > 0) &&
|
if ((int($hash->{MINONOFFTIME}) > 0) &&
|
||||||
($newstate ne "") &&
|
(($newstate eq "on") or ($newstate eq "off")) &&
|
||||||
($onoff < int($hash->{MINONOFFTIME}))
|
($onoff < int($hash->{MINONOFFTIME}))
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -341,11 +351,9 @@ PWM_Calculate($)
|
|||||||
}
|
}
|
||||||
$minRoomsOnList =~ s/,$//;
|
$minRoomsOnList =~ s/,$//;
|
||||||
|
|
||||||
#if ($roomsActive == 0 or $hash->{NoRoomsToStayOnThreshold} == 0 or $newpulseSum/$roomsActive < $hash->{NoRoomsToStayOnThreshold})
|
|
||||||
|
|
||||||
|
|
||||||
if ($roomsActive == 0 or $hash->{NoRoomsToStayOnThreshold} == 0 or $pulseSum/$roomsCounted < $hash->{NoRoomsToStayOnThreshold}) {
|
if ($roomsActive == 0 or $hash->{NoRoomsToStayOnThreshold} == 0 or $pulseSum/$roomsCounted < $hash->{NoRoomsToStayOnThreshold}) {
|
||||||
$minRoomsOn = 0;
|
$minRoomsOn = 0;
|
||||||
|
$minRoomsOnList = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
#Log3 ($hash, 3, "PWM_Calculate: newpulseSum $newpulseSum avg ".$newpulseSum/$roomsActive." minRoomsOn(".$minRoomsOn.")") if ($roomsActive > 0);
|
#Log3 ($hash, 3, "PWM_Calculate: newpulseSum $newpulseSum avg ".$newpulseSum/$roomsActive." minRoomsOn(".$minRoomsOn.")") if ($roomsActive > 0);
|
||||||
@ -428,6 +436,26 @@ PWM_Calculate($)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach my $roomVP (sort keys %RoomsValveProtect) {
|
||||||
|
|
||||||
|
my $wkey = $name."-".$roomVP;
|
||||||
|
$roomsWaitOffset{$wkey} = 0;
|
||||||
|
|
||||||
|
if ( $RoomsValveProtect{$roomVP} eq "on") {
|
||||||
|
|
||||||
|
PWMR_SetRoom ($defs{$roomVP}, "on");
|
||||||
|
$cntRoomsOn++;
|
||||||
|
$pulseRoomsOn += $RoomsPulses{$roomVP};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
PWMR_SetRoom ($defs{$roomVP}, "off");
|
||||||
|
$cntRoomsOff++;
|
||||||
|
$pulseRoomsOff += $RoomsPulses{$roomVP};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
readingsBulkUpdate ($hash, "roomsActive", $roomsActive);
|
readingsBulkUpdate ($hash, "roomsActive", $roomsActive);
|
||||||
readingsBulkUpdate ($hash, "roomsOn", $cntRoomsOn);
|
readingsBulkUpdate ($hash, "roomsOn", $cntRoomsOn);
|
||||||
@ -445,33 +473,33 @@ PWM_Calculate($)
|
|||||||
if ( defined ($hash->{OverallHeatingSwitch}) ) {
|
if ( defined ($hash->{OverallHeatingSwitch}) ) {
|
||||||
if ( $hash->{OverallHeatingSwitch} ne "") {
|
if ( $hash->{OverallHeatingSwitch} ne "") {
|
||||||
|
|
||||||
my $newstate = "on";
|
my $newstateOHS = "on";
|
||||||
if ( $hash->{OverallHeatingSwitch_threshold} > 0) {
|
if ( $hash->{OverallHeatingSwitch_threshold} > 0) {
|
||||||
|
|
||||||
# threshold based
|
# threshold based
|
||||||
$newstate = ($newpulseMax > $hash->{OverallHeatingSwitch_threshold}) ? "on" : "off";
|
$newstateOHS = ($newpulseMax > $hash->{OverallHeatingSwitch_threshold}) ? "on" : "off";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
# room based
|
# room based
|
||||||
$newstate = ($cntRoomsOn > 0) ? "on" : "off";
|
$newstateOHS = ($cntRoomsOn > 0) ? "on" : "off";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
my $actor = $hash->{OverallHeatingSwitch};
|
my $actor = $hash->{OverallHeatingSwitch};
|
||||||
my $actstate = ($defs{$actor}{STATE} =~ $hash->{OverallHeatingSwitch_regexp_on}) ? "on" : "off";
|
my $actstateOHS = ($defs{$actor}{STATE} =~ $hash->{OverallHeatingSwitch_regexp_on}) ? "on" : "off";
|
||||||
|
|
||||||
if ($hash->{OverallHeatingSwitch_followUpTime} > 0) {
|
if ($hash->{OverallHeatingSwitch_followUpTime} > 0) {
|
||||||
|
|
||||||
if ($actstate eq "on" and $newstate eq "off") {
|
if ($actstateOHS eq "on" and $newstateOHS eq "off") {
|
||||||
|
|
||||||
if ($hash->{READINGS}{OverallHeatingSwitchWaitUntil}{VAL} eq "") {
|
if ($hash->{READINGS}{OverallHeatingSwitchWaitUntil}{VAL} eq "") {
|
||||||
$newstate = "on";
|
$newstateOHS = "on";
|
||||||
Log3 ($name, 2, "PWM_Calculate: $name: OverallHeatingSwitch wait for followUpTime before switching off (init timestamp)");
|
Log3 ($name, 2, "PWM_Calculate: $name: OverallHeatingSwitch wait for followUpTime before switching off (init timestamp)");
|
||||||
readingsBulkUpdate ($hash, "OverallHeatingSwitchWaitUntil", FmtDateTime(time() + $hash->{OverallHeatingSwitch_followUpTime}));
|
readingsBulkUpdate ($hash, "OverallHeatingSwitchWaitUntil", FmtDateTime(time() + $hash->{OverallHeatingSwitch_followUpTime}));
|
||||||
|
|
||||||
} elsif ($hash->{READINGS}{OverallHeatingSwitchWaitUntil}{VAL} ge TimeNow()) {
|
} elsif ($hash->{READINGS}{OverallHeatingSwitchWaitUntil}{VAL} ge TimeNow()) {
|
||||||
$newstate = "on";
|
$newstateOHS = "on";
|
||||||
Log3 ($name, 2, "PWM_Calculate: $name: OverallHeatingSwitch wait for followUpTime before switching off");
|
Log3 ($name, 2, "PWM_Calculate: $name: OverallHeatingSwitch wait for followUpTime before switching off");
|
||||||
} else {
|
} else {
|
||||||
readingsBulkUpdate ($hash, "OverallHeatingSwitchWaitUntil", "");
|
readingsBulkUpdate ($hash, "OverallHeatingSwitchWaitUntil", "");
|
||||||
@ -482,19 +510,19 @@ PWM_Calculate($)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($newstate ne $actstate or $hash->{READINGS}{OverallHeatingSwitch}{VAL} ne $actstate) {
|
if ($newstateOHS ne $actstateOHS or $hash->{READINGS}{OverallHeatingSwitch}{VAL} ne $actstateOHS) {
|
||||||
|
|
||||||
my $ret = fhem sprintf ("set %s %s", $hash->{OverallHeatingSwitch}, $newstate);
|
my $ret = fhem sprintf ("set %s %s", $hash->{OverallHeatingSwitch}, $newstateOHS);
|
||||||
if (!defined($ret)) { # sucessfull
|
if (!defined($ret)) { # sucessfull
|
||||||
Log3 ($name, 4, "PWMR_SetRoom: $name: set $actor $newstate");
|
Log3 ($name, 4, "PWMR_SetRoom: $name: set $actor $newstateOHS");
|
||||||
|
|
||||||
readingsBulkUpdate ($hash, "OverallHeatingSwitch", $newstate);
|
readingsBulkUpdate ($hash, "OverallHeatingSwitch", $newstateOHS);
|
||||||
|
|
||||||
# push @{$room->{CHANGED}}, "actor $newstate";
|
# push @{$room->{CHANGED}}, "actor $newstateOHS";
|
||||||
# DoTrigger($name, undef);
|
# DoTrigger($name, undef);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log3 ($name, 4, "PWMR_SetRoom $name: set $actor $newstate failed ($ret)");
|
Log3 ($name, 4, "PWMR_SetRoom $name: set $actor $newstateOHS failed ($ret)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -534,6 +562,22 @@ PWM_CalcRoom(@)
|
|||||||
|
|
||||||
if ($actorV eq "on") # current state is "on"
|
if ($actorV eq "on") # current state is "on"
|
||||||
{
|
{
|
||||||
|
# ----------------
|
||||||
|
# check if valve protection is active, keep this state for 5 minutes
|
||||||
|
|
||||||
|
if (defined ($room->{helper}{valveProtectLastSwitch})) {
|
||||||
|
if ( $room->{helper}{valveProtectLastSwitch} + 300 > time()) {
|
||||||
|
Log3 ($hash, 3, "PWM_CalcRoom $room->{NAME}: F13 valveProtect continue");
|
||||||
|
return ("", $newpulse, $cycletime, $actorV);
|
||||||
|
} else {
|
||||||
|
Log3 ($hash, 3, "PWM_CalcRoom $room->{NAME}: F14 valveProtect off");
|
||||||
|
delete ($room->{helper}{valveProtectLastSwitch});
|
||||||
|
return ("off_vp", $newpulse, $cycletime, $actorV);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------
|
||||||
# decide if to change to "off"
|
# decide if to change to "off"
|
||||||
|
|
||||||
if ($newpulse == 1) {
|
if ($newpulse == 1) {
|
||||||
@ -577,6 +621,20 @@ PWM_CalcRoom(@)
|
|||||||
}
|
}
|
||||||
elsif ($actorV eq "off") # current state is "off"
|
elsif ($actorV eq "off") # current state is "off"
|
||||||
{
|
{
|
||||||
|
# ----------------
|
||||||
|
# check if valve protection is activated (attribute valveProtectIdlePeriod is set)
|
||||||
|
|
||||||
|
if (defined ($attr{$name}{"valveProtectIdlePeriod"})) {
|
||||||
|
# period is defined in days (*86400)
|
||||||
|
if ($room->{READINGS}{lastswitch}{VAL} + ($attr{$name}{"valveProtectIdlePeriod"} * 86400) < time()) {
|
||||||
|
|
||||||
|
$room->{helper}{valveProtectLastSwitch} = time();
|
||||||
|
Log3 ($hash, 3, "PWM_CalcRoom $room->{NAME}: F12 valve protect");
|
||||||
|
return ("on_vp", $newpulse, $cycletime, $actorV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------
|
||||||
# decide if to change to "on"
|
# decide if to change to "on"
|
||||||
|
|
||||||
if ($oldpulse == 0 && $newpulse > 0) { # was 0% now heating is required
|
if ($oldpulse == 0 && $newpulse > 0) { # was 0% now heating is required
|
||||||
@ -615,6 +673,7 @@ PWM_CalcRoom(@)
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else # $actorV not "on" of "off"
|
else # $actorV not "on" of "off"
|
||||||
{
|
{
|
||||||
@ -806,6 +865,37 @@ sub PWM_Undef($$)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
PWM_Attr(@)
|
||||||
|
{
|
||||||
|
my @a = @_;
|
||||||
|
my ($action, $name, $attrname, $attrval) = @a;
|
||||||
|
|
||||||
|
my $hash = $defs{$name};
|
||||||
|
|
||||||
|
$attrval = "" unless defined ($attrval);
|
||||||
|
|
||||||
|
if ($action eq "del")
|
||||||
|
{
|
||||||
|
if (defined $attr{$name}{$attrname}) {
|
||||||
|
delete ($attr{$name}{$attrname});
|
||||||
|
}
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
elsif ($action eq "set")
|
||||||
|
{
|
||||||
|
if (defined $attr{$name}{$attrname})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log3 (undef, 2, "called PWM_Attr($a[0],$a[1],$a[2],<$a[3]>)");
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
1;
|
1;
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
@ -874,7 +964,7 @@ sub PWM_Undef($$)
|
|||||||
<br>
|
<br>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>overallHeatingSwitch>[,<pulseMaxThreshold>[,<followUpTime>[,<regexp_on>]]]<br>
|
<li><overallHeatingSwitch>[,<pulseMaxThreshold>[,<followUpTime>[,<regexp_on>]]]<br>
|
||||||
Universal switch to controll eg. pumps or the heater itself. It will be set to "off" if no heating is required and otherwise "on".<br>
|
Universal switch to controll eg. pumps or the heater itself. It will be set to "off" if no heating is required and otherwise "on".<br>
|
||||||
<i>pulseMaxThreshold</i> defines a threshold which is applied to reading <i>maxPulse</i> of the PWM object to decide if heating is required. If (calculated maxPulse > threshold) then actor is set to "on", otherwise "off".<br>
|
<i>pulseMaxThreshold</i> defines a threshold which is applied to reading <i>maxPulse</i> of the PWM object to decide if heating is required. If (calculated maxPulse > threshold) then actor is set to "on", otherwise "off".<br>
|
||||||
If <i>pulseMaxThreshold</i> is set to 0 (or is not defined) then the decision is based on <i>roomsOn</i>. If (roomsOn > 0) then actor is set to "on", otherwise "off".<br>
|
If <i>pulseMaxThreshold</i> is set to 0 (or is not defined) then the decision is based on <i>roomsOn</i>. If (roomsOn > 0) then actor is set to "on", otherwise "off".<br>
|
||||||
@ -926,6 +1016,11 @@ sub PWM_Undef($$)
|
|||||||
|
|
||||||
<b>Attributes</b>
|
<b>Attributes</b>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>valveProtectIdlePeriod<br>
|
||||||
|
Protect Valve by switching on actor for 300 seconds.<br>
|
||||||
|
After <i>valveProtectIdlePeriod</i> number of days without switching the valve the actor is set to "on" for 300 seconds.
|
||||||
|
overallHeatingSwitch is not affected.
|
||||||
|
</li><br>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
</ul>
|
</ul>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user