diff --git a/fhem/FHEM/10_RESIDENTS.pm b/fhem/FHEM/10_RESIDENTS.pm index b3e0bc1f1..bc0cb2e24 100644 --- a/fhem/FHEM/10_RESIDENTS.pm +++ b/fhem/FHEM/10_RESIDENTS.pm @@ -151,8 +151,8 @@ sub RESIDENTS_Notify($$) { foreach my $change ( @{ $dev->{CHANGED} } ) { - Log3 $dev->{NAME}, 5, - "RESIDENTS " . $dev->{NAME} . ": processing change $change"; + Log3 $hash, 5, + "RESIDENTS " . $hashName . ": processing change $change"; # state changed if ( $change !~ /:/ @@ -199,7 +199,8 @@ sub RESIDENTS_Notify($$) { # update statistics readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "lastActivity", ReadingsVal($devName, "state", $change) ); + readingsBulkUpdate( $hash, "lastActivity", + ReadingsVal( $devName, "state", $change ) ); readingsBulkUpdate( $hash, "lastActivityBy", $realname ); readingsBulkUpdate( $hash, "lastActivityByDev", $devName ); readingsEndUpdate( $hash, 1 ); @@ -257,13 +258,10 @@ sub RESIDENTS_Notify($$) { ################################### sub RESIDENTS_Set($@) { my ( $hash, @a ) = @_; - my $name = $hash->{NAME}; - my $state = - ( defined( $hash->{READINGS}{state}{VAL} ) ) - ? $hash->{READINGS}{state}{VAL} - : "initialized"; + my $name = $hash->{NAME}; + my $state = ReadingsVal( $name, "state", "initialized" ); my $roommates = ( $hash->{ROOMMATES} ? $hash->{ROOMMATES} : "" ); - my $guests = ( $hash->{GUESTS} ? $hash->{GUESTS} : "" ); + my $guests = ( $hash->{GUESTS} ? $hash->{GUESTS} : "" ); Log3 $name, 5, "RESIDENTS $name: called function RESIDENTS_Set()"; @@ -350,11 +348,9 @@ sub RESIDENTS_Set($@) { split( /,/, $hash->{ROOMMATES} ); foreach my $roommate (@registeredRoommates) { - if ( defined( $defs{$roommate} ) - && $defs{$roommate}{READINGS}{state} ne $newstate ) - { - fhem "set $roommate silentSet state $newstate"; - } + fhem "set $roommate silentSet state $newstate" + if ( ReadingsVal( $roommate, "state", "initialized" ) ne + $newstate ); } } @@ -368,12 +364,9 @@ sub RESIDENTS_Set($@) { split( /,/, $hash->{GUESTS} ); foreach my $guest (@registeredGuests) { - if ( defined( $defs{$guest} ) - && $defs{$guest}{READINGS}{state}{VAL} ne "none" - && $defs{$guest}{READINGS}{state}{VAL} ne $newstate ) - { - fhem "set $guest silentSet state $newstate"; - } + fhem "set $guest silentSet state $newstate" + if ( ReadingsVal( $guest, "state", "initialized" ) ne + $newstate ); } } } @@ -642,61 +635,55 @@ sub RESIDENTS_Set($@) { sub RESIDENTS_UpdateReadings (@) { my ($hash) = @_; my $name = $hash->{NAME}; - my $state = - ( defined( $hash->{READINGS}{state}{VAL} ) ) - ? $hash->{READINGS}{state}{VAL} - : "none"; - my $presence = - ( defined( $hash->{READINGS}{presence}{VAL} ) ) - ? $hash->{READINGS}{presence}{VAL} - : "absent"; + 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_totalAbsent = "-"; - my $residentsDevs_totalPresent = "-"; - my $residentsDevs_totalAbsentGuest = "-"; - my $residentsDevs_totalPresentGuest = "-"; + 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_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_totalAbsent = "-"; - my $residents_totalPresent = "-"; - my $residents_totalAbsentGuest = "-"; - my $residents_totalPresentGuest = "-"; + 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_totalAbsent = "-"; + my $residents_totalPresent = "-"; + my $residents_totalAbsentGuest = "-"; + my $residents_totalPresentGuest = "-"; my $residents_totalAbsentRoommates = "-"; my $residents_totalPresentRoommates = "-"; - my $wayhome = 0; - my $wakeup = 0; + my $wayhome = 0; + my $wakeup = 0; my $newstate; my @registeredRoommates = @@ -721,198 +708,208 @@ sub RESIDENTS_UpdateReadings (@) { Log3 $name, 5, "RESIDENTS $name: considering $roommate for state change"; - if ( defined( $defs{$roommate}{READINGS}{state}{VAL} ) ) { - if ( $defs{$roommate}{READINGS}{state}{VAL} 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 "-" ); + 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 ( $defs{$roommate}{READINGS}{state}{VAL} 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 ( $defs{$roommate}{READINGS}{state}{VAL} 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 ( $defs{$roommate}{READINGS}{state}{VAL} 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 ( $defs{$roommate}{READINGS}{state}{VAL} 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 ( $defs{$roommate}{READINGS}{state}{VAL} 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 "-" ); - } + $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 "-" ); } - if ( defined( $defs{$roommate}{READINGS}{wakeup}{VAL} ) - && $defs{$roommate}{READINGS}{wakeup}{VAL} > 0 ) + elsif ( + ReadingsVal( $roommate, "state", "initialized" ) eq "gotosleep" ) { - $wakeup += $defs{$roommate}{READINGS}{wakeup}{VAL}; + $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 += ReadingsVal( $name, "wakeup", "0" ); $residentsDevs_wakeup .= "," . $roommate if ( $residentsDevs_wakeup ne "-" ); $residentsDevs_wakeup = $roommate @@ -923,10 +920,8 @@ sub RESIDENTS_UpdateReadings (@) { if ( $roommateName ne "" && $residents_wakeup eq "-" ); } - if ( defined( $defs{$roommate}{READINGS}{wayhome}{VAL} ) - && $defs{$roommate}{READINGS}{wayhome}{VAL} > 0 ) - { - $wayhome += $defs{$roommate}{READINGS}{wayhome}{VAL}; + if ( ReadingsVal( $roommate, "wayhome", "0" ) > 0 ) { + $wayhome += ReadingsVal( $name, "wayhome", "0" ); $residents_wayhome .= "," . $roommate if ( $residents_wayhome ne "-" ); $residents_wayhome = $roommate if ( $residents_wayhome eq "-" ); @@ -946,162 +941,158 @@ sub RESIDENTS_UpdateReadings (@) { Log3 $name, 5, "RESIDENTS $name: considering $guest for state change"; - if ( defined( $defs{$guest}{READINGS}{state}{VAL} ) ) { - if ( $defs{$guest}{READINGS}{state}{VAL} eq "home" ) { - $state_home++; - $state_totalPresent++; - $state_totalGuestsPresent++; - $state_totalGuests++; - $state_total++; + 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_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 ( $defs{$guest}{READINGS}{state}{VAL} 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 ( $defs{$guest}{READINGS}{state}{VAL} 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 ( $defs{$guest}{READINGS}{state}{VAL} 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 ( $defs{$guest}{READINGS}{state}{VAL} 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 "-" ); - } + $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 "-" ); } - if ( defined( $defs{$guest}{READINGS}{wakeup}{VAL} ) - && $defs{$guest}{READINGS}{wakeup}{VAL} > 0 ) - { - $wakeup += $defs{$guest}{READINGS}{wakeup}{VAL}; + 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 += ReadingsVal( $guest, "wakeup", "0" ); $residentsDevs_wakeup .= "," . $guest if ( $residentsDevs_wakeup ne "-" ); $residentsDevs_wakeup = $guest @@ -1112,10 +1103,8 @@ sub RESIDENTS_UpdateReadings (@) { if ( $guestName ne "" && $residents_wakeup eq "-" ); } - if ( defined( $defs{$guest}{READINGS}{wayhome}{VAL} ) - && $defs{$guest}{READINGS}{wayhome}{VAL} > 0 ) - { - $wayhome += $defs{$guest}{READINGS}{wayhome}{VAL}; + if ( ReadingsVal( $guest, "wayhome", "0" ) > 0 ) { + $wayhome += ReadingsVal( $guest, "wakeup", "0" ); $residents_wayhome .= "," . $guest if ( $residents_wayhome ne "-" ); $residents_wayhome = $guest if ( $residents_wayhome eq "-" ); @@ -1141,17 +1130,15 @@ sub RESIDENTS_UpdateReadings (@) { readingsBeginUpdate($hash); readingsBulkUpdate( $hash, "residentsTotal", $state_total ) - if ( !defined( $hash->{READINGS}{residentsTotal}{VAL} ) - || $hash->{READINGS}{residentsTotal}{VAL} ne $state_total ); + if ( ReadingsVal( $name, "residentsTotal", "" ) ne $state_total ); readingsBulkUpdate( $hash, "residentsTotalGuests", $state_totalGuests ) - if ( !defined( $hash->{READINGS}{residentsTotalGuests}{VAL} ) - || $hash->{READINGS}{residentsTotalGuests}{VAL} ne $state_totalGuests ); + if ( ReadingsVal( $name, "residentsTotalGuests", "" ) ne + $state_totalGuests ); readingsBulkUpdate( $hash, "residentsTotalGuestsPresent", $state_totalGuestsPresent ) - if ( !defined( $hash->{READINGS}{residentsTotalGuestsPresent}{VAL} ) - || $hash->{READINGS}{residentsTotalGuestsPresent}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalGuestsPresent", "" ) ne $state_totalGuestsPresent ); readingsBulkUpdate( @@ -1159,20 +1146,17 @@ sub RESIDENTS_UpdateReadings (@) { "residentsTotalGuestsPresentDevs", $residentsDevs_totalPresentGuest ) - if ( !defined( $hash->{READINGS}{residentsTotalGuestsPresentDevs}{VAL} ) - || $hash->{READINGS}{residentsTotalGuestsPresentDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalGuestsPresentDevs", "" ) ne $residentsDevs_totalPresentGuest ); readingsBulkUpdate( $hash, "residentsTotalGuestsPresentNames", $residents_totalPresentGuest ) - if ( !defined( $hash->{READINGS}{residentsTotalGuestsPresentNames}{VAL} ) - || $hash->{READINGS}{residentsTotalGuestsPresentNames}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalGuestsPresentNames", "" ) ne $residents_totalPresentGuest ); readingsBulkUpdate( $hash, "residentsTotalGuestsAbsent", $state_totalGuestsAbsent ) - if ( !defined( $hash->{READINGS}{residentsTotalGuestsAbsent}{VAL} ) - || $hash->{READINGS}{residentsTotalGuestsAbsent}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalGuestsAbsent", "" ) ne $state_totalGuestsAbsent ); readingsBulkUpdate( @@ -1180,24 +1164,22 @@ sub RESIDENTS_UpdateReadings (@) { "residentsTotalGuestsAbsentDevs", $residentsDevs_totalAbsentGuest ) - if ( !defined( $hash->{READINGS}{residentsTotalGuestsAbsentDevs}{VAL} ) - || $hash->{READINGS}{residentsTotalGuestsAbsentDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalGuestsAbsentDevs", "" ) ne $residentsDevs_totalAbsentGuest ); readingsBulkUpdate( $hash, "residentsTotalGuestsAbsentNames", $residents_totalAbsentGuest ) - if ( !defined( $hash->{READINGS}{residentsTotalGuestsAbsentNames}{VAL} ) - || $hash->{READINGS}{residentsTotalGuestsAbsentNames}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalGuestsAbsentNames", "" ) ne $residents_totalAbsentGuest ); - readingsBulkUpdate( $hash, "residentsTotalRoommates", $state_totalRoommates ) - if ( !defined( $hash->{READINGS}{residentsTotalRoommates}{VAL} ) - || $hash->{READINGS}{residentsTotalRoommates}{VAL} ne $state_totalRoommates ); + readingsBulkUpdate( $hash, "residentsTotalRoommates", + $state_totalRoommates ) + if ( ReadingsVal( $name, "residentsTotalRoommates", "" ) ne + $state_totalRoommates ); readingsBulkUpdate( $hash, "residentsTotalRoommatesPresent", $state_totalRoommatesPresent ) - if ( !defined( $hash->{READINGS}{residentsTotalRoommatesPresent}{VAL} ) - || $hash->{READINGS}{residentsTotalRoommatesPresent}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalRoommatesPresent", "" ) ne $state_totalRoommatesPresent ); readingsBulkUpdate( @@ -1205,20 +1187,20 @@ sub RESIDENTS_UpdateReadings (@) { "residentsTotalRoommatesPresentDevs", $residentsDevs_totalPresentRoommates ) - if ( !defined( $hash->{READINGS}{residentsTotalRoommatesPresentDevs}{VAL} ) - || $hash->{READINGS}{residentsTotalRoommatesPresentDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalRoommatesPresentDevs", "" ) ne $residentsDevs_totalPresentRoommates ); - readingsBulkUpdate( $hash, "residentsTotalRoommatesPresentNames", - $residents_totalPresentRoommates ) - if ( !defined( $hash->{READINGS}{residentsTotalRoommatesPresentNames}{VAL} ) - || $hash->{READINGS}{residentsTotalRoommatesPresentNames}{VAL} ne + readingsBulkUpdate( + $hash, + "residentsTotalRoommatesPresentNames", + $residents_totalPresentRoommates + ) + if ( ReadingsVal( $name, "residentsTotalRoommatesPresentNames", "" ) ne $residents_totalPresentRoommates ); readingsBulkUpdate( $hash, "residentsTotalRoommatesAbsent", $state_totalRoommatesAbsent ) - if ( !defined( $hash->{READINGS}{residentsTotalRoommatesAbsent}{VAL} ) - || $hash->{READINGS}{residentsTotalRoommatesAbsent}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalRoommatesAbsent", "" ) ne $state_totalRoommatesAbsent ); readingsBulkUpdate( @@ -1226,156 +1208,133 @@ sub RESIDENTS_UpdateReadings (@) { "residentsTotalRoommatesAbsentDevs", $residentsDevs_totalAbsentRoommates ) - if ( !defined( $hash->{READINGS}{residentsTotalRoommatesAbsentDevs}{VAL} ) - || $hash->{READINGS}{residentsTotalRoommatesAbsentDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalRoommatesAbsentDevs", "" ) ne $residentsDevs_totalAbsentRoommates ); - readingsBulkUpdate( $hash, "residentsTotalRoommatesAbsentNames", - $residents_totalAbsentRoommates ) - if ( !defined( $hash->{READINGS}{residentsTotalRoommatesAbsentNames}{VAL} ) - || $hash->{READINGS}{residentsTotalRoommatesAbsentNames}{VAL} ne + readingsBulkUpdate( + $hash, + "residentsTotalRoommatesAbsentNames", + $residents_totalAbsentRoommates + ) + if ( ReadingsVal( $name, "residentsTotalRoommatesAbsentNames", "" ) ne $residents_totalAbsentRoommates ); readingsBulkUpdate( $hash, "residentsTotalPresent", $state_totalPresent ) - if ( !defined( $hash->{READINGS}{residentsTotalPresent}{VAL} ) - || $hash->{READINGS}{residentsTotalPresent}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalPresent", "" ) ne $state_totalPresent ); readingsBulkUpdate( $hash, "residentsTotalPresentDevs", $residentsDevs_totalPresent ) - if ( !defined( $hash->{READINGS}{residentsTotalPresentDevs}{VAL} ) - || $hash->{READINGS}{residentsTotalPresentDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalPresentDevs", "" ) ne $residentsDevs_totalPresent ); readingsBulkUpdate( $hash, "residentsTotalPresentNames", $residents_totalPresent ) - if ( !defined( $hash->{READINGS}{residentsTotalPresentNames}{VAL} ) - || $hash->{READINGS}{residentsTotalPresentNames}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalPresentNames", "" ) ne $residents_totalPresent ); readingsBulkUpdate( $hash, "residentsTotalAbsent", $state_totalAbsent ) - if ( !defined( $hash->{READINGS}{residentsTotalAbsent}{VAL} ) - || $hash->{READINGS}{residentsTotalAbsent}{VAL} ne $state_totalAbsent ); + if ( ReadingsVal( $name, "residentsTotalAbsent", "" ) ne + $state_totalAbsent ); readingsBulkUpdate( $hash, "residentsTotalAbsentDevs", $residentsDevs_totalAbsent ) - if ( !defined( $hash->{READINGS}{residentsTotalAbsentDevs}{VAL} ) - || $hash->{READINGS}{residentsTotalAbsentDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalAbsentDevs", "" ) ne $residentsDevs_totalAbsent ); readingsBulkUpdate( $hash, "residentsTotalAbsentNames", $residents_totalAbsent ) - if ( !defined( $hash->{READINGS}{residentsTotalAbsentNames}{VAL} ) - || $hash->{READINGS}{residentsTotalAbsentNames}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalAbsentNames", "" ) ne $residents_totalAbsent ); readingsBulkUpdate( $hash, "residentsHome", $state_home ) - if ( !defined( $hash->{READINGS}{residentsHome}{VAL} ) - || $hash->{READINGS}{residentsHome}{VAL} ne $state_home ); + if ( ReadingsVal( $name, "residentsHome", "" ) ne $state_home ); readingsBulkUpdate( $hash, "residentsHomeDevs", $residentsDevs_home ) - if ( !defined( $hash->{READINGS}{residentsHomeDevs}{VAL} ) - || $hash->{READINGS}{residentsHomeDevs}{VAL} ne $residentsDevs_home ); + if ( + ReadingsVal( $name, "residentsHomeDevs", "" ) ne $residentsDevs_home ); readingsBulkUpdate( $hash, "residentsHomeNames", $residents_home ) - if ( !defined( $hash->{READINGS}{residentsHomeNames}{VAL} ) - || $hash->{READINGS}{residentsHomeNames}{VAL} ne $residents_home ); + if ( ReadingsVal( $name, "residentsHomeNames", "" ) ne $residents_home ); readingsBulkUpdate( $hash, "residentsGotosleep", $state_gotosleep ) - if ( !defined( $hash->{READINGS}{residentsGotosleep}{VAL} ) - || $hash->{READINGS}{residentsGotosleep}{VAL} ne $state_gotosleep ); + if ( ReadingsVal( $name, "residentsGotosleep", "" ) ne $state_gotosleep ); readingsBulkUpdate( $hash, "residentsGotosleepDevs", $residentsDevs_gotosleep ) - if ( !defined( $hash->{READINGS}{residentsGotosleepDevs}{VAL} ) - || $hash->{READINGS}{residentsGotosleepDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsGotosleepDevs", "" ) ne $residentsDevs_gotosleep ); readingsBulkUpdate( $hash, "residentsGotosleepNames", $residents_gotosleep ) - if ( !defined( $hash->{READINGS}{residentsGotosleepNames}{VAL} ) - || $hash->{READINGS}{residentsGotosleepNames}{VAL} ne + if ( ReadingsVal( $name, "residentsGotosleepNames", "" ) ne $residents_gotosleep ); readingsBulkUpdate( $hash, "residentsAsleep", $state_asleep ) - if ( !defined( $hash->{READINGS}{residentsAsleep}{VAL} ) - || $hash->{READINGS}{residentsAsleep}{VAL} ne $state_asleep ); + if ( ReadingsVal( $name, "residentsAsleep", "" ) ne $state_asleep ); readingsBulkUpdate( $hash, "residentsAsleepDevs", $residentsDevs_asleep ) - if ( !defined( $hash->{READINGS}{residentsAsleepDevs}{VAL} ) - || $hash->{READINGS}{residentsAsleepDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsAsleepDevs", "" ) ne $residentsDevs_asleep ); readingsBulkUpdate( $hash, "residentsAsleepNames", $residents_asleep ) - if ( !defined( $hash->{READINGS}{residentsAsleepNames}{VAL} ) - || $hash->{READINGS}{residentsAsleepNames}{VAL} ne $residents_asleep ); + if ( + ReadingsVal( $name, "residentsAsleepNames", "" ) ne $residents_asleep ); readingsBulkUpdate( $hash, "residentsAwoken", $state_awoken ) - if ( !defined( $hash->{READINGS}{residentsAwoken}{VAL} ) - || $hash->{READINGS}{residentsAwoken}{VAL} ne $state_awoken ); + if ( ReadingsVal( $name, "residentsAwoken", "" ) ne $state_awoken ); readingsBulkUpdate( $hash, "residentsAwokenDevs", $residentsDevs_awoken ) - if ( !defined( $hash->{READINGS}{residentsAwokenDevs}{VAL} ) - || $hash->{READINGS}{residentsAwokenDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsAwokenDevs", "" ) ne $residentsDevs_awoken ); readingsBulkUpdate( $hash, "residentsAwokenNames", $residents_awoken ) - if ( !defined( $hash->{READINGS}{residentsAwokenNames}{VAL} ) - || $hash->{READINGS}{residentsAwokenNames}{VAL} ne $residents_awoken ); + if ( + ReadingsVal( $name, "residentsAwokenNames", "" ) ne $residents_awoken ); readingsBulkUpdate( $hash, "residentsAbsent", $state_absent ) - if ( !defined( $hash->{READINGS}{residentsAbsent}{VAL} ) - || $hash->{READINGS}{residentsAbsent}{VAL} ne $state_absent ); + if ( ReadingsVal( $name, "residentsAbsent", "" ) ne $state_absent ); readingsBulkUpdate( $hash, "residentsAbsentDevs", $residentsDevs_absent ) - if ( !defined( $hash->{READINGS}{residentsAbsentDevs}{VAL} ) - || $hash->{READINGS}{residentsAbsentDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsAbsentDevs", "" ) ne $residentsDevs_absent ); readingsBulkUpdate( $hash, "residentsAbsentNames", $residents_absent ) - if ( !defined( $hash->{READINGS}{residentsAbsentNames}{VAL} ) - || $hash->{READINGS}{residentsAbsentNames}{VAL} ne $residents_absent ); + if ( + ReadingsVal( $name, "residentsAbsentNames", "" ) ne $residents_absent ); readingsBulkUpdate( $hash, "residentsGone", $state_gone ) - if ( !defined( $hash->{READINGS}{residentsGone}{VAL} ) - || $hash->{READINGS}{residentsGone}{VAL} ne $state_gone ); + if ( ReadingsVal( $name, "residentsGone", "" ) ne $state_gone ); readingsBulkUpdate( $hash, "residentsGoneDevs", $residentsDevs_gone ) - if ( !defined( $hash->{READINGS}{residentsGoneDevs}{VAL} ) - || $hash->{READINGS}{residentsGoneDevs}{VAL} ne $residentsDevs_gone ); + if ( + ReadingsVal( $name, "residentsGoneDevs", "" ) ne $residentsDevs_gone ); readingsBulkUpdate( $hash, "residentsGoneNames", $residents_gone ) - if ( !defined( $hash->{READINGS}{residentsGoneNames}{VAL} ) - || $hash->{READINGS}{residentsGoneNames}{VAL} ne $residents_gone ); + if ( ReadingsVal( $name, "residentsGoneNames", "" ) ne $residents_gone ); readingsBulkUpdate( $hash, "residentsTotalWakeup", $wakeup ) - if ( !defined( $hash->{READINGS}{residentsTotalWakeup}{VAL} ) - || $hash->{READINGS}{residentsTotalWakeup}{VAL} ne $wakeup ); + if ( ReadingsVal( $name, "residentsTotalWakeup", "" ) ne $wakeup ); readingsBulkUpdate( $hash, "residentsTotalWakeupDevs", $residentsDevs_wakeup ) - if ( !defined( $hash->{READINGS}{residentsTotalWakeupDevs}{VAL} ) - || $hash->{READINGS}{residentsTotalWakeupDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalWakeupDevs", "" ) ne $residentsDevs_wakeup ); readingsBulkUpdate( $hash, "residentsTotalWakeupNames", $residents_wakeup ) - if ( !defined( $hash->{READINGS}{residentsTotalWakeupNames}{VAL} ) - || $hash->{READINGS}{residentsTotalWakeupNames}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalWakeupNames", "" ) ne $residents_wakeup ); readingsBulkUpdate( $hash, "residentsTotalWayhome", $wayhome ) - if ( !defined( $hash->{READINGS}{residentsTotalWayhome}{VAL} ) - || $hash->{READINGS}{residentsTotalWayhome}{VAL} ne $wayhome ); + if ( ReadingsVal( $name, "residentsTotalWayhome", "" ) ne $wayhome ); readingsBulkUpdate( $hash, "residentsTotalWayhomeDevs", $residentsDevs_wayhome ) - if ( !defined( $hash->{READINGS}{residentsTotalWayhomeDevs}{VAL} ) - || $hash->{READINGS}{residentsTotalWayhomeDevs}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalWayhomeDevs", "" ) ne $residentsDevs_wayhome ); readingsBulkUpdate( $hash, "residentsTotalWayhomeNames", $residents_wayhome ) - if ( !defined( $hash->{READINGS}{residentsTotalWayhomeNames}{VAL} ) - || $hash->{READINGS}{residentsTotalWayhomeNames}{VAL} ne + if ( ReadingsVal( $name, "residentsTotalWayhomeNames", "" ) ne $residents_wayhome ); # @@ -1499,28 +1458,29 @@ sub RESIDENTS_UpdateReadings (@) { if ( $newstate eq "asleep" ); # if prior state was asleep, update sleep statistics - if ( defined( $hash->{READINGS}{state}{VAL} ) - && $state eq "asleep" ) + if ( $state eq "asleep" + && ReadingsVal( $name, "lastSleep", "" ) ne "" ) { readingsBulkUpdate( $hash, "lastAwake", $datetime ); readingsBulkUpdate( $hash, "lastDurSleep", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastSleep}{VAL} + $datetime, ReadingsVal( $name, "lastSleep", "" ) ) ); readingsBulkUpdate( $hash, "lastDurSleep_cr", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastSleep}{VAL}, "min" + $datetime, ReadingsVal( $name, "lastSleep", "" ), "min" ) ); } - readingsBulkUpdate( $hash, "lastState", $hash->{READINGS}{state}{VAL} ); - readingsBulkUpdate( $hash, "state", $newstate ); + readingsBulkUpdate( $hash, "lastState", + ReadingsVal( $name, "state", "initialized" ) ); + readingsBulkUpdate( $hash, "state", $newstate ); } # if presence changed @@ -1532,21 +1492,19 @@ sub RESIDENTS_UpdateReadings (@) { readingsBulkUpdate( $hash, "lastArrival", $datetime ); # absence duration - if ( defined( $hash->{READINGS}{lastDeparture}{VAL} ) - && $hash->{READINGS}{lastDeparture}{VAL} ne "-" ) - { + if ( ReadingsVal( $name, "lastDeparture", "-" ) ne "-" ) { readingsBulkUpdate( $hash, "lastDurAbsence", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastDeparture}{VAL} + $datetime, ReadingsVal( $name, "lastDeparture", "-" ) ) ); readingsBulkUpdate( $hash, "lastDurAbsence_cr", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastDeparture}{VAL}, + $datetime, ReadingsVal( $name, "lastDeparture", "-" ), "min" ) ); @@ -1556,21 +1514,19 @@ sub RESIDENTS_UpdateReadings (@) { readingsBulkUpdate( $hash, "lastDeparture", $datetime ); # presence duration - if ( defined( $hash->{READINGS}{lastArrival}{VAL} ) - && $hash->{READINGS}{lastArrival}{VAL} ne "-" ) - { + if ( ReadingsVal( $name, "lastArrival", "-" ) ne "-" ) { readingsBulkUpdate( $hash, "lastDurPresence", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastArrival}{VAL} + $datetime, ReadingsVal( $name, "lastArrival", "-" ) ) ); readingsBulkUpdate( $hash, "lastDurPresence_cr", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastArrival}{VAL}, + $datetime, ReadingsVal( $name, "lastArrival", "-" ), "min" ) ); diff --git a/fhem/FHEM/20_GUEST.pm b/fhem/FHEM/20_GUEST.pm index da75a42c3..30ceedd7e 100644 --- a/fhem/FHEM/20_GUEST.pm +++ b/fhem/FHEM/20_GUEST.pm @@ -144,7 +144,7 @@ sub GUEST_Define($$) { # trigger for modified objects unless ( $modified == 0 ) { - readingsBulkUpdate( $hash, "state", $hash->{READINGS}{state}{VAL} ); + readingsBulkUpdate( $hash, "state", ReadingsVal( $name, "state", "" ) ); } readingsEndUpdate( $hash, 1 ); @@ -256,24 +256,12 @@ sub GUEST_Notify($$) { ################################### sub GUEST_Set($@) { my ( $hash, @a ) = @_; - my $name = $hash->{NAME}; - my $state = - ( defined( $hash->{READINGS}{state}{VAL} ) ) - ? $hash->{READINGS}{state}{VAL} - : "initialized"; - my $presence = - ( defined( $hash->{READINGS}{presence}{VAL} ) ) - ? $hash->{READINGS}{presence}{VAL} - : "undefined"; - my $mood = - ( defined( $hash->{READINGS}{mood}{VAL} ) ) - ? $hash->{READINGS}{mood}{VAL} - : "-"; - my $location = - ( defined( $hash->{READINGS}{location}{VAL} ) ) - ? $hash->{READINGS}{location}{VAL} - : "undefined"; - my $silent = 0; + my $name = $hash->{NAME}; + my $state = ReadingsVal( $name, "state", "initialized" ); + my $presence = ReadingsVal( $name, "presence", "undefined" ); + my $mood = ReadingsVal( $name, "mood", "-" ); + my $location = ReadingsVal( $name, "location", "undefined" ); + my $silent = 0; Log3 $name, 5, "GUEST $name: called function GUEST_Set()"; @@ -441,21 +429,22 @@ sub GUEST_Set($@) { # if prior state was asleep, update sleep statistics if ( $state eq "asleep" - && defined( $hash->{READINGS}{lastSleep}{VAL} ) ) + && ReadingsVal( $name, "lastSleep", "" ) ne "" ) { readingsBulkUpdate( $hash, "lastAwake", $datetime ); readingsBulkUpdate( $hash, "lastDurSleep", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastSleep}{VAL} + $datetime, ReadingsVal( $name, "lastSleep", "" ) ) ); readingsBulkUpdate( $hash, "lastDurSleep_cr", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastSleep}{VAL}, "min" + $datetime, ReadingsVal( $name, "lastSleep", "" ), + "min" ) ); } @@ -517,7 +506,8 @@ sub GUEST_Set($@) { } } else { - if ( !grep( m/^$searchstring$/, @location_underway ) + if ( !$silent + && !grep( m/^$searchstring$/, @location_underway ) && $location ne $location_underway[0] ) { Log3 $name, 4, @@ -529,9 +519,7 @@ sub GUEST_Set($@) { } # reset wayhome - if ( !defined( $hash->{READINGS}{wayhome}{VAL} ) - || $hash->{READINGS}{wayhome}{VAL} ne "0" ) - { + if ( ReadingsVal( $name, "wayhome", 1 ) > 0 ) { readingsBulkUpdate( $hash, "wayhome", "0" ); } @@ -540,14 +528,13 @@ sub GUEST_Set($@) { readingsBulkUpdate( $hash, "lastArrival", $datetime ); # absence duration - if ( defined( $hash->{READINGS}{lastDeparture}{VAL} ) - && $hash->{READINGS}{lastDeparture}{VAL} ne "-" ) - { + if ( ReadingsVal( $name, "lastDeparture", "-" ) ne "-" ) { readingsBulkUpdate( $hash, "lastDurAbsence", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastDeparture}{VAL} + $datetime, + ReadingsVal( $name, "lastDeparture", "-" ) ) ); readingsBulkUpdate( @@ -555,7 +542,8 @@ sub GUEST_Set($@) { "lastDurAbsence_cr", RESIDENTStk_TimeDiff( $datetime, - $hash->{READINGS}{lastDeparture}{VAL}, "min" + ReadingsVal( $name, "lastDeparture", "-" ), + "min" ) ); } @@ -564,22 +552,21 @@ sub GUEST_Set($@) { readingsBulkUpdate( $hash, "lastDeparture", $datetime ); # presence duration - if ( defined( $hash->{READINGS}{lastArrival}{VAL} ) - && $hash->{READINGS}{lastArrival}{VAL} ne "-" ) - { + if ( ReadingsVal( $name, "lastArrival", "-" ) ne "-" ) { readingsBulkUpdate( $hash, "lastDurPresence", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastArrival}{VAL} + $datetime, + ReadingsVal( $name, "lastArrival", "-" ) ) ); readingsBulkUpdate( $hash, "lastDurPresence_cr", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastArrival}{VAL}, - "min" + $datetime, + ReadingsVal( $name, "lastArrival", "-" ), "min" ) ); } @@ -599,9 +586,8 @@ sub GUEST_Set($@) { && defined( $defs{$object}{TYPE} ) && ( $defs{$object}{TYPE} eq "ROOMMATE" || $defs{$object}{TYPE} eq "GUEST" ) - && defined( $defs{$object}{READINGS}{state}{VAL} ) - && $defs{$object}{READINGS}{state}{VAL} ne "gone" - && $defs{$object}{READINGS}{state}{VAL} ne "none" + && ReadingsVal( $object, "state", "" ) ne "gone" + && ReadingsVal( $object, "state", "" ) ne "none" ) { fhem("set $object $newstate"); @@ -613,23 +599,23 @@ sub GUEST_Set($@) { # clear readings if guest is gone if ( $newstate eq "none" ) { readingsBulkUpdate( $hash, "lastArrival", "-" ) - if ( defined( $hash->{READINGS}{lastArrival}{VAL} ) ); + if ( ReadingsVal( $name, "lastArrival", "-" ) ne "-" ); readingsBulkUpdate( $hash, "lastAwake", "-" ) - if ( defined( $hash->{READINGS}{lastAwake}{VAL} ) ); + if ( ReadingsVal( $name, "lastAwake", "-" ) ne "-" ); readingsBulkUpdate( $hash, "lastDurAbsence", "-" ) - if ( defined( $hash->{READINGS}{lastDurAbsence}{VAL} ) ); + if ( ReadingsVal( $name, "lastDurAbsence", "-" ) ne "-" ); readingsBulkUpdate( $hash, "lastDurSleep", "-" ) - if ( defined( $hash->{READINGS}{lastDurSleep}{VAL} ) ); + if ( ReadingsVal( $name, "lastDurSleep", "-" ) ne "-" ); readingsBulkUpdate( $hash, "lastLocation", "-" ) - if ( defined( $hash->{READINGS}{lastLocation}{VAL} ) ); + if ( ReadingsVal( $name, "lastLocation", "-" ) ne "-" ); readingsBulkUpdate( $hash, "lastSleep", "-" ) - if ( defined( $hash->{READINGS}{lastSleep}{VAL} ) ); + if ( ReadingsVal( $name, "lastSleep", "-" ) ne "-" ); readingsBulkUpdate( $hash, "lastMood", "-" ) - if ( defined( $hash->{READINGS}{lastMood}{VAL} ) ); + if ( ReadingsVal( $name, "lastMood", "-" ) ne "-" ); readingsBulkUpdate( $hash, "location", "-" ) - if ( defined( $hash->{READINGS}{location}{VAL} ) ); + if ( ReadingsVal( $name, "location", "-" ) ne "-" ); readingsBulkUpdate( $hash, "mood", "-" ) - if ( defined( $hash->{READINGS}{mood}{VAL} ) ); + if ( ReadingsVal( $name, "mood", "-" ) ne "-" ); } # calculate duration timers @@ -653,12 +639,12 @@ sub GUEST_Set($@) { Log3 $name, 2, "GUEST set $name mood " . $a[2] if ( !$silent ); readingsBeginUpdate($hash) if ( !$silent ); - if ( $a[2] eq "toggle" ) { - if ( defined( $hash->{READINGS}{lastMood}{VAL} ) ) { - readingsBulkUpdate( $hash, "mood", - $hash->{READINGS}{lastMood}{VAL} ); - readingsBulkUpdate( $hash, "lastMood", $mood ); - } + if ( $a[2] eq "toggle" + && ReadingsVal( $name, "lastMood", "" ) ne "" ) + { + readingsBulkUpdate( $hash, "mood", + ReadingsVal( $name, "lastMood", "" ) ); + readingsBulkUpdate( $hash, "lastMood", $mood ); } elsif ( $mood ne $a[2] ) { readingsBulkUpdate( $hash, "lastMood", $mood ) @@ -676,13 +662,91 @@ sub GUEST_Set($@) { # location elsif ( $a[1] eq "location" ) { if ( defined( $a[2] ) && $a[2] ne "" ) { - shift @a; - shift @a; - my $location = join( " ", @a ); - Log3 $name, 2, "ROOMMATE set $name location " . $location - if ( !$silent ); + Log3 $name, 2, "GUEST set $name location " . $a[2] if ( !$silent ); - GUEST_SetLocation( $name, $location, 1, undef ); + if ( $location ne $a[2] ) { + my $searchstring; + + readingsBeginUpdate($hash) if ( !$silent ); + + # read attributes + my @location_home = + ( defined( $attr{$name}{"rg_locationHome"} ) ) + ? split( ' ', $attr{$name}{"rg_locationHome"} ) + : ("home"); + + my @location_underway = + ( defined( $attr{$name}{"rg_locationUnderway"} ) ) + ? split( ' ', $attr{$name}{"rg_locationUnderway"} ) + : ("underway"); + + my @location_wayhome = + ( defined( $attr{$name}{"rg_locationWayhome"} ) ) + ? split( ' ', $attr{$name}{"rg_locationWayhome"} ) + : ("wayhome"); + + $searchstring = quotemeta($location); + readingsBulkUpdate( $hash, "lastLocation", $location ) + if ( $location ne "wayhome" + && !grep( m/^$searchstring$/, @location_underway ) ); + readingsBulkUpdate( $hash, "location", $a[2] ) + if ( $a[2] ne "wayhome" ); + + # wayhome detection + $searchstring = quotemeta($location); + if ( + ( + $a[2] eq "wayhome" + || grep( m/^$searchstring$/, @location_wayhome ) + ) + && ( $presence eq "absent" ) + ) + { + Log3 $name, 3, + "GUEST $name: on way back home from $location"; + readingsBulkUpdate( $hash, "wayhome", "1" ) + if ( !defined( $hash->{READINGS}{wayhome}{VAL} ) + || $hash->{READINGS}{wayhome}{VAL} ne "1" ); + } + + readingsEndUpdate( $hash, 1 ) if ( !$silent ); + + # auto-updates + $searchstring = quotemeta( $a[2] ); + if ( + ( + $a[2] eq "home" + || grep( m/^$searchstring$/, @location_home ) + ) + && $state ne "home" + && $state ne "gotosleep" + && $state ne "asleep" + && $state ne "awoken" + && $state ne "initialized" + ) + { + Log3 $name, 4, + "GUEST $name: implicit state change caused by location " + . $a[2]; + GUEST_Set( $hash, $name, "silentSet", "state", "home" ); + } + elsif ( + ( + $a[2] eq "underway" + || grep( m/^$searchstring$/, @location_underway ) + ) + && $state ne "gone" + && $state ne "none" + && $state ne "absent" + && $state ne "initialized" + ) + { + Log3 $name, 4, + "GUEST $name: implicit state change caused by location " + . $a[2]; + GUEST_Set( $hash, $name, "silentSet", "state", "absent" ); + } + } } else { return "Invalid 2nd argument, choose one of location "; @@ -774,9 +838,7 @@ sub GUEST_AutoGone($;$) { RESIDENTStk_RemoveInternalTimer( "AutoGone", $hash ); - if ( defined( $hash->{READINGS}{state}{VAL} ) - && $hash->{READINGS}{state}{VAL} eq "absent" ) - { + if ( ReadingsVal( $name, "state", "home" ) eq "absent" ) { my ( $date, $time, $y, $m, $d, $hour, $min, $sec, $timestamp, $timeDiff ); my $timestampNow = gettimeofday(); @@ -812,13 +874,10 @@ sub GUEST_AutoGone($;$) { ################################### sub GUEST_DurationTimer($;$) { my ( $mHash, @a ) = @_; - my $hash = ( $mHash->{HASH} ) ? $mHash->{HASH} : $mHash; - my $name = $hash->{NAME}; - my $state = - ( $hash->{READINGS}{state}{VAL} ) - ? $hash->{READINGS}{state}{VAL} - : "initialized"; - my $silent = ( defined( $a[0] ) && $a[0] eq "1" ) ? 1 : 0; + my $hash = ( $mHash->{HASH} ) ? $mHash->{HASH} : $mHash; + my $name = $hash->{NAME}; + my $state = ReadingsVal( $name, "state", "initialized" ); + my $silent = ( defined( $a[0] ) && $a[0] eq "1" ) ? 1 : 0; my $timestampNow = gettimeofday(); my $diff; my $durPresence = "0"; @@ -832,47 +891,33 @@ sub GUEST_DurationTimer($;$) { { # presence timer - if ( defined( $hash->{READINGS}{presence}{VAL} ) - && $hash->{READINGS}{presence}{VAL} eq "present" ) + if ( ReadingsVal( $name, "presence", "absent" ) eq "present" + && ReadingsVal( $name, "lastArrival", "-" ) ne "-" ) { - if ( defined( $hash->{READINGS}{lastArrival}{VAL} ) - && $hash->{READINGS}{lastArrival}{VAL} ne "-" ) - { - $durPresence = - $timestampNow - - RESIDENTStk_Datetime2Timestamp( - $hash->{READINGS}{lastArrival}{VAL} ); - } + $durPresence = + $timestampNow - + RESIDENTStk_Datetime2Timestamp( + ReadingsVal( $name, "lastArrival", "-" ) ); } # absence timer - if ( defined( $hash->{READINGS}{presence}{VAL} ) - && $hash->{READINGS}{presence}{VAL} eq "absent" - && defined( $hash->{READINGS}{state}{VAL} ) - && $hash->{READINGS}{state}{VAL} eq "absent" ) + if ( ReadingsVal( $name, "presence", "present" ) eq "absent" + && ReadingsVal( $name, "lastDeparture", "-" ) ne "-" ) { - if ( defined( $hash->{READINGS}{lastDeparture}{VAL} ) - && $hash->{READINGS}{lastDeparture}{VAL} ne "-" ) - { - $durAbsence = - $timestampNow - - RESIDENTStk_Datetime2Timestamp( - $hash->{READINGS}{lastDeparture}{VAL} ); - } + $durAbsence = + $timestampNow - + RESIDENTStk_Datetime2Timestamp( + ReadingsVal( $name, "lastDeparture", "-" ) ); } # sleep timer - if ( defined( $hash->{READINGS}{state}{VAL} ) - && $hash->{READINGS}{state}{VAL} eq "asleep" ) + if ( ReadingsVal( $name, "state", "home" ) eq "asleep" + && ReadingsVal( $name, "lastSleep", "-" ) ne "-" ) { - if ( defined( $hash->{READINGS}{lastSleep}{VAL} ) - && $hash->{READINGS}{lastSleep}{VAL} ne "-" ) - { - $durSleep = - $timestampNow - - RESIDENTStk_Datetime2Timestamp( - $hash->{READINGS}{lastSleep}{VAL} ); - } + $durSleep = + $timestampNow - + RESIDENTStk_Datetime2Timestamp( + ReadingsVal( $name, "lastSleep", "-" ) ); } my $durPresence_hr = @@ -891,23 +936,20 @@ sub GUEST_DurationTimer($;$) { readingsBeginUpdate($hash) if ( !$silent ); readingsBulkUpdate( $hash, "durTimerPresence_cr", $durPresence_cr ) - if ( !defined( $hash->{READINGS}{durTimerPresence_cr}{VAL} ) - || $hash->{READINGS}{durTimerPresence_cr}{VAL} ne $durPresence_cr ); + if ( ReadingsVal( $name, "durTimerPresence_cr", "" ) ne + $durPresence_cr ); readingsBulkUpdate( $hash, "durTimerPresence", $durPresence_hr ) - if ( !defined( $hash->{READINGS}{durTimerPresence}{VAL} ) - || $hash->{READINGS}{durTimerPresence}{VAL} ne $durPresence_hr ); + if ( + ReadingsVal( $name, "durTimerPresence", "" ) ne $durPresence_hr ); readingsBulkUpdate( $hash, "durTimerAbsence_cr", $durAbsence_cr ) - if ( !defined( $hash->{READINGS}{durTimerAbsence_cr}{VAL} ) - || $hash->{READINGS}{durTimerAbsence_cr}{VAL} ne $durAbsence_cr ); + if ( + ReadingsVal( $name, "durTimerAbsence_cr", "" ) ne $durAbsence_cr ); readingsBulkUpdate( $hash, "durTimerAbsence", $durAbsence_hr ) - if ( !defined( $hash->{READINGS}{durTimerAbsence}{VAL} ) - || $hash->{READINGS}{durTimerAbsence}{VAL} ne $durAbsence_hr ); + if ( ReadingsVal( $name, "durTimerAbsence", "" ) ne $durAbsence_hr ); readingsBulkUpdate( $hash, "durTimerSleep_cr", $durSleep_cr ) - if ( !defined( $hash->{READINGS}{durTimerSleep_cr}{VAL} ) - || $hash->{READINGS}{durTimerSleep_cr}{VAL} ne $durSleep_cr ); + if ( ReadingsVal( $name, "durTimerSleep_cr", "" ) ne $durSleep_cr ); readingsBulkUpdate( $hash, "durTimerSleep", $durSleep_hr ) - if ( !defined( $hash->{READINGS}{durTimerSleep}{VAL} ) - || $hash->{READINGS}{durTimerSleep}{VAL} ne $durSleep_hr ); + if ( ReadingsVal( $name, "durTimerSleep", "" ) ne $durSleep_hr ); readingsEndUpdate( $hash, 1 ) if ( !$silent ); } @@ -933,7 +975,8 @@ sub GUEST_SetLocation($$$;$$$$$$) { $lat = "-" if ( !$lat || $lat eq "" ); $long = "-" if ( !$long || $long eq "" ); $address = "-" if ( !$address || $address eq "" ); - $location = "underway" if ( $trigger eq "0" ); + $time = "" if ( !$time ); + $device = "" if ( !$device ); Log3 $name, 5, "GUEST $name: received location information: id=$id name=$location trig=$trigger date=$time lat=$lat long=$long address:$address device=$device"; @@ -944,63 +987,41 @@ sub GUEST_SetLocation($$$;$$$$$$) { # read attributes my @location_home = - split( ' ', AttrVal( $name, "rr_locationHome", "home" ) ); + split( ' ', AttrVal( $name, "rg_locationHome", "home" ) ); my @location_underway = - split( ' ', AttrVal( $name, "rr_locationUnderway", "underway" ) ); + split( ' ', AttrVal( $name, "rg_locationUnderway", "underway" ) ); my @location_wayhome = - split( ' ', AttrVal( $name, "rr_locationWayhome", "wayhome" ) ); + split( ' ', AttrVal( $name, "rg_locationWayhome", "wayhome" ) ); $searchstring = quotemeta($location); - if ( $location ne "wayhome" ) { - if ( - !grep( m/^$searchstring$/, @location_underway ) - && ( $currLocation ne $location - || $currLat ne $lat - || $currLong ne $long - || $currAddr ne $address ) - ) - { - readingsBulkUpdate( $hash, "lastLocation", $currLocation ); - readingsBulkUpdate( $hash, "lastLocationLat", $currLat ); - readingsBulkUpdate( $hash, "lastLocationLong", $currLong ); - readingsBulkUpdate( $hash, "lastLocationAddr", $currAddr ); - } - readingsBulkUpdate( $hash, "location", $location ); - readingsBulkUpdate( $hash, "locationLat", $lat ); - readingsBulkUpdate( $hash, "locationLong", $long ); - readingsBulkUpdate( $hash, "locationAddr", $address ); - } + # check for implicit state change + # + my $stateChange = 0; - # wayhome detection - $searchstring = quotemeta($location); - if ( - ( - $location eq "wayhome" - || grep( m/^$searchstring$/, @location_wayhome ) - ) - && ( $presence eq "absent" ) - ) - { - Log3 $name, 3, "GUEST $name: on way back home from $location"; - readingsBulkUpdate( $hash, "wayhome", "1" ) - if ( ReadingsVal( $name, "wayhome", "0" ) ne "1" ); - } - - readingsEndUpdate( $hash, 1 ); - - # auto-updates - $searchstring = quotemeta($location); + # home/1 if ( ( $location eq "home" || grep( m/^$searchstring$/, @location_home ) ) && $state ne "home" && $state ne "gotosleep" && $state ne "asleep" - && $state ne "awoken" ) + && $state ne "awoken" + && $trigger eq "1" ) { - Log3 $name, 4, - "GUEST $name: implicit state change caused by location " . $location; - GUEST_Set( $hash, $name, "silentSet", "state", "home" ); + $stateChange = 1; } + + # home/0 + elsif ( + ( $location eq "home" || grep( m/^$searchstring$/, @location_home ) ) + && $state ne "gone" + && $state ne "none" + && $state ne "absent" + && $trigger eq "0" ) + { + $stateChange = 2; + } + + # absent elsif ( ( $location eq "underway" @@ -1011,9 +1032,87 @@ sub GUEST_SetLocation($$$;$$$$$$) { && $state ne "absent" ) { + $stateChange = 2; + } + + # wayhome + my $wayhome; + if ( + ( + $location eq "wayhome" + || ( grep( m/^$searchstring$/, @location_wayhome ) + && $trigger eq "0" ) + ) + && $presence eq "absent" + ) + { + Log3 $name, 5, "GUEST $name: wayhome signal received"; + if ( + ( + ( $location eq "wayhome" && $trigger eq "1" ) + || ( $location ne "wayhome" && $trigger eq "0" ) + ) + && ReadingsVal( $name, "wayhome", "0" ) ne "1" + ) + { + Log3 $name, 3, "GUEST $name: on way back home from $location"; + readingsBulkUpdate( $hash, "wayhome", "1" ); + $wayhome = 1; + } + elsif ($location eq "wayhome" + && $trigger eq "0" + && ReadingsVal( $name, "wayhome", "0" ) ne "0" ) + { + Log3 $name, 3, + "GUEST $name: seems not to be on way back home anymore"; + readingsBulkUpdate( $hash, "wayhome", "0" ); + $wayhome = 1; + $location = "underway"; + } + } + + if ( !grep( m/^$searchstring$/, @location_underway ) + && ( $stateChange > 0 || $currLocation ne $location ) ) + { + Log3 $name, 5, "GUEST $name: archiving last known location"; + readingsBulkUpdate( $hash, "lastLocationLat", $currLat ); + readingsBulkUpdate( $hash, "lastLocationLong", $currLong ); + readingsBulkUpdate( $hash, "lastLocationAddr", $currAddr ); + readingsBulkUpdate( $hash, "lastLocation", $currLocation ); + } + + if ( $wayhome + || $stateChange > 0 + || ( $lat ne "-" && $long ne "-" ) ) + { + Log3 $name, 5, "GUEST $name: Using new lat/long/addr information"; + readingsBulkUpdate( $hash, "locationLat", $lat ); + readingsBulkUpdate( $hash, "locationLong", $long ); + readingsBulkUpdate( $hash, "locationAddr", $address ); + } + + else { + Log3 $name, 5, + "GUEST $name: keeping last known lat/long/addr information"; + readingsBulkUpdate( $hash, "locationLat", $currLat ); + readingsBulkUpdate( $hash, "locationLong", $currLong ); + readingsBulkUpdate( $hash, "locationAddr", $currAddr ); + } + + readingsBulkUpdate( $hash, "location", $location ) + if ( $location ne "wayhome" ); + + readingsEndUpdate( $hash, 1 ); + + # trigger state change + if ( $stateChange > 0 ) { Log3 $name, 4, "GUEST $name: implicit state change caused by location " . $location; - GUEST_Set( $hash, $name, "silentSet", "state", "absent" ); + + GUEST_Set( $hash, $name, "silentSet", "state", "home" ) + if $stateChange == 1; + GUEST_Set( $hash, $name, "silentSet", "state", "absent" ) + if $stateChange == 2; } } diff --git a/fhem/FHEM/20_ROOMMATE.pm b/fhem/FHEM/20_ROOMMATE.pm index 4941f3791..024cb878f 100644 --- a/fhem/FHEM/20_ROOMMATE.pm +++ b/fhem/FHEM/20_ROOMMATE.pm @@ -145,7 +145,7 @@ sub ROOMMATE_Define($$) { # trigger for modified objects unless ( $modified == 0 ) { - readingsBulkUpdate( $hash, "state", $hash->{READINGS}{state}{VAL} ); + readingsBulkUpdate( $hash, "state", ReadingsVal( $name, "state", "" ) ); } readingsEndUpdate( $hash, 1 ); @@ -261,24 +261,12 @@ sub ROOMMATE_Notify($$) { ################################### sub ROOMMATE_Set($@) { my ( $hash, @a ) = @_; - my $name = $hash->{NAME}; - my $state = - ( defined( $hash->{READINGS}{state}{VAL} ) ) - ? $hash->{READINGS}{state}{VAL} - : "initialized"; - my $presence = - ( defined( $hash->{READINGS}{presence}{VAL} ) ) - ? $hash->{READINGS}{presence}{VAL} - : "undefined"; - my $mood = - ( defined( $hash->{READINGS}{mood}{VAL} ) ) - ? $hash->{READINGS}{mood}{VAL} - : "-"; - my $location = - ( defined( $hash->{READINGS}{location}{VAL} ) ) - ? $hash->{READINGS}{location}{VAL} - : "undefined"; - my $silent = 0; + my $name = $hash->{NAME}; + my $state = ReadingsVal( $name, "state", "initialized" ); + my $presence = ReadingsVal( $name, "presence", "undefined" ); + my $mood = ReadingsVal( $name, "mood", "-" ); + my $location = ReadingsVal( $name, "location", "undefined" ); + my $silent = 0; Log3 $name, 5, "ROOMMATE $name: called function ROOMMATE_Set()"; @@ -443,21 +431,22 @@ sub ROOMMATE_Set($@) { # if prior state was asleep, update sleep statistics if ( $state eq "asleep" - && defined( $hash->{READINGS}{lastSleep}{VAL} ) ) + && ReadingsVal( $name, "lastSleep", "" ) ne "" ) { readingsBulkUpdate( $hash, "lastAwake", $datetime ); readingsBulkUpdate( $hash, "lastDurSleep", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastSleep}{VAL} + $datetime, ReadingsVal( $name, "lastSleep", "" ) ) ); readingsBulkUpdate( $hash, "lastDurSleep_cr", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastSleep}{VAL}, "min" + $datetime, ReadingsVal( $name, "lastSleep", "" ), + "min" ) ); } @@ -507,7 +496,7 @@ sub ROOMMATE_Set($@) { : ("underway"); my $searchstring = quotemeta($location); - if ( $newpresence eq "present" ) { + if ( !$silent && $newpresence eq "present" ) { if ( !grep( m/^$searchstring$/, @location_home ) && $location ne $location_home[0] ) { @@ -519,7 +508,8 @@ sub ROOMMATE_Set($@) { } } else { - if ( !grep( m/^$searchstring$/, @location_underway ) + if ( !$silent + && !grep( m/^$searchstring$/, @location_underway ) && $location ne $location_underway[0] ) { Log3 $name, 4, @@ -531,9 +521,7 @@ sub ROOMMATE_Set($@) { } # reset wayhome - if ( !defined( $hash->{READINGS}{wayhome}{VAL} ) - || $hash->{READINGS}{wayhome}{VAL} ne "0" ) - { + if ( ReadingsVal( $name, "wayhome", 1 ) > 0 ) { readingsBulkUpdate( $hash, "wayhome", "0" ); } @@ -542,14 +530,13 @@ sub ROOMMATE_Set($@) { readingsBulkUpdate( $hash, "lastArrival", $datetime ); # absence duration - if ( defined( $hash->{READINGS}{lastDeparture}{VAL} ) - && $hash->{READINGS}{lastDeparture}{VAL} ne "-" ) - { + if ( ReadingsVal( $name, "lastDeparture", "-" ) ne "-" ) { readingsBulkUpdate( $hash, "lastDurAbsence", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastDeparture}{VAL} + $datetime, + ReadingsVal( $name, "lastDeparture", "-" ) ) ); readingsBulkUpdate( @@ -557,7 +544,8 @@ sub ROOMMATE_Set($@) { "lastDurAbsence_cr", RESIDENTStk_TimeDiff( $datetime, - $hash->{READINGS}{lastDeparture}{VAL}, "min" + ReadingsVal( $name, "lastDeparture", "-" ), + "min" ) ); } @@ -566,22 +554,21 @@ sub ROOMMATE_Set($@) { readingsBulkUpdate( $hash, "lastDeparture", $datetime ); # presence duration - if ( defined( $hash->{READINGS}{lastArrival}{VAL} ) - && $hash->{READINGS}{lastArrival}{VAL} ne "-" ) - { + if ( ReadingsVal( $name, "lastArrival", "-" ) ne "-" ) { readingsBulkUpdate( $hash, "lastDurPresence", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastArrival}{VAL} + $datetime, + ReadingsVal( $name, "lastArrival", "-" ) ) ); readingsBulkUpdate( $hash, "lastDurPresence_cr", RESIDENTStk_TimeDiff( - $datetime, $hash->{READINGS}{lastArrival}{VAL}, - "min" + $datetime, + ReadingsVal( $name, "lastArrival", "-" ), "min" ) ); } @@ -601,9 +588,8 @@ sub ROOMMATE_Set($@) { && defined( $defs{$object}{TYPE} ) && ( $defs{$object}{TYPE} eq "ROOMMATE" || $defs{$object}{TYPE} eq "GUEST" ) - && defined( $defs{$object}{READINGS}{state}{VAL} ) - && $defs{$object}{READINGS}{state}{VAL} ne "gone" - && $defs{$object}{READINGS}{state}{VAL} ne "none" + && ReadingsVal( $object, "state", "" ) ne "gone" + && ReadingsVal( $object, "state", "" ) ne "none" ) { fhem("set $object $newstate"); @@ -633,12 +619,12 @@ sub ROOMMATE_Set($@) { Log3 $name, 2, "ROOMMATE set $name mood " . $a[2] if ( !$silent ); readingsBeginUpdate($hash) if ( !$silent ); - if ( $a[2] eq "toggle" ) { - if ( defined( $hash->{READINGS}{lastMood}{VAL} ) ) { - readingsBulkUpdate( $hash, "mood", - $hash->{READINGS}{lastMood}{VAL} ); - readingsBulkUpdate( $hash, "lastMood", $mood ); - } + if ( $a[2] eq "toggle" + && ReadingsVal( $name, "lastMood", "" ) ne "" ) + { + readingsBulkUpdate( $hash, "mood", + ReadingsVal( $name, "lastMood", "" ) ); + readingsBulkUpdate( $hash, "lastMood", $mood ); } elsif ( $mood ne $a[2] ) { readingsBulkUpdate( $hash, "lastMood", $mood ) @@ -656,13 +642,93 @@ sub ROOMMATE_Set($@) { # location elsif ( $a[1] eq "location" ) { if ( defined( $a[2] ) && $a[2] ne "" ) { - shift @a; - shift @a; - my $location = join( " ", @a ); - Log3 $name, 2, "ROOMMATE set $name location " . $location + Log3 $name, 2, "ROOMMATE set $name location " . $a[2] if ( !$silent ); - ROOMMATE_SetLocation( $name, $location, 1, undef ); + if ( $location ne $a[2] ) { + my $searchstring; + + readingsBeginUpdate($hash) if ( !$silent ); + + # read attributes + my @location_home = + ( defined( $attr{$name}{"rr_locationHome"} ) ) + ? split( ' ', $attr{$name}{"rr_locationHome"} ) + : ("home"); + + my @location_underway = + ( defined( $attr{$name}{"rr_locationUnderway"} ) ) + ? split( ' ', $attr{$name}{"rr_locationUnderway"} ) + : ("underway"); + + my @location_wayhome = + ( defined( $attr{$name}{"rr_locationWayhome"} ) ) + ? split( ' ', $attr{$name}{"rr_locationWayhome"} ) + : ("wayhome"); + + $searchstring = quotemeta($location); + readingsBulkUpdate( $hash, "lastLocation", $location ) + if ( $location ne "wayhome" + && !grep( m/^$searchstring$/, @location_underway ) ); + readingsBulkUpdate( $hash, "location", $a[2] ) + if ( $a[2] ne "wayhome" ); + + # wayhome detection + $searchstring = quotemeta($location); + if ( + ( + $a[2] eq "wayhome" + || grep( m/^$searchstring$/, @location_wayhome ) + ) + && ( $presence eq "absent" ) + ) + { + Log3 $name, 3, + "ROOMMATE $name: on way back home from $location"; + readingsBulkUpdate( $hash, "wayhome", "1" ) + if ( !defined( $hash->{READINGS}{wayhome}{VAL} ) + || $hash->{READINGS}{wayhome}{VAL} ne "1" ); + } + + readingsEndUpdate( $hash, 1 ) if ( !$silent ); + + # auto-updates + $searchstring = quotemeta( $a[2] ); + if ( + ( + $a[2] eq "home" + || grep( m/^$searchstring$/, @location_home ) + ) + && $state ne "home" + && $state ne "gotosleep" + && $state ne "asleep" + && $state ne "awoken" + && $state ne "initialized" + ) + { + Log3 $name, 4, +"ROOMMATE $name: implicit state change caused by location " + . $a[2]; + ROOMMATE_Set( $hash, $name, "silentSet", "state", "home" ); + } + elsif ( + ( + $a[2] eq "underway" + || grep( m/^$searchstring$/, @location_underway ) + ) + && $state ne "gone" + && $state ne "none" + && $state ne "absent" + && $state ne "initialized" + ) + { + Log3 $name, 4, +"ROOMMATE $name: implicit state change caused by location " + . $a[2]; + ROOMMATE_Set( $hash, $name, "silentSet", "state", + "absent" ); + } + } } else { return "Invalid 2nd argument, choose one of location "; @@ -754,9 +820,7 @@ sub ROOMMATE_AutoGone($;$) { RESIDENTStk_RemoveInternalTimer( "AutoGone", $hash ); - if ( defined( $hash->{READINGS}{state}{VAL} ) - && $hash->{READINGS}{state}{VAL} eq "absent" ) - { + if ( ReadingsVal( $name, "state", "home" ) eq "absent" ) { my ( $date, $time, $y, $m, $d, $hour, $min, $sec, $timestamp, $timeDiff ); my $timestampNow = gettimeofday(); @@ -808,45 +872,33 @@ sub ROOMMATE_DurationTimer($;$) { { # presence timer - if ( defined( $hash->{READINGS}{presence}{VAL} ) - && $hash->{READINGS}{presence}{VAL} eq "present" ) + if ( ReadingsVal( $name, "presence", "absent" ) eq "present" + && ReadingsVal( $name, "lastArrival", "-" ) ne "-" ) { - if ( defined( $hash->{READINGS}{lastArrival}{VAL} ) - && $hash->{READINGS}{lastArrival}{VAL} ne "-" ) - { - $durPresence = - $timestampNow - - RESIDENTStk_Datetime2Timestamp( - $hash->{READINGS}{lastArrival}{VAL} ); - } + $durPresence = + $timestampNow - + RESIDENTStk_Datetime2Timestamp( + ReadingsVal( $name, "lastArrival", "-" ) ); } # absence timer - if ( defined( $hash->{READINGS}{presence}{VAL} ) - && $hash->{READINGS}{presence}{VAL} eq "absent" ) + if ( ReadingsVal( $name, "presence", "present" ) eq "absent" + && ReadingsVal( $name, "lastDeparture", "-" ) ne "-" ) { - if ( defined( $hash->{READINGS}{lastDeparture}{VAL} ) - && $hash->{READINGS}{lastDeparture}{VAL} ne "-" ) - { - $durAbsence = - $timestampNow - - RESIDENTStk_Datetime2Timestamp( - $hash->{READINGS}{lastDeparture}{VAL} ); - } + $durAbsence = + $timestampNow - + RESIDENTStk_Datetime2Timestamp( + ReadingsVal( $name, "lastDeparture", "-" ) ); } # sleep timer - if ( defined( $hash->{READINGS}{state}{VAL} ) - && $hash->{READINGS}{state}{VAL} eq "asleep" ) + if ( ReadingsVal( $name, "state", "home" ) eq "asleep" + && ReadingsVal( $name, "lastSleep", "-" ) ne "-" ) { - if ( defined( $hash->{READINGS}{lastSleep}{VAL} ) - && $hash->{READINGS}{lastSleep}{VAL} ne "-" ) - { - $durSleep = - $timestampNow - - RESIDENTStk_Datetime2Timestamp( - $hash->{READINGS}{lastSleep}{VAL} ); - } + $durSleep = + $timestampNow - + RESIDENTStk_Datetime2Timestamp( + ReadingsVal( $name, "lastSleep", "-" ) ); } my $durPresence_hr = @@ -865,23 +917,20 @@ sub ROOMMATE_DurationTimer($;$) { readingsBeginUpdate($hash) if ( !$silent ); readingsBulkUpdate( $hash, "durTimerPresence_cr", $durPresence_cr ) - if ( !defined( $hash->{READINGS}{durTimerPresence_cr}{VAL} ) - || $hash->{READINGS}{durTimerPresence_cr}{VAL} ne $durPresence_cr ); + if ( ReadingsVal( $name, "durTimerPresence_cr", "" ) ne + $durPresence_cr ); readingsBulkUpdate( $hash, "durTimerPresence", $durPresence_hr ) - if ( !defined( $hash->{READINGS}{durTimerPresence}{VAL} ) - || $hash->{READINGS}{durTimerPresence}{VAL} ne $durPresence_hr ); + if ( + ReadingsVal( $name, "durTimerPresence", "" ) ne $durPresence_hr ); readingsBulkUpdate( $hash, "durTimerAbsence_cr", $durAbsence_cr ) - if ( !defined( $hash->{READINGS}{durTimerAbsence_cr}{VAL} ) - || $hash->{READINGS}{durTimerAbsence_cr}{VAL} ne $durAbsence_cr ); + if ( + ReadingsVal( $name, "durTimerAbsence_cr", "" ) ne $durAbsence_cr ); readingsBulkUpdate( $hash, "durTimerAbsence", $durAbsence_hr ) - if ( !defined( $hash->{READINGS}{durTimerAbsence}{VAL} ) - || $hash->{READINGS}{durTimerAbsence}{VAL} ne $durAbsence_hr ); + if ( ReadingsVal( $name, "durTimerAbsence", "" ) ne $durAbsence_hr ); readingsBulkUpdate( $hash, "durTimerSleep_cr", $durSleep_cr ) - if ( !defined( $hash->{READINGS}{durTimerSleep_cr}{VAL} ) - || $hash->{READINGS}{durTimerSleep_cr}{VAL} ne $durSleep_cr ); + if ( ReadingsVal( $name, "durTimerSleep_cr", "" ) ne $durSleep_cr ); readingsBulkUpdate( $hash, "durTimerSleep", $durSleep_hr ) - if ( !defined( $hash->{READINGS}{durTimerSleep}{VAL} ) - || $hash->{READINGS}{durTimerSleep}{VAL} ne $durSleep_hr ); + if ( ReadingsVal( $name, "durTimerSleep", "" ) ne $durSleep_hr ); readingsEndUpdate( $hash, 1 ) if ( !$silent ); } @@ -906,7 +955,8 @@ sub ROOMMATE_SetLocation($$$;$$$$$$) { $lat = "-" if ( !$lat || $lat eq "" ); $long = "-" if ( !$long || $long eq "" ); $address = "-" if ( !$address || $address eq "" ); - $location = "underway" if ( $trigger eq "0" ); + $time = "" if ( !$time ); + $device = "" if ( !$device ); Log3 $name, 5, "ROOMMATE $name: received location information: id=$id name=$location trig=$trigger date=$time lat=$lat long=$long address:$address device=$device"; @@ -924,57 +974,34 @@ sub ROOMMATE_SetLocation($$$;$$$$$$) { split( ' ', AttrVal( $name, "rr_locationWayhome", "wayhome" ) ); $searchstring = quotemeta($location); - if ( $location ne "wayhome" ) { - if ( - !grep( m/^$searchstring$/, @location_underway ) - && ( $currLocation ne $location - || $currLat ne $lat - || $currLong ne $long - || $currAddr ne $address ) - ) - { - readingsBulkUpdate( $hash, "lastLocation", $currLocation ); - readingsBulkUpdate( $hash, "lastLocationLat", $currLat ); - readingsBulkUpdate( $hash, "lastLocationLong", $currLong ); - readingsBulkUpdate( $hash, "lastLocationAddr", $currAddr ); - } - readingsBulkUpdate( $hash, "location", $location ); - readingsBulkUpdate( $hash, "locationLat", $lat ); - readingsBulkUpdate( $hash, "locationLong", $long ); - readingsBulkUpdate( $hash, "locationAddr", $address ); - } + # check for implicit state change + # + my $stateChange = 0; - # wayhome detection - $searchstring = quotemeta($location); - if ( - ( - $location eq "wayhome" - || grep( m/^$searchstring$/, @location_wayhome ) - ) - && ( $presence eq "absent" ) - ) - { - Log3 $name, 3, "ROOMMATE $name: on way back home from $location"; - readingsBulkUpdate( $hash, "wayhome", "1" ) - if ( ReadingsVal( $name, "wayhome", "0" ) ne "1" ); - } - - readingsEndUpdate( $hash, 1 ); - - # auto-updates - $searchstring = quotemeta($location); + # home/1 if ( ( $location eq "home" || grep( m/^$searchstring$/, @location_home ) ) && $state ne "home" && $state ne "gotosleep" && $state ne "asleep" - && $state ne "awoken" ) + && $state ne "awoken" + && $trigger eq "1" ) { - Log3 $name, 4, - "ROOMMATE $name: implicit state change caused by location " - . $location; - ROOMMATE_Set( $hash, $name, "silentSet", "state", "home" ); + $stateChange = 1; } + + # home/0 + elsif ( + ( $location eq "home" || grep( m/^$searchstring$/, @location_home ) ) + && $state ne "gone" + && $state ne "none" + && $state ne "absent" + && $trigger eq "0" ) + { + $stateChange = 2; + } + + # absent elsif ( ( $location eq "underway" @@ -985,10 +1012,88 @@ sub ROOMMATE_SetLocation($$$;$$$$$$) { && $state ne "absent" ) { + $stateChange = 2; + } + + # wayhome + my $wayhome; + if ( + ( + $location eq "wayhome" + || ( grep( m/^$searchstring$/, @location_wayhome ) + && $trigger eq "0" ) + ) + && $presence eq "absent" + ) + { + Log3 $name, 5, "ROOMMATE $name: wayhome signal received"; + if ( + ( + ( $location eq "wayhome" && $trigger eq "1" ) + || ( $location ne "wayhome" && $trigger eq "0" ) + ) + && ReadingsVal( $name, "wayhome", "0" ) ne "1" + ) + { + Log3 $name, 3, "ROOMMATE $name: on way back home from $location"; + readingsBulkUpdate( $hash, "wayhome", "1" ); + $wayhome = 1; + } + elsif ($location eq "wayhome" + && $trigger eq "0" + && ReadingsVal( $name, "wayhome", "0" ) ne "0" ) + { + Log3 $name, 3, + "ROOMMATE $name: seems not to be on way back home anymore"; + readingsBulkUpdate( $hash, "wayhome", "0" ); + $wayhome = 1; + $location = "underway"; + } + } + + if ( !grep( m/^$searchstring$/, @location_underway ) + && ( $stateChange > 0 || $currLocation ne $location ) ) + { + Log3 $name, 5, "ROOMMATE $name: archiving last known location"; + readingsBulkUpdate( $hash, "lastLocationLat", $currLat ); + readingsBulkUpdate( $hash, "lastLocationLong", $currLong ); + readingsBulkUpdate( $hash, "lastLocationAddr", $currAddr ); + readingsBulkUpdate( $hash, "lastLocation", $currLocation ); + } + + if ( $wayhome + || $stateChange > 0 + || ( $lat ne "-" && $long ne "-" ) ) + { + Log3 $name, 5, "ROOMMATE $name: Using new lat/long/addr information"; + readingsBulkUpdate( $hash, "locationLat", $lat ); + readingsBulkUpdate( $hash, "locationLong", $long ); + readingsBulkUpdate( $hash, "locationAddr", $address ); + } + + else { + Log3 $name, 5, + "ROOMMATE $name: keeping last known lat/long/addr information"; + readingsBulkUpdate( $hash, "locationLat", $currLat ); + readingsBulkUpdate( $hash, "locationLong", $currLong ); + readingsBulkUpdate( $hash, "locationAddr", $currAddr ); + } + + readingsBulkUpdate( $hash, "location", $location ) + if ( $location ne "wayhome" ); + + readingsEndUpdate( $hash, 1 ); + + # trigger state change + if ( $stateChange > 0 ) { Log3 $name, 4, "ROOMMATE $name: implicit state change caused by location " . $location; - ROOMMATE_Set( $hash, $name, "silentSet", "state", "absent" ); + + ROOMMATE_Set( $hash, $name, "silentSet", "state", "home" ) + if $stateChange == 1; + ROOMMATE_Set( $hash, $name, "silentSet", "state", "absent" ) + if $stateChange == 2; } }