diff --git a/fhem/CHANGED b/fhem/CHANGED
index 8d374af63..776807598 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -1,5 +1,9 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it.
+ - feature: GUEST: added support for RESIDENTS toolkit
+ - feature: ROOMMATE: added support for RESIDENTS toolkit
+ - feature: RESIDENTS: added support for RESIDENTS toolkit
+ - added: RESIDENTStk: new RESIDENTS toolkit and first function wakeuptimer
- bugfix: 37_SHC: go back to last release version v0.9.0 (rr2000)
- change: SYSMON: prevent some warnings
- bugfix: SYSMON: ethernet readings on bbb (thx to nesges)
diff --git a/fhem/FHEM/10_RESIDENTS.pm b/fhem/FHEM/10_RESIDENTS.pm
old mode 100755
new mode 100644
index 1d8d25569..f67cdcffb
--- a/fhem/FHEM/10_RESIDENTS.pm
+++ b/fhem/FHEM/10_RESIDENTS.pm
@@ -23,9 +23,12 @@
# along with fhem. If not, see .
#
#
-# Version: 1.1.0
+# Version: 1.2.0
#
# Major Version History:
+# - 1.2.0 - 2015-03-11
+# -- add RESIDENTStoolkit support
+#
# - 1.1.0 - 2014-04-07
# -- new readings in computer readable format (*_cr)
# -- format of readings durTimer readings changed from minutes to HH:MM:ss
@@ -41,6 +44,7 @@ use strict;
use warnings;
use Time::Local;
use Data::Dumper;
+require RESIDENTStk;
sub RESIDENTS_Set($@);
sub RESIDENTS_Define($$);
@@ -58,7 +62,8 @@ sub RESIDENTS_Initialize($) {
$hash->{NotifyFn} = "RESIDENTS_Notify";
$hash->{UndefFn} = "RESIDENTS_Undefine";
$hash->{AttrList} =
- "rgr_showAllStates:0,1 rgr_states " . $readingFnAttributes;
+ "rgr_showAllStates:0,1 rgr_states rgr_wakeupDevice "
+ . $readingFnAttributes;
}
###################################
@@ -73,13 +78,13 @@ sub RESIDENTS_Define($$) {
# set default settings on first define
if ($init_done) {
- $attr{$name}{alias} = "Residents";
- $attr{$name}{devStateIcon} =
+ $attr{$name}{alias} = "Residents";
+ $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';
- $attr{$name}{group} = "Home State";
- $attr{$name}{icon} = "control_building_filled";
- $attr{$name}{room} = "Residents";
- $attr{$name}{webCmd} = "state";
+ $attr{$name}{group} = "Home State";
+ $attr{$name}{icon} = "control_building_filled";
+ $attr{$name}{room} = "Residents";
+ $attr{$name}{webCmd} = "state";
}
return undef;
@@ -137,6 +142,11 @@ sub RESIDENTS_Notify($$) {
if ( defined( $hash->{GUESTS} )
&& $hash->{GUESTS} ne "" );
+ my @registeredWakeupdevs =
+ split( /,/, $attr{$hashName}{rgr_wakeupDevice} )
+ if ( defined( $attr{$hashName}{rgr_wakeupDevice} )
+ && $attr{$hashName}{rgr_wakeupDevice} ne "" );
+
# process only registered ROOMMATE or GUEST devices
if ( ( @registeredRoommates && $devName ~~ @registeredRoommates )
|| ( @registeredGuests && $devName ~~ @registeredGuests ) )
@@ -183,6 +193,27 @@ sub RESIDENTS_Notify($$) {
}
}
}
+
+ # process only registered devices for wakeup function
+ if ( @registeredWakeupdevs && $devName ~~ @registeredWakeupdevs ) {
+
+ return
+ if ( !$dev->{CHANGED} ); # Some previous notify deleted the array.
+
+ 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";
+
+ return RESIDENTStk_wakeupSet( $devName, $change );
+ }
+ }
+ }
}
return;
@@ -221,6 +252,7 @@ sub RESIDENTS_Set($@) {
$usage .= " state:$states";
$usage .= " removeRoommate:" . $roommates if ( $roommates ne "" );
$usage .= " removeGuest:" . $guests if ( $guests ne "" );
+ $usage .= " create:wakeuptimer";
# states
if ( $a[1] eq "state"
@@ -478,6 +510,61 @@ sub RESIDENTS_Set($@) {
RESIDENTS_UpdateReadings($hash);
}
+ # create
+ elsif ( $a[1] eq "create" ) {
+ if ( defined( $a[2] ) && $a[2] eq "wakeuptimer" ) {
+ my $i = "1";
+ my $wakeuptimerName = $name . "_wakeuptimer" . $i;
+ my $created = 0;
+
+ until ($created) {
+ if ( defined( $defs{$wakeuptimerName} ) ) {
+ $i++;
+ $wakeuptimerName = $name . "_wakeuptimer" . $i;
+ }
+ else {
+
+ # create new dummy device
+ fhem "define $wakeuptimerName dummy";
+ fhem "attr $wakeuptimerName alias Wake-up Timer $i";
+ fhem "attr $wakeuptimerName comment Auto-created by RESIDENTS module for use with RESIDENTS Toolkit";
+ fhem
+"attr $wakeuptimerName devStateIcon OFF:general_aus\@red .*:general_an\@green:OFF";
+ fhem "attr $wakeuptimerName group " . $attr{$name}{group}
+ if ( defined( $attr{$name}{group} ) );
+ fhem "attr $wakeuptimerName icon time_clock";
+ fhem "attr $wakeuptimerName room " . $attr{$name}{room}
+ if ( defined( $attr{$name}{room} ) );
+ 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";
+ fhem "attr $wakeuptimerName userattr wakeupUserdevice";
+ fhem "attr $wakeuptimerName wakeupUserdevice $name";
+ fhem "attr $wakeuptimerName webCmd state";
+
+ # register slave device
+ if ( defined( $attr{$name}{rgr_wakeupDevice} ) ) {
+ fhem "attr $name rgr_wakeupDevice "
+ . $attr{$name}{rgr_wakeupDevice}
+ . ",$wakeuptimerName";
+ }
+ else {
+ fhem "attr $name rgr_wakeupDevice $wakeuptimerName";
+ }
+
+ # trigger first update
+ fhem "set $wakeuptimerName OFF";
+
+ $created = 1;
+ return
+"Dummy $wakeuptimerName and other pending devices created and pre-configured. You may edit Macro_$wakeuptimerName to define your wake-up actions.";
+ }
+ }
+ }
+ else {
+ return "Invalid 2nd argument, choose one of wakeuptimer ";
+ }
+ }
+
# return usage hint
else {
return $usage;
@@ -841,7 +928,7 @@ sub RESIDENTS_UpdateReadings (@) {
}
- readingsEndUpdate($hash, 1);
+ readingsEndUpdate( $hash, 1 );
}
###################################
@@ -936,6 +1023,9 @@ sub RESIDENTS_Datetime2Timestamp($) {
state home,gotosleep,asleep,awoken,absent,gone switch between states for all group members at once; see attribute rgr_states to adjust list shown in FHEMWEB
+
+ create wakeuptimer add several pre-configurations provided by RESIDENTS Toolkit. See separate section for details.
+
@@ -1069,6 +1159,45 @@ sub RESIDENTS_Datetime2Timestamp($) {
+
+
+ RESIDENTS Toolkit
+
+
+ Using set-command create you may add pre-configured configurations to your RESIDENTS, ROOMMATE or GUEST devices for your convenience.
+ The following commands are currently available:
+
+ -
+ wakeuptimer - adds a wake-up timer dummy device with enhanced functions to start with wake-up automations
+
+ A notify device is created to be used as a Macro to carry out your actual automations. The macro is triggered by a normal at device you may customize as well. However, a special RESIDENTS Toolkit function is handling the wake-up trigger event for you.
+
+ The wake-up behaviour may be influenced by the following device attributes:
+ -
+ wakeupAutosave - Triggers FHEM command 'save' after adjusting wake-up time value (defaults to 0=false)
+
+ -
+ wakeupDays - only trigger macro at these days. Mon=1,Tue=2,Wed=3,Thu=4,Fri=5,Sat=6,Sun=0 (optional)
+
+ -
+ wakeupDefaultTime - after triggering macro reset the wake-up time to this default value (optional)
+
+ -
+ wakeupMacro - name of the notify macro device (mandatory)
+
+ -
+ wakeupOffset - value in minutes to trigger your macro earlier than the user requested to be woken up, e.g. if you have a complex wake-up program over 30 minutes (defaults to 0)
+
+ -
+ wakeupResetdays - 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)
+
+ -
+ wakeupUserdevice - backlink to RESIDENTS, ROOMMATE or GUEST device to check it's status (mandatory)
+
+
+
+
+
=end html
@@ -1117,6 +1246,9 @@ sub RESIDENTS_Datetime2Timestamp($) {
state home,gotosleep,asleep,awoken,absent,gone wechselt den Status für alle Gruppenmitglieder gleichzeitig; siehe Attribut rgr_states, um die angezeigte Liste in FHEMWEB abzuändern
+
+ create wakeuptimer fügt diverse Vorkonfigurationen auf Basis von RESIDENTS Toolkit hinzu. Siehe separate Sektion.
+
@@ -1250,6 +1382,45 @@ sub RESIDENTS_Datetime2Timestamp($) {
+
+
+ RESIDENTS Toolkit
+
+
+ Mit dem set-Kommando create können zur Vereinfachung vorkonfigurierte Konfigurationen zu RESIDENTS, ROOMMATE oder GUEST Geräten hinzugefügt werden.
+ The folgenden Kommandos sind momentan verfügbar:
+
+ -
+ wakeuptimer - fügt ein Dummy Gerät mit erweiterten Funktionen als Wecker hinzu, um darauf Weck-Automationen aufzubauen.
+
+ Ein notify Gerät wird als Makro erstellt, um die eigentliche Automation auszuführen. Das Makro wird durch ein normales at-Gerät ausgelöst und kann ebenfalls angepasst werden. Die Hauptfunktion wird dabei trotzdem von einer speziellen RESIDENTS Toolkit funktion gehandhabt.
+
+ Die Weckfunktion kann wie folgt über Attribute beinflusst werden:
+ -
+ wakeupAutosave - Löst das FHEM Kommando 'save' nach einer Änderung der Weckzeit aus (Standard 0=aus)
+
+ -
+ wakeupDays - Makro nur an bestimmten Tagen auslösen. Mon=1,Di=2,Mi=3,Do=4,Fr=5,Sa=6,So=0 (optional)
+
+ -
+ wakeupDefaultTime - Stellt die Weckzeit nach dem auslösen zurück auf diesen Standardwert (optional)
+
+ -
+ wakeupMacro - Name des notify Makro Gerätes (notwendig)
+
+ -
+ wakeupOffset - Wert in Minuten, die das Makro früher ausgelöst werden soll, z.B. bei komplexen Weckprogrammen über einen Zeitraum von 30 Minuten (Standard ist 0)
+
+ -
+ wakeupResetdays - 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)
+
+ -
+ wakeupUserdevice - Backlink zum RESIDENTS, ROOMMATE oder GUEST Gerät, um dessen Status zu prüfen (notwendig)
+
+
+
+
+
=end html_DE
diff --git a/fhem/FHEM/20_GUEST.pm b/fhem/FHEM/20_GUEST.pm
old mode 100755
new mode 100644
index 9b779cc51..f77fe63cb
--- a/fhem/FHEM/20_GUEST.pm
+++ b/fhem/FHEM/20_GUEST.pm
@@ -23,9 +23,12 @@
# along with fhem. If not, see .
#
#
-# Version: 1.1.0
+# Version: 1.2.0
#
# Major Version History:
+# - 1.2.0 - 2015-03-11
+# -- add RESIDENTStoolkit support
+#
# - 1.1.0 - 2014-04-07
# -- new readings in computer readable format (*_cr)
# -- format of readings durTimer readings changed from minutes to HH:MM:ss
@@ -41,9 +44,11 @@ use strict;
use warnings;
use Time::Local;
use Data::Dumper;
+require RESIDENTStk;
sub GUEST_Set($@);
sub GUEST_Define($$);
+sub GUEST_Notify($$);
sub GUEST_Undefine($$);
###################################
@@ -52,11 +57,12 @@ sub GUEST_Initialize($) {
Log3 $hash, 5, "GUEST_Initialize: Entering";
- $hash->{SetFn} = "GUEST_Set";
- $hash->{DefFn} = "GUEST_Define";
- $hash->{UndefFn} = "GUEST_Undefine";
+ $hash->{SetFn} = "GUEST_Set";
+ $hash->{DefFn} = "GUEST_Define";
+ $hash->{NotifyFn} = "GUEST_Notify";
+ $hash->{UndefFn} = "GUEST_Undefine";
$hash->{AttrList} =
-"rg_locationHome rg_locationWayhome rg_locationUnderway rg_autoGoneAfter:12,16,24,26,28,30,36,48,60 rg_showAllStates:0,1 rg_realname:group,alias rg_states rg_locations rg_moods rg_moodDefault rg_moodSleepy rg_noDuration:0,1 "
+"rg_locationHome rg_locationWayhome rg_locationUnderway rg_autoGoneAfter:12,16,24,26,28,30,36,48,60 rg_showAllStates:0,1 rg_realname:group,alias rg_states rg_locations rg_moods rg_moodDefault rg_moodSleepy rg_noDuration:0,1 rg_wakeupDevice "
. $readingFnAttributes;
}
@@ -134,16 +140,17 @@ sub GUEST_Define($$) {
$aliasname =~ s/^rg_//;
$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";
- $attr{$name}{group} = "Guests";
- $attr{$name}{icon} = "scene_visit_guests";
- $attr{$name}{rg_realname} = "alias";
- $attr{$name}{sortby} = "1";
- $attr{$name}{webCmd} = "state";
+ $attr{$name}{group} = "Guests";
+ $attr{$name}{icon} = "scene_visit_guests";
+ $attr{$name}{rg_realname} = "alias";
+ $attr{$name}{sortby} = "1";
+ $attr{$name}{webCmd} = "state";
- $attr{$name}{room} = $attr{ $registeredResidentgroups[0] }{room}
- if (@registeredResidentgroups && exists($attr{$registeredResidentgroups[0]}{room}));
+ $attr{$name}{room} = $attr{ $registeredResidentgroups[0] }{room}
+ if ( @registeredResidentgroups
+ && exists( $attr{ $registeredResidentgroups[0] }{room} ) );
}
# trigger for modified objects
@@ -185,6 +192,45 @@ sub GUEST_Undefine($$) {
return undef;
}
+###################################
+sub GUEST_Notify($$) {
+ my ( $hash, $dev ) = @_;
+ my $devName = $dev->{NAME};
+ my $hashName = $hash->{NAME};
+ my $hashName_attr;
+
+ # process child notifies
+ if ( $devName ne $hashName ) {
+ my @registeredWakeupdevs =
+ split( /,/, $attr{$hashName}{rg_wakeupDevice} )
+ if ( defined( $attr{$hashName}{rg_wakeupDevice} )
+ && $attr{$hashName}{rg_wakeupDevice} ne "" );
+
+ # process only registered devices for wakeup function
+ if ( @registeredWakeupdevs && $devName ~~ @registeredWakeupdevs ) {
+
+ return
+ if ( !$dev->{CHANGED} ); # Some previous notify deleted the array.
+
+ 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";
+
+ return RESIDENTStk_wakeupSet( $devName, $change );
+ }
+ }
+ }
+ }
+
+ return;
+}
+
###################################
sub GUEST_Set($@) {
my ( $hash, @a ) = @_;
@@ -253,10 +299,9 @@ sub GUEST_Set($@) {
$usage .= " state:$states";
$usage .= " mood:$moods";
$usage .= " location$locations";
+ $usage .= " create:wakeuptimer";
-# $usage .=
-#" create:wuTimerWd,wuTimerWe,wuTimerMon,wuTimerTue,wuTimerWed,wuTimerThu,wuTimerFri,wuTimerSat,wuTimerSun";
-# $usage .= " compactMode:noArg largeMode:noArg";
+ # $usage .= " compactMode:noArg largeMode:noArg";
# silentSet
if ( $a[1] eq "silentSet" ) {
@@ -664,6 +709,61 @@ sub GUEST_Set($@) {
}
}
+ # create
+ elsif ( $a[1] eq "create" ) {
+ if ( defined( $a[2] ) && $a[2] eq "wakeuptimer" ) {
+ my $i = "1";
+ my $wakeuptimerName = $name . "_wakeuptimer" . $i;
+ my $created = 0;
+
+ until ($created) {
+ if ( defined( $defs{$wakeuptimerName} ) ) {
+ $i++;
+ $wakeuptimerName = $name . "_wakeuptimer" . $i;
+ }
+ else {
+
+ # create new dummy device
+ fhem "define $wakeuptimerName dummy";
+ fhem "attr $wakeuptimerName alias Wake-up Timer $i";
+ fhem "attr $wakeuptimerName comment Auto-created by GUEST module for use with RESIDENTS Toolkit";
+ fhem
+"attr $wakeuptimerName devStateIcon OFF:general_aus\@red .*:general_an\@green:OFF";
+ fhem "attr $wakeuptimerName group " . $attr{$name}{group}
+ if ( defined( $attr{$name}{group} ) );
+ fhem "attr $wakeuptimerName icon time_clock";
+ fhem "attr $wakeuptimerName room " . $attr{$name}{room}
+ if ( defined( $attr{$name}{room} ) );
+ 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";
+ fhem "attr $wakeuptimerName userattr wakeupUserdevice";
+ fhem "attr $wakeuptimerName wakeupUserdevice $name";
+ fhem "attr $wakeuptimerName webCmd state";
+
+ # register slave device
+ if ( defined( $attr{$name}{rg_wakeupDevice} ) ) {
+ fhem "attr $name rg_wakeupDevice "
+ . $attr{$name}{rg_wakeupDevice}
+ . ",$wakeuptimerName";
+ }
+ else {
+ fhem "attr $name rg_wakeupDevice $wakeuptimerName";
+ }
+
+ # trigger first update
+ fhem "set $wakeuptimerName OFF";
+
+ $created = 1;
+ return
+"Dummy $wakeuptimerName and other pending devices created and pre-configured. You may edit Macro_$wakeuptimerName to define your wake-up actions.";
+ }
+ }
+ }
+ else {
+ return "Invalid 2nd argument, choose one of wakeuptimer ";
+ }
+ }
+
# return usage hint
else {
return $usage;
@@ -739,82 +839,86 @@ sub GUEST_DurationTimer($;$) {
GUEST_RemoveInternalTimer( "DurationTimer", $hash );
- if ( !defined($attr{$name}{rg_noDuration}) || $attr{$name}{rg_noDuration} == 0 ) {
+ if ( !defined( $attr{$name}{rg_noDuration} )
+ || $attr{$name}{rg_noDuration} == 0 )
+ {
- # presence timer
- if ( defined( $hash->{READINGS}{presence}{VAL} )
- && $hash->{READINGS}{presence}{VAL} eq "present" )
- {
- if ( defined( $hash->{READINGS}{lastArrival}{VAL} )
- && $hash->{READINGS}{lastArrival}{VAL} ne "-" )
- {
- $durPresence =
- $timestampNow -
- GUEST_Datetime2Timestamp( $hash->{READINGS}{lastArrival}{VAL} );
- }
- }
+ # presence timer
+ if ( defined( $hash->{READINGS}{presence}{VAL} )
+ && $hash->{READINGS}{presence}{VAL} eq "present" )
+ {
+ if ( defined( $hash->{READINGS}{lastArrival}{VAL} )
+ && $hash->{READINGS}{lastArrival}{VAL} ne "-" )
+ {
+ $durPresence =
+ $timestampNow -
+ GUEST_Datetime2Timestamp(
+ $hash->{READINGS}{lastArrival}{VAL} );
+ }
+ }
- # absence timer
- if ( defined( $hash->{READINGS}{presence}{VAL} )
- && $hash->{READINGS}{presence}{VAL} eq "absent"
- && defined( $hash->{READINGS}{state}{VAL} )
- && $hash->{READINGS}{state}{VAL} eq "absent" )
- {
- if ( defined( $hash->{READINGS}{lastDeparture}{VAL} )
- && $hash->{READINGS}{lastDeparture}{VAL} ne "-" )
- {
- $durAbsence =
- $timestampNow -
- GUEST_Datetime2Timestamp( $hash->{READINGS}{lastDeparture}{VAL} );
- }
- }
+ # absence timer
+ if ( defined( $hash->{READINGS}{presence}{VAL} )
+ && $hash->{READINGS}{presence}{VAL} eq "absent"
+ && defined( $hash->{READINGS}{state}{VAL} )
+ && $hash->{READINGS}{state}{VAL} eq "absent" )
+ {
+ if ( defined( $hash->{READINGS}{lastDeparture}{VAL} )
+ && $hash->{READINGS}{lastDeparture}{VAL} ne "-" )
+ {
+ $durAbsence =
+ $timestampNow -
+ GUEST_Datetime2Timestamp(
+ $hash->{READINGS}{lastDeparture}{VAL} );
+ }
+ }
- # sleep timer
- if ( defined( $hash->{READINGS}{state}{VAL} )
- && $hash->{READINGS}{state}{VAL} eq "asleep" )
- {
- if ( defined( $hash->{READINGS}{lastSleep}{VAL} )
- && $hash->{READINGS}{lastSleep}{VAL} ne "-" )
- {
- $durSleep =
- $timestampNow -
- GUEST_Datetime2Timestamp( $hash->{READINGS}{lastSleep}{VAL} );
- }
- }
+ # sleep timer
+ if ( defined( $hash->{READINGS}{state}{VAL} )
+ && $hash->{READINGS}{state}{VAL} eq "asleep" )
+ {
+ if ( defined( $hash->{READINGS}{lastSleep}{VAL} )
+ && $hash->{READINGS}{lastSleep}{VAL} ne "-" )
+ {
+ $durSleep =
+ $timestampNow -
+ GUEST_Datetime2Timestamp( $hash->{READINGS}{lastSleep}{VAL} );
+ }
+ }
- my $durPresence_hr =
- ( $durPresence > 0 ) ? GUEST_sec2time($durPresence) : "00:00:00";
- my $durPresence_cr =
- ( $durPresence > 60 ) ? int( $durPresence / 60 + 0.5 ) : 0;
- my $durAbsence_hr =
- ( $durAbsence > 0 ) ? GUEST_sec2time($durAbsence) : "00:00:00";
- my $durAbsence_cr =
- ( $durAbsence > 60 ) ? int( $durAbsence / 60 + 0.5 ) : 0;
- my $durSleep_hr =
- ( $durSleep > 0 ) ? GUEST_sec2time($durSleep) : "00:00:00";
- my $durSleep_cr = ( $durSleep > 60 ) ? int( $durSleep / 60 + 0.5 ) : 0;
+ my $durPresence_hr =
+ ( $durPresence > 0 ) ? GUEST_sec2time($durPresence) : "00:00:00";
+ my $durPresence_cr =
+ ( $durPresence > 60 ) ? int( $durPresence / 60 + 0.5 ) : 0;
+ my $durAbsence_hr =
+ ( $durAbsence > 0 ) ? GUEST_sec2time($durAbsence) : "00:00:00";
+ my $durAbsence_cr =
+ ( $durAbsence > 60 ) ? int( $durAbsence / 60 + 0.5 ) : 0;
+ my $durSleep_hr =
+ ( $durSleep > 0 ) ? GUEST_sec2time($durSleep) : "00:00:00";
+ my $durSleep_cr = ( $durSleep > 60 ) ? int( $durSleep / 60 + 0.5 ) : 0;
- readingsBeginUpdate($hash) if ( !$silent );
- readingsBulkUpdate( $hash, "durTimerPresence_cr", $durPresence_cr )
- if ( !defined( $hash->{READINGS}{durTimerPresence_cr}{VAL} )
- || $hash->{READINGS}{durTimerPresence_cr}{VAL} ne $durPresence_cr );
- readingsBulkUpdate( $hash, "durTimerPresence", $durPresence_hr )
- if ( !defined( $hash->{READINGS}{durTimerPresence}{VAL} )
- || $hash->{READINGS}{durTimerPresence}{VAL} ne $durPresence_hr );
- readingsBulkUpdate( $hash, "durTimerAbsence_cr", $durAbsence_cr )
- if ( !defined( $hash->{READINGS}{durTimerAbsence_cr}{VAL} )
- || $hash->{READINGS}{durTimerAbsence_cr}{VAL} ne $durAbsence_cr );
- readingsBulkUpdate( $hash, "durTimerAbsence", $durAbsence_hr )
- if ( !defined( $hash->{READINGS}{durTimerAbsence}{VAL} )
- || $hash->{READINGS}{durTimerAbsence}{VAL} ne $durAbsence_hr );
- readingsBulkUpdate( $hash, "durTimerSleep_cr", $durSleep_cr )
- if ( !defined( $hash->{READINGS}{durTimerSleep_cr}{VAL} )
- || $hash->{READINGS}{durTimerSleep_cr}{VAL} ne $durSleep_cr );
- readingsBulkUpdate( $hash, "durTimerSleep", $durSleep_hr )
- if ( !defined( $hash->{READINGS}{durTimerSleep}{VAL} )
- || $hash->{READINGS}{durTimerSleep}{VAL} ne $durSleep_hr );
- readingsEndUpdate( $hash, 1 ) if ( !$silent );
- }
+ readingsBeginUpdate($hash) if ( !$silent );
+ readingsBulkUpdate( $hash, "durTimerPresence_cr", $durPresence_cr )
+ if ( !defined( $hash->{READINGS}{durTimerPresence_cr}{VAL} )
+ || $hash->{READINGS}{durTimerPresence_cr}{VAL} ne $durPresence_cr );
+ readingsBulkUpdate( $hash, "durTimerPresence", $durPresence_hr )
+ if ( !defined( $hash->{READINGS}{durTimerPresence}{VAL} )
+ || $hash->{READINGS}{durTimerPresence}{VAL} ne $durPresence_hr );
+ readingsBulkUpdate( $hash, "durTimerAbsence_cr", $durAbsence_cr )
+ if ( !defined( $hash->{READINGS}{durTimerAbsence_cr}{VAL} )
+ || $hash->{READINGS}{durTimerAbsence_cr}{VAL} ne $durAbsence_cr );
+ readingsBulkUpdate( $hash, "durTimerAbsence", $durAbsence_hr )
+ if ( !defined( $hash->{READINGS}{durTimerAbsence}{VAL} )
+ || $hash->{READINGS}{durTimerAbsence}{VAL} ne $durAbsence_hr );
+ readingsBulkUpdate( $hash, "durTimerSleep_cr", $durSleep_cr )
+ if ( !defined( $hash->{READINGS}{durTimerSleep_cr}{VAL} )
+ || $hash->{READINGS}{durTimerSleep_cr}{VAL} ne $durSleep_cr );
+ readingsBulkUpdate( $hash, "durTimerSleep", $durSleep_hr )
+ if ( !defined( $hash->{READINGS}{durTimerSleep}{VAL} )
+ || $hash->{READINGS}{durTimerSleep}{VAL} ne $durSleep_hr );
+ readingsEndUpdate( $hash, 1 ) if ( !$silent );
+ }
GUEST_InternalTimer( "DurationTimer", $timestampNow + 60,
"GUEST_DurationTimer", $hash, 1 )
@@ -987,6 +1091,9 @@ sub GUEST_StartInternalTimers($$) {
state home,gotosleep,asleep,awoken,absent,none switch between states; see attribute rg_states to adjust list shown in FHEMWEB
+
+ create wakeuptimer add several pre-configurations provided by RESIDENTS Toolkit. See separate section in RESIDENTS module commandref for details.
+
@@ -1257,6 +1364,9 @@ sub GUEST_StartInternalTimers($$) {
state home,gotosleep,asleep,awoken,absent,gone wechselt den Status; siehe auch Attribut rg_states, um die in FHEMWEB angezeigte Liste anzupassen
+
+ create wakeuptimer fügt diverse Vorkonfigurationen auf Basis von RESIDENTS Toolkit hinzu. Siehe separate Sektion in der RESIDENTS Modul Kommandoreferenz.
+
diff --git a/fhem/FHEM/20_ROOMMATE.pm b/fhem/FHEM/20_ROOMMATE.pm
old mode 100755
new mode 100644
index 775e8fbfc..552b66c4d
--- a/fhem/FHEM/20_ROOMMATE.pm
+++ b/fhem/FHEM/20_ROOMMATE.pm
@@ -23,9 +23,12 @@
# along with fhem. If not, see .
#
#
-# Version: 1.1.0
+# Version: 1.2.0
#
# Major Version History:
+# - 1.2.0 - 2015-03-11
+# -- add RESIDENTStoolkit support
+#
# - 1.1.0 - 2014-04-07
# -- new readings in computer readable format (*_cr)
# -- format of readings durTimer readings changed from minutes to HH:MM:ss
@@ -41,9 +44,11 @@ use strict;
use warnings;
use Time::Local;
use Data::Dumper;
+require RESIDENTStk;
sub ROOMMATE_Set($@);
sub ROOMMATE_Define($$);
+sub ROOMMATE_Notify($$);
sub ROOMMATE_Undefine($$);
###################################
@@ -52,11 +57,12 @@ sub ROOMMATE_Initialize($) {
Log3 $hash, 5, "ROOMMATE_Initialize: Entering";
- $hash->{SetFn} = "ROOMMATE_Set";
- $hash->{DefFn} = "ROOMMATE_Define";
- $hash->{UndefFn} = "ROOMMATE_Undefine";
+ $hash->{SetFn} = "ROOMMATE_Set";
+ $hash->{DefFn} = "ROOMMATE_Define";
+ $hash->{NotifyFn} = "ROOMMATE_Notify";
+ $hash->{UndefFn} = "ROOMMATE_Undefine";
$hash->{AttrList} =
-"rr_locationHome rr_locationWayhome rr_locationUnderway rr_autoGoneAfter:12,16,24,26,28,30,36,48,60 rr_showAllStates:0,1 rr_realname:group,alias rr_states rr_locations rr_moods rr_moodDefault rr_moodSleepy rr_passPresenceTo rr_noDuration:0,1 "
+"rr_locationHome rr_locationWayhome rr_locationUnderway rr_autoGoneAfter:12,16,24,26,28,30,36,48,60 rr_showAllStates:0,1 rr_realname:group,alias rr_states rr_locations rr_moods rr_moodDefault rr_moodSleepy rr_passPresenceTo rr_noDuration:0,1 rr_wakeupDevice "
. $readingFnAttributes;
}
@@ -135,16 +141,17 @@ sub ROOMMATE_Define($$) {
$groupname =~ s/^rr_//;
$attr{$name}{group} = $groupname;
- $attr{$name}{alias} = "Status";
- $attr{$name}{devStateIcon} =
+ $attr{$name}{alias} = "Status";
+ $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";
- $attr{$name}{icon} = "people_sensor";
- $attr{$name}{rr_realname} = "alias";
- $attr{$name}{sortby} = "1";
- $attr{$name}{webCmd} = "state";
+ $attr{$name}{icon} = "people_sensor";
+ $attr{$name}{rr_realname} = "alias";
+ $attr{$name}{sortby} = "1";
+ $attr{$name}{webCmd} = "state";
- $attr{$name}{room} = $attr{ $registeredResidentgroups[0] }{room}
- if (@registeredResidentgroups && exists($attr{$registeredResidentgroups[0]}{room}));
+ $attr{$name}{room} = $attr{ $registeredResidentgroups[0] }{room}
+ if ( @registeredResidentgroups
+ && exists( $attr{ $registeredResidentgroups[0] }{room} ) );
}
# trigger for modified objects
@@ -190,6 +197,45 @@ sub ROOMMATE_Undefine($$) {
return undef;
}
+###################################
+sub ROOMMATE_Notify($$) {
+ my ( $hash, $dev ) = @_;
+ my $devName = $dev->{NAME};
+ my $hashName = $hash->{NAME};
+ my $hashName_attr;
+
+ # process child notifies
+ if ( $devName ne $hashName ) {
+ my @registeredWakeupdevs =
+ split( /,/, $attr{$hashName}{rr_wakeupDevice} )
+ if ( defined( $attr{$hashName}{rr_wakeupDevice} )
+ && $attr{$hashName}{rr_wakeupDevice} ne "" );
+
+ # process only registered devices for wakeup function
+ if ( @registeredWakeupdevs && $devName ~~ @registeredWakeupdevs ) {
+
+ return
+ if ( !$dev->{CHANGED} ); # Some previous notify deleted the array.
+
+ 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";
+
+ return RESIDENTStk_wakeupSet( $devName, $change );
+ }
+ }
+ }
+ }
+
+ return;
+}
+
###################################
sub ROOMMATE_Set($@) {
my ( $hash, @a ) = @_;
@@ -258,10 +304,9 @@ sub ROOMMATE_Set($@) {
$usage .= " state:$states";
$usage .= " mood:$moods";
$usage .= " location$locations";
+ $usage .= " create:wakeuptimer";
-# $usage .=
-#" create:wuTimerWd,wuTimerWe,wuTimerMon,wuTimerTue,wuTimerWed,wuTimerThu,wuTimerFri,wuTimerSat,wuTimerSun";
-# $usage .= " compactMode:noArg largeMode:noArg";
+ # $usage .= " compactMode:noArg largeMode:noArg";
# silentSet
if ( $a[1] eq "silentSet" ) {
@@ -646,6 +691,61 @@ sub ROOMMATE_Set($@) {
}
}
+ # create
+ elsif ( $a[1] eq "create" ) {
+ if ( defined( $a[2] ) && $a[2] eq "wakeuptimer" ) {
+ my $i = "1";
+ my $wakeuptimerName = $name . "_wakeuptimer" . $i;
+ my $created = 0;
+
+ until ($created) {
+ if ( defined( $defs{$wakeuptimerName} ) ) {
+ $i++;
+ $wakeuptimerName = $name . "_wakeuptimer" . $i;
+ }
+ else {
+
+ # create new dummy device
+ fhem "define $wakeuptimerName dummy";
+ fhem "attr $wakeuptimerName alias Wake-up Timer $i";
+ fhem "attr $wakeuptimerName comment Auto-created by ROOMMATE module for use with RESIDENTS Toolkit";
+ fhem
+"attr $wakeuptimerName devStateIcon OFF:general_aus\@red .*:general_an\@green:OFF";
+ fhem "attr $wakeuptimerName group " . $attr{$name}{group}
+ if ( defined( $attr{$name}{group} ) );
+ fhem "attr $wakeuptimerName icon time_clock";
+ fhem "attr $wakeuptimerName room " . $attr{$name}{room}
+ if ( defined( $attr{$name}{room} ) );
+ 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";
+ fhem "attr $wakeuptimerName userattr wakeupUserdevice";
+ fhem "attr $wakeuptimerName wakeupUserdevice $name";
+ fhem "attr $wakeuptimerName webCmd state";
+
+ # register slave device
+ if ( defined( $attr{$name}{rr_wakeupDevice} ) ) {
+ fhem "attr $name rr_wakeupDevice "
+ . $attr{$name}{rr_wakeupDevice}
+ . ",$wakeuptimerName";
+ }
+ else {
+ fhem "attr $name rr_wakeupDevice $wakeuptimerName";
+ }
+
+ # trigger first update
+ fhem "set $wakeuptimerName OFF";
+
+ $created = 1;
+ return
+"Dummy $wakeuptimerName and other pending devices created and pre-configured. You may edit Macro_$wakeuptimerName to define your wake-up actions.";
+ }
+ }
+ }
+ else {
+ return "Invalid 2nd argument, choose one of wakeuptimer ";
+ }
+ }
+
# return usage hint
else {
return $usage;
@@ -717,82 +817,85 @@ sub ROOMMATE_DurationTimer($;$) {
ROOMMATE_RemoveInternalTimer( "DurationTimer", $hash );
- if ( !defined($attr{$name}{rr_noDuration}) || $attr{$name}{rr_noDuration} == 0 ) {
+ if ( !defined( $attr{$name}{rr_noDuration} )
+ || $attr{$name}{rr_noDuration} == 0 )
+ {
- # presence timer
- if ( defined( $hash->{READINGS}{presence}{VAL} )
- && $hash->{READINGS}{presence}{VAL} eq "present" )
- {
- if ( defined( $hash->{READINGS}{lastArrival}{VAL} )
- && $hash->{READINGS}{lastArrival}{VAL} ne "-" )
- {
- $durPresence =
- $timestampNow -
- ROOMMATE_Datetime2Timestamp(
- $hash->{READINGS}{lastArrival}{VAL} );
- }
- }
+ # presence timer
+ if ( defined( $hash->{READINGS}{presence}{VAL} )
+ && $hash->{READINGS}{presence}{VAL} eq "present" )
+ {
+ if ( defined( $hash->{READINGS}{lastArrival}{VAL} )
+ && $hash->{READINGS}{lastArrival}{VAL} ne "-" )
+ {
+ $durPresence =
+ $timestampNow -
+ ROOMMATE_Datetime2Timestamp(
+ $hash->{READINGS}{lastArrival}{VAL} );
+ }
+ }
- # absence timer
- if ( defined( $hash->{READINGS}{presence}{VAL} )
- && $hash->{READINGS}{presence}{VAL} eq "absent" )
- {
- if ( defined( $hash->{READINGS}{lastDeparture}{VAL} )
- && $hash->{READINGS}{lastDeparture}{VAL} ne "-" )
- {
- $durAbsence =
- $timestampNow -
- ROOMMATE_Datetime2Timestamp(
- $hash->{READINGS}{lastDeparture}{VAL} );
- }
- }
+ # absence timer
+ if ( defined( $hash->{READINGS}{presence}{VAL} )
+ && $hash->{READINGS}{presence}{VAL} eq "absent" )
+ {
+ if ( defined( $hash->{READINGS}{lastDeparture}{VAL} )
+ && $hash->{READINGS}{lastDeparture}{VAL} ne "-" )
+ {
+ $durAbsence =
+ $timestampNow -
+ ROOMMATE_Datetime2Timestamp(
+ $hash->{READINGS}{lastDeparture}{VAL} );
+ }
+ }
- # sleep timer
- if ( defined( $hash->{READINGS}{state}{VAL} )
- && $hash->{READINGS}{state}{VAL} eq "asleep" )
- {
- if ( defined( $hash->{READINGS}{lastSleep}{VAL} )
- && $hash->{READINGS}{lastSleep}{VAL} ne "-" )
- {
- $durSleep =
- $timestampNow -
- ROOMMATE_Datetime2Timestamp( $hash->{READINGS}{lastSleep}{VAL} );
- }
- }
+ # sleep timer
+ if ( defined( $hash->{READINGS}{state}{VAL} )
+ && $hash->{READINGS}{state}{VAL} eq "asleep" )
+ {
+ if ( defined( $hash->{READINGS}{lastSleep}{VAL} )
+ && $hash->{READINGS}{lastSleep}{VAL} ne "-" )
+ {
+ $durSleep =
+ $timestampNow -
+ ROOMMATE_Datetime2Timestamp(
+ $hash->{READINGS}{lastSleep}{VAL} );
+ }
+ }
- my $durPresence_hr =
- ( $durPresence > 0 ) ? ROOMMATE_sec2time($durPresence) : "00:00:00";
- my $durPresence_cr =
- ( $durPresence > 60 ) ? int( $durPresence / 60 + 0.5 ) : 0;
- my $durAbsence_hr =
- ( $durAbsence > 0 ) ? ROOMMATE_sec2time($durAbsence) : "00:00:00";
- my $durAbsence_cr =
- ( $durAbsence > 60 ) ? int( $durAbsence / 60 + 0.5 ) : 0;
- my $durSleep_hr =
- ( $durSleep > 0 ) ? ROOMMATE_sec2time($durSleep) : "00:00:00";
- my $durSleep_cr = ( $durSleep > 60 ) ? int( $durSleep / 60 + 0.5 ) : 0;
+ my $durPresence_hr =
+ ( $durPresence > 0 ) ? ROOMMATE_sec2time($durPresence) : "00:00:00";
+ my $durPresence_cr =
+ ( $durPresence > 60 ) ? int( $durPresence / 60 + 0.5 ) : 0;
+ my $durAbsence_hr =
+ ( $durAbsence > 0 ) ? ROOMMATE_sec2time($durAbsence) : "00:00:00";
+ my $durAbsence_cr =
+ ( $durAbsence > 60 ) ? int( $durAbsence / 60 + 0.5 ) : 0;
+ my $durSleep_hr =
+ ( $durSleep > 0 ) ? ROOMMATE_sec2time($durSleep) : "00:00:00";
+ my $durSleep_cr = ( $durSleep > 60 ) ? int( $durSleep / 60 + 0.5 ) : 0;
- readingsBeginUpdate($hash) if ( !$silent );
- readingsBulkUpdate( $hash, "durTimerPresence_cr", $durPresence_cr )
- if ( !defined( $hash->{READINGS}{durTimerPresence_cr}{VAL} )
- || $hash->{READINGS}{durTimerPresence_cr}{VAL} ne $durPresence_cr );
- readingsBulkUpdate( $hash, "durTimerPresence", $durPresence_hr )
- if ( !defined( $hash->{READINGS}{durTimerPresence}{VAL} )
- || $hash->{READINGS}{durTimerPresence}{VAL} ne $durPresence_hr );
- readingsBulkUpdate( $hash, "durTimerAbsence_cr", $durAbsence_cr )
- if ( !defined( $hash->{READINGS}{durTimerAbsence_cr}{VAL} )
- || $hash->{READINGS}{durTimerAbsence_cr}{VAL} ne $durAbsence_cr );
- readingsBulkUpdate( $hash, "durTimerAbsence", $durAbsence_hr )
- if ( !defined( $hash->{READINGS}{durTimerAbsence}{VAL} )
- || $hash->{READINGS}{durTimerAbsence}{VAL} ne $durAbsence_hr );
- readingsBulkUpdate( $hash, "durTimerSleep_cr", $durSleep_cr )
- if ( !defined( $hash->{READINGS}{durTimerSleep_cr}{VAL} )
- || $hash->{READINGS}{durTimerSleep_cr}{VAL} ne $durSleep_cr );
- readingsBulkUpdate( $hash, "durTimerSleep", $durSleep_hr )
- if ( !defined( $hash->{READINGS}{durTimerSleep}{VAL} )
- || $hash->{READINGS}{durTimerSleep}{VAL} ne $durSleep_hr );
- readingsEndUpdate( $hash, 1 ) if ( !$silent );
- }
+ readingsBeginUpdate($hash) if ( !$silent );
+ readingsBulkUpdate( $hash, "durTimerPresence_cr", $durPresence_cr )
+ if ( !defined( $hash->{READINGS}{durTimerPresence_cr}{VAL} )
+ || $hash->{READINGS}{durTimerPresence_cr}{VAL} ne $durPresence_cr );
+ readingsBulkUpdate( $hash, "durTimerPresence", $durPresence_hr )
+ if ( !defined( $hash->{READINGS}{durTimerPresence}{VAL} )
+ || $hash->{READINGS}{durTimerPresence}{VAL} ne $durPresence_hr );
+ readingsBulkUpdate( $hash, "durTimerAbsence_cr", $durAbsence_cr )
+ if ( !defined( $hash->{READINGS}{durTimerAbsence_cr}{VAL} )
+ || $hash->{READINGS}{durTimerAbsence_cr}{VAL} ne $durAbsence_cr );
+ readingsBulkUpdate( $hash, "durTimerAbsence", $durAbsence_hr )
+ if ( !defined( $hash->{READINGS}{durTimerAbsence}{VAL} )
+ || $hash->{READINGS}{durTimerAbsence}{VAL} ne $durAbsence_hr );
+ readingsBulkUpdate( $hash, "durTimerSleep_cr", $durSleep_cr )
+ if ( !defined( $hash->{READINGS}{durTimerSleep_cr}{VAL} )
+ || $hash->{READINGS}{durTimerSleep_cr}{VAL} ne $durSleep_cr );
+ readingsBulkUpdate( $hash, "durTimerSleep", $durSleep_hr )
+ if ( !defined( $hash->{READINGS}{durTimerSleep}{VAL} )
+ || $hash->{READINGS}{durTimerSleep}{VAL} ne $durSleep_hr );
+ readingsEndUpdate( $hash, 1 ) if ( !$silent );
+ }
ROOMMATE_InternalTimer( "DurationTimer", $timestampNow + 60,
"ROOMMATE_DurationTimer", $hash, 1 );
@@ -970,6 +1073,9 @@ sub ROOMMATE_StartInternalTimers($$) {
state home,gotosleep,asleep,awoken,absent,gone switch between states; see attribute rr_states to adjust list shown in FHEMWEB
+
+ create wakeuptimer add several pre-configurations provided by RESIDENTS Toolkit. See separate section in RESIDENTS module commandref for details.
+
@@ -1240,6 +1346,9 @@ sub ROOMMATE_StartInternalTimers($$) {
state home,gotosleep,asleep,awoken,absent,gone wechselt den Status; siehe auch Attribut rr_states, um die in FHEMWEB angezeigte Liste anzupassen
+
+ create wakeuptimer fügt diverse Vorkonfigurationen auf Basis von RESIDENTS Toolkit hinzu. Siehe separate Sektion in der RESIDENTS Modul Kommandoreferenz.
+
diff --git a/fhem/FHEM/RESIDENTStk.pm b/fhem/FHEM/RESIDENTStk.pm
new file mode 100644
index 000000000..fb736116c
--- /dev/null
+++ b/fhem/FHEM/RESIDENTStk.pm
@@ -0,0 +1,210 @@
+# $Id$
+##############################################################################
+#
+# RESIDENTStk.pm
+# Additional functions for 10_RESIDENTS.pm, 20_ROOMMATE.pm, 20_GUEST.pm
+#
+# Copyright by Julian Pawlowski
+# e-mail: julian.pawlowski at gmail.com
+#
+# This file is part of fhem.
+#
+# Fhem is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# Fhem is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with fhem. If not, see .
+#
+#
+# Version: 1.0.0
+#
+# Version History:
+# - 1.0.0 - 2015-03-11
+# -- First release
+#
+##############################################################################
+
+#####################################
+# Enslave DUMMY device to be used for alarm clock
+#
+sub RESIDENTStk_wakeupSet($$) {
+ my ( $NAME, $VALUE ) = @_;
+ my $userattr = AttrVal( $NAME, "userattr", 0 );
+ my $autosave = AttrVal( $NAME, "wakeupAutosave", 0 );
+ my $wakeupMacro = AttrVal( $NAME, "wakeupMacro", 0 );
+ my $wakeupOffset = AttrVal( $NAME, "wakeupOffset", "0" );
+ my $room = AttrVal( $NAME, "room", "" );
+ my $atName = "at_" . $NAME;
+ my $macroName = "Macro_" . $NAME;
+
+ # check for required userattr attribute
+ my $userattributes =
+"wakeupOffset:slider,0,1,120 wakeupDefaultTime:time wakeupMacro wakeupUserdevice wakeupResetdays:multiple-strict,0,1,2,3,4,5,6 wakeupDays:multiple-strict,0,1,2,3,4,5,6 wakeupAutosave:1,0";
+ if ( !$userattr || $userattr ne $userattributes ) {
+ Log3 $NAME, 3,
+"RESIDENTStk $NAME: adjusting dummy device for required attribute userattr";
+ fhem "attr $NAME userattr $userattributes";
+ }
+
+ # check for required macro attribute
+ if ( !$wakeupMacro ) {
+ Log3 $NAME, 3,
+"RESIDENTStk $NAME: adjusting dummy device for required attribute wakeupMacro";
+ fhem "attr $NAME wakeupMacro $macroName";
+ $wakeupMacro = $macroName;
+ }
+
+ # check for existing macro
+ if ( !defined( $defs{$wakeupMacro} ) ) {
+ Log3 $NAME, 3,
+ "RESIDENTStk $NAME: new notify macro device $wakeupMacro created";
+ fhem "define $wakeupMacro notify $wakeupMacro {}";
+ if ($room) { fhem "attr $wakeupMacro room $room" }
+ }
+ elsif ( $defs{$wakeupMacro}{TYPE} ne "notify" ) {
+ Log3 $NAME, 3,
+"RESIDENTStk $NAME: WARNING - defined macro device '$wakeupMacro' is not a notify device!";
+ }
+
+ # check for required userdevice attribute
+ if ( !AttrVal( $NAME, "wakeupUserdevice", 0 ) ) {
+ Log3 $NAME, 3,
+"RESIDENTStk $NAME: WARNING - set attribute wakeupUserdevice before running wakeup function";
+ }
+
+ 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 ( !defined( $defs{$atName} ) ) {
+ Log3 $NAME, 3, "RESIDENTStk $NAME: $atName created and set to "
+ . sprintf( "%02d:%02d", $hour, $min );
+ fhem "define $atName at *"
+ . sprintf( "%02d:%02d", $hour, $min )
+ . " { RESIDENTStk_wakeupRun(\"$NAME\") }";
+ if ($room) { fhem "attr $atName room $room" }
+ }
+ elsif ( $defs{$atName}{TYPE} ne "at" ) {
+ Log3 $NAME, 3,
+"RESIDENTStk $NAME: WARNING - defined device '$atName' is not an at device!";
+ }
+ else {
+ Log3 $NAME, 4, "RESIDENTStk $NAME: $atName modified to "
+ . sprintf( "%02d:%02d", $hour, $min );
+ fhem "modify $atName *" . sprintf( "%02d:%02d", $hour, $min );
+ }
+ }
+ else {
+ Log3 $NAME, 4, "RESIDENTStk $NAME: alarm set to OFF";
+ }
+
+ # autosave
+ if ($autosave) { fhem "save" }
+
+ return undef;
+}
+
+#####################################
+# Use DUMMY device to run wakup event
+#
+sub RESIDENTStk_wakeupRun($) {
+ my ($NAME) = @_;
+
+ my $wakeupMacro = AttrVal( $NAME, "wakeupMacro", 0 );
+ my $wakeupDefaultTime = AttrVal( $NAME, "wakeupDefaultTime", 0 );
+ my $wakeupUserdevice = AttrVal( $NAME, "wakeupUserdevice", 0 );
+ my $wakeupDays = AttrVal( $NAME, "wakeupDays", 0 );
+ my $wakeupResetdays = AttrVal( $NAME, "wakeupResetdays", 0 );
+
+ my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
+ localtime(time);
+
+ my @days = ($wday);
+ if ($wakeupDays) {
+ @days = split /,/, $wakeupDays;
+ }
+
+ my @rdays = ($wday);
+ if ($wakeupResetdays) {
+ @rdays = split /,/, $wakeupResetdays;
+ }
+
+ if ( !defined( $defs{$NAME} ) ) {
+ Log3 $NAME, 3, "RESIDENTStk $NAME: Non existing device";
+ return "$NAME: Non existing device";
+ }
+ elsif ( ReadingsVal( $NAME, "state", "OFF" ) eq "OFF" ) {
+ Log3 $NAME, 4,
+ "RESIDENTStk $NAME: alarm set to OFF - not running any action";
+ return;
+ }
+ elsif ( !$wakeupUserdevice ) {
+ Log3 $NAME, 4, "RESIDENTStk $NAME: missing attribute wakeupUserdevice";
+ return "$NAME: missing attribute wakeupUserdevice";
+ }
+ elsif ( !defined( $defs{$wakeupUserdevice} ) ) {
+ Log3 $NAME, 4,
+ "RESIDENTStk $NAME: Non existing wakeupUserdevice $wakeupUserdevice";
+ return "$NAME: Non existing wakeupUserdevice $wakeupUserdevice";
+ }
+ elsif ($defs{$wakeupUserdevice}{TYPE} ne "ROOMMATE"
+ && $defs{$wakeupUserdevice}{TYPE} ne "GUEST" )
+ {
+ Log3 $NAME, 4,
+"RESIDENTStk $NAME: device $wakeupUserdevice is not of type ROOMMATE or GUEST";
+ return
+ "$NAME: device $wakeupUserdevice is not of type ROOMMATE or GUEST";
+ }
+ elsif ( $defs{$wakeupUserdevice}{TYPE} eq "GUEST"
+ && ReadingsVal( $wakeupUserdevice, "state", "" ) eq "none" )
+ {
+ fhem "set $NAME OFF";
+ return;
+ }
+ elsif ($wday ~~ @days
+ && ReadingsVal( $wakeupUserdevice, "state", "" ) ne "absent"
+ && ReadingsVal( $wakeupUserdevice, "state", "" ) ne "gone" )
+ {
+ if ( !$wakeupMacro ) {
+ Log3 $NAME, 2, "RESIDENTStk $NAME: missing attribute wakeupMacro";
+ return "$NAME: missing attribute wakeupMacro";
+ }
+ elsif ( !defined( $defs{$wakeupMacro} ) ) {
+ Log3 $NAME, 2,
+"RESIDENTStk $NAME: notify macro $wakeupMacro not found - no wakeup actions defined!";
+ return
+"$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";
+ return "$NAME: device $wakeupMacro is not of type notify";
+ }
+ else {
+ Log3 $NAME, 4, "RESIDENTStk $NAME: trigger $wakeupMacro";
+ fhem "trigger $wakeupMacro";
+ }
+ }
+
+ if ( $wakeupDefaultTime && $wday ~~ @rdays ) {
+ Log3 $NAME, 4,
+ "RESIDENTStk $NAME: Resetting based on wakeupDefaultTime";
+ fhem "set $NAME $wakeupDefaultTime";
+ }
+
+ return undef;
+}
+
+1;
diff --git a/fhem/HISTORY b/fhem/HISTORY
index 4b4d90953..685b40173 100644
--- a/fhem/HISTORY
+++ b/fhem/HISTORY
@@ -613,3 +613,7 @@
- Fri Jan 30 2015 (fhainz)
- added new module 70_Pushbullet
+
+- Wed Mar 11 2015 (loredo)
+ - added new RESIDENTS toolkit functions for RESIDENTS, ROOMMMATE and GUEST devices
+ first function: wakeuptimer
diff --git a/fhem/MAINTAINER.txt b/fhem/MAINTAINER.txt
index fae3307fa..5dc2c6737 100644
--- a/fhem/MAINTAINER.txt
+++ b/fhem/MAINTAINER.txt
@@ -302,6 +302,7 @@ FHEM/OWX_DS2480.pm ntruchsess http://forum.fhem.de 1Wire
FHEM/OWX_DS9097.pm ntruchsess http://forum.fhem.de 1Wire
FHEM/OWX_FRM.pm ntruchsess http://forum.fhem.de 1Wire
FHEM/OWX_SER.pm ntruchsess http://forum.fhem.de 1Wire
+FHEM/RESIDENTStk.pm loredo http://forum.fhem.de Automatisierung
FHEM/SetExtensions.pm rudolfkoenig http://forum.fhem.de Automatisierung
FHEM/SHC_datafields.pm rr2000 http://forum.fhem.de Sonstige Systeme
FHEM/SHC_parser.pm rr2000 http://forum.fhem.de Sonstige Systeme