############################################################################### # $Id$ package main; use strict; use warnings; use Data::Dumper; use Time::Local; require RESIDENTStk; # 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 " . $readingFnAttributes; } # module Fn #################################################################### sub RESIDENTS_UpdateReadings (@) { my ($hash) = @_; my $name = $hash->{NAME}; my $state = ReadingsVal( $name, "state", "none" ); my $presence = ReadingsVal( $name, "presence", "absent" ); my $state_home = 0; my $state_gotosleep = 0; my $state_asleep = 0; my $state_awoken = 0; my $state_absent = 0; my $state_gone = 0; my $state_total = 0; my $state_totalPresent = 0; my $state_totalAbsent = 0; my $state_totalGuests = 0; my $state_totalGuestsPresent = 0; my $state_totalGuestsAbsent = 0; my $state_totalRoommates = 0; my $state_totalRoommatesPresent = 0; my $state_totalRoommatesAbsent = 0; my $state_guestDev = 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_totalAbsentGuest = "-"; my $residentsDevs_totalPresentGuest = "-"; my $residentsDevs_totalAbsentRoommates = "-"; my $residentsDevs_totalPresentRoommates = "-"; 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_totalAbsentGuest = "-"; my $residents_totalPresentGuest = "-"; my $residents_totalAbsentRoommates = "-"; my $residents_totalPresentRoommates = "-"; 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 "" ); # count child states for ROOMMATE devices foreach my $roommate (@registeredRoommates) { $state_total++; $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_totalRoommatesPresent++; $residentsDevs_totalPresent .= "," . $roommate if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $roommate if ( $residentsDevs_totalPresent 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_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_totalRoommatesPresent++; $residentsDevs_totalPresent .= "," . $roommate if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $roommate if ( $residentsDevs_totalPresent 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_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_totalRoommatesPresent++; $residentsDevs_totalPresent .= "," . $roommate if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $roommate if ( $residentsDevs_totalPresent 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_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_totalRoommatesPresent++; $residentsDevs_totalPresent .= "," . $roommate if ( $residentsDevs_totalPresent ne "-" ); $residentsDevs_totalPresent = $roommate if ( $residentsDevs_totalPresent 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_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_totalRoommatesAbsent++; $residentsDevs_totalAbsent .= "," . $roommate if ( $residentsDevs_totalAbsent ne "-" ); $residentsDevs_totalAbsent = $roommate if ( $residentsDevs_totalAbsent 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_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_totalRoommatesAbsent++; $residentsDevs_totalAbsent .= "," . $roommate if ( $residentsDevs_totalAbsent ne "-" ); $residentsDevs_totalAbsent = $roommate if ( $residentsDevs_totalAbsent 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_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 "-" ); } } } # count child states for GUEST devices foreach my $guest (@registeredGuests) { $state_guestDev++; 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_totalGuestsPresent++; $state_totalGuests++; $state_total++; $residentsDevs_totalPresentGuest .= "," . $guest if ( $residentsDevs_totalPresentGuest ne "-" ); $residentsDevs_totalPresentGuest = $guest if ( $residentsDevs_totalPresentGuest eq "-" ); $residents_totalPresentGuest .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentGuest ne "-" ); $residents_totalPresentGuest = $guestName if ( $guestName ne "" && $residents_totalPresentGuest 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_totalGuestsPresent++; $state_totalGuests++; $state_total++; $residentsDevs_totalPresentGuest .= "," . $guest if ( $residentsDevs_totalPresentGuest ne "-" ); $residentsDevs_totalPresentGuest = $guest if ( $residentsDevs_totalPresentGuest eq "-" ); $residents_totalPresentGuest .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentGuest ne "-" ); $residents_totalPresentGuest = $guestName if ( $guestName ne "" && $residents_totalPresentGuest 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_totalGuestsPresent++; $state_totalGuests++; $state_total++; $residentsDevs_totalPresentGuest .= "," . $guest if ( $residentsDevs_totalPresentGuest ne "-" ); $residentsDevs_totalPresentGuest = $guest if ( $residentsDevs_totalPresentGuest eq "-" ); $residents_totalPresentGuest .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentGuest ne "-" ); $residents_totalPresentGuest = $guestName if ( $guestName ne "" && $residents_totalPresentGuest 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_totalGuestsPresent++; $state_totalGuests++; $state_total++; $residentsDevs_totalPresentGuest .= "," . $guest if ( $residentsDevs_totalPresentGuest ne "-" ); $residentsDevs_totalPresentGuest = $guest if ( $residentsDevs_totalPresentGuest eq "-" ); $residents_totalPresentGuest .= ", " . $guestName if ( $guestName ne "" && $residents_totalPresentGuest ne "-" ); $residents_totalPresentGuest = $guestName if ( $guestName ne "" && $residents_totalPresentGuest 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_totalGuestsAbsent++; $state_totalGuests++; $state_total++; $residentsDevs_totalAbsentGuest .= "," . $guest if ( $residentsDevs_totalAbsentGuest ne "-" ); $residentsDevs_totalAbsentGuest = $guest if ( $residentsDevs_totalAbsentGuest eq "-" ); $residents_totalAbsentGuest .= ", " . $guestName if ( $guestName ne "" && $residents_totalAbsentGuest ne "-" ); $residents_totalAbsentGuest = $guestName if ( $guestName ne "" && $residents_totalAbsentGuest 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 "-" ); } } } # update counter readingsBulkUpdateIfChanged( $hash, "residentsTotal", $state_total ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuests", $state_totalGuests ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsPresent", $state_totalGuestsPresent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsPresentDevs", $residentsDevs_totalPresentGuest ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsPresentNames", $residents_totalPresentGuest ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsAbsent", $state_totalGuestsAbsent ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsAbsentDevs", $residentsDevs_totalAbsentGuest ); readingsBulkUpdateIfChanged( $hash, "residentsTotalGuestsAbsentNames", $residents_totalAbsentGuest ); 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, "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_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"; Log3 $name, 4, "RESIDENTS $name: calculation result - residentsTotal:$state_total residentsTotalRoommates:$state_totalRoommates residentsTotalRoommatesPresent:$state_totalRoommatesPresent residentsTotalRoommatesAbsent:$state_totalRoommatesAbsent residentsTotalGuests:$state_totalGuests residentsTotalGuestsPresent:$state_totalGuestsPresent residentsTotalGuestsAbsent:$state_totalGuestsAbsent 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"; # 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", RESIDENTStk_TimeDiff( $datetime, ReadingsVal( $name, "lastSleep", "" ) ) ); readingsBulkUpdate( $hash, "lastDurSleep_cr", RESIDENTStk_TimeDiff( $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", RESIDENTStk_TimeDiff( $datetime, ReadingsVal( $name, "lastDeparture", "-" ) ) ); readingsBulkUpdate( $hash, "lastDurAbsence_cr", RESIDENTStk_TimeDiff( $datetime, ReadingsVal( $name, "lastDeparture", "-" ), "min" ) ); } } else { readingsBulkUpdate( $hash, "lastDeparture", $datetime ); # presence duration if ( ReadingsVal( $name, "lastArrival", "-" ) ne "-" ) { readingsBulkUpdate( $hash, "lastDurPresence", RESIDENTStk_TimeDiff( $datetime, ReadingsVal( $name, "lastArrival", "-" ) ) ); readingsBulkUpdate( $hash, "lastDurPresence_cr", RESIDENTStk_TimeDiff( $datetime, ReadingsVal( $name, "lastArrival", "-" ), "min" ) ); } } } # calculate duration timers RESIDENTStk_DurationTimer( $hash, 1 ); } 1; =pod =item helper =item summary combines ROOMMATE and GUEST devices to a residential community =item summary_de fasst ROOMMATE und GUEST Geräte zu einer Wohngemeinschaft zusammen =begin html

RESIDENTS

=end html =begin html_DE

RESIDENTS

=end html_DE =cut