Understanding the service_template action

I’ve looked at the documentation and seen other posts and still cant figure out why I get errors with these actions:

  action:
    - service: input_boolean.turn_off
      entity_id: input_boolean.vacation_mode
    - service_template: >
       {% if is_state('sun.sun', 'below_horizon') %}
         light.turn_on
         entity_id: group.interior_lights
       {% endif %}
    - service_template: >
       {% if is_state('sensor.whoishome', 'X') %}
         input_boolean.turn_on
         entity_id: input_boolean.X_home
       {% elif is_state('sensor.whoishome', 'Both') %}
         input_boolean.turn_on
         entity_id: input_boolean.X_home
       {% endif %}
    - service_template: >
       {% if is_state('sensor.whoishome', 'X') %}
         notify.mypushover
         data:
          message: Home! Turn on lights.
       {% elif is_state('sensor.whoishome', 'Both') %}
        notify.mypushover
        data:
         message: Home! Turn on lights.
       {% endif %}
    - delay: 00:03:00
    - service_template: >
       {% if is_state('sensor.whoishome', 'X') %}
         tts.amazon_polly_say
         data:
          entity_id: media_player.audiogroup
          message: Welcome home, X!
       {% elif is_state('sensor.whoishome', 'Y') %}
         tts.amazon_polly_say
         data:
          entity_id: media_player.audiogroup
          message: Welcome home, Y!
       {% elif is_state('sensor.whoishome', 'Both') %}
        tts.amazon_polly_say
        data:
          entity_id: media_player.audiogroup
          message: Welcome home, X and Y!
       {% endif %}

I get the error:

Error while executing automation automation.welcome_home. Invalid data for call_service at pos 2: Service does not match format .

The service template should only output a service call, e.g. tts.amazon_polly_say. Nothing more. You should move the data: part down, and use a data_template for that.

Also, a service template needs a valid output in all situations. So when you define an if, you should cover all possible states. Not just ‘if below horizon’, but also ‘if above horizon’.

1 Like

For example:

  action:
    - service: input_boolean.turn_off
      entity_id: input_boolean.vacation_mode
    - service_template: >
       {% if is_state('sun.sun', 'below_horizon') %}
         light.turn_on
       {% else %}
         ### you need a valid service for the light group entity here ###
       {% endif %}
      entity_id: group.interior_lights

Ok, so for the lights and input boolean I can understand but the services with messages, how would that work?

- service: input_boolean.turn_off
  entity_id: input_boolean.vacation_mode
- service_template: >
   {% if is_state('sun.sun', 'below_horizon') %}
     homeassistant.turn_on
   {% else %}
     homeassistant.turn_off
   {% endif %}
     entity_id: group.interior_lights
- service_template: >
   {% if is_state('sensor.whoishome', 'X') %}
     input_boolean.turn_on
   {% elif is_state('sensor.whoishome', 'Both') %}
     input_boolean.turn_on
   {% else %}
     homeassistant.turn_off
   {% endif %}
     entity_id: input_boolean.X_home
- service_template: >
   {% if is_state('sensor.whoishome', 'X') %}
     notify.mypushover
   {% elif is_state('sensor.whoishome', 'Both') %}
    notify.mypushover
   {% endif %}
     data_template:
      message: Home! Turn on lights.
- delay: 00:03:00
- service_template: >
   {% if is_state('sensor.whoishome', 'X') %}
     tts.amazon_polly_say
     data_template:
      entity_id: media_player.audiogroup
      message: Welcome home, X!
   {% elif is_state('sensor.whoishome', 'Y') %}
     tts.amazon_polly_say
     data_template:
      entity_id: media_player.audiogroup
      message: Welcome home, Y!
   {% elif is_state('sensor.whoishome', 'Both') %}
    tts.amazon_polly_say
    data_template:
      entity_id: media_player.audiogroup
      message: Welcome home, X and Y!
   {% endif %}

How can I put a catch all “else” for a tts and notify services? Guess I could put a generic system_log.write ? But then still leaves the issue of the different message options.

Don’t use a service template.

Call the service you want (e.g. tts) and add a data_template for the message. e.g.

- service: tts.amazon_polly_say
  data_template:
    entity_id: media_player.audiogroup
    message: >
     {% if is_state('sensor.whoishome', 'X') %}
       Welcome home, X!
     {% elif is_state('sensor.whoishome', 'Y') %}
       Welcome home, Y!
     {% elif is_state('sensor.whoishome', 'Both') %}
       Welcome home, X and Y!
     {% endif %}

This assumes someone will be home when your automation triggers. If not you will need an {% else %} case as well (e.g. “hello, talking to myself”) :smiley:

Also, you need to watch out for your indentations.

You have this:


- service_template: >
   {% if is_state('sun.sun', 'below_horizon') %}
     homeassistant.turn_on
   {% else %}
     homeassistant.turn_off
   {% endif %}
     entity_id: group.interior_lights

Which will probably give you errors.

You need this:


- service_template: >
    {% if is_state('sun.sun', 'below_horizon') %}
      homeassistant.turn_on
    {% else %}
      homeassistant.turn_off
    {% endif %}
  entity_id: group.interior_lights

Excellent. I seem to have gotten the idea. Got it sorted.
Thanks for the assist @finity, @tom_l, @Emphyrio!

I seemed to have botched something. It keeps generating service errors. If anyone would be able to help, that would be greatly appreciated.

  action:
    - service_template: >
        {% if is_state('sun.sun', 'below_horizon') %}
          homeassistant.turn_on
        {% else %}
          homeassistant.turn_off
        {% endif %}
      entity_id: group.interior_lights
    - service: input_boolean.turn_off
      entity_id: input_boolean.vacation_mode
    - service_template: >
        {% if is_state('sensor.whoishome', 'P') %}
          input_boolean.turn_on
        {% elif is_state('sensor.whoishome', 'Both') %}
          input_boolean.turn_on
        {% endif %}
      entity_id: input_boolean.P_home
    - service_template: >
        {% if is_state('sensor.whoishome', 'P') %}
          input_boolean.turn_on
        {% elif is_state('sensor.whoishome', 'Both') %}
          input_boolean.turn_on
        {% endif %}
      data:
       entity_id: notify.mypushover
       message: Welcome home, P!
    - delay: 00:03:00
    - service_template: >
       {% if is_state('sensor.whoishome', 'P') %}
       tts.google_cloud_say
       {% endif %}
      data:
       entity_id: media_player.audiogroup
       message: Welcome home, P!
    - service_template: >
       {% if is_state('sensor.whoishome', 'J') %}
       tts.google_cloud_say
       {% endif %}
      data:
       entity_id: media_player.audiogroup
       message: Welcome home, J!
    - service_template: >
       {% if is_state('sensor.whoishome', 'Both') %}
       tts.google_cloud_say
       {% endif %}
      data:
       entity_id: media_player.audiogroup
       message: Welcome home, P and J!

When you create a template for the service_template option, that template must ALWAYS produce a result. In other words, if you do this:

    - service_template: >
       {% if is_state('sensor.whoishome', 'Both') %}
       tts.google_cloud_say
       {% endif %}

What does the template produce when the sensor’s state is not Both? The answer is it produces nothing. It sets sensor_template to blank and that’s invalid. The template must report a valid service.

One more thing, this is incorrect. This is a mismatch of service and entity_id:

    - service_template: >
        {% if is_state('sensor.whoishome', 'P') %}
          input_boolean.turn_on
        {% elif is_state('sensor.whoishome', 'Both') %}
          input_boolean.turn_on
        {% endif %}
      data:
       entity_id: notify.mypushover
       message: Welcome home, P!

So what would I be able to do for a none responding service for this

    - service_template: >
       {% if is_state('sensor.whoishome', 'Both') %}
       tts.google_cloud_say
       {% endif %}

maybe something generic like:

    - service_template: >
       {% if is_state('sensor.whoishome', 'Both') %}
       tts.google_cloud_say
        {% else %}
        homeassistant.update_entity
        {% endif %}
       {% endif %}

Whats the proper way?

    - service_template: >
        {% if is_state('sensor.whoishome', 'P') %}
          input_boolean.turn_on
        {% elif is_state('sensor.whoishome', 'Both') %}
          input_boolean.turn_on
        {% endif %}
      entity_id:notify.mypushover
       data: 
       message: Welcome home, P!

?

The answer depends on what you’re trying to do. I can’t tell because it’s currently an invalid mix of two things. Is it supposed to control an input_boolean or send a notification?

Sorry, I had a brain fart.

    - service_template: >
        {% if is_state('sensor.whoishome', 'P') %}
          notify.mypushover
        {% elif is_state('sensor.whoishome', 'Both') %}
          notify.mypushover
        {% endif %}
       data: 
        message: Welcome home, P!

I dont know why i put the input boolean. I am trying to send a notification if either of those two states are true.

Actually, you need to step back and reconsider how you’ve designed the entire action. It currently uses separate services to report nearly-identical messages that only vary based on who is home. This can be done with one service call that alters the message based on who is home.

That’s the over all goal. Is reducing the amount of code. Before I had separate automations for each of these if statements. I read about the service calls but my grasp of the concept has been more than struggle.

OK, that’s a fine goal but you’ve reduced it to the point it is subject to failure.

You can’t allow a service_template to be blank. If you have to resort to supplying it with do-nothing services then you may want to re-think the approach you’ve chosen. The automation’s action performs many repeated checks (like determining who is home and if the sun is up) that would be more efficient if they were triggers for an automation.

Out of curiosity, what triggers this automation?

Are you on upwork or fiverr?
I would happily pay to have this package/yaml file reworked.

Pretty sure I’m not because I don’t even know what those are …

The current sentiment of this community forum is that payment for solutions is discouraged. This forum is for DIYers looking for answers to their questions.

If you describe what you are attempting to achieve with your automation, it may attract other members to participate in this topic and help you.

oh ok.

The triggers are person.p at home or person.j at home.

  action:
    - service_template: >
        {% if is_state('sun.sun', 'below_horizon') %}
          homeassistant.turn_on
        {% else %}
          homeassistant.turn_off
        {% endif %}
      entity_id: group.interior_lights

^Only when dark out, turn on the interior lights.


    - service: input_boolean.turn_off
      entity_id: input_boolean.vacation_mode

^ turn off vacation boolean


    - service_template: >
        {% if is_state('sensor.whoishome', 'P') %}
          input_boolean.turn_on
        {% elif is_state('sensor.whoishome', 'Both') %}
          input_boolean.turn_on
        {% endif %}
      entity_id: input_boolean.P_home

^turn on “p_home” boolean if whoishome sensor = Both OR P


    - service_template: >
        {% if is_state('sensor.whoishome', 'P') %}
          notify.mypushover
        {% elif is_state('sensor.whoishome', 'Both') %}
          notify.mypushover
        {% endif %}
      data:
       message: Welcome home, P!

^send pushover message if whoishome sensor equals P or both


    - service_template: >
       {% if is_state('sensor.whoishome', 'P') %}
       tts.google_cloud_say
       {% endif %}
      data:
       entity_id: media_player.audiogroup
       message: Welcome home, P!
    - service_template: >
       {% if is_state('sensor.whoishome', 'J') %}
       tts.google_cloud_say
       {% endif %}
      data:
       entity_id: media_player.audiogroup
       message: Welcome home, J!
    - service_template: >
       {% if is_state('sensor.whoishome', 'Both') %}
       tts.google_cloud_say
       {% endif %}
      data:
       entity_id: media_player.audiogroup
       message: Welcome home, P and J!

^Announce who is here based on on the whoishome sensor.

What’s the relationship between sensor.whoishome and the person entities? What I’m attempting to establish is whether this automation can be triggered by sensor.whoishome.

I assume sensor.whoishome has three valid states: P, J, Both. Is that correct?