2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

RESIDENTStk: Add RESIDENTS toolkit and wakeuptimer function

git-svn-id: https://svn.fhem.de/fhem/trunk@8194 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
jpawlowski 2015-03-11 14:16:05 +00:00
parent 6bf2621422
commit a35f2d79df
7 changed files with 792 additions and 183 deletions

View File

@ -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)

189
fhem/FHEM/10_RESIDENTS.pm Executable file → Normal file
View File

@ -23,9 +23,12 @@
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
#
#
# 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($) {
<li>
<b>state</b> &nbsp;&nbsp;home,gotosleep,asleep,awoken,absent,gone&nbsp;&nbsp; switch between states for all group members at once; see attribute rgr_states to adjust list shown in FHEMWEB
</li>
<li>
<b>create</b> &nbsp;&nbsp;wakeuptimer&nbsp;&nbsp; add several pre-configurations provided by RESIDENTS Toolkit. See separate section for details.
</li>
</ul>
</div><br>
<br>
@ -1069,6 +1159,45 @@ sub RESIDENTS_Datetime2Timestamp($) {
</li>
</ul>
</div>
<br>
<br>
<b>RESIDENTS Toolkit</b><br>
<div style="margin-left: 2em">
<ul>
Using set-command <code>create</code> you may add pre-configured configurations to your RESIDENTS, <a href="#ROOMMATE">ROOMMATE</a> or <a href="#GUEST">GUEST</a> devices for your convenience.<br>
The following commands are currently available:<br>
<br>
<li>
<b>wakeuptimer</b> &nbsp;&nbsp;-&nbsp;&nbsp; adds a wake-up timer dummy device with enhanced functions to start with wake-up automations
<ul>
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.<br>
<br>
The wake-up behaviour may be influenced by the following device attributes:<br>
<li>
<i>wakeupAutosave</i> - Triggers FHEM command 'save' after adjusting wake-up time value (defaults to 0=false)
</li>
<li>
<i>wakeupDays</i> - only trigger macro at these days. Mon=1,Tue=2,Wed=3,Thu=4,Fri=5,Sat=6,Sun=0 (optional)
</li>
<li>
<i>wakeupDefaultTime</i> - after triggering macro reset the wake-up time to this default value (optional)
</li>
<li>
<i>wakeupMacro</i> - name of the notify macro device (mandatory)
</li>
<li>
<i>wakeupOffset</i> - 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)
</li>
<li>
<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>
<i>wakeupUserdevice</i> - backlink to RESIDENTS, ROOMMATE or GUEST device to check it's status (mandatory)
</li>
</ul>
</li>
</ul>
</div>
</div>
=end html
@ -1117,6 +1246,9 @@ sub RESIDENTS_Datetime2Timestamp($) {
<li>
<b>state</b> &nbsp;&nbsp;home,gotosleep,asleep,awoken,absent,gone&nbsp;&nbsp; wechselt den Status für alle Gruppenmitglieder gleichzeitig; siehe Attribut rgr_states, um die angezeigte Liste in FHEMWEB abzuändern
</li>
<li>
<b>create</b> &nbsp;&nbsp;wakeuptimer&nbsp;&nbsp; f&uuml;gt diverse Vorkonfigurationen auf Basis von RESIDENTS Toolkit hinzu. Siehe separate Sektion.
</li>
</ul>
</div><br>
<br>
@ -1250,6 +1382,45 @@ sub RESIDENTS_Datetime2Timestamp($) {
</li>
</ul>
</div>
<br>
<br>
<b>RESIDENTS Toolkit</b><br>
<div style="margin-left: 2em">
<ul>
Mit dem set-Kommando <code>create</code> k&ouml;nnen zur Vereinfachung vorkonfigurierte Konfigurationen zu RESIDENTS, <a href="#ROOMMATE">ROOMMATE</a> oder <a href="#GUEST">GUEST</a> Ger&auml;ten hinzugef&uuml;gt werden.<br>
The folgenden Kommandos sind momentan verf&uuml;gbar:<br>
<br>
<li>
<b>wakeuptimer</b> &nbsp;&nbsp;-&nbsp;&nbsp; f&uuml;gt ein Dummy Ger&auml;t mit erweiterten Funktionen als Wecker hinzu, um darauf Weck-Automationen aufzubauen.
<ul>
Ein notify Ger&auml;t wird als Makro erstellt, um die eigentliche Automation auszuf&uuml;hren. Das Makro wird durch ein normales at-Ger&auml;t ausgel&ouml;st und kann ebenfalls angepasst werden. Die Hauptfunktion wird dabei trotzdem von einer speziellen RESIDENTS Toolkit funktion gehandhabt.<br>
<br>
Die Weckfunktion kann wie folgt &uuml;ber Attribute beinflusst werden:<br>
<li>
<i>wakeupAutosave</i> - L&ouml;st das FHEM Kommando 'save' nach einer &Auml;nderung der Weckzeit aus (Standard 0=aus)
</li>
<li>
<i>wakeupDays</i> - Makro nur an bestimmten Tagen ausl&ouml;sen. Mon=1,Di=2,Mi=3,Do=4,Fr=5,Sa=6,So=0 (optional)
</li>
<li>
<i>wakeupDefaultTime</i> - Stellt die Weckzeit nach dem ausl&ouml;sen zur&uuml;ck auf diesen Standardwert (optional)
</li>
<li>
<i>wakeupMacro</i> - Name des notify Makro Ger&auml;tes (notwendig)
</li>
<li>
<i>wakeupOffset</i> - Wert in Minuten, die das Makro fr&uuml;her ausgel&ouml;st werden soll, z.B. bei komplexen Weckprogrammen &uuml;ber einen Zeitraum von 30 Minuten (Standard ist 0)
</li>
<li>
<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>
<i>wakeupUserdevice</i> - Backlink zum RESIDENTS, ROOMMATE oder GUEST Ger&auml;t, um dessen Status zu pr&uuml;fen (notwendig)
</li>
</ul>
</li>
</ul>
</div>
</div>
=end html_DE

284
fhem/FHEM/20_GUEST.pm Executable file → Normal file
View File

@ -23,9 +23,12 @@
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
#
#
# 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($$) {
<li>
<b>state</b> &nbsp;&nbsp;home,gotosleep,asleep,awoken,absent,none&nbsp;&nbsp; switch between states; see attribute rg_states to adjust list shown in FHEMWEB
</li>
<li>
<b>create</b> &nbsp;&nbsp;wakeuptimer&nbsp;&nbsp; add several pre-configurations provided by RESIDENTS Toolkit. See separate section in <a href="#RESIDENTS">RESIDENTS module commandref</a> for details.
</li>
</ul>
</div><br>
<br>
@ -1257,6 +1364,9 @@ sub GUEST_StartInternalTimers($$) {
<li>
<b>state</b> &nbsp;&nbsp;home,gotosleep,asleep,awoken,absent,gone&nbsp;&nbsp; wechselt den Status; siehe auch Attribut rg_states, um die in FHEMWEB angezeigte Liste anzupassen
</li>
<li>
<b>create</b> &nbsp;&nbsp;wakeuptimer&nbsp;&nbsp; f&uuml;gt diverse Vorkonfigurationen auf Basis von RESIDENTS Toolkit hinzu. Siehe separate Sektion in der <a href="#RESIDENTS">RESIDENTS Modul Kommandoreferenz</a>.
</li>
</ul>
</div><br>
<br>

283
fhem/FHEM/20_ROOMMATE.pm Executable file → Normal file
View File

@ -23,9 +23,12 @@
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
#
#
# 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($$) {
<li>
<b>state</b> &nbsp;&nbsp;home,gotosleep,asleep,awoken,absent,gone&nbsp;&nbsp; switch between states; see attribute rr_states to adjust list shown in FHEMWEB
</li>
<li>
<b>create</b> &nbsp;&nbsp;wakeuptimer&nbsp;&nbsp; add several pre-configurations provided by RESIDENTS Toolkit. See separate section in <a href="#RESIDENTS">RESIDENTS module commandref</a> for details.
</li>
</ul>
</div><br>
<br>
@ -1240,6 +1346,9 @@ sub ROOMMATE_StartInternalTimers($$) {
<li>
<b>state</b> &nbsp;&nbsp;home,gotosleep,asleep,awoken,absent,gone&nbsp;&nbsp; wechselt den Status; siehe auch Attribut rr_states, um die in FHEMWEB angezeigte Liste anzupassen
</li>
<li>
<b>create</b> &nbsp;&nbsp;wakeuptimer&nbsp;&nbsp; f&uuml;gt diverse Vorkonfigurationen auf Basis von RESIDENTS Toolkit hinzu. Siehe separate Sektion in der <a href="#RESIDENTS">RESIDENTS Modul Kommandoreferenz</a>.
</li>
</ul>
</div><br />
<br />

210
fhem/FHEM/RESIDENTStk.pm Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
#
#
# 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;

View File

@ -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

View File

@ -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