mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-08 01:14:19 +00:00
93_PWMR.pm : restructured readings
git-svn-id: https://svn.fhem.de/fhem/trunk@9817 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
e966257d92
commit
5814683d6f
@ -13,6 +13,9 @@
|
||||
# 13.10.15 GA add event-on-change-reading
|
||||
# 14.10.15 GA fix round energyusedp
|
||||
# 15.10.15 GA add a_regexp_on, a regular expression for the on state of the actor
|
||||
# 05.11.15 GA fix new reading desired-temp-until which substitutes modification date of desired-temp in the future
|
||||
# events for desired-temp adjusted (no update of timestamp if temperature stays the same)
|
||||
|
||||
|
||||
# module for PWM (Pulse Width Modulation) calculation
|
||||
# this module defines a room for calculation
|
||||
@ -107,10 +110,8 @@ PWMR_CalcDesiredTemp($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{STATE} = "Calculating";
|
||||
|
||||
if($hash->{INTERVAL} > 0) {
|
||||
if ($hash->{INTERVAL} eq 300) {
|
||||
if ($hash->{INTERVAL} == 300) {
|
||||
# align interval to hh:00:ss, hh:05:ss, ... hh:55:ss
|
||||
|
||||
my $n = gettimeofday();
|
||||
@ -129,21 +130,44 @@ PWMR_CalcDesiredTemp($)
|
||||
}
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
if ($hash->{READINGS}{"desired-temp"}{TIME} gt TimeNow()) {
|
||||
Log3 ($hash, 4, "PWMR_CalcDesiredTemp $name: desired-temp was manualy set until ".
|
||||
$hash->{READINGS}{"desired-temp"}{TIME});
|
||||
|
||||
$hash->{STATE} = "ManualSetUntil";
|
||||
return undef;
|
||||
} else {
|
||||
Log3 ($hash, 4, "PWMR_CalcDesiredTemp $name: calc desired-temp");
|
||||
if (defined($hash->{READINGS}{"desired-temp-until"})) {
|
||||
if ($hash->{READINGS}{"desired-temp-until"}{VAL} ne "no" ) {
|
||||
|
||||
if ($hash->{READINGS}{"desired-temp-until"}{VAL} gt TimeNow()) {
|
||||
|
||||
Log3 ($hash, 4, "PWMR_CalcDesiredTemp $name: desired-temp was manualy set until ".
|
||||
$hash->{READINGS}{"desired-temp"}{TIME});
|
||||
$hash->{STATE} = "ManualSetUntil";
|
||||
return undef;
|
||||
}
|
||||
else
|
||||
{
|
||||
readingsSingleUpdate ($hash, "desired-temp-until", "no", 1);
|
||||
Log3 ($hash, 4, "PWMR_CalcDesiredTemp $name: calc desired-temp");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if ($hash->{READINGS}{"desired-temp"}{TIME} gt TimeNow()) {
|
||||
# Log3 ($hash, 4, "PWMR_CalcDesiredTemp $name: desired-temp was manualy set until ".
|
||||
# $hash->{READINGS}{"desired-temp"}{TIME});
|
||||
#
|
||||
# $hash->{STATE} = "ManualSetUntil";
|
||||
# return undef;
|
||||
#} else {
|
||||
# Log3 ($hash, 4, "PWMR_CalcDesiredTemp $name: calc desired-temp");
|
||||
#}
|
||||
|
||||
####################
|
||||
# frost protection
|
||||
|
||||
if ($hash->{c_frostProtect} > 0) {
|
||||
readingsSingleUpdate ($hash, "desired-temp", $hash->{c_tempFrostProtect}, 1);
|
||||
if ($hash->{READINGS}{"desired-temp"}{VAL} ne $hash->{c_tempFrostProtect}) {
|
||||
readingsSingleUpdate ($hash, "desired-temp", $hash->{c_tempFrostProtect}, 1);
|
||||
} else {
|
||||
readingsSingleUpdate ($hash, "desired-temp", $hash->{c_tempFrostProtect}, 0);
|
||||
}
|
||||
|
||||
#$hash->{READINGS}{"desired-tem"}{TIME} = TimeNow();
|
||||
#$hash->{READINGS}{"desired-temp"}{VAL} = $hash->{c_tempFrostProtect};
|
||||
@ -160,6 +184,8 @@ PWMR_CalcDesiredTemp($)
|
||||
|
||||
if ($hash->{c_autoCalcTemp} > 0) {
|
||||
|
||||
$hash->{STATE} = "Calculating";
|
||||
|
||||
my @time = localtime();
|
||||
my $wday = $time[6];
|
||||
my $cmptime = sprintf ("%02d%02d", $time[2], $time[1]);
|
||||
@ -202,7 +228,11 @@ PWMR_CalcDesiredTemp($)
|
||||
|
||||
Log3 ($hash, 4, "PWMR_CalcDesiredTemp $name: match i:$i $points[$i] ($tempV/$temperature)");
|
||||
|
||||
readingsSingleUpdate ($hash, "desired-temp", $temperature, 1);
|
||||
if ($hash->{READINGS}{"desired-temp"}{VAL} ne $temperature) {
|
||||
readingsSingleUpdate ($hash, "desired-temp", $temperature, 1);
|
||||
} else {
|
||||
readingsSingleUpdate ($hash, "desired-temp", $temperature, 0);
|
||||
}
|
||||
|
||||
#$hash->{READINGS}{"desired-temp"}{TIME} = TimeNow();
|
||||
#$hash->{READINGS}{"desired-temp"}{VAL} = $temperature;
|
||||
@ -221,7 +251,11 @@ PWMR_CalcDesiredTemp($)
|
||||
my $act_dtemp = $hash->{READINGS}{"desired-temp"}{VAL};
|
||||
Log3 ($hash, 4, "PWMR_CalcDesiredTemp $name: use last value ($act_dtemp)");
|
||||
|
||||
readingsSingleUpdate ($hash, "desired-temp", $newTemp, 1);
|
||||
if ($act_dtemp ne $newTemp) {
|
||||
readingsSingleUpdate ($hash, "desired-temp", $newTemp, 1);
|
||||
#} else {
|
||||
# readingsSingleUpdate ($hash, "desired-temp", $newTemp, 0);
|
||||
}
|
||||
|
||||
#$hash->{READINGS}{"desired-temp"}{TIME} = TimeNow();
|
||||
#$hash->{READINGS}{"desired-temp"}{VAL} = $newTemp;
|
||||
@ -237,7 +271,7 @@ PWMR_CalcDesiredTemp($)
|
||||
$hash->{STATE} = "Manual";
|
||||
}
|
||||
|
||||
DoTrigger($name, undef);
|
||||
#DoTrigger($name, undef);
|
||||
return undef;
|
||||
|
||||
}
|
||||
@ -289,7 +323,7 @@ PWMR_Set($@)
|
||||
# manualTempDuration
|
||||
|
||||
if ( $cmd eq "manualTempDuration" ) {
|
||||
readingsSingleUpdate ($hash, "manualTempDuration", $a[2], 0);
|
||||
readingsSingleUpdate ($hash, "manualTempDuration", $a[2], 1);
|
||||
|
||||
#$hash->{READINGS}{"manualTempDuration"}{VAL} = $a[2];
|
||||
#$hash->{READINGS}{"manualTempDuration"}{TIME} = TimeNow();
|
||||
@ -311,18 +345,29 @@ PWMR_Set($@)
|
||||
$duration = int($a[3]) * 60;
|
||||
}
|
||||
|
||||
#$hash->{READINGS}{$cmd}{TIME} = TimeNow();
|
||||
|
||||
# manual set desired-temp will be set for 1 hour (default)
|
||||
# afterwards it will be overwritten by auto calc
|
||||
|
||||
my $now = time();
|
||||
|
||||
$hash->{READINGS}{$cmd}{TIME} = FmtDateTime($now + $duration);
|
||||
$hash->{READINGS}{$cmd}{VAL} = $val;
|
||||
readingsBeginUpdate ($hash);
|
||||
readingsBulkUpdate ($hash, "desired-temp", $a[2]);
|
||||
if ($hash->{c_autoCalcTemp} == 0) {
|
||||
$hash->{STATE} = "Manual";
|
||||
} else {
|
||||
$hash->{STATE} = "ManualSetUntil";
|
||||
readingsBulkUpdate ($hash, "desired-temp-until", FmtDateTime($now + $duration));
|
||||
}
|
||||
readingsEndUpdate($hash, 1);
|
||||
|
||||
#readingsSingleUpdate ($hash, "desired-temp", $a[2], 1);
|
||||
|
||||
$hash->{STATE} = "ManualSetUntil";
|
||||
#$hash->{READINGS}{$cmd}{TIME} = FmtDateTime($now + $duration);
|
||||
#$hash->{READINGS}{$cmd}{VAL} = $val;
|
||||
|
||||
|
||||
#push @{$hash->{CHANGED}}, "$cmd: $val";
|
||||
#DoTrigger($hash, undef);
|
||||
return undef
|
||||
}
|
||||
|
||||
@ -526,27 +571,26 @@ PWMR_SetRoom(@)
|
||||
|
||||
Log3 ($room, 4, "PWMR_SetRoom $name <$newState>");
|
||||
|
||||
my $nowR = TimeNow();
|
||||
my $now = time();
|
||||
|
||||
$room->{READINGS}{energyused}{TIME} = $nowR;
|
||||
$room->{READINGS}{energyusedp}{TIME} = $nowR;
|
||||
if (!defined($room->{READINGS}{energyused}{VAL})) {
|
||||
$room->{READINGS}{energyused}{VAL} = "";
|
||||
my $energyused = "";
|
||||
if (defined($room->{READINGS}{energyused}{VAL})) {
|
||||
$energyused = substr ( $room->{READINGS}{energyused}{VAL}, -29);
|
||||
}
|
||||
|
||||
my $energyused = substr ( $room->{READINGS}{energyused}{VAL}, -29);
|
||||
|
||||
# newState may be "", "on", "off"
|
||||
if ($newState eq "") {
|
||||
$energyused = $energyused.substr ( $energyused ,-1);
|
||||
} else {
|
||||
$energyused = $energyused.($newState eq "on" ? "1" : "0");
|
||||
}
|
||||
$room->{READINGS}{energyused}{VAL} = $energyused;
|
||||
$room->{READINGS}{energyusedp}{VAL} = sprintf ("%.2f", ($energyused =~ tr/1//) /30);
|
||||
|
||||
readingsBeginUpdate ($room);
|
||||
readingsBulkUpdate ($room, "energyused", $energyused);
|
||||
readingsBulkUpdate ($room, "energyusedp", sprintf ("%.2f", ($energyused =~ tr/1//) /30));
|
||||
readingsEndUpdate($room, 0);
|
||||
|
||||
|
||||
return if ($newState eq "");
|
||||
if ($newState eq "") {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($room->{actor})
|
||||
{
|
||||
@ -555,12 +599,8 @@ PWMR_SetRoom(@)
|
||||
Log3 ($room, 2, "PWMR_SetRoom $room->{NAME}: set $room->{actor} $newState");
|
||||
|
||||
$room->{actorState} = $newState;
|
||||
readingsSingleUpdate ($room, "lastswitch", time(), 1);
|
||||
|
||||
$room->{READINGS}{lastswitch}{TIME} = $nowR;
|
||||
$room->{READINGS}{lastswitch}{VAL} = $now;
|
||||
|
||||
push @{$room->{CHANGED}}, "actor $newState";
|
||||
DoTrigger($name, undef);
|
||||
} else {
|
||||
Log3 ($room, 2, "PWMR_SetRoom $name: set $room->{actor} $newState failed ($ret)");
|
||||
}
|
||||
@ -630,20 +670,17 @@ PWMR_ReadRoom(@)
|
||||
|
||||
if (!$room->{READINGS}{"desired-temp"}{TIME})
|
||||
{
|
||||
$room->{READINGS}{"desired-temp"}{VAL} = 6.0;
|
||||
$room->{READINGS}{"desired-temp"}{TIME} = TimeNow();
|
||||
readingsSingleUpdate ($room, "desired-temp", 6.0, 0);
|
||||
}
|
||||
|
||||
if (!$room->{READINGS}{oldpulse}{TIME})
|
||||
{
|
||||
$room->{READINGS}{oldpulse}{VAL} = 0.0;
|
||||
$room->{READINGS}{oldpulse}{TIME} = TimeNow();
|
||||
readingsSingleUpdate ($room, "oldpulse", 0.0, 0);
|
||||
}
|
||||
|
||||
if (!$room->{READINGS}{lastswitch}{TIME})
|
||||
{
|
||||
$room->{READINGS}{lastswitch}{VAL} = time();
|
||||
$room->{READINGS}{lastswitch}{TIME} = TimeNow();
|
||||
readingsSingleUpdate ($room, "lastswitch", time(), 0);
|
||||
}
|
||||
|
||||
$factor = $room->{FACTOR};
|
||||
@ -850,6 +887,7 @@ PWMR_Attr(@)
|
||||
$hash->{c_frostProtect} = 0;
|
||||
} elsif ($attr eq "autoCalcTemp") {
|
||||
$hash->{c_autoCalcTemp} = 1;
|
||||
$hash->{STATE} = "Calculating";
|
||||
}
|
||||
|
||||
}
|
||||
@ -871,10 +909,15 @@ PWMR_Attr(@)
|
||||
}
|
||||
|
||||
} elsif ($attr eq "autoCalcTemp") { # autoCalcTemp 0/1
|
||||
if ($val eq 0 or $val eq 1) {
|
||||
$hash->{c_autoCalcTemp} = $val;
|
||||
if ($val eq 0) {
|
||||
$hash->{c_autoCalcTemp} = 0;
|
||||
$hash->{STATE} = "Manual";
|
||||
} elsif ( $val eq 1) {
|
||||
$hash->{c_autoCalcTemp} = 1;
|
||||
$hash->{STATE} = "Calculating";
|
||||
} elsif ($val eq "") {
|
||||
$hash->{c_autoCalcTemp} = 1;
|
||||
$hash->{STATE} = "Calculating";
|
||||
} else {
|
||||
return "valid values are 0 or 1";
|
||||
}
|
||||
@ -947,12 +990,18 @@ PWMR_Boost(@)
|
||||
"temp($temperaturV) desired-temp($desiredTemp) -> boost");
|
||||
|
||||
my $now = time();
|
||||
$room->{READINGS}{"desired-temp"}{TIME} = FmtDateTime($now + $boostDuration * 60);
|
||||
$room->{READINGS}{"desired-temp"}{VAL} = $desiredTemp + $desiredOffset;
|
||||
|
||||
my $t = $room->{READINGS}{"desired-temp"}{VAL};
|
||||
push @{$room->{CHANGED}}, "desired-temp $t";
|
||||
DoTrigger($name, undef);
|
||||
readingsBeginUpdate ($room);
|
||||
readingsBulkUpdate ($room, "desired-temp", $desiredTemp + $desiredOffset);
|
||||
readingsBulkUpdate ($room, "desired-temp-until", FmtDateTime($now + $boostDuration * 60));
|
||||
readingsEndUpdate($room, 1);
|
||||
|
||||
#$room->{READINGS}{"desired-temp"}{TIME} = FmtDateTime($now + $boostDuration * 60);
|
||||
#$room->{READINGS}{"desired-temp"}{VAL} = $desiredTemp + $desiredOffset;
|
||||
|
||||
#my $t = $room->{READINGS}{"desired-temp"}{VAL};
|
||||
#push @{$room->{CHANGED}}, "desired-temp $t";
|
||||
#DoTrigger($name, undef);
|
||||
|
||||
Log3 ($room, 4, "PWMR_Boost: $name ".
|
||||
"set desiredtemp ".$room->{READINGS}{"desired-temp"}{TIME}." ".
|
||||
|
@ -6,6 +6,10 @@
|
||||
#
|
||||
# 21.09.15 GA update, use Log3
|
||||
# 07.10.15 GA initial version published
|
||||
# 13.10.15 GA add event-on-change-reading
|
||||
# 13.10.15 GA add several readings
|
||||
# 15.10.15 GA add reading for avg pulses
|
||||
|
||||
##############################################
|
||||
# $Id:
|
||||
|
||||
@ -42,7 +46,6 @@ sub PWM_Set($@);
|
||||
sub PWM_Define($$);
|
||||
sub PWM_Calculate($);
|
||||
sub PWM_Undef($$);
|
||||
sub PWM_State($$$$);
|
||||
sub PWM_CalcRoom(@);
|
||||
|
||||
my %roomsWaitOffset = ();
|
||||
@ -57,9 +60,8 @@ PWM_Initialize($)
|
||||
$hash->{SetFn} = "PWM_Set";
|
||||
$hash->{DefFn} = "PWM_Define";
|
||||
$hash->{UndefFn} = "PWM_Undef";
|
||||
#$hash->{StateFn} = "PWM_State";
|
||||
|
||||
$hash->{AttrList} = "";
|
||||
$hash->{AttrList} = "event-on-change-reading";
|
||||
|
||||
}
|
||||
|
||||
@ -77,6 +79,7 @@ PWM_Calculate($)
|
||||
my %RoomsPulses = ();
|
||||
my $roomsActive = 0;
|
||||
my $newpulseSum = 0;
|
||||
my $newpulseMax = 0;
|
||||
my $wkey = "";
|
||||
|
||||
if($hash->{INTERVAL} > 0) {
|
||||
@ -85,9 +88,11 @@ PWM_Calculate($)
|
||||
|
||||
Log3 ($hash, 3, "PWM_Calculate $name");
|
||||
|
||||
readingsBeginUpdate ($hash);
|
||||
|
||||
#$hash->{STATE} = "lastrun: ".TimeNow();
|
||||
#$hash->{STATE} = "calculating";
|
||||
readingsSingleUpdate ($hash, "lastrun", "calculating", 1);
|
||||
readingsBulkUpdate ($hash, "lastrun", "calculating");
|
||||
$hash->{STATE} = "lastrun: ".$hash->{READINGS}{lastrun}{TIME};
|
||||
|
||||
# loop over all devices
|
||||
@ -127,6 +132,7 @@ PWM_Calculate($)
|
||||
$roomsActive++;
|
||||
$RoomsPulses{$d} = $newpulse;
|
||||
$newpulseSum += $newpulse;
|
||||
$newpulseMax = max($newpulseMax, $newpulse);
|
||||
|
||||
# $newstate ne "" -> state changed "on" -> "off" or "off" -> "on"
|
||||
if ((int($hash->{MINONOFFTIME}) > 0) &&
|
||||
@ -263,7 +269,6 @@ PWM_Calculate($)
|
||||
#my $maxRoomsOn = $roomsActive * 0.6; # 11 rooms -> max 6 active
|
||||
#$maxRoomsOn = (8 * 0.7) if ($roomsActive < 8);
|
||||
|
||||
# HERE
|
||||
my $maxRoomsOn = $roomsActive - $hash->{NoRoomsToStayOff};
|
||||
|
||||
#
|
||||
@ -309,8 +314,8 @@ PWM_Calculate($)
|
||||
# $minRoomsOn = 0;
|
||||
#}
|
||||
|
||||
# HERE
|
||||
my $minRoomsOn = $hash->{NoRoomsToStayOn};
|
||||
my $minRoomsOnList = "";
|
||||
|
||||
if ($minRoomsOn > 0) {
|
||||
|
||||
@ -322,9 +327,11 @@ PWM_Calculate($)
|
||||
last if ($roomsCounted == $minRoomsOn);
|
||||
Log3 ($hash, 3, "PWM_Calculate: loop $roomsCounted $room $RoomsPulses{$room}");
|
||||
|
||||
$minRoomsOnList .= "$room,";
|
||||
$pulseSum += $RoomsPulses{$room};
|
||||
$roomsCounted++;
|
||||
}
|
||||
$minRoomsOnList =~ s/,$//;
|
||||
|
||||
#if ($roomsActive == 0 or $hash->{NoRoomsToStayOnThreshold} == 0 or $newpulseSum/$roomsActive < $hash->{NoRoomsToStayOnThreshold}) {
|
||||
|
||||
@ -369,22 +376,36 @@ PWM_Calculate($)
|
||||
#
|
||||
# now process the calculated actions
|
||||
#
|
||||
|
||||
|
||||
my $cntRoomsOn = 0;
|
||||
my $cntRoomsOff = 0;
|
||||
my $pulseRoomsOn = 0;
|
||||
my $pulseRoomsOff = 0;
|
||||
|
||||
foreach my $roomStay (sort keys %RoomsToStayOff) {
|
||||
|
||||
PWMR_SetRoom ($defs{$roomStay}, "");
|
||||
|
||||
$cntRoomsOff++;
|
||||
$pulseRoomsOff += $RoomsPulses{$roomStay};
|
||||
|
||||
}
|
||||
|
||||
foreach my $roomStay (sort keys %RoomsToStayOn) {
|
||||
|
||||
PWMR_SetRoom ($defs{$roomStay}, "");
|
||||
|
||||
$cntRoomsOn++;
|
||||
$pulseRoomsOn += $RoomsPulses{$roomStay};
|
||||
|
||||
}
|
||||
|
||||
foreach my $roomOff (sort keys %RoomsToSwitchOff) {
|
||||
|
||||
PWMR_SetRoom ($defs{$roomOff}, "off");
|
||||
|
||||
$cntRoomsOff++;
|
||||
$pulseRoomsOff += $RoomsPulses{$roomOff};
|
||||
}
|
||||
|
||||
foreach my $roomOn (sort keys %RoomsToSwitchOn) {
|
||||
@ -393,7 +414,26 @@ PWM_Calculate($)
|
||||
$roomsWaitOffset{$wkey} = 0;
|
||||
PWMR_SetRoom ($defs{$roomOn}, "on");
|
||||
|
||||
$cntRoomsOn++;
|
||||
$pulseRoomsOn += $RoomsPulses{$roomOn};
|
||||
|
||||
}
|
||||
|
||||
|
||||
readingsBulkUpdate ($hash, "roomsActive", $roomsActive);
|
||||
readingsBulkUpdate ($hash, "roomsOn", $cntRoomsOn);
|
||||
readingsBulkUpdate ($hash, "roomsOff", $cntRoomsOff);
|
||||
readingsBulkUpdate ($hash, "avgPulseRoomsOn", ($cntRoomsOn > 0 ? sprintf ("%.2f", $pulseRoomsOn / $cntRoomsOn) : 0));
|
||||
readingsBulkUpdate ($hash, "avgPulseRoomsOff", ($cntRoomsOff > 0 ? sprintf ("%.2f", $pulseRoomsOff /$cntRoomsOff) : 0));
|
||||
readingsBulkUpdate ($hash, "pulseMax", $newpulseMax);
|
||||
readingsBulkUpdate ($hash, "pulseSum", $newpulseSum);
|
||||
|
||||
if ( $hash->{NoRoomsToStayOn} > 0) {
|
||||
readingsBulkUpdate ($hash, "roomsToStayOn", $minRoomsOn);
|
||||
readingsBulkUpdate ($hash, "roomsToStayOnList", $minRoomsOnList);
|
||||
}
|
||||
|
||||
readingsEndUpdate($hash, 1);
|
||||
|
||||
# if(!$hash->{LOCAL}) {
|
||||
# DoTrigger($name, undef) if($init_done);
|
||||
@ -662,26 +702,6 @@ sub PWM_Undef($$)
|
||||
|
||||
return undef;
|
||||
|
||||
}
|
||||
###################################
|
||||
sub PWM_State($$$$)
|
||||
{
|
||||
my ($hash, $time, $var, $value) = @_;
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
Log3 ($hash, 3, "PWM States $name: $time $var $value");
|
||||
|
||||
$hash->{READINGS}{$var}{VAL} = $value;
|
||||
$hash->{READINGS}{$var}{TIME} = $time;
|
||||
|
||||
#if ($var =~ /INTERVAL|SCOPE|CYCLETIME/)
|
||||
#{
|
||||
# Log3 ($hash, 3, "PWM States $name: set $var $value");
|
||||
# $hash->{$var} = $value;
|
||||
#}
|
||||
|
||||
return undef;
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user