Xmas tree trigger w/ off + randomness help request

I’m trying to learn a bit here from a basic automation that turns or turns off at a time or sensor trigger. I figured maybe I can have the tree turn off at a specific time (never tried this) and additionally add a little randomness where it turns off 2 to 30 minutes after the 22:32 trigger (never tried randomness, either).

I’m sure I crapped this up and am happy for guidance to learn. Thanks!

- id: '5000000000001'
  alias: Exterior front lights evening
  trigger:
  - platform: sun
    event: sunset
    offset: -00:20:00
  condition: []
action:
  - condition: state
    entity_id: switch.livingroom_tree
    state: 'off'
  - service: switch.turn_on
    target:
      entity_id: switch.livingroom_tree
  - wait_for_trigger:
      - platform: time
        at: "22:32:00"
	  - delay:
        minutes: '{{ range(2, 36) | random }}'
    continue_on_timeout: false
  - service: switch.turn_off
    target:
      entity_id: switch.livingroom_tree

That is really not optimal. It is a long time to wait to turn the lights off. If you restart home assistant or reload automations during that time the lights wont turn off.

Far better to use two automations. One for on (sunset trigger). One for off (time trigger).

Or if you must use one automation, use two separate triggers and use the choose action to decide what to do when it triggers.

- id: '5000000000001'
  alias: Exterior front lights evening
  trigger:
    - platform: sun
      event: sunset
      offset: -00:20:00
      id: 'lights_on'
    - platform: time
      at: "22:32:00"
  action:
    - choose:
        - conditions:
            - "{{ trigger.id == 'lights_on'}}"
      sequence:
        - service: switch.turn_on
          target:
            entity_id: switch.livingroom_tree
      default:
        - delay:
            minutes: '{{ range(2, 36) | random }}'
        - service: switch.turn_off
          target:
            entity_id: switch.livingroom_tree

I’m content splitting it up. That’s what I’ve been doing, but I have so many automations I figured man I must be inefficient as hell doing it that way. But, hey if it’s best it’s best!

Would I just drop the delay line below the action in such an instance like this below?

- id: '5000000000002'
  alias: Christmas tree off randomized
  trigger:
    - platform: time
      at: "22:32:00"
  condition: []
  action:
  - delay:
      minutes: '{{ range(2, 36) | random }}'
  - service: switch.turn_off
    target:
      entity_id: switch.livingroom_tree

Yep that will do it. And no it is not any less efficient than using a combined single automation.

For your consideration, here’s another way to do it.

Create a Trigger-based Template Sensor that computes a randomized time at the start of every day (and whenever Home Assistant is restarted or Template Entities are reloaded).

template:
  - trigger:
      - platform: time
        at: '00:00:00'
      - platform: homeassistant
        event: start
      - platform: event
        event_type: event_template_reloaded
    sensor:
      - name: Tree Off
        unique_id: tree_off
        state: "{{ (today_at('22:32') + timedelta(minutes = range(2,36) | random)).isoformat() }}"
        device_class: timestamp

One advantage of this approach is that the sensor’s value will be visible in the UI so for any given day you will know when the tree will be turned off. For example, here’s how it appears in Developer Tools > States:

and in the UI:

Screenshot from 2021-11-14 09-09-50

The automation to turn the tree on/off can now be reduced to this:

- id: '5000000000003'
  alias: Christmas tree randomized
  trigger:
    - platform: sun
      event: sunset
      offset: -00:20:00
    - platform: time
      at: sensor.tree_off
  action:
    - service: "switch.turn_{{ 'on' if trigger.platform == 'sun' else 'off' }}"
      target:
        entity_id: switch.livingroom_tree

The main advantage of this approach is that the scheduled off time doesn’t rely on delay which, although useful, is cancelled by a restart (or Reload Automations) just like tom_I explained for wait_for_trigger (the same is true for wait_template, for, repeat, etc).

This automation isn’t affected by restarts/reloads unless they occur at the scheduled “off” time. There are techniques to mitigate that situation as well (but will make the automation a bit more complicated). If you’re interested, you can see how an automation can be made more “fault resistant” in this short tutorial:

Thank you both for the options. I’ve been playing with them. With respect to the templates, I tried expanding it to be a little different for another room’s decorations (just kept tree as a label). However, it’s only creating a sensor timer for the livingroom.

This is what I added to configuration.yaml:


template:
  - trigger:
      - platform: time
        at: '00:00:00'
      - platform: homeassistant
        event: start
      - platform: event
        event_type: event_template_reloaded
    sensor:
      - name: Livingroom_Tree_Off
        unique_id: tree_off
        state: "{{ (today_at('22:32') + timedelta(minutes = range(2,36) | random)).isoformat() }}"
        device_class: timestamp
      - name: Familyroom_Tree_Off
        unique_id: tree_off
        state: "{{ (today_at('21:00') + timedelta(minutes = range(2,36) | random)).isoformat() }}"
        device_class: timestamp

I tried having it broken out as template: twice with each instance in its own string, but I get an error and HA won’t reload configuration that way.

Where am I running afoul here?

You assigned both sensors the same value for unique_id. It should be a unique value for each sensor. Make the second sensor’s unique_id different from the first one (then execute Reload Template Entities).

Lol DOOOOOH! I thought I changed that. What I get for giving up caffeine I suppose. Need to blame it on something. :smiley:

If you’re interested, you can use a single automation to control both trees. This example assumes they both turn on at the same time (before sunset) but turn off at different (randomized) times.

- id: '5000000000003'
  alias: Christmas trees randomized
  trigger:
    - platform: sun
      event: sunset
      offset: -00:20:00
    - id: 'livingroom_tree'
      platform: time
      at: sensor.livingroom_tree_off
    - id: 'familyroom_tree'
      platform: time
      at: sensor.familyroom_tree_off
  action:
    - choose:
      - conditions: "{{ trigger.platform == 'sun' }}"
        sequence:
        - service: switch.turn_on
          target:
            entity_id: [ 'switch.livingroom_tree', 'switch.familyroom_tree' ]
      default:
      - service: switch.turn_off
        target:
          entity_id: 'switch.{{ trigger.id }}'