Sequenced good night button

I’ve been working on my “Good Night” button and here’s what I’ve come up with. I’m using the custom:button-card for the visual aspect. Here’s my coding for that:

                            - template: standard-button
                              type: 'custom:button-card'
                              aspect_ratio: 1/1.1
                              double_tap_action:
                                action: call-service
                                service: script.good_night_quick
                              tap_action:
                                action: call-service
                                service: script.good_night
                              name: |
                                [[[
                                  if (states["timer.gn_01"].state == "active") return "lights off";
                                  if (states["timer.gn_01"].state == "paused") return "lights...";
                                  if (states["timer.gn_02"].state == "active") return "in bed on";
                                  if (states["timer.gn_02"].state == "paused") return "in bed...";
                                  return "Good Night";
                                ]]]
                              icon: |
                                [[[
                                  if (states["timer.gn_01"].state == "active") return "mdi:lightbulb-group";
                                  if (states["timer.gn_01"].state == "paused") return "mdi:question";
                                  if (states["timer.gn_02"].state == "active") return "mdi:bed";
                                  if (states["timer.gn_02"].state == "paused") return "mdi:question";
                                  return "mdi:power";
                                ]]]

You’ll notice that both the label and the icon are based on the state of two timers, timer.gn_01 and timer.gn_02. The button simply calls a “fast” script (without the timers) on double_tap and a timed script on single tap. Since the visuals of the button are based on the timers, while they’re running, the button shows what’s going on.
Here are the scripts:

good_night:
  alias: "timed shut down of main floor"
  sequence:
    - service: timer.start
      target:
        entity_id: timer.gn_01
      data:
        duration: '30'
good_night_quick:
  alias: "quick shut down of main floor"
  sequence:
    - service: homeassistant.turn_off
      target:
        entity_id:
          - group.downstairs_lights
          - fan.lr_sonoff
    - service: homeassistant.turn_on
      target:
        entity_id:
          - input_boolean.in_bed

Clearly there’s something else going on with that “good_night” script because all it does is start the timer. The following automations do the rest of the operations:

- alias: 'good night timer 01 finishes'
  trigger:
    platform: event
    event_type: timer.finished
    event_data:
      entity_id: timer.gn_01
  action:
    - service: homeassistant.turn_off
      target:
        entity_id:
          - group.downstairs_lights
          - fan.lr_sonoff
    - service: timer.start
      target:
        entity_id:
          - timer.gn_02
- alias: 'good night timer 02 finishes'
  trigger:
    platform: event
    event_type: timer.finished
    event_data:
      entity_id: timer.gn_02
  action:
    - service: homeassistant.turn_on
      target:
        entity_id:
          - input_boolean.in_bed

This all works. The only thing I don’t like about it is that I’m editing up to three separate files (and possibly changing the timer definitions) in order to change the functionality. Can any of you folks more versed in HA figure a way to eliminate the scripts? I haven’t figured out any way to put a sequence into a tap_action if there is one. I also haven’t figured out how I can specify a duration in the start.timer service call in the automation. (I tried using the same syntax as the script and it threw me an error message.)
Alternatively, I do know how to do the whole thing in a script, but I’m not sure how to change the button label and icon according to where execution is in the script.

You can have it all in one file. As long ss you address all the right domains and respect the yaml file structure.

Thanks. I assume that when you put multiple versions of headers, those get merged with the headers that are elsewhere.
As it is, I came up with another solution:
First, I define an input_select as a dropdown with three options:

  • idle
  • lights
  • bed
    My button is defined thusly:
                            - template: standard-button
                              type: 'custom:button-card'
                              aspect_ratio: 1/1.1
                              double_tap_action:
                                action: call-service
                                service: script.good_night_02
                                service_data:
                                  lights_wait: '0'
                                  in_bed_wait: '0'
                              tap_action:
                                action: call-service
                                service: script.good_night_02
                                service_data:
                                  lights_wait: '10'
                                  in_bed_wait: '15'
                              name: |
                                [[[
                                  if (states["input_select.good_night_phase"].state == "lights") return "lights...";
                                  if (states["input_select.good_night_phase"].state == "bed") return "in bed...";
                                  return "Good Night";
                                ]]]
                              icon: |
                                [[[
                                  if (states["input_select.good_night_phase"].state == "lights") return "mdi:lightbulb-group";
                                  if (states["input_select.good_night_phase"].state == "bed") return "mdi:bed";
                                  return "mdi:power";
                                ]]]

And the script is as follows:

good_night_02:
  alias: "timed lights off & in_bed indicator"
  description: "wait, turn lights off, wait, turn on in_bed_indicator"
  fields:
    lights_wait:
      description: "time in seconds to delay lights off"
      example: "30"
    in_bed_wait:
      description: "time in seconds to delay in_bed indicator"
      example: "30"
  mode: queued
  sequence:
    - service: input_select.select_option
      target:
        entity_id: input_select.good_night_phase
      data:
        option: lights
    - delay:
        seconds: "{{ lights_wait }}"
    - service: homeassistant.turn_off
      target:
        entity_id:
          - group.downstairs_lights
          - fan.lr_sonoff
    - service: input_select.select_option
      target:
        entity_id: input_select.good_night_phase
      data:
        option: bed
    - delay:
        seconds: "{{ in_bed_wait }}"
    - service: homeassistant.turn_on
      target:
        entity_id:
          - input_boolean.in_bed
    - service: input_select.select_option
      target:
        entity_id: input_select.good_night_phase
      data:
        option: idle

As you can see, using variables in the script allows me to use one script for fast shut down and timed shut down. Most of my tweaking will be in the ui-lovelace.yaml file with an occasional change in the script if I want to add something to the goodnight routines.
All-in-all, I think this is much more elegant and more easily extensible.