Template switch script already running

Hi

I recently discovered template switches and am trying to simplify my messy automations to instead use these.

I am hitting a problem with one switch, which when turned on/off and then back on reports that the script associated to its turn_on is already running. I guess this is because I have put in a delay in the turn_on function, to allow the switch to turn itself off automatically after some time. The error I get in the log is

Logger: homeassistant.helpers.script.shower_cozifier
Source: helpers/script.py:1365
First occurred: 17:03:37 (1 occurrences)
Last logged: 17:03:37

Shower Cozifier: Already running

Does switch.turn_off kill the running turn_on script automatically? Or do I need to kill it by hand somehow e.g.by putting in some command to kill it in the turn_off script?? Or am I doing something quite unforgivable and this auto-off should be done differently. I used to use an external automation, but I have ended up with way too many such auxilliary scripts and am trying to clean up.

I could in principle move the delay to the end of the script script.cozify_on – I don’t always want to have it, but I could condition on something I guess. Would it be enough then to script.turn_off to interrupt the delay?

The rough switch yaml:

shower_cozifier:
      friendly_name: Shower Cozifier
      icon_template: mdi:fire
      value_template: "{{is_state('input_boolean.shower_cozify_status','on')}}"
      unique_id: "9384tu9384y537fj84yj892734yj928"
      turn_on:
        - service: input_boolean.turn_on
          target:
            entity_id: input_boolean.shower_cozify_status
        - service: script.cozify_on
          data:
            heater_h2o: climate.trv_shower
            heater_electric: switch.plug_shower_grzejnik
            scene_name: shower_saved
        - delay: 02:00:00
        - condition: state
          entity_id: binary_sensor.shower_cozify_ontime
          state: "off"
        - service: switch.turn_off
          target:
            entity_id: switch.shower_cozifier
      turn_off:
        - service: script.cozify_off
          data:
            heater_h2o: climate.trv_shower
            heater_electric: switch.plug_shower_grzejnik
            scene_name: shower_saved
        - service: input_boolean.turn_off
          target:
            entity_id: input_boolean.shower_cozify_status

The scripts the switch calls do some climate shenanigans such as increasing target temperature or turning on electric heaters, but I do not think that is the issue (and the off part seems to execute fine). It really is the fact that I cannot call the turn_on script again.

Thanks for suggestions!

When you call a script like this:

service: script.cozify_on
data:
  heater_h2o: climate.trv_shower
  heater_electric: switch.plug_shower_grzejnik
  scene_name: shower_saved

it doesn’t return until it finishes executing everything within the script.

When you call a script like this:

service: script.turn_on
target:
  entity_id: script.cozify_on
data:
  heater_h2o: climate.trv_shower
  heater_electric: switch.plug_shower_grzejnik
  scene_name: shower_saved

it returns immediately. It doesn’t wait until the script finishes executing everything within it.

What I just described is explained here: Waiting for script to complete.

Change the way you call the script and see if that helps. Be advised it may cause other issues (script.cozy_on may still be running when you call script.cozy_off).

Thanks, but this hasn’t helped.

The cozify_on script complete in around 10 seconds and I make sure to wait longer than that before turning the swithc to on again. I think it’s this delay inside the turn_on part and I would have to turn_off the switch’s internal turn_on script – but I have no idea how to address that – it’s not one of my entities.

Based on the information I provided, what did you change in the configuration of switch.shower_cozifier? Please post the revised version.

In addition, post the two scripts that are called.

Hi,

So I’ve created a minimal example that behaves in the same manner. All it does it flip an input_boolean toggle and has a delay before toggling it back.

    test_switch:
      friendly_name: "Testin testin 123"
      value_template: "{{is_state('input_boolean.test_switch','on')}}"
      unique_id: "weip0j34jp5374p5g38j4"
      turn_on:
        - service: input_boolean.turn_on
          target:
            entity_id: input_boolean.test_switch
        - delay: "01:00:00"
        - service: switch.turn_off
          target:
            entity_id: switch.test_switch
      turn_off:
        - service: input_boolean.turn_off
          target:
            entity_id: input_boolean.test_switch

This if turned on/off/on fails with the error:

Logger: homeassistant.helpers.script.testin_testin_123
Source: helpers/script.py:1365
First occurred: 10:00:27 (1 occurrences)
Last logged: 10:00:27

Testin testin 123: Already running

Should this be considered a bug or it works as designed?

I’ve solved it for myself by moving the delay into an automation, where I wait for a delayed state trigger before flipping the switch off, but it would be nice to have this auto-turn-off feature in the switch script.

As designed.

Once turned on it will be impossible to alter the state of your switch until the delay has expired.

It would be much better to do this:

    test_switch:
      friendly_name: "Testin testin 123"
      value_template: "{{is_state('input_boolean.test_switch','on')}}"
      unique_id: "weip0j34jp5374p5g38j4"
      turn_on:
        - service: input_boolean.turn_on
          target:
            entity_id: input_boolean.test_switch
      turn_off:
        - service: input_boolean.turn_off
          target:
            entity_id: input_boolean.test_switch

And this:

trigger:
  - platform: state
    entity_id: switch.test_switch
    from: 'off'
    to: 'on'
    for:
      hours: 1
action:
  - service: switch.turn_off
    target:
      entity_id: switch.test_switch

Yeah that is what i have now, but I was hoping to have fewer random crappy atomations like that.

Thanks!

Did you try changing the script’s mode from its default value of single to restart?

Single mode disallows executing a script that is already running whereas restart cancels the running script (and restarts it).

You can see the minimal example that it’s not the script that’s the issue but really the turn_on function of the switch. Now if there were a way to add an execution mode to that, then hat should help, but then you might end up with some turn_on script running with the switch seemingly already turned off, so maybe this is by design to aim predictability.

Your minimal example doesn’t transfer control of the turn_on function to a separate script whose execution mode is restart. Unless you test that arrangement, it may be premature to conclude the Template Switch’s turn_on service blocks all subsequent calls.

The minimal example doesn’t have the script and does block itself from running because of the delay command. Why would adding something on top (handing over the execution to a script) help here?

Now it may well be that transferring the delay command to the script and running in a different execution mode will allow me to run concurrent scripts, but I don’t actually want to do that since I call this script in other instances where the delay is not wanted.

Or am I not really understanding something at all here?

Possibly; you may wish to review the explanation I posted earlier.

I created this Template Switch (note the use of script.turn_on to execute the script):

switch:
  - platform: template
    switches:
      test_switch:
        value_template: "{{ is_state('input_boolean.test','on') }}"
        turn_on:
          - service: script.turn_on
            target:
              entity_id: script.test_switch
        turn_off:
          - service: input_boolean.turn_off
            target:
              entity_id: input_boolean.test

Its turn_on service employs this script (note the inclusion of mode:restart):

test_switch:
  mode: restart
  sequence:
  - service: input_boolean.turn_on
    target:
      entity_id: input_boolean.test
  - delay: '00:01:00'
  - service: switch.turn_off
    target:
      entity_id: switch.test_switch

When I turn on switch.test_switch, one minute later it turns itself off.

If I turn it on then promptly turn it off and back on, it turns on without generating a warning message in Logs.

It’s the inclusion of mode:restart that permits the script to be restarted, without complaint, when it’s called while still running. Plus the use of service: script.turn_on instead of calling the script directly.

1 Like