Trouble trying to capture multiple devices and iterating on them with for_each

hey all, C/C++ dev wading into my first HA blueprint, getting an error

“Message malformed: extra keys not allowed @ data[‘repeat’]”

on this code:

blueprint:
    name: Cool Room When in AC
    description: Opens vents if AC is running and the room is warmer than the thermostat.
    domain: automation
    input:
        target_vent:
            name: Vent Controller
            description: Vent to be controlled.
            selector:
                entity:
                    domain: cover
                    device_class: damper
                    multiple: true
        temperature_sensor:
            name: Temperature Sensor
            description: Temperature sensor that dictates state of vent.
            selector:
                entity:
                    domain: sensor
                    device_class: temperature
repeat:
    for_each:
      - !input target_vent
    sequence:
        trigger:
          - platform: numeric_state
            entity_id: !input temperature_sensor
            above: sensor.ecobee_temperature
        condition:
          - condition: and
            conditions:
              - condition: device
                device_id: device_id(repeat.item)
                domain: cover
                entity_id: repeat.item
                type: is_position
                below: 100
              - condition: and
                conditions:
                  - condition: device
                    device_id: x
                    domain: climate
                    entity_id: climate.ecobee
                    type: is_hvac_mode
                    hvac_mode: cool
        action:
          - device_id: device_id(repeat.item)
            domain: cover
            entity_id: repeat.item
            type: set_position
            position: 100
mode: single

Repeat is an action type, so it should be in the action block. Also, Device conditions and actions do not take templates, so you will need to change those to the appropriate types… i.e. State and Service Call.

So how do I iterate on the conditional of having multiple vent inputs? Or is that not possible?

blueprint:
  name: Cool Room When in AC
  description: Opens vents if AC is running and the room is warmer than the thermostat.
  domain: automation
  input:
      target_vent:
        name: Vent Controller
        description: Vent to be controlled.
        selector:
          entity:
              domain: cover
              device_class: damper
              multiple: true
      temperature_sensor:
        name: Temperature Sensor
        description: Temperature sensor that dictates state of vent.
        selector:
          entity:
              domain: sensor
              device_class: temperature
trigger:
  - platform: numeric_state
    entity_id: !input temperature_sensor
    above: sensor.ecobee_temperature
condition:
  - condition: state
    attribute: hvac_mode
    entity_id: climate.ecobee
    state: cool
action:
  - repeat:
      for_each: !input target_vent
      sequence:
        - condition: template
          value_template: "{{ state_attr(repeat.item, 'position') | int < 100 }}"
        - service: cover.set_cover_position
          target:
            entity_id: "{{repeat.item}}"
          data:
            position: 100
mode: single

EDIT: Corrected condition mistake in repeat

OHHHH I see, you move that condition down into the action. Apologies, getting acclimated to this syntax still, super appreciate the assist!

It does not seem to like this line:

Message malformed: Entity {{ repeat.item }} is neither a valid entity ID nor a valid UUID for dictionary value @ data[‘action’][0][‘repeat’][‘sequence’][0][‘entity_id’]

Is there a particular reason you used a repeat for this application?

Because it’s not necessary to use repeat for setting the position of multiple covers.

blueprint:
  name: Cool Room When in AC
  description: Opens vents if AC is running and the room is warmer than the thermostat.
  domain: automation
  input:
      target_vent:
        name: Vent Controller
        description: Vent to be controlled.
        selector:
          entity:
              domain: cover
              device_class: damper
              multiple: true
      temperature_sensor:
        name: Temperature Sensor
        description: Temperature sensor that dictates state of vent.
        selector:
          entity:
              domain: sensor
              device_class: temperature
trigger:
  - platform: numeric_state
    entity_id: !input temperature_sensor
    above: sensor.ecobee_temperature
condition:
  - condition: state
    attribute: hvac_mode
    entity_id: climate.ecobee
    state: cool
action:
  - variables:
      vents: !input target_vent
      open_vents: "{{ expand(vents) | selectattr('attributes.position', 'lt', 100) | map(attribute='entity_id') | list }}"
  - condition: template 
    value_template: "{{ open_vents | count > 0 }}"
  - service: cover.set_cover_position
    target:
      entity_id: "{{ open_vents }}"
    data:
      position: 100
mode: single

Yep, that’s my dumb mistake… Numeric state conditions don’t accept templates. I’ve replaced it above with a Template condition.

1 Like

Thank you so much! That seemed to work! There are a lot of “gotchyas” I still need to learn, apologies for my ignorance and I appreciate your patience!

@123 I appreciate your input as well, I used it because I am new to this syntax and am still learning, so it was my own ignorance :slight_smile: I tested your solution out and it threw an error, Drew’s solution appears to be working but I thought I would provide that information for completeness sake on this issue, and thank you again kindly :slight_smile:

What’s the error?

Message malformed: invalid template (TemplateSyntaxError: expected token ',', got 'string') for dictionary value @ data['action'][0]['variables']['open_vents']

Can you confirm what you used is identical to this:

      open_vents: "{{ expand(vents) | selectattr('attributes.position', 'lt', 100) | map(attribute='entity_id') | list }}"

The initial version had a missing single-quote before the word attributes.position. If you used that version then it would definitely produce an error.

I copied/pasted exactly, so it was probably that :slight_smile: Nice catch!

Anyway, at least now you know that most service calls support multiple entities so there’s no need to use repeat for that purpose.

1 Like