How do I skip a light in a script if it's already off?

My google-fu has failed me, so I’m hoping someone here can point me in the right direction.

I have a script for bedtime (“sunset”) that slowly dims the lights before turning them off. I also have an input_boolean that controls a “reading mode” setting for my lights (toggling between an ‘on’ and ‘off’ script to change the lights). Right now I have the sunset script set up to turn reading mode off, but if it’s not already on then that flashes one of the lights that’s only on as part of the reading mode as it resets the brightness. Is there a way to make my sunset script skip turning off reading mode if it’s not already on? So far, I have:

'1560502398295':
  alias: Sunset
  sequence:
  - data:
      entity_id: input_boolean.reading_mode
    service_template: >
      {% if is_state('input_boolean.reading_mode', 'on') %}
        input_boolean.turn_off
      {% else %}{% endif %}
  - data:
      entity_id: [continues on to dimming the lights]

Unfortunately, with this it only works when reading mode is on. Otherwise, it seems to stop when the ‘if’ condition returns false. Is there a way to tell it to continue if the state is ‘off’? I can’t find anything in the documentation to figure this out.

Do the reading mode change in your script last and use a condition to only execute it if on.

'1560502398295':
  alias: Sunset
  sequence:
    - [ your dimming services/actions here] ### move these to the 1st actions so they always run
    - condition: state #### script will stop here if reading mode is off.
      entity_id: input_boolean.reading_mode
      state: 'on'
    - service: input_boolean.turn_off
      entity_id: input_boolean.reading_mode

Unfortunately, the two involve some of the same lights (all in my bedroom), and the ‘reading mode off’ script resets its lights to my default brightness. So doing it that way would cause it to turn on some of the lights that were just turned off.

I do basically what you’ve done above in a lot of scripts, and in mine, it does not stop. Though my else statement does have an action, though its a script called do_nothing, and it… does nothing, its empty.

    - service_template: >
        {% if not (states.timer.aircon_run_timer.state == 'idle') %}
          timer.cancel
        {% else %}
          script.do_nothing
        {% endif %}
      data:
        entity_id: timer.aircon_run_timer

And while that will work it is a sign you need to rethink how you are doing things.

1 Like

What would you suggest?

I suggest you rethink how you are doing it. Or post the full config so we can point out other approaches.

I’m not saying you are necessarily wrong in this case because we haven’t seen the full config yet but there really are times when there is just no other way to do somethings. I’ve seen a few others using that approach when nothing else seemed to work. I even have a “script.nop” that I use in a place or two in my config as well.

In every case where I thought I needed this I have been able to avoid it.

1 Like

You may well be right here too. :slightly_smiling_face:

Here’s a useful script that you can re-use in a bunch of places, potentially:

script:
  turn_entity_on_off_if_not_already:
    sequence:
      - condition: template
        value_template: '{{ not is_state(entity_id, on_off) }}'
      - service_template: 'homeassistant.turn_{{ on_off }}'
        data_template:
          entity_id: '{{ entity_id }}'

Then call it from your script as such:

'1560502398295':
  alias: Sunset
  sequence:
    - service: script.turn_entity_on_off_if_not_already
      data:
        entity_id: 'input_boolean.reading_mode'
        on_off: 'off'
  - data:
      entity_id: [continues on to dimming the lights]
4 Likes

So here’s the setup.

“Reading Mode” is for when I want to read in bed. It turns off the overhead light, adjusts the Hue Lightstrip running around the edge of the ceiling, and turns on the Hue lightstrip around the bottom of my bed, so I have good ambient lighting to read by. The input boolean controls the on and off scripts.

Automation:

# Reading Mode

- id: '1560507010472'
  alias: Reading Mode On
  trigger:
  - entity_id: input_boolean.reading_mode
    from: 'off'
    platform: state
    to: 'on'
  condition: []
  action:
  - service: script.1560389076342

- id: '1560507050416'
  alias: Reading Mode Off
  trigger:
  - entity_id: input_boolean.reading_mode
    from: 'on'
    platform: state
    to: 'off'
  condition: []
  action:
  - service: script.1560389351693

Scripts:

'1560389076342':
  alias: Reading Mode On
  sequence:
  - data:
      brightness: 255
      entity_id: light.hue_lightstrip_plus_2
    service: light.turn_on
  - data:
      brightness: 170
      entity_id: light.hue_lightstrip_plus_3
    service: light.turn_on
  - data:
      entity_id: light.leviton_dzmx1_1lz_dimmer_level
    service: light.turn_off

'1560389351693':
  alias: Reading Mode Off
  sequence:
  - data:
      brightness: 255
      entity_id: light.leviton_dzmx1_1lz_dimmer_level
    service: light.turn_on
  - data:
      brightness: 127
      entity_id: light.hue_lightstrip_plus_3
      rgb_color:
      - 255
      - 208
      - 128
    service: light.turn_on
  - data:
      brightness: 255
      entity_id: light.hue_lightstrip_plus_2
      rgb_color:
      - 255
      - 208
      - 128
    service: light.turn_on
  - data:
      entity_id: light.hue_lightstrip_plus_2
    service: light.turn_off

The “Sunset” script turns off the lights in the rest of the house, turns off the overhead bedroom light, turns on the bedside fan, and starts the bedroom lights dimming through a few color changes to emulate a sunset before turning them off completely.

Sunset script (with the “if-then” test I’m trying to figure out):

'1560502398295':
  alias: Sunset
  sequence:
  - data:
      entity_id: input_boolean.reading_mode
    service_template: >
      {% if is_state('input_boolean.reading_mode', 'on') %}
        input_boolean.turn_off
      {% endif %}
  - data:
      entity_id: input_boolean.daylight_mode
    service: input_boolean.turn_off
  - data:
      entity_id:
      - light.leviton_dzmx1_1lz_dimmer_level
      - light.hue_white_lamp_2
      - light.leviton_dzpd3_1lw_plug_in_dimming_lamp_module_level
      - light.hue_color_lamp_1
      - light.hue_white_lamp_1
      - light.linear_nortek_security_control_llc_wd500z_1_wall_dimmer_switch_level
    service: light.turn_off
  - data:
      entity_id:
      - switch.jasco_products_12722_on_off_relay_switch_switch
    service: switch.turn_off
  - data:
      entity_id:
      - light.hue_lightstrip_plus_2
      rgb_color:
      - 255
      - 208
      - 128
      brightness: 255
    service: light.turn_on
  - data:
      entity_id:
      - light.hue_lightstrip_plus_3
      rgb_color:
      - 255
      - 208
      - 128
      brightness: 170
    service: light.turn_on
  - delay: 00:00:15
  - data:
      entity_id:
      - light.hue_lightstrip_plus_1
      transition: 5
    service: light.turn_off
  - delay: 00:00:25
  - data:
      entity_id:
      - light.hue_lightstrip_plus_3
      - light.hue_lightstrip_plus_2
      rgb_color:
      - 255
      - 100
      - 0
      brightness: 153
      transition: 20
    service: light.turn_on
  - data:
      entity_id: switch.leviton_dzpa1_2bw_plug_in_outlet_switch
    service: switch.turn_on
  - delay: 00:00:20
  - data:
      entity_id:
      - light.hue_lightstrip_plus_3
      - light.hue_lightstrip_plus_2
      rgb_color:
      - 255
      - 100
      - 0
      brightness: 100
      transition: 20
    service: light.turn_on
  - delay: 00:00:20
  - data:
      entity_id:
      - light.hue_lightstrip_plus_3
      - light.hue_lightstrip_plus_2
      rgb_color:
      - 76
      - 0
      - 0
      brightness: 50
      transition: 20
    service: light.turn_on
  - delay: 00:00:20
  - data:
      entity_id:
      - light.hue_lightstrip_plus_3
      - light.hue_lightstrip_plus_2
      transition: 20
    service: light.turn_off
  - data:
      entity_id: input_boolean.night_mode
    service: input_boolean.turn_on

Looking at it again, I think I don’t need the “skip if already off” option in the Sunset routine, but I do need it for the “Reading Mode Off” routine to skip turning on the overhead light if I’ve triggered the Sunset script - which right now causes the overhead light to turn on then immediately off again. But if I’m just turning off Reading Mode, I do want the overhead light to come on before changing the other lights due to visibility issues if I save that for last. So I think I still need a “do A if X is true and then continue, or skip A if X is false and continue” option.

Solved! All I needed to do is turn off the “Reading Mode Off” automation before turning off the input-boolean, then turn the automation back on at the end of the script. So the relevant part is:

'1560502398295':
  alias: Sunset
  sequence:
  - data:
      entity_id: automation.reading_mode_off
    service: homeassistant.turn_off
  - data:
      entity_id: input_boolean.reading_mode
    service: input_boolean.turn_off

[skip a bunch]

  - data:
      entity_id: automation.reading_mode_off
    service: homeassistant.turn_on

Simple!