Service_template automation problems

This is an automation, that turns on and off two of my humidifiers, triggered by windows sensors and humidity level. It worked in a past, but all my automations are gone because of a bug in HA. Now i dont remember all of my automation, and stucked a bit in a syntax.

  alias: Humidifier toggle
  trigger:
  - entity_id: binary_sensor.door_window_sensor_bedroom
    platform: state
  - entity_id: sensor.humidity_bedroom
    platform: state
  - entity_id: binary_sensor.door_window_sensor_living_room
    platform: state
  - entity_id: sensor.humidity_living_room
    platform: state
  action:
  - data_template:
      entity_id: >-
        {%- set brws = "binary_sensor.door_window_sensor_bedroom" -%}
        {%- set brhs = "sensor.humidity_bedroom" -%}
        {%- set lrws = "binary_sensor.door_window_sensor_living_room" -%}
        {%- set lrhs = "sensor.humidity_living_room" -%}
        {%- if trigger.entity_id == brws or brhs -%}fan.humidifier_bedroom
        {%- elif trigger.entity_id == lrws or lrhs -%}fan.humidifier_living_room
        {% else %}
        {% endif %}
    service_template: >- 
      {%- set brhfon = is_state("fan.humidifier_bedroom", "on") -%}
      {%- set brhfoff = is_state("fan.humidifier_bedroom", "off") -%}
      {%- set brwson = is_state("binary_sensor.door_window_sensor_bedroom", "on") -%}
      {%- set brwsoff = is_state("binary_sensor.door_window_sensor_bedroom", "off") -%}
      {%- set brhson = states.sensor.humidity_bedroom.state|int < 45 -%}
      {%- set brhsoff = states.sensor.humidity_bedroom.state|int > 60 -%}
      {%- set lrhfon = is_state("fan.humidifier_living_room", "on") -%}
      {%- set lrhfoff = is_state("fan.humidifier_living_room", "off") -%}
      {%- set lrwson = is_state("binary_sensor.door_window_sensor_bedroom", "on") -%}
      {%- set lrwsoff = is_state("binary_sensor.door_window_sensor_bedroom", "off") -%}
      {%- set lrhson = states.sensor.humidity_bedroom.state|int < 45 -%}
      {%- set lrhsoff = states.sensor.humidity_bedroom.state|int > 60 -%}
      {%- if brwson and brhfon or brhsoff and brhfon-%}fan.turn_off 
      {%- elif brwsoff and brhfoff or brhson and brhfoff -%}fan.turn_on
      {%- elif lrwson and lrhfon or lrhsoff and lrhfon-%}fan.turn_off 
      {%- elif lrwsoff and lrhfoff or lrhson and lrhfoff -%}fan.turn_on 
      {% else %}
      {% endif %}

The error is:

2019-05-09 01:28:55 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event automation_triggered[L]: entity_id=automation.humidifier_toggle, name=Humidifier toggle>
2019-05-09 01:28:55 INFO (MainThread) [homeassistant.components.automation] Executing Humidifier toggle
2019-05-09 01:28:55 INFO (MainThread) [homeassistant.helpers.script] Script Humidifier toggle: Running script
2019-05-09 01:28:55 INFO (MainThread) [homeassistant.helpers.script] Script Humidifier toggle: Executing step call service
2019-05-09 01:28:55 ERROR (MainThread) [homeassistant.components.automation] Error while executing automation automation.humidifier_toggle. Invalid data for call_service at pos 1: Service does not match format .

You have an empty else on the service template and data template, otherwise it looks fine.

Either define a default with the else, or remove it.

Well, without {% else %} it,s the same error:

2019-05-09 02:00:22 ERROR (MainThread) [homeassistant.components.automation] Error while executing automation automation.humidifier_toggle. Invalid data for call_service at pos 1: Service does not match format <domain>.<name>

The else needs to be set, otherwise it will throw an error. Try this:


  action:
  - data_template:
      entity_id: >-
        {%- set brws = "binary_sensor.door_window_sensor_bedroom" -%}
        {%- set brhs = "sensor.humidity_bedroom" -%}
        {%- set lrws = "binary_sensor.door_window_sensor_living_room" -%}
        {%- set lrhs = "sensor.humidity_living_room" -%}
        {%- if trigger.entity_id == brws or brhs -%}fan.humidifier_bedroom
        {% else %}fan.humidifier_living_room
        {% endif %}
    service_template: >- 
      {%- set brhfoff = is_state("fan.humidifier_bedroom", "off") -%}
      {%- set brwsoff = is_state("binary_sensor.door_window_sensor_bedroom", "off") -%}
      {%- set brhson = states('sensor.humidity_bedroom')|int < 45 -%}
      {%- set lrhfoff = is_state("fan.humidifier_living_room", "off") -%}
      {%- set lrwsoff = is_state("binary_sensor.door_window_sensor_living_room", "off") -%}
      {%- set lrhson = states('sensor.humidity_living_room')|int < 45 -%}
      {%- if brwsoff and brhfoff or brhson and brhfoff -%}fan.turn_on
      {%- elif lrwsoff and lrhfoff or lrhson and lrhfoff -%}fan.turn_on 
      {% else %}fan.turn_off
      {% endif %}

Second data template elif was redundant, replaced with else.

Removed turn_off elif arguments, and simplified to else turn_off.

EDIT: switched states.state to states() for comparators

@walrus_parka

In your revised service template, the bedroom and living room variables are identical.

… because they’re also identical in the original service template. Which must be an error.

I think this is one automation that would be dramatically simplified by separating it into two separate automations (one to handle the bedroom fan, the other for the living room).


It took me awhile to the untangle the logic but here’s what it boils down to for the bedroom:

- alias: Bedroom Humidifier toggle
  trigger:
  - platform: state
    entity_id:
      - binary_sensor.door_window_sensor_bedroom
      - sensor.humidity_bedroom
  action:
  - service_template: >- 
      {% set fan = states('fan.humidifier_bedroom') %}
      {% set sensor = states('binary_sensor.door_window_sensor_bedroom') %}
      {% set humidity = states('sensor.humidity_bedroom')|int %}
      {% if fan == 'on' and (sensor == 'on' or humidity > 60) %}
        fan.turn_off 
      {% elif fan == 'off' and (sensor == 'off' or humidity < 45 %}
        fan.turn_on
      {% else %}
        fan.turn_off 
      {% endif %}
    data:
      entity_id: fan.humidifier_bedroom

@renga

Take a look at a solution I provided for another user. It also involves controlling room humidity within a desired range. It might be of interest to you.

1 Like

I probably flew too close to the sun. Could have been simplified, but didn’t think if I should…

Thank you, service template works brilliant, but data template sends fan.humidifier_bedroom, despite of trigger.

2019-05-09 17:55:37 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: old_state=<state binary_sensor.door_window_sensor_living_room=on; device_class=opening, Open since=0, friendly_name=Окно гостиная, battery_level=45.0 @ 2019-05-09T17:54:37.886649+03:00>, new_state=<state binary_sensor.door_window_sensor_living_room=on; device_class=opening, Open since=60, friendly_name=Окно гостиная, battery_level=45.0 @ 2019-05-09T17:54:37.886649+03:00>, entity_id=binary_sensor.door_window_sensor_living_room>
2019-05-09 17:55:37 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event automation_triggered[L]: name=Humidifier toggle, entity_id=automation.humidifier_toggle>
2019-05-09 17:55:37 INFO (MainThread) [homeassistant.components.automation] Executing Humidifier toggle
2019-05-09 17:55:37 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: service=turn_on, domain=fan, service_data=entity_id=fan.humidifier_bedroom>

@renga

The automation is needlessly complicated by the fact it attempts to control two different humidifier fans (bedroom and living room) within a single automation. The two fans have nothing in common so there is no synergy, nor reduction in automation code, by combining them into one automation.

For example, effectively this is the trigger section. It monitors the states of four sensors, two per room.

- alias: Humidifier toggle
  trigger:
  - platform: state
    entity_id:
      - binary_sensor.door_window_sensor_bedroom
      - sensor.humidity_bedroom
      - binary_sensor.door_window_sensor_living_room
      - sensor.humidity_living_room

Then it uses a data_template to determine what triggered it. The irony is that it bases its decision on the room. It wouldn’t have to do this if each room was handled by its own automation. Additional irony is that the two rooms have no interaction so there’s no pressing need to combine them into one automation.

  action:
  - data_template:
      entity_id: >-
        # <snip> 4 lines of setting room variables </snip>
        {%- if trigger.entity_id == brws or brhs -%}
          fan.humidifier_bedroom
        {%- elif trigger.entity_id == lrws or lrhs -%}
          fan.humidifier_living_room
        {% else %}
         # < missing statement />
        {% endif %}

The service_template repeats what the data_template just did and determines which room’s sensors were responsible for activating the automation.

    service_template: >- 
      # <snip> 12 lines of setting room variables </snip>
      {%- if brwson and brhfon or brhsoff and brhfon-%}
        fan.turn_off 
      {%- elif brwsoff and brhfoff or brhson and brhfoff -%}
        fan.turn_on
      {%- elif lrwson and lrhfon or lrhsoff and lrhfon-%}
        fan.turn_off 
      {%- elif lrwsoff and lrhfoff or lrhson and lrhfoff -%}
        fan.turn_on 
      {% else %}
       # < missing statement />
      {% endif %}

I urge you to reconsider the solution’s approach and to split it into two separate automations, one per room. I provided an example for handling the bedroom in a previous post. You only need to make a copy of it for the living room and adjust the entity names accordingly.