HOMESTATEtk: add homealone support

git-svn-id: https://svn.fhem.de/fhem/trunk@19386 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
jpawlowski 2019-05-14 16:47:14 +00:00
parent 5d33f71232
commit 2400deb9cc
6 changed files with 221 additions and 70 deletions

View File

@ -7,6 +7,7 @@ use Data::Dumper;
use Time::Local; use Time::Local;
require RESIDENTStk; require RESIDENTStk;
our ( %RESIDENTStk_types, %RESIDENTStk_subTypes );
# initialize ################################################################## # initialize ##################################################################
sub RESIDENTS_Initialize($) { sub RESIDENTS_Initialize($) {
@ -29,7 +30,7 @@ sub RESIDENTS_Initialize($) {
. "rgr_showAllStates:0,1 " . "rgr_showAllStates:0,1 "
. "rgr_wakeupDevice " . "rgr_wakeupDevice "
. "rgr_homealoneInStatus:0,1 " . "rgr_homealoneInStatus:0,1 "
. "rgr_homealoneSubTypes:multiple-strict,pet,bird,pig,monkey,cat,dog,baby,toddler,minor,child,guest,domesticWorker,vacationer,teenager,senior " . "rgr_homealoneSubTypes:multiple-strict,pet,bird,pig,monkey,cat,dog,baby,toddler,childcare,child,guest,domesticWorker,vacationer,teenager,senior "
. $readingFnAttributes; . $readingFnAttributes;
return FHEM::Meta::InitMod( __FILE__, $hash ); return FHEM::Meta::InitMod( __FILE__, $hash );
@ -47,7 +48,7 @@ sub RESIDENTS_UpdateReadings (@) {
AttrVal( AttrVal(
$name, $name,
"rgr_homealoneSubTypes", "rgr_homealoneSubTypes",
"pet,bird,pig,monkey,cat,dog,baby,toddler,minor,child,guest,domesticWorker,vacationer,teenager,senior" "pet,bird,pig,monkey,cat,dog,baby,toddler,childcare,child,guest,domesticWorker,vacationer,teenager,senior"
) )
); );
@ -456,7 +457,7 @@ sub RESIDENTS_UpdateReadings (@) {
my $SubType = my $SubType =
defined( $defs{$roommate}{SUBTYPE} ) defined( $defs{$roommate}{SUBTYPE} )
? $defs{$roommate}{SUBTYPE} ? $defs{$roommate}{SUBTYPE}
: 'generic'; : 'adult';
$state_homealone = 0 $state_homealone = 0
unless ( grep m/^$SubType$/, @homealoneSubTypes ); unless ( grep m/^$SubType$/, @homealoneSubTypes );
@ -1297,13 +1298,16 @@ sub RESIDENTS_UpdateReadings (@) {
next unless $TYPE; next unless $TYPE;
my $subtype = 'generic'; my $subtype = 'generic';
$subtype = InternalVal( $obj, 'SUBTYPE', 'pet' ) $subtype = InternalVal( $obj, 'SUBTYPE', 'generic' )
if ( $TYPE eq 'PET' ); if ( $TYPE eq 'PET' );
$subtype = InternalVal( $obj, 'SUBTYPE', 'adult' ) $subtype = InternalVal( $obj, 'SUBTYPE', 'adult' )
if ( $TYPE eq 'ROOMMATE' ); if ( $TYPE eq 'ROOMMATE' );
$subtype = InternalVal( $obj, 'SUBTYPE', 'guest' ) $subtype = InternalVal( $obj, 'SUBTYPE', 'generic' )
if ( $TYPE eq 'GUEST' ); if ( $TYPE eq 'GUEST' );
$subtype = $RESIDENTStk_types{en}{$TYPE}
if ( $subtype eq 'generic' );
my $importance = 99; my $importance = 99;
my (@index) = grep { $homealoneSubTypes[$_] eq $subtype } my (@index) = grep { $homealoneSubTypes[$_] eq $subtype }
0 .. scalar @homealoneSubTypes - 1; 0 .. scalar @homealoneSubTypes - 1;

View File

@ -26,7 +26,7 @@ sub GUEST_Initialize($) {
"disable:1,0 disabledForIntervals do_not_notify:1,0 " "disable:1,0 disabledForIntervals do_not_notify:1,0 "
. "rg_states:multiple-strict,home,gotosleep,asleep,awoken,absent,none " . "rg_states:multiple-strict,home,gotosleep,asleep,awoken,absent,none "
. "subType:" . "subType:"
. join( ',', @{ $RESIDENTStk_subTypes{GUEST} } ) . " " . join( ',', @{ $RESIDENTStk_subTypes{en}{GUEST} } ) . " "
. $readingFnAttributes; . $readingFnAttributes;
foreach (@RESIDENTStk_attr) { foreach (@RESIDENTStk_attr) {

View File

@ -26,7 +26,7 @@ sub PET_Initialize($) {
"disable:1,0 disabledForIntervals do_not_notify:1,0 " "disable:1,0 disabledForIntervals do_not_notify:1,0 "
. "rp_states:multiple-strict,home,gotosleep,asleep,awoken,absent,gone " . "rp_states:multiple-strict,home,gotosleep,asleep,awoken,absent,gone "
. "subType:" . "subType:"
. join( ',', @{ $RESIDENTStk_subTypes{PET} } ) . " " . join( ',', @{ $RESIDENTStk_subTypes{en}{PET} } ) . " "
. $readingFnAttributes; . $readingFnAttributes;
foreach (@RESIDENTStk_attr) { foreach (@RESIDENTStk_attr) {

View File

@ -26,7 +26,7 @@ sub ROOMMATE_Initialize($) {
"disable:1,0 disabledForIntervals do_not_notify:1,0 " "disable:1,0 disabledForIntervals do_not_notify:1,0 "
. "rr_states:multiple-strict,home,gotosleep,asleep,awoken,absent,gone " . "rr_states:multiple-strict,home,gotosleep,asleep,awoken,absent,gone "
. "subType:" . "subType:"
. join( ',', @{ $RESIDENTStk_subTypes{ROOMMATE} } ) . " " . join( ',', @{ $RESIDENTStk_subTypes{en}{ROOMMATE} } ) . " "
. $readingFnAttributes; . $readingFnAttributes;
foreach (@RESIDENTStk_attr) { foreach (@RESIDENTStk_attr) {

View File

@ -4,9 +4,9 @@ package main;
use strict; use strict;
use warnings; use warnings;
use Data::Dumper; use Data::Dumper;
use Time::Local;
require RESIDENTStk; require RESIDENTStk;
our ( %RESIDENTStk_types, %RESIDENTStk_subTypes );
# module variables ############################################################ # module variables ############################################################
my %stateSecurity = ( my %stateSecurity = (
@ -39,7 +39,7 @@ my %readingsMap = (
dst_long => 'calTodDST', dst_long => 'calTodDST',
isholiday => 'calTodHoliday', isholiday => 'calTodHoliday',
isly => 'calTodLeapyear', isly => 'calTodLeapyear',
iswe => 'calTodTodWeekend', iswe => 'calTodWeekend',
mday => 'calTodMonthday', mday => 'calTodMonthday',
mdayrem => 'calTodMonthdayRem', mdayrem => 'calTodMonthdayRem',
monISO => 'calTodMonthN', monISO => 'calTodMonthN',
@ -124,7 +124,8 @@ sub HOMESTATEtk_Initialize($) {
" HolidayDevices:multiple," " HolidayDevices:multiple,"
. join( ",", devspec2array( "TYPE=holiday" . $holidayFilter ) ); . join( ",", devspec2array( "TYPE=holiday" . $holidayFilter ) );
$hash->{AttrList} .= " ResidentsDevices:multiple," $hash->{AttrList} .= " ResidentsDevices:multiple,"
. join( ",", devspec2array("TYPE=RESIDENTS,TYPE=ROOMMATE,TYPE=GUEST") ); . join( ",",
devspec2array("TYPE=RESIDENTS,TYPE=ROOMMATE,TYPE=PET,TYPE=GUEST") );
} }
# module Fn #################################################################### # module Fn ####################################################################
@ -269,12 +270,12 @@ sub HOMESTATEtk_Define($$$) {
$attr{$name}{icon} = "control_building_control" $attr{$name}{icon} = "control_building_control"
if ( $TYPE eq "HOMESTATE" ); if ( $TYPE eq "HOMESTATE" );
$attr{$name}{icon} = "control_building_eg" $attr{$name}{icon} = "control_building_eg"
if ( $TYPE eq "SECTIONSTATE" ); if ( $TYPE eq "ZONESTATE" );
$attr{$name}{icon} = "floor" $attr{$name}{icon} = "floor"
if ( $TYPE eq "ROOMSTATE" ); if ( $TYPE eq "ROOMSTATE" );
# find HOMESTATE device # find HOMESTATE device
if ( $TYPE eq "ROOMSTATE" || $TYPE eq "SECTIONSTATE" ) { if ( $TYPE eq "ROOMSTATE" || $TYPE eq "ZONESTATE" ) {
my @homestates = devspec2array("TYPE=HOMESTATE"); my @homestates = devspec2array("TYPE=HOMESTATE");
if ( scalar @homestates ) { if ( scalar @homestates ) {
$attr{$name}{"HomestateDevices"} = $homestates[0]; $attr{$name}{"HomestateDevices"} = $homestates[0];
@ -310,7 +311,7 @@ sub HOMESTATEtk_Define($$$) {
} }
# find ROOMSTATE device # find ROOMSTATE device
if ( $TYPE eq "SECTIONSTATE" ) { if ( $TYPE eq "ZONESTATE" ) {
my @roomstates = devspec2array("TYPE=ROOMSTATE"); my @roomstates = devspec2array("TYPE=ROOMSTATE");
unless ( scalar @roomstates ) { unless ( scalar @roomstates ) {
my $n = "Room"; my $n = "Room";
@ -334,7 +335,8 @@ sub HOMESTATEtk_Define($$$) {
# find RESIDENTS device # find RESIDENTS device
if ( $TYPE eq "HOMESTATE" ) { if ( $TYPE eq "HOMESTATE" ) {
my @residents = devspec2array("TYPE=RESIDENTS,TYPE=ROOMMATE"); my @residents =
devspec2array("TYPE=RESIDENTS,TYPE=ROOMMATE,TYPE=PET");
if ( scalar @residents ) { if ( scalar @residents ) {
$attr{$name}{"ResidentsDevices"} = $residents[0]; $attr{$name}{"ResidentsDevices"} = $residents[0];
$attr{$name}{room} = $attr{ $residents[0] }{room} $attr{$name}{room} = $attr{ $residents[0] }{room}
@ -696,8 +698,8 @@ sub HOMESTATEtk_Attr(@) {
unless ( $cmd eq "del" unless ( $cmd eq "del"
|| $value =~ m/^[A-Za-z\d._]+(?:,[A-Za-z\d._]*)*$/ ); || $value =~ m/^[A-Za-z\d._]+(?:,[A-Za-z\d._]*)*$/ );
delete $hash->{SECTIONSTATES}; delete $hash->{ZONESTATES};
$hash->{SECTIONSTATES} = $value unless ( $cmd eq "del" ); $hash->{ZONESTATES} = $value unless ( $cmd eq "del" );
} }
elsif ( $attribute eq "RoomstateDevices" ) { elsif ( $attribute eq "RoomstateDevices" ) {
@ -775,7 +777,7 @@ sub HOMESTATEtk_Attr(@) {
if ( !defined( $attr{$name}{group} ) if ( !defined( $attr{$name}{group} )
|| $attr{$name}{group} eq "Home State" ); || $attr{$name}{group} eq "Home State" );
} }
if ( $TYPE eq "SECTIONSTATE" ) { if ( $TYPE eq "ZONESTATE" ) {
$attr{$name}{group} = "Bereichstatus" $attr{$name}{group} = "Bereichstatus"
if ( !defined( $attr{$name}{group} ) if ( !defined( $attr{$name}{group} )
|| $attr{$name}{group} eq "Section State" ); || $attr{$name}{group} eq "Section State" );
@ -800,7 +802,7 @@ sub HOMESTATEtk_Attr(@) {
if ( !defined( $attr{$name}{group} ) if ( !defined( $attr{$name}{group} )
|| $attr{$name}{group} eq "Zuhause Status" ); || $attr{$name}{group} eq "Zuhause Status" );
} }
if ( $TYPE eq "SECTIONSTATE" ) { if ( $TYPE eq "ZONESTATE" ) {
$attr{$name}{group} = "Section State" $attr{$name}{group} = "Section State"
if ( !defined( $attr{$name}{group} ) if ( !defined( $attr{$name}{group} )
|| $attr{$name}{group} eq "Bereichstatus" ); || $attr{$name}{group} eq "Bereichstatus" );
@ -910,11 +912,11 @@ m/^((?:DELETE)?ATTR)\s+([A-Za-z\d._]+)\s+([A-Za-z\d_\.\-\/]+)(?:\s+(.*)\s*)?$/
return "" if ( IsDisabled($name) or IsDisabled($devName) ); return "" if ( IsDisabled($name) or IsDisabled($devName) );
# process events from RESIDENTS, ROOMMATE or GUEST devices # process events from RESIDENTS, ROOMMATE, PET or GUEST devices
# only when they hit HOMESTATE devices # only when they hit HOMESTATE devices
if ( $TYPE ne $devType if ( $TYPE ne $devType
&& $devType =~ && $devType =~
m/^HOMESTATE|SECTIONSTATE|ROOMSTATE|RESIDENTS|ROOMMATE|GUEST$/ ) m/^HOMESTATE|ZONESTATE|ROOMSTATE|RESIDENTS|ROOMMATE|PET|GUEST$/ )
{ {
my $events = deviceEvents( $dev, 1 ); my $events = deviceEvents( $dev, 1 );
@ -925,6 +927,7 @@ m/^((?:DELETE)?ATTR)\s+([A-Za-z\d._]+)\s+([A-Za-z\d_\.\-\/]+)(?:\s+(.*)\s*)?$/
# state changed # state changed
if ( $event !~ /^[a-zA-Z\d._]+:/ if ( $event !~ /^[a-zA-Z\d._]+:/
|| $event =~ /^homealoneType:/
|| $event =~ /^state:/ || $event =~ /^state:/
|| $event =~ /^presence:/ || $event =~ /^presence:/
|| $event =~ /^mode:/ || $event =~ /^mode:/
@ -973,31 +976,31 @@ sub HOMESTATEtk_findHomestateSlaves($;$) {
if ( $hash->{TYPE} eq "HOMESTATE" ) { if ( $hash->{TYPE} eq "HOMESTATE" ) {
my @SECTIONSTATES; my @ZONESTATES;
foreach ( devspec2array("TYPE=SECTIONSTATE") ) { foreach ( devspec2array("TYPE=ZONESTATE") ) {
next next
unless ( unless (
defined( $defs{$_}{SECTIONSTATES} ) defined( $defs{$_}{ZONESTATES} )
&& grep { $hash->{NAME} eq $_ } && grep { $hash->{NAME} eq $_ }
split( /,/, $defs{$_}{SECTIONSTATES} ) split( /,/, $defs{$_}{ZONESTATES} )
); );
push @SECTIONSTATES, $_; push @ZONESTATES, $_;
} }
if ( scalar @SECTIONSTATES ) { if ( scalar @ZONESTATES ) {
$hash->{SECTIONSTATES} = join( ",", @SECTIONSTATES ); $hash->{ZONESTATES} = join( ",", @ZONESTATES );
} }
elsif ( $hash->{SECTIONSTATES} ) { elsif ( $hash->{ZONESTATES} ) {
delete $hash->{SECTIONSTATES}; delete $hash->{ZONESTATES};
} }
if ( $hash->{SECTIONSTATES} ) { if ( $hash->{ZONESTATES} ) {
$ret .= "," if ($ret); $ret .= "," if ($ret);
$ret .= $hash->{SECTIONSTATES}; $ret .= $hash->{ZONESTATES};
} }
} }
if ( $hash->{TYPE} eq "HOMESTATE" || $hash->{TYPE} eq "SECTIONSTATE" ) { if ( $hash->{TYPE} eq "HOMESTATE" || $hash->{TYPE} eq "ZONESTATE" ) {
my @ROOMSTATES; my @ROOMSTATES;
foreach ( devspec2array("TYPE=ROOMSTATE") ) { foreach ( devspec2array("TYPE=ROOMSTATE") ) {
@ -1009,9 +1012,9 @@ sub HOMESTATEtk_findHomestateSlaves($;$) {
split( /,/, $defs{$_}{HOMESTATES} ) split( /,/, $defs{$_}{HOMESTATES} )
) )
|| ( || (
defined( $defs{$_}{SECTIONSTATES} ) defined( $defs{$_}{ZONESTATES} )
&& grep { $hash->{NAME} eq $_ } && grep { $hash->{NAME} eq $_ }
split( /,/, $defs{$_}{SECTIONSTATES} ) split( /,/, $defs{$_}{ZONESTATES} )
) )
); );
push @ROOMSTATES, $_; push @ROOMSTATES, $_;
@ -1058,27 +1061,60 @@ sub HOMESTATEtk_devStateIcon($) {
my $langUc = uc($lang); my $langUc = uc($lang);
my @devStateIcon; my @devStateIcon;
# mode # homeAlone
my $i = 0; my $i = 0;
foreach ( @{ $UConv::daytimes{en} } ) { foreach my $TYPE ( keys %{ $RESIDENTStk_subTypes{en} } ) {
push @devStateIcon, "$_:$UConv::daytimes{icons}[$i++]:toggle"; $i = 0;
foreach my $subType ( @{ $RESIDENTStk_subTypes{en}{$TYPE} } ) {
$subType = $RESIDENTStk_types{en}{$TYPE}
if ( $subType eq 'generic' );
push @devStateIcon,
$subType . "_.+:"
. $RESIDENTStk_subTypes{icons}{$TYPE}[ $i++ ]
. ":toggle";
}
} }
unless ( $lang eq "en" && defined( $UConv::daytimes{$lang} ) ) { unless ( $lang ne "en" && defined( $RESIDENTStk_subTypes{$lang} ) ) {
foreach my $TYPE ( keys %{ $RESIDENTStk_subTypes{$lang} } ) {
$i = 0;
foreach my $subType ( @{ $RESIDENTStk_subTypes{en}{$TYPE} } ) {
if ( $subType eq 'generic' ) {
$subType = $RESIDENTStk_types{$lang}{$TYPE};
}
else {
$subType = $RESIDENTStk_subTypes{$lang}{$TYPE}[$i];
}
push @devStateIcon,
$subType . "_.+:"
. $RESIDENTStk_subTypes{icons}{$TYPE}[ $i++ ]
. ":toggle";
}
}
}
# mode
$i = 0;
foreach ( @{ $UConv::daytimes{en} } ) {
push @devStateIcon,
$_ . ":" . $UConv::daytimes{icons}[ $i++ ] . ":toggle";
}
if ( $lang ne "en" && defined( $UConv::daytimes{$lang} ) ) {
$i = 0; $i = 0;
foreach ( @{ $UConv::daytimes{$lang} } ) { foreach ( @{ $UConv::daytimes{$lang} } ) {
push @devStateIcon, "$_:$UConv::daytimes{icons}[$i++]:toggle"; push @devStateIcon,
$_ . ":" . $UConv::daytimes{icons}[ $i++ ] . ":toggle";
} }
} }
# security # security
$i = 0; $i = 0;
foreach ( @{ $stateSecurity{en} } ) { foreach ( @{ $stateSecurity{en} } ) {
push @devStateIcon, "$_:$stateSecurity{icons}[$i++]"; push @devStateIcon, $_ . ":" . $stateSecurity{icons}[ $i++ ];
} }
unless ( $lang eq "en" && defined( $UConv::daytimes{$lang} ) ) { if ( $lang ne "en" && defined( $UConv::daytimes{$lang} ) ) {
$i = 0; $i = 0;
foreach ( @{ $stateSecurity{$lang} } ) { foreach ( @{ $stateSecurity{$lang} } ) {
push @devStateIcon, "$_:$stateSecurity{icons}[$i++]"; push @devStateIcon, $_ . ":" . $stateSecurity{icons}[ $i++ ];
} }
} }
@ -1162,19 +1198,40 @@ sub HOMESTATEtk_UpdateReadings (@) {
my $state_awoken = 0; my $state_awoken = 0;
my $state_absent = 0; my $state_absent = 0;
my $state_gone = 0; my $state_gone = 0;
my $wayhome = 0; my $state_homealoneType;
my $wayhomeDelayed = 0; my $state_homealoneSubtype;
my $wakeup = 0; my $wayhome = 0;
foreach my $internal ( "RESIDENTS", "SECTIONSTATES", "ROOMSTATES" ) { my $wayhomeDelayed = 0;
my $wakeup = 0;
foreach my $internal ( "RESIDENTS", "ZONESTATES", "ROOMSTATES" ) {
next unless ( $hash->{$internal} ); next unless ( $hash->{$internal} );
foreach my $presenceDev ( split( /,/, $hash->{$internal} ) ) { foreach my $presenceDev ( split( /,/, $hash->{$internal} ) ) {
my $state = ReadingsVal( $presenceDev, "state", "gone" ); my $state = ReadingsVal( $presenceDev, "state", "gone" );
$state_home++ if ( $state eq "home" ); $state_home++ if ( $state =~ /home$/ );
$state_gotosleep++ if ( $state eq "gotosleep" ); $state_gotosleep++ if ( $state =~ /gotosleep$/ );
$state_asleep++ if ( $state eq "asleep" ); $state_asleep++ if ( $state =~ /asleep$/ );
$state_awoken++ if ( $state eq "awoken" ); $state_awoken++ if ( $state =~ /awoken$/ );
$state_absent++ if ( $state eq "absent" ); $state_absent++ if ( $state =~ /absent$/ );
$state_gone++ if ( $state eq "gone" || $state eq "none" ); $state_gone++ if ( $state =~ /(?:gone|none)$/ );
my $homealoneType =
ReadingsVal( $presenceDev, "homealoneType", "-" );
my $homealoneSubtype =
ReadingsVal( $presenceDev, "homealoneSubtype", "-" );
if (
$homealoneType ne '-'
&& (
!$state_homealoneType
|| ( $state_homealoneType eq 'PET'
&& $homealoneType ne 'PET' )
)
)
{
$state_homealoneType = $homealoneType;
$state_homealoneSubtype = $homealoneSubtype;
}
my $wayhome = ReadingsVal( $presenceDev, "wayhome", 0 ); my $wayhome = ReadingsVal( $presenceDev, "wayhome", 0 );
$wayhome++ if ($wayhome); $wayhome++ if ($wayhome);
@ -1186,7 +1243,7 @@ sub HOMESTATEtk_UpdateReadings (@) {
} }
$state_home = 1 $state_home = 1
unless ( $hash->{RESIDENTS} unless ( $hash->{RESIDENTS}
|| $hash->{SECTIONSTATES} || $hash->{ZONESTATES}
|| $hash->{ROOMSTATES} ); || $hash->{ROOMSTATES} );
# autoMode # autoMode
@ -1229,21 +1286,40 @@ sub HOMESTATEtk_UpdateReadings (@) {
my $newsecurity; my $newsecurity;
# unsecured # unsecured
if ( $state_home > 0 && $mode !~ /^night|midevening$/ ) { if (
$state_home > 0
&& $mode !~ /^night|midevening$/
&& (
!$state_homealoneType
|| (
$state_homealoneType eq 'GUEST'
&& ( $state_homealoneSubtype eq 'guest'
|| $state_homealoneSubtype eq 'generic'
|| $state_homealoneSubtype eq 'domesticWorker'
|| $state_homealoneSubtype eq 'vacationer' )
)
)
)
{
$newsecurity = "unlocked"; $newsecurity = "unlocked";
} }
# locked # locked
elsif ($state_home > 0 elsif (
|| $state_awoken > 0 ( !$state_homealoneType || $state_homealoneType ne 'PET' )
|| $state_gotosleep > 0 && ( $state_home > 0
|| $wakeup > 0 ) || $state_awoken > 0
|| $state_gotosleep > 0
|| $wakeup > 0 )
)
{ {
$newsecurity = "locked"; $newsecurity = "locked";
} }
# night # night or pet at home
elsif ( $state_asleep > 0 ) { elsif ( $state_asleep > 0
|| ( $state_homealoneType && $state_homealoneType eq 'PET' ) )
{
$newsecurity = "protected"; $newsecurity = "protected";
} }
@ -1277,7 +1353,7 @@ sub HOMESTATEtk_UpdateReadings (@) {
# #
# state calculation: # state calculation:
# combine security and mode # combine security, mode and homealone
# #
my $newstate; my $newstate;
my $statesrc; my $statesrc;
@ -1294,16 +1370,48 @@ sub HOMESTATEtk_UpdateReadings (@) {
$statesrc = "security"; $statesrc = "security";
} }
# homealone
if ($state_homealoneType) {
my $hs;
if ( $state_homealoneSubtype eq 'generic'
|| $state_homealoneType eq 'PET' )
{
$hs = $RESIDENTStk_types{en}{$state_homealoneType};
}
else {
$hs = $state_homealoneSubtype;
}
$newstate = $hs . '_' . $newstate;
}
if ( $newstate ne $state ) { if ( $newstate ne $state ) {
readingsBulkUpdate( $hash, "lastState", $state ) if ( $state ne "" ); readingsBulkUpdate( $hash, "lastState", $state ) if ( $state ne "" );
readingsBulkUpdate( $hash, "state", $newstate );
$state = $newstate; $state = $newstate;
readingsBulkUpdate( $hash, "state", $state );
unless ( $lang eq "en" ) { unless ( $lang eq "en" ) {
my $stateL = ReadingsVal( $name, "state_$langUc", "" ); my $stateL = ReadingsVal( $name, "state_$langUc", "" );
readingsBulkUpdate( $hash, "lastState_$langUc", $stateL ) readingsBulkUpdate( $hash, "lastState_$langUc", $stateL )
if ( $stateL ne "" ); if ( $stateL ne "" );
$stateL = ReadingsVal( $name, $statesrc . "_$langUc", "" ); $stateL = ReadingsVal( $name, $statesrc . "_$langUc", "" );
if ($state_homealoneType) {
my $hs;
if ( $state_homealoneSubtype eq 'generic'
|| $state_homealoneType eq 'PET' )
{
$hs = $RESIDENTStk_types{$lang}{$state_homealoneType};
}
else {
$hs = $RESIDENTStk_subTypes{$lang}{$state_homealoneType}[
HOMESTATEtk_GetIndexFromArray( $state_homealoneSubtype,
$RESIDENTStk_subTypes{en}{$state_homealoneType} )
];
}
$stateL = $hs . '_' . $stateL;
}
readingsBulkUpdate( $hash, "state_$langUc", $stateL ); readingsBulkUpdate( $hash, "state_$langUc", $stateL );
} }
} }
@ -1312,7 +1420,6 @@ sub HOMESTATEtk_UpdateReadings (@) {
1; 1;
=pod =pod
=encoding utf8 =encoding utf8

View File

@ -7,7 +7,7 @@ use Data::Dumper;
use Unit; use Unit;
use FHEM::Meta; use FHEM::Meta;
our ( @RESIDENTStk_attr, %RESIDENTStk_subTypes ); our ( @RESIDENTStk_attr, %RESIDENTStk_types, %RESIDENTStk_subTypes );
# module variables ############################################################ # module variables ############################################################
@RESIDENTStk_attr = ( @RESIDENTStk_attr = (
@ -31,10 +31,50 @@ our ( @RESIDENTStk_attr, %RESIDENTStk_subTypes );
"wakeupDevice", "wakeupDevice",
); );
%RESIDENTStk_types = (
en => {
ROOMMATE => 'roommate',
GUEST => 'guest',
PET => 'pet',
},
de => {
ROOMMATE => 'Bewohner',
GUEST => 'Gast',
PET => 'Haustier',
},
);
%RESIDENTStk_subTypes = ( %RESIDENTStk_subTypes = (
ROOMMATE => [ 'baby', 'toddler', 'child', 'teenager', 'adult', 'senior' ], en => {
GUEST => [ 'generic', 'minor', 'domesticWorker', 'vacationer' ], ROOMMATE =>
PET => [ 'generic', 'bird', 'cat', 'dog', 'monkey', 'pig' ] [ 'baby', 'toddler', 'child', 'teenager', 'adult', 'senior' ],
GUEST => [ 'generic', 'childcare', 'domesticWorker', 'vacationer' ],
PET => [ 'generic', 'bird', 'cat', 'dog', 'monkey', 'pig' ]
},
de => {
ROOMMATE => [
'Säugling', 'Kleinkind', 'Kind', 'Teenager',
'Erwachsener', 'Senior'
],
GUEST =>
[ 'generisch', 'Kinderbetreuung', 'Hausangestellter', 'Urlaubsgast' ],
PET => [ 'generisch', 'Vogel', 'Katze', 'Hund', 'Affe', 'Schwein' ]
},
icons => {
ROOMMATE => [
'scene_baby@orange', 'scene_childs_room@orange',
'scene_childs_room@orange', 'people_sensor@orange',
'people_sensor@green', 'people_sensor@orange'
],
GUEST => [
'scene_visit_guests@orange', 'scene_childs_room@orange',
'scene_cleaning@orange', 'scene_visit_guests@orange'
],
PET => [
'dog_silhouette@green', 'dog_silhouette@green',
'dog_silhouette@green', 'dog_silhouette@green',
'dog_silhouette@green', 'dog_silhouette@green'
]
},
); );
## initialize ################################################################# ## initialize #################################################################
@ -1126,8 +1166,8 @@ m/^([a-zA-Z\d._]+(:[A-Za-z\d_\.\-\/]+)?,?)([a-zA-Z\d._]+(:[A-Za-z\d_\.\-\/]+)?,?
return "invalid value $value" return "invalid value $value"
unless ( unless (
$cmd eq "del" $cmd eq "del"
|| defined( $RESIDENTStk_subTypes{$TYPE} ) && grep m/^$value$/, || defined( $RESIDENTStk_subTypes{en}{$TYPE} ) && grep m/^$value$/,
@{ $RESIDENTStk_subTypes{$TYPE} } @{ $RESIDENTStk_subTypes{en}{$TYPE} }
); );
if ( $cmd eq "del" ) { if ( $cmd eq "del" ) {
$hash->{SUBTYPE} = 'generic' $hash->{SUBTYPE} = 'generic'