Away time in Home Assistant and surviving reboots

by Patrick Connelly posted on November 28, 2018

One of the biggest reasons I wanted to set up Home Assistant was to be able to handle a “vacation mode” for my house to change things like the thermostats and lighting. The addition of an input_boolean for this is really straight forward. However reminding myself to set vacation mode if we are away for a long period of time is something a bit harder. To do this, we need to calculate the away time for each user.

The Problem

The linchpin for knowing if I should send a reminder is around how long a person has been away. Originally thought I could just use my Ubiquiti access point’s last_seen time and calculate hours from there. However this field disappears after about 10 minutes of the user being disconnected from the access point. So I needed to find a way to persist the last_seen time event after the access point removes the data from the device_tracker entry.

Getting Last Seen

To start getting our away time, we need a way to persist when the last time we saw the user. This isn’t as simple as I’d like but it works well,

First we need to pull out the last_seen variable from the device tracker into a sensor so we can store it. Since you can’t create an automation on an attribute we need to create a template sensor for this value.

- platform: template
      friendly_name: "Seen Patrick timestamp"
      value_template: "{{ state_attr('device_tracker.pcon', 'last_seen') }}"

This will either return the unix timestamp that the user was last seen or a value of None

Persisting Last Seen

Now that we’re able to get our last seen time and trigger automation on it, we need to store it in a way that will survive reboots and will not be emptied when the client disconnects from the access point. First we need to create an input_number to store the timestamp in.

    name: Timestamp pcon
    min: 1514764800
    max: 4102444800

Since there are some required fields, I chose to use the beginning of 2018 as my minimum timestamp and the beginning of 2100 as my ending. Hopefully this system isn’t still running in 82 years.

Now we can write our automation to store the value every time the last seen is updated.

alias: "Set last seen timestamp for pcon"
  - platform: state
    entity_id: sensor.pcon_last_seen
    condition: template
    value_template: '{{ states("sensor.pcon_last_seen") != None }}'
  - service: input_number.set_value
      entity_id: input_number.timestamp_pcon
      value: '{{ states("sensor.pcon_last_seen") }}'

This will write the value of the sensor to the input_number field every time it changes if it is not None. If it’s None that means the access point has forgotten about our user and we don’t want to change their last_seen time. If you want this to survive a reboot, you will need to have recorder configured.

Calculating Away Time

Now that we have the timestamp for when we’ve seen the user we can calculate the number of hours since that timestamp

  friendly_name: "Time Patrick has been gone"
  unit_of_measurement: 'hours'
  value_template: "{{ ((as_timestamp(utcnow()) - states('input_number.timestamp_pcon') | float) / 3600) | round (2) }}"

From here we can use this variable in our other automations such, but that’s another post.

Keeping Away Time Refreshed

There’s a small note in the docs for template sensors that I missed originally that says

If you do not supply an entity_id in the configuration you will need to run the service homeassistant.update_entity to update the sensor.

So when the input_number quits updating the template sensor does too. So to combat this, I’ve added an automation that runs every five minutes to update the template. You could change this threshold if you want it more or less frequent.

alias: "Update the gone time"
  - platform: time
    minutes: '/5'
  - service: homeassistant.update_entity
      entity_id: sensor.pcon_gone

You can find all of my home assistant configs in my github repo.

NOTE: If you’re using logbook in your configuration, you might want to add the input_number and automations to your exclude list as to not fill up your log.