############################################################################### # $Id$ package main; use strict; use warnings; use POSIX; use RESIDENTStk; our ( %RESIDENTStk_types, %RESIDENTStk_subTypes ); # initialize ################################################################## sub RESIDENTS_Initialize($) { my ($hash) = @_; $hash->{InitDevFn} = "RESIDENTStk_InitializeDev"; $hash->{DefFn} = "RESIDENTStk_Define"; $hash->{UndefFn} = "RESIDENTStk_Undefine"; $hash->{SetFn} = "RESIDENTStk_Set"; $hash->{AttrFn} = "RESIDENTStk_Attr"; $hash->{NotifyFn} = "RESIDENTStk_Notify"; $hash->{AttrPrefix} = "rgr_"; $hash->{AttrList} = "disable:1,0 disabledForIntervals do_not_notify:1,0 " . "rgr_states:multiple-strict,home,gotosleep,asleep,awoken,absent,gone " . "rgr_lang:EN,DE " . "rgr_noDuration:0,1 " . "rgr_showAllStates:0,1 " . "rgr_wakeupDevice " . "rgr_homealoneInStatus:0,1 " . "rgr_homealoneSubTypes:multiple-strict,pet,bird,pig,monkey,cat,dog,baby,toddler,childcare,child,guest,domesticWorker,vacationer,teenager,senior " . $readingFnAttributes; return FHEM::Meta::InitMod( __FILE__, $hash ); } # module Fn #################################################################### sub RESIDENTS_UpdateReadings (@) { my ($hash) = @_; my $name = $hash->{NAME}; my $state = ReadingsVal( $name, "state", "none" ); my $presence = ReadingsVal( $name, "presence", "absent" ); my $homealoneInStatus = AttrVal( $name, 'rgr_homealoneInStatus', '0' ); my @homealoneSubTypes = split( /,/, AttrVal( $name, "rgr_homealoneSubTypes", "pet,bird,pig,monkey,cat,dog,baby,toddler,childcare,child,guest,domesticWorker,vacationer,teenager,senior" ) ); 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_homealone = 1; my $state_totalAbsent = 0; my $state_totalGuests = 0; my $state_totalGuestsPresent = 0; my $state_totalGuestsAbsent = 0; my $state_totalPets = 0; my $state_totalPetsPresent = 0; my $state_totalPetsAbsent = 0; my $state_totalRoommates = 0; my $state_totalRoommatesPresent = 0; my $state_totalRoommatesAbsent = 0; my $state_totalPeople = 0; my $state_totalPeoplePresent = 0; my $state_totalPeopleAbsent = 0; my $residentsDevs_home = "-"; my $residentsDevs_absent = "-"; my $residentsDevs_asleep = "-"; my $residentsDevs_awoken = "-"; my $residentsDevs_gone = "-"; my $residentsDevs_gotosleep = "-"; my $residentsDevs_wakeup = "-"; my $residentsDevs_wayhome = "-"; my $residentsDevs_wayhomeDelayed = "-"; my $residentsDevs_totalAbsent = "-"; my $residentsDevs_totalPresent = "-"; my $residentsDevs_totalAbsentGuests = "-"; my $residentsDevs_totalPresentGuests = "-"; my $residentsDevs_totalAbsentPets = "-"; my $residentsDevs_totalPresentPets = "-"; my $residentsDevs_totalAbsentRoommates = "-"; my $residentsDevs_totalPresentRoommates = "-"; my $residentsDevs_totalAbsentPeople = "-"; my $residentsDevs_totalPresentPeople = "-"; my $residents_home = "-"; my $residents_absent = "-"; my $residents_asleep = "-"; my $residents_awoken = "-"; my $residents_gone = "-"; my $residents_gotosleep = "-"; my $residents_wakeup = "-"; my $residents_wayhome = "-"; my $residents_wayhomeDelayed = "-"; my $residents_totalAbsent = "-"; my $residents_totalPresent = "-"; my $residents_totalAbsentGuests = "-"; my $residents_totalPresentGuests = "-"; my $residents_totalAbsentPets = "-"; my $residents_totalPresentPets = "-"; my $residents_totalAbsentRoommates = "-"; my $residents_totalPresentRoommates = "-"; my $residents_totalAbsentPeople = "-"; my $residents_totalPresentPeople = "-"; my $wayhome = 0; my $wayhomeDelayed = 0; my $wakeup = 0; my $newstate; my @registeredRoommates = split( /,/, $hash->{ROOMMATES} ) if ( defined( $hash->{ROOMMATES} ) && $hash->{ROOMMATES} ne "" ); my @registeredGuests = split( /,/, $hash->{GUESTS} ) if ( defined( $hash->{GUESTS} ) && $hash->{GUESTS} ne "" ); my @registeredPets = split( /,/, $hash->{PETS} ) if ( defined( $hash->{PETS} ) && $hash->{PETS} ne "" ); # count child states for ROOMMATE devices foreach my $roommate (@registeredRoommates) { $state_total++; $state_totalPeople++; $state_totalRoommates++; my $roommateName = AttrVal( $roommate, AttrVal( $roommate, "rr_realname", "group" ), "" ); Log3 $name, 5, "RESIDENTS $name: considering $roommate for state change"; if ( ReadingsVal( $roommate, "state", "initialized" ) eq "home" ) { $state_home++; $residentsDevs_home .= "," . $roommate if ( $residentsDevs_home ne "-" ); $residentsDevs_home = $roommate if ( $residentsDevs_home eq "-" ); $residents_home .= ", " . $roommateName if ( $roommateName ne "" && $residents_home ne "-" ); $residents_home = $roommateName if ( $roommateName ne "" && $residents_home eq "-" ); $state_totalPresent++; $state_totalPeoplePresent++; $state_totalRoommatesPresent++; $residentsDevs_totalPresent .= "," . $roommate if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $roommate if ( $residentsDevs_totalPresent eq "-" ); $residentsDevs_totalPresentPeople .= "," . $roommate if ( $residentsDevs_totalPresentPeople ne "-" ); $residentsDevs_totalPresentPeople = $roommate if ( $residentsDevs_totalPresentPeople eq "-" ); $residentsDevs_totalPresentRoommates .= "," . $roommate if ( $residentsDevs_totalPresentRoommates ne "-" ); $residentsDevs_totalPresentRoommates = $roommate if ( $residentsDevs_totalPresentRoommates eq "-" ); $residents_totalPresent .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $roommateName if ( $roommateName ne "" && $residents_totalPresent eq "-" ); $residents_totalPresentPeople .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresentPeople ne "-" ); $residents_totalPresentPeople = $roommateName if ( $roommateName ne "" && $residents_totalPresentPeople eq "-" ); $residents_totalPresentRoommates .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresentRoommates ne "-" ); $residents_totalPresentRoommates = $roommateName if ( $roommateName ne "" && $residents_totalPresentRoommates eq "-" ); } elsif ( ReadingsVal( $roommate, "state", "initialized" ) eq "gotosleep" ) { $state_gotosleep++; $residentsDevs_gotosleep .= "," . $roommate if ( $residentsDevs_gotosleep ne "-" ); $residentsDevs_gotosleep = $roommate if ( $residentsDevs_gotosleep eq "-" ); $residents_gotosleep .= ", " . $roommateName if ( $roommateName ne "" && $residents_gotosleep ne "-" ); $residents_gotosleep = $roommateName if ( $roommateName ne "" && $residents_gotosleep eq "-" ); $state_totalPresent++; $state_totalPeoplePresent++; $state_totalRoommatesPresent++; $residentsDevs_totalPresent .= "," . $roommate if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $roommate if ( $residentsDevs_totalPresent eq "-" ); $residentsDevs_totalPresentPeople .= "," . $roommate if ( $residentsDevs_totalPresentPeople ne "-" ); $residentsDevs_totalPresentPeople = $roommate if ( $residentsDevs_totalPresentPeople eq "-" ); $residentsDevs_totalPresentRoommates .= "," . $roommate if ( $residentsDevs_totalPresentRoommates ne "-" ); $residentsDevs_totalPresentRoommates = $roommate if ( $residentsDevs_totalPresentRoommates eq "-" ); $residents_totalPresent .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $roommateName if ( $roommateName ne "" && $residents_totalPresent eq "-" ); $residents_totalPresentPeople .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresentPeople ne "-" ); $residents_totalPresentPeople = $roommateName if ( $roommateName ne "" && $residents_totalPresentPeople eq "-" ); $residents_totalPresentRoommates .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresentRoommates ne "-" ); $residents_totalPresentRoommates = $roommateName if ( $roommateName ne "" && $residents_totalPresentRoommates eq "-" ); } elsif ( ReadingsVal( $roommate, "state", "initialized" ) eq "asleep" ) { $state_asleep++; $residentsDevs_asleep .= "," . $roommate if ( $residentsDevs_asleep ne "-" ); $residentsDevs_asleep = $roommate if ( $residentsDevs_asleep eq "-" ); $residents_asleep .= ", " . $roommateName if ( $roommateName ne "" && $residents_asleep ne "-" ); $residents_asleep = $roommateName if ( $roommateName ne "" && $residents_asleep eq "-" ); $state_totalPresent++; $state_totalPeoplePresent++; $state_totalRoommatesPresent++; $residentsDevs_totalPresent .= "," . $roommate if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $roommate if ( $residentsDevs_totalPresent eq "-" ); $residentsDevs_totalPresentPeople .= "," . $roommate if ( $residentsDevs_totalPresentPeople ne "-" ); $residentsDevs_totalPresentPeople = $roommate if ( $residentsDevs_totalPresentPeople eq "-" ); $residentsDevs_totalPresentRoommates .= "," . $roommate if ( $residentsDevs_totalPresentRoommates ne "-" ); $residentsDevs_totalPresentRoommates = $roommate if ( $residentsDevs_totalPresentRoommates eq "-" ); $residents_totalPresent .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $roommateName if ( $roommateName ne "" && $residents_totalPresent eq "-" ); $residents_totalPresentPeople .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresentPeople ne "-" ); $residents_totalPresentPeople = $roommateName if ( $roommateName ne "" && $residents_totalPresentPeople eq "-" ); $residents_totalPresentRoommates .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresentRoommates ne "-" ); $residents_totalPresentRoommates = $roommateName if ( $roommateName ne "" && $residents_totalPresentRoommates eq "-" ); } elsif ( ReadingsVal( $roommate, "state", "initialized" ) eq "awoken" ) { $state_awoken++; $residentsDevs_awoken .= "," . $roommate if ( $residentsDevs_awoken ne "-" ); $residentsDevs_awoken = $roommate if ( $residentsDevs_awoken eq "-" ); $residents_awoken .= ", " . $roommateName if ( $roommateName ne "" && $residents_awoken ne "-" ); $residents_awoken = $roommateName if ( $roommateName ne "" && $residents_awoken eq "-" ); $state_totalPresent++; $state_totalPeoplePresent++; $state_totalRoommatesPresent++; $residentsDevs_totalPresent .= "," . $roommate if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $roommate if ( $residentsDevs_totalPresent eq "-" ); $residentsDevs_totalPresentPeople .= "," . $roommate if ( $residentsDevs_totalPresentPeople ne "-" ); $residentsDevs_totalPresentPeople = $roommate if ( $residentsDevs_totalPresentPeople eq "-" ); $residentsDevs_totalPresentRoommates .= "," . $roommate if ( $residentsDevs_totalPresentRoommates ne "-" ); $residentsDevs_totalPresentRoommates = $roommate if ( $residentsDevs_totalPresentRoommates eq "-" ); $residents_totalPresent .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $roommateName if ( $roommateName ne "" && $residents_totalPresent eq "-" ); $residents_totalPresentPeople .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresentPeople ne "-" ); $residents_totalPresentPeople = $roommateName if ( $roommateName ne "" && $residents_totalPresentPeople eq "-" ); $residents_totalPresentRoommates .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalPresentRoommates ne "-" ); $residents_totalPresentRoommates = $roommateName if ( $roommateName ne "" && $residents_totalPresentRoommates eq "-" ); } elsif ( ReadingsVal( $roommate, "state", "initialized" ) eq "absent" ) { $state_absent++; $residentsDevs_absent .= "," . $roommate if ( $residentsDevs_absent ne "-" ); $residentsDevs_absent = $roommate if ( $residentsDevs_absent eq "-" ); $residents_absent .= ", " . $roommateName if ( $roommateName ne "" && $residents_absent ne "-" ); $residents_absent = $roommateName if ( $roommateName ne "" && $residents_absent eq "-" ); $state_totalAbsent++; $state_totalPeopleAbsent++; $state_totalRoommatesAbsent++; $residentsDevs_totalAbsent .= "," . $roommate if ( $residentsDevs_totalAbsent ne "-" ); $residentsDevs_totalAbsent = $roommate if ( $residentsDevs_totalAbsent eq "-" ); $residentsDevs_totalAbsentPeople .= "," . $roommate if ( $residentsDevs_totalAbsentPeople ne "-" ); $residentsDevs_totalAbsentPeople = $roommate if ( $residentsDevs_totalAbsentPeople eq "-" ); $residentsDevs_totalAbsentRoommates .= "," . $roommate if ( $residentsDevs_totalAbsentRoommates ne "-" ); $residentsDevs_totalAbsentRoommates = $roommate if ( $residentsDevs_totalAbsentRoommates eq "-" ); $residents_totalAbsent .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalAbsent ne "-" ); $residents_totalAbsent = $roommateName if ( $roommateName ne "" && $residents_totalAbsent eq "-" ); $residents_totalAbsentPeople .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalAbsentPeople ne "-" ); $residents_totalAbsentPeople = $roommateName if ( $roommateName ne "" && $residents_totalAbsentPeople eq "-" ); $residents_totalAbsentRoommates .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalAbsentRoommates ne "-" ); $residents_totalAbsentRoommates = $roommateName if ( $roommateName ne "" && $residents_totalAbsentRoommates eq "-" ); } elsif ( ReadingsVal( $roommate, "state", "initialized" ) eq "gone" ) { $state_gone++; $residentsDevs_gone .= "," . $roommate if ( $residentsDevs_gone ne "-" ); $residentsDevs_gone = $roommate if ( $residentsDevs_gone eq "-" ); $residents_gone .= ", " . $roommateName if ( $roommateName ne "" && $residents_gone ne "-" ); $residents_gone = $roommateName if ( $roommateName ne "" && $residents_gone eq "-" ); $state_totalAbsent++; $state_totalPeopleAbsent++; $state_totalRoommatesAbsent++; $residentsDevs_totalAbsent .= "," . $roommate if ( $residentsDevs_totalAbsent ne "-" ); $residentsDevs_totalAbsent = $roommate if ( $residentsDevs_totalAbsent eq "-" ); $residentsDevs_totalAbsentPeople .= "," . $roommate if ( $residentsDevs_totalAbsentPeople ne "-" ); $residentsDevs_totalAbsentPeople = $roommate if ( $residentsDevs_totalAbsentPeople eq "-" ); $residentsDevs_totalAbsentRoommates .= "," . $roommate if ( $residentsDevs_totalAbsentRoommates ne "-" ); $residentsDevs_totalAbsentRoommates = $roommate if ( $residentsDevs_totalAbsentRoommates eq "-" ); $residents_totalAbsent .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalAbsent ne "-" ); $residents_totalAbsent = $roommateName if ( $roommateName ne "" && $residents_totalAbsent eq "-" ); $residents_totalAbsentPeople .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalAbsentPeople ne "-" ); $residents_totalAbsentPeople = $roommateName if ( $roommateName ne "" && $residents_totalAbsentPeople eq "-" ); $residents_totalAbsentRoommates .= ", " . $roommateName if ( $roommateName ne "" && $residents_totalAbsentRoommates ne "-" ); $residents_totalAbsentRoommates = $roommateName if ( $roommateName ne "" && $residents_totalAbsentRoommates eq "-" ); } if ( ReadingsVal( $roommate, "wakeup", "0" ) > 0 ) { $wakeup++; $residentsDevs_wakeup .= "," . $roommate if ( $residentsDevs_wakeup ne "-" ); $residentsDevs_wakeup = $roommate if ( $residentsDevs_wakeup eq "-" ); $residents_wakeup .= ", " . $roommateName if ( $roommateName ne "" && $residents_wakeup ne "-" ); $residents_wakeup = $roommateName if ( $roommateName ne "" && $residents_wakeup eq "-" ); } if ( ReadingsVal( $roommate, "wayhome", "0" ) > 0 ) { $wayhome++; $residentsDevs_wayhome .= "," . $roommate if ( $residentsDevs_wayhome ne "-" ); $residentsDevs_wayhome = $roommate if ( $residentsDevs_wayhome eq "-" ); $residents_wayhome .= ", " . $roommateName if ( $roommateName ne "" && $residents_wayhome ne "-" ); $residents_wayhome = $roommateName if ( $roommateName ne "" && $residents_wayhome eq "-" ); if ( ReadingsVal( $roommate, "wayhome", "0" ) == 2 ) { $wayhomeDelayed++; $residentsDevs_wayhomeDelayed .= "," . $roommate if ( $residentsDevs_wayhomeDelayed ne "-" ); $residentsDevs_wayhomeDelayed = $roommate if ( $residentsDevs_wayhomeDelayed eq "-" ); $residents_wayhomeDelayed .= ", " . $roommateName if ( $roommateName ne "" && $residents_wayhomeDelayed ne "-" ); $residents_wayhomeDelayed = $roommateName if ( $roommateName ne "" && $residents_wayhomeDelayed eq "-" ); } } if ( $state_homealone && ReadingsVal( $roommate, "presence", "absent" ) eq "present" ) { my $TYPE = GetType($roommate); my $SubType = defined( $defs{$roommate}{SUBTYPE} ) ? $defs{$roommate}{SUBTYPE} : 'adult'; $state_homealone = 0 unless ( grep m/^$SubType$/, @homealoneSubTypes ); } } # count child states for PET devices foreach my $pet (@registeredPets) { $state_total++; $state_totalPets++; my $petName = AttrVal( $pet, AttrVal( $pet, "rp_realname", "group" ), "" ); Log3 $name, 5, "RESIDENTS $name: considering $pet for state change"; if ( ReadingsVal( $pet, "state", "initialized" ) eq "home" ) { $state_home++; $residentsDevs_home .= "," . $pet if ( $residentsDevs_home ne "-" ); $residentsDevs_home = $pet if ( $residentsDevs_home eq "-" ); $residents_home .= ", " . $petName if ( $petName ne "" && $residents_home ne "-" ); $residents_home = $petName if ( $petName ne "" && $residents_home eq "-" ); $state_totalPresent++; $state_totalPetsPresent++; $residentsDevs_totalPresent .= "," . $pet if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $pet if ( $residentsDevs_totalPresent eq "-" ); $residentsDevs_totalPresentPets .= "," . $pet if ( $residentsDevs_totalPresentPets ne "-" ); $residentsDevs_totalPresentPets = $pet if ( $residentsDevs_totalPresentPets eq "-" ); $residents_totalPresent .= ", " . $petName if ( $petName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $petName if ( $petName ne "" && $residents_totalPresent eq "-" ); $residents_totalPresentPets .= ", " . $petName if ( $petName ne "" && $residents_totalPresentPets ne "-" ); $residents_totalPresentPets = $petName if ( $petName ne "" && $residents_totalPresentPets eq "-" ); } elsif ( ReadingsVal( $pet, "state", "initialized" ) eq "gotosleep" ) { $state_gotosleep++; $residentsDevs_gotosleep .= "," . $pet if ( $residentsDevs_gotosleep ne "-" ); $residentsDevs_gotosleep = $pet if ( $residentsDevs_gotosleep eq "-" ); $residents_gotosleep .= ", " . $petName if ( $petName ne "" && $residents_gotosleep ne "-" ); $residents_gotosleep = $petName if ( $petName ne "" && $residents_gotosleep eq "-" ); $state_totalPresent++; $state_totalPetsPresent++; $residentsDevs_totalPresent .= "," . $pet if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $pet if ( $residentsDevs_totalPresent eq "-" ); $residentsDevs_totalPresentPets .= "," . $pet if ( $residentsDevs_totalPresentPets ne "-" ); $residentsDevs_totalPresentPets = $pet if ( $residentsDevs_totalPresentPets eq "-" ); $residents_totalPresent .= ", " . $petName if ( $petName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $petName if ( $petName ne "" && $residents_totalPresent eq "-" ); $residents_totalPresentPets .= ", " . $petName if ( $petName ne "" && $residents_totalPresentPets ne "-" ); $residents_totalPresentPets = $petName if ( $petName ne "" && $residents_totalPresentPets eq "-" ); } elsif ( ReadingsVal( $pet, "state", "initialized" ) eq "asleep" ) { $state_asleep++; $residentsDevs_asleep .= "," . $pet if ( $residentsDevs_asleep ne "-" ); $residentsDevs_asleep = $pet if ( $residentsDevs_asleep eq "-" ); $residents_asleep .= ", " . $petName if ( $petName ne "" && $residents_asleep ne "-" ); $residents_asleep = $petName if ( $petName ne "" && $residents_asleep eq "-" ); $state_totalPresent++; $state_totalPetsPresent++; $residentsDevs_totalPresent .= "," . $pet if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $pet if ( $residentsDevs_totalPresent eq "-" ); $residentsDevs_totalPresentPets .= "," . $pet if ( $residentsDevs_totalPresentPets ne "-" ); $residentsDevs_totalPresentPets = $pet if ( $residentsDevs_totalPresentPets eq "-" ); $residents_totalPresent .= ", " . $petName if ( $petName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $petName if ( $petName ne "" && $residents_totalPresent eq "-" ); $residents_totalPresentPets .= ", " . $petName if ( $petName ne "" && $residents_totalPresentPets ne "-" ); $residents_totalPresentPets = $petName if ( $petName ne "" && $residents_totalPresentPets eq "-" ); } elsif ( ReadingsVal( $pet, "state", "initialized" ) eq "awoken" ) { $state_awoken++; $residentsDevs_awoken .= "," . $pet if ( $residentsDevs_awoken ne "-" ); $residentsDevs_awoken = $pet if ( $residentsDevs_awoken eq "-" ); $residents_awoken .= ", " . $petName if ( $petName ne "" && $residents_awoken ne "-" ); $residents_awoken = $petName if ( $petName ne "" && $residents_awoken eq "-" ); $state_totalPresent++; $state_totalPetsPresent++; $residentsDevs_totalPresent .= "," . $pet if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $pet if ( $residentsDevs_totalPresent eq "-" ); $residentsDevs_totalPresentPets .= "," . $pet if ( $residentsDevs_totalPresentPets ne "-" ); $residentsDevs_totalPresentPets = $pet if ( $residentsDevs_totalPresentPets eq "-" ); $residents_totalPresent .= ", " . $petName if ( $petName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $petName if ( $petName ne "" && $residents_totalPresent eq "-" ); $residents_totalPresentPets .= ", " . $petName if ( $petName ne "" && $residents_totalPresentPets ne "-" ); $residents_totalPresentPets = $petName if ( $petName ne "" && $residents_totalPresentPets eq "-" ); } elsif ( ReadingsVal( $pet, "state", "initialized" ) eq "absent" ) { $state_absent++; $residentsDevs_absent .= "," . $pet if ( $residentsDevs_absent ne "-" ); $residentsDevs_absent = $pet if ( $residentsDevs_absent eq "-" ); $residents_absent .= ", " . $petName if ( $petName ne "" && $residents_absent ne "-" ); $residents_absent = $petName if ( $petName ne "" && $residents_absent eq "-" ); $state_totalAbsent++; $state_totalPetsAbsent++; $residentsDevs_totalAbsent .= "," . $pet if ( $residentsDevs_totalAbsent ne "-" ); $residentsDevs_totalAbsent = $pet if ( $residentsDevs_totalAbsent eq "-" ); $residentsDevs_totalAbsentPets .= "," . $pet if ( $residentsDevs_totalAbsentPets ne "-" ); $residentsDevs_totalAbsentPets = $pet if ( $residentsDevs_totalAbsentPets eq "-" ); $residents_totalAbsent .= ", " . $petName if ( $petName ne "" && $residents_totalAbsent ne "-" ); $residents_totalAbsent = $petName if ( $petName ne "" && $residents_totalAbsent eq "-" ); $residents_totalAbsentPets .= ", " . $petName if ( $petName ne "" && $residents_totalAbsentPets ne "-" ); $residents_totalAbsentPets = $petName if ( $petName ne "" && $residents_totalAbsentPets eq "-" ); } elsif ( ReadingsVal( $pet, "state", "initialized" ) eq "gone" ) { $state_gone++; $residentsDevs_gone .= "," . $pet if ( $residentsDevs_gone ne "-" ); $residentsDevs_gone = $pet if ( $residentsDevs_gone eq "-" ); $residents_gone .= ", " . $petName if ( $petName ne "" && $residents_gone ne "-" ); $residents_gone = $petName if ( $petName ne "" && $residents_gone eq "-" ); $state_totalAbsent++; $state_totalPetsAbsent++; $residentsDevs_totalAbsent .= "," . $pet if ( $residentsDevs_totalAbsent ne "-" ); $residentsDevs_totalAbsent = $pet if ( $residentsDevs_totalAbsent eq "-" ); $residentsDevs_totalAbsentPets .= "," . $pet if ( $residentsDevs_totalAbsentPets ne "-" ); $residentsDevs_totalAbsentPets = $pet if ( $residentsDevs_totalAbsentPets eq "-" ); $residents_totalAbsent .= ", " . $petName if ( $petName ne "" && $residents_totalAbsent ne "-" ); $residents_totalAbsent = $petName if ( $petName ne "" && $residents_totalAbsent eq "-" ); $residents_totalAbsentPets .= ", " . $petName if ( $petName ne "" && $residents_totalAbsentPets ne "-" ); $residents_totalAbsentPets = $petName if ( $petName ne "" && $residents_totalAbsentPets eq "-" ); } if ( ReadingsVal( $pet, "wakeup", "0" ) > 0 ) { $wakeup++; $residentsDevs_wakeup .= "," . $pet if ( $residentsDevs_wakeup ne "-" ); $residentsDevs_wakeup = $pet if ( $residentsDevs_wakeup eq "-" ); $residents_wakeup .= ", " . $petName if ( $petName ne "" && $residents_wakeup ne "-" ); $residents_wakeup = $petName if ( $petName ne "" && $residents_wakeup eq "-" ); } if ( ReadingsVal( $pet, "wayhome", "0" ) > 0 ) { $wayhome++; $residentsDevs_wayhome .= "," . $pet if ( $residentsDevs_wayhome ne "-" ); $residentsDevs_wayhome = $pet if ( $residentsDevs_wayhome eq "-" ); $residents_wayhome .= ", " . $petName if ( $petName ne "" && $residents_wayhome ne "-" ); $residents_wayhome = $petName if ( $petName ne "" && $residents_wayhome eq "-" ); if ( ReadingsVal( $pet, "wayhome", "0" ) == 2 ) { $wayhomeDelayed++; $residentsDevs_wayhomeDelayed .= "," . $pet if ( $residentsDevs_wayhomeDelayed ne "-" ); $residentsDevs_wayhomeDelayed = $pet if ( $residentsDevs_wayhomeDelayed eq "-" ); $residents_wayhomeDelayed .= ", " . $petName if ( $petName ne "" && $residents_wayhomeDelayed ne "-" ); $residents_wayhomeDelayed = $petName if ( $petName ne "" && $residents_wayhomeDelayed eq "-" ); } } if ( $state_homealone && ReadingsVal( $pet, "presence", "absent" ) eq "present" ) { my $TYPE = GetType($pet); my $SubType = defined( $defs{$pet}{SUBTYPE} ) ? $defs{$pet}{SUBTYPE} : 'generic'; $SubType = 'pet' if ( $SubType eq 'generic' ); $state_homealone = 0 unless ( grep m/^$SubType$/, @homealoneSubTypes ); } } # count child states for GUEST devices foreach my $guest (@registeredGuests) { my $guestName = AttrVal( $guest, AttrVal( $guest, "rg_realname", "group" ), "" ); Log3 $name, 5, "RESIDENTS $name: considering $guest for state change"; if ( ReadingsVal( $guest, "state", "initialized" ) eq "home" ) { $state_home++; $state_totalPresent++; $state_totalPeoplePresent++; $state_totalGuestsPresent++; $state_totalPeople++; $state_totalGuests++; $state_total++; $residentsDevs_totalPresentPeople .= "," . $guest if ( $residentsDevs_totalPresentPeople ne "-" ); $residentsDevs_totalPresentPeople = $guest if ( $residentsDevs_totalPresentPeople eq "-" ); $residentsDevs_totalPresentGuests .= "," . $guest if ( $residentsDevs_totalPresentGuests ne "-" ); $residentsDevs_totalPresentGuests = $guest if ( $residentsDevs_totalPresentGuests eq "-" ); $residents_totalPresentPeople .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentPeople ne "-" ); $residents_totalPresentPeople = $guestName if ( $guestName ne "" && $residents_totalPresentPeople eq "-" ); $residents_totalPresentGuests .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentGuests ne "-" ); $residents_totalPresentGuests = $guestName if ( $guestName ne "" && $residents_totalPresentGuests eq "-" ); $residentsDevs_totalPresent .= "," . $guest if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $guest if ( $residentsDevs_totalPresent eq "-" ); $residents_totalPresent .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $guestName if ( $guestName ne "" && $residents_totalPresent eq "-" ); } elsif ( ReadingsVal( $guest, "state", "initialized" ) eq "gotosleep" ) { $state_gotosleep++; $state_totalPresent++; $state_totalPeoplePresent++; $state_totalGuestsPresent++; $state_totalPeople++; $state_totalGuests++; $state_total++; $residentsDevs_totalPresentPeople .= "," . $guest if ( $residentsDevs_totalPresentPeople ne "-" ); $residentsDevs_totalPresentPeople = $guest if ( $residentsDevs_totalPresentPeople eq "-" ); $residentsDevs_totalPresentGuests .= "," . $guest if ( $residentsDevs_totalPresentGuests ne "-" ); $residentsDevs_totalPresentGuests = $guest if ( $residentsDevs_totalPresentGuests eq "-" ); $residents_totalPresentPeople .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentPeople ne "-" ); $residents_totalPresentPeople = $guestName if ( $guestName ne "" && $residents_totalPresentPeople eq "-" ); $residents_totalPresentGuests .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentGuests ne "-" ); $residents_totalPresentGuests = $guestName if ( $guestName ne "" && $residents_totalPresentGuests eq "-" ); $residentsDevs_totalPresent .= "," . $guest if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $guest if ( $residentsDevs_totalPresent eq "-" ); $residents_totalPresent .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $guestName if ( $guestName ne "" && $residents_totalPresent eq "-" ); } elsif ( ReadingsVal( $guest, "state", "initialized" ) eq "asleep" ) { $state_asleep++; $state_totalPresent++; $state_totalPeoplePresent++; $state_totalGuestsPresent++; $state_totalPeople++; $state_totalGuests++; $state_total++; $residentsDevs_totalPresentPeople .= "," . $guest if ( $residentsDevs_totalPresentPeople ne "-" ); $residentsDevs_totalPresentPeople = $guest if ( $residentsDevs_totalPresentPeople eq "-" ); $residentsDevs_totalPresentGuests .= "," . $guest if ( $residentsDevs_totalPresentGuests ne "-" ); $residentsDevs_totalPresentGuests = $guest if ( $residentsDevs_totalPresentGuests eq "-" ); $residents_totalPresentPeople .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentPeople ne "-" ); $residents_totalPresentPeople = $guestName if ( $guestName ne "" && $residents_totalPresentPeople eq "-" ); $residents_totalPresentGuests .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentGuests ne "-" ); $residents_totalPresentGuests = $guestName if ( $guestName ne "" && $residents_totalPresentGuests eq "-" ); $residentsDevs_totalPresent .= "," . $guest if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $guest if ( $residentsDevs_totalPresent eq "-" ); $residents_totalPresent .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $guestName if ( $guestName ne "" && $residents_totalPresent eq "-" ); } elsif ( ReadingsVal( $guest, "state", "initialized" ) eq "awoken" ) { $state_awoken++; $state_totalPresent++; $state_totalPeoplePresent++; $state_totalGuestsPresent++; $state_totalPeople++; $state_totalGuests++; $state_total++; $residentsDevs_totalPresentPeople .= "," . $guest if ( $residentsDevs_totalPresentPeople ne "-" ); $residentsDevs_totalPresentPeople = $guest if ( $residentsDevs_totalPresentPeople eq "-" ); $residentsDevs_totalPresentGuests .= "," . $guest if ( $residentsDevs_totalPresentGuests ne "-" ); $residentsDevs_totalPresentGuests = $guest if ( $residentsDevs_totalPresentGuests eq "-" ); $residents_totalPresentPeople .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentPeople ne "-" ); $residents_totalPresentPeople = $guestName if ( $guestName ne "" && $residents_totalPresentPeople eq "-" ); $residents_totalPresentGuests .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentGuests ne "-" ); $residents_totalPresentGuests = $guestName if ( $guestName ne "" && $residents_totalPresentGuests eq "-" ); $residentsDevs_totalPresent .= "," . $guest if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $guest if ( $residentsDevs_totalPresent eq "-" ); $residents_totalPresent .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresent ne "-" ); $residents_totalPresent = $guestName if ( $guestName ne "" && $residents_totalPresent eq "-" ); } elsif ( ReadingsVal( $guest, "state", "initialized" ) eq "absent" ) { $state_absent++; $state_totalAbsent++; $state_totalPeopleAbsent++; $state_totalGuestsAbsent++; $state_totalPeople++; $state_totalGuests++; $state_total++; $residentsDevs_totalAbsentPeople .= "," . $guest if ( $residentsDevs_totalAbsentPeople ne "-" ); $residentsDevs_totalAbsentPeople = $guest if ( $residentsDevs_totalAbsentPeople eq "-" ); $residentsDevs_totalAbsentGuests .= "," . $guest if ( $residentsDevs_totalAbsentGuests ne "-" ); $residentsDevs_totalAbsentGuests = $guest if ( $residentsDevs_totalAbsentGuests eq "-" ); $residents_totalAbsentPeople .= ", " . $guestName if ( $guestName ne "" && $residents_totalAbsentPeople ne "-" ); $residents_totalAbsentPeople = $guestName if ( $guestName ne "" && $residents_totalAbsentPeople eq "-" ); $residents_totalAbsentGuests .= ", " . $guestName if ( $guestName ne "" && $residents_totalAbsentGuests ne "-" ); $residents_totalAbsentGuests = $guestName if ( $guestName ne "" && $residents_totalAbsentGuests eq "-" ); $residentsDevs_totalAbsent .= "," . $guest if ( $residentsDevs_totalAbsent ne "-" ); $residentsDevs_totalAbsent = $guest if ( $residentsDevs_totalAbsent eq "-" ); $residents_totalAbsent .= ", " . $guestName if ( $guestName ne "" && $residents_totalAbsent ne "-" ); $residents_totalAbsent = $guestName if ( $guestName ne "" && $residents_totalAbsent eq "-" ); } if ( ReadingsVal( $guest, "wakeup", "0" ) > 0 ) { $wakeup++; $residentsDevs_wakeup .= "," . $guest if ( $residentsDevs_wakeup ne "-" ); $residentsDevs_wakeup = $guest if ( $residentsDevs_wakeup eq "-" ); $residents_wakeup .= ", " . $guestName if ( $guestName ne "" && $residents_wakeup ne "-" ); $residents_wakeup = $guestName if ( $guestName ne "" && $residents_wakeup eq "-" ); } if ( ReadingsVal( $guest, "wayhome", "0" ) > 0 ) { $wayhome++; $residents_wayhome .= "," . $guest if ( $residents_wayhome ne "-" ); $residents_wayhome = $guest if ( $residents_wayhome eq "-" ); $residents_wayhome .= ", " . $guestName if ( $guestName ne "" && $residents_wayhome ne "-" ); $residents_wayhome = $guestName if ( $guestName ne "" && $residents_wayhome eq "-" ); if ( ReadingsVal( $guest, "wayhome", "0" ) == 2 ) { $wayhomeDelayed++; $residentsDevs_wayhomeDelayed .= "," . $guest if ( $residentsDevs_wayhomeDelayed ne "-" ); $residentsDevs_wayhomeDelayed = $guest if ( $residentsDevs_wayhomeDelayed eq "-" ); $residents_wayhomeDelayed .= ", " . $guestName if ( $guestName ne "" && $residents_wayhomeDelayed ne "-" ); $residents_wayhomeDelayed = $guestName if ( $guestName ne "" && $residents_wayhomeDelayed eq "-" ); } } if ( $state_homealone && ReadingsVal( $guest, "presence", "absent" ) eq "present" ) { my $TYPE = GetType($guest); my $SubType = defined( $defs{$guest}{SUBTYPE} ) ? $defs{$guest}{SUBTYPE} : 'generic'; $SubType = 'guest' if ( $SubType eq 'generic' ); $state_homealone = 0 unless ( grep m/^$SubType$/, @homealoneSubTypes ); } } # update counter readingsBulkUpdateIfChanged( $hash, "residentsTotal", $state_total ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuests", $state_totalGuests ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPets", $state_totalPets ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsPresent", $state_totalGuestsPresent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPetsPresent", $state_totalPetsPresent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsPresentDevs", $residentsDevs_totalPresentGuests ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPetsPresentDevs", $residentsDevs_totalPresentPets ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsPresentNames", $residents_totalPresentGuests ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPetsPresentNames", $residents_totalPresentPets ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsAbsent", $state_totalGuestsAbsent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPetsAbsent", $state_totalPetsAbsent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsAbsentDevs", $residentsDevs_totalAbsentGuests ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPetsAbsentDevs", $residentsDevs_totalAbsentPets ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsAbsentNames", $residents_totalAbsentGuests ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPetsAbsentNames", $residents_totalAbsentPets ); readingsBulkUpdateIfChanged( $hash, "residentsTotalRoommates", $state_totalRoommates ); readingsBulkUpdateIfChanged( $hash, "residentsTotalRoommatesPresent", $state_totalRoommatesPresent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalRoommatesPresentDevs", $residentsDevs_totalPresentRoommates ); readingsBulkUpdateIfChanged( $hash, "residentsTotalRoommatesPresentNames", $residents_totalPresentRoommates ); readingsBulkUpdateIfChanged( $hash, "residentsTotalRoommatesAbsent", $state_totalRoommatesAbsent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalRoommatesAbsentDevs", $residentsDevs_totalAbsentRoommates ); readingsBulkUpdateIfChanged( $hash, "residentsTotalRoommatesAbsentNames", $residents_totalAbsentRoommates ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPeople", $state_totalPeople ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPeoplePresent", $state_totalPeoplePresent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPeoplePresentDevs", $residentsDevs_totalPresentPeople ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPeoplePresentNames", $residents_totalPresentPeople ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPeopleAbsent", $state_totalPeopleAbsent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPeopleAbsentDevs", $residentsDevs_totalAbsentPeople ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPeopleAbsentNames", $residents_totalAbsentPeople ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPresent", $state_totalPresent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPresentDevs", $residentsDevs_totalPresent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalPresentNames", $residents_totalPresent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalAbsent", $state_totalAbsent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalAbsentDevs", $residentsDevs_totalAbsent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalAbsentNames", $residents_totalAbsent ); readingsBulkUpdateIfChanged( $hash, "residentsHome", $state_home ); readingsBulkUpdateIfChanged( $hash, "residentsHomeDevs", $residentsDevs_home ); readingsBulkUpdateIfChanged( $hash, "residentsHomeNames", $residents_home ); readingsBulkUpdateIfChanged( $hash, "residentsGotosleep", $state_gotosleep ); readingsBulkUpdateIfChanged( $hash, "residentsGotosleepDevs", $residentsDevs_gotosleep ); readingsBulkUpdateIfChanged( $hash, "residentsGotosleepNames", $residents_gotosleep ); readingsBulkUpdateIfChanged( $hash, "residentsAsleep", $state_asleep ); readingsBulkUpdateIfChanged( $hash, "residentsAsleepDevs", $residentsDevs_asleep ); readingsBulkUpdateIfChanged( $hash, "residentsAsleepNames", $residents_asleep ); readingsBulkUpdateIfChanged( $hash, "residentsAwoken", $state_awoken ); readingsBulkUpdateIfChanged( $hash, "residentsAwokenDevs", $residentsDevs_awoken ); readingsBulkUpdateIfChanged( $hash, "residentsAwokenNames", $residents_awoken ); readingsBulkUpdateIfChanged( $hash, "residentsAbsent", $state_absent ); readingsBulkUpdateIfChanged( $hash, "residentsAbsentDevs", $residentsDevs_absent ); readingsBulkUpdateIfChanged( $hash, "residentsAbsentNames", $residents_absent ); readingsBulkUpdateIfChanged( $hash, "residentsGone", $state_gone ); readingsBulkUpdateIfChanged( $hash, "residentsGoneDevs", $residentsDevs_gone ); readingsBulkUpdateIfChanged( $hash, "residentsGoneNames", $residents_gone ); readingsBulkUpdateIfChanged( $hash, "residentsTotalWakeup", $wakeup ); readingsBulkUpdateIfChanged( $hash, "residentsTotalWakeupDevs", $residentsDevs_wakeup ); readingsBulkUpdateIfChanged( $hash, "residentsTotalWakeupNames", $residents_wakeup ); readingsBulkUpdateIfChanged( $hash, "residentsTotalWayhome", $wayhome ); readingsBulkUpdateIfChanged( $hash, "residentsTotalWayhomeDevs", $residentsDevs_wayhome ); readingsBulkUpdateIfChanged( $hash, "residentsTotalWayhomeNames", $residents_wayhome ); readingsBulkUpdateIfChanged( $hash, "residentsTotalWayhomeDelayed", $wayhomeDelayed ); readingsBulkUpdateIfChanged( $hash, "residentsTotalWayhomeDelayedDevs", $residentsDevs_wayhomeDelayed ); readingsBulkUpdateIfChanged( $hash, "residentsTotalWayhomeDelayedNames", $residents_wayhomeDelayed ); # # 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_totalPets == 0 && $state_totalRoommates == 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 my $newpresence = ( $newstate ne "none" && $newstate ne "gone" && $newstate ne "absent" ) ? "present" : "absent"; # calculate homealone state $state_homealone = 0 if ( $newpresence eq "absent" ); my $homealone_type; my $homealone_subtype; my $newstate_prefix; if ($state_homealone) { foreach my $obj ( split( /,/, $residentsDevs_totalPresent ) ) { my $TYPE = GetType($obj); next unless $TYPE; my $subtype = 'generic'; $subtype = InternalVal( $obj, 'SUBTYPE', 'generic' ) if ( $TYPE eq 'PET' ); $subtype = InternalVal( $obj, 'SUBTYPE', 'adult' ) if ( $TYPE eq 'ROOMMATE' ); $subtype = InternalVal( $obj, 'SUBTYPE', 'generic' ) if ( $TYPE eq 'GUEST' ); $subtype = $RESIDENTStk_types{en}{$TYPE} if ( $subtype eq 'generic' ); my $importance = 99; my (@index) = grep { $homealoneSubTypes[$_] eq $subtype } 0 .. scalar @homealoneSubTypes - 1; $importance = $index[0] if ( scalar @index ); my $importance2 = 99; if ($homealone_subtype) { my (@index2) = grep { $homealoneSubTypes[$_] eq $homealone_subtype } 0 .. scalar @homealoneSubTypes - 1; $importance2 = $index2[0] if ( scalar @index2 ); } $homealone_type = $TYPE if ( !$homealone_type || $importance2 < $importance ); $homealone_subtype = $subtype if ( !$homealone_subtype || $importance2 < $importance ); $newstate_prefix = ( $TYPE eq 'PET' ? 'pet' : $subtype ) if ( !$newstate_prefix || $importance2 < $importance ); } } readingsBulkUpdateIfChanged( $hash, "lastHomealoneType", ReadingsVal( $name, "homealoneType", "-" ) ) if ( ReadingsVal( $name, "homealoneType", undef ) ); readingsBulkUpdateIfChanged( $hash, "lastHomealoneSubtype", ReadingsVal( $name, "homealoneSubtype", "-" ) ) if ( ReadingsVal( $name, "homealoneSubtype", undef ) ); readingsBulkUpdateIfChanged( $hash, "homealoneType", $homealone_type ? $homealone_type : '-' ); readingsBulkUpdateIfChanged( $hash, "homealoneSubtype", $homealone_subtype ? $homealone_subtype : '-' ); $newstate = $newstate_prefix . '_' . $newstate if ( $homealoneInStatus ne '0' && $newstate_prefix ); Log3 $name, 4, "RESIDENTS $name: calculation result - residentsTotal:$state_total residentsTotalRoommates:$state_totalRoommates residentsTotalRoommatesPresent:$state_totalRoommatesPresent residentsTotalRoommatesAbsent:$state_totalRoommatesAbsent residentsTotalGuests:$state_totalGuests residentsTotalPets:$state_totalPets residentsTotalGuestsPresent:$state_totalGuestsPresent residentsTotalPetsPresent:$state_totalPetsPresent residentsTotalGuestsAbsent:$state_totalGuestsAbsent residentsTotalPetsAbsent:$state_totalPetsAbsent 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:$newpresence state:$newstate homealone:$state_homealone"; # safe current time my $datetime = FmtDateTime(time); # if state changed if ( $state ne $newstate ) { # stop any running wakeup-timers in case state changed my $wakeupState = AttrVal( $name, "wakeup", 0 ); if ($wakeupState) { my $wakeupDeviceList = AttrVal( $name, "rgr_wakeupDevice", 0 ); for my $wakeupDevice ( split /,/, $wakeupDeviceList ) { next if !$wakeupDevice; if ( IsDevice( $wakeupDevice, "dummy" ) ) { # forced-stop only if resident is not present anymore if ( $newpresence eq "present" ) { fhem "set $wakeupDevice:FILTER=running!=0 end"; } else { fhem "set $wakeupDevice:FILTER=running!=0 stop"; } } } } # if newstate is asleep, start sleep timer readingsBulkUpdate( $hash, "lastSleep", $datetime ) if ( $newstate eq "asleep" ); # if prior state was asleep, update sleep statistics if ( $state eq "asleep" && ReadingsVal( $name, "lastSleep", "" ) ne "" ) { readingsBulkUpdate( $hash, "lastAwake", $datetime ); readingsBulkUpdate( $hash, "lastDurSleep", UConv::duration( $datetime, ReadingsVal( $name, "lastSleep", "" ) ) ); readingsBulkUpdate( $hash, "lastDurSleep_cr", UConv::duration( $datetime, ReadingsVal( $name, "lastSleep", "" ), "min" ) ); } readingsBulkUpdate( $hash, "lastState", ReadingsVal( $name, "state", "initialized" ) ); readingsBulkUpdate( $hash, "state", $newstate ); } # if presence changed if ( $newpresence ne $presence ) { readingsBulkUpdate( $hash, "presence", $newpresence ); # update statistics if ( $newpresence eq "present" ) { readingsBulkUpdate( $hash, "lastArrival", $datetime ); # absence duration if ( ReadingsVal( $name, "lastDeparture", "-" ) ne "-" ) { readingsBulkUpdate( $hash, "lastDurAbsence", UConv::duration( $datetime, ReadingsVal( $name, "lastDeparture", "-" ) ) ); readingsBulkUpdate( $hash, "lastDurAbsence_cr", UConv::duration( $datetime, ReadingsVal( $name, "lastDeparture", "-" ), "min" ) ); } } else { readingsBulkUpdate( $hash, "lastDeparture", $datetime ); # presence duration if ( ReadingsVal( $name, "lastArrival", "-" ) ne "-" ) { readingsBulkUpdate( $hash, "lastDurPresence", UConv::duration( $datetime, ReadingsVal( $name, "lastArrival", "-" ) ) ); readingsBulkUpdate( $hash, "lastDurPresence_cr", UConv::duration( $datetime, ReadingsVal( $name, "lastArrival", "-" ), "min" ) ); } } } # calculate duration timers RESIDENTStk_DurationTimer( $hash, 1 ); } 1; =pod =item helper =item summary combines ROOMMATE, GUEST and PET devices to a residential community =item summary_de fasst ROOMMATE, GUEST und PET Geräte zu einer Wohngemeinschaft zusammen =begin html

RESIDENTS

=end html =begin html_DE

RESIDENTS

=end html_DE =for :application/json;q=META.json 10_RESIDENTS.pm { "author": [ "Julian Pawlowski " ], "x_fhem_maintainer": [ "loredo" ], "x_fhem_maintainer_github": [ "jpawlowski" ], "keywords": [ "Attendence", "Family", "People", "Presence", "RESIDENTS" ] } =end :application/json;q=META.json =cut