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:
parent
c53e0c5c32
commit
62e053feac
@ -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ät, um dessen Status zu prü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>
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user