Calling multiple scripts from a script (conditional)

Tags: #<Tag:0x00007f326bdcae70>

Hi all,

I can’t seem to make an if-then-else structure to work when calling multiple scripts from within a script.

The following script works. It calls two other scripts to toggle the light.

switch_off_all:
  alias: switch all off
  mode: single
  sequence:
    - service: script.turn_on
      data:
        entity_id:
          - script.toggle_kitchen
    - service: script.turn_on
      data:
        entity_id:
          - script.toggle_livingroom

However, when I try to call the subscripts conditionally with a binary sensor, it doesn’t work. E.g.:

switch_off_all:
  alias: switch all off
  mode: single
  sequence:
    - service: script.turn_on
      data:
        entity_id: >
          {% if is_state('binary_sensor.light_kitchen', 'on') %}
            - script.toggle_kitchen
          {% endif %}
    - service: script.turn_on
      data:
        entity_id: >
          {% if is_state('binary_sensor.light_livingroom', 'on') %}
            - script.toggle_livingroom
          {% endif %}

I tried multiple versions of the structure. They pass the [Check Configuration] but the two subscripts simply are not called. What am I doing wrong?

Thanks big time for your help.
Kind regards.

There is probably an easier way to do this from the automation front end

switch_off_all:
  alias: switch all off
  mode: single
  sequence:
    - service: >
        {% if is_state('binary_sensor.light_kitchen', 'on') %} script.toggle_kitchen
        {% else %} script.toggle_livingroom {% endif %}
1 Like

Hi M0E-lnx,
Thanks for the suggestion, but I prefer to do it with a script for now. It makes automation on a higher level easier for me.

Hi Marc,

Regret to say this is not what I was looking for, but big thanks for your suggestion. In reality this is only a snippet of about 40 switches that I am monitoring. It’s not an If then else structure between the kitchen or the living room only. I have separate sensors that measure either the kitchen or the living room (or the bedroom, or the hallway … you name it). For each of the sensors I want to verify if I need to toggle the light switch.

Thanks again for looking into it.
Kind regards.

I suspect your logic is badly flawed here. You shouldn’t need to check if anything is on.

If you want everything to be switched off (which I’m guessing from the name of the script) then it should be as simple as…

switch_off_all:
  alias: switch all off
  mode: single
  sequence:
    - service: homeassistant.turn_off
      entity_id:
         - light.kitchen
         - light.livingroom
         - OTHER 40 THINGS

Your current method of an automation calling a script, which then calls another script is inefficient if nothing else, but it shows that the logic is flawed.

To fix thoughts, let me expand the previous example. Assume the previous example with three switches:

switch_off_all:
  alias: switch all off
  mode: single
  sequence:
    - service: script.turn_on
      data:
        entity_id: >
          {% if is_state('binary_sensor.light_kitchen', 'on') %}
            - script.toggle_kitchen
          {% endif %}
    - service: script.turn_on
      data:
        entity_id: >
          {% if is_state('binary_sensor.light_livingroom', 'on') %}
            - script.toggle_livingroom
          {% endif %}
    - service: script.turn_on
      data:
        entity_id: >
          {% if is_state('binary_sensor.light_hallway', 'on') %}
            - script.toggle_hallway
          {% endif %}

The subscripts “toggle_xxx”, e.g. “toggle_kitchen” then would look as follows.

toggle_kitchen:
  alias: Toggle Kitchen Light
  mode: single
  sequence:
  - data: {}
    entity_id: switch.relay_kitchen
    service: switch.turn_on
  - delay: '0.4'
  - data: {}
    entity_id: switch.relay_kitchen
    service: switch.turn_off

You can’t call templates like that, you have to resolve to something so in the example you gave, in the first service call, if binary_sensor.light_kitchen is on it resolves to the kitchen script, but if the sensor is off it doesn’t resolve to anything, so it is invalid.

Those subscripts shouldn’t be there. Each one of those should be a template switch

switch:
  - platform: template
    switches: 
      toggle_kitchen_light:
        value_template: "{{ is_state('binary_sensor.light_hallway') }}"
        turn_on: &toggle_kitchen
          - service: switch.turn_on
            entity_id: switch.relay_kitchen
          - delay: '0.4'
          - service: switch.turn_on
            entity_id: switch.relay_kitchen
        turn_off: *toggle_kitchen
1 Like

Hi Marc,

I understand where you are coming from, and I appreciate your help. I’m afraid more information is necessary.

Please be informed that my sensors work completely independent from my toggle logic. They are not the same, so you cannot simply ‘turn_off’ the service. Once you call the toggle service, it effectively toggles the switch, independent of its current state.

My home is both manually and automatically controlled. So I have independent sensors verifying the current state of an output. Also the toggle switches work independently. Let me know if you want to see the details :slight_smile:

So, dependent on the sensor state I want to take the decision to either toggle the switch or not.

Kind regards.

See my edit. They shouldn’t be subscripts, they should be template switches.

That’s where your logic is flawed because you’re not using the correct components for your use case.

Thanks Marc,
Let me study on that topic, this is new stuff for me (yes, I’m a newbe on Home Assistant). Promise I’ll be back when it works out (or not). :slight_smile:
Much appreciate your help.
Kind regards.

1 Like

No worries.

Basically replace all those subscripts with template switches, this will give you an actual logical switch in homeassistant that accurately reflects whether or not the physical switch is on or off.

After that your logic around turning the switches on or off is massively simplified, and your automations and scripts will make much more sense :slightly_smiling_face:

Hi Marc,

Wanted to thank you again for putting me on the right track! I needed to go through a crash course advanced yaml to understand what you were doing with the & and * signs, but it is all clear now :smiley:. For info, I used the “light” template instead of the switch because it also has the light bulb indicator.

Now, there may be more people running into the same issue, so let me provide more details on the configuration and the solution. Hope this will help other people too.

Configuration

  • This is about an existing house where lights are steered with impulse switches (aka teleruptors). This means that the lights can also be switched on/off manually. The Home Assistant domotics layer is installed on a Raspberry Pi and is used as a secondary control.
  • To monitor the state of a light I have installed relays over the teleruptor outputs. Each relay switches a 5V output, which is captured with an mcp23017 I/O expander. Feel free to use an optocoupler instead of a relay if you prefer, but in my (240V) case using relays was the better option.
  • To control the teleruptor with Home Assistant, I have a second mcp23017 board with a series of smaller relays that can toggle the teleruptors.

Controlling the mcp23017 with Home Assistant

I will use two lights in this example, one for the living room and one for the kitchen. The mcp23017 ICs are read/written every 0.2 seconds which gives a nice response time, while I can still control up to eight I/O expanders with the Raspberry Pi. In this example one mcp23017 board is configured as a binary sensor, and the other as an external switch.

Add the following lines to configuration.yaml.

binary_sensor:
  - platform: mcp23017
    i2c_address: 0x20
    scan_interval: 0.2
    pins:
      0: sensor_light_livingroom
      1: sensor_light_kitchen

switch:
  - platform: mcp23017
    i2c_address: 0x21
    scan_interval: 0.2
    pins:
      0: relay_light_livingroom
      1: relay_light_kitchen

Note that in the above example one board has ID 0 on the I2C connection, and the other has ID 1. For controlling the teleruptors, I will switch the relays for 0.4 seconds as follows. The below YAML lines will provide you with two lights that will do the trick. Add the following lines to configuration.yaml.

light:
  - platform: template
    lights:
      light_living:
        friendly_name: "Livingroom Light"
        value_template: "{{ is_state('binary_sensor.sensor_light_living', 'on') }}"
        turn_on:
          - condition: state
            entity_id: binary_sensor.sensor_light_living
            state: 'off'
          - service: switch.turn_on
            entity_id: switch.relay_light_livingroom
          - delay: '0.4'
          - service: switch.turn_off
            entity_id: switch.relay_light_livingroom
        turn_off:
          - condition: state
            entity_id: binary_sensor.sensor_light_living
            state: 'on'
          - service: switch.turn_on
            entity_id: switch.relay_light_livingroom
          - delay: '0.4'
          - service: switch.turn_off
            entity_id: switch.relay_light_livingroom


      light_kitchen:
        friendly_name: "Kitchen Light"
        value_template: "{{ is_state('binary_sensor.sensor_light_kitchen', 'on') }}"
        turn_on:
          - condition: state
            entity_id: binary_sensor.sensor_light_kitchen
            state: 'off'
          - service: switch.turn_on
            entity_id: switch.relay_light_kitchen
          - delay: '0.4'
          - service: switch.turn_off
            entity_id: switch.relay_light_kitchen
        turn_off:
          - condition: state
            entity_id: binary_sensor.sensor_light_kitchen
            state: 'on'
          - service: switch.turn_on
            entity_id: switch.relay_light_kitchen
          - delay: '0.4'
          - service: switch.turn_off
            entity_id: switch.relay_light_kitchen

Switching off all lights is then done through a script. Add e.g. the following lines to the scripts.yaml file as.

switch_off_all:
  alias: Switch all lights off
  mode: single
  sequence:
  - service: light.turn_off
    entity_id: light.light_living
  - service: light.turn_off
    entity_id: light.light_kitchen

It is also possible to add the lights and script to the Overview as

  - entity: light.light_living
  - entity: light.light_kitchen
  - entity: script.switch_off_all

… and this solves the original question.

Acknowledgement

Kudos go to Marc “mf_social” for helping me with the yaml part.

Additional information

Please mind I2C is not enabled by default in Home Assistant. As a new user I cannot add the link, but you will find more information in the Home Assistant site. I had to redo the configuration twice before it actually worked, but this could be me :slight_smile: . Just don’t give up.

I wish you much success in your Home Assistant implementation!

1 Like