mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 18:59:33 +00:00
RESIDENTStk wakeuptimer: add holiday support and aggregate states to parent devices
git-svn-id: https://svn.fhem.de/fhem/trunk@8228 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
959dc1cee2
commit
ade12bdba6
@ -572,7 +572,7 @@ sub RESIDENTS_Set($@) {
|
||||
fhem "attr $wakeuptimerName room " . $attr{$name}{room}
|
||||
if ( defined( $attr{$name}{room} ) );
|
||||
fhem
|
||||
"attr $wakeuptimerName setList nextRun: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 reset:noArg stop:noArg";
|
||||
"attr $wakeuptimerName setList nextRun: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 reset:noArg trigger:noArg start:noArg stop:noArg";
|
||||
fhem "attr $wakeuptimerName userattr wakeupUserdevice";
|
||||
fhem "attr $wakeuptimerName sortby " . $sortby
|
||||
if ($sortby);
|
||||
|
@ -766,7 +766,7 @@ sub GUEST_Set($@) {
|
||||
fhem "attr $wakeuptimerName room " . $attr{$name}{room}
|
||||
if ( defined( $attr{$name}{room} ) );
|
||||
fhem
|
||||
"attr $wakeuptimerName setList nextRun: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 reset:noArg stop:noArg";
|
||||
"attr $wakeuptimerName setList nextRun: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 reset:noArg trigger:noArg start:noArg stop:noArg";
|
||||
fhem "attr $wakeuptimerName userattr wakeupUserdevice";
|
||||
fhem "attr $wakeuptimerName sortby " . $sortby
|
||||
if ($sortby);
|
||||
|
@ -748,7 +748,7 @@ sub ROOMMATE_Set($@) {
|
||||
fhem "attr $wakeuptimerName room " . $attr{$name}{room}
|
||||
if ( defined( $attr{$name}{room} ) );
|
||||
fhem
|
||||
"attr $wakeuptimerName setList nextRun: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 reset:noArg stop:noArg";
|
||||
"attr $wakeuptimerName setList nextRun: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 reset:noArg trigger:noArg start:noArg stop:noArg";
|
||||
fhem "attr $wakeuptimerName userattr wakeupUserdevice";
|
||||
fhem "attr $wakeuptimerName sortby " . $sortby
|
||||
if ($sortby);
|
||||
|
@ -45,7 +45,9 @@ sub RESIDENTStk_wakeupSet($$) {
|
||||
|
||||
# filter non-registered notifies
|
||||
my @notify = split / /, $notifyValue;
|
||||
if ( lc( $notify[0] ) !~ /off|nextrun|stop|reset|auto|([0-9]{2}:[0-9]{2})/ )
|
||||
if (
|
||||
lc( $notify[0] ) !~
|
||||
/off|nextrun|trigger|start|stop|reset|auto|([0-9]{2}:[0-9]{2})/ )
|
||||
{
|
||||
Log3 $NAME, 5,
|
||||
"RESIDENTStk $NAME: received unspecified notify '"
|
||||
@ -61,26 +63,28 @@ sub RESIDENTStk_wakeupSet($$) {
|
||||
$VALUE = $notify[0];
|
||||
}
|
||||
|
||||
my $wakeupMacro = AttrVal( $NAME, "wakeupMacro", 0 );
|
||||
my $wakeupDefaultTime = AttrVal( $NAME, "wakeupDefaultTime", 0 );
|
||||
my $wakeupAtdevice = AttrVal( $NAME, "wakeupAtdevice", 0 );
|
||||
my $wakeupUserdevice = AttrVal( $NAME, "wakeupUserdevice", 0 );
|
||||
my $wakeupDays = AttrVal( $NAME, "wakeupDays", 0 );
|
||||
my $wakeupResetdays = AttrVal( $NAME, "wakeupResetdays", 0 );
|
||||
my $wakeupOffset = AttrVal( $NAME, "wakeupOffset", 0 );
|
||||
my $wakeupResetSwitcher = AttrVal( $NAME, "wakeupResetSwitcher", 0 );
|
||||
my $wakeupUserdevice = AttrVal( $NAME, "wakeupUserdevice", 0 );
|
||||
my $room = AttrVal( $NAME, "room", 0 );
|
||||
my $userattr = AttrVal( $NAME, "userattr", 0 );
|
||||
my $lastRun = ReadingsVal( $NAME, "lastRun", "07:00" );
|
||||
my $nextRun = ReadingsVal( $NAME, "nextRun", "07:00" );
|
||||
my $running = ReadingsVal( $NAME, "running", 0 );
|
||||
my $macroName = "Macro_" . $NAME;
|
||||
my $atName = "at_" . $NAME;
|
||||
my $wakeupMacro = AttrVal( $NAME, "wakeupMacro", 0 );
|
||||
my $wakeupDefaultTime = AttrVal( $NAME, "wakeupDefaultTime", 0 );
|
||||
my $wakeupAtdevice = AttrVal( $NAME, "wakeupAtdevice", 0 );
|
||||
my $wakeupUserdevice = AttrVal( $NAME, "wakeupUserdevice", 0 );
|
||||
my $wakeupDays = AttrVal( $NAME, "wakeupDays", "" );
|
||||
my $wakeupHolidays = AttrVal( $NAME, "wakeupHolidays", 0 );
|
||||
my $wakeupResetdays = AttrVal( $NAME, "wakeupResetdays", "" );
|
||||
my $wakeupOffset = AttrVal( $NAME, "wakeupOffset", 0 );
|
||||
my $wakeupEnforced = AttrVal( $NAME, "wakeupEnforced", 0 );
|
||||
my $wakeupResetSwitcher = AttrVal( $NAME, "wakeupResetSwitcher", 0 );
|
||||
my $holidayDevice = AttrVal( "global", "holiday2we", 0 );
|
||||
my $room = AttrVal( $NAME, "room", 0 );
|
||||
my $userattr = AttrVal( $NAME, "userattr", 0 );
|
||||
my $lastRun = ReadingsVal( $NAME, "lastRun", "07:00" );
|
||||
my $nextRun = ReadingsVal( $NAME, "nextRun", "07:00" );
|
||||
my $running = ReadingsVal( $NAME, "running", 0 );
|
||||
my $macroName = "Macro_" . $NAME;
|
||||
my $atName = "at_" . $NAME;
|
||||
|
||||
# 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";
|
||||
"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";
|
||||
if ( !$userattr || $userattr ne $userattributes ) {
|
||||
Log3 $NAME, 4,
|
||||
"RESIDENTStk $NAME: adjusting dummy device for required attribute userattr";
|
||||
@ -113,47 +117,49 @@ sub RESIDENTStk_wakeupSet($$) {
|
||||
}
|
||||
if ( !defined( $defs{$wakeupMacro} ) ) {
|
||||
my $wakeUpMacroTemplate = "{\
|
||||
#\
|
||||
# This is an example wake-up program running within a period of 30 minutes:\
|
||||
# - drive shutters upwards slowly\
|
||||
# - light up a HUE bulb from 2000K to 6500K\
|
||||
# - have some voice notifications via SONOS\
|
||||
# - have some wake-up chill music via SONOS during program run\
|
||||
#\
|
||||
# Available wake-up variables:\
|
||||
# 1. \$EVTPART0 -> start or stop\
|
||||
# 2. \$EVTPART1 -> target wake-up time\
|
||||
# 2. \$EVTPART2 -> wake-up begin offset time\
|
||||
#\
|
||||
##\
|
||||
## This is an example wake-up program running within a period of 30 minutes:\
|
||||
## - drive shutters upwards slowly\
|
||||
## - light up a HUE bulb from 2000K to 6500K\
|
||||
## - have some voice notifications via SONOS\
|
||||
## - have some wake-up chill music via SONOS during program run\
|
||||
##\
|
||||
## Available wake-up variables:\
|
||||
## 1. \$EVTPART0 -> start or stop\
|
||||
## 2. \$EVTPART1 -> target wake-up time\
|
||||
## 3. \$EVTPART2 -> wake-up begin time considering wakeupOffset attribute\
|
||||
## 4. \$EVTPART3 -> enforced wakeup yes=1,no=0 from wakeupEnforced attribute\
|
||||
## 5. \$EVTPART4 -> device name of the user which called this macro\
|
||||
##\
|
||||
\
|
||||
#------------------------------------------------------------------------------------\
|
||||
# DELETE TEMP. AT-COMMANDS POTENTIALLY CREATED EARLIER BY THIS SCRIPT\
|
||||
# Executed for start to cleanup in case this wake-up automation is re-started.\
|
||||
# Executed for stop to cleanup in case the user ends this automation earlier.\
|
||||
#\
|
||||
##------------------------------------------------------------------------------------\
|
||||
## DELETE TEMP. AT-COMMANDS POTENTIALLY CREATED EARLIER BY THIS SCRIPT\
|
||||
## Executed for start to cleanup in case this wake-up automation is re-started.\
|
||||
## Executed for stop to cleanup in case the user ends this automation earlier.\
|
||||
##\
|
||||
for (my \$i=1;; \$i <= 10;; \$i++) {\
|
||||
if (defined(\$defs{\"atTmp_\".\$i.\"_\".\$NAME})) {\
|
||||
fhem \"delete atTmp_\".\$i.\"_\".\$NAME;;\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
#------------------------------------------------------------------------------------\
|
||||
# BEGIN WAKE-UP PROGRAM\
|
||||
# Run first automation commands and create temp. at-devices for lagging actions.\
|
||||
#\
|
||||
##------------------------------------------------------------------------------------\
|
||||
## BEGIN WAKE-UP PROGRAM\
|
||||
## Run first automation commands and create temp. at-devices for lagging actions.\
|
||||
##\
|
||||
if (\$EVTPART0 eq \"start\") {\
|
||||
Log3 \$NAME, 3, \"\$NAME: Wake-up program started for \".\$EVTPART1;;\
|
||||
Log3 \$NAME, 3, \"\$NAME: Wake-up program started for \$EVTPART4 with target time \$EVTPART1\";;\
|
||||
\
|
||||
fhem \"set BR_FloorLamp pct 1 : ct 2000 : transitiontime 0;; set BR_FloorLamp pct 90 : ct 5600 : transitiontime 1770\";;\
|
||||
# fhem \"set BR_FloorLamp:FILTER=onoff=0 pct 1 : ct 2000 : transitiontime 0;; set BR_FloorLamp:FILTER=pct=1 pct 90 : ct 5600 : transitiontime 1770\";;\
|
||||
\
|
||||
fhem \"define atTmp_1_\$NAME at +00:10:00 set BR_Shutter pct 20\";;\
|
||||
fhem \"define atTmp_2_\$NAME at +00:20:00 set BR_Shutter pct 40\";;\
|
||||
fhem \"define atTmp_4_\$NAME at +00:30:00 set Sonos_Bedroom Speak 33 de |Hint| Es ist \".\$EVTPART1.\" Uhr, Zeit zum aufstehen!;;;; set BR_FloorLamp pct 100 60;;;; sleep 10;;;; set BR_Shutter pct 60;;;; set Sonos_Bedroom volume 10 10\";;\
|
||||
# fhem \"define atTmp_1_\$NAME at +00:10:00 set BR_Shutter:FILTER=pct<20 pct 20\";;\
|
||||
# fhem \"define atTmp_2_\$NAME at +00:20:00 set BR_Shutter:FILTER=pct<40 pct 40\";;\
|
||||
# fhem \"define atTmp_4_\$NAME at +00:30:00 set Sonos_Bedroom Speak 33 de |Hint| Es ist \".\$EVTPART1.\" Uhr, Zeit zum aufstehen!;;;; set BR_FloorLamp:FILTER=pct<100 pct 100 60;;;; sleep 10;;;; set BR_Shutter:FILTER=pct<60 pct 60;;;; set Sonos_Bedroom:FILTER=Volume<10 Volume 10 10\";;\
|
||||
\
|
||||
# Working days only (Mon-Fri except bank holidays): do enforced wake-up actions\
|
||||
if (!\$we) {\
|
||||
# if wake-up should be enforced\
|
||||
if (\$EVTPART3) {\
|
||||
Log (4, \"\$NAME: planning enforced wake-up\");;\
|
||||
fhem \"define atTmp_3_\$NAME at +00:25:00 set Sonos_Bedroom volume 2;;;; set Sonos_Bedroom Shuffle 1;;;; set Sonos_Bedroom StartFavourite Morning%%20Sounds;;;; sleep 4;;;; set Sonos_Bedroom volume 8 290\";;\
|
||||
# fhem \"define atTmp_3_\$NAME at +00:25:00 set Sonos_Bedroom:FILTER=Volume>2 Volume 2;;;; set Sonos_Bedroom:FILTER=Shuffle=0 Shuffle 1;;;; set Sonos_Bedroom StartFavourite Morning%%20Sounds;;;; sleep 4;;;; set Sonos_Bedroom Volume 8 290\";;\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
@ -162,19 +168,19 @@ if (\$EVTPART0 eq \"start\") {\
|
||||
# Put some post wake-up tasks here like reminders after the actual wake-up period.\
|
||||
#\
|
||||
if (\$EVTPART0 eq \"stop\") {\
|
||||
Log3 \$NAME, 3, \"\$NAME: Wake-up program ended for \".\$EVTPART1;;\
|
||||
Log3 \$NAME, 3, \"\$NAME: Wake-up program ended for \$EVTPART4 with target time \$EVTPART1\";;\
|
||||
\
|
||||
# Working days only (Mon-Fri except bank holidays): after only a small additional nap,\
|
||||
# get you out of bed :-)\
|
||||
# if wake-up should be enforced, auto-change user state from 'asleep' to 'awoken'\
|
||||
# after a small additional nap to kick you out of bed if user did not confirm to be awake :-)\
|
||||
# An additional notify for user state 'awoken' may take further actions\
|
||||
# and change to state 'home' afterwards.\
|
||||
if (!\$we) {\
|
||||
fhem \"define atTmp_5_\$NAME at +00:05:00 set rr_Julian:FILTER=STATE=asleep awoken\";;\
|
||||
if (\$EVTPART3) {\
|
||||
fhem \"define atTmp_5_\$NAME at +00:05:00 set \$EVTPART4:FILTER=STATE=asleep awoken\";;\
|
||||
\
|
||||
# At weekend and bank holidays: be jentle and just set user state to 'home' after some\
|
||||
# Without enforced wake-up, be jentle and just set user state to 'home' after some\
|
||||
# additional long nap time\
|
||||
} else {\
|
||||
fhem \"define atTmp_5_\$NAME at +01:30:00 set rr_Julian:FILTER=STATE=asleep home\";;\
|
||||
fhem \"define atTmp_5_\$NAME at +01:30:00 set \$EVTPART4:FILTER=STATE=asleep home\";;\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
@ -213,9 +219,43 @@ if (\$EVTPART0 eq \"stop\") {\
|
||||
"RESIDENTStk $NAME: WARNING - defined at-device '$wakeupAtdevice' is not an at-device!";
|
||||
}
|
||||
|
||||
# verify holiday2we attribute
|
||||
if ($wakeupHolidays) {
|
||||
if ( !$holidayDevice ) {
|
||||
Log3 $NAME, 3,
|
||||
"RESIDENTStk $NAME: ERROR - wakeupHolidays set in this alarm clock but global attribute holiday2we not set!";
|
||||
return
|
||||
"ERROR: wakeupHolidays set in this alarm clock but global attribute holiday2we not set!";
|
||||
}
|
||||
elsif ( !defined( $defs{$holidayDevice} ) ) {
|
||||
Log3 $NAME, 3,
|
||||
"RESIDENTStk $NAME: ERROR - global attribute holiday2we has reference to non-existing device $holidayDevice";
|
||||
return
|
||||
"ERROR: global attribute holiday2we has reference to non-existing device $holidayDevice";
|
||||
}
|
||||
elsif ( $defs{$holidayDevice}{TYPE} ne "holiday" ) {
|
||||
Log3 $NAME, 3,
|
||||
"RESIDENTStk $NAME: ERROR - global attribute holiday2we seems to have invalid device reference - $holidayDevice is not of type 'holiday'";
|
||||
return
|
||||
"ERROR: global attribute holiday2we seems to have invalid device reference - $holidayDevice is not of type 'holiday'";
|
||||
}
|
||||
}
|
||||
|
||||
# start
|
||||
#
|
||||
if ( $VALUE eq "start" ) {
|
||||
RESIDENTStk_wakeupRun( $NAME, 1 );
|
||||
}
|
||||
|
||||
# trigger
|
||||
#
|
||||
elsif ( $VALUE eq "trigger" ) {
|
||||
RESIDENTStk_wakeupRun($NAME);
|
||||
}
|
||||
|
||||
# stop
|
||||
#
|
||||
if ( $VALUE eq "stop" && $running ) {
|
||||
elsif ( $VALUE eq "stop" && $running ) {
|
||||
Log3 $NAME, 4, "RESIDENTStk $NAME: stopping wake-up program";
|
||||
fhem "setreading $NAME running 0";
|
||||
fhem "set $NAME nextRun $nextRun";
|
||||
@ -236,13 +276,15 @@ if (\$EVTPART0 eq \"stop\") {\
|
||||
else {
|
||||
if ( defined( $notify[1] ) ) {
|
||||
Log3 $NAME, 4,
|
||||
"RESIDENTStk $NAME: trigger $wakeupMacro (running=0,forced-stop=0)";
|
||||
fhem "trigger $wakeupMacro stop $lastRun $wakeupOffset";
|
||||
"RESIDENTStk $NAME: trigger $wakeupMacro stop $lastRun $wakeupOffset $wakeupEnforced $wakeupUserdevice";
|
||||
fhem
|
||||
"trigger $wakeupMacro stop $lastRun $wakeupOffset $wakeupEnforced $wakeupUserdevice";
|
||||
}
|
||||
else {
|
||||
Log3 $NAME, 4,
|
||||
"RESIDENTStk $NAME: trigger $wakeupMacro (running=0,forced-stop=1)";
|
||||
fhem "trigger $wakeupMacro forced-stop $lastRun $wakeupOffset";
|
||||
"RESIDENTStk $NAME: trigger $wakeupMacro forced-stop $lastRun $wakeupOffset $wakeupEnforced $wakeupUserdevice";
|
||||
fhem
|
||||
"trigger $wakeupMacro forced-stop $lastRun $wakeupOffset $wakeupEnforced $wakeupUserdevice";
|
||||
}
|
||||
fhem "setreading $wakeupUserdevice:FILTER=wakeup=1 wakeup 0";
|
||||
|
||||
@ -290,6 +332,13 @@ if (\$EVTPART0 eq \"stop\") {\
|
||||
if ( ReadingsVal( $NAME, "nextRun", 0 ) ne $VALUE );
|
||||
readingsEndUpdate( $defs{$NAME}, 1 );
|
||||
|
||||
my $nextWakeup = RESIDENTStk_wakeupGetNext($wakeupUserdevice);
|
||||
if ($nextWakeup) {
|
||||
fhem "setreading $wakeupUserdevice:FILTER=nextWakeup!=$nextWakeup nextWakeup $nextWakeup";
|
||||
} else {
|
||||
fhem "setreading $wakeupUserdevice:FILTER=nextWakeup!=OFF nextWakeup OFF";
|
||||
}
|
||||
|
||||
fhem
|
||||
"set $wakeupAtdevice modifyTimeSpec {RESIDENTStk_wakeupGetBegin(\"$NAME\")}";
|
||||
|
||||
@ -306,21 +355,25 @@ if (\$EVTPART0 eq \"stop\") {\
|
||||
#
|
||||
sub RESIDENTStk_wakeupGetBegin($) {
|
||||
my ($NAME) = @_;
|
||||
my $defaultBeginTime = "05:00";
|
||||
my $wakeupDefaultTime = AttrVal( $NAME, "wakeupDefaultTime", $defaultBeginTime );
|
||||
my $defaultBeginTime = "05:00";
|
||||
my $wakeupDefaultTime =
|
||||
AttrVal( $NAME, "wakeupDefaultTime", $defaultBeginTime );
|
||||
my $nextRun = ReadingsVal( $NAME, "nextRun", $wakeupDefaultTime );
|
||||
my $wakeupTime = (
|
||||
lc($nextRun) ne "off"
|
||||
? $nextRun
|
||||
: ( lc($wakeupDefaultTime) ne "off" ? $wakeupDefaultTime : $defaultBeginTime ) );
|
||||
lc($nextRun) ne "off" ? $nextRun
|
||||
: (
|
||||
lc($wakeupDefaultTime) ne "off" ? $wakeupDefaultTime
|
||||
: $defaultBeginTime
|
||||
)
|
||||
);
|
||||
my $wakeupOffset = AttrVal( $NAME, "wakeupOffset", 0 );
|
||||
my $return;
|
||||
|
||||
# Recalculate new wake-up value
|
||||
if ( $wakeupTime =~ /^([0-9]{2}:[0-9]{2})$/ ) {
|
||||
my @time = split /:/, $wakeupTime;
|
||||
|
||||
my $seconds = $time[0] * 3600 + $time[1] * 60 - $wakeupOffset * 60;
|
||||
if ( $wakeupTime =~ /^([0-9]{2}:[0-9]{2})$/
|
||||
&& looks_like_number($wakeupOffset) )
|
||||
{
|
||||
my $seconds = RESIDENTStk_time2sec($wakeupTime) - $wakeupOffset * 60;
|
||||
if ( $seconds < 0 ) { $seconds = 86400 + $seconds }
|
||||
|
||||
$return = RESIDENTStk_sec2time($seconds);
|
||||
@ -332,41 +385,71 @@ sub RESIDENTStk_wakeupGetBegin($) {
|
||||
#
|
||||
# Use DUMMY device to run wakup event
|
||||
#
|
||||
sub RESIDENTStk_wakeupRun($) {
|
||||
my ($NAME) = @_;
|
||||
sub RESIDENTStk_wakeupRun($;$) {
|
||||
my ( $NAME, $forceRun ) = @_;
|
||||
|
||||
my $wakeupMacro = AttrVal( $NAME, "wakeupMacro", 0 );
|
||||
my $wakeupDefaultTime = AttrVal( $NAME, "wakeupDefaultTime", 0 );
|
||||
my $wakeupAtdevice = AttrVal( $NAME, "wakeupAtdevice", 0 );
|
||||
my $wakeupUserdevice = AttrVal( $NAME, "wakeupUserdevice", 0 );
|
||||
my $wakeupDays = AttrVal( $NAME, "wakeupDays", 0 );
|
||||
my $wakeupResetdays = AttrVal( $NAME, "wakeupResetdays", 0 );
|
||||
my $wakeupOffset = AttrVal( $NAME, "wakeupOffset", 0 );
|
||||
my $wakeupResetSwitcher = AttrVal( $NAME, "wakeupResetSwitcher", 0 );
|
||||
my $wakeupMacro = AttrVal( $NAME, "wakeupMacro", 0 );
|
||||
my $wakeupDefaultTime = AttrVal( $NAME, "wakeupDefaultTime", 0 );
|
||||
my $wakeupAtdevice = AttrVal( $NAME, "wakeupAtdevice", 0 );
|
||||
my $wakeupUserdevice = AttrVal( $NAME, "wakeupUserdevice", 0 );
|
||||
my $wakeupDays = AttrVal( $NAME, "wakeupDays", "" );
|
||||
my $wakeupHolidays = AttrVal( $NAME, "wakeupHolidays", 0 );
|
||||
my $wakeupResetdays = AttrVal( $NAME, "wakeupResetdays", "" );
|
||||
my $wakeupOffset = AttrVal( $NAME, "wakeupOffset", 0 );
|
||||
my $wakeupEnforced = AttrVal( $NAME, "wakeupEnforced", 0 );
|
||||
my $wakeupResetSwitcher = AttrVal( $NAME, "wakeupResetSwitcher", 0 );
|
||||
my $holidayDevice = AttrVal( "global", "holiday2we", 0 );
|
||||
my $lastRun = ReadingsVal( $NAME, "lastRun", "07:00" );
|
||||
my $nextRun = ReadingsVal( $NAME, "nextRun", "07:00" );
|
||||
my $running = ReadingsVal( $NAME, "running", 0 );
|
||||
my $wakeupUserdeviceWakeup = ReadingsVal( $wakeupUserdevice, "wakeup", 0 );
|
||||
my $room = AttrVal( $NAME, "room", 0 );
|
||||
my $running = 0;
|
||||
my $room = AttrVal( $NAME, "room", 0 );
|
||||
my $running = 0;
|
||||
my $holidayToday = "";
|
||||
|
||||
if ( $wakeupHolidays
|
||||
&& $holidayDevice
|
||||
&& defined( $defs{$holidayDevice} )
|
||||
&& $defs{$holidayDevice}{TYPE} eq "holiday" )
|
||||
{
|
||||
my $hdayTod = ReadingsVal( $holidayDevice, "state", "" );
|
||||
|
||||
if ( $hdayTod ne "none" && $hdayTod ne "" ) { $holidayToday = 1 }
|
||||
else { $holidayToday = 0 }
|
||||
}
|
||||
else {
|
||||
$wakeupHolidays = 0;
|
||||
}
|
||||
|
||||
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
|
||||
localtime(time);
|
||||
localtime( time + $wakeupOffset * 60 );
|
||||
|
||||
if ( $nextRun ne $hour . ":" . $min ) {
|
||||
$lastRun = substr(
|
||||
RESIDENTStk_sec2time(
|
||||
RESIDENTStk_time2sec( $hour . ":" . $min ) - $wakeupOffset * 60
|
||||
),
|
||||
0, -3
|
||||
);
|
||||
}
|
||||
else {
|
||||
$lastRun = $nextRun;
|
||||
}
|
||||
|
||||
my @days = ($wday);
|
||||
if ($wakeupDays) {
|
||||
if ( $wakeupDays ne "" ) {
|
||||
@days = split /,/, $wakeupDays;
|
||||
}
|
||||
|
||||
my @rdays = ($wday);
|
||||
if ($wakeupResetdays) {
|
||||
if ( $wakeupResetdays ne "" ) {
|
||||
@rdays = split /,/, $wakeupResetdays;
|
||||
}
|
||||
|
||||
if ( !defined( $defs{$NAME} ) ) {
|
||||
return "$NAME: Non existing device";
|
||||
}
|
||||
elsif ( lc($nextRun) eq "off" ) {
|
||||
elsif ( lc($nextRun) eq "off" && !$forceRun ) {
|
||||
Log3 $NAME, 4,
|
||||
"RESIDENTStk $NAME: alarm set to OFF - not triggering wake-up program";
|
||||
}
|
||||
@ -385,15 +468,58 @@ sub RESIDENTStk_wakeupRun($) {
|
||||
elsif ( $defs{$wakeupUserdevice}{TYPE} eq "GUEST"
|
||||
&& ReadingsVal( $wakeupUserdevice, "state", "" ) eq "none" )
|
||||
{
|
||||
Log3 $NAME, 4,
|
||||
"RESIDENTStk $NAME: GUEST device $wakeupUserdevice has status value 'none' so let's disable this alarm timer";
|
||||
fhem "set $NAME nextRun OFF";
|
||||
return;
|
||||
}
|
||||
elsif ($wday ~~ @days
|
||||
&& ReadingsVal( $wakeupUserdevice, "state", "" ) ne "absent"
|
||||
&& ReadingsVal( $wakeupUserdevice, "state", "" ) ne "gone"
|
||||
&& ReadingsVal( $wakeupUserdevice, "state", "" ) ne "gotosleep"
|
||||
&& ReadingsVal( $wakeupUserdevice, "state", "" ) ne "awoken" )
|
||||
elsif ( !$wakeupHolidays && !( $wday ~~ @days ) && !$forceRun ) {
|
||||
Log3 $NAME, 4,
|
||||
"RESIDENTStk $NAME: weekday restriction in use - not triggering wake-up program this time";
|
||||
}
|
||||
elsif (
|
||||
$wakeupHolidays
|
||||
&& !$forceRun
|
||||
&& ( $wakeupHolidays eq "orHoliday"
|
||||
|| $wakeupHolidays eq "orNoHoliday" )
|
||||
&& (
|
||||
!( $wday ~~ @days )
|
||||
&& ( ( $wakeupHolidays eq "orHoliday" && !$holidayToday )
|
||||
|| ( $wakeupHolidays eq "orNoHoliday" && $holidayToday ) )
|
||||
)
|
||||
)
|
||||
{
|
||||
Log3 $NAME, 4,
|
||||
"RESIDENTStk $NAME: neither weekday nor holiday restriction matched - not triggering wake-up program this time";
|
||||
}
|
||||
elsif (
|
||||
$wakeupHolidays
|
||||
&& !$forceRun
|
||||
&& ( $wakeupHolidays eq "andHoliday"
|
||||
|| $wakeupHolidays eq "andNoHoliday" )
|
||||
&& (
|
||||
!( $wday ~~ @days )
|
||||
|| ( ( $wakeupHolidays eq "andHoliday" && !$holidayToday )
|
||||
|| ( $wakeupHolidays eq "andNoHoliday" && $holidayToday ) )
|
||||
)
|
||||
)
|
||||
{
|
||||
Log3 $NAME, 4,
|
||||
"RESIDENTStk $NAME: weekday restriction in conjunction with $wakeupHolidays in use - not triggering wake-up program this time";
|
||||
}
|
||||
elsif (ReadingsVal( $wakeupUserdevice, "state", "" ) eq "absent"
|
||||
|| ReadingsVal( $wakeupUserdevice, "state", "" ) eq "gone"
|
||||
|| ReadingsVal( $wakeupUserdevice, "state", "" ) eq "gotosleep"
|
||||
|| ReadingsVal( $wakeupUserdevice, "state", "" ) eq "awoken" )
|
||||
{
|
||||
Log3 $NAME, 4,
|
||||
"RESIDENTStk $NAME: we should not start any wake-up program for resident device $wakeupUserdevice being in state '"
|
||||
. ReadingsVal( $wakeupUserdevice, "state", "" )
|
||||
. "' - not triggering wake-up program this time";
|
||||
}
|
||||
|
||||
# general conditions to trigger program fulfilled
|
||||
else {
|
||||
if ( !$wakeupMacro ) {
|
||||
return "$NAME: missing attribute wakeupMacro";
|
||||
}
|
||||
@ -406,14 +532,18 @@ sub RESIDENTStk_wakeupRun($) {
|
||||
}
|
||||
elsif ($wakeupUserdeviceWakeup) {
|
||||
Log3 $NAME, 3,
|
||||
"RESIDENTStk $NAME: Another wake-up program is already being executed, won't trigger $wakeupMacro";
|
||||
"RESIDENTStk $NAME: Another wake-up program is already being executed for device $wakeupUserdevice, won't trigger $wakeupMacro";
|
||||
}
|
||||
else {
|
||||
Log3 $NAME, 4,
|
||||
"RESIDENTStk $NAME: trigger $wakeupMacro (running=1)";
|
||||
fhem "trigger $wakeupMacro start $nextRun $wakeupOffset";
|
||||
fhem
|
||||
"trigger $wakeupMacro start $lastRun $wakeupOffset $wakeupEnforced $wakeupUserdevice";
|
||||
fhem "setreading $wakeupUserdevice lastWakeup $lastRun";
|
||||
fhem "setreading $wakeupUserdevice wakeup 1";
|
||||
fhem "setreading $NAME lastRun $nextRun";
|
||||
fhem "setreading $wakeupUserdevice wakeup 0"
|
||||
if ( !$wakeupOffset );
|
||||
fhem "setreading $NAME lastRun $lastRun";
|
||||
|
||||
if ( $wakeupOffset > 0 ) {
|
||||
my $wakeupStopAtdevice = $wakeupAtdevice . "_stop";
|
||||
@ -460,6 +590,10 @@ sub RESIDENTStk_wakeupRun($) {
|
||||
readingsEndUpdate( $defs{$NAME}, 1 );
|
||||
}
|
||||
|
||||
if ( !$running ) {
|
||||
fhem "setreading $NAME:FILTER=state!=$nextRun state $nextRun";
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
@ -516,6 +650,183 @@ sub RESIDENTStk_AttrFnDummy(@) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
# GENERAL USER AUTOMATION FUNCTIONS
|
||||
#------------------------------------
|
||||
#
|
||||
|
||||
sub RESIDENTStk_wakeupGetNext($) {
|
||||
my ($name) = @_;
|
||||
|
||||
my $wakeupDeviceList = (
|
||||
AttrVal( $name, "rgr_wakeupDevice", 0 )
|
||||
? AttrVal( $name, "rgr_wakeupDevice", 0 )
|
||||
: (
|
||||
AttrVal( $name, "rr_wakeupDevice", 0 )
|
||||
? AttrVal( $name, "rr_wakeupDevice", 0 )
|
||||
: (
|
||||
AttrVal( $name, "rg_wakeupDevice", 0 )
|
||||
? AttrVal( $name, "rg_wakeupDevice", 0 )
|
||||
: 0
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
return "Device $name does not seem to have any wakeup devices registered."
|
||||
if ( !$wakeupDeviceList );
|
||||
|
||||
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
|
||||
localtime(time);
|
||||
|
||||
my $wdayTomorrow = $wday + 1;
|
||||
$wdayTomorrow = 0 if ( $wdayTomorrow == 7 );
|
||||
my $secNow = RESIDENTStk_time2sec( $hour . ":" . $min ) + $sec;
|
||||
my $definitiveNextToday = 0;
|
||||
my $definitiveNextTomorrow = 0;
|
||||
|
||||
for my $wakeupDevice ( split /,/, $wakeupDeviceList ) {
|
||||
|
||||
my $nextRun = ReadingsVal( $wakeupDevice, "nextRun", 0 );
|
||||
my $wakeupDays = AttrVal( $wakeupDevice, "wakeupDays", "" );
|
||||
my $holidayDevice = AttrVal( "global", "holiday2we", 0 );
|
||||
my $wakeupHolidays = AttrVal( $wakeupDevice, "wakeupHolidays", 0 );
|
||||
my $holidayToday = "";
|
||||
my $holidayTomorrow = "";
|
||||
|
||||
if ( $wakeupHolidays
|
||||
&& $holidayDevice
|
||||
&& defined( $defs{$holidayDevice} )
|
||||
&& $defs{$holidayDevice}{TYPE} eq "holiday" )
|
||||
{
|
||||
my $hdayTod = ReadingsVal( $holidayDevice, "state", "" );
|
||||
my $hdayTom = ReadingsVal( $holidayDevice, "tomorrow", "" );
|
||||
|
||||
if ( $hdayTod ne "none" && $hdayTod ne "" ) { $holidayToday = 1 }
|
||||
else { $holidayToday = 0 }
|
||||
|
||||
if ( $hdayTom ne "none" && $hdayTom ne "" ) { $holidayTomorrow = 1 }
|
||||
else { $holidayTomorrow = 0 }
|
||||
}
|
||||
|
||||
my @days = ($wday);
|
||||
if ( $wakeupDays ne "" ) {
|
||||
@days = split /,/, $wakeupDays;
|
||||
}
|
||||
|
||||
my @daysTomorrow = ($wdayTomorrow);
|
||||
if ( $wakeupDays ne "" ) {
|
||||
@daysTomorrow = split /,/, $wakeupDays;
|
||||
}
|
||||
|
||||
if ( lc($nextRun) ne "off" && $nextRun =~ /^([0-9]{2}:[0-9]{2})$/ ) {
|
||||
my $nextRunSec = RESIDENTStk_time2sec($nextRun);
|
||||
|
||||
# still running today
|
||||
if ( $nextRunSec > $secNow ) {
|
||||
|
||||
# if today is in scope
|
||||
if ( $wday ~~ @days ) {
|
||||
|
||||
# if we need to consider holidays in addition
|
||||
if (
|
||||
$wakeupHolidays
|
||||
&& ( $wakeupHolidays eq "andHoliday" && !$holidayToday )
|
||||
|| ( $wakeupHolidays eq "andNoHoliday"
|
||||
&& $holidayToday )
|
||||
)
|
||||
{
|
||||
next;
|
||||
}
|
||||
|
||||
# easy if there is no holiday dependency
|
||||
elsif ( !$definitiveNextToday
|
||||
|| $nextRunSec < $definitiveNextToday )
|
||||
{
|
||||
$definitiveNextToday = $nextRunSec;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# if we need to consider holidays in parallel to weekdays
|
||||
if (
|
||||
$wakeupHolidays
|
||||
&& (
|
||||
( $wakeupHolidays eq "orHoliday" && $holidayToday )
|
||||
|| ( $wakeupHolidays eq "orNoHoliday"
|
||||
&& !$holidayToday )
|
||||
)
|
||||
)
|
||||
{
|
||||
|
||||
if ( !$definitiveNextToday
|
||||
|| $nextRunSec < $definitiveNextToday )
|
||||
{
|
||||
$definitiveNextToday = $nextRunSec;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# running tomorrow
|
||||
else {
|
||||
|
||||
# if tomorrow is in scope
|
||||
if ( $wdayTomorrow ~~ @daysTomorrow ) {
|
||||
|
||||
# if we need to consider holidays in addition
|
||||
if (
|
||||
$wakeupHolidays && ( $wakeupHolidays eq "andHoliday"
|
||||
&& !$holidayTomorrow )
|
||||
|| ( $wakeupHolidays eq "andNoHoliday"
|
||||
&& $holidayTomorrow )
|
||||
)
|
||||
{
|
||||
next;
|
||||
}
|
||||
|
||||
# easy if there is no holiday dependency
|
||||
elsif ( !$definitiveNextTomorrow
|
||||
|| $nextRunSec < $definitiveNextTomorrow )
|
||||
{
|
||||
$definitiveNextTomorrow = $nextRunSec;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# if we need to consider holidays in parallel to weekdays
|
||||
if (
|
||||
$wakeupHolidays
|
||||
&& (
|
||||
( $wakeupHolidays eq "orHoliday" && $holidayTomorrow )
|
||||
|| ( $wakeupHolidays eq "orNoHoliday"
|
||||
&& !$holidayTomorrow )
|
||||
)
|
||||
)
|
||||
{
|
||||
|
||||
if ( !$definitiveNextTomorrow
|
||||
|| $nextRunSec < $definitiveNextTomorrow )
|
||||
{
|
||||
$definitiveNextTomorrow = $nextRunSec;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return substr( RESIDENTStk_sec2time($definitiveNextToday), 0, -3 )
|
||||
if ($definitiveNextToday);
|
||||
|
||||
return substr( RESIDENTStk_sec2time($definitiveNextTomorrow), 0, -3 )
|
||||
if ($definitiveNextTomorrow);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#####################################
|
||||
# GENERAL FUNCTIONS USED IN RESIDENTS, ROOMMATE, GUEST
|
||||
#------------------------------------
|
||||
@ -570,6 +881,13 @@ sub RESIDENTStk_sec2time($) {
|
||||
return "$hours:$minutes:$seconds";
|
||||
}
|
||||
|
||||
sub RESIDENTStk_time2sec($) {
|
||||
my ($timeString) = @_;
|
||||
my @time = split /:/, $timeString;
|
||||
|
||||
return $time[0] * 3600 + $time[1] * 60;
|
||||
}
|
||||
|
||||
sub RESIDENTStk_InternalTimer($$$$$) {
|
||||
my ( $modifier, $tim, $callback, $hash, $waitIfInitNotDone ) = @_;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user