2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-04 05:16:45 +00:00

RESIDENTStk wakeuptimer: generally stop wakeup program if user device changes state; add wakeupWaitPeriod attribute to avoid multiple run in the morning if wakeuptime is earlier than wakeupDefaultTime

git-svn-id: https://svn.fhem.de/fhem/trunk@8586 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
jpawlowski 2015-05-16 15:47:30 +00:00
parent c53e0c5c32
commit 62e053feac
4 changed files with 134 additions and 58 deletions

View File

@ -649,11 +649,15 @@ sub RESIDENTS_Set($@) {
sub RESIDENTS_UpdateReadings (@) {
my ($hash) = @_;
my $state =
( defined $hash->{READINGS}{state}{VAL} ) ? $hash->{READINGS}{state}{VAL}
: ( defined $hash->{STATE} ) ? $hash->{STATE}
: "undefined";
my $name = $hash->{NAME};
my $state =
( defined( $hash->{READINGS}{state}{VAL} ) )
? $hash->{READINGS}{state}{VAL}
: "none";
my $presence =
( defined( $hash->{READINGS}{presence}{VAL} ) )
? $hash->{READINGS}{presence}{VAL}
: "absent";
my $state_home = 0;
my $state_gotosleep = 0;
@ -671,7 +675,6 @@ sub RESIDENTS_UpdateReadings (@) {
my $wayhome = 0;
my $wakeup = 0;
my $newstate;
my $presence = "absent";
my @registeredRoommates =
split( /,/, $hash->{ROOMMATES} )
@ -925,35 +928,48 @@ sub RESIDENTS_UpdateReadings (@) {
$newstate = "unspecified";
}
# stop any running wakeup-timers in case user went away
if ( $newstate eq "away" || $newstate eq "gone"|| $newstate eq "none" ) {
my $wakeupDeviceList = AttrVal( $name, "rgr_wakeupDevice", 0 );
for my $wakeupDevice ( split /,/, $wakeupDeviceList ) {
next if !$wakeupDevice;
if ( defined( $defs{$wakeupDevice} ) && $defs{$wakeupDevice}{TYPE} eq "dummy" ) {
fhem "set $wakeupDevice:FILTER=running!=0 stop";
}
}
}
# calculate presence state
$presence = "present"
if ( $newstate ne "gone"
&& $newstate ne "none"
&& $newstate ne "absent" );
my $newpresence =
( $newstate ne "none" && $newstate ne "gone" && $newstate ne "absent" )
? "present"
: "absent";
Log3 $name, 4,
"RESIDENTS $name: calculation result - residentsTotal:$state_total residentsTotalGuests:$state_totalGuests residentsTotalGuestsPresent:$state_totalGuestsPresent residentsTotalGuestsAbsent:$state_totalGuestsAbsent residentsTotalPresent:$state_totalPresent residentsTotalAbsent:$state_totalAbsent residentsHome:$state_home residentsGotosleep:$state_gotosleep residentsAsleep:$state_asleep residentsAwoken:$state_awoken residentsAbsent:$state_absent residentsGone:$state_gone presence:$presence state:$newstate";
"RESIDENTS $name: calculation result - residentsTotal:$state_total residentsTotalGuests:$state_totalGuests residentsTotalGuestsPresent:$state_totalGuestsPresent residentsTotalGuestsAbsent:$state_totalGuestsAbsent residentsTotalPresent:$state_totalPresent residentsTotalAbsent:$state_totalAbsent residentsHome:$state_home residentsGotosleep:$state_gotosleep residentsAsleep:$state_asleep residentsAwoken:$state_awoken residentsAbsent:$state_absent residentsGone:$state_gone presence:$newpresence state:$newstate";
# safe current time
my $datetime = FmtDateTime(time);
# if state changed
if ( !defined( $hash->{READINGS}{state}{VAL} )
|| $state ne $newstate )
{
if ( $state ne $newstate ) {
# stop any running wakeup-timers in case state changed
my $wakeupState = AttrVal( $name, "wakeup", 0 );
if ($wakeupState) {
my $wakeupDeviceList = AttrVal( $name, "rgr_wakeupDevice", 0 );
for my $wakeupDevice ( split /,/, $wakeupDeviceList ) {
next if !$wakeupDevice;
if ( defined( $defs{$wakeupDevice} )
&& $defs{$wakeupDevice}{TYPE} eq "dummy" )
{
# forced-stop only if resident is not present anymore
my $wakeupNormalStop;
if ( $newstate ne "gone"
&& $newstate ne "none"
&& $newstate ne "absent" )
{
$wakeupNormalStop =
AttrVal( $wakeupDevice, "lastRun", "00:00" );
}
fhem
"set $wakeupDevice:FILTER=running!=0 stop $wakeupNormalStop";
}
}
}
# if newstate is asleep, start sleep timer
readingsBulkUpdate( $hash, "lastSleep", $datetime )
if ( $newstate eq "asleep" );
@ -984,10 +1000,8 @@ sub RESIDENTS_UpdateReadings (@) {
}
# if presence changed
if ( !defined( $hash->{READINGS}{presence}{VAL} )
|| $hash->{READINGS}{presence}{VAL} ne $presence )
{
readingsBulkUpdate( $hash, "presence", $presence );
if ( $newpresence ne $presence ) {
readingsBulkUpdate( $hash, "presence", $newpresence );
# update statistics
if ( $presence eq "present" ) {
@ -1304,6 +1318,9 @@ sub RESIDENTS_UpdateReadings (@) {
<li>
<i>wakeupUserdevice</i> - backlink to RESIDENTS, ROOMMATE or GUEST device to check it's status (mandatory)
</li>
<li>
<i>wakeupWaitPeriod</i> - waiting period threshold in minutes until wake-up program may be triggered again, e.g. if you manually set an earlier wake-up time than normal while using wakeupDefaultTime. Does not apply in case wake-up time was changed during this period; defaults to 360 minutes / 6h (optional)
</li>
</ul>
</li>
</ul>
@ -1567,6 +1584,9 @@ sub RESIDENTS_UpdateReadings (@) {
<li>
<i>wakeupUserdevice</i> - Backlink zum RESIDENTS, ROOMMATE oder GUEST Ger&auml;t, um dessen Status zu pr&uuml;fen (notwendig)
</li>
<li>
<i>wakeupWaitPeriod</i> - Schwelle der Wartezeit in Minuten bis das Weckprogramm erneut ausgeführt werden kann, z.B. wenn manuell eine frühere Weckzeit gesetzt wurde als normal während wakeupDefaultTime verwendet wird. Greift nicht, wenn die Weckzeit während dieser Zeit geändert wurde; Standard ist 360 Minuten / 6h (optional)
</li>
</ul>
</li>
</ul>

View File

@ -388,6 +388,7 @@ sub GUEST_Set($@) {
Log3 $name, 2, "GUEST set $name " . $newstate if ( !$silent );
# if state changed
if ( $state ne $newstate ) {
readingsBeginUpdate($hash);
@ -463,19 +464,6 @@ sub GUEST_Set($@) {
);
}
# stop any running wakeup-timers in case user went away
if ( $newstate eq "away" || $newstate eq "gone" ) {
my $wakeupDeviceList = AttrVal( $name, "rg_wakeupDevice", 0 );
for my $wakeupDevice ( split /,/, $wakeupDeviceList ) {
next if !$wakeupDevice;
if ( defined( $defs{$wakeupDevice} ) && $defs{$wakeupDevice}{TYPE} eq "dummy" ) {
fhem "set $wakeupDevice:FILTER=running!=0 stop";
}
}
}
# calculate presence state
my $newpresence =
( $newstate ne "none"
@ -484,6 +472,28 @@ sub GUEST_Set($@) {
? "present"
: "absent";
# stop any running wakeup-timers in case state changed
my $wakeupState = AttrVal( $name, "wakeup", 0 );
if ($wakeupState) {
my $wakeupDeviceList = AttrVal( $name, "rg_wakeupDevice", 0 );
for my $wakeupDevice ( split /,/, $wakeupDeviceList ) {
next if !$wakeupDevice;
if ( defined( $defs{$wakeupDevice} )
&& $defs{$wakeupDevice}{TYPE} eq "dummy" )
{
my $wakeupNormalStop;
$wakeupNormalStop =
AttrVal( $wakeupDevice, "lastRun", "00:00" )
if ( $newpresence eq "present" );
fhem
"set $wakeupDevice:FILTER=running!=0 stop $wakeupNormalStop";
}
}
}
# if presence changed
if ( $newpresence ne $presence ) {
readingsBulkUpdate( $hash, "presence", $newpresence );

View File

@ -389,6 +389,7 @@ sub ROOMMATE_Set($@) {
Log3 $name, 2, "ROOMMATE set $name " . $newstate if ( !$silent );
# if state changed
if ( $state ne $newstate ) {
readingsBeginUpdate($hash);
@ -464,19 +465,6 @@ sub ROOMMATE_Set($@) {
)
);
}
# stop any running wakeup-timers in case user went away
if ( $newstate eq "away" || $newstate eq "gone"|| $newstate eq "none" ) {
my $wakeupDeviceList = AttrVal( $name, "rr_wakeupDevice", 0 );
for my $wakeupDevice ( split /,/, $wakeupDeviceList ) {
next if !$wakeupDevice;
if ( defined( $defs{$wakeupDevice} ) && $defs{$wakeupDevice}{TYPE} eq "dummy" ) {
fhem "set $wakeupDevice:FILTER=running!=0 stop";
}
}
}
# calculate presence state
my $newpresence =
@ -486,6 +474,28 @@ sub ROOMMATE_Set($@) {
? "present"
: "absent";
# stop any running wakeup-timers in case state changed
my $wakeupState = AttrVal( $name, "wakeup", 0 );
if ($wakeupState) {
my $wakeupDeviceList = AttrVal( $name, "rr_wakeupDevice", 0 );
for my $wakeupDevice ( split /,/, $wakeupDeviceList ) {
next if !$wakeupDevice;
if ( defined( $defs{$wakeupDevice} )
&& $defs{$wakeupDevice}{TYPE} eq "dummy" )
{
my $wakeupNormalStop;
$wakeupNormalStop =
AttrVal( $wakeupDevice, "lastRun", "00:00" )
if ( $newpresence eq "present" );
fhem
"set $wakeupDevice:FILTER=running!=0 stop $wakeupNormalStop";
}
}
}
# if presence changed
if ( $newpresence ne $presence ) {
readingsBulkUpdate( $hash, "presence", $newpresence );

View File

@ -90,7 +90,7 @@ sub RESIDENTStk_wakeupSet($$) {
# check for required userattr attribute
my $userattributes =
"wakeupOffset:slider,0,1,120 wakeupDefaultTime:OFF,00:00,00:15,00:30,00:45,01:00,01:15,01:30,01:45,02:00,02:15,02:30,02:45,03:00,03:15,03:30,03:45,04:00,04:15,04:30,04:45,05:00,05:15,05:30,05:45,06:00,06:15,06:30,06:45,07:00,07:15,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00,10:15,10:30,10:45,11:00,11:15,11:30,11:45,12:00,12:15,12:30,12:45,13:00,13:15,13:30,13:45,14:00,14:15,14:30,14:45,15:00,15:15,15:30,15:45,16:00,16:15,16:30,16:45,17:00,17:15,17:30,17:45,18:00,18:15,18:30,18:45,19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00,22:15,22:30,22:45,23:00,23:15,23:30,23:45 wakeupMacro wakeupUserdevice wakeupAtdevice wakeupResetSwitcher wakeupResetdays:multiple-strict,0,1,2,3,4,5,6 wakeupDays:multiple-strict,0,1,2,3,4,5,6 wakeupHolidays:andHoliday,orHoliday,andNoHoliday,orNoHoliday wakeupEnforced:0,1,2";
"wakeupOffset:slider,0,1,120 wakeupDefaultTime:OFF,00:00,00:15,00:30,00:45,01:00,01:15,01:30,01:45,02:00,02:15,02:30,02:45,03:00,03:15,03:30,03:45,04:00,04:15,04:30,04:45,05:00,05:15,05:30,05:45,06:00,06:15,06:30,06:45,07:00,07:15,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00,10:15,10:30,10:45,11:00,11:15,11:30,11:45,12:00,12:15,12:30,12:45,13:00,13:15,13:30,13:45,14:00,14:15,14:30,14:45,15:00,15:15,15:30,15:45,16:00,16:15,16:30,16:45,17:00,17:15,17:30,17:45,18:00,18:15,18:30,18:45,19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00,22:15,22:30,22:45,23:00,23:15,23:30,23:45 wakeupMacro wakeupUserdevice wakeupAtdevice wakeupResetSwitcher wakeupResetdays:multiple-strict,0,1,2,3,4,5,6 wakeupDays:multiple-strict,0,1,2,3,4,5,6 wakeupHolidays:andHoliday,orHoliday,andNoHoliday,orNoHoliday wakeupEnforced:0,1,2 wakeupWaitPeriod:slider,0,1,360";
if ( !$userattr || $userattr ne $userattributes ) {
Log3 $NAME, 4,
"RESIDENTStk $NAME: adjusting dummy device for required attribute userattr";
@ -914,13 +914,18 @@ sub RESIDENTStk_wakeupRun($;$) {
my $wakeupOffset = AttrVal( $NAME, "wakeupOffset", 0 );
my $wakeupEnforced = AttrVal( $NAME, "wakeupEnforced", 0 );
my $wakeupResetSwitcher = AttrVal( $NAME, "wakeupResetSwitcher", 0 );
my $wakeupWaitPeriod = AttrVal( $NAME, "wakeupWaitPeriod", 360 );
my $holidayDevice = AttrVal( "global", "holiday2we", 0 );
my $lastRun = ReadingsVal( $NAME, "lastRun", "06:00" );
my $lastRunTimestamp =
ReadingsTimestamp( $NAME, "lastRun", "1970-01-01 00:00:00" );
my $nextRun = ReadingsVal( $NAME, "nextRun", "06:00" );
my $running = ReadingsVal( $NAME, "running", 0 );
my $nextRunTimestamp =
ReadingsTimestamp( $NAME, "nextRun", "1970-01-01 00:00:00" );
my $wakeupUserdeviceWakeup = ReadingsVal( $wakeupUserdevice, "wakeup", 0 );
my $room = AttrVal( $NAME, "room", 0 );
my $running = 0;
my $preventRun = 0;
my $holidayToday = "";
if ( $wakeupHolidays
@ -939,11 +944,19 @@ sub RESIDENTStk_wakeupRun($;$) {
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
localtime( time + $wakeupOffset * 60 );
$mon += 01;
$hour = "0" . $hour if ( $hour < 10 );
$min = "0" . $min if ( $min < 10 );
my $nowRun = $hour . ":" . $min;
my $nowRunSec =
RESIDENTStk_Datetime2Timestamp( $year . "-"
. $mon . "-"
. $mday . " "
. $hour . ":"
. $min . ":"
. $sec );
if ( $nextRun ne $nowRun ) {
$lastRun = $nowRun;
@ -954,6 +967,24 @@ sub RESIDENTStk_wakeupRun($;$) {
Log3 $NAME, 4, "RESIDENTStk $NAME: lastRun = nextRun = $lastRun";
}
# do not run if wakeupWaitPeriod expiration was not reached yet
my $expLastRun =
RESIDENTStk_Datetime2Timestamp($lastRunTimestamp) - 1 +
$wakeupOffset * 60 +
$wakeupWaitPeriod * 60;
my $expNextRun = RESIDENTStk_Datetime2Timestamp($nextRunTimestamp) - 1 +
$wakeupWaitPeriod * 60;
if ( $expLastRun > $nowRunSec
&& $expNextRun < time() )
{
$preventRun = 1;
}
else {
Log3 $NAME, 5,
"RESIDENTStk $NAME: wakeupWaitPeriod threshold reached (expLastRun=$expLastRun nowRunSec=$nowRunSec expNextRun=$expNextRun localtime="
. time() . ")";
}
my @days = ($wday);
if ( $wakeupDays ne "" ) {
@days = split /,/, $wakeupDays;
@ -1053,6 +1084,11 @@ sub RESIDENTStk_wakeupRun($;$) {
Log3 $NAME, 3,
"RESIDENTStk $NAME: Another wake-up program is already being executed for device $wakeupUserdevice, won't trigger $wakeupMacro";
}
elsif ( $preventRun && !$forceRun ) {
Log3 $NAME, 4,
"RESIDENTStk $NAME: won't trigger wake-up program due to non-expired wakeupWaitPeriod threshold since lastRun (expLastRun=$expLastRun nowRunSec=$nowRunSec expNextRun=$expNextRun localtime="
. time() . ")";
}
else {
# conditional enforced wake-up:
# only if actual wake-up time is not wakeupDefaultTime