Using targets as conditions?

Hi all, thanks for the awesome new feature. One question I am struggling with is designing a blue print that checks a condition based on a target.
Simplified below, something along the lines of

  input:
    light_target:
      name: Light
      selector:
        target:
          entity:
            domain: light
...
condition:
  - condition: state
    target: !input light_target
    state: "on"
...
action:
  - service: light.turn_off
    target: !input light_target

I suppose this fails because conditions cannot be contain targets, is this correct? or am I missing something. I suppose I can specify the target to be a light, but would like to incorporate the slick new target selector if I can.

Thanks!

FWIW, I tried your example and based on this last part of the resulting error message, I believe you are correct; it doesn’t recognize the target key.

extra keys not allowed @ data[‘condition’][0][‘target’]. Got None required key not provided @ data[‘condition’][0][‘entity_id’]. Got None

Thanks so much for trying and confirming!

I managed to circumvent the problem by taking out the target and directly specifying ‘light groups’ instead of areas, little fiddly changing the existing automations in automation.yaml, but success none the less.

Blueprints are still awesome, specifically since its the initial roll-out.

I have the same issue. The light target is actually an object w/ with the entity_id under the key “entity_id”. I haven’t figured out how to get at the actual id contained within for use in my condition.

Not being able to resolve/use targets outside of service calls is still a problem. Here are some possible ways how Home Assistant might be able to fix this.

Option 1) Allow target to be used in other locations entity_id can be provided. Resolve target to a list of entities which is transparently provided as a list to entity_id. E.g.

condition: state
target: !input my_input_target
state: 'on'

Option 2) Add a template filter/function that turns a provided target into a list of entities. Provides better flexibility to be used wherever templates can be used. E.g.

- variables:
  my_target: !input my_target_input
- service: system_log.write
  data:
    message: "{{ expand(my_target) }}"
    level: info

Option 3) Making scene.apply compatible with target might also be useful, e.g.

service: scene.apply
data:
  target: !input my_target_input
  apply:
    brightness_pct: 50

Option 4) Since a common use-case for a lot of this is probably to remove specific entities from a service call (e.g. only call light.turn_on with a specific argument on light entities in the target group that are currently on), making target’s filterable by condition, might also work, e.g.

service: light.turn_on
target: 
 input: !input my_target_input
 filter: 
 - condition: state
   state: on
data: 
  brightness_pct: 50

Do any of these options seem reasonable? Is this something we could get with an upcoming release of HA?

3 Likes

I was also struggling with this.
I wanted to build a blueprint where I select a single entity ID and re-use it for the several conditions and services.

I played around a few hours now. It seems I got it eventually to work via the following but I still needed to stick with the target selector.

!input entity_id('my_target_input')

Extract of blueprint example:

blueprint:
  name: "Set blind position to 2 percent"
  domain: script
  input:
    my_target_input:
      name: "Blind"
      selector:
        target:
          entity:
            domain: cover
            device_class: shutter

mode: single

sequence:
  - condition: numeric_state
    entity_id: !input entity_id('my_target_input')
    attribute: current_position
    below: 1
  - service: cover.set_cover_position
    data:
      position: 2
    target:
      entity_id: !input my_target_input



Edit (2021-12-19):
Sorry that didn’t even work. I got it to work but not w/ what I stated above. Let’s correct this w/ another example:

Blueprint:

blueprint:
  name: Set blind position to 2 percent
  domain: script
  input:
    my_target_input:
      name: "Blind"
      selector:
        target:
          entity:
            domain: cover
            device_class: shutter
            integration: shelly

mode: single

sequence:
  - condition: numeric_state
    entity_id: !input my_target_input
    attribute: current_position
    below: 1
  - service: cover.set_cover_position
    data:
      position: 2
    target:
      entity_id: !input my_target_input

Script using the blueprint:

script_shutter_open:
  alias: SHUTTER - Set blind position to 2 percent for living room blind 1
  use_blueprint:
    path: blueprint__shutter__blind-pos-2-percent.yaml
    input:
      my_target_input: cover.living_room_blind_1

Note that I needed to manually remove the target keyword within the script.

@ringbuchblock in your case, I think you’re dealing with something different. If you add the following to your blueprint you’ll find the variable is accessible like you would expect:

variables:
  my_target_input: !input my_target_input

The OP is trying to use this inside of a condition which is a different animal. Go ahead and add the lines above to your blueprint and you’ll be able to do things like {{ my_input_target }} in the way you would normally expect.

Note that with the addition of area_entities and device_entities in one of the more recent updates one should be able to manually “untangle” a target object using Jinja, since all the primitives to turn a target into a list of entities now exist.

Edit: Obviously, abstracting this in e.g. a target_entities template function might still make our lifes easier :slight_smile:

Hi @luma,

thank you for your reply. But I also work w/ conditions or is my case a different one?

I have a condition

  - condition: numeric_state
    entity_id: !input my_target_input
    attribute: current_position
    below: 1

… which wants an entity ID input and then I call a service

  - service: cover.set_cover_position
    data:
      position: 2
    target:
      entity_id: !input my_target_input

… which wants a target input.

Maybe I did not express my problem properly but I am “suffering” from the mixture of needed selectors. All I want is to provide one (or more) entity IDs and use them for both the actions.


I tried to work w/ your suggestion w.r.t. variables but so far I could not figure out where to put this exactly.

@dev0, this sounds interesting. Could you maybe point me to some documentation of this new feature?

You can find it in the Templating documentation.

@dev0 could you maybe explain further what you mean with “untangle a target object”?

I am looking to do the same thing I think some other here are trying too: I have a blueprint with a target input

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

and I want to add a condition that checks if all these devices are switched on. Something like this seems logical but does not work:

- condition: state
        entity_id: !input light_target
        state: "on"

From what I can see if a rule based on the blueprint is built it actually contains a variable that has an entity_id field that contains a list of the actual entities. I assume I would need to provide these to the entity id field somehow? I am not sure how to do that though.
I would be very grateful for some advice here

PS I tried something like this but it does not seem to work either

# making the input variable usable in the condition
variables:
  lights: !input "light_target"
...
- condition: state
        entity_id: "{% expand(lights.entity_id) %}"
        state: "on"

Have you tried using a template condition and checking the entities “manually”? I didn’t say it was easy or straightforward to do, just that it appears to be now possible (although still requiring a lot of elbow grease).

I have been working on that for the last day and I think I finally found a working solution. This seems to work as a condition that checks if any of the lights in the target group are on:

# making the input variable usable in the condition
variables:
  lights: !input "light_target"
...
- "{{ expand(lights.entity_id) | selectattr('state', '==', 'on') | list | count > 0 }}"

This is not very flexible (yet) though as I assume if you pick groups or devices instead of entities they would not be in the “entity_id” attribute. It would be really awesome to have a built-in condition for things like this

5 Likes

Since it wasn’t immediately obvious to me, I’ll note that the above goes into a template condition, i.e.

instead of

- condition: state
  entity_id: ...
  state: "on"

you use

- condition: template
  value_template: "{{ expand(lights.entity_id) | selectattr('state', '==', 'on') | list | count > 0 }}"