Boucle for dans les actions d'une automatisation

Hello.

Je suis entrain de revoir un peu le mode canicule de la maison et j’en profite pour basculer une partie Nodered vers HA (pour voir)

  1. Pour l’exercice j’ai crée un groupe avec l’id de tous mes volets cover.ouvrants :

  2. J’ai depuis le début un input select qui me permet de sélectionner un mode pour ma canicule

mode_volets_canicule:
  options:
    - Normal
    - Velux
    - Ombre
    - Canicule
    - Frais ETG
    - Frais RDC
    - Nuit
  1. Pour les volets via le fichier customize.yaml j’ai créée des attributes_templates (je viens de découvrir), une valeur de position que j’aimerai exploiter pour chaque mode

  2. je sais récupérer la valeur de l’attributes_templates d’un volet en fonction du mode:

  3. Je sais faire une automatisation qui balance une position unique (issue d’in sensor ou en dur) à tous les membres du groupe cover. En fait c’est natif.

alias: Gestion mode canicule
description: ""
trigger:
  - platform: state
    entity_id:
      - input_select.mode_volets_canicule
condition:
  - condition: state
    entity_id: input_boolean.activation_chauffage
    state: "off"
  - condition: not
    conditions:
      - condition: state
        entity_id: input_select.mode_volets_canicule
        state: Normal
action:
  - service: cover.set_cover_position
    data:
      position: 10
    target:
      entity_id: cover.ouvrants
mode: single
  1. je sais envoyer la position specifique à chaque volet (en X appels séquentiels du service) en fonction du trigger
alias: Gestion mode canicule
description: ""
trigger:
  - platform: state
    entity_id:
      - input_select.mode_volets_canicule
condition:
  - condition: state
    entity_id: input_boolean.activation_chauffage
    state: "off"
  - condition: not
    conditions:
      - condition: state
        entity_id: input_select.mode_volets_canicule
        state: Normal
action:
  - service: cover.set_cover_position
    data:
      position: >-
        {{
        state_attr('cover.volet_sam_prop','attribute_templates')[trigger.to_state.state|lower] 
        }}
    target:
      entity_id: cover.volet_sam_prop
  - service: cover.set_cover_position
    data:
      position: >-
        {{
        state_attr('cover.volet_cuisine_prop','attribute_templates')[trigger.to_state.state|lower] 
        }}
    target:
      entity_id: cover.volet_cuisine_prop

mais ce que je NE sais pas faire, c’est éviter de de faire les X appels consécutifs au service et je voudrais utiliser l’équivalent d’une boucle for pour toutes les entités du group directement.

Voilà, pas sur que ce soit aussi clair pour les lectures que ça l’est dans ma tête

Bonjour ,

As-tu ces attributs pour ton cover.ouvrants?
Si oui. Ne peux pas tu utiliser le cover.ouvrants pour avoir tous en même temps ?

abel

Salut.
Effectivement c’est une bonne question, mais justement : non
Le cover.ouvrants c’est juste une liste d’entités (un groupe via les entrées dans l’ui)

Par ailleurs mes volets n’ont pas tous la même valeur à chaque fois pour les modes, en fonction du type de volet, de l’exposition etc j’ai plusieurs variations
Par exemple :

ça, HA n’aime pas
image

alias: Gestion mode canicule
description: ""
trigger:
  - platform: state
    entity_id:
      - input_select.mode_volets_canicule
condition:
  - condition: state
    entity_id: input_boolean.activation_chauffage
    state: "off"
  - condition: not
    conditions:
      - condition: state
        entity_id: input_select.mode_volets_canicule
        state: Normal
action: >
  {% set ns = namespace(select=[],covers="cover.ouvrants",mode=trigger.to_state.state|lower) %}
  {% for cover in state_attr(ns.covers, 'entity_id') %}
    {% set ns.select = ns.select + [
      {
        "service": "cover.set_cover_position",
        "data": {
          "position": "{{ state_attr('"+cover+"','attribute_templates')["+ns.mode+"]  }}"
        },
        "target": {
          "entity_id": cover
        }
      }
    ] %}
  {% endfor %}
  {{ ns.select }}

essaye avec data_template: { …

Pas mieux.
A noter qu’il semble que ce soit deprecated

La boucle for each correspond à tes attentes :

1 « J'aime »

C’est moins direct que ce que j’imaginais mais ça fonctionne (plus besoin du cover.ouvrants) :

alias: Gestion modes Canicule
description: Determine la position des volets en fonction de l'état du mode canicule
trigger:
  - platform: state
    entity_id:
      - input_select.mode_volets_canicule
condition:
  - condition: state
    entity_id: input_boolean.activation_chauffage
    state: "off"
  - condition: not
    conditions:
      - condition: state
        entity_id: input_select.mode_volets_canicule
        state: Normal
action:
  - service: script.launch_mode_canicule
    data: {}
mode: single

et le script

launch_mode_canicule:
  mode: restart
  sequence:
    repeat:
      for_each:
        - cover.velux_bureau_prop
        - cover.velux_suite_prop
        - cover.volet_amis_prop
        - cover.volet_cuisine_prop
        - cover.volet_sam_prop
        - cover.volet_sdbh_prop
        - cover.volet_salon_allee_prop
        - cover.volet_salon_rue_prop
        - cover.volet_suite_prop
      sequence:
        - service: cover.set_cover_position
          target:
            entity_id: "{{ repeat.item }}"
          data:
            position: "{{ state_attr(repeat.item,'attribute_templates')[states('input_select.mode_volets_canicule')|lower]}}"

Merci !!

Il semble que ce soit possible, quand je regarde vite fait dans les outils de dev après avoir créé un group bidon dans le configuration.yaml :

sensor:
  - platform: group
    type: mean
    entities:
      - sensor.capteur_presence_exterieur_battery
      - sensor.capteur_temperature_chambre_parents_battery
      - sensor.interrupteur_domi_battery
      - sensor.interrupteur_salle_de_jeu_battery

ce code me donne le OK :

{% set ns = namespace(test = []) %}
{% for x in expand('sensor.sensor_group_mean') if x.state | int(15) < 15 %}
    {% set ns.test = ns.test + [x.name] %}
{% endfor %}
{% if ns.test | count == 0 %}
  OK
{%- else -%}
  Pile thermo - de 15% : {{ ' et '.join((ns.test | join(', ')).rsplit(', ', 1)) }}
{%- endif -%}

celui ci me donne la liste des sensors qui sont en dessous de 75 %

{% set ns = namespace(test = []) %}
{% for x in expand('sensor.sensor_group_mean') if x.state | int(15) < 75 %}
    {% set ns.test = ns.test + [x.name] %}
{% endfor %}
{% if ns.test | count == 0 %}
  OK
{%- else -%}
  Pile thermo - de 15% : {{ ' et '.join((ns.test | join(', ')).rsplit(', ', 1)) }}
{%- endif -%}

Bon ok c’est pas exactement ce que tu veux mais tu as un exemple de boucle for.
C’est que je suis en train de mettre en place une liste de mes capteurs où la pile faiblit.

edit : pfff… t’es trop rapide.

1 « J'aime »

Oui, c’était élégant comme solution , mais le templating de la section action n’est valable avec cette syntaxe

1 « J'aime »

Ben oui, c’est pas Pulpy-Luke pour rien :joy:

3 « J'aime »