Problems with service_template

Hi All,

I have some covers which follow an automated open/close cycle. But with the hot weather now, I want to choose if a cover follows the automated procedure or not. For that instance I’ve created a “input_boolean” to toggle the cover in the automated cycle. Below is my code for one, intention is to expand the automation to the others also.

- id: '1561801151216'
  alias: Rolluik naar beneden auto
  trigger:
  - event: sunset
    offset: +00:30:00
    platform: sun
  condition: []
  action:
  - data:      
    service_template: >
             {% if is_state('input_boolean.rolluikachteraan', 'on') %}
                cover.close_cover
             {% else %}
             {% endif %}
    entity_id: rolluik_achteraan

Home Assistant (0.94.1) spits out this error:

Invalid config for [automation]: expected dict for dictionary value @ data[‘action’][0][‘data’]. Got None
not a valid value for dictionary value @ data[‘action’][0][‘entity_id’]. Got None.

It has probably something to do with indentation but after reading a few hours and changing the indentation a million times, I’m out of solutions. Can someone point me to the solution?

Thanks!

you dont need data there and you really need something after else or it can error out… Think of it like this do this else do (what) …but here is a example of a service template https://github.com/Vasiley/Home-Assistant-Main/blob/5beef63814934b978ccab71d81d8b9e54c676e6f/packages/room_kids_room_device_watchdog.yaml#L56

You don’t need a template. Just use the condition in the automation.

metbril beat me to it!

Here it is anyway:

- id: '1561801151216'
  alias: Rolluik naar beneden auto
  trigger:
  - event: sunset
    offset: +00:30:00
    platform: sun
  condition:
    condition: state
    entity_id: input_boolean.rolluikachteraan
    state: 'on'
  action:
  - service: cover.close_cover
    entity_id: rolluik_achteraan

did you all notice that that entity_id is suspicious? Missing a domain.

@metbril and @123. That would have been correct as only one condition but as I stated in the OP, this is for one cover but I the intention is to write one automation for all the covers which checks, on a per cover basis, if it needs to go op (or down) or stay the way it is.

@Vasiley Left out the data but to no avail. here’s the code

- id: '1561801151216'
  alias: Rolluik naar beneden auto
  trigger:
  - event: sunset
    offset: +00:30:00
    platform: sun
  condition: []
  action:
  - service_template: >
      {%if is_state('input_boolean.rolluikachteraan', 'on') %}
        cover.close_cover
      {% else %}
      {% endif %}
    data:
      entity_id: cover.rolluik_achteraan

which spits out (on execution)

“Invalid data for call_service at pos 1: Service does not match format domain.name”

which is probably what @petro is talking about and for which I don’t have a clue. I really don’t know what to do with the “do-nothing” {% else %} part.

you still have data

  - service_template: >
      {%if is_state('input_boolean.rolluikachteraan', 'on') %}
        cover.close_cover
      {% else %}
      {% endif %}
    entity_id: cover.rolluik_achteraan

You could do that with a combination of AND and OR conditions and still don’t need templating.

sorry @Vasiley. Pasted the wrong version. The “data” was left out

  - service_template: >
      {%if is_state('input_boolean.rolluikachteraan', 'on') %}
        cover.close_cover
      {% else %}
      {% endif %}
    entity_id: cover.rolluik_achteraan

but the error remained the same

Invalid data for call_service at pos 1: Service does not match format domain.name

Missing space?

{% if

and, if ever you need an ‘else’ without doing anything, just to keep your templates save, use a dummy

script:
  dummy:
    alias: 'Dummy script'
    sequence:
      delay: 00:00:00

Nice catch @metril. But the error remains the same.

Metbril and I addressed the problem you presented and the solution is correct.

Your future plans are entirely different matter. Your first post introduced a very limited preview of what you intend to do. Had metbril and I acted on it, we would have been off the mark because your second post expands on the requirements. Now we know there may be close and open cover services required.

It would help everyone if you explained precisely what you wish to achieve with multiple covers and input_booleans.


EDIT
You should also be aware that when multiple covers become involved, where some may need to be opened or closed, it presents a challenge. Now the automation’s action may need to call none, one, or two services (do nothing, open one or more covers, close one or more covers). There may be a need to use scripts. Anyway, first we need to know more about what you wish to accomplish.

FWIW, here’s a ‘brute force’ approach to closing multiple covers depending on the state of their respective input_boolean:

  - service: cover.close_cover
    data_template:
      entity_id: >
        {% set a = ', cover.rolluik_achteraan' if is_state('input_boolean.rolluikachteraan', 'on') else '' %}
        {% set b = ', cover.rolluik_2' if is_state('input_boolean.rolluik2', 'on') else '' %}
        {% set c = ', cover.rolluik_3' if is_state('input_boolean.rolluik3', 'on') else '' %}
        {% set d = ', cover.rolluik_4' if is_state('input_boolean.rolluik4', 'on') else '' %}
        cover.none{{a}}{{b}}{{c}}{{d}}

Relax it is not that complicated

I showed him a simple use of service template and that should work

If you’re referring to the automation in the first post, I agree. The solution is not complicated. Move the test from the action to the condition

If you are referring to this:

  - service_template: >
      {% if is_state('input_boolean.rolluikachteraan', 'on') %}
        cover.close_cover
      {% else %}
      {% endif %}
    entity_id: cover.rolluik_achteraan

then, no, it won’t work and custk9 has confirmed it doesn’t work.

It won’t work because when the input_boolean is off the template’s execution proceeds to {% else %} which returns … nothing. That means nothing is assigned to service_template which is invalid and produces the error:

Invalid data for call_service at pos 1: Service does not match format <domain>.<name>

The template must return a valid service name.

The technique of using a service_template only gets messier when attempting to handle multiple cover entities where some may need to be closed or opened. That’s why, in the example I posted above, I chose to fix the service and template the entities. One entity template for cover.close_cover and a separate one for cover.open_cover. Home Assistant silently ignores a non-existent entity (cover.none) but carps if given a non-existent service.

nothing messy about service_templates, as a matter if fact, they are wonderful and a magic tool in the box. Especially so when using the same template for multiple entities, using trigger.to_state etc etc.

the {% else %} should be fixed indeed, thats why I suggested the script.dummy:

{% else %} script.dummy does wonders, but needs the service template to read:

  - service_template: >
      script.{{ 'close_cover_achteraan' if is_state('input_boolean.rolluikachteraan', 'on')  else 'dummy' }}
script.close_cover_achteraan:
  sequence:
    service: cover.close_cover
    entity_id: cover.rolluik_achteraan

I wasn’t generalizing; my comment was constrained to its use for this particular situation.

Using scripts to solve this is certainly one way of doing it. However, it adds complexity (many scripts, one per cover per service call). It can all be done in the automation’s action (see example above) without employing a service_template.

sure for this instance it might be overkill. But as I tried to imply, when this gets bigger, and it will, it can be very useful and the use of trigger in the template will do wonders, preventing may sub scripts, or even extra automations per entity.
Best to start learning about that technique in simpler situation :wink:

the beauty of this is as always: ymmv, and there are always more options available than 1 to find a solution