mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00
RESIDENTStk wakeuptimer: add macro example code, auto-cleanup of temp. at-devices, advanced readings, error handlings and many other things
git-svn-id: https://svn.fhem.de/fhem/trunk@8208 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
ee51e6dcd0
commit
d483e42c97
@ -23,7 +23,7 @@
|
|||||||
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Version: 1.2.0
|
# Version: 1.2.1
|
||||||
#
|
#
|
||||||
# Major Version History:
|
# Major Version History:
|
||||||
# - 1.2.0 - 2015-03-11
|
# - 1.2.0 - 2015-03-11
|
||||||
@ -80,7 +80,7 @@ sub RESIDENTS_Define($$) {
|
|||||||
if ($init_done) {
|
if ($init_done) {
|
||||||
$attr{$name}{alias} = "Residents";
|
$attr{$name}{alias} = "Residents";
|
||||||
$attr{$name}{devStateIcon} =
|
$attr{$name}{devStateIcon} =
|
||||||
'.*home:status_available:absent .*absent:status_away_1:home .*gone:status_standby:home .*none:control_building_empty .*gotosleep:status_night:asleep .*asleep:status_night:awoken .*awoken:status_available:home';
|
'.*home:status_available:absent .*absent:status_away_1:home .*gone:status_standby:home .*none:control_building_empty .*gotosleep:status_night:asleep .*asleep:status_night:awoken .*awoken:status_available:home .*:user_unknown:home';
|
||||||
$attr{$name}{group} = "Home State";
|
$attr{$name}{group} = "Home State";
|
||||||
$attr{$name}{icon} = "control_building_filled";
|
$attr{$name}{icon} = "control_building_filled";
|
||||||
$attr{$name}{room} = "Residents";
|
$attr{$name}{room} = "Residents";
|
||||||
@ -166,7 +166,10 @@ sub RESIDENTS_Notify($$) {
|
|||||||
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
||||||
|
|
||||||
# state changed
|
# state changed
|
||||||
if ( $change !~ /:/ || $change =~ /wayhome:/ ) {
|
if ( $change !~ /:/
|
||||||
|
|| $change =~ /wayhome:/
|
||||||
|
|| $change =~ /wakeup:/ )
|
||||||
|
{
|
||||||
Log3 $hash, 4,
|
Log3 $hash, 4,
|
||||||
"RESIDENTS "
|
"RESIDENTS "
|
||||||
. $hashName . ": "
|
. $hashName . ": "
|
||||||
@ -200,6 +203,8 @@ sub RESIDENTS_Notify($$) {
|
|||||||
readingsEndUpdate( $hash, 1 );
|
readingsEndUpdate( $hash, 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# if we have registered wakeup devices
|
# if we have registered wakeup devices
|
||||||
@ -213,28 +218,13 @@ sub RESIDENTS_Notify($$) {
|
|||||||
if ( !$dev->{CHANGED} );
|
if ( !$dev->{CHANGED} );
|
||||||
|
|
||||||
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
||||||
|
|
||||||
# state changed
|
|
||||||
if ( $change =~ /OFF|([0-9]{2}:[0-9]{2})/ ) {
|
|
||||||
Log3 $hash, 4,
|
|
||||||
"RESIDENTS "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": notify about change to $change";
|
|
||||||
|
|
||||||
RESIDENTStk_wakeupSet( $devName, $change );
|
RESIDENTStk_wakeupSet( $devName, $change );
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Log3 $hash, 5,
|
return;
|
||||||
"RESIDENTS "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": received unhandled notify about change $change";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# stuff for every registered wakeupdev
|
# process sub-child notifies: *_wakeupDevice
|
||||||
foreach my $wakeupDev (@registeredWakeupdevs) {
|
foreach my $wakeupDev (@registeredWakeupdevs) {
|
||||||
|
|
||||||
# if this is a notification of a registered sub dummy device
|
# if this is a notification of a registered sub dummy device
|
||||||
@ -249,25 +239,11 @@ sub RESIDENTS_Notify($$) {
|
|||||||
if ( !$dev->{CHANGED} );
|
if ( !$dev->{CHANGED} );
|
||||||
|
|
||||||
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
||||||
|
RESIDENTStk_wakeupSet( $wakeupDev, $change )
|
||||||
|
if ( $change ne "off" );
|
||||||
|
}
|
||||||
|
|
||||||
# state changed to on
|
last;
|
||||||
if ( $change eq "auto" ) {
|
|
||||||
Log3 $hash, 4,
|
|
||||||
"RESIDENTS "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": notify about change to $change";
|
|
||||||
|
|
||||||
RESIDENTStk_wakeupSet($wakeupDev);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log3 $hash, 5,
|
|
||||||
"RESIDENTS "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": received unhandled notify about change $change";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -580,6 +556,8 @@ sub RESIDENTS_Set($@) {
|
|||||||
$wakeuptimerName = $name . "_wakeuptimer" . $i;
|
$wakeuptimerName = $name . "_wakeuptimer" . $i;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
my $sortby = AttrVal( $name, "sortby", -1 );
|
||||||
|
$sortby++;
|
||||||
|
|
||||||
# create new dummy device
|
# create new dummy device
|
||||||
fhem "define $wakeuptimerName dummy";
|
fhem "define $wakeuptimerName dummy";
|
||||||
@ -587,36 +565,41 @@ sub RESIDENTS_Set($@) {
|
|||||||
fhem
|
fhem
|
||||||
"attr $wakeuptimerName comment Auto-created by RESIDENTS module for use with RESIDENTS Toolkit";
|
"attr $wakeuptimerName comment Auto-created by RESIDENTS module for use with RESIDENTS Toolkit";
|
||||||
fhem
|
fhem
|
||||||
"attr $wakeuptimerName devStateIcon OFF:general_aus\@red .*:general_an\@green:OFF";
|
"attr $wakeuptimerName devStateIcon OFF:general_aus\@red:reset running:general_an\@blue:stop .*:general_an\@green:nextRun%20OFF";
|
||||||
fhem "attr $wakeuptimerName group " . $attr{$name}{group}
|
fhem "attr $wakeuptimerName group " . $attr{$name}{group}
|
||||||
if ( defined( $attr{$name}{group} ) );
|
if ( defined( $attr{$name}{group} ) );
|
||||||
fhem "attr $wakeuptimerName icon time_timer";
|
fhem "attr $wakeuptimerName icon time_timer";
|
||||||
fhem "attr $wakeuptimerName room " . $attr{$name}{room}
|
fhem "attr $wakeuptimerName room " . $attr{$name}{room}
|
||||||
if ( defined( $attr{$name}{room} ) );
|
if ( defined( $attr{$name}{room} ) );
|
||||||
fhem
|
fhem
|
||||||
"attr $wakeuptimerName setList state: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";
|
"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";
|
||||||
fhem "attr $wakeuptimerName userattr wakeupUserdevice";
|
fhem "attr $wakeuptimerName userattr wakeupUserdevice";
|
||||||
|
fhem "attr $wakeuptimerName sortby " . $sortby
|
||||||
|
if ($sortby);
|
||||||
fhem "attr $wakeuptimerName wakeupUserdevice $name";
|
fhem "attr $wakeuptimerName wakeupUserdevice $name";
|
||||||
fhem "attr $wakeuptimerName webCmd state";
|
fhem "attr $wakeuptimerName webCmd nextRun";
|
||||||
|
|
||||||
# register slave device
|
# register slave device
|
||||||
if ( defined( $attr{$name}{rgr_wakeupDevice} ) ) {
|
my $wakeupDevice = AttrVal( $name, "rgr_wakeupDevice", 0 );
|
||||||
fhem "attr $name rgr_wakeupDevice "
|
if ( !$wakeupDevice ) {
|
||||||
. $attr{$name}{rgr_wakeupDevice}
|
|
||||||
. ",$wakeuptimerName";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fhem "attr $name rgr_wakeupDevice $wakeuptimerName";
|
fhem "attr $name rgr_wakeupDevice $wakeuptimerName";
|
||||||
}
|
}
|
||||||
|
elsif ( $wakeupDevice !~ /(.*,?)($wakeuptimerName)(.*,?)/ )
|
||||||
|
{
|
||||||
|
fhem "attr $name rgr_wakeupDevice "
|
||||||
|
. $wakeupDevice
|
||||||
|
. ",$wakeuptimerName";
|
||||||
|
}
|
||||||
|
|
||||||
# trigger first update
|
# trigger first update
|
||||||
fhem "set $wakeuptimerName OFF";
|
fhem "set $wakeuptimerName nextRun OFF";
|
||||||
|
|
||||||
$created = 1;
|
$created = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
"Dummy $wakeuptimerName and other pending devices created and pre-configured. You may edit Macro_$wakeuptimerName to define your wake-up actions and at_$wakeuptimerName for optional at-device adjustments.";
|
"Dummy $wakeuptimerName and other pending devices created and pre-configured.\nYou may edit Macro_$wakeuptimerName to define your wake-up actions\nand at_$wakeuptimerName for optional at-device adjustments.";
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return "Invalid 2nd argument, choose one of wakeuptimer ";
|
return "Invalid 2nd argument, choose one of wakeuptimer ";
|
||||||
@ -657,6 +640,7 @@ sub RESIDENTS_UpdateReadings (@) {
|
|||||||
my $state_totalGuests = 0;
|
my $state_totalGuests = 0;
|
||||||
my $state_guestDev = 0;
|
my $state_guestDev = 0;
|
||||||
my $wayhome = 0;
|
my $wayhome = 0;
|
||||||
|
my $wakeup = 0;
|
||||||
my $newstate;
|
my $newstate;
|
||||||
my $presence = "absent";
|
my $presence = "absent";
|
||||||
|
|
||||||
@ -680,32 +664,36 @@ sub RESIDENTS_UpdateReadings (@) {
|
|||||||
$state_totalPresent++;
|
$state_totalPresent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $defs{$roommate}{READINGS}{state}{VAL} eq "gotosleep" ) {
|
elsif ( $defs{$roommate}{READINGS}{state}{VAL} eq "gotosleep" ) {
|
||||||
$state_gotosleep++;
|
$state_gotosleep++;
|
||||||
$state_totalPresent++;
|
$state_totalPresent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $defs{$roommate}{READINGS}{state}{VAL} eq "asleep" ) {
|
elsif ( $defs{$roommate}{READINGS}{state}{VAL} eq "asleep" ) {
|
||||||
$state_asleep++;
|
$state_asleep++;
|
||||||
$state_totalPresent++;
|
$state_totalPresent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $defs{$roommate}{READINGS}{state}{VAL} eq "awoken" ) {
|
elsif ( $defs{$roommate}{READINGS}{state}{VAL} eq "awoken" ) {
|
||||||
$state_awoken++;
|
$state_awoken++;
|
||||||
$state_totalPresent++;
|
$state_totalPresent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $defs{$roommate}{READINGS}{state}{VAL} eq "absent" ) {
|
elsif ( $defs{$roommate}{READINGS}{state}{VAL} eq "absent" ) {
|
||||||
$state_absent++;
|
$state_absent++;
|
||||||
$state_totalAbsent++;
|
$state_totalAbsent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $defs{$roommate}{READINGS}{state}{VAL} eq "gone" ) {
|
elsif ( $defs{$roommate}{READINGS}{state}{VAL} eq "gone" ) {
|
||||||
$state_gone++;
|
$state_gone++;
|
||||||
$state_totalAbsent++;
|
$state_totalAbsent++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( defined( $defs{$roommate}{READINGS}{wakeup}{VAL} ) ) {
|
||||||
|
$wakeup += $defs{$roommate}{READINGS}{wakeup}{VAL};
|
||||||
|
}
|
||||||
|
|
||||||
if ( defined( $defs{$roommate}{READINGS}{wayhome}{VAL} ) ) {
|
if ( defined( $defs{$roommate}{READINGS}{wayhome}{VAL} ) ) {
|
||||||
$wayhome += $defs{$roommate}{READINGS}{wayhome}{VAL};
|
$wayhome += $defs{$roommate}{READINGS}{wayhome}{VAL};
|
||||||
}
|
}
|
||||||
@ -752,6 +740,10 @@ sub RESIDENTS_UpdateReadings (@) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( defined( $defs{$guest}{READINGS}{wakeup}{VAL} ) ) {
|
||||||
|
$wakeup += $defs{$guest}{READINGS}{wakeup}{VAL};
|
||||||
|
}
|
||||||
|
|
||||||
if ( defined( $defs{$guest}{READINGS}{wayhome}{VAL} ) ) {
|
if ( defined( $defs{$guest}{READINGS}{wayhome}{VAL} ) ) {
|
||||||
$wayhome += $defs{$guest}{READINGS}{wayhome}{VAL};
|
$wayhome += $defs{$guest}{READINGS}{wayhome}{VAL};
|
||||||
}
|
}
|
||||||
@ -801,6 +793,10 @@ sub RESIDENTS_UpdateReadings (@) {
|
|||||||
if ( !defined( $hash->{READINGS}{residentsGone}{VAL} )
|
if ( !defined( $hash->{READINGS}{residentsGone}{VAL} )
|
||||||
|| $hash->{READINGS}{residentsGone}{VAL} ne $state_gone );
|
|| $hash->{READINGS}{residentsGone}{VAL} ne $state_gone );
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsTotalWakeup", $wakeup )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsTotalWakeup}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsTotalWakeup}{VAL} ne $wakeup );
|
||||||
|
|
||||||
readingsBulkUpdate( $hash, "residentsTotalWayhome", $wayhome )
|
readingsBulkUpdate( $hash, "residentsTotalWayhome", $wayhome )
|
||||||
if ( !defined( $hash->{READINGS}{residentsTotalWayhome}{VAL} )
|
if ( !defined( $hash->{READINGS}{residentsTotalWayhome}{VAL} )
|
||||||
|| $hash->{READINGS}{residentsTotalWayhome}{VAL} ne $wayhome );
|
|| $hash->{READINGS}{residentsTotalWayhome}{VAL} ne $wayhome );
|
||||||
@ -911,14 +907,14 @@ sub RESIDENTS_UpdateReadings (@) {
|
|||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurSleep",
|
"lastDurSleep",
|
||||||
RESIDENTS_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastSleep}{VAL}
|
$datetime, $hash->{READINGS}{lastSleep}{VAL}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurSleep_cr",
|
"lastDurSleep_cr",
|
||||||
RESIDENTS_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastSleep}{VAL}, "min"
|
$datetime, $hash->{READINGS}{lastSleep}{VAL}, "min"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -945,14 +941,14 @@ sub RESIDENTS_UpdateReadings (@) {
|
|||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurAbsence",
|
"lastDurAbsence",
|
||||||
RESIDENTS_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastDeparture}{VAL}
|
$datetime, $hash->{READINGS}{lastDeparture}{VAL}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurAbsence_cr",
|
"lastDurAbsence_cr",
|
||||||
RESIDENTS_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastDeparture}{VAL},
|
$datetime, $hash->{READINGS}{lastDeparture}{VAL},
|
||||||
"min"
|
"min"
|
||||||
)
|
)
|
||||||
@ -969,14 +965,14 @@ sub RESIDENTS_UpdateReadings (@) {
|
|||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurPresence",
|
"lastDurPresence",
|
||||||
RESIDENTS_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastArrival}{VAL}
|
$datetime, $hash->{READINGS}{lastArrival}{VAL}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurPresence_cr",
|
"lastDurPresence_cr",
|
||||||
RESIDENTS_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastArrival}{VAL},
|
$datetime, $hash->{READINGS}{lastArrival}{VAL},
|
||||||
"min"
|
"min"
|
||||||
)
|
)
|
||||||
@ -989,49 +985,6 @@ sub RESIDENTS_UpdateReadings (@) {
|
|||||||
readingsEndUpdate( $hash, 1 );
|
readingsEndUpdate( $hash, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
###################################
|
|
||||||
sub RESIDENTS_TimeDiff($$;$) {
|
|
||||||
my ( $datetimeNow, $datetimeOld, $format ) = @_;
|
|
||||||
|
|
||||||
my $timestampNow = RESIDENTS_Datetime2Timestamp($datetimeNow);
|
|
||||||
my $timestampOld = RESIDENTS_Datetime2Timestamp($datetimeOld);
|
|
||||||
my $timeDiff = $timestampNow - $timestampOld;
|
|
||||||
|
|
||||||
# return seconds
|
|
||||||
return int( $timeDiff + 0.5 ) if ( defined($format) && $format eq "sec" );
|
|
||||||
|
|
||||||
# return minutes
|
|
||||||
return int( $timeDiff / 60 + 0.5 )
|
|
||||||
if ( defined($format) && $format eq "min" );
|
|
||||||
|
|
||||||
# return human readable format
|
|
||||||
my $hours = ( $timeDiff < 3600 ? 0 : int( $timeDiff / 3600 ) );
|
|
||||||
$timeDiff -= ( $hours == 0 ? 0 : ( $hours * 3600 ) );
|
|
||||||
my $minutes = ( $timeDiff < 60 ? 0 : int( $timeDiff / 60 ) );
|
|
||||||
my $seconds = $timeDiff % 60;
|
|
||||||
|
|
||||||
$hours = "0" . $hours if ( $hours < 10 );
|
|
||||||
$minutes = "0" . $minutes if ( $minutes < 10 );
|
|
||||||
$seconds = "0" . $seconds if ( $seconds < 10 );
|
|
||||||
|
|
||||||
return "$hours:$minutes:$seconds";
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################
|
|
||||||
sub RESIDENTS_Datetime2Timestamp($) {
|
|
||||||
my ($datetime) = @_;
|
|
||||||
|
|
||||||
my ( $date, $time, $y, $m, $d, $hour, $min, $sec, $timestamp );
|
|
||||||
|
|
||||||
( $date, $time ) = split( ' ', $datetime );
|
|
||||||
( $y, $m, $d ) = split( '-', $date );
|
|
||||||
( $hour, $min, $sec ) = split( ':', $time );
|
|
||||||
$m -= 01;
|
|
||||||
$timestamp = timelocal( $sec, $min, $hour, $d, $m, $y );
|
|
||||||
|
|
||||||
return $timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
@ -1212,6 +1165,9 @@ sub RESIDENTS_Datetime2Timestamp($) {
|
|||||||
<li>
|
<li>
|
||||||
<b>residentsTotalPresent</b> - number of all residents who are currently at home
|
<b>residentsTotalPresent</b> - number of all residents who are currently at home
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>residentsTotalWakeup</b> - number of all residents which currently have a wake-up program being executed
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>residentsTotalWayhome</b> - number of all active residents who are currently on their way back home
|
<b>residentsTotalWayhome</b> - number of all active residents who are currently on their way back home
|
||||||
</li>
|
</li>
|
||||||
@ -1256,7 +1212,7 @@ sub RESIDENTS_Datetime2Timestamp($) {
|
|||||||
<i>wakeupResetdays</i> - if wakeupDefaultTime is set you may restrict timer reset to specific days only. Mon=1,Tue=2,Wed=3,Thu=4,Fri=5,Sat=6,Sun=0 (optional)
|
<i>wakeupResetdays</i> - if wakeupDefaultTime is set you may restrict timer reset to specific days only. Mon=1,Tue=2,Wed=3,Thu=4,Fri=5,Sat=6,Sun=0 (optional)
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<i>wakeupResetSwitcher</i> - DUMMY device to quickly turn on/off reset function (optional, device will be auto-created/-deleted)
|
<i>wakeupResetSwitcher</i> - DUMMY device to quickly turn on/off reset function (optional, device will be auto-created)
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<i>wakeupUserdevice</i> - backlink to RESIDENTS, ROOMMATE or GUEST device to check it's status (mandatory)
|
<i>wakeupUserdevice</i> - backlink to RESIDENTS, ROOMMATE or GUEST device to check it's status (mandatory)
|
||||||
@ -1444,6 +1400,9 @@ sub RESIDENTS_Datetime2Timestamp($) {
|
|||||||
<li>
|
<li>
|
||||||
<b>residentsTotalPresent</b> - Summe aller aktiven Bewohner, die momentan zu Hause sind
|
<b>residentsTotalPresent</b> - Summe aller aktiven Bewohner, die momentan zu Hause sind
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>residentsTotalWakeup</b> - Summe aller Bewohner, bei denen aktuell ein Weckprogramm ausgeführt wird
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>residentsTotalWayhome</b> - Summe aller aktiven Bewohner, die momentan auf dem Weg zurück nach Hause sind
|
<b>residentsTotalWayhome</b> - Summe aller aktiven Bewohner, die momentan auf dem Weg zurück nach Hause sind
|
||||||
</li>
|
</li>
|
||||||
@ -1488,7 +1447,7 @@ sub RESIDENTS_Datetime2Timestamp($) {
|
|||||||
<i>wakeupResetdays</i> - sofern wakeupDefaultTime gesetzt ist, kann der Reset hier auf betimmte Tage begrenzt werden. Mon=1,Di=2,Mi=3,Do=4,Fr=5,Sa=6,So=0 (optional)
|
<i>wakeupResetdays</i> - sofern wakeupDefaultTime gesetzt ist, kann der Reset hier auf betimmte Tage begrenzt werden. Mon=1,Di=2,Mi=3,Do=4,Fr=5,Sa=6,So=0 (optional)
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<i>wakeupResetSwitcher</i> - das DUMMY Device, welches zum schnellen ein/aus schalten der Resetfunktion verwendet wird (optional, Device wird automatisch angelegt/gelöscht)
|
<i>wakeupResetSwitcher</i> - das DUMMY Device, welches zum schnellen ein/aus schalten der Resetfunktion verwendet wird (optional, Device wird automatisch angelegt)
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<i>wakeupUserdevice</i> - Backlink zum RESIDENTS, ROOMMATE oder GUEST Gerät, um dessen Status zu prüfen (notwendig)
|
<i>wakeupUserdevice</i> - Backlink zum RESIDENTS, ROOMMATE oder GUEST Gerät, um dessen Status zu prüfen (notwendig)
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Version: 1.2.0
|
# Version: 1.2.1
|
||||||
#
|
#
|
||||||
# Major Version History:
|
# Major Version History:
|
||||||
# - 1.2.0 - 2015-03-11
|
# - 1.2.0 - 2015-03-11
|
||||||
@ -141,7 +141,7 @@ sub GUEST_Define($$) {
|
|||||||
$attr{$name}{alias} = $aliasname;
|
$attr{$name}{alias} = $aliasname;
|
||||||
|
|
||||||
$attr{$name}{devStateIcon} =
|
$attr{$name}{devStateIcon} =
|
||||||
".*home:user_available:absent .*absent:user_away:home .*none:control_building_empty:home .*gotosleep:scene_toilet:asleep .*asleep:scene_sleeping:awoken .*awoken:scene_sleeping_alternat:home .*:user_unknown";
|
".*home:user_available:absent .*absent:user_away:home .*none:control_building_empty:home .*gotosleep:scene_toilet:asleep .*asleep:scene_sleeping:awoken .*awoken:scene_sleeping_alternat:home .*:user_unknown:home";
|
||||||
$attr{$name}{group} = "Guests";
|
$attr{$name}{group} = "Guests";
|
||||||
$attr{$name}{icon} = "scene_visit_guests";
|
$attr{$name}{icon} = "scene_visit_guests";
|
||||||
$attr{$name}{rg_realname} = "alias";
|
$attr{$name}{rg_realname} = "alias";
|
||||||
@ -179,8 +179,8 @@ sub GUEST_Define($$) {
|
|||||||
sub GUEST_Undefine($$) {
|
sub GUEST_Undefine($$) {
|
||||||
my ( $hash, $name ) = @_;
|
my ( $hash, $name ) = @_;
|
||||||
|
|
||||||
GUEST_RemoveInternalTimer( "AutoGone", $hash );
|
RESIDENTStk_RemoveInternalTimer( "AutoGone", $hash );
|
||||||
GUEST_RemoveInternalTimer( "DurationTimer", $hash );
|
RESIDENTStk_RemoveInternalTimer( "DurationTimer", $hash );
|
||||||
|
|
||||||
if ( defined( $hash->{RESIDENTGROUPS} ) ) {
|
if ( defined( $hash->{RESIDENTGROUPS} ) ) {
|
||||||
my @registeredResidentgroups =
|
my @registeredResidentgroups =
|
||||||
@ -225,28 +225,13 @@ sub GUEST_Notify($$) {
|
|||||||
if ( !$dev->{CHANGED} );
|
if ( !$dev->{CHANGED} );
|
||||||
|
|
||||||
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
||||||
|
|
||||||
# state changed
|
|
||||||
if ( $change =~ /OFF|([0-9]{2}:[0-9]{2})/ ) {
|
|
||||||
Log3 $hash, 4,
|
|
||||||
"GUEST "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": notify about change to $change";
|
|
||||||
|
|
||||||
RESIDENTStk_wakeupSet( $devName, $change );
|
RESIDENTStk_wakeupSet( $devName, $change );
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Log3 $hash, 5,
|
return;
|
||||||
"GUEST "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": received unhandled notify about change $change";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# stuff for every registered wakeupdev
|
# process sub-child notifies: *_wakeupDevice
|
||||||
foreach my $wakeupDev (@registeredWakeupdevs) {
|
foreach my $wakeupDev (@registeredWakeupdevs) {
|
||||||
|
|
||||||
# if this is a notification of a registered sub dummy device
|
# if this is a notification of a registered sub dummy device
|
||||||
@ -261,25 +246,11 @@ sub GUEST_Notify($$) {
|
|||||||
if ( !$dev->{CHANGED} );
|
if ( !$dev->{CHANGED} );
|
||||||
|
|
||||||
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
||||||
|
RESIDENTStk_wakeupSet( $wakeupDev, $change )
|
||||||
|
if ( $change ne "off" );
|
||||||
|
}
|
||||||
|
|
||||||
# state changed to on
|
last;
|
||||||
if ( $change eq "auto" ) {
|
|
||||||
Log3 $hash, 4,
|
|
||||||
"GUEST "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": notify about change to $change";
|
|
||||||
|
|
||||||
RESIDENTStk_wakeupSet($wakeupDev);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log3 $hash, 5,
|
|
||||||
"GUEST "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": received unhandled notify about change $change";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -468,14 +439,14 @@ sub GUEST_Set($@) {
|
|||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurSleep",
|
"lastDurSleep",
|
||||||
GUEST_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastSleep}{VAL}
|
$datetime, $hash->{READINGS}{lastSleep}{VAL}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurSleep_cr",
|
"lastDurSleep_cr",
|
||||||
GUEST_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastSleep}{VAL}, "min"
|
$datetime, $hash->{READINGS}{lastSleep}{VAL}, "min"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -545,14 +516,14 @@ sub GUEST_Set($@) {
|
|||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurAbsence",
|
"lastDurAbsence",
|
||||||
GUEST_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastDeparture}{VAL}
|
$datetime, $hash->{READINGS}{lastDeparture}{VAL}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurAbsence_cr",
|
"lastDurAbsence_cr",
|
||||||
GUEST_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime,
|
$datetime,
|
||||||
$hash->{READINGS}{lastDeparture}{VAL}, "min"
|
$hash->{READINGS}{lastDeparture}{VAL}, "min"
|
||||||
)
|
)
|
||||||
@ -569,14 +540,14 @@ sub GUEST_Set($@) {
|
|||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurPresence",
|
"lastDurPresence",
|
||||||
GUEST_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastArrival}{VAL}
|
$datetime, $hash->{READINGS}{lastArrival}{VAL}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurPresence_cr",
|
"lastDurPresence_cr",
|
||||||
GUEST_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastArrival}{VAL},
|
$datetime, $hash->{READINGS}{lastArrival}{VAL},
|
||||||
"min"
|
"min"
|
||||||
)
|
)
|
||||||
@ -641,7 +612,7 @@ sub GUEST_Set($@) {
|
|||||||
GUEST_AutoGone($hash);
|
GUEST_AutoGone($hash);
|
||||||
}
|
}
|
||||||
elsif ( $state eq "absent" ) {
|
elsif ( $state eq "absent" ) {
|
||||||
GUEST_RemoveInternalTimer( "AutoGone", $hash );
|
RESIDENTStk_RemoveInternalTimer( "AutoGone", $hash );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -779,6 +750,8 @@ sub GUEST_Set($@) {
|
|||||||
$wakeuptimerName = $name . "_wakeuptimer" . $i;
|
$wakeuptimerName = $name . "_wakeuptimer" . $i;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
my $sortby = AttrVal( $name, "sortby", -1 );
|
||||||
|
$sortby++;
|
||||||
|
|
||||||
# create new dummy device
|
# create new dummy device
|
||||||
fhem "define $wakeuptimerName dummy";
|
fhem "define $wakeuptimerName dummy";
|
||||||
@ -786,36 +759,41 @@ sub GUEST_Set($@) {
|
|||||||
fhem
|
fhem
|
||||||
"attr $wakeuptimerName comment Auto-created by GUEST module for use with RESIDENTS Toolkit";
|
"attr $wakeuptimerName comment Auto-created by GUEST module for use with RESIDENTS Toolkit";
|
||||||
fhem
|
fhem
|
||||||
"attr $wakeuptimerName devStateIcon OFF:general_aus\@red .*:general_an\@green:OFF";
|
"attr $wakeuptimerName devStateIcon OFF:general_aus\@red:reset running:general_an\@blue:stop .*:general_an\@green:nextRun%20OFF";
|
||||||
fhem "attr $wakeuptimerName group " . $attr{$name}{group}
|
fhem "attr $wakeuptimerName group " . $attr{$name}{group}
|
||||||
if ( defined( $attr{$name}{group} ) );
|
if ( defined( $attr{$name}{group} ) );
|
||||||
fhem "attr $wakeuptimerName icon time_timer";
|
fhem "attr $wakeuptimerName icon time_timer";
|
||||||
fhem "attr $wakeuptimerName room " . $attr{$name}{room}
|
fhem "attr $wakeuptimerName room " . $attr{$name}{room}
|
||||||
if ( defined( $attr{$name}{room} ) );
|
if ( defined( $attr{$name}{room} ) );
|
||||||
fhem
|
fhem
|
||||||
"attr $wakeuptimerName setList state: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";
|
"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";
|
||||||
fhem "attr $wakeuptimerName userattr wakeupUserdevice";
|
fhem "attr $wakeuptimerName userattr wakeupUserdevice";
|
||||||
|
fhem "attr $wakeuptimerName sortby " . $sortby
|
||||||
|
if ($sortby);
|
||||||
fhem "attr $wakeuptimerName wakeupUserdevice $name";
|
fhem "attr $wakeuptimerName wakeupUserdevice $name";
|
||||||
fhem "attr $wakeuptimerName webCmd state";
|
fhem "attr $wakeuptimerName webCmd nextRun";
|
||||||
|
|
||||||
# register slave device
|
# register slave device
|
||||||
if ( defined( $attr{$name}{rg_wakeupDevice} ) ) {
|
my $wakeupDevice = AttrVal( $name, "rg_wakeupDevice", 0 );
|
||||||
fhem "attr $name rg_wakeupDevice "
|
if ( !$wakeupDevice ) {
|
||||||
. $attr{$name}{rg_wakeupDevice}
|
|
||||||
. ",$wakeuptimerName";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fhem "attr $name rg_wakeupDevice $wakeuptimerName";
|
fhem "attr $name rg_wakeupDevice $wakeuptimerName";
|
||||||
}
|
}
|
||||||
|
elsif ( $wakeupDevice !~ /(.*,?)($wakeuptimerName)(.*,?)/ )
|
||||||
|
{
|
||||||
|
fhem "attr $name rg_wakeupDevice "
|
||||||
|
. $wakeupDevice
|
||||||
|
. ",$wakeuptimerName";
|
||||||
|
}
|
||||||
|
|
||||||
# trigger first update
|
# trigger first update
|
||||||
fhem "set $wakeuptimerName OFF";
|
fhem "set $wakeuptimerName nextRun OFF";
|
||||||
|
|
||||||
$created = 1;
|
$created = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
"Dummy $wakeuptimerName and other pending devices created and pre-configured. You may edit Macro_$wakeuptimerName to define your wake-up actions and at_$wakeuptimerName for optional at-device adjustments.";
|
"Dummy $wakeuptimerName and other pending devices created and pre-configured.\nYou may edit Macro_$wakeuptimerName to define your wake-up actions\nand at_$wakeuptimerName for optional at-device adjustments.";
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return "Invalid 2nd argument, choose one of wakeuptimer ";
|
return "Invalid 2nd argument, choose one of wakeuptimer ";
|
||||||
@ -842,7 +820,7 @@ sub GUEST_AutoGone($;$) {
|
|||||||
my $hash = ( $mHash->{HASH} ) ? $mHash->{HASH} : $mHash;
|
my $hash = ( $mHash->{HASH} ) ? $mHash->{HASH} : $mHash;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
GUEST_RemoveInternalTimer( "AutoGone", $hash );
|
RESIDENTStk_RemoveInternalTimer( "AutoGone", $hash );
|
||||||
|
|
||||||
if ( defined( $hash->{READINGS}{state}{VAL} )
|
if ( defined( $hash->{READINGS}{state}{VAL} )
|
||||||
&& $hash->{READINGS}{state}{VAL} eq "absent" )
|
&& $hash->{READINGS}{state}{VAL} eq "absent" )
|
||||||
@ -871,8 +849,8 @@ sub GUEST_AutoGone($;$) {
|
|||||||
else {
|
else {
|
||||||
my $runtime = $timestamp + $timeout * 3600;
|
my $runtime = $timestamp + $timeout * 3600;
|
||||||
Log3 $name, 4, "GUEST $name: AutoGone timer scheduled: $runtime";
|
Log3 $name, 4, "GUEST $name: AutoGone timer scheduled: $runtime";
|
||||||
GUEST_InternalTimer( "AutoGone", $runtime, "GUEST_AutoGone", $hash,
|
RESIDENTStk_InternalTimer( "AutoGone", $runtime, "GUEST_AutoGone",
|
||||||
1 );
|
$hash, 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -895,7 +873,7 @@ sub GUEST_DurationTimer($;$) {
|
|||||||
my $durAbsence = "0";
|
my $durAbsence = "0";
|
||||||
my $durSleep = "0";
|
my $durSleep = "0";
|
||||||
|
|
||||||
GUEST_RemoveInternalTimer( "DurationTimer", $hash );
|
RESIDENTStk_RemoveInternalTimer( "DurationTimer", $hash );
|
||||||
|
|
||||||
if ( !defined( $attr{$name}{rg_noDuration} )
|
if ( !defined( $attr{$name}{rg_noDuration} )
|
||||||
|| $attr{$name}{rg_noDuration} == 0 )
|
|| $attr{$name}{rg_noDuration} == 0 )
|
||||||
@ -910,7 +888,7 @@ sub GUEST_DurationTimer($;$) {
|
|||||||
{
|
{
|
||||||
$durPresence =
|
$durPresence =
|
||||||
$timestampNow -
|
$timestampNow -
|
||||||
GUEST_Datetime2Timestamp(
|
RESIDENTStk_Datetime2Timestamp(
|
||||||
$hash->{READINGS}{lastArrival}{VAL} );
|
$hash->{READINGS}{lastArrival}{VAL} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -926,7 +904,7 @@ sub GUEST_DurationTimer($;$) {
|
|||||||
{
|
{
|
||||||
$durAbsence =
|
$durAbsence =
|
||||||
$timestampNow -
|
$timestampNow -
|
||||||
GUEST_Datetime2Timestamp(
|
RESIDENTStk_Datetime2Timestamp(
|
||||||
$hash->{READINGS}{lastDeparture}{VAL} );
|
$hash->{READINGS}{lastDeparture}{VAL} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -940,20 +918,23 @@ sub GUEST_DurationTimer($;$) {
|
|||||||
{
|
{
|
||||||
$durSleep =
|
$durSleep =
|
||||||
$timestampNow -
|
$timestampNow -
|
||||||
GUEST_Datetime2Timestamp( $hash->{READINGS}{lastSleep}{VAL} );
|
RESIDENTStk_Datetime2Timestamp(
|
||||||
|
$hash->{READINGS}{lastSleep}{VAL} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $durPresence_hr =
|
my $durPresence_hr =
|
||||||
( $durPresence > 0 ) ? GUEST_sec2time($durPresence) : "00:00:00";
|
( $durPresence > 0 )
|
||||||
|
? RESIDENTStk_sec2time($durPresence)
|
||||||
|
: "00:00:00";
|
||||||
my $durPresence_cr =
|
my $durPresence_cr =
|
||||||
( $durPresence > 60 ) ? int( $durPresence / 60 + 0.5 ) : 0;
|
( $durPresence > 60 ) ? int( $durPresence / 60 + 0.5 ) : 0;
|
||||||
my $durAbsence_hr =
|
my $durAbsence_hr =
|
||||||
( $durAbsence > 0 ) ? GUEST_sec2time($durAbsence) : "00:00:00";
|
( $durAbsence > 0 ) ? RESIDENTStk_sec2time($durAbsence) : "00:00:00";
|
||||||
my $durAbsence_cr =
|
my $durAbsence_cr =
|
||||||
( $durAbsence > 60 ) ? int( $durAbsence / 60 + 0.5 ) : 0;
|
( $durAbsence > 60 ) ? int( $durAbsence / 60 + 0.5 ) : 0;
|
||||||
my $durSleep_hr =
|
my $durSleep_hr =
|
||||||
( $durSleep > 0 ) ? GUEST_sec2time($durSleep) : "00:00:00";
|
( $durSleep > 0 ) ? RESIDENTStk_sec2time($durSleep) : "00:00:00";
|
||||||
my $durSleep_cr = ( $durSleep > 60 ) ? int( $durSleep / 60 + 0.5 ) : 0;
|
my $durSleep_cr = ( $durSleep > 60 ) ? int( $durSleep / 60 + 0.5 ) : 0;
|
||||||
|
|
||||||
readingsBeginUpdate($hash) if ( !$silent );
|
readingsBeginUpdate($hash) if ( !$silent );
|
||||||
@ -978,115 +959,13 @@ sub GUEST_DurationTimer($;$) {
|
|||||||
readingsEndUpdate( $hash, 1 ) if ( !$silent );
|
readingsEndUpdate( $hash, 1 ) if ( !$silent );
|
||||||
}
|
}
|
||||||
|
|
||||||
GUEST_InternalTimer( "DurationTimer", $timestampNow + 60,
|
RESIDENTStk_InternalTimer( "DurationTimer", $timestampNow + 60,
|
||||||
"GUEST_DurationTimer", $hash, 1 )
|
"GUEST_DurationTimer", $hash, 1 )
|
||||||
if ( $state ne "none" );
|
if ( $state ne "none" );
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
###################################
|
|
||||||
sub GUEST_TimeDiff ($$;$) {
|
|
||||||
my ( $datetimeNow, $datetimeOld, $format ) = @_;
|
|
||||||
|
|
||||||
my $timestampNow = GUEST_Datetime2Timestamp($datetimeNow);
|
|
||||||
my $timestampOld = GUEST_Datetime2Timestamp($datetimeOld);
|
|
||||||
my $timeDiff = $timestampNow - $timestampOld;
|
|
||||||
|
|
||||||
# return seconds
|
|
||||||
return int( $timeDiff + 0.5 ) if ( defined($format) && $format eq "sec" );
|
|
||||||
|
|
||||||
# return minutes
|
|
||||||
return int( $timeDiff / 60 + 0.5 )
|
|
||||||
if ( defined($format) && $format eq "min" );
|
|
||||||
|
|
||||||
# return human readable format
|
|
||||||
my $hours = ( $timeDiff < 3600 ? 0 : int( $timeDiff / 3600 ) );
|
|
||||||
$timeDiff -= ( $hours == 0 ? 0 : ( $hours * 3600 ) );
|
|
||||||
my $minutes = ( $timeDiff < 60 ? 0 : int( $timeDiff / 60 ) );
|
|
||||||
my $seconds = $timeDiff % 60;
|
|
||||||
|
|
||||||
$hours = "0" . $hours if ( $hours < 10 );
|
|
||||||
$minutes = "0" . $minutes if ( $minutes < 10 );
|
|
||||||
$seconds = "0" . $seconds if ( $seconds < 10 );
|
|
||||||
|
|
||||||
return "$hours:$minutes:$seconds";
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################
|
|
||||||
sub GUEST_Datetime2Timestamp($) {
|
|
||||||
my ($datetime) = @_;
|
|
||||||
|
|
||||||
my ( $date, $time, $y, $m, $d, $hour, $min, $sec, $timestamp );
|
|
||||||
|
|
||||||
( $date, $time ) = split( ' ', $datetime );
|
|
||||||
( $y, $m, $d ) = split( '-', $date );
|
|
||||||
( $hour, $min, $sec ) = split( ':', $time );
|
|
||||||
$m -= 01;
|
|
||||||
$timestamp = timelocal( $sec, $min, $hour, $d, $m, $y );
|
|
||||||
|
|
||||||
return $timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################
|
|
||||||
sub GUEST_sec2time($) {
|
|
||||||
my ($sec) = @_;
|
|
||||||
|
|
||||||
# return human readable format
|
|
||||||
my $hours = ( $sec < 3600 ? 0 : int( $sec / 3600 ) );
|
|
||||||
$sec -= ( $hours == 0 ? 0 : ( $hours * 3600 ) );
|
|
||||||
my $minutes = ( $sec < 60 ? 0 : int( $sec / 60 ) );
|
|
||||||
my $seconds = $sec % 60;
|
|
||||||
|
|
||||||
$hours = "0" . $hours if ( $hours < 10 );
|
|
||||||
$minutes = "0" . $minutes if ( $minutes < 10 );
|
|
||||||
$seconds = "0" . $seconds if ( $seconds < 10 );
|
|
||||||
|
|
||||||
return "$hours:$minutes:$seconds";
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################
|
|
||||||
sub GUEST_InternalTimer($$$$$) {
|
|
||||||
my ( $modifier, $tim, $callback, $hash, $waitIfInitNotDone ) = @_;
|
|
||||||
|
|
||||||
my $mHash;
|
|
||||||
if ( $modifier eq "" ) {
|
|
||||||
$mHash = $hash;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
my $timerName = $hash->{NAME} . "_" . $modifier;
|
|
||||||
if ( exists( $hash->{TIMER}{$timerName} ) ) {
|
|
||||||
$mHash = $hash->{TIMER}{$timerName};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$mHash = {
|
|
||||||
HASH => $hash,
|
|
||||||
NAME => $hash->{NAME} . "_" . $modifier,
|
|
||||||
MODIFIER => $modifier
|
|
||||||
};
|
|
||||||
$hash->{TIMER}{$timerName} = $mHash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InternalTimer( $tim, $callback, $mHash, $waitIfInitNotDone );
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################
|
|
||||||
sub GUEST_RemoveInternalTimer($$) {
|
|
||||||
my ( $modifier, $hash ) = @_;
|
|
||||||
|
|
||||||
my $timerName = $hash->{NAME} . "_" . $modifier;
|
|
||||||
if ( $modifier eq "" ) {
|
|
||||||
RemoveInternalTimer($hash);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
my $mHash = $hash->{TIMER}{$timerName};
|
|
||||||
if ( defined($mHash) ) {
|
|
||||||
delete $hash->{TIMER}{$timerName};
|
|
||||||
RemoveInternalTimer($mHash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
sub GUEST_StartInternalTimers($$) {
|
sub GUEST_StartInternalTimers($$) {
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
@ -1360,6 +1239,9 @@ sub GUEST_StartInternalTimers($$) {
|
|||||||
<li>
|
<li>
|
||||||
<b>state</b> - reflects the current state
|
<b>state</b> - reflects the current state
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>wakeup</b> - becomes '1' while a wake-up program of this resident is being executed
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>wayhome</b> - depending on current location, it can become '1' if individual is on his/her way back home
|
<b>wayhome</b> - depending on current location, it can become '1' if individual is on his/her way back home
|
||||||
</li>
|
</li>
|
||||||
@ -1636,6 +1518,9 @@ sub GUEST_StartInternalTimers($$) {
|
|||||||
<li>
|
<li>
|
||||||
<b>state</b> - gibt den aktuellen Status wieder
|
<b>state</b> - gibt den aktuellen Status wieder
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>wakeup</b> - hat den Wert '1' während ein Weckprogramm dieses Bewohners ausgeführt wird
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>wayhome</b> - abhängig vom aktullen Aufenthaltsort, kann der Wert '1' werden, wenn die Person auf dem weg zurück nach Hause ist
|
<b>wayhome</b> - abhängig vom aktullen Aufenthaltsort, kann der Wert '1' werden, wenn die Person auf dem weg zurück nach Hause ist
|
||||||
</li>
|
</li>
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Version: 1.2.0
|
# Version: 1.2.1
|
||||||
#
|
#
|
||||||
# Major Version History:
|
# Major Version History:
|
||||||
# - 1.2.0 - 2015-03-11
|
# - 1.2.0 - 2015-03-11
|
||||||
@ -143,7 +143,7 @@ sub ROOMMATE_Define($$) {
|
|||||||
|
|
||||||
$attr{$name}{alias} = "Status";
|
$attr{$name}{alias} = "Status";
|
||||||
$attr{$name}{devStateIcon} =
|
$attr{$name}{devStateIcon} =
|
||||||
".*home:user_available:absent .*absent:user_away:home .*gone:user_ext_away:home .*gotosleep:scene_toilet:asleep .*asleep:scene_sleeping:awoken .*awoken:scene_sleeping_alternat:home .*:user_unknown";
|
".*home:user_available:absent .*absent:user_away:home .*gone:user_ext_away:home .*gotosleep:scene_toilet:asleep .*asleep:scene_sleeping:awoken .*awoken:scene_sleeping_alternat:home .*:user_unknown:home";
|
||||||
$attr{$name}{icon} = "people_sensor";
|
$attr{$name}{icon} = "people_sensor";
|
||||||
$attr{$name}{rr_realname} = "alias";
|
$attr{$name}{rr_realname} = "alias";
|
||||||
$attr{$name}{sortby} = "1";
|
$attr{$name}{sortby} = "1";
|
||||||
@ -184,8 +184,8 @@ sub ROOMMATE_Define($$) {
|
|||||||
sub ROOMMATE_Undefine($$) {
|
sub ROOMMATE_Undefine($$) {
|
||||||
my ( $hash, $name ) = @_;
|
my ( $hash, $name ) = @_;
|
||||||
|
|
||||||
ROOMMATE_RemoveInternalTimer( "AutoGone", $hash );
|
RESIDENTStk_RemoveInternalTimer( "AutoGone", $hash );
|
||||||
ROOMMATE_RemoveInternalTimer( "DurationTimer", $hash );
|
RESIDENTStk_RemoveInternalTimer( "DurationTimer", $hash );
|
||||||
|
|
||||||
if ( defined( $hash->{RESIDENTGROUPS} ) ) {
|
if ( defined( $hash->{RESIDENTGROUPS} ) ) {
|
||||||
my @registeredResidentgroups =
|
my @registeredResidentgroups =
|
||||||
@ -230,28 +230,13 @@ sub ROOMMATE_Notify($$) {
|
|||||||
if ( !$dev->{CHANGED} );
|
if ( !$dev->{CHANGED} );
|
||||||
|
|
||||||
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
||||||
|
|
||||||
# state changed
|
|
||||||
if ( $change =~ /OFF|([0-9]{2}:[0-9]{2})/ ) {
|
|
||||||
Log3 $hash, 4,
|
|
||||||
"ROOMMATE "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": notify about change to $change";
|
|
||||||
|
|
||||||
RESIDENTStk_wakeupSet( $devName, $change );
|
RESIDENTStk_wakeupSet( $devName, $change );
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Log3 $hash, 5,
|
return;
|
||||||
"ROOMMATE "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": received unhandled notify about change $change";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# stuff for every registered wakeupdev
|
# process sub-child notifies: *_wakeupDevice
|
||||||
foreach my $wakeupDev (@registeredWakeupdevs) {
|
foreach my $wakeupDev (@registeredWakeupdevs) {
|
||||||
|
|
||||||
# if this is a notification of a registered sub dummy device
|
# if this is a notification of a registered sub dummy device
|
||||||
@ -266,25 +251,11 @@ sub ROOMMATE_Notify($$) {
|
|||||||
if ( !$dev->{CHANGED} );
|
if ( !$dev->{CHANGED} );
|
||||||
|
|
||||||
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
||||||
|
RESIDENTStk_wakeupSet( $wakeupDev, $change )
|
||||||
|
if ( $change ne "off" );
|
||||||
|
}
|
||||||
|
|
||||||
# state changed to on
|
last;
|
||||||
if ( $change eq "auto" ) {
|
|
||||||
Log3 $hash, 4,
|
|
||||||
"ROOMMATE "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": notify about change to $change";
|
|
||||||
|
|
||||||
RESIDENTStk_wakeupSet($wakeupDev);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log3 $hash, 5,
|
|
||||||
"ROOMMATE "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": received unhandled notify about change $change";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -470,14 +441,14 @@ sub ROOMMATE_Set($@) {
|
|||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurSleep",
|
"lastDurSleep",
|
||||||
ROOMMATE_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastSleep}{VAL}
|
$datetime, $hash->{READINGS}{lastSleep}{VAL}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurSleep_cr",
|
"lastDurSleep_cr",
|
||||||
ROOMMATE_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastSleep}{VAL}, "min"
|
$datetime, $hash->{READINGS}{lastSleep}{VAL}, "min"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -547,14 +518,14 @@ sub ROOMMATE_Set($@) {
|
|||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurAbsence",
|
"lastDurAbsence",
|
||||||
ROOMMATE_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastDeparture}{VAL}
|
$datetime, $hash->{READINGS}{lastDeparture}{VAL}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurAbsence_cr",
|
"lastDurAbsence_cr",
|
||||||
ROOMMATE_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime,
|
$datetime,
|
||||||
$hash->{READINGS}{lastDeparture}{VAL}, "min"
|
$hash->{READINGS}{lastDeparture}{VAL}, "min"
|
||||||
)
|
)
|
||||||
@ -571,14 +542,14 @@ sub ROOMMATE_Set($@) {
|
|||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurPresence",
|
"lastDurPresence",
|
||||||
ROOMMATE_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastArrival}{VAL}
|
$datetime, $hash->{READINGS}{lastArrival}{VAL}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
readingsBulkUpdate(
|
readingsBulkUpdate(
|
||||||
$hash,
|
$hash,
|
||||||
"lastDurPresence_cr",
|
"lastDurPresence_cr",
|
||||||
ROOMMATE_TimeDiff(
|
RESIDENTStk_TimeDiff(
|
||||||
$datetime, $hash->{READINGS}{lastArrival}{VAL},
|
$datetime, $hash->{READINGS}{lastArrival}{VAL},
|
||||||
"min"
|
"min"
|
||||||
)
|
)
|
||||||
@ -621,7 +592,7 @@ sub ROOMMATE_Set($@) {
|
|||||||
ROOMMATE_AutoGone($hash);
|
ROOMMATE_AutoGone($hash);
|
||||||
}
|
}
|
||||||
elsif ( $state eq "absent" ) {
|
elsif ( $state eq "absent" ) {
|
||||||
ROOMMATE_RemoveInternalTimer( "AutoGone", $hash );
|
RESIDENTStk_RemoveInternalTimer( "AutoGone", $hash );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -761,6 +732,8 @@ sub ROOMMATE_Set($@) {
|
|||||||
$wakeuptimerName = $name . "_wakeuptimer" . $i;
|
$wakeuptimerName = $name . "_wakeuptimer" . $i;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
my $sortby = AttrVal( $name, "sortby", -1 );
|
||||||
|
$sortby++;
|
||||||
|
|
||||||
# create new dummy device
|
# create new dummy device
|
||||||
fhem "define $wakeuptimerName dummy";
|
fhem "define $wakeuptimerName dummy";
|
||||||
@ -768,36 +741,41 @@ sub ROOMMATE_Set($@) {
|
|||||||
fhem
|
fhem
|
||||||
"attr $wakeuptimerName comment Auto-created by ROOMMATE module for use with RESIDENTS Toolkit";
|
"attr $wakeuptimerName comment Auto-created by ROOMMATE module for use with RESIDENTS Toolkit";
|
||||||
fhem
|
fhem
|
||||||
"attr $wakeuptimerName devStateIcon OFF:general_aus\@red .*:general_an\@green:OFF";
|
"attr $wakeuptimerName devStateIcon OFF:general_aus\@red:reset running:general_an\@blue:stop .*:general_an\@green:nextRun%20OFF";
|
||||||
fhem "attr $wakeuptimerName group " . $attr{$name}{group}
|
fhem "attr $wakeuptimerName group " . $attr{$name}{group}
|
||||||
if ( defined( $attr{$name}{group} ) );
|
if ( defined( $attr{$name}{group} ) );
|
||||||
fhem "attr $wakeuptimerName icon time_timer";
|
fhem "attr $wakeuptimerName icon time_timer";
|
||||||
fhem "attr $wakeuptimerName room " . $attr{$name}{room}
|
fhem "attr $wakeuptimerName room " . $attr{$name}{room}
|
||||||
if ( defined( $attr{$name}{room} ) );
|
if ( defined( $attr{$name}{room} ) );
|
||||||
fhem
|
fhem
|
||||||
"attr $wakeuptimerName setList state: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";
|
"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";
|
||||||
fhem "attr $wakeuptimerName userattr wakeupUserdevice";
|
fhem "attr $wakeuptimerName userattr wakeupUserdevice";
|
||||||
|
fhem "attr $wakeuptimerName sortby " . $sortby
|
||||||
|
if ($sortby);
|
||||||
fhem "attr $wakeuptimerName wakeupUserdevice $name";
|
fhem "attr $wakeuptimerName wakeupUserdevice $name";
|
||||||
fhem "attr $wakeuptimerName webCmd state";
|
fhem "attr $wakeuptimerName webCmd nextRun";
|
||||||
|
|
||||||
# register slave device
|
# register slave device
|
||||||
if ( defined( $attr{$name}{rr_wakeupDevice} ) ) {
|
my $wakeupDevice = AttrVal( $name, "rr_wakeupDevice", 0 );
|
||||||
fhem "attr $name rr_wakeupDevice "
|
if ( !$wakeupDevice ) {
|
||||||
. $attr{$name}{rr_wakeupDevice}
|
|
||||||
. ",$wakeuptimerName";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fhem "attr $name rr_wakeupDevice $wakeuptimerName";
|
fhem "attr $name rr_wakeupDevice $wakeuptimerName";
|
||||||
}
|
}
|
||||||
|
elsif ( $wakeupDevice !~ /(.*,?)($wakeuptimerName)(.*,?)/ )
|
||||||
|
{
|
||||||
|
fhem "attr $name rr_wakeupDevice "
|
||||||
|
. $wakeupDevice
|
||||||
|
. ",$wakeuptimerName";
|
||||||
|
}
|
||||||
|
|
||||||
# trigger first update
|
# trigger first update
|
||||||
fhem "set $wakeuptimerName OFF";
|
fhem "set $wakeuptimerName nextRun OFF";
|
||||||
|
|
||||||
$created = 1;
|
$created = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
"Dummy $wakeuptimerName and other pending devices created and pre-configured. You may edit Macro_$wakeuptimerName to define your wake-up actions and at_$wakeuptimerName for optional at-device adjustments.";
|
"Dummy $wakeuptimerName and other pending devices created and pre-configured.\nYou may edit Macro_$wakeuptimerName to define your wake-up actions\nand at_$wakeuptimerName for optional at-device adjustments.";
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return "Invalid 2nd argument, choose one of wakeuptimer ";
|
return "Invalid 2nd argument, choose one of wakeuptimer ";
|
||||||
@ -824,7 +802,7 @@ sub ROOMMATE_AutoGone($;$) {
|
|||||||
my $hash = ( $mHash->{HASH} ) ? $mHash->{HASH} : $mHash;
|
my $hash = ( $mHash->{HASH} ) ? $mHash->{HASH} : $mHash;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
ROOMMATE_RemoveInternalTimer( "AutoGone", $hash );
|
RESIDENTStk_RemoveInternalTimer( "AutoGone", $hash );
|
||||||
|
|
||||||
if ( defined( $hash->{READINGS}{state}{VAL} )
|
if ( defined( $hash->{READINGS}{state}{VAL} )
|
||||||
&& $hash->{READINGS}{state}{VAL} eq "absent" )
|
&& $hash->{READINGS}{state}{VAL} eq "absent" )
|
||||||
@ -853,8 +831,8 @@ sub ROOMMATE_AutoGone($;$) {
|
|||||||
else {
|
else {
|
||||||
my $runtime = $timestamp + $timeout * 3600;
|
my $runtime = $timestamp + $timeout * 3600;
|
||||||
Log3 $name, 4, "ROOMMATE $name: AutoGone timer scheduled: $runtime";
|
Log3 $name, 4, "ROOMMATE $name: AutoGone timer scheduled: $runtime";
|
||||||
ROOMMATE_InternalTimer( "AutoGone", $runtime, "ROOMMATE_AutoGone",
|
RESIDENTStk_InternalTimer( "AutoGone", $runtime,
|
||||||
$hash, 1 );
|
"ROOMMATE_AutoGone", $hash, 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -873,7 +851,7 @@ sub ROOMMATE_DurationTimer($;$) {
|
|||||||
my $durAbsence = "0";
|
my $durAbsence = "0";
|
||||||
my $durSleep = "0";
|
my $durSleep = "0";
|
||||||
|
|
||||||
ROOMMATE_RemoveInternalTimer( "DurationTimer", $hash );
|
RESIDENTStk_RemoveInternalTimer( "DurationTimer", $hash );
|
||||||
|
|
||||||
if ( !defined( $attr{$name}{rr_noDuration} )
|
if ( !defined( $attr{$name}{rr_noDuration} )
|
||||||
|| $attr{$name}{rr_noDuration} == 0 )
|
|| $attr{$name}{rr_noDuration} == 0 )
|
||||||
@ -888,7 +866,7 @@ sub ROOMMATE_DurationTimer($;$) {
|
|||||||
{
|
{
|
||||||
$durPresence =
|
$durPresence =
|
||||||
$timestampNow -
|
$timestampNow -
|
||||||
ROOMMATE_Datetime2Timestamp(
|
RESIDENTStk_Datetime2Timestamp(
|
||||||
$hash->{READINGS}{lastArrival}{VAL} );
|
$hash->{READINGS}{lastArrival}{VAL} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -902,7 +880,7 @@ sub ROOMMATE_DurationTimer($;$) {
|
|||||||
{
|
{
|
||||||
$durAbsence =
|
$durAbsence =
|
||||||
$timestampNow -
|
$timestampNow -
|
||||||
ROOMMATE_Datetime2Timestamp(
|
RESIDENTStk_Datetime2Timestamp(
|
||||||
$hash->{READINGS}{lastDeparture}{VAL} );
|
$hash->{READINGS}{lastDeparture}{VAL} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -916,21 +894,23 @@ sub ROOMMATE_DurationTimer($;$) {
|
|||||||
{
|
{
|
||||||
$durSleep =
|
$durSleep =
|
||||||
$timestampNow -
|
$timestampNow -
|
||||||
ROOMMATE_Datetime2Timestamp(
|
RESIDENTStk_Datetime2Timestamp(
|
||||||
$hash->{READINGS}{lastSleep}{VAL} );
|
$hash->{READINGS}{lastSleep}{VAL} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $durPresence_hr =
|
my $durPresence_hr =
|
||||||
( $durPresence > 0 ) ? ROOMMATE_sec2time($durPresence) : "00:00:00";
|
( $durPresence > 0 )
|
||||||
|
? RESIDENTStk_sec2time($durPresence)
|
||||||
|
: "00:00:00";
|
||||||
my $durPresence_cr =
|
my $durPresence_cr =
|
||||||
( $durPresence > 60 ) ? int( $durPresence / 60 + 0.5 ) : 0;
|
( $durPresence > 60 ) ? int( $durPresence / 60 + 0.5 ) : 0;
|
||||||
my $durAbsence_hr =
|
my $durAbsence_hr =
|
||||||
( $durAbsence > 0 ) ? ROOMMATE_sec2time($durAbsence) : "00:00:00";
|
( $durAbsence > 0 ) ? RESIDENTStk_sec2time($durAbsence) : "00:00:00";
|
||||||
my $durAbsence_cr =
|
my $durAbsence_cr =
|
||||||
( $durAbsence > 60 ) ? int( $durAbsence / 60 + 0.5 ) : 0;
|
( $durAbsence > 60 ) ? int( $durAbsence / 60 + 0.5 ) : 0;
|
||||||
my $durSleep_hr =
|
my $durSleep_hr =
|
||||||
( $durSleep > 0 ) ? ROOMMATE_sec2time($durSleep) : "00:00:00";
|
( $durSleep > 0 ) ? RESIDENTStk_sec2time($durSleep) : "00:00:00";
|
||||||
my $durSleep_cr = ( $durSleep > 60 ) ? int( $durSleep / 60 + 0.5 ) : 0;
|
my $durSleep_cr = ( $durSleep > 60 ) ? int( $durSleep / 60 + 0.5 ) : 0;
|
||||||
|
|
||||||
readingsBeginUpdate($hash) if ( !$silent );
|
readingsBeginUpdate($hash) if ( !$silent );
|
||||||
@ -955,114 +935,12 @@ sub ROOMMATE_DurationTimer($;$) {
|
|||||||
readingsEndUpdate( $hash, 1 ) if ( !$silent );
|
readingsEndUpdate( $hash, 1 ) if ( !$silent );
|
||||||
}
|
}
|
||||||
|
|
||||||
ROOMMATE_InternalTimer( "DurationTimer", $timestampNow + 60,
|
RESIDENTStk_InternalTimer( "DurationTimer", $timestampNow + 60,
|
||||||
"ROOMMATE_DurationTimer", $hash, 1 );
|
"ROOMMATE_DurationTimer", $hash, 1 );
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
###################################
|
|
||||||
sub ROOMMATE_TimeDiff($$;$) {
|
|
||||||
my ( $datetimeNow, $datetimeOld, $format ) = @_;
|
|
||||||
|
|
||||||
my $timestampNow = ROOMMATE_Datetime2Timestamp($datetimeNow);
|
|
||||||
my $timestampOld = ROOMMATE_Datetime2Timestamp($datetimeOld);
|
|
||||||
my $timeDiff = $timestampNow - $timestampOld;
|
|
||||||
|
|
||||||
# return seconds
|
|
||||||
return int( $timeDiff + 0.5 ) if ( defined($format) && $format eq "sec" );
|
|
||||||
|
|
||||||
# return minutes
|
|
||||||
return int( $timeDiff / 60 + 0.5 )
|
|
||||||
if ( defined($format) && $format eq "min" );
|
|
||||||
|
|
||||||
# return human readable format
|
|
||||||
my $hours = ( $timeDiff < 3600 ? 0 : int( $timeDiff / 3600 ) );
|
|
||||||
$timeDiff -= ( $hours == 0 ? 0 : ( $hours * 3600 ) );
|
|
||||||
my $minutes = ( $timeDiff < 60 ? 0 : int( $timeDiff / 60 ) );
|
|
||||||
my $seconds = $timeDiff % 60;
|
|
||||||
|
|
||||||
$hours = "0" . $hours if ( $hours < 10 );
|
|
||||||
$minutes = "0" . $minutes if ( $minutes < 10 );
|
|
||||||
$seconds = "0" . $seconds if ( $seconds < 10 );
|
|
||||||
|
|
||||||
return "$hours:$minutes:$seconds";
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################
|
|
||||||
sub ROOMMATE_Datetime2Timestamp($) {
|
|
||||||
my ($datetime) = @_;
|
|
||||||
|
|
||||||
my ( $date, $time, $y, $m, $d, $hour, $min, $sec, $timestamp );
|
|
||||||
|
|
||||||
( $date, $time ) = split( ' ', $datetime );
|
|
||||||
( $y, $m, $d ) = split( '-', $date );
|
|
||||||
( $hour, $min, $sec ) = split( ':', $time );
|
|
||||||
$m -= 01;
|
|
||||||
$timestamp = timelocal( $sec, $min, $hour, $d, $m, $y );
|
|
||||||
|
|
||||||
return $timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################
|
|
||||||
sub ROOMMATE_sec2time($) {
|
|
||||||
my ($sec) = @_;
|
|
||||||
|
|
||||||
# return human readable format
|
|
||||||
my $hours = ( $sec < 3600 ? 0 : int( $sec / 3600 ) );
|
|
||||||
$sec -= ( $hours == 0 ? 0 : ( $hours * 3600 ) );
|
|
||||||
my $minutes = ( $sec < 60 ? 0 : int( $sec / 60 ) );
|
|
||||||
my $seconds = $sec % 60;
|
|
||||||
|
|
||||||
$hours = "0" . $hours if ( $hours < 10 );
|
|
||||||
$minutes = "0" . $minutes if ( $minutes < 10 );
|
|
||||||
$seconds = "0" . $seconds if ( $seconds < 10 );
|
|
||||||
|
|
||||||
return "$hours:$minutes:$seconds";
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################
|
|
||||||
sub ROOMMATE_InternalTimer($$$$$) {
|
|
||||||
my ( $modifier, $tim, $callback, $hash, $waitIfInitNotDone ) = @_;
|
|
||||||
|
|
||||||
my $mHash;
|
|
||||||
if ( $modifier eq "" ) {
|
|
||||||
$mHash = $hash;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
my $timerName = $hash->{NAME} . "_" . $modifier;
|
|
||||||
if ( exists( $hash->{TIMER}{$timerName} ) ) {
|
|
||||||
$mHash = $hash->{TIMER}{$timerName};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$mHash = {
|
|
||||||
HASH => $hash,
|
|
||||||
NAME => $hash->{NAME} . "_" . $modifier,
|
|
||||||
MODIFIER => $modifier
|
|
||||||
};
|
|
||||||
$hash->{TIMER}{$timerName} = $mHash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InternalTimer( $tim, $callback, $mHash, $waitIfInitNotDone );
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################
|
|
||||||
sub ROOMMATE_RemoveInternalTimer($$) {
|
|
||||||
my ( $modifier, $hash ) = @_;
|
|
||||||
|
|
||||||
my $timerName = $hash->{NAME} . "_" . $modifier;
|
|
||||||
if ( $modifier eq "" ) {
|
|
||||||
RemoveInternalTimer($hash);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
my $mHash = $hash->{TIMER}{$timerName};
|
|
||||||
if ( defined($mHash) ) {
|
|
||||||
delete $hash->{TIMER}{$timerName};
|
|
||||||
RemoveInternalTimer($mHash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
sub ROOMMATE_StartInternalTimers($$) {
|
sub ROOMMATE_StartInternalTimers($$) {
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
@ -1342,6 +1220,9 @@ sub ROOMMATE_StartInternalTimers($$) {
|
|||||||
<li>
|
<li>
|
||||||
<b>state</b> - reflects the current state
|
<b>state</b> - reflects the current state
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>wakeup</b> - becomes '1' while a wake-up program of this resident is being executed
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>wayhome</b> - depending on current location, it can become '1' if individual is on his/her way back home
|
<b>wayhome</b> - depending on current location, it can become '1' if individual is on his/her way back home
|
||||||
</li>
|
</li>
|
||||||
@ -1618,6 +1499,9 @@ sub ROOMMATE_StartInternalTimers($$) {
|
|||||||
<li>
|
<li>
|
||||||
<b>state</b> - gibt den aktuellen Status wieder
|
<b>state</b> - gibt den aktuellen Status wieder
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>wakeup</b> - hat den Wert '1' während ein Weckprogramm dieses Bewohners ausgeführt wird
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>wayhome</b> - abhängig vom aktullen Aufenthaltsort, kann der Wert '1' werden, wenn die Person auf dem weg zurück nach Hause ist
|
<b>wayhome</b> - abhängig vom aktullen Aufenthaltsort, kann der Wert '1' werden, wenn die Person auf dem weg zurück nach Hause ist
|
||||||
</li>
|
</li>
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Version: 1.0.0
|
# Version: 1.0.1
|
||||||
#
|
#
|
||||||
# Version History:
|
# Version History:
|
||||||
# - 1.0.0 - 2015-03-11
|
# - 1.0.0 - 2015-03-11
|
||||||
@ -32,58 +32,158 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
|
# PRE-DEFINITION: wakeuptimer
|
||||||
|
#------------------------------------
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
# Enslave DUMMY device to be used for alarm clock
|
# Enslave DUMMY device to be used for alarm clock
|
||||||
#
|
#
|
||||||
sub RESIDENTStk_wakeupSet($;$) {
|
sub RESIDENTStk_wakeupSet($$) {
|
||||||
my ( $NAME, $VALUE ) = @_;
|
my ( $NAME, $notifyValue ) = @_;
|
||||||
my $userattr = AttrVal( $NAME, "userattr", 0 );
|
my $VALUE;
|
||||||
my $autosave = AttrVal( $NAME, "wakeupAutosave", 0 );
|
|
||||||
my $wakeupDefaultTime = AttrVal( $NAME, "wakeupDefaultTime", 0 );
|
# filter non-registered notifies
|
||||||
|
my @notify = split / /, $notifyValue;
|
||||||
|
if ( lc( $notify[0] ) !~ /off|nextrun|stop|reset|auto|([0-9]{2}:[0-9]{2})/ )
|
||||||
|
{
|
||||||
|
Log3 $NAME, 5,
|
||||||
|
"RESIDENTStk $NAME: received unspecified notify '"
|
||||||
|
. $notify[0]
|
||||||
|
. "' - nothing to do";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
elsif ( lc( $notify[0] ) eq "nextrun" ) {
|
||||||
|
return if ( !defined( $notify[1] ) );
|
||||||
|
$VALUE = $notify[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$VALUE = $notify[0];
|
||||||
|
}
|
||||||
|
|
||||||
my $wakeupMacro = AttrVal( $NAME, "wakeupMacro", 0 );
|
my $wakeupMacro = AttrVal( $NAME, "wakeupMacro", 0 );
|
||||||
|
my $wakeupDefaultTime = AttrVal( $NAME, "wakeupDefaultTime", 0 );
|
||||||
my $wakeupAtdevice = AttrVal( $NAME, "wakeupAtdevice", 0 );
|
my $wakeupAtdevice = AttrVal( $NAME, "wakeupAtdevice", 0 );
|
||||||
my $wakeupOffset = AttrVal( $NAME, "wakeupOffset", "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 $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 $macroName = "Macro_" . $NAME;
|
||||||
my $atName = "at_" . $NAME;
|
my $atName = "at_" . $NAME;
|
||||||
|
|
||||||
if ( !$VALUE ) {
|
|
||||||
if ($wakeupDefaultTime) {
|
|
||||||
Log3 $NAME, 4,
|
|
||||||
"RESIDENTStk $NAME: Resetting based on wakeupDefaultTime";
|
|
||||||
fhem
|
|
||||||
"set $NAME:FILTER=state!=$wakeupDefaultTime $wakeupDefaultTime";
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
# check for required userattr attribute
|
# check for required userattr attribute
|
||||||
my $userattributes =
|
my $userattributes =
|
||||||
"wakeupOffset:slider,0,1,120 wakeupDefaultTime:time wakeupMacro wakeupUserdevice wakeupAtdevice wakeupResetSwitcher wakeupResetdays:multiple-strict,0,1,2,3,4,5,6 wakeupDays:multiple-strict,0,1,2,3,4,5,6 wakeupAutosave:1,0";
|
"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";
|
||||||
if ( !$userattr || $userattr ne $userattributes ) {
|
if ( !$userattr || $userattr ne $userattributes ) {
|
||||||
Log3 $NAME, 3,
|
Log3 $NAME, 4,
|
||||||
"RESIDENTStk $NAME: adjusting dummy device for required attribute userattr";
|
"RESIDENTStk $NAME: adjusting dummy device for required attribute userattr";
|
||||||
fhem "attr $NAME userattr $userattributes";
|
fhem "attr $NAME userattr $userattributes";
|
||||||
}
|
}
|
||||||
|
|
||||||
# check for required userdevice attribute
|
# check for required userdevice attribute
|
||||||
if ( !AttrVal( $NAME, "wakeupUserdevice", 0 ) ) {
|
if ( !$wakeupUserdevice ) {
|
||||||
Log3 $NAME, 3,
|
Log3 $NAME, 3,
|
||||||
"RESIDENTStk $NAME: WARNING - set attribute wakeupUserdevice before running wakeup function";
|
"RESIDENTStk $NAME: WARNING - set attribute wakeupUserdevice before running wakeup function!";
|
||||||
|
}
|
||||||
|
elsif ( !defined( $defs{$wakeupUserdevice} ) ) {
|
||||||
|
Log3 $NAME, 3,
|
||||||
|
"RESIDENTStk $NAME: WARNING - user device $wakeupUserdevice does not exist!";
|
||||||
|
}
|
||||||
|
elsif ($defs{$wakeupUserdevice}{TYPE} ne "RESIDENTS"
|
||||||
|
&& $defs{$wakeupUserdevice}{TYPE} ne "ROOMMATE"
|
||||||
|
&& $defs{$wakeupUserdevice}{TYPE} ne "GUEST" )
|
||||||
|
{
|
||||||
|
Log3 $NAME, 3,
|
||||||
|
"RESIDENTStk $NAME: WARNING - defined user device '$wakeupUserdevice' is not a RESIDENTS, ROOMMATE or GUEST device!";
|
||||||
}
|
}
|
||||||
|
|
||||||
# check for required wakeupMacro attribute
|
# check for required wakeupMacro attribute
|
||||||
if ( !$wakeupMacro ) {
|
if ( !$wakeupMacro ) {
|
||||||
Log3 $NAME, 3,
|
Log3 $NAME, 4,
|
||||||
"RESIDENTStk $NAME: adjusting dummy device for required attribute wakeupMacro";
|
"RESIDENTStk $NAME: adjusting dummy device for required attribute wakeupMacro";
|
||||||
fhem "attr $NAME wakeupMacro $macroName";
|
fhem "attr $NAME wakeupMacro $macroName";
|
||||||
$wakeupMacro = $macroName;
|
$wakeupMacro = $macroName;
|
||||||
}
|
}
|
||||||
|
|
||||||
# check for existing macro notify device
|
|
||||||
if ( !defined( $defs{$wakeupMacro} ) ) {
|
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\
|
||||||
|
#\
|
||||||
|
\
|
||||||
|
#------------------------------------------------------------------------------------\
|
||||||
|
# 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.\
|
||||||
|
#\
|
||||||
|
if (\$EVTPART0 eq \"start\") {\
|
||||||
|
Log3 \$NAME, 3, \"\$NAME: Wake-up program started for \".\$EVTPART1;;\
|
||||||
|
\
|
||||||
|
fhem \"set BR_FloorLamp pct 1 : ct 2000 : transitiontime 0;; set BR_FloorLamp 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\";;\
|
||||||
|
\
|
||||||
|
# Working days only (Mon-Fri except bank holidays): do enforced wake-up actions\
|
||||||
|
if (!\$we) {\
|
||||||
|
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\";;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
#------------------------------------------------------------------------------------\
|
||||||
|
# END WAKE-UP PROGRAM (OPTIONAL)\
|
||||||
|
# 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;;\
|
||||||
|
\
|
||||||
|
# Working days only (Mon-Fri except bank holidays): after only a small additional nap,\
|
||||||
|
# get you out of bed :-)\
|
||||||
|
# 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\";;\
|
||||||
|
\
|
||||||
|
# At weekend and bank holidays: 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\";;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
}\
|
||||||
|
";
|
||||||
|
|
||||||
Log3 $NAME, 3,
|
Log3 $NAME, 3,
|
||||||
"RESIDENTStk $NAME: new notify macro device $wakeupMacro created";
|
"RESIDENTStk $NAME: new notify macro device $wakeupMacro created";
|
||||||
fhem "define $wakeupMacro notify $wakeupMacro {}";
|
fhem "define $wakeupMacro notify $wakeupMacro $wakeUpMacroTemplate";
|
||||||
fhem
|
fhem
|
||||||
"attr $wakeupMacro comment Macro auto-created by RESIDENTS Toolkit";
|
"attr $wakeupMacro comment Macro auto-created by RESIDENTS Toolkit";
|
||||||
if ($room) { fhem "attr $wakeupMacro room $room" }
|
if ($room) { fhem "attr $wakeupMacro room $room" }
|
||||||
@ -95,66 +195,140 @@ sub RESIDENTStk_wakeupSet($;$) {
|
|||||||
|
|
||||||
# check for required wakeupAtdevice attribute
|
# check for required wakeupAtdevice attribute
|
||||||
if ( !$wakeupAtdevice ) {
|
if ( !$wakeupAtdevice ) {
|
||||||
Log3 $NAME, 3,
|
Log3 $NAME, 4,
|
||||||
"RESIDENTStk $NAME: adjusting dummy device for required attribute wakeupAtdevice";
|
"RESIDENTStk $NAME: adjusting dummy device for required attribute wakeupAtdevice";
|
||||||
fhem "attr $NAME wakeupAtdevice $atName";
|
fhem "attr $NAME wakeupAtdevice $atName";
|
||||||
$wakeupAtdevice = $atName;
|
$wakeupAtdevice = $atName;
|
||||||
}
|
}
|
||||||
|
|
||||||
# check for existing at device
|
|
||||||
if ( !defined( $defs{$wakeupAtdevice} ) ) {
|
if ( !defined( $defs{$wakeupAtdevice} ) ) {
|
||||||
Log3 $NAME, 3,
|
Log3 $NAME, 3,
|
||||||
"RESIDENTStk $NAME: new at device $wakeupAtdevice created";
|
"RESIDENTStk $NAME: new at-device $wakeupAtdevice created";
|
||||||
fhem
|
fhem
|
||||||
"define $wakeupAtdevice at *08:00 { RESIDENTStk_wakeupRun(\"$NAME\") }";
|
"define $wakeupAtdevice at *{RESIDENTStk_wakeupGetBegin(\"$NAME\")} { RESIDENTStk_wakeupRun(\"$NAME\") }";
|
||||||
fhem "attr $wakeupAtdevice comment Auto-created by RESIDENTS Toolkit";
|
fhem "attr $wakeupAtdevice comment Auto-created by RESIDENTS Toolkit";
|
||||||
if ($room) { fhem "attr $wakeupAtdevice room $room" }
|
if ($room) { fhem "attr $wakeupAtdevice room $room" }
|
||||||
}
|
}
|
||||||
|
elsif ( $defs{$wakeupAtdevice}{TYPE} ne "at" ) {
|
||||||
# Reset at device if wake-up timer was disabled and wakeupDefaultTime is present
|
|
||||||
if ( $VALUE eq "OFF" ) {
|
|
||||||
Log3 $NAME, 4, "RESIDENTStk $NAME: Wake-up timer disabled";
|
|
||||||
if ($wakeupDefaultTime) {
|
|
||||||
$VALUE = $wakeupDefaultTime;
|
|
||||||
Log3 $NAME, 4,
|
|
||||||
"RESIDENTStk $NAME: Wake-up timer disabled and triggered at device reset";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log3 $NAME, 4, "RESIDENTStk $NAME: Wake-up timer disabled";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Recalculate new wake-up value
|
|
||||||
if ( $VALUE ne "OFF" ) {
|
|
||||||
my @time = split /:/, $VALUE;
|
|
||||||
my $time_sec = $time[0] * 3600 + $time[1] * 60;
|
|
||||||
my $begin = $time_sec - $wakeupOffset * 60;
|
|
||||||
my $hour = int( $begin / 3600 );
|
|
||||||
my $leftover = $begin % 3600;
|
|
||||||
my $min = int( $leftover / 60 );
|
|
||||||
if ( $time_sec < 1800 && $wakeupOffset > 0 ) { $hour = 23 }
|
|
||||||
|
|
||||||
if ( $defs{$wakeupAtdevice}{TYPE} ne "at" ) {
|
|
||||||
Log3 $NAME, 3,
|
Log3 $NAME, 3,
|
||||||
"RESIDENTStk $NAME: ERROR - defined device '$wakeupAtdevice' is not an at device!";
|
"RESIDENTStk $NAME: WARNING - defined at-device '$wakeupAtdevice' is not an at-device!";
|
||||||
|
}
|
||||||
|
|
||||||
|
# stop
|
||||||
|
#
|
||||||
|
if ( $VALUE eq "stop" && $running ) {
|
||||||
|
Log3 $NAME, 4, "RESIDENTStk $NAME: stopping wake-up program";
|
||||||
|
fhem "setreading $NAME running 0";
|
||||||
|
fhem "set $NAME nextRun $nextRun";
|
||||||
|
|
||||||
|
# trigger macro again so it may clean up it's stuff.
|
||||||
|
# use $EVTPART1 to check
|
||||||
|
if ( !$wakeupMacro ) {
|
||||||
|
Log3 $NAME, 2, "RESIDENTStk $NAME: missing attribute wakeupMacro";
|
||||||
|
}
|
||||||
|
elsif ( !defined( $defs{$wakeupMacro} ) ) {
|
||||||
|
Log3 $NAME, 2,
|
||||||
|
"RESIDENTStk $NAME: notify macro $wakeupMacro not found - no wakeup actions defined!";
|
||||||
|
}
|
||||||
|
elsif ( $defs{$wakeupMacro}{TYPE} ne "notify" ) {
|
||||||
|
Log3 $NAME, 2,
|
||||||
|
"RESIDENTStk $NAME: device $wakeupMacro is not of type notify";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fhem "modify $wakeupAtdevice *"
|
if ( defined( $notify[1] ) ) {
|
||||||
. sprintf( "%02d:%02d", $hour, $min );
|
|
||||||
|
|
||||||
Log3 $NAME, 4,
|
Log3 $NAME, 4,
|
||||||
"RESIDENTStk $NAME($wakeupAtdevice): Wake-up begin scheduled for "
|
"RESIDENTStk $NAME: trigger $wakeupMacro (running=0,forced-stop=0)";
|
||||||
. sprintf( "%02d:%02d", $hour, $min );
|
fhem "trigger $wakeupMacro stop $lastRun $wakeupOffset";
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Log3 $NAME, 4,
|
||||||
|
"RESIDENTStk $NAME: trigger $wakeupMacro (running=0,forced-stop=1)";
|
||||||
|
fhem "trigger $wakeupMacro forced-stop $lastRun $wakeupOffset";
|
||||||
|
}
|
||||||
|
fhem "setreading $wakeupUserdevice:FILTER=wakeup=1 wakeup 0";
|
||||||
|
|
||||||
|
my $wakeupStopAtdevice = $wakeupAtdevice . "_stop";
|
||||||
|
if ( defined( $defs{$wakeupStopAtdevice} ) ) {
|
||||||
|
fhem "delete $wakeupStopAtdevice";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# autosave
|
# auto or reset
|
||||||
if ($autosave) { fhem "save" }
|
#
|
||||||
|
elsif ( $VALUE eq "auto" || $VALUE eq "reset" ) {
|
||||||
|
my $resetTime = ReadingsVal( $NAME, "lastRun", 0 );
|
||||||
|
if ($wakeupDefaultTime) {
|
||||||
|
$resetTime = $wakeupDefaultTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $resetTime
|
||||||
|
&& !( $VALUE eq "auto" && lc($resetTime) eq "off" ) )
|
||||||
|
{
|
||||||
|
fhem "set $NAME:FILTER=state!=$resetTime nextRun $resetTime";
|
||||||
|
}
|
||||||
|
elsif ( $VALUE eq "reset" ) {
|
||||||
|
Log3 $NAME, 4,
|
||||||
|
"RESIDENTStk $NAME: no default value specified in attribute wakeupDefaultTime, just keeping setting OFF";
|
||||||
|
fhem "set $NAME:FILTER=state!=OFF nextRun OFF";
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# set new wakeup value
|
||||||
|
elsif (( lc($VALUE) eq "off" || $VALUE =~ /^([0-9]{2}:[0-9]{2})$/ )
|
||||||
|
&& defined( $defs{$wakeupAtdevice} )
|
||||||
|
&& $defs{$wakeupAtdevice}{TYPE} eq "at" )
|
||||||
|
{
|
||||||
|
Log3 $NAME, 4,
|
||||||
|
"RESIDENTStk $NAME: New wake-up time: $VALUE";
|
||||||
|
|
||||||
|
readingsBeginUpdate( $defs{$NAME} );
|
||||||
|
readingsBulkUpdate( $defs{$NAME}, "state", $VALUE )
|
||||||
|
if ( ReadingsVal( $NAME, "state", 0 ) ne $VALUE );
|
||||||
|
readingsBulkUpdate( $defs{$NAME}, "nextRun", $VALUE )
|
||||||
|
if ( ReadingsVal( $NAME, "nextRun", 0 ) ne $VALUE );
|
||||||
|
readingsEndUpdate( $defs{$NAME}, 1 );
|
||||||
|
|
||||||
|
fhem
|
||||||
|
"set $wakeupAtdevice modifyTimeSpec {RESIDENTStk_wakeupGetBegin(\"$NAME\")}";
|
||||||
|
|
||||||
|
if ( !$running ) {
|
||||||
|
fhem "setreading $wakeupUserdevice:FILTER=wakeup!=0 wakeup 0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
#####################################
|
#
|
||||||
|
# Get current wakeup begin
|
||||||
|
#
|
||||||
|
sub RESIDENTStk_wakeupGetBegin($) {
|
||||||
|
my ($NAME) = @_;
|
||||||
|
my $wakeupDefaultTime = AttrVal( $NAME, "wakeupDefaultTime", "07:00" );
|
||||||
|
my $wakeupTime = ReadingsVal( $NAME, "nextRun", $wakeupDefaultTime );
|
||||||
|
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 ( $seconds < 0 ) { $seconds = 86400 + $seconds }
|
||||||
|
|
||||||
|
$return = RESIDENTStk_sec2time($seconds);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$return = "07:00";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
# Use DUMMY device to run wakup event
|
# Use DUMMY device to run wakup event
|
||||||
#
|
#
|
||||||
sub RESIDENTStk_wakeupRun($) {
|
sub RESIDENTStk_wakeupRun($) {
|
||||||
@ -162,10 +336,18 @@ sub RESIDENTStk_wakeupRun($) {
|
|||||||
|
|
||||||
my $wakeupMacro = AttrVal( $NAME, "wakeupMacro", 0 );
|
my $wakeupMacro = AttrVal( $NAME, "wakeupMacro", 0 );
|
||||||
my $wakeupDefaultTime = AttrVal( $NAME, "wakeupDefaultTime", 0 );
|
my $wakeupDefaultTime = AttrVal( $NAME, "wakeupDefaultTime", 0 );
|
||||||
|
my $wakeupAtdevice = AttrVal( $NAME, "wakeupAtdevice", 0 );
|
||||||
my $wakeupUserdevice = AttrVal( $NAME, "wakeupUserdevice", 0 );
|
my $wakeupUserdevice = AttrVal( $NAME, "wakeupUserdevice", 0 );
|
||||||
my $wakeupDays = AttrVal( $NAME, "wakeupDays", 0 );
|
my $wakeupDays = AttrVal( $NAME, "wakeupDays", 0 );
|
||||||
my $wakeupResetdays = AttrVal( $NAME, "wakeupResetdays", 0 );
|
my $wakeupResetdays = AttrVal( $NAME, "wakeupResetdays", 0 );
|
||||||
|
my $wakeupOffset = AttrVal( $NAME, "wakeupOffset", 0 );
|
||||||
my $wakeupResetSwitcher = AttrVal( $NAME, "wakeupResetSwitcher", 0 );
|
my $wakeupResetSwitcher = AttrVal( $NAME, "wakeupResetSwitcher", 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 ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
|
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
|
||||||
localtime(time);
|
localtime(time);
|
||||||
@ -181,58 +363,74 @@ sub RESIDENTStk_wakeupRun($) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( !defined( $defs{$NAME} ) ) {
|
if ( !defined( $defs{$NAME} ) ) {
|
||||||
Log3 $NAME, 3, "RESIDENTStk $NAME: Non existing device";
|
|
||||||
return "$NAME: Non existing device";
|
return "$NAME: Non existing device";
|
||||||
}
|
}
|
||||||
elsif ( ReadingsVal( $NAME, "state", "OFF" ) eq "OFF" ) {
|
elsif ( lc($nextRun) eq "off" ) {
|
||||||
Log3 $NAME, 4,
|
Log3 $NAME, 4,
|
||||||
"RESIDENTStk $NAME: alarm set to OFF - not running any action";
|
"RESIDENTStk $NAME: alarm set to OFF - not triggering wake-up program";
|
||||||
}
|
}
|
||||||
elsif ( !$wakeupUserdevice ) {
|
elsif ( !$wakeupUserdevice ) {
|
||||||
Log3 $NAME, 4, "RESIDENTStk $NAME: missing attribute wakeupUserdevice";
|
|
||||||
return "$NAME: missing attribute wakeupUserdevice";
|
return "$NAME: missing attribute wakeupUserdevice";
|
||||||
}
|
}
|
||||||
elsif ( !defined( $defs{$wakeupUserdevice} ) ) {
|
elsif ( !defined( $defs{$wakeupUserdevice} ) ) {
|
||||||
Log3 $NAME, 4,
|
|
||||||
"RESIDENTStk $NAME: Non existing wakeupUserdevice $wakeupUserdevice";
|
|
||||||
return "$NAME: Non existing wakeupUserdevice $wakeupUserdevice";
|
return "$NAME: Non existing wakeupUserdevice $wakeupUserdevice";
|
||||||
}
|
}
|
||||||
elsif ($defs{$wakeupUserdevice}{TYPE} ne "ROOMMATE"
|
elsif ($defs{$wakeupUserdevice}{TYPE} ne "ROOMMATE"
|
||||||
&& $defs{$wakeupUserdevice}{TYPE} ne "GUEST" )
|
&& $defs{$wakeupUserdevice}{TYPE} ne "GUEST" )
|
||||||
{
|
{
|
||||||
Log3 $NAME, 4,
|
|
||||||
"RESIDENTStk $NAME: device $wakeupUserdevice is not of type ROOMMATE or GUEST";
|
|
||||||
return
|
return
|
||||||
"$NAME: device $wakeupUserdevice is not of type ROOMMATE or GUEST";
|
"$NAME: device $wakeupUserdevice is not of type ROOMMATE or GUEST";
|
||||||
}
|
}
|
||||||
elsif ( $defs{$wakeupUserdevice}{TYPE} eq "GUEST"
|
elsif ( $defs{$wakeupUserdevice}{TYPE} eq "GUEST"
|
||||||
&& ReadingsVal( $wakeupUserdevice, "state", "" ) eq "none" )
|
&& ReadingsVal( $wakeupUserdevice, "state", "" ) eq "none" )
|
||||||
{
|
{
|
||||||
fhem "set $NAME OFF";
|
fhem "set $NAME nextRun OFF";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
elsif ($wday ~~ @days
|
elsif ($wday ~~ @days
|
||||||
&& ReadingsVal( $wakeupUserdevice, "state", "" ) ne "absent"
|
&& ReadingsVal( $wakeupUserdevice, "state", "" ) ne "absent"
|
||||||
&& ReadingsVal( $wakeupUserdevice, "state", "" ) ne "gone" )
|
&& ReadingsVal( $wakeupUserdevice, "state", "" ) ne "gone"
|
||||||
|
&& ReadingsVal( $wakeupUserdevice, "state", "" ) ne "gotosleep"
|
||||||
|
&& ReadingsVal( $wakeupUserdevice, "state", "" ) ne "awoken" )
|
||||||
{
|
{
|
||||||
if ( !$wakeupMacro ) {
|
if ( !$wakeupMacro ) {
|
||||||
Log3 $NAME, 2, "RESIDENTStk $NAME: missing attribute wakeupMacro";
|
|
||||||
return "$NAME: missing attribute wakeupMacro";
|
return "$NAME: missing attribute wakeupMacro";
|
||||||
}
|
}
|
||||||
elsif ( !defined( $defs{$wakeupMacro} ) ) {
|
elsif ( !defined( $defs{$wakeupMacro} ) ) {
|
||||||
Log3 $NAME, 2,
|
|
||||||
"RESIDENTStk $NAME: notify macro $wakeupMacro not found - no wakeup actions defined!";
|
|
||||||
return
|
return
|
||||||
"$NAME: notify macro $wakeupMacro not found - no wakeup actions defined!";
|
"$NAME: notify macro $wakeupMacro not found - no wakeup actions defined!";
|
||||||
}
|
}
|
||||||
elsif ( $defs{$wakeupMacro}{TYPE} ne "notify" ) {
|
elsif ( $defs{$wakeupMacro}{TYPE} ne "notify" ) {
|
||||||
Log3 $NAME, 2,
|
|
||||||
"RESIDENTStk $NAME: device $wakeupMacro is not of type notify";
|
|
||||||
return "$NAME: device $wakeupMacro is not of type notify";
|
return "$NAME: device $wakeupMacro is not of type notify";
|
||||||
}
|
}
|
||||||
|
elsif ($wakeupUserdeviceWakeup) {
|
||||||
|
Log3 $NAME, 3,
|
||||||
|
"RESIDENTStk $NAME: Another wake-up program is already being executed, won't trigger $wakeupMacro";
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
Log3 $NAME, 4, "RESIDENTStk $NAME: trigger $wakeupMacro";
|
Log3 $NAME, 4,
|
||||||
fhem "trigger $wakeupMacro";
|
"RESIDENTStk $NAME: trigger $wakeupMacro (running=1)";
|
||||||
|
fhem "trigger $wakeupMacro start $nextRun $wakeupOffset";
|
||||||
|
fhem "setreading $wakeupUserdevice wakeup 1";
|
||||||
|
fhem "setreading $NAME lastRun $nextRun";
|
||||||
|
|
||||||
|
if ( $wakeupOffset > 0 ) {
|
||||||
|
my $wakeupStopAtdevice = $wakeupAtdevice . "_stop";
|
||||||
|
|
||||||
|
if ( defined( $defs{$wakeupStopAtdevice} ) ) {
|
||||||
|
fhem "delete $wakeupStopAtdevice";
|
||||||
|
}
|
||||||
|
|
||||||
|
Log3 $NAME, 4,
|
||||||
|
"RESIDENTStk $NAME: created at-device $wakeupStopAtdevice to stop wake-up program in $wakeupOffset minutes";
|
||||||
|
fhem "define $wakeupStopAtdevice at +"
|
||||||
|
. RESIDENTStk_sec2time( $wakeupOffset * 60 + 1 )
|
||||||
|
. " set $NAME:FILTER=running=1 stop triggerpost";
|
||||||
|
fhem
|
||||||
|
"attr $wakeupStopAtdevice comment Auto-created by RESIDENTS Toolkit";
|
||||||
|
}
|
||||||
|
|
||||||
|
$running = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,13 +446,28 @@ sub RESIDENTStk_wakeupRun($) {
|
|||||||
if ( $wakeupDefaultTime && $wday ~~ @rdays && $doReset ) {
|
if ( $wakeupDefaultTime && $wday ~~ @rdays && $doReset ) {
|
||||||
Log3 $NAME, 4,
|
Log3 $NAME, 4,
|
||||||
"RESIDENTStk $NAME: Resetting based on wakeupDefaultTime";
|
"RESIDENTStk $NAME: Resetting based on wakeupDefaultTime";
|
||||||
fhem "set $NAME:FILTER=state!=$wakeupDefaultTime $wakeupDefaultTime";
|
fhem
|
||||||
|
"set $NAME:FILTER=state!=$wakeupDefaultTime nextRun $wakeupDefaultTime";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $running && $wakeupOffset > 0 ) {
|
||||||
|
readingsBeginUpdate( $defs{$NAME} );
|
||||||
|
readingsBulkUpdate( $defs{$NAME}, "running", "1" )
|
||||||
|
if ( ReadingsVal( $NAME, "running", 0 ) ne "1" );
|
||||||
|
readingsBulkUpdate( $defs{$NAME}, "state", "running" )
|
||||||
|
if ( ReadingsVal( $NAME, "state", 0 ) ne "running" );
|
||||||
|
readingsEndUpdate( $defs{$NAME}, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
|
# FHEM CODE INJECTION
|
||||||
|
#------------------------------------
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
# AttFn for enslaved dummy devices
|
# AttFn for enslaved dummy devices
|
||||||
#
|
#
|
||||||
sub RESIDENTStk_AttrFnDummy(@) {
|
sub RESIDENTStk_AttrFnDummy(@) {
|
||||||
@ -297,24 +510,103 @@ sub RESIDENTStk_AttrFnDummy(@) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
# del attribute
|
|
||||||
elsif ( $cmd eq "del" ) {
|
|
||||||
|
|
||||||
# wakeupResetSwitcher
|
|
||||||
if ( $aName eq "wakeupResetSwitcher" ) {
|
|
||||||
if ( defined( $defs{$aVal} ) && $defs{$aVal}{TYPE} eq "dummy" ) {
|
|
||||||
fhem "delete $aVal";
|
|
||||||
|
|
||||||
Log3 $name, 3,
|
|
||||||
"RESIDENTStk $name: slave dummy device $aVal deleted";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# GENERAL FUNCTIONS USED IN RESIDENTS, ROOMMATE, GUEST
|
||||||
|
#------------------------------------
|
||||||
|
#
|
||||||
|
|
||||||
|
sub RESIDENTStk_TimeDiff ($$;$) {
|
||||||
|
my ( $datetimeNow, $datetimeOld, $format ) = @_;
|
||||||
|
|
||||||
|
my $timestampNow = RESIDENTStk_Datetime2Timestamp($datetimeNow);
|
||||||
|
my $timestampOld = RESIDENTStk_Datetime2Timestamp($datetimeOld);
|
||||||
|
my $timeDiff = $timestampNow - $timestampOld;
|
||||||
|
|
||||||
|
# return seconds
|
||||||
|
return int( $timeDiff + 0.5 )
|
||||||
|
if ( defined($format) && $format eq "sec" );
|
||||||
|
|
||||||
|
# return minutes
|
||||||
|
return int( $timeDiff / 60 + 0.5 )
|
||||||
|
if ( defined($format) && $format eq "min" );
|
||||||
|
|
||||||
|
# return human readable format
|
||||||
|
return RESIDENTStk_sec2time( int( $timeDiff + 0.5 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub RESIDENTStk_Datetime2Timestamp($) {
|
||||||
|
my ($datetime) = @_;
|
||||||
|
|
||||||
|
my ( $date, $time, $y, $m, $d, $hour, $min, $sec, $timestamp );
|
||||||
|
|
||||||
|
( $date, $time ) = split( ' ', $datetime );
|
||||||
|
( $y, $m, $d ) = split( '-', $date );
|
||||||
|
( $hour, $min, $sec ) = split( ':', $time );
|
||||||
|
$m -= 01;
|
||||||
|
$timestamp = timelocal( $sec, $min, $hour, $d, $m, $y );
|
||||||
|
|
||||||
|
return $timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub RESIDENTStk_sec2time($) {
|
||||||
|
my ($sec) = @_;
|
||||||
|
|
||||||
|
# return human readable format
|
||||||
|
my $hours = ( abs($sec) < 3600 ? 0 : int( abs($sec) / 3600 ) );
|
||||||
|
$sec -= ( $hours == 0 ? 0 : ( $hours * 3600 ) );
|
||||||
|
my $minutes = ( abs($sec) < 60 ? 0 : int( abs($sec) / 60 ) );
|
||||||
|
my $seconds = abs($sec) % 60;
|
||||||
|
|
||||||
|
$hours = "0" . $hours if ( $hours < 10 );
|
||||||
|
$minutes = "0" . $minutes if ( $minutes < 10 );
|
||||||
|
$seconds = "0" . $seconds if ( $seconds < 10 );
|
||||||
|
|
||||||
|
return "$hours:$minutes:$seconds";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub RESIDENTStk_InternalTimer($$$$$) {
|
||||||
|
my ( $modifier, $tim, $callback, $hash, $waitIfInitNotDone ) = @_;
|
||||||
|
|
||||||
|
my $mHash;
|
||||||
|
if ( $modifier eq "" ) {
|
||||||
|
$mHash = $hash;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
my $timerName = $hash->{NAME} . "_" . $modifier;
|
||||||
|
if ( exists( $hash->{TIMER}{$timerName} ) ) {
|
||||||
|
$mHash = $hash->{TIMER}{$timerName};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$mHash = {
|
||||||
|
HASH => $hash,
|
||||||
|
NAME => $hash->{NAME} . "_" . $modifier,
|
||||||
|
MODIFIER => $modifier
|
||||||
|
};
|
||||||
|
$hash->{TIMER}{$timerName} = $mHash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InternalTimer( $tim, $callback, $mHash, $waitIfInitNotDone );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub RESIDENTStk_RemoveInternalTimer($$) {
|
||||||
|
my ( $modifier, $hash ) = @_;
|
||||||
|
|
||||||
|
my $timerName = $hash->{NAME} . "_" . $modifier;
|
||||||
|
if ( $modifier eq "" ) {
|
||||||
|
RemoveInternalTimer($hash);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
my $mHash = $hash->{TIMER}{$timerName};
|
||||||
|
if ( defined($mHash) ) {
|
||||||
|
delete $hash->{TIMER}{$timerName};
|
||||||
|
RemoveInternalTimer($mHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user