blueprint:
  name: Christmas lights schedule (TechnoGecko)
  description: >-
    Turns holiday lights on at sunset (with an optional offset) during the
    dates you choose, and off at a weekday or weekend bedtime. Optionally
    skips turning on when nobody is home, turns the lights off when the
    last person leaves, and turns them back on if someone comes home
    before bedtime. Outside the season dates it does nothing. Works with
    any switch or light entity, including Zigbee, Wi-Fi and Matter smart
    plugs.
  domain: automation
  author: TechnoGecko
  source_url: https://technogecko.net/blueprints/christmas-lights-automation.yaml
  homeassistant:
    min_version: "2026.2.0"
  input:
    lights:
      name: Lights and plugs
      description: The smart plugs (switches) or lights that power your decorations.
      selector:
        entity:
          multiple: true
          filter:
            - domain:
                - switch
                - light
    schedule_section:
      name: Schedule
      icon: mdi:calendar-clock
      input:
        season_start:
          name: Season starts
          description: First day the lights run. Only the month and day are used, so it repeats every year.
          default: "2026-11-27"
          selector:
            date:
        season_end:
          name: Season ends
          description: Last day the lights run. Can be in January; the season wraps past New Year.
          default: "2027-01-06"
          selector:
            date:
        sunset_offset:
          name: Sunset offset
          description: Negative turns the lights on before sunset, positive after.
          default:
            hours: 0
            minutes: 0
            seconds: 0
          selector:
            duration:
              allow_negative: true
        weekday_off_time:
          name: Weekday off time
          description: Pick a time before midnight.
          default: "22:30:00"
          selector:
            time:
        weekend_off_time:
          name: Weekend off time
          description: Pick a time before midnight.
          default: "23:30:00"
          selector:
            time:
        weekend_days:
          name: Weekend nights
          description: Nights that use the weekend off time. Pick at least one.
          default:
            - fri
            - sat
          selector:
            select:
              multiple: true
              options:
                - label: Monday
                  value: mon
                - label: Tuesday
                  value: tue
                - label: Wednesday
                  value: wed
                - label: Thursday
                  value: thu
                - label: Friday
                  value: fri
                - label: Saturday
                  value: sat
                - label: Sunday
                  value: sun
    presence_section:
      name: Away handling
      icon: mdi:home-account
      input:
        home_zone:
          name: Home zone
          description: Its state is the number of people at home.
          default: zone.home
          selector:
            entity:
              filter:
                - domain: zone
        require_someone_home:
          name: Only turn on when someone is home
          default: true
          selector:
            boolean:
        off_when_everyone_leaves:
          name: Turn off when the last person leaves
          default: true
          selector:
            boolean:

mode: queued
max_exceeded: silent

variables:
  season_start: !input season_start
  season_end: !input season_end
  home_zone: !input home_zone
  require_someone_home: !input require_someone_home
  off_when_everyone_leaves: !input off_when_everyone_leaves

triggers:
  - trigger: sun
    event: sunset
    offset: !input sunset_offset
    id: lights_on
  - trigger: time
    at: !input weekday_off_time
    id: weekday_off
  - trigger: time
    at: !input weekend_off_time
    id: weekend_off
  - trigger: numeric_state
    entity_id: !input home_zone
    below: 1
    id: everyone_left
  - trigger: numeric_state
    entity_id: !input home_zone
    above: 0
    id: someone_home

# Season check for every trigger: outside the season dates, nothing happens.
conditions:
  - condition: template
    value_template: >-
      {% set today = now().strftime('%m-%d') %}
      {% set s = season_start[5:10] %}
      {% set e = season_end[5:10] %}
      {% if s <= e %}{{ s <= today <= e }}{% else %}{{ today >= s or today <= e }}{% endif %}

actions:
  - choose:
      - conditions:
          - condition: trigger
            id: lights_on
          - condition: template
            value_template: >-
              {{ not require_someone_home or (states(home_zone) | int(0)) > 0 }}
        sequence:
          - action: homeassistant.turn_on
            target:
              entity_id: !input lights
      - conditions:
          - condition: trigger
            id: weekday_off
          - condition: not
            conditions:
              - condition: time
                weekday: !input weekend_days
        sequence:
          - action: homeassistant.turn_off
            target:
              entity_id: !input lights
      - conditions:
          - condition: trigger
            id: weekend_off
          - condition: time
            weekday: !input weekend_days
        sequence:
          - action: homeassistant.turn_off
            target:
              entity_id: !input lights
      - conditions:
          - condition: trigger
            id: everyone_left
          - condition: template
            value_template: "{{ off_when_everyone_leaves }}"
        sequence:
          - action: homeassistant.turn_off
            target:
              entity_id: !input lights
      - conditions:
          - condition: trigger
            id: someone_home
          # Only between sunset (plus your offset) and tonight's off time.
          - condition: sun
            after: sunset
            after_offset: !input sunset_offset
          - condition: or
            conditions:
              - condition: and
                conditions:
                  - condition: time
                    weekday: !input weekend_days
                  - condition: time
                    before: !input weekend_off_time
              - condition: and
                conditions:
                  - condition: not
                    conditions:
                      - condition: time
                        weekday: !input weekend_days
                  - condition: time
                    before: !input weekday_off_time
        sequence:
          - action: homeassistant.turn_on
            target:
              entity_id: !input lights
