Last active
January 15, 2026 12:37
-
-
Save tim-peters/9f5188d67184ef330bb01d63fc5fe0fa to your computer and use it in GitHub Desktop.
Home Assistant Blueprint, that adds a basic while functionality – enabling users to sync states between different entities.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| blueprint: | |
| name: "While Condition – Entity State Sync" | |
| description: > | |
| Synchronisiert den Status mehrerer Entitäten bidirektional oder unidirektional. | |
| Unterstützt Master-Modus, Invertierung und Debouncing. | |
| source_url: https://gist.githubusercontent.com/tim-peters/9f5188d67184ef330bb01d63fc5fe0fa/raw/while.yaml | |
| domain: automation | |
| input: | |
| entities: | |
| name: Zu synchronisierende Entitäten | |
| description: > | |
| Liste aller Entitäten, deren Status synchronisiert werden soll. | |
| Unterstützt Schalter, Lichter, Input Booleans und andere on/off Entitäten. | |
| selector: | |
| entity: | |
| multiple: true | |
| domain: | |
| - switch | |
| - light | |
| - input_boolean | |
| - fan | |
| - automation | |
| - script | |
| sync_mode: | |
| name: Synchronisationsmodus | |
| description: > | |
| - Bidirektional: Alle Entitäten synchronisieren sich gegenseitig | |
| - Master: Nur die Master-Entität steuert alle anderen (unidirektional) | |
| default: bidirectional | |
| selector: | |
| select: | |
| options: | |
| - label: "Bidirektional (alle synchronisieren sich)" | |
| value: "bidirectional" | |
| - label: "Master (eine Entität steuert alle)" | |
| value: "master" | |
| mode: dropdown | |
| master_entity: | |
| name: Master-Entität | |
| description: > | |
| Nur relevant im Master-Modus. Diese Entität steuert alle anderen. | |
| Muss auch in der Entitätenliste oben enthalten sein! | |
| default: [] | |
| selector: | |
| entity: | |
| domain: | |
| - switch | |
| - light | |
| - input_boolean | |
| - fan | |
| - automation | |
| - script | |
| invert_mode: | |
| name: Invertierung aktivieren | |
| description: > | |
| Wenn aktiviert, werden die anderen Entitäten auf den | |
| ENTGEGENGESETZTEN Status gesetzt (Ein → Aus, Aus → Ein). | |
| default: false | |
| selector: | |
| boolean: {} | |
| only_react_to_manual: | |
| name: Nur auf manuelle Änderungen reagieren | |
| description: > | |
| WICHTIG für Invertierung mit mehr als 2 Entitäten! | |
| Wenn aktiviert, werden nur Änderungen durch Benutzeraktionen (UI, | |
| physischer Schalter, etc.) berücksichtigt. Änderungen durch andere | |
| Automationen werden ignoriert. Dies verhindert Endlosschleifen. | |
| default: true | |
| selector: | |
| boolean: {} | |
| debounce_time: | |
| name: Debounce-Zeit | |
| description: > | |
| Verzögerung in Millisekunden, um schnelle aufeinanderfolgende | |
| Änderungen zu ignorieren. Erhöhen bei Problemen mit Endlosschleifen. | |
| default: 150 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 5000 | |
| step: 50 | |
| unit_of_measurement: "ms" | |
| mode: slider | |
| ignore_unavailable: | |
| name: Nicht verfügbare Entitäten ignorieren | |
| description: > | |
| Wenn aktiviert, werden Entitäten im Status "unavailable" oder "unknown" ignoriert. | |
| default: true | |
| selector: | |
| boolean: {} | |
| # Verhindert parallele Ausführungen und bricht bei neuen Triggern ab | |
| mode: restart | |
| max_exceeded: silent | |
| trigger: | |
| - platform: state | |
| entity_id: !input entities | |
| not_from: | |
| - "unavailable" | |
| - "unknown" | |
| not_to: | |
| - "unavailable" | |
| - "unknown" | |
| variables: | |
| # Inputs als Variablen laden | |
| all_entities: !input entities | |
| sync_mode: !input sync_mode | |
| master: !input master_entity | |
| invert: !input invert_mode | |
| only_manual: !input only_react_to_manual | |
| debounce: !input debounce_time | |
| ignore_unavailable: !input ignore_unavailable | |
| # Trigger-Informationen | |
| trigger_entity: "{{ trigger.entity_id }}" | |
| new_state: "{{ trigger.to_state.state }}" | |
| old_state: "{{ trigger.from_state.state if trigger.from_state else 'unknown' }}" | |
| # Kontext-Prüfung: Wurde die Änderung von einer Automation ausgelöst? | |
| is_automation_triggered: "{{ trigger.to_state.context.parent_id is not none }}" | |
| # Modus-Prüfung | |
| is_master_mode: "{{ sync_mode == 'master' and master is defined and master | length > 0 }}" | |
| # Ziel-Status berechnen (mit Invertierung) | |
| target_state: > | |
| {% if invert %} | |
| {{ 'off' if new_state == 'on' else 'on' }} | |
| {% else %} | |
| {{ new_state }} | |
| {% endif %} | |
| # Ziel-Entitäten (alle außer dem Trigger) | |
| target_entities: > | |
| {{ all_entities | reject('eq', trigger_entity) | list }} | |
| condition: | |
| # Bedingung 1: Nur echte on/off Statusänderungen | |
| - condition: template | |
| value_template: > | |
| {{ new_state in ['on', 'off'] and | |
| old_state in ['on', 'off'] and | |
| new_state != old_state }} | |
| # Bedingung 2: Im Master-Modus nur auf Master reagieren | |
| - condition: template | |
| value_template: > | |
| {{ not is_master_mode or trigger_entity == master }} | |
| # Bedingung 3: Wenn nur manuelle Änderungen erlaubt, Automation-Trigger ignorieren | |
| # Dies ist der SCHLÜSSEL zur Verhinderung von Endlosschleifen! | |
| - condition: template | |
| value_template: > | |
| {{ not only_manual or not is_automation_triggered }} | |
| # Bedingung 4: Prüfen ob überhaupt eine Änderung nötig ist | |
| - condition: template | |
| value_template: > | |
| {% set needs_change = namespace(value=false) %} | |
| {% for entity in target_entities %} | |
| {% set entity_state = states(entity) %} | |
| {% if entity_state in ['on', 'off'] and entity_state != target_state %} | |
| {% set needs_change.value = true %} | |
| {% endif %} | |
| {% endfor %} | |
| {{ needs_change.value }} | |
| action: | |
| # Debouncing: Kurz warten um schnelle Änderungen abzufangen | |
| - delay: | |
| milliseconds: "{{ debounce | int }}" | |
| # Erneute Prüfung nach Debounce (Status könnte sich geändert haben) | |
| - condition: template | |
| value_template: > | |
| {{ states(trigger_entity) == new_state }} | |
| # Entitäten filtern die tatsächlich geändert werden müssen | |
| - variables: | |
| entities_to_change: > | |
| {% set to_change = namespace(list=[]) %} | |
| {% for entity in target_entities %} | |
| {% set entity_state = states(entity) %} | |
| {% if ignore_unavailable and entity_state in ['unavailable', 'unknown'] %} | |
| {# Ignorieren #} | |
| {% elif entity_state in ['on', 'off'] and entity_state != target_state %} | |
| {% set to_change.list = to_change.list + [entity] %} | |
| {% endif %} | |
| {% endfor %} | |
| {{ to_change.list }} | |
| # Status setzen (nur wenn Entitäten zu ändern sind) | |
| - if: | |
| - condition: template | |
| value_template: "{{ entities_to_change | length > 0 }}" | |
| then: | |
| - choose: | |
| # Einschalten | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ target_state == 'on' }}" | |
| sequence: | |
| - service: homeassistant.turn_on | |
| target: | |
| entity_id: "{{ entities_to_change }}" | |
| # Ausschalten (default) | |
| default: | |
| - service: homeassistant.turn_off | |
| target: | |
| entity_id: "{{ entities_to_change }}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment