mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +00:00
add new modules 10_RESIDENTS, 20_ROOMMATE, 20_GUEST
git-svn-id: https://svn.fhem.de/fhem/trunk@4852 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
100eebe0b0
commit
32d4b49cc8
@ -1,6 +1,7 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# 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.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
- SVN
|
- SVN
|
||||||
|
- feature: new modules 10_RESIDENTS, 20_ROOMMATE and 20_GUEST added (loredo)
|
||||||
- feature: LUXTRONIK2: attribute 'doStatistics' calculates boiler gradients
|
- feature: LUXTRONIK2: attribute 'doStatistics' calculates boiler gradients
|
||||||
- feature: GEOFANCY: support both apps, Geofency.app and Geofancy.app
|
- feature: GEOFANCY: support both apps, Geofency.app and Geofancy.app
|
||||||
- feature: LightScene: added attribute lightSceneRestoreOnlyIfChanged
|
- feature: LightScene: added attribute lightSceneRestoreOnlyIfChanged
|
||||||
|
991
fhem/FHEM/10_RESIDENTS.pm
Normal file
991
fhem/FHEM/10_RESIDENTS.pm
Normal file
@ -0,0 +1,991 @@
|
|||||||
|
# $Id$
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# 10_RESIDENTS.pm
|
||||||
|
# An FHEM Perl module to ease resident administration.
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
# Major Version History:
|
||||||
|
# - 1.0.0 - 2014-02-08
|
||||||
|
# -- First release
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
package main;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Time::Local;
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
|
sub RESIDENTS_Set($@);
|
||||||
|
sub RESIDENTS_Define($$);
|
||||||
|
sub RESIDENTS_Notify($$);
|
||||||
|
sub RESIDENTS_Undefine($$);
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub RESIDENTS_Initialize($) {
|
||||||
|
my ($hash) = @_;
|
||||||
|
|
||||||
|
Log3 $hash, 5, "RESIDENTS_Initialize: Entering";
|
||||||
|
|
||||||
|
$hash->{SetFn} = "RESIDENTS_Set";
|
||||||
|
$hash->{DefFn} = "RESIDENTS_Define";
|
||||||
|
$hash->{NotifyFn} = "RESIDENTS_Notify";
|
||||||
|
$hash->{UndefFn} = "RESIDENTS_Undefine";
|
||||||
|
$hash->{AttrList} =
|
||||||
|
"rgr_showAllStates:0,1 rgr_states " . $readingFnAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub RESIDENTS_Define($$) {
|
||||||
|
my ( $hash, $def ) = @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my $name_attr;
|
||||||
|
|
||||||
|
Log3 $name, 5, "RESIDENTS $name: called function RESIDENTS_Define()";
|
||||||
|
|
||||||
|
$hash->{TYPE} = "RESIDENTS";
|
||||||
|
|
||||||
|
# attr alias
|
||||||
|
$name_attr = "alias";
|
||||||
|
unless ( exists( $attr{$name}{$name_attr} ) ) {
|
||||||
|
$attr{$name}{$name_attr} = "Residents";
|
||||||
|
}
|
||||||
|
|
||||||
|
# attr devStateIcon
|
||||||
|
$name_attr = "devStateIcon";
|
||||||
|
unless ( exists( $attr{$name}{$name_attr} ) ) {
|
||||||
|
$attr{$name}{$name_attr} =
|
||||||
|
'.*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 group
|
||||||
|
$name_attr = "group";
|
||||||
|
unless ( exists( $attr{$name}{$name_attr} ) ) {
|
||||||
|
$attr{$name}{$name_attr} = "Home State";
|
||||||
|
}
|
||||||
|
|
||||||
|
# attr icon
|
||||||
|
$name_attr = "icon";
|
||||||
|
unless ( exists( $attr{$name}{$name_attr} ) ) {
|
||||||
|
$attr{$name}{$name_attr} = "control_building_filled";
|
||||||
|
}
|
||||||
|
|
||||||
|
# attr room
|
||||||
|
$name_attr = "room";
|
||||||
|
unless ( exists( $attr{$name}{$name_attr} ) ) {
|
||||||
|
$attr{$name}{$name_attr} = "Residents";
|
||||||
|
}
|
||||||
|
|
||||||
|
# attr webCmd
|
||||||
|
$name_attr = "webCmd";
|
||||||
|
unless ( exists( $attr{$name}{$name_attr} ) ) {
|
||||||
|
$attr{$name}{$name_attr} = "state";
|
||||||
|
}
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub RESIDENTS_Undefine($$) {
|
||||||
|
my ( $hash, $name ) = @_;
|
||||||
|
|
||||||
|
# delete child roommates
|
||||||
|
if ( defined( $hash->{ROOMMATES} )
|
||||||
|
&& $hash->{ROOMMATES} ne "" )
|
||||||
|
{
|
||||||
|
my @registeredRoommates =
|
||||||
|
split( /,/, $hash->{ROOMMATES} );
|
||||||
|
|
||||||
|
foreach my $child (@registeredRoommates) {
|
||||||
|
fhem( "delete " . $child );
|
||||||
|
Log3 $name, 3, "RESIDENTS $name: deleted device $child";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# delete child guests
|
||||||
|
if ( defined( $hash->{GUESTS} )
|
||||||
|
&& $hash->{GUESTS} ne "" )
|
||||||
|
{
|
||||||
|
my @registeredGuests =
|
||||||
|
split( /,/, $hash->{GUESTS} );
|
||||||
|
|
||||||
|
foreach my $child (@registeredGuests) {
|
||||||
|
fhem( "delete " . $child );
|
||||||
|
Log3 $name, 3, "RESIDENTS $name: deleted device $child";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub RESIDENTS_Notify($$) {
|
||||||
|
my ( $hash, $dev ) = @_;
|
||||||
|
my $devName = $dev->{NAME};
|
||||||
|
my $hashName = $hash->{NAME};
|
||||||
|
my $hashName_attr;
|
||||||
|
|
||||||
|
# process child notifies
|
||||||
|
if ( $devName ne $hashName ) {
|
||||||
|
my @registeredRoommates =
|
||||||
|
split( /,/, $hash->{ROOMMATES} )
|
||||||
|
if ( defined( $hash->{ROOMMATES} )
|
||||||
|
&& $hash->{ROOMMATES} ne "" );
|
||||||
|
|
||||||
|
my @registeredGuests =
|
||||||
|
split( /,/, $hash->{GUESTS} )
|
||||||
|
if ( defined( $hash->{GUESTS} )
|
||||||
|
&& $hash->{GUESTS} ne "" );
|
||||||
|
|
||||||
|
# process only registered ROOMMATE or GUEST devices
|
||||||
|
if ( ( @registeredRoommates && $devName ~~ @registeredRoommates )
|
||||||
|
|| ( @registeredGuests && $devName ~~ @registeredGuests ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
return
|
||||||
|
if ( !$dev->{CHANGED} ); # Some previous notify deleted the array.
|
||||||
|
|
||||||
|
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
||||||
|
|
||||||
|
# state changed
|
||||||
|
if ( $change !~ /:/ || $change =~ /wayhome:/ ) {
|
||||||
|
Log3 $hash, 4,
|
||||||
|
"RESIDENTS "
|
||||||
|
. $hashName . ": "
|
||||||
|
. $devName
|
||||||
|
. ": notify about change to $change";
|
||||||
|
|
||||||
|
RESIDENTS_UpdateReadings($hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
# activity
|
||||||
|
if ( $change !~ /:/ ) {
|
||||||
|
|
||||||
|
# get user realname
|
||||||
|
my $realnamesrc = (
|
||||||
|
defined( $attr{$devName}{rr_realname} )
|
||||||
|
&& $attr{$devName}{rr_realname} ne ""
|
||||||
|
? $attr{$devName}{rr_realname}
|
||||||
|
: "group"
|
||||||
|
);
|
||||||
|
my $realname = (
|
||||||
|
defined( $attr{$devName}{$realnamesrc} )
|
||||||
|
&& $attr{$devName}{$realnamesrc} ne ""
|
||||||
|
? $attr{$devName}{$realnamesrc}
|
||||||
|
: $devName
|
||||||
|
);
|
||||||
|
|
||||||
|
# update statistics
|
||||||
|
readingsBeginUpdate($hash);
|
||||||
|
readingsBulkUpdate( $hash, "lastActivity", $change );
|
||||||
|
readingsBulkUpdate( $hash, "lastActivityBy", $realname );
|
||||||
|
readingsEndUpdate( $hash, 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
|
sub RESIDENTS_Set($@) {
|
||||||
|
my ( $hash, @a ) = @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my $state =
|
||||||
|
( defined( $hash->{READINGS}{state}{VAL} ) )
|
||||||
|
? $hash->{READINGS}{state}{VAL}
|
||||||
|
: "initialized";
|
||||||
|
my $roommates = ( $hash->{ROOMMATES} ? $hash->{ROOMMATES} : "" );
|
||||||
|
my $guests = ( $hash->{GUESTS} ? $hash->{GUESTS} : "" );
|
||||||
|
|
||||||
|
Log3 $name, 5, "RESIDENTS $name: called function RESIDENTS_Set()";
|
||||||
|
|
||||||
|
return "No Argument given" if ( !defined( $a[1] ) );
|
||||||
|
|
||||||
|
# states
|
||||||
|
my $states = (
|
||||||
|
defined( $attr{$name}{rgr_states} ) ? $attr{$name}{rgr_states}
|
||||||
|
: (
|
||||||
|
defined( $attr{$name}{rgr_showAllStates} )
|
||||||
|
&& $attr{$name}{rgr_showAllStates} == 1
|
||||||
|
? "home,gotosleep,asleep,awoken,absent,gone"
|
||||||
|
: "home,gotosleep,absent,gone"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$states = $state . "," . $states
|
||||||
|
if ( $state ne "initialized" && $states !~ /$state/ );
|
||||||
|
|
||||||
|
my $usage =
|
||||||
|
"Unknown argument " . $a[1] . ", choose one of addRoommate addGuest";
|
||||||
|
$usage .= " state:$states";
|
||||||
|
$usage .= " removeRoommate:" . $roommates if ( $roommates ne "" );
|
||||||
|
$usage .= " removeGuest:" . $guests if ( $guests ne "" );
|
||||||
|
|
||||||
|
# states
|
||||||
|
if ( $a[1] eq "state"
|
||||||
|
|| $a[1] eq "home"
|
||||||
|
|| $a[1] eq "gotosleep"
|
||||||
|
|| $a[1] eq "asleep"
|
||||||
|
|| $a[1] eq "awoken"
|
||||||
|
|| $a[1] eq "absent"
|
||||||
|
|| $a[1] eq "gone" )
|
||||||
|
{
|
||||||
|
my $newstate;
|
||||||
|
my $presence = "absent";
|
||||||
|
|
||||||
|
# if not direct
|
||||||
|
if (
|
||||||
|
$a[1] eq "state"
|
||||||
|
&& defined( $a[2] )
|
||||||
|
&& ( $a[2] eq "home"
|
||||||
|
|| $a[2] eq "gotosleep"
|
||||||
|
|| $a[2] eq "asleep"
|
||||||
|
|| $a[2] eq "awoken"
|
||||||
|
|| $a[2] eq "absent"
|
||||||
|
|| $a[2] eq "gone" )
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$newstate = $a[2];
|
||||||
|
}
|
||||||
|
elsif ( defined( $a[2] ) ) {
|
||||||
|
return
|
||||||
|
"Invalid 2nd argument, choose one of home gotosleep asleep awoken absent gone ";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$newstate = $a[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Log3 $name, 2, "RESIDENTS set $name " . $newstate;
|
||||||
|
|
||||||
|
# loop through every roommate
|
||||||
|
if ( defined( $hash->{ROOMMATES} )
|
||||||
|
&& $hash->{ROOMMATES} ne "" )
|
||||||
|
{
|
||||||
|
my @registeredRoommates =
|
||||||
|
split( /,/, $hash->{ROOMMATES} );
|
||||||
|
|
||||||
|
foreach my $roommate (@registeredRoommates) {
|
||||||
|
if ( defined( $defs{$roommate} )
|
||||||
|
&& $defs{$roommate}{READINGS}{state} ne $newstate )
|
||||||
|
{
|
||||||
|
fhem "set $roommate silentSet state $newstate";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# loop through every guest
|
||||||
|
if ( defined( $hash->{GUESTS} )
|
||||||
|
&& $hash->{GUESTS} ne "" )
|
||||||
|
{
|
||||||
|
$newstate = "none" if ( $newstate eq "gone" );
|
||||||
|
|
||||||
|
my @registeredGuests =
|
||||||
|
split( /,/, $hash->{GUESTS} );
|
||||||
|
|
||||||
|
foreach my $guest (@registeredGuests) {
|
||||||
|
if ( defined( $defs{$guest} )
|
||||||
|
&& $defs{$guest}{READINGS}{state}{VAL} ne "none"
|
||||||
|
&& $defs{$guest}{READINGS}{state}{VAL} ne $newstate )
|
||||||
|
{
|
||||||
|
fhem "set $guest silentSet state $newstate";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# addRoommate
|
||||||
|
elsif ( $a[1] eq "addRoommate" ) {
|
||||||
|
Log3 $name, 2, "RESIDENTS set $name " . $a[1] . " " . $a[2]
|
||||||
|
if ( defined( $a[2] ) );
|
||||||
|
|
||||||
|
my $rr_name;
|
||||||
|
my $rr_name_attr;
|
||||||
|
|
||||||
|
if ( $a[2] ne "" ) {
|
||||||
|
$rr_name = "rr_" . $a[2];
|
||||||
|
|
||||||
|
# define roommate
|
||||||
|
if ( !defined( $defs{$rr_name} ) ) {
|
||||||
|
fhem( "define " . $rr_name . " ROOMMATE " . $name );
|
||||||
|
if ( defined( $defs{$rr_name} ) ) {
|
||||||
|
fhem "set $rr_name silentSet state home";
|
||||||
|
Log3 $name, 3,
|
||||||
|
"RESIDENTS $name: created new device $rr_name";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "Can't create, device $rr_name already existing.";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "No Argument given, choose one of name ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# removeRoommate
|
||||||
|
elsif ( $a[1] eq "removeRoommate" ) {
|
||||||
|
Log3 $name, 2, "RESIDENTS set $name " . $a[1] . " " . $a[2]
|
||||||
|
if ( defined( $a[2] ) );
|
||||||
|
|
||||||
|
if ( $a[2] ne "" ) {
|
||||||
|
my $rr_name = $a[2];
|
||||||
|
|
||||||
|
# delete roommate
|
||||||
|
if ( defined( $defs{$rr_name} ) ) {
|
||||||
|
Log3 $name, 3, "RESIDENTS $name: deleted device $rr_name"
|
||||||
|
if fhem( "delete " . $rr_name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "No Argument given, choose one of name ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# addGuest
|
||||||
|
elsif ( $a[1] eq "addGuest" ) {
|
||||||
|
Log3 $name, 2, "RESIDENTS set $name " . $a[1] . " " . $a[2]
|
||||||
|
if ( defined( $a[2] ) );
|
||||||
|
|
||||||
|
my $rg_name;
|
||||||
|
my $rg_name_attr;
|
||||||
|
|
||||||
|
if ( $a[2] ne "" ) {
|
||||||
|
$rg_name = "rg_" . $a[2];
|
||||||
|
|
||||||
|
# define guest
|
||||||
|
if ( !defined( $defs{$rg_name} ) ) {
|
||||||
|
fhem( "define " . $rg_name . " GUEST " . $name );
|
||||||
|
if ( defined( $defs{$rg_name} ) ) {
|
||||||
|
fhem "set $rg_name silentSet state none";
|
||||||
|
Log3 $name, 3,
|
||||||
|
"RESIDENTS $name: created new device $rg_name";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "Can't create, device $rg_name already existing.";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "No Argument given, choose one of name ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# removeGuest
|
||||||
|
elsif ( $a[1] eq "removeGuest" ) {
|
||||||
|
Log3 $name, 2, "RESIDENTS set $name " . $a[1] . " " . $a[2]
|
||||||
|
if ( defined( $a[2] ) );
|
||||||
|
|
||||||
|
if ( $a[2] ne "" ) {
|
||||||
|
my $rg_name = $a[2];
|
||||||
|
|
||||||
|
# delete guest
|
||||||
|
if ( defined( $defs{$rg_name} ) ) {
|
||||||
|
Log3 $name, 3, "RESIDENTS $name: deleted device $rg_name"
|
||||||
|
if fhem( "delete " . $rg_name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "No Argument given, choose one of name ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# register
|
||||||
|
elsif ( $a[1] eq "register" ) {
|
||||||
|
if ( defined( $a[2] ) && $a[2] ne "" ) {
|
||||||
|
return "No such device " . $a[2]
|
||||||
|
if ( !defined( $defs{ $a[2] } ) );
|
||||||
|
|
||||||
|
# ROOMMATE
|
||||||
|
if ( $defs{ $a[2] }{TYPE} eq "ROOMMATE" ) {
|
||||||
|
Log3 $name, 4, "RESIDENTS $name: " . $a[2] . " registered";
|
||||||
|
|
||||||
|
# update readings
|
||||||
|
$roommates .= ( $roommates eq "" ? $a[2] : "," . $a[2] )
|
||||||
|
if ( $roommates !~ /$a[2]/ );
|
||||||
|
|
||||||
|
$hash->{ROOMMATES} = $roommates;
|
||||||
|
}
|
||||||
|
|
||||||
|
# GUEST
|
||||||
|
elsif ( $defs{ $a[2] }{TYPE} eq "GUEST" ) {
|
||||||
|
Log3 $name, 4, "RESIDENTS $name: " . $a[2] . " registered";
|
||||||
|
|
||||||
|
# update readings
|
||||||
|
$guests .= ( $guests eq "" ? $a[2] : "," . $a[2] )
|
||||||
|
if ( $guests !~ /$a[2]/ );
|
||||||
|
|
||||||
|
$hash->{GUESTS} = $guests;
|
||||||
|
}
|
||||||
|
|
||||||
|
# unsupported
|
||||||
|
else {
|
||||||
|
return "Device type is not supported.";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "No Argument given, choose one of ROOMMATE GUEST ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# unregister
|
||||||
|
elsif ( $a[1] eq "unregister" ) {
|
||||||
|
if ( defined( $a[2] ) && $a[2] ne "" ) {
|
||||||
|
return "No such device " . $a[2]
|
||||||
|
if ( !defined( $defs{ $a[2] } ) );
|
||||||
|
|
||||||
|
# ROOMMATE
|
||||||
|
if ( $defs{ $a[2] }{TYPE} eq "ROOMMATE" ) {
|
||||||
|
Log3 $name, 4, "RESIDENTS $name: " . $a[2] . " unregistered";
|
||||||
|
|
||||||
|
# update readings
|
||||||
|
my $replace = "," . $a[2];
|
||||||
|
$roommates =~ s/$replace//g;
|
||||||
|
$replace = $a[2] . ",";
|
||||||
|
$roommates =~ s/^$replace//g;
|
||||||
|
$roommates =~ s/^$a[2]//g;
|
||||||
|
|
||||||
|
$hash->{ROOMMATES} = $roommates;
|
||||||
|
}
|
||||||
|
|
||||||
|
# GUEST
|
||||||
|
elsif ( $defs{ $a[2] }{TYPE} eq "GUEST" ) {
|
||||||
|
Log3 $name, 4, "RESIDENTS $name: " . $a[2] . " unregistered";
|
||||||
|
|
||||||
|
# update readings
|
||||||
|
my $replace = "," . $a[2];
|
||||||
|
$guests =~ s/$replace//g;
|
||||||
|
$replace = $a[2] . ",";
|
||||||
|
$guests =~ s/^$replace//g;
|
||||||
|
$guests =~ s/^$a[2]//g;
|
||||||
|
|
||||||
|
$hash->{GUESTS} = $guests;
|
||||||
|
}
|
||||||
|
|
||||||
|
# unsupported
|
||||||
|
else {
|
||||||
|
return "Device type is not supported.";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "No Argument given, choose one of ROOMMATE GUEST ";
|
||||||
|
}
|
||||||
|
|
||||||
|
RESIDENTS_UpdateReadings($hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
# return usage hint
|
||||||
|
else {
|
||||||
|
return $usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
############################################################################################################
|
||||||
|
#
|
||||||
|
# Begin of helper functions
|
||||||
|
#
|
||||||
|
############################################################################################################
|
||||||
|
|
||||||
|
sub RESIDENTS_UpdateReadings (@) {
|
||||||
|
my ($hash) = @_;
|
||||||
|
my $state =
|
||||||
|
( defined $hash->{READINGS}{state}{VAL} ) ? $hash->{READINGS}{state}{VAL}
|
||||||
|
: ( defined $hash->{STATE} ) ? $hash->{STATE}
|
||||||
|
: "undefined";
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
my $state_home = 0;
|
||||||
|
my $state_gotosleep = 0;
|
||||||
|
my $state_asleep = 0;
|
||||||
|
my $state_awoken = 0;
|
||||||
|
my $state_absent = 0;
|
||||||
|
my $state_gone = 0;
|
||||||
|
my $state_total = 0;
|
||||||
|
my $state_totalPresent = 0;
|
||||||
|
my $state_totalAbsent = 0;
|
||||||
|
my $state_totalGuests = 0;
|
||||||
|
my $state_guestDev = 0;
|
||||||
|
my $wayhome = 0;
|
||||||
|
my $newstate;
|
||||||
|
my $presence = "absent";
|
||||||
|
|
||||||
|
my @registeredRoommates =
|
||||||
|
split( /,/, $hash->{ROOMMATES} )
|
||||||
|
if ( defined( $hash->{ROOMMATES} )
|
||||||
|
&& $hash->{ROOMMATES} ne "" );
|
||||||
|
|
||||||
|
my @registeredGuests =
|
||||||
|
split( /,/, $hash->{GUESTS} )
|
||||||
|
if ( defined( $hash->{GUESTS} )
|
||||||
|
&& $hash->{GUESTS} ne "" );
|
||||||
|
|
||||||
|
# count child states for ROOMMATE devices
|
||||||
|
foreach my $roommate (@registeredRoommates) {
|
||||||
|
$state_total++;
|
||||||
|
|
||||||
|
if ( defined( $defs{$roommate}{READINGS}{state}{VAL} ) ) {
|
||||||
|
if ( $defs{$roommate}{READINGS}{state}{VAL} eq "home" ) {
|
||||||
|
$state_home++;
|
||||||
|
$state_totalPresent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $defs{$roommate}{READINGS}{state}{VAL} eq "gotosleep" ) {
|
||||||
|
$state_gotosleep++;
|
||||||
|
$state_totalPresent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $defs{$roommate}{READINGS}{state}{VAL} eq "asleep" ) {
|
||||||
|
$state_asleep++;
|
||||||
|
$state_totalPresent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $defs{$roommate}{READINGS}{state}{VAL} eq "awoken" ) {
|
||||||
|
$state_awoken++;
|
||||||
|
$state_totalPresent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $defs{$roommate}{READINGS}{state}{VAL} eq "absent" ) {
|
||||||
|
$state_absent++;
|
||||||
|
$state_totalAbsent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $defs{$roommate}{READINGS}{state}{VAL} eq "gone" ) {
|
||||||
|
$state_gone++;
|
||||||
|
$state_totalAbsent++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( defined( $defs{$roommate}{READINGS}{wayhome}{VAL} ) ) {
|
||||||
|
$wayhome += $defs{$roommate}{READINGS}{wayhome}{VAL};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# count child states for GUEST devices
|
||||||
|
foreach my $guest (@registeredGuests) {
|
||||||
|
$state_guestDev++;
|
||||||
|
|
||||||
|
if ( defined( $defs{$guest}{READINGS}{state}{VAL} ) ) {
|
||||||
|
if ( $defs{$guest}{READINGS}{state}{VAL} eq "home" ) {
|
||||||
|
$state_home++;
|
||||||
|
$state_totalPresent++;
|
||||||
|
$state_totalGuests++;
|
||||||
|
$state_total++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $defs{$guest}{READINGS}{state}{VAL} eq "gotosleep" ) {
|
||||||
|
$state_gotosleep++;
|
||||||
|
$state_totalPresent++;
|
||||||
|
$state_totalGuests++;
|
||||||
|
$state_total++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $defs{$guest}{READINGS}{state}{VAL} eq "asleep" ) {
|
||||||
|
$state_asleep++;
|
||||||
|
$state_totalPresent++;
|
||||||
|
$state_totalGuests++;
|
||||||
|
$state_total++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $defs{$guest}{READINGS}{state}{VAL} eq "awoken" ) {
|
||||||
|
$state_awoken++;
|
||||||
|
$state_totalPresent++;
|
||||||
|
$state_totalGuests++;
|
||||||
|
$state_total++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $defs{$guest}{READINGS}{state}{VAL} eq "absent" ) {
|
||||||
|
$state_absent++;
|
||||||
|
$state_totalAbsent++;
|
||||||
|
$state_totalGuests++;
|
||||||
|
$state_total++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( defined( $defs{$guest}{READINGS}{wayhome}{VAL} ) ) {
|
||||||
|
$wayhome += $defs{$guest}{READINGS}{wayhome}{VAL};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# update counter
|
||||||
|
readingsBeginUpdate($hash);
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsTotal", $state_total )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsTotal}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsTotal}{VAL} ne $state_total );
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsGuests", $state_totalGuests )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsGuests}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsGuests}{VAL} ne $state_totalGuests );
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsTotalPresent", $state_totalPresent )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsTotalPresent}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsTotalPresent}{VAL} ne
|
||||||
|
$state_totalPresent );
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsTotalAbsent", $state_totalAbsent )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsTotalAbsent}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsTotalAbsent}{VAL} ne $state_totalAbsent );
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsHome", $state_home )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsHome}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsHome}{VAL} ne $state_home );
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsGotosleep", $state_gotosleep )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsGotosleep}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsGotosleep}{VAL} ne $state_gotosleep );
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsAsleep", $state_asleep )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsAsleep}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsAsleep}{VAL} ne $state_asleep );
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsAwoken", $state_awoken )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsAwoken}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsAwoken}{VAL} ne $state_awoken );
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsAbsent", $state_absent )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsAbsent}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsAbsent}{VAL} ne $state_absent );
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsGone", $state_gone )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsGone}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsGone}{VAL} ne $state_gone );
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "residentsTotalWayhome", $wayhome )
|
||||||
|
if ( !defined( $hash->{READINGS}{residentsTotalWayhome}{VAL} )
|
||||||
|
|| $hash->{READINGS}{residentsTotalWayhome}{VAL} ne $wayhome );
|
||||||
|
|
||||||
|
#
|
||||||
|
# state calculation
|
||||||
|
#
|
||||||
|
|
||||||
|
# gotosleep
|
||||||
|
if ( $state_home == 0
|
||||||
|
&& $state_gotosleep > 0
|
||||||
|
&& $state_asleep >= 0
|
||||||
|
&& $state_awoken == 0 )
|
||||||
|
{
|
||||||
|
$newstate = "gotosleep";
|
||||||
|
}
|
||||||
|
|
||||||
|
# asleep
|
||||||
|
elsif ($state_home == 0
|
||||||
|
&& $state_gotosleep == 0
|
||||||
|
&& $state_asleep > 0
|
||||||
|
&& $state_awoken == 0 )
|
||||||
|
{
|
||||||
|
$newstate = "asleep";
|
||||||
|
}
|
||||||
|
|
||||||
|
# awoken
|
||||||
|
elsif ($state_home == 0
|
||||||
|
&& $state_gotosleep >= 0
|
||||||
|
&& $state_asleep >= 0
|
||||||
|
&& $state_awoken > 0 )
|
||||||
|
{
|
||||||
|
$newstate = "awoken";
|
||||||
|
}
|
||||||
|
|
||||||
|
# general presence
|
||||||
|
elsif ($state_home > 0
|
||||||
|
|| $state_gotosleep > 0
|
||||||
|
|| $state_asleep > 0
|
||||||
|
|| $state_awoken > 0 )
|
||||||
|
{
|
||||||
|
$newstate = "home";
|
||||||
|
}
|
||||||
|
|
||||||
|
# absent
|
||||||
|
elsif ($state_absent > 0
|
||||||
|
&& $state_home == 0
|
||||||
|
&& $state_gotosleep == 0
|
||||||
|
&& $state_asleep == 0
|
||||||
|
&& $state_awoken == 0 )
|
||||||
|
{
|
||||||
|
$newstate = "absent";
|
||||||
|
}
|
||||||
|
|
||||||
|
# gone
|
||||||
|
elsif ($state_gone > 0
|
||||||
|
&& $state_absent == 0
|
||||||
|
&& $state_home == 0
|
||||||
|
&& $state_gotosleep == 0
|
||||||
|
&& $state_asleep == 0
|
||||||
|
&& $state_awoken == 0 )
|
||||||
|
{
|
||||||
|
$newstate = "gone";
|
||||||
|
}
|
||||||
|
|
||||||
|
# none
|
||||||
|
elsif ($state_totalGuests == 0
|
||||||
|
&& $state_gone == 0
|
||||||
|
&& $state_absent == 0
|
||||||
|
&& $state_home == 0
|
||||||
|
&& $state_gotosleep == 0
|
||||||
|
&& $state_asleep == 0
|
||||||
|
&& $state_awoken == 0 )
|
||||||
|
{
|
||||||
|
$newstate = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
# unspecified; this should not happen
|
||||||
|
else {
|
||||||
|
$newstate = "unspecified";
|
||||||
|
}
|
||||||
|
|
||||||
|
# calculate presence state
|
||||||
|
$presence = "present"
|
||||||
|
if ( $newstate ne "gone"
|
||||||
|
&& $newstate ne "none"
|
||||||
|
&& $newstate ne "absent" );
|
||||||
|
|
||||||
|
Log3 $name, 4,
|
||||||
|
"RESIDENTS $name: calculation result - residentsTotal:$state_total residentsGuests:$state_totalGuests residentsTotalPresent:$state_totalPresent residentsTotalAbsent:$state_totalAbsent residentsHome:$state_home residentsGotosleep:$state_gotosleep residentsAsleep:$state_asleep residentsAwoken:$state_awoken residentsAbsent:$state_absent residentsGone:$state_gone presence:$presence state:$newstate";
|
||||||
|
|
||||||
|
# safe current time
|
||||||
|
my $datetime = FmtDateTime(time);
|
||||||
|
|
||||||
|
# if state changed
|
||||||
|
if ( !defined( $hash->{READINGS}{state}{VAL} )
|
||||||
|
|| $state ne $newstate )
|
||||||
|
{
|
||||||
|
# if newstate is asleep, start sleep timer
|
||||||
|
readingsBulkUpdate( $hash, "lastSleep", $datetime )
|
||||||
|
if ( $newstate eq "asleep" );
|
||||||
|
|
||||||
|
# if prior state was asleep, update sleep statistics
|
||||||
|
if ( defined( $hash->{READINGS}{state}{VAL} )
|
||||||
|
&& $state eq "asleep" )
|
||||||
|
{
|
||||||
|
readingsBulkUpdate( $hash, "lastAwake", $datetime );
|
||||||
|
readingsBulkUpdate(
|
||||||
|
$hash,
|
||||||
|
"lastDurSleep",
|
||||||
|
RESIDENTS_TimeDiff(
|
||||||
|
$datetime, $hash->{READINGS}{lastSleep}{VAL}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
readingsBulkUpdate( $hash, "lastState", $hash->{READINGS}{state}{VAL} );
|
||||||
|
readingsBulkUpdate( $hash, "state", $newstate );
|
||||||
|
}
|
||||||
|
|
||||||
|
# if presence changed
|
||||||
|
if ( !defined( $hash->{READINGS}{presence}{VAL} )
|
||||||
|
|| $hash->{READINGS}{presence}{VAL} ne $presence )
|
||||||
|
{
|
||||||
|
readingsBulkUpdate( $hash, "presence", $presence );
|
||||||
|
|
||||||
|
# update statistics
|
||||||
|
if ( $presence eq "present" ) {
|
||||||
|
readingsBulkUpdate( $hash, "lastArrival", $datetime );
|
||||||
|
|
||||||
|
# absence duration
|
||||||
|
if ( defined( $hash->{READINGS}{lastDeparture}{VAL} )
|
||||||
|
&& $hash->{READINGS}{lastDeparture}{VAL} ne "-" )
|
||||||
|
{
|
||||||
|
readingsBulkUpdate(
|
||||||
|
$hash,
|
||||||
|
"lastDurAbsence",
|
||||||
|
RESIDENTS_TimeDiff(
|
||||||
|
$datetime, $hash->{READINGS}{lastDeparture}{VAL}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
readingsBulkUpdate( $hash, "lastDeparture", $datetime );
|
||||||
|
|
||||||
|
# presence duration
|
||||||
|
if ( defined( $hash->{READINGS}{lastArrival}{VAL} )
|
||||||
|
&& $hash->{READINGS}{lastArrival}{VAL} ne "-" )
|
||||||
|
{
|
||||||
|
readingsBulkUpdate(
|
||||||
|
$hash,
|
||||||
|
"lastDurPresence",
|
||||||
|
RESIDENTS_TimeDiff(
|
||||||
|
$datetime, $hash->{READINGS}{lastArrival}{VAL}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub RESIDENTS_TimeDiff($$) {
|
||||||
|
my ( $datetimeNow, $datetimeOld ) = @_;
|
||||||
|
|
||||||
|
my (
|
||||||
|
$date, $time, $date2, $time2,
|
||||||
|
$y, $m, $d, $hour,
|
||||||
|
$min, $sec, $y2, $m2,
|
||||||
|
$d2, $hour2, $min2, $sec2,
|
||||||
|
$timestampNow, $timestampOld, $timeDiff, $hours,
|
||||||
|
$minutes, $seconds
|
||||||
|
);
|
||||||
|
|
||||||
|
( $date, $time ) = split( ' ', $datetimeNow );
|
||||||
|
( $y, $m, $d ) = split( '-', $date );
|
||||||
|
( $hour, $min, $sec ) = split( ':', $time );
|
||||||
|
$m -= 01;
|
||||||
|
$timestampNow = timelocal( $sec, $min, $hour, $d, $m, $y );
|
||||||
|
|
||||||
|
( $date2, $time2 ) = split( ' ', $datetimeOld );
|
||||||
|
( $y2, $m2, $d2 ) = split( '-', $date2 );
|
||||||
|
( $hour2, $min2, $sec2 ) = split( ':', $time2 );
|
||||||
|
$m2 -= 01;
|
||||||
|
$timestampOld = timelocal( $sec2, $min2, $hour2, $d2, $m2, $y2 );
|
||||||
|
|
||||||
|
$timeDiff = $timestampNow - $timestampOld;
|
||||||
|
$hours = ( $timeDiff < 3600 ? 0 : int( $timeDiff / 3600 ) );
|
||||||
|
$timeDiff -= ( $hours == 0 ? 0 : ( $hours * 3600 ) );
|
||||||
|
$minutes = ( $timeDiff < 60 ? 0 : int( $timeDiff / 60 ) );
|
||||||
|
$seconds = $timeDiff % 60;
|
||||||
|
|
||||||
|
$hours = "0" . $hours if ( $hours < 10 );
|
||||||
|
$minutes = "0" . $minutes if ( $minutes < 10 );
|
||||||
|
$seconds = "0" . $seconds if ( $seconds < 10 );
|
||||||
|
|
||||||
|
return "$hours:$minutes:$seconds";
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
=pod
|
||||||
|
=begin html
|
||||||
|
|
||||||
|
<a name="RESIDENTS"></a>
|
||||||
|
<h3>RESIDENTS</h3>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
<a name="RESIDENTSdefine"></a>
|
||||||
|
<b>Define</b>
|
||||||
|
<ul>
|
||||||
|
<code>define <rgr_ResidentsName> RESIDENTS</code>
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
Provides a special dummy device to represent a group if individuals living at your home.<br>
|
||||||
|
It locically combines individual states of <a href="#ROOMMATE">ROOMMATE</a> and <a href="#GUEST">GUEST</a> devices and allows state changes for all members.<br>
|
||||||
|
Based on the current state and other readings, you may trigger other actions within FHEM.<br><br>
|
||||||
|
|
||||||
|
Example:<br>
|
||||||
|
<ul><code>
|
||||||
|
# Standalone
|
||||||
|
define rgr_Residents RESIDENTS
|
||||||
|
</code></ul>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="RESIDENTSset"></a>
|
||||||
|
<b>Set</b>
|
||||||
|
<ul>
|
||||||
|
<code>set <rg_FirstName> <command> [<parameter>]</code>
|
||||||
|
<br><br>
|
||||||
|
Currently, the following commands are defined.<br>
|
||||||
|
<ul>
|
||||||
|
<li><b>location</b> - sets reading 'location'; see attribute rg_locations to adjust list shown in FHEMWEB</li>
|
||||||
|
<li><b>mood</b> - sets reading 'mood'; see attribute rg_moods to adjust list shown in FHEMWEB</li>
|
||||||
|
<li><b>state</b> home,gotosleep,asleep,awoken,absent,gone switch between states; see attribute rg_states to adjust list shown in FHEMWEB</li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<u>Possible states and their meaning</u><br><br>
|
||||||
|
<ul>
|
||||||
|
This module differs 7 states:<br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><b>home</b> - residents are present at home and awake</li>
|
||||||
|
<li><b>gotosleep</b> - all present residents are on it's way to bed</li>
|
||||||
|
<li><b>asleep</b> - all present residents are currently sleeping</li>
|
||||||
|
<li><b>awoken</b> - all present residents just woke up from sleep</li>
|
||||||
|
<li><b>absent</b> - no resident is currently at home but will be back shortly</li>
|
||||||
|
<li><b>gone</b> - all residents left home for longer period</li>
|
||||||
|
<li><b>none</b> - no active member</li>
|
||||||
|
</ul><br>
|
||||||
|
<br>
|
||||||
|
Note: State 'none' cannot explicitly be set. Setting state to 'gone' will be handled as 'none' for GUEST member devices.
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="RESIDENTSattr"></a>
|
||||||
|
<b>Attributes</b><br>
|
||||||
|
<ul><ul>
|
||||||
|
<li><b>rgr_showAllStates</b> - states 'asleep' and 'awoken' are hidden by default to allow simple gotosleep process via devStateIcon; defaults to 0</li>
|
||||||
|
<li><b>rgr_states</b> - list of states ot be shown in FHEMWEB; separate entries by comma only and do NOT use spaces; unsupported states will lead to errors though</li>
|
||||||
|
</ul></ul>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<b>Generated Readings/Events:</b><br>
|
||||||
|
<ul><ul>
|
||||||
|
<li><b>lastArrival</b> - timestamp of last arrival at home</li>
|
||||||
|
<li><b>lastAwake</b> - timestamp of last sleep cycle end</li>
|
||||||
|
<li><b>lastDeparture</b> - timestamp of last departure from home</li>
|
||||||
|
<li><b>lastDurAbsence</b> - duration of last absence from home in following format: hours:minutes:seconds</li>
|
||||||
|
<li><b>lastDurPresence</b> - duration of last presence at home in following format: hours:minutes:seconds</li>
|
||||||
|
<li><b>lastDurSleep</b> - duration of last sleep in following format: hours:minutes:seconds</li>
|
||||||
|
<li><b>lastSleep</b> - timestamp of last sleep cycle begin</li>
|
||||||
|
<li><b>lastState</b> - the prior state</li>
|
||||||
|
<li><b>presence</b> - reflects the home presence state, depending on value of reading 'state' (can be 'present' or 'absent')</li>
|
||||||
|
<li><b>residentsAbsent</b> - number of residents with state 'absent'</li>
|
||||||
|
<li><b>residentsAsleep</b> - number of residents with state 'asleep'</li>
|
||||||
|
<li><b>residentsAwoken</b> - number of residents with state 'awoken'</li>
|
||||||
|
<li><b>residentsGone</b> - number of residents with state 'gone'</li>
|
||||||
|
<li><b>residentsGotosleep</b> - number of residents with state 'gotosleep'</li>
|
||||||
|
<li><b>residentsGuests</b> - number of active guests who are currently threated as part of the residents scope</li>
|
||||||
|
<li><b>residentsHome</b> - number of residents with state 'home'</li>
|
||||||
|
<li><b>residentsTotal</b> - total number of all active residents despite their current state</li>
|
||||||
|
<li><b>residentsTotalAbsent</b> - number of all residents who are currently underway</li>
|
||||||
|
<li><b>residentsTotalPresent</b> - number of all residents who are currently at home</li>
|
||||||
|
<li><b>residentsTotalWayhome</b> - number of all active residents who are currently on their way back home</li>
|
||||||
|
<li><b>state</b> - reflects the current state</li>
|
||||||
|
</ul></ul>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
=end html
|
||||||
|
|
||||||
|
=begin html_DE
|
||||||
|
Eine deutsche Version der Dokumentation ist derzeit nicht vorhanden.
|
||||||
|
Die englische Version ist hier zu finden:
|
||||||
|
|
||||||
|
<a href='http://fhem.de/commandref.html#RESIDENTS>'>RESIDENTS</a>
|
||||||
|
|
||||||
|
=end html_DE
|
||||||
|
|
||||||
|
=cut
|
1064
fhem/FHEM/20_GUEST.pm
Normal file
1064
fhem/FHEM/20_GUEST.pm
Normal file
File diff suppressed because it is too large
Load Diff
1053
fhem/FHEM/20_ROOMMATE.pm
Normal file
1053
fhem/FHEM/20_ROOMMATE.pm
Normal file
File diff suppressed because it is too large
Load Diff
@ -43,6 +43,7 @@ FHEM/10_IT.pm odroegehorn http://forum.fhem.de InterTech
|
|||||||
FHEM/10_MAX.pm mgehre http://forum.fhem.de MAX
|
FHEM/10_MAX.pm mgehre http://forum.fhem.de MAX
|
||||||
FHEM/10_OWServer.pm borisneubert/mfr69bs http://forum.fhem.de 1Wire
|
FHEM/10_OWServer.pm borisneubert/mfr69bs http://forum.fhem.de 1Wire
|
||||||
FHEM/10_ZWave.pm rudolfkoenig http://forum.fhem.de ZWave
|
FHEM/10_ZWave.pm rudolfkoenig http://forum.fhem.de ZWave
|
||||||
|
FHEM/10_RESIDENTS.pm loredo http://forum.fhem.de Automatisierung
|
||||||
FHEM/11_FHT.pm rudolfkoenig http://forum.fhem.de SlowRF
|
FHEM/11_FHT.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||||
FHEM/11_FHT8V.pm rudolfkoenig http://forum.fhem.de SlowRF
|
FHEM/11_FHT8V.pm rudolfkoenig http://forum.fhem.de SlowRF
|
||||||
FHEM/11_OWDevice.pm borisneubert/mfr69bs http://forum.fhem.de 1Wire
|
FHEM/11_OWDevice.pm borisneubert/mfr69bs http://forum.fhem.de 1Wire
|
||||||
@ -66,6 +67,8 @@ FHEM/20_FRM_PWM.pm ntruchsess http://forum.fhem.de Sonstiges
|
|||||||
FHEM/20_FRM_SERVO.pm ntruchsess http://forum.fhem.de Sonstiges
|
FHEM/20_FRM_SERVO.pm ntruchsess http://forum.fhem.de Sonstiges
|
||||||
FHEM/20_OWFS.pm mfr69bs http://forum.fhem.de 1Wire (deprecated)
|
FHEM/20_OWFS.pm mfr69bs http://forum.fhem.de 1Wire (deprecated)
|
||||||
FHEM/20_X10.pm borisneubert http://forum.fhem.de SlowRF
|
FHEM/20_X10.pm borisneubert http://forum.fhem.de SlowRF
|
||||||
|
FHEM/20_ROOMMATE.pm loredo http://forum.fhem.de Automatisierung
|
||||||
|
FHEM/20_GUEST.pm loredo http://forum.fhem.de Automatisierung
|
||||||
FHEM/21_OWAD.pm pahenning http://forum.fhem.de 1Wire
|
FHEM/21_OWAD.pm pahenning http://forum.fhem.de 1Wire
|
||||||
FHEM/21_OWCOUNT.pm pahenning http://forum.fhem.de 1Wire
|
FHEM/21_OWCOUNT.pm pahenning http://forum.fhem.de 1Wire
|
||||||
FHEM/21_OWID.pm pahenning http://forum.fhem.de 1Wire
|
FHEM/21_OWID.pm pahenning http://forum.fhem.de 1Wire
|
||||||
|
Loading…
x
Reference in New Issue
Block a user