Making Home Assistant’s Presence Detection not so Binary

In Home Assistant and many other home automation controllers, your home status is either Home or Away. There’s no in-between. 

 

The Problem

So, you’ve got your home automation started, and it’s time to add some cool automations, like turning off everything when you leave, or playing some music when you get home. These can be pretty easy to do with presence detection, but sometimes you need more.

In my Home Assistant setup I’m using Bluetooth presence detection. Every ten seconds my Synology NAS running Home Assistant checks to see what Bluetooth devices it can ‘see’. If it detects my phone, then it knows I’m home.

When I get home, and it’s between a certain time, my house will start playing my Chillout playlist on Spotify through my Sonos speakers. It will only do that, if I arrive home alone, or my fiancée isn’t home. When everyone leaves, Home Assistant will shut everything down – including music, Philips Hue Lights, the TV, heating/cooling etc.

I’m in a two bedroom apartment, and the Bluetooth presence detection works across the entire apartment. There seems to be a blackspot when I’m at my desk with my phone. I’ll be working away, writing my next awesome automation or piece of code, only for Home Assistant to cut the power to my computer monitor and pause my music. A massive first world problem that needs to be solved.

I could increase the timeout which would reduce this from happening (which I’ve done) or even use multiple presence detection options like WiFi and Bluetooth. However this doesn’t solve the problem of my house doing things too quickly.

I’ll wake my phone, place it on the desk and wait for Home Assistant to detect it again. But here comes the problem. After waiting what seems like a lifetime for my phone to be detected again, everything starts as if I have been away for hours. My music is changed to my Chillout playlist again (or starts from the beginning), lights that I don’t need might come back on, I get messages that the dishwasher is done etc. At the moment, Home Assistant doesn’t know that I was home one minute ago, but maybe there’s a way we don’t need to start from scratch each time.

There’s also some times when we might be away from home. Maybe a weekend in the country, or away for work. The house should be able to tell that we’re more than just away for the day, so maybe it shouldn’t send us alerts that a battery needs to be replaced. Or, if I’m away for a long time, but my fiancée is home, maybe send those alerts to her instead.

 

Adding New States To Home Assistant

In my home, I want to track the following states that a person could be.

Just Arrived when someone has just arrived home after being away
HOME The classic Home state
Just Left When someone has just left the house
AWAY The classic Away or not_home state
Extended Away If someone is away for more than 24 hours

I’m using the Home Assistant input select component to track the states of my dishwasher and washing machine. I can re-use the same logic for that here.

 

Making Them Look Nice

Just like I did for my washing machine and dishwasher, I’m going to use a template sensor that will read the value of the drop-down. I can then make it look like a normal device tracker by adding our photos to the sensor.

 

Automating Transitions Between States

In Home Assistant we can see when someone is home or away only. But we now have some more complex states. Like I did for my washing machines, I’m going to use a for: condition. So as soon as someone is marked as away from their device tracker, they’ll be set to “Just Left”. If they are then in the “Just Left” status for five minutes, they’ll be marked as “Away”. The opposite is true when getting home.

However one problem I mentioned was music jumping back to my Chillout playlist. Let’s make sure that if someone is marked as “Just Left” and then their device tracker ‘sees’ them again, instead of marking them as Just Arrived, mark them as Home. This will stop any automations for when you get home for the first time firing off again.

Here’s some code which will do that.

 

We also want to add the special case “Extended Away”. This is useful if someone is away for the house for more than a whole day, like a vacation.

 

The Latest In Your Inbox

Enter your email address below to receive my latest blog posts and videos about Home Automation in your Inbox

 

Using Templates for Multiple People

With the code blocks above, there’s five automations just to go through those states. What if you have two people in your house? That becomes ten automations you need to maintain.

Let’s use Home Assistant templates to make the automations more dynamic. We can use the trigger variable to see which device caused the state to change, and then update the drop-down for the right person. Using templates, our whole automation for today becomes the following.

Note: I’m using bluetooth and WiFi presence detection for my fiancée’s iPhone, which I have in a Home Assistant group. When her iPhone is detected on Bluetooth or WiFi the group Helen will be marked as home.

 

Stopping the Just Arrived State

Update January 2018: Thanks to u/barqers on Reddit for pointing this out. With the code block above, it is possible for you to be marked as Just Left -> Just Arrived -> Home in the matter of a second if your phone disconnects and reconnects quickly. This means any automations you have setup that you want triggered when you enter the Just Arrived state could be triggered when you don’t want them.

You could use a for in your automation to account for this, however this may increase the time for Home Assistant to detect you as Home, which we don’t want.

To cover this edge-case, I’ve made the following changes to my automation, using templates to first check what my previous state was. If my previous state was Just Left, then instead of marking me as Just Arrived it will instead mark me as Home, skipping the Just Arrived state altogether.

 

Some Automations We Can Now Do

Now that we’ve got our new states setup, here’s some examples of automations we can do:

  • Play music when someone is marked as Just Arrived
  • Send dishwasher/washing machine alerts to someone when they are marked as Just Arrived, so the notification doesn’t get sent every time their device is marked as home
  • If everyone is marked as Extended Away, activate vacation mode to automatically turn off/on lights to make it look like someone is home
  • Don’t send alerts/messages to anyone marked as Extended Away for day-to-day operations of the house, like the washing being done or a battery needing to be replaced.
  • If you are marked as Home after being marked as Extended Away, send an email to you with the status of your smart home. What sensors need their battery replaced etc.
  • When someone is marked as Just Arrived and there are people marked as Home, announce who just got home over Text-to-Speech. Great for an announcement to let kids know when a parent is home from work for the day.

 

Additional States

At the moment, these five states work well for me, but i may want to change them in the future. Remember, they may not be the best fit for you but you can tailor them to suit your own home.

I don’t use this feature, but Home Assistant can be used with GPS to identify ‘zones’, such as work or school. These zones are used by Home Assistant instead of “home” or “not home”.

You could also do something similar with the drop-downs. One example would be to add a work option to the drop-down. If you have Home Assistant exposed to the world, you could use Tasker on Android to change the state of the drop-down to work when you connect to your work’s WiFi. If you have something like an Eight Sleep tracker, you could also mark someone as “asleep” when they’re laying in bed.

 

Wrapping Up

By adding additional states for presence, your home gets more information about what is happening. This means your smart home can tell the difference between when you’ve arrived home from a vacation and when you’ve just picked up milk from the shops.

Hopefully this inspires you to think outside the binary constraints of your controller software, to help you build some really smart automations.

Recommended Posts
  • pattyland

    Hi, just a quick question: Why are you using Bluetooth detection instead of WiFi? I thought WiFi would me much more wide range than Bluetooth, speaking of repeaters or multiple access points…

    • WiFi would absolutely cover more range. I’ve found that in our house, we tend to turn our WiFi on our phones off quite a bit. Generally 4G is faster than our WiFi here, so if we need to download something quickly we turn WiFi off. My work WiFi sucks, so I generally have to turn WiFi off, and then forget to turn it back on before I’m home.

      WiFi can also be a bit slower. Because phones go to sleep, you have to increase the timeout or “consider home” time to allow for this. So, Home Assistant may not see that we’ve left the house until 10 minutes after we’ve actually left.

      Bluetooth we keep on, as it drains little battery in the background, and doesn’t have the sleep issues that WiFi does.

  • Stephen Arbon

    I believe you should be able to shorten this up significantly if you were to bundle some of the actions together. For instance Mark Person as home could be
    – alias: Mark person as home
    trigger:
    – platform: state
    entity_id: input_select.phil_status_dropdown,input_select.helen_status_dropdown
    to: ‘Just Arrived’
    for:
    minutes: 10
    – platform: state
    entity_id: input_select.phil_status_dropdown,input_select.helen_status_dropdown
    from: ‘Just Left’
    to: ‘Just Arrived’
    action:
    – service: input_select.select_option
    data_template:
    entity_id: >
    {% if trigger.entity_id == ‘input_select.phil_status_dropdown’ %}
    input_select.phil_status_dropdown
    {% else %}
    input_select.helen_status_dropdown
    {% endif %}
    option: Home

  • This is great, thank you 🙂

    As an aside, do you know if it’s possible to overlay the status onto the image, like the regular sensor presence would do?

    • Thanks!

      I think it might be possible. Think you would have to create your own custom UI component for it though, which I am not sure exactly where to point you for that.

  • David Pickel

    hey, thank you for sharing your solution!
    you did great job 🙂 and the guide was very helpful
    i have problem,
    why my People Status wont show the status? and how can i hide the input_select box?

    thanks phil

    https://uploads.disquscdn.com/images/5f930372073e89963034a0a8a286fff5424ed8e8c3261bf6fd5c71eccccdcf31.png

    • David Pickel

      hey, somehow i managed to show the state , but didnt manage to hide the input select. can you help?
      thanks

      • Hey David,

        I’m guessing this is showing on your default view?

        You might be able to do this in your customize.yaml file to hide those

        That should hide the dropdowns on the home assistant UI for you.

        You may also be able to do this from the interface. Configuration -> Customize -> (Select Dropdown) -> Pick An Attribute to Override -> Hidden

        • David Pickel

          phil you are the man!
          thanks for the quick response
          thank you 🙂

  • doune

    Hi,

    How do you handle the state “all people are away” OR “all people are home” ?
    Because, being home is (or can be) the following 3 states :
    – “home”
    – “just arrived”
    – “just left”

    and being away can be the 3 following states :
    – “away”
    – “extended away”
    – “just left”

    Thanks for your help 🙂

    • For that, I use the regular Home Assistant group functionality of device trackers.

      So, in my groups YAML file I have

      Then let’s say I want an automation for when everyone has left the house to turn off my study lamp, the automation could be done in two ways. First using my dropdowns

      With the above, as soon as a dropdown changes to Away, the conditon against

      will ensure everyone is away.

      Another option could be to use a

      in the trigger against the all people group, like so

      Where the number of minutes is equal to the same

      you use in your automations between states.

  • Jorge Assunção

    Hi Phil, great job you’ve done! I’m having a small problem on the automation because i need to track three persons. I’ve changed:

    entity_id: >
    {% if trigger.entity_id == ‘input_select.jorge_status_dropdown’ %}
    input_select.jorge_status_dropdown
    {% else %}
    input_select.lara_status_dropdown
    {% endif %}

    into this:

    entity_id: >
    {% if trigger.entity_id == “input_select.jorge_status_dropdown” %}
    input_select.jorge_status_dropdown
    {% elif trigger.entity_id == “input_select.lara_status_dropdown” %}
    input_select.lara_status_dropdown
    {% else %}
    input_select.bia_status_dropdown
    {% endif %}

    But i get this automation error in Home Assistant log:

    ERROR (MainThread) [homeassistant.config] Invalid config for [automation]: invalid template (TemplateSyntaxError: Expected an expression, got ‘end of statement block’) for dictionary value @ data[‘action’][0][‘data_template’][‘entity_id’]. Got None.

    What am i doing wrong?

    • Hey Jorge,

      That’s so strange. So I copied your template into my Home Assistant to check that the syntax was correct, and it seems fine to me.

      In your config.yaml is your spacing correct?

      • Jorge Assunção

        yes it is. It stopped giving error when i wrapped it inside comas.

        entity_id: >
        “{% if trigger.entity_id == ‘input_select.jorge_status_dropdown’ %}
        input_select.jorge_status_dropdown
        {% elif trigger.entity_id == ‘input_select.lara_status_dropdown’ %}
        input_select.lara_status_dropdown
        {% else %}
        input_select.bia_status_dropdown
        {% endif %}”

        but i don’t know if it is working because state doesn’t change…

        If i check the syntax inside Developer Tools – Templates gives me the error (Error rendering template: UndefinedError: ‘trigger’ is undefined).

        • So in the developer tools, it will error because trigger is only available inside automations, so that makes sense. I replaced trigger with state, just to check the syntax.

          I have a feeling that using the double quote ” might have been the issue here. In your first example you had

          In your second example, using

          seemed to do the trick.

          So, now I’m looking at the code you’ve supplied and I’m not sure what it is trying to do. I think it should be

          You want to change the input_select based on what device_tracker entity gets updated. In your code. Try that out, and if it still doesn’t work can you post your automation?

          • Jorge Assunção

            Hi Phill. Thank you for your answer. It’s all working now!

  • Andrey Laptev

    Hello Phil.

    How do you keep persistence of template sensor during reboot?

    • So that’s a tricky one actually. For some reason Home Assistant is meant to remember the state of the dropdowns on reboot, but for some reason it doesn’t quite work for these.

      Yesterday I was doing some config changes remotely and restarting Home Assistant when I noticed we were being marked as Home, even though we were both away at work. I ended up adding an automation for each person to cover it. For example I added this automation so when HA boots, I am marked as away if my device tracker is “not_home”.

      You could also add another one to mark you as Home when it reboots.

      • Andrey Laptev

        Do you use initial attribute in your input_select config?
        I think it overrides remembered state.
        I have it in config and every time Hass reboots input_select goes to initial value.

        • So, I have one setup for me, but not one setup for my SO. So it seems it doesn’t matter if I use initial_state of not against the input_select it always seems to default people to Home for some reason.

  • – wιlғred

    Hi Phil,

    Nice approach! Question: why do you use entity_id: group.helen instead of something like entity_id: device_tracker.helen on row 61 of automation.yaml?

    • That’s an easy one 🙂

      I use multiple device trackers for my SO’s phone. She has an iPhone, which goes to sleep frequently so her Bluetooth and Wifi aren’t reliable.

      I track her iPhone with both WiFi and Bluetooth. So, if her bluetooth chip goes to sleep, the WiFi tracker will still “see” her as home, because her phone would still be connected to the WiFi.

      So, I have her group setup as

  • Mark Rennie

    I just wanted to say thanks Phil, this is genius and is working a treat on my system. I was always wanting to use something like this, now I can 🙂
    I also have grafana working following your guide, after failing a few months ago. I love stats!!

  • sangve

    Awesome work Phil!

  • Mark Reyes

    This is Awesome Phil! I’m adding to my HA config and looking forward to adding notifications based on state.
    I noticed some depreciation messages when testing in my dev instance:

    2018-01-24 01:04:15 WARNING (MainThread) [homeassistant.components.sensor.template] The 'entity_id' option (with value 'input_select.mark_status_dropdown') is deprecated, please remove it from your configuration.

    To clear this message, comment out the entity_id in the sensor template:

    mark_status:
    value_template: '{{ states.input_select.mark_status_dropdown.state }}'
    friendly_name: 'Mark'
    # entity_id: input_select.mark_status_dropdown

    Thanks again for the detailed walk through!

    • Hey Mark!

      Thanks so much for pointing that out. It seems as though that has been deprecated in the latest release. So I’ll update the code above for future readers!

      • Mark Reyes

        Hey Phil,
        I noticed another ‘edge case’ scenario: If the device tracker used to trigger the input_select.status_dropdown is out of range and HASS is restarted. Since the input_select is set with initial state of ‘home’ and there is no state change to trigger, then sensor.mark_status never transitions from ‘home’ even when device is not home.

        Steps to recreate: turn off your device’s wifi, restart HASS.
        IE: if you’re out for a week vacation, and your power resets, HASS will act as if devices are present.
        Possible solution: automation for a ‘backup-timmer’: if device_tracker is away for longer than +1hour, place into Away status…?
        (i’m checking into it too)

        • Oooh. That’s a good point. I’m usually restarting Home Assistant when everyone is home, so haven’t seen it. However your case of there being an unscheduled restart of HASS makes sense.

          I like your solution. I actually overcame this by adding another automation into the mix, which might be overkill. However adding another “for” trigger as you suggested might be cleaner.

          • Mark Reyes

            Awesome Phil! I think i’m going to merge that start trigger in, it’s cleaner than a running backoff timer. Thanks again!

          • Mark Rennie

            I was just back here to say exactly the same thing as I am going away shortly and, was wondering of there was anyway to retain the “extended away” status after a reboot. This would work fine, but it would need to wait another 24 hours for it to be extended away again, therefore run my away on holiday scripts..

          • Ah that’s a conundrum.

            When you restart home assistant, its internal timers for how long each device has been in a state will be reset.

            You could have it so when people are marked as Extended Away, an input Boolean is turned on. When home assistant restarts, it will check if that is turned on. If it is, then everyone is marked as Extended Away instead of away.

  • Eduard Antonyan

    Thanks, this is great! FYI I used https://github.com/rogro82/hass-variables instead for a cleaner implementation that also retains status across restarts.

    • That looks like a handy component! Thanks for sharing

Start typing and press Enter to search