mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-16 04:36:02 +00:00
10_RESIDENTS,20_ROOMMATE,20_GUEST: implement dynamic slave handling; remove experimental dependencies
git-svn-id: https://svn.fhem.de/fhem/trunk@13608 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
63b1893132
commit
737af5ee5f
@ -32,8 +32,6 @@ use Time::Local;
|
|||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
require RESIDENTStk;
|
require RESIDENTStk;
|
||||||
|
|
||||||
no if $] >= 5.017011, warnings => 'experimental';
|
|
||||||
|
|
||||||
sub RESIDENTS_Set($@);
|
sub RESIDENTS_Set($@);
|
||||||
sub RESIDENTS_Define($$);
|
sub RESIDENTS_Define($$);
|
||||||
sub RESIDENTS_Notify($$);
|
sub RESIDENTS_Notify($$);
|
||||||
@ -62,8 +60,6 @@ sub RESIDENTS_Define($$) {
|
|||||||
|
|
||||||
Log3 $name, 5, "RESIDENTS $name: called function RESIDENTS_Define()";
|
Log3 $name, 5, "RESIDENTS $name: called function RESIDENTS_Define()";
|
||||||
|
|
||||||
$hash->{TYPE} = "RESIDENTS";
|
|
||||||
|
|
||||||
# set default settings on first define
|
# set default settings on first define
|
||||||
if ( $init_done && !defined( $hash->{OLDDEF} ) ) {
|
if ( $init_done && !defined( $hash->{OLDDEF} ) ) {
|
||||||
$attr{$name}{alias} = "Residents";
|
$attr{$name}{alias} = "Residents";
|
||||||
@ -91,6 +87,8 @@ sub RESIDENTS_Define($$) {
|
|||||||
sub RESIDENTS_Undefine($$) {
|
sub RESIDENTS_Undefine($$) {
|
||||||
my ( $hash, $name ) = @_;
|
my ( $hash, $name ) = @_;
|
||||||
|
|
||||||
|
RESIDENTStk_findResidentSlaves($hash);
|
||||||
|
|
||||||
# delete child roommates
|
# delete child roommates
|
||||||
if ( defined( $hash->{ROOMMATES} )
|
if ( defined( $hash->{ROOMMATES} )
|
||||||
&& $hash->{ROOMMATES} ne "" )
|
&& $hash->{ROOMMATES} ne "" )
|
||||||
@ -125,135 +123,139 @@ sub RESIDENTS_Notify($$) {
|
|||||||
my ( $hash, $dev ) = @_;
|
my ( $hash, $dev ) = @_;
|
||||||
my $devName = $dev->{NAME};
|
my $devName = $dev->{NAME};
|
||||||
my $hashName = $hash->{NAME};
|
my $hashName = $hash->{NAME};
|
||||||
|
return unless ( $devName ne $hashName ); # only foreign events
|
||||||
|
return
|
||||||
|
unless ( defined( $defs{$devName} )
|
||||||
|
&& defined( $defs{$devName}{TYPE} )
|
||||||
|
&& $defs{$devName}{TYPE} =~ /^(ROOMMATE|GUEST|DUMMY)$/ );
|
||||||
|
|
||||||
# process child notifies
|
RESIDENTStk_findResidentSlaves($hash);
|
||||||
if ( $devName ne $hashName ) {
|
|
||||||
my @registeredRoommates =
|
|
||||||
split( /,/, $hash->{ROOMMATES} )
|
|
||||||
if ( defined( $hash->{ROOMMATES} )
|
|
||||||
&& $hash->{ROOMMATES} ne "" );
|
|
||||||
|
|
||||||
my @registeredGuests =
|
my @registeredRoommates =
|
||||||
split( /,/, $hash->{GUESTS} )
|
split( /,/, $hash->{ROOMMATES} )
|
||||||
if ( defined( $hash->{GUESTS} )
|
if ( defined( $hash->{ROOMMATES} )
|
||||||
&& $hash->{GUESTS} ne "" );
|
&& $hash->{ROOMMATES} ne "" );
|
||||||
|
|
||||||
my @registeredWakeupdevs =
|
my @registeredGuests =
|
||||||
split( /,/, $attr{$hashName}{rgr_wakeupDevice} )
|
split( /,/, $hash->{GUESTS} )
|
||||||
if ( defined( $attr{$hashName}{rgr_wakeupDevice} )
|
if ( defined( $hash->{GUESTS} )
|
||||||
&& $attr{$hashName}{rgr_wakeupDevice} ne "" );
|
&& $hash->{GUESTS} ne "" );
|
||||||
|
|
||||||
# process only registered ROOMMATE or GUEST devices
|
my @registeredWakeupdevs =
|
||||||
if ( ( @registeredRoommates && $devName ~~ @registeredRoommates )
|
split( /,/, $attr{$hashName}{rgr_wakeupDevice} )
|
||||||
|| ( @registeredGuests && $devName ~~ @registeredGuests ) )
|
if ( defined( $attr{$hashName}{rgr_wakeupDevice} )
|
||||||
{
|
&& $attr{$hashName}{rgr_wakeupDevice} ne "" );
|
||||||
|
|
||||||
return
|
# process only registered ROOMMATE or GUEST devices
|
||||||
if ( !$dev->{CHANGED} ); # Some previous notify deleted the array.
|
if ( ( @registeredRoommates && grep { /^$devName$/ } @registeredRoommates )
|
||||||
|
|| ( @registeredGuests && grep { /^$devName$/ } @registeredGuests ) )
|
||||||
|
{
|
||||||
|
|
||||||
readingsBeginUpdate($hash);
|
return
|
||||||
|
if ( !$dev->{CHANGED} ); # Some previous notify deleted the array.
|
||||||
|
|
||||||
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
readingsBeginUpdate($hash);
|
||||||
|
|
||||||
Log3 $hash, 5,
|
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
||||||
"RESIDENTS " . $hashName . ": processing change $change";
|
|
||||||
|
|
||||||
# state changed
|
Log3 $hash, 5,
|
||||||
if ( $change !~ /:/
|
"RESIDENTS " . $hashName . ": processing change $change";
|
||||||
|| $change =~ /wayhome:/
|
|
||||||
|| $change =~ /wakeup:/ )
|
|
||||||
{
|
|
||||||
Log3 $hash, 4,
|
|
||||||
"RESIDENTS "
|
|
||||||
. $hashName . ": "
|
|
||||||
. $devName
|
|
||||||
. ": notify about change to $change";
|
|
||||||
|
|
||||||
RESIDENTS_UpdateReadings($hash);
|
# state changed
|
||||||
}
|
if ( $change !~ /:/
|
||||||
|
|| $change =~ /wayhome:/
|
||||||
|
|| $change =~ /wakeup:/ )
|
||||||
|
{
|
||||||
|
Log3 $hash, 4,
|
||||||
|
"RESIDENTS "
|
||||||
|
. $hashName . ": "
|
||||||
|
. $devName
|
||||||
|
. ": notify about change to $change";
|
||||||
|
|
||||||
# activity
|
RESIDENTS_UpdateReadings($hash);
|
||||||
if ( $change !~ /:/ ) {
|
}
|
||||||
|
|
||||||
# get user realname
|
# activity
|
||||||
my $realnamesrc;
|
if ( $change !~ /:/ ) {
|
||||||
if ( $dev->{TYPE} eq "GUEST" ) {
|
|
||||||
$realnamesrc = (
|
|
||||||
defined( $attr{$devName}{rg_realname} )
|
|
||||||
&& $attr{$devName}{rg_realname} ne ""
|
|
||||||
? $attr{$devName}{rg_realname}
|
|
||||||
: "alias"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$realnamesrc = (
|
|
||||||
defined( $attr{$devName}{rr_realname} )
|
|
||||||
&& $attr{$devName}{rr_realname} ne ""
|
|
||||||
? $attr{$devName}{rr_realname}
|
|
||||||
: "group"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
my $realname = (
|
# get user realname
|
||||||
defined( $attr{$devName}{$realnamesrc} )
|
my $realnamesrc;
|
||||||
&& $attr{$devName}{$realnamesrc} ne ""
|
if ( $dev->{TYPE} eq "GUEST" ) {
|
||||||
? $attr{$devName}{$realnamesrc}
|
$realnamesrc = (
|
||||||
: $devName
|
defined( $attr{$devName}{rg_realname} )
|
||||||
|
&& $attr{$devName}{rg_realname} ne ""
|
||||||
|
? $attr{$devName}{rg_realname}
|
||||||
|
: "alias"
|
||||||
);
|
);
|
||||||
|
|
||||||
# update statistics
|
|
||||||
readingsBulkUpdate( $hash, "lastActivity",
|
|
||||||
ReadingsVal( $devName, "state", $change ) );
|
|
||||||
readingsBulkUpdate( $hash, "lastActivityBy", $realname );
|
|
||||||
readingsBulkUpdate( $hash, "lastActivityByDev", $devName );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$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
|
||||||
|
readingsBulkUpdate( $hash, "lastActivity",
|
||||||
|
ReadingsVal( $devName, "state", $change ) );
|
||||||
|
readingsBulkUpdate( $hash, "lastActivityBy", $realname );
|
||||||
|
readingsBulkUpdate( $hash, "lastActivityByDev", $devName );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readingsEndUpdate( $hash, 1 );
|
}
|
||||||
|
|
||||||
|
readingsEndUpdate( $hash, 1 );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# if we have registered wakeup devices
|
||||||
|
if (@registeredWakeupdevs) {
|
||||||
|
|
||||||
|
# if this is a notification of a registered wakeup device
|
||||||
|
if ( grep { /^$devName$/ } @registeredWakeupdevs ) {
|
||||||
|
|
||||||
|
# Some previous notify deleted the array.
|
||||||
|
return
|
||||||
|
if ( !$dev->{CHANGED} );
|
||||||
|
|
||||||
|
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
||||||
|
RESIDENTStk_wakeupSet( $devName, $change );
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# if we have registered wakeup devices
|
# process sub-child notifies: *_wakeupDevice
|
||||||
if (@registeredWakeupdevs) {
|
foreach my $wakeupDev (@registeredWakeupdevs) {
|
||||||
|
|
||||||
# if this is a notification of a registered wakeup device
|
# if this is a notification of a registered sub dummy device
|
||||||
if ( $devName ~~ @registeredWakeupdevs ) {
|
# of one of our wakeup devices
|
||||||
|
if ( defined( $attr{$wakeupDev}{wakeupResetSwitcher} )
|
||||||
|
&& $attr{$wakeupDev}{wakeupResetSwitcher} eq $devName
|
||||||
|
&& $defs{$devName}{TYPE} eq "dummy" )
|
||||||
|
{
|
||||||
|
|
||||||
# Some previous notify deleted the array.
|
# Some previous notify deleted the array.
|
||||||
return
|
return
|
||||||
if ( !$dev->{CHANGED} );
|
if ( !$dev->{CHANGED} );
|
||||||
|
|
||||||
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
||||||
RESIDENTStk_wakeupSet( $devName, $change );
|
RESIDENTStk_wakeupSet( $wakeupDev, $change )
|
||||||
|
if ( $change ne "off" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
last;
|
||||||
}
|
|
||||||
|
|
||||||
# process sub-child notifies: *_wakeupDevice
|
|
||||||
foreach my $wakeupDev (@registeredWakeupdevs) {
|
|
||||||
|
|
||||||
# if this is a notification of a registered sub dummy device
|
|
||||||
# of one of our wakeup devices
|
|
||||||
if ( defined( $attr{$wakeupDev}{wakeupResetSwitcher} )
|
|
||||||
&& $attr{$wakeupDev}{wakeupResetSwitcher} eq $devName
|
|
||||||
&& $defs{$devName}{TYPE} eq "dummy" )
|
|
||||||
{
|
|
||||||
|
|
||||||
# Some previous notify deleted the array.
|
|
||||||
return
|
|
||||||
if ( !$dev->{CHANGED} );
|
|
||||||
|
|
||||||
foreach my $change ( @{ $dev->{CHANGED} } ) {
|
|
||||||
RESIDENTStk_wakeupSet( $wakeupDev, $change )
|
|
||||||
if ( $change ne "off" );
|
|
||||||
}
|
|
||||||
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,15 +266,17 @@ sub RESIDENTS_Notify($$) {
|
|||||||
###################################
|
###################################
|
||||||
sub RESIDENTS_Set($@) {
|
sub RESIDENTS_Set($@) {
|
||||||
my ( $hash, @a ) = @_;
|
my ( $hash, @a ) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $state = ReadingsVal( $name, "state", "initialized" );
|
my $state = ReadingsVal( $name, "state", "initialized" );
|
||||||
my $roommates = ( $hash->{ROOMMATES} ? $hash->{ROOMMATES} : "" );
|
|
||||||
my $guests = ( $hash->{GUESTS} ? $hash->{GUESTS} : "" );
|
|
||||||
|
|
||||||
Log3 $name, 5, "RESIDENTS $name: called function RESIDENTS_Set()";
|
Log3 $name, 5, "RESIDENTS $name: called function RESIDENTS_Set()";
|
||||||
|
|
||||||
return "No Argument given" if ( !defined( $a[1] ) );
|
return "No Argument given" if ( !defined( $a[1] ) );
|
||||||
|
|
||||||
|
RESIDENTStk_findResidentSlaves($hash);
|
||||||
|
my $roommates = ( $hash->{ROOMMATES} ? $hash->{ROOMMATES} : "" );
|
||||||
|
my $guests = ( $hash->{GUESTS} ? $hash->{GUESTS} : "" );
|
||||||
|
|
||||||
# depending on current FHEMWEB instance's allowedCommands,
|
# depending on current FHEMWEB instance's allowedCommands,
|
||||||
# restrict set commands if there is "set-user" in it
|
# restrict set commands if there is "set-user" in it
|
||||||
my $adminMode = 1;
|
my $adminMode = 1;
|
||||||
@ -475,94 +479,6 @@ sub RESIDENTS_Set($@) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# 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 ";
|
|
||||||
}
|
|
||||||
|
|
||||||
readingsBeginUpdate($hash);
|
|
||||||
RESIDENTS_UpdateReadings($hash);
|
|
||||||
readingsEndUpdate( $hash, 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
# create
|
# create
|
||||||
elsif ( $a[1] eq "create" ) {
|
elsif ( $a[1] eq "create" ) {
|
||||||
if ( defined( $a[2] ) && $a[2] eq "wakeuptimer" ) {
|
if ( defined( $a[2] ) && $a[2] eq "wakeuptimer" ) {
|
||||||
|
@ -32,8 +32,6 @@ use Time::Local;
|
|||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
require RESIDENTStk;
|
require RESIDENTStk;
|
||||||
|
|
||||||
no if $] >= 5.017011, warnings => 'experimental';
|
|
||||||
|
|
||||||
sub GUEST_Set($@);
|
sub GUEST_Set($@);
|
||||||
sub GUEST_Define($$);
|
sub GUEST_Define($$);
|
||||||
sub GUEST_Notify($$);
|
sub GUEST_Notify($$);
|
||||||
@ -69,57 +67,14 @@ sub GUEST_Define($$) {
|
|||||||
return $msg;
|
return $msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
$hash->{TYPE} = "GUEST";
|
$hash->{RESIDENTGROUPS} = defined( $a[2] ) ? $a[2] : "";
|
||||||
|
if ( defined( $hash->{RESIDENTGROUPS} ) ) {
|
||||||
my $parents = ( defined( $a[2] ) ? $a[2] : "" );
|
foreach ( split( /,/, $hash->{RESIDENTGROUPS} ) ) {
|
||||||
|
RESIDENTStk_findResidentSlaves( $defs{$_} )
|
||||||
# unregister at parent objects if we get modified
|
if ( defined( $defs{$_} ) );
|
||||||
my @registeredResidentgroups;
|
|
||||||
my $modified = 0;
|
|
||||||
if ( defined( $hash->{RESIDENTGROUPS} ) && $hash->{RESIDENTGROUPS} ne "" ) {
|
|
||||||
$modified = 1;
|
|
||||||
@registeredResidentgroups =
|
|
||||||
split( /,/, $hash->{RESIDENTGROUPS} );
|
|
||||||
|
|
||||||
# unregister at parent objects
|
|
||||||
foreach my $parent (@registeredResidentgroups) {
|
|
||||||
if ( defined( $defs{$parent} )
|
|
||||||
&& $defs{$parent}{TYPE} eq "RESIDENTS" )
|
|
||||||
{
|
|
||||||
fhem("set $parent unregister $name");
|
|
||||||
Log3 $name, 4,
|
|
||||||
"GUEST $name: Unregistered at RESIDENTS device $parent";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# register at parent objects
|
|
||||||
$hash->{RESIDENTGROUPS} = "";
|
|
||||||
if ( $parents ne "" ) {
|
|
||||||
@registeredResidentgroups = split( /,/, $parents );
|
|
||||||
foreach my $parent (@registeredResidentgroups) {
|
|
||||||
if ( !defined( $defs{$parent} ) ) {
|
|
||||||
Log3 $name, 3,
|
|
||||||
"GUEST $name: Unable to register at RESIDENTS device $parent (not existing)";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $defs{$parent}{TYPE} ne "RESIDENTS" ) {
|
|
||||||
Log3 $name, 3,
|
|
||||||
"GUEST $name: Device $parent is not a RESIDENTS device (wrong type)";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
fhem("set $parent register $name");
|
|
||||||
$hash->{RESIDENTGROUPS} .= $parent . ",";
|
|
||||||
Log3 $name, 4,
|
|
||||||
"GUEST $name: Registered at RESIDENTS device $parent";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$modified = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
# set reverse pointer
|
# set reverse pointer
|
||||||
$modules{GUEST}{defptr}{$name} = \$hash;
|
$modules{GUEST}{defptr}{$name} = \$hash;
|
||||||
|
|
||||||
@ -139,15 +94,15 @@ sub GUEST_Define($$) {
|
|||||||
$attr{$name}{sortby} = "1";
|
$attr{$name}{sortby} = "1";
|
||||||
$attr{$name}{webCmd} = "state";
|
$attr{$name}{webCmd} = "state";
|
||||||
|
|
||||||
$attr{$name}{room} = $attr{ $registeredResidentgroups[0] }{room}
|
my $firstRgr = $hash->{RESIDENTGROUPS};
|
||||||
if ( @registeredResidentgroups
|
$firstRgr =~ s/,[\s\S]*$//gmi;
|
||||||
&& exists( $attr{ $registeredResidentgroups[0] }{room} ) );
|
$attr{$name}{room} = $attr{$firstRgr}{room}
|
||||||
|
if ( exists( $attr{$firstRgr}{room} ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
# trigger for modified objects
|
# trigger for modified objects
|
||||||
unless ( $modified == 0 ) {
|
readingsBulkUpdateIfChanged( $hash, "state",
|
||||||
readingsBulkUpdate( $hash, "state", ReadingsVal( $name, "state", "" ) );
|
ReadingsVal( $name, "state", "" ) );
|
||||||
}
|
|
||||||
|
|
||||||
readingsEndUpdate( $hash, 1 );
|
readingsEndUpdate( $hash, 1 );
|
||||||
|
|
||||||
@ -176,18 +131,9 @@ sub GUEST_Undefine($$) {
|
|||||||
RESIDENTStk_RemoveInternalTimer( "DurationTimer", $hash );
|
RESIDENTStk_RemoveInternalTimer( "DurationTimer", $hash );
|
||||||
|
|
||||||
if ( defined( $hash->{RESIDENTGROUPS} ) ) {
|
if ( defined( $hash->{RESIDENTGROUPS} ) ) {
|
||||||
my @registeredResidentgroups =
|
foreach ( split( /,/, $hash->{RESIDENTGROUPS} ) ) {
|
||||||
split( /,/, $hash->{RESIDENTGROUPS} );
|
RESIDENTStk_findResidentSlaves( $defs{$_} )
|
||||||
|
if ( defined( $defs{$_} ) );
|
||||||
# unregister at parent objects
|
|
||||||
foreach my $parent (@registeredResidentgroups) {
|
|
||||||
if ( defined( $defs{$parent} )
|
|
||||||
&& $defs{$parent}{TYPE} eq "RESIDENTS" )
|
|
||||||
{
|
|
||||||
fhem("set $parent unregister $name");
|
|
||||||
Log3 $name, 4,
|
|
||||||
"GUEST $name: Unregistered at RESIDENTS device $parent";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +197,7 @@ sub GUEST_Notify($$) {
|
|||||||
if (@registeredWakeupdevs) {
|
if (@registeredWakeupdevs) {
|
||||||
|
|
||||||
# if this is a notification of a registered wakeup device
|
# if this is a notification of a registered wakeup device
|
||||||
if ( $devName ~~ @registeredWakeupdevs ) {
|
if ( grep { /^$devName$/ } @registeredWakeupdevs ) {
|
||||||
|
|
||||||
# Some previous notify deleted the array.
|
# Some previous notify deleted the array.
|
||||||
return
|
return
|
||||||
@ -289,7 +235,7 @@ sub GUEST_Notify($$) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# process PRESENCE
|
# process PRESENCE
|
||||||
if ( @presenceDevices && $devName ~~ @presenceDevices ) {
|
if ( @presenceDevices && grep { /^$devName$/ } @presenceDevices ) {
|
||||||
|
|
||||||
my $counter = {
|
my $counter = {
|
||||||
absent => 0,
|
absent => 0,
|
||||||
|
@ -32,8 +32,6 @@ use Time::Local;
|
|||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
require RESIDENTStk;
|
require RESIDENTStk;
|
||||||
|
|
||||||
no if $] >= 5.017011, warnings => 'experimental';
|
|
||||||
|
|
||||||
sub ROOMMATE_Set($@);
|
sub ROOMMATE_Set($@);
|
||||||
sub ROOMMATE_Define($$);
|
sub ROOMMATE_Define($$);
|
||||||
sub ROOMMATE_Notify($$);
|
sub ROOMMATE_Notify($$);
|
||||||
@ -70,57 +68,14 @@ sub ROOMMATE_Define($$) {
|
|||||||
return $msg;
|
return $msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
$hash->{TYPE} = "ROOMMATE";
|
$hash->{RESIDENTGROUPS} = defined( $a[2] ) ? $a[2] : "";
|
||||||
|
if ( defined( $hash->{RESIDENTGROUPS} ) ) {
|
||||||
my $parents = ( defined( $a[2] ) ? $a[2] : "" );
|
foreach ( split( /,/, $hash->{RESIDENTGROUPS} ) ) {
|
||||||
|
RESIDENTStk_findResidentSlaves( $defs{$_} )
|
||||||
# unregister at parent objects if we get modified
|
if ( defined( $defs{$_} ) );
|
||||||
my @registeredResidentgroups;
|
|
||||||
my $modified = 0;
|
|
||||||
if ( defined( $hash->{RESIDENTGROUPS} ) && $hash->{RESIDENTGROUPS} ne "" ) {
|
|
||||||
$modified = 1;
|
|
||||||
@registeredResidentgroups =
|
|
||||||
split( /,/, $hash->{RESIDENTGROUPS} );
|
|
||||||
|
|
||||||
# unregister at parent objects
|
|
||||||
foreach my $parent (@registeredResidentgroups) {
|
|
||||||
if ( defined( $defs{$parent} )
|
|
||||||
&& $defs{$parent}{TYPE} eq "RESIDENTS" )
|
|
||||||
{
|
|
||||||
fhem("set $parent unregister $name");
|
|
||||||
Log3 $name, 4,
|
|
||||||
"ROOMMATE $name: Unregistered at RESIDENTS device $parent";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# register at parent objects
|
|
||||||
$hash->{RESIDENTGROUPS} = "";
|
|
||||||
if ( $parents ne "" ) {
|
|
||||||
@registeredResidentgroups = split( /,/, $parents );
|
|
||||||
foreach my $parent (@registeredResidentgroups) {
|
|
||||||
if ( !defined( $defs{$parent} ) ) {
|
|
||||||
Log3 $name, 3,
|
|
||||||
"ROOMMATE $name: Unable to register at RESIDENTS device $parent (not existing)";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $defs{$parent}{TYPE} ne "RESIDENTS" ) {
|
|
||||||
Log3 $name, 3,
|
|
||||||
"ROOMMATE $name: Device $parent is not a RESIDENTS device (wrong type)";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
fhem("set $parent register $name");
|
|
||||||
$hash->{RESIDENTGROUPS} .= $parent . ",";
|
|
||||||
Log3 $name, 4,
|
|
||||||
"ROOMMATE $name: Registered at RESIDENTS device $parent";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$modified = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
# set reverse pointer
|
# set reverse pointer
|
||||||
$modules{ROOMMATE}{defptr}{$name} = \$hash;
|
$modules{ROOMMATE}{defptr}{$name} = \$hash;
|
||||||
|
|
||||||
@ -140,15 +95,15 @@ sub ROOMMATE_Define($$) {
|
|||||||
$attr{$name}{sortby} = "1";
|
$attr{$name}{sortby} = "1";
|
||||||
$attr{$name}{webCmd} = "state";
|
$attr{$name}{webCmd} = "state";
|
||||||
|
|
||||||
$attr{$name}{room} = $attr{ $registeredResidentgroups[0] }{room}
|
my $firstRgr = $hash->{RESIDENTGROUPS};
|
||||||
if ( @registeredResidentgroups
|
$firstRgr =~ s/,[\s\S]*$//gmi;
|
||||||
&& exists( $attr{ $registeredResidentgroups[0] }{room} ) );
|
$attr{$name}{room} = $attr{$firstRgr}{room}
|
||||||
|
if ( exists( $attr{$firstRgr}{room} ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
# trigger for modified objects
|
# trigger for modified objects
|
||||||
unless ( $modified == 0 ) {
|
readingsBulkUpdateIfChanged( $hash, "state",
|
||||||
readingsBulkUpdate( $hash, "state", ReadingsVal( $name, "state", "" ) );
|
ReadingsVal( $name, "state", "" ) );
|
||||||
}
|
|
||||||
|
|
||||||
readingsEndUpdate( $hash, 1 );
|
readingsEndUpdate( $hash, 1 );
|
||||||
|
|
||||||
@ -181,18 +136,9 @@ sub ROOMMATE_Undefine($$) {
|
|||||||
RESIDENTStk_RemoveInternalTimer( "DurationTimer", $hash );
|
RESIDENTStk_RemoveInternalTimer( "DurationTimer", $hash );
|
||||||
|
|
||||||
if ( defined( $hash->{RESIDENTGROUPS} ) ) {
|
if ( defined( $hash->{RESIDENTGROUPS} ) ) {
|
||||||
my @registeredResidentgroups =
|
foreach ( split( /,/, $hash->{RESIDENTGROUPS} ) ) {
|
||||||
split( /,/, $hash->{RESIDENTGROUPS} );
|
RESIDENTStk_findResidentSlaves( $defs{$_} )
|
||||||
|
if ( defined( $defs{$_} ) );
|
||||||
# unregister at parent objects
|
|
||||||
foreach my $parent (@registeredResidentgroups) {
|
|
||||||
if ( defined( $defs{$parent} )
|
|
||||||
&& $defs{$parent}{TYPE} eq "RESIDENTS" )
|
|
||||||
{
|
|
||||||
fhem("set $parent unregister $name");
|
|
||||||
Log3 $name, 4,
|
|
||||||
"ROOMMATE $name: Unregistered at RESIDENTS device $parent";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +202,7 @@ sub ROOMMATE_Notify($$) {
|
|||||||
if (@registeredWakeupdevs) {
|
if (@registeredWakeupdevs) {
|
||||||
|
|
||||||
# if this is a notification of a registered wakeup device
|
# if this is a notification of a registered wakeup device
|
||||||
if ( $devName ~~ @registeredWakeupdevs ) {
|
if ( grep { /^$devName$/ } @registeredWakeupdevs ) {
|
||||||
|
|
||||||
# Some previous notify deleted the array.
|
# Some previous notify deleted the array.
|
||||||
return
|
return
|
||||||
@ -294,7 +240,7 @@ sub ROOMMATE_Notify($$) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# process PRESENCE
|
# process PRESENCE
|
||||||
if ( @presenceDevices && $devName ~~ @presenceDevices ) {
|
if ( @presenceDevices && grep { /^$devName$/ } @presenceDevices ) {
|
||||||
|
|
||||||
my $counter = {
|
my $counter = {
|
||||||
absent => 0,
|
absent => 0,
|
||||||
|
@ -1715,4 +1715,33 @@ sub RESIDENTStk_RemoveInternalTimer($$) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub RESIDENTStk_findResidentSlaves($) {
|
||||||
|
my ($hash) = @_;
|
||||||
|
return unless ( ref($hash) eq "HASH" && defined( $hash->{NAME} ) );
|
||||||
|
|
||||||
|
delete $hash->{ROOMMATES};
|
||||||
|
foreach ( devspec2array("TYPE=ROOMMATE") ) {
|
||||||
|
next
|
||||||
|
unless (
|
||||||
|
defined( $defs{$_}{RESIDENTGROUPS} )
|
||||||
|
&& grep { /^$hash->{NAME}$/ }
|
||||||
|
split( /,/, $defs{$_}{RESIDENTGROUPS} )
|
||||||
|
);
|
||||||
|
$hash->{ROOMMATES} .= "," if ( $hash->{ROOMMATES} );
|
||||||
|
$hash->{ROOMMATES} .= $_;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete $hash->{GUESTS};
|
||||||
|
foreach ( devspec2array("TYPE=GUEST") ) {
|
||||||
|
next
|
||||||
|
unless (
|
||||||
|
defined( $defs{$_}{RESIDENTGROUPS} )
|
||||||
|
&& grep { /^$hash->{NAME}$/ }
|
||||||
|
split( /,/, $defs{$_}{RESIDENTGROUPS} )
|
||||||
|
);
|
||||||
|
$hash->{GUESTS} .= "," if ( $hash->{GUESTS} );
|
||||||
|
$hash->{GUESTS} .= $_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user