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:
parent
6bf2621422
commit
a35f2d79df
@ -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
189
fhem/FHEM/10_RESIDENTS.pm
Executable file → Normal 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> 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
|
||||
</li>
|
||||
<li>
|
||||
<b>create</b> wakeuptimer 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> - 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> 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
|
||||
</li>
|
||||
<li>
|
||||
<b>create</b> wakeuptimer fü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önnen zur Vereinfachung vorkonfigurierte Konfigurationen zu RESIDENTS, <a href="#ROOMMATE">ROOMMATE</a> oder <a href="#GUEST">GUEST</a> Geräten hinzugefügt werden.<br>
|
||||
The folgenden Kommandos sind momentan verfügbar:<br>
|
||||
<br>
|
||||
<li>
|
||||
<b>wakeuptimer</b> - fügt ein Dummy Gerät mit erweiterten Funktionen als Wecker hinzu, um darauf Weck-Automationen aufzubauen.
|
||||
<ul>
|
||||
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.<br>
|
||||
<br>
|
||||
Die Weckfunktion kann wie folgt über Attribute beinflusst werden:<br>
|
||||
<li>
|
||||
<i>wakeupAutosave</i> - Löst das FHEM Kommando 'save' nach einer Änderung der Weckzeit aus (Standard 0=aus)
|
||||
</li>
|
||||
<li>
|
||||
<i>wakeupDays</i> - Makro nur an bestimmten Tagen auslö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ösen zurück auf diesen Standardwert (optional)
|
||||
</li>
|
||||
<li>
|
||||
<i>wakeupMacro</i> - Name des notify Makro Gerätes (notwendig)
|
||||
</li>
|
||||
<li>
|
||||
<i>wakeupOffset</i> - 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)
|
||||
</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ät, um dessen Status zu prüfen (notwendig)
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
=end html_DE
|
||||
|
284
fhem/FHEM/20_GUEST.pm
Executable file → Normal file
284
fhem/FHEM/20_GUEST.pm
Executable file → Normal 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> home,gotosleep,asleep,awoken,absent,none switch between states; see attribute rg_states to adjust list shown in FHEMWEB
|
||||
</li>
|
||||
<li>
|
||||
<b>create</b> wakeuptimer 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> home,gotosleep,asleep,awoken,absent,gone wechselt den Status; siehe auch Attribut rg_states, um die in FHEMWEB angezeigte Liste anzupassen
|
||||
</li>
|
||||
<li>
|
||||
<b>create</b> wakeuptimer fü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
283
fhem/FHEM/20_ROOMMATE.pm
Executable file → Normal 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> home,gotosleep,asleep,awoken,absent,gone switch between states; see attribute rr_states to adjust list shown in FHEMWEB
|
||||
</li>
|
||||
<li>
|
||||
<b>create</b> wakeuptimer 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> home,gotosleep,asleep,awoken,absent,gone wechselt den Status; siehe auch Attribut rr_states, um die in FHEMWEB angezeigte Liste anzupassen
|
||||
</li>
|
||||
<li>
|
||||
<b>create</b> wakeuptimer fü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
210
fhem/FHEM/RESIDENTStk.pm
Normal 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;
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user