Created
December 21, 2025 20:16
-
-
Save deg0nz/54da3d4723dca332236e10c87c12aa26 to your computer and use it in GitHub Desktop.
HA Lights Holiday Automation
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: Urlaubs-Simulation – realistisch nach Sonnenuntergang | |
| description: > | |
| Schaltet nach Sonnenuntergang zufällig Lichter an/aus, wenn seit mindestens X Stunden niemand zuhause war. | |
| Stoppt sofort, wenn jemand nach Hause kommt. | |
| domain: automation | |
| input: | |
| presence_entity: | |
| name: Anwesenheits-Entität | |
| description: z.B. group.family, person.xyz oder ein Binary-Sensor (home/away bzw. on/off) | |
| selector: | |
| entity: | |
| multiple: false | |
| away_state: | |
| name: "State der 'niemand zuhause' bedeutet" | |
| description: > | |
| Für group/person meist "not_home". Für binary_sensor meist "off". | |
| default: not_home | |
| selector: | |
| text: {} | |
| min_away_hours: | |
| name: Mindest-Abwesenheit vor Sonnenuntergang (Stunden) | |
| default: 5 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 24 | |
| step: 1 | |
| mode: slider | |
| target_lights: | |
| name: Ziel-Lichter (frei wählbar) | |
| selector: | |
| target: | |
| entity: | |
| domain: light | |
| end_time: | |
| name: Endzeit (bis wann simuliert wird) | |
| default: "23:30:00" | |
| selector: | |
| time: {} | |
| min_delay_minutes: | |
| name: Minimale Wartezeit zwischen Aktionen (Minuten) | |
| default: 8 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 60 | |
| step: 1 | |
| mode: slider | |
| max_delay_minutes: | |
| name: Maximale Wartezeit zwischen Aktionen (Minuten) | |
| default: 25 | |
| selector: | |
| number: | |
| min: 2 | |
| max: 120 | |
| step: 1 | |
| mode: slider | |
| min_on_minutes: | |
| name: Minimale Einschalt-Dauer pro Licht (Minuten) | |
| default: 6 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 120 | |
| step: 1 | |
| mode: slider | |
| max_on_minutes: | |
| name: Maximale Einschalt-Dauer pro Licht (Minuten) | |
| default: 35 | |
| selector: | |
| number: | |
| min: 2 | |
| max: 240 | |
| step: 1 | |
| mode: slider | |
| random_brightness: | |
| name: Zufällige Helligkeit nutzen (wenn unterstützt) | |
| default: true | |
| selector: | |
| boolean: {} | |
| brightness_min: | |
| name: Helligkeit Minimum (%) | |
| default: 35 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 100 | |
| step: 1 | |
| mode: slider | |
| brightness_max: | |
| name: Helligkeit Maximum (%) | |
| default: 85 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 100 | |
| step: 1 | |
| mode: slider | |
| random_color_temp: | |
| name: Zufällige Farbtemperatur nutzen (wenn unterstützt) | |
| default: true | |
| selector: | |
| boolean: {} | |
| mode: restart | |
| max_exceeded: silent | |
| trigger: | |
| - platform: sun | |
| event: sunset | |
| variables: | |
| presence_entity: !input presence_entity | |
| away_state: !input away_state | |
| min_away_hours: !input min_away_hours | |
| end_time: !input end_time | |
| min_delay_minutes: !input min_delay_minutes | |
| max_delay_minutes: !input max_delay_minutes | |
| min_on_minutes: !input min_on_minutes | |
| max_on_minutes: !input max_on_minutes | |
| random_brightness: !input random_brightness | |
| brightness_min: !input brightness_min | |
| brightness_max: !input brightness_max | |
| random_color_temp: !input random_color_temp | |
| # "Seit mind. X Stunden away" – einfache, robuste Näherung über last_changed. | |
| away_long_enough: > | |
| {% set s = states(presence_entity) %} | |
| {% if s != away_state %} | |
| false | |
| {% else %} | |
| {{ (as_timestamp(now()) - as_timestamp(states[presence_entity].last_changed)) >= (min_away_hours * 3600) }} | |
| {% endif %} | |
| condition: | |
| - condition: template | |
| value_template: "{{ away_long_enough }}" | |
| action: | |
| - variables: | |
| # Ziel-Entity-IDs als Liste | |
| light_entities: > | |
| {% set t = !input target_lights %} | |
| {% if t.entity_id is string %} | |
| [ t.entity_id ] | |
| {% elif t.entity_id is sequence %} | |
| {{ t.entity_id }} | |
| {% else %} | |
| [] | |
| {% endif %} | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ light_entities | length > 0 }}" | |
| sequence: | |
| # Haupt-Loop bis Endzeit oder bis jemand nach Hause kommt | |
| - repeat: | |
| while: | |
| - condition: template | |
| value_template: > | |
| {{ now().strftime('%H:%M:%S') < end_time }} | |
| - condition: template | |
| value_template: > | |
| {{ states(presence_entity) == away_state }} | |
| sequence: | |
| # 1) Zufällig ein Licht auswählen und einschalten | |
| - variables: | |
| chosen_light: "{{ light_entities | random }}" | |
| do_bri: "{{ random_brightness }}" | |
| bri_pct: "{{ range(brightness_min, brightness_max + 1) | random }}" | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ chosen_light }}" | |
| data: | |
| transition: 1 | |
| brightness_pct: > | |
| {% if do_bri %}{{ bri_pct }}{% else %}{{ omit }}{% endif %} | |
| color_temp_kelvin: > | |
| {% if random_color_temp %} | |
| {{ range(2200, 3201) | random }} | |
| {% else %} | |
| {{ omit }} | |
| {% endif %} | |
| # 2) Licht bleibt zufällig lange an | |
| - delay: | |
| minutes: "{{ range(min_on_minutes, max_on_minutes + 1) | random }}" | |
| # 3) Zufällig entscheiden: aus / oder “noch eins dazu” | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ (range(1, 101) | random) <= 70 }}" | |
| sequence: | |
| - service: light.turn_off | |
| target: | |
| entity_id: "{{ chosen_light }}" | |
| data: | |
| transition: 1 | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ (range(1, 101) | random) <= 50 }}" | |
| sequence: | |
| - variables: | |
| second_light: "{{ (light_entities | reject('eq', chosen_light) | list | default(light_entities)) | random }}" | |
| bri2: "{{ range(brightness_min, brightness_max + 1) | random }}" | |
| - service: light.turn_on | |
| target: | |
| entity_id: "{{ second_light }}" | |
| data: | |
| transition: 1 | |
| brightness_pct: > | |
| {% if random_brightness %}{{ bri2 }}{% else %}{{ omit }}{% endif %} | |
| # 4) Pause zwischen Aktionen (randomisiert) | |
| - delay: | |
| minutes: "{{ range(min_delay_minutes, max_delay_minutes + 1) | random }}" | |
| # Am Ende: optional alles aus, aber nur wenn weiterhin niemand da ist | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ states(presence_entity) == away_state }}" | |
| sequence: | |
| - service: light.turn_off | |
| target: !input target_lights | |
| data: | |
| transition: 2 | |
| default: | |
| - stop: "Keine Lichter ausgewählt." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment