Skip to content
ggodart edited this page Jan 11, 2021 · 2 revisions

Idle times

Items that are derived from the Generic_Item inherit the get_idle_time method which returns the number of seconds since the last state change however if you are in a state change handler, then the idle time will be zero because you only got into the state change handler because the item just changed state. In this circumstance you need the last idle time, i.e. how long was it in the previous state before it changed to this one. This is often needed when debouncing an item. Here is how to achieve this.

#-----------------------------------------------------------------------
# $Driveway_PIR is defined in items.mht
# this state change handler fires whenever $Driveway_PIR changes state
# NOTE this_idle will be zero
#-----------------------------------------------------------------------
if ( $state = state_now $Driveway_PIR) {
	my $this_idle = $Driveway_PIR->get_idle_time;
	my $last_idle = get_last_idle_time($Driveway_PIR);
	print_log( "Driveway PIR just changed to $state This idle=$this_idle last idle=$last_idle" );
	return;   
}

#-----------------------------------------------------------------------
# get the idle time before the most recent change by name
# get_last_idle_time_by_name(Object_name)
#-----------------------------------------------------------------------
sub get_last_idle_time_by_name {
my $object_name = $_[0];
    my $object      = &get_object_by_name($object_name);
    if ( !defined($object) ) {
        print_log("ERROR Invalid object in get_last_idle_time_by_name $object_name");
	return 0;
    }
    my $last_idle_time = get_last_idle_time($object);
    return $last_idle_time;
}

#-----------------------------------------------------------------------
# get the idle time before the most recent change, passed an object
# get_last_idle_time(Object)
#-----------------------------------------------------------------------
sub get_last_idle_time {
    my $object = $_[0];
    my $object_name = substr( $object->{object_name}, 1 );
    if ( defined($object) ) {
	my $state_log = $object->state_log;
	my ( $lastDate, $lastTime, $lastState ) =
		 ( state_log $object)[1] =~ /(\S+) (\S+) *(.*)/;
	my @dates = split( '/', $lastDate );
	my @times = split( ":", $lastTime );
	if ( defined( $dates[0] ) && defined( $times[0] ) ) {
	    $dates[1]--;
	    my $tcat = timelocal(
		$times[2], $times[1], $times[0],
		$dates[0], $dates[1], $dates[2]
	    );
	    my $tdiff = $Time - $tcat;
	    return $tdiff;
	}
	else {
		print_log("ERROR Invalid last date/time in get_last_idle $object_name");
		return 0;
	}
    }
    else {
	print_log("ERROR Invalid object in get_last_idle $object");
	return 0;
    }
}

NOTE: two subroutines are included here, one expects an item name and the other the item object

Clone this wiki locally