Automation Action -> Service with If Condition to Switch Combinations of Switches

I’ve been trying to work out an automation that will, dependent upon the amount of spare solar I have, switch multiple devices on or off so that I can consume as much spare solar as possible and limit export.

I have this so far which looks to run but not switch anything. I have no entity reference in the service section which i guess maybe the issue…? Not sure how to resolve it though. Any help appreciated.

id: "1642074956921"
  alias: USE SPARE SOLAR
  description: ""
  trigger:
    - platform: numeric_state
      entity_id: sensor.gridconsumption
      above: "800"
      below: "1000"
    - platform: numeric_state
      entity_id: sensor.gridconsumption
      above: "1000"
      below: "1800"
    - platform: numeric_state
      entity_id: sensor.gridconsumption
      above: "1800"
    - platform: numeric_state
      entity_id: sensor.gridconsumption
      below: "0"
  condition: []
  action:
    service: >
      {% if states('sensor.gridconsumption') > 800 and states('sensor.gridconsumption') < 1000 | float %}
        switch.kitchen_door_sockets_s1.turn_on
        switch.x_office_door_sockets_s2.turn_off
      {% elif states('sensor.gridconsumption') > 1000 and states('sensor.gridconsumption') < 1800 | float %}
        switch.kitchen_door_sockets_s1.turn_off
        switch.x_office_door_sockets_s2.turn_on
      {% elif states('sensor.gridconsumption') > 1800 | float %}
        switch.kitchen_door_sockets_s1.turn_on
        switch.x_office_door_sockets_s2.turn_on
      {% else %} 
        switch.kitchen_door_sockets_s1.turn_off
        switch.x_office_door_sockets_s2.turn_off
      {% endif %}
  mode: single

Those actions don’t look right.

If you find it challenging to understand the service documentation, one trick I use to figure out the needed yaml is to create a simple automation in the GUI editor and then review automations.yaml.

You can then copy/paste the service call syntax.

Your float conversions are wrong. Should be done thus (first line only, similarly for others):

      {% if states('sensor.gridconsumption')|float(0) > 800 and states('sensor.gridconsumption')|float(0) < 1000 %}

The states() is a string and needs converting to int or float before comparison. Your original compares a string to 800 then a string to a float-converted 1000. These days, you should include a default value in the float filter, which is what the (0) is.

you can’t create multiple service calls like that within a template branch.

And there is no such service as “switch.kitchen_door_sockets_s1.turn_on”.

the service is “switch.turn_on” and then you reference the entity_id.

What I would do is use choose actions and set the conditions for each sequence as the branches in your template and the set the sequence to be syntactically correct service calls.

action:
  - choose:
      - conditions:
          - "{{states('sensor.gridconsumption')|float(0) > 800 and states('sensor.gridconsumption')|float(0) < 1000 }}"
        sequence:
          - service: switch.turn_on
            entity_id: switch.kitchen_door_sockets_s1
          - service: switch.turn_off
            entity_id: switch.x_office_door_sockets_s2
      - conditions:
          -  "{{ states('sensor.gridconsumption')|float(0) > 1000 and states('sensor.gridconsumption')|float(0) < 1800 }}"
        sequence:
          - service: switch.turn_off
            entity_id: switch.kitchen_door_sockets_s1
          - service: switch.turn_on
            entity_id: switch.x_office_door_sockets_s2
      - conditions:
          - "{{ states('sensor.gridconsumption')|float(0) > 1800 }}"
        sequence:
          - service: switch.turn_on
            entity_id: 
              - switch.kitchen_door_sockets_s1
              - switch.x_office_door_sockets_s2
    default
      - service: switch.turn_off
        entity_id: 
          - switch.kitchen_door_sockets_s1
          - switch.x_office_door_sockets_s2

I think I have the indentation correct. But couldn’t test it.

2 Likes

You can use the trigger’s id to indicate which switches should be on or off. This helps to simplify the action.

  id: 1642074956921
  alias: USE SPARE SOLAR
  description: 
  trigger:
    - id: 'switch.kitchen_door_sockets_s1 switch.x_office_door_sockets_s2'
      platform: numeric_state
      entity_id: sensor.gridconsumption
      above: 800
      below: 1000
    - id: 'switch.kitchen_door_sockets_s2 switch.x_office_door_sockets_s1'
      platform: numeric_state
      entity_id: sensor.gridconsumption
      above: 1000
      below: 1800
    - id: 'switch.kitchen_door_sockets_s1,switch.x_office_door_sockets_s2 none'
      platform: numeric_state
      entity_id: sensor.gridconsumption
      above: 1800
    - id: 'none switch.kitchen_door_sockets_s1,switch.x_office_door_sockets_s2'
      platform: numeric_state
      entity_id: sensor.gridconsumption
      below: 0
  condition: []
  action:
    - service: switch.turn_on
      target:
        entity_id: '{{ trigger.id.split()[0] }}'
    - service: switch.turn_off
      target:
        entity_id: '{{ trigger.id.split()[1] }}'

FWIW, I confirmed this technique works (tested with an input_number in place of the sensor and input_booleans instead of switches).

The value of id is handled like this:

  • Anything to the left of the space represents switches to be turned on.
  • Anything to the right of the space represents switches to be turned off.
  • none indicates there are no switches to be turned on or off.
  • Multiple switches, to be turned on or off, are separated by a comma.
id: 'switch.kitchen_door_sockets_s1 switch.x_office_door_sockets_s2'
     ------------------------------^-------------------------------
                   ON              |              OFF
                                 space
id: 'switch.kitchen_door_sockets_s1,switch.x_office_door_sockets_s2 none'
     ------------------------------^-------------------------------^----
                   ON              |              ON               | OFF
                                 comma                           space
1 Like

@finity & @123 Thank you both for these great solutions.

Got the @finity solution working. I’ll test the @123 later today :+1:

I assume you may already know this but, in case you don’t, I noticed the following behavior when testing the automation:

  1. Assume that initially the value of sensor.gridconsumption is below 800 and both switches are off.

  2. The moment the sensor’s value rises above and crosses the 800 watt threshold, the first switch is turned on.

  3. Now let’s say the value decreases below 800 watts. The first switch is left on and not turned off. It won’t be turned off until the sensor’s value decreases below 0.

Is that the way you want it to work?

1 Like

It’s a good point @123. And no its not. I have been thinking the same.

What I’ll need to do is store a property, somehow, against both switches (sockets) as the value of their consumption when on: i.e.

  • switch.kitchen_door_sockets_s2: 800 (Watts)
  • switch.x_office_door_sockets_s1: 1000 (Watts)

That or I put power monitors on each device… :grinning:
This way I I can check the grid consumption and then check, if the switches are on, that the live grid consumption includes 800, 1000 or 1800 Watts.

Using your example:

  1. Assume that initially the value of sensor.gridconsumption is below 800 and both switches are off.
  • ‘sensor.gridconsumption’ = 750W.
  • ‘sensor.spare_solar_devices_consumption’ = 0W.
  • ‘sensor.corrected_consumption’ = 750W.
  1. The moment the sensor’s value rises above and crosses the 800 watt threshold, the first switch is turned on @800W consumtpion
  • ‘sensor.gridconsumption’ = 50W.
  • ‘sensor.spare_solar_devices_consumption’ = 800W.
  • ‘sensor.corrected_consumption’ = ‘sensor.gridconsumption’ + ‘sensor.spare_solar_devices_consumption’ = 850W.
  1. Now let’s say the value decreases below 800 watts. The first switch is left on and not turned off. It won’t be turned off until the sensor’s value decreases below 0
  • ‘sensor.corrected_consumption’ = 750W
  • ‘sensor.gridconsumption’ = ‘sensor.corrected_consumption’ - ‘sensor.spare_solar_devices_consumption’ = 750 - 800 = - 50W. The negative suggest you are now importing power form the grid!
  • if ‘sensor.corrected_consumption’ < ‘sensor.spare_solar_devices_consumption’ then turn OFF solar devices.

Does that make sense? It would take a couple more sensors being created but i think it could work…?!

Cheers,

I can’t answer your question because I don’t understand the underlying purpose of turning the switches on/off. It seems like a way of reducing overall power consumption based on thresholds of total power consumption. However, I’m not sure if that’s the actual goal.