Using a target selector in a condition with Home Assistant blueprints

Published by Oliver on

Blueprints are a powerful feature of Home Assistant that makes sharing and using automations simpler. Unfortunately using the target selector in a condition is not supported by default. I needed this for an automation of mine and found a way.

Blueprints and the target selector

Blueprints are one of the best recent additions to Home Assistant in my opinion. They are basically a generalized automation. Instead of building an automation with exactly this and that device you can instead also define a generic blueprint. That blueprint can than easily be used to create automations (from the UI!) and to share it with others.

The way of defining an input for an automation is to use a selector. This is basically telling Home Assistant that this automation will need a device/entity/group/state/… of some kind to work. There is a great selector called target which can be used to define a flexible (entity, device or group) target of your automation. Services like light.turn_on can be used with a target making these automations very generic. You can also restrict the target to certain domains (only lights for example).

Using a target selector in a condition

I have used and shared some blueprints of my own here. My most used blueprint is the motion-brightness-light combination for my smart lighting setup. Using the small Aqara Zigbee motion sensors (via ZHA) I created an automation that takes into account their motion/no motion data as well as the brightness level they send to decide whether to automatically turn on the lights.

If you want to use this great motion sensor too consider buying it via this affiliate link to support the blog

Basically the light is turned on only while motion is detected and the room is not bright enough already. Unfortunately there was a small logic error in my automation. Turning the lights on will obviously increase the brightness in the room. This might lead to the lights being turned off afterwards, even if motion is still detected. I tried to work around this by also testing if the sun is still up but in the dark winter in Germany even during the day it might be too dark in some rooms.

There is an easy fix for that: checking if the lights are already on and only turning them off if no motion is detected anymore. Or in another way: only turn on the lights if motion is detected and [the brightness was below a certain point or any of the lights were already on (or both)].

I receive all the devices to turn on in the blueprint via a target selector like this:

light_target:
      name: Light(s) to control
      selector:
        target:
          entity:
            domain: light

Unfortunately the simple condition statements in Home Assistant do not yet support a target as input (as described in this forum post I found). After not finding a solution I started experimenting to get around this problem.

It turns out that the target is basically a list with all the entities inside (if you selected entities on the UI). Using a condition with custom logic you can work with that. In the blog post above I found the information that input variables are not directly accessible inside the condition but you can get around this by moving them to a variable like this:

# making the input variable usable in the condition
variables:
  lights: !input "light_target"

Next I use this variable in a custom condition that puts all the entity ids in this list (you need to change this code if you use devices/groups I guess) into a stream, gets their state by id and filters for on, puts those states into a list and finally checks if the list is empty.

If there are any lights turned on the list will not be empty and the timer to turn off the lights will be reset. If they are all off and the brightness is already high enough the timer to turn off the lights will start ticking. The new condition looks like this:

condition:
  - condition: or
    conditions:
      - "{{ expand(lights.entity_id) | selectattr('state', '==', 'on') | list | count > 0 }}" # some lights in the group are on
      - condition: numeric_state
        entity_id: !input brightness_entity
        below: !input brightness_trigger

Shortfalls

This works very well for me, no more lights randomly turning off. It does not yet work with anything but entities though I think. As always you can find the code on my Github account.

if you used the target selector in a condition with this trick you need to only use entities or change the code
Only used entities with this trick

I sincerely hope that the Home Assistant devs keep expanding the capabilities of the blueprints and add support for targets as conditions too. It feels like a feature that could be really useful from time to time.