Service_template error

Hello everyone.
I have an error, when trying to automate my light switching with service_template.

  - service_template: >-
  {%- if (as_timestamp(states.sun.sun.attributes.next_rising) -86400 < as_timestamp(now()) ) and is_state('light.lenta_gostinaia', 'off') -%}
    service: light.turn_on
    data:
      entity_id: light.lenta_gostinaia
      brightness_pct: '10'
      rgb_color:
      - 255
      - 132
      - 2
  {%- elif (as_timestamp(states.sun.sun.attributes.next_setting) -86400 > as_timestamp(now()) ) and is_state('light.lenta_gostinaia', 'off') -%}
    data:
      entity_id: light.lenta_gostinaia
      brightness_pct: '50'
      rgb_color:
      - 255
      - 255
      - 255
    service: light.turn_on
  {%- else -%}
    data:
      entity_id: light.lenta_gostinaia
    service: light.turn_off
  {%- endif -%}

i hav ean error in logs: Invalid data for call_service at pos 1: Service light.turn_on
data: entity_id: light.lenta_gostinaia does not match format .
, and my automation does not work.
Help me please.

Not sure if this is behind the error, but since you’re only using one entity_id it could be removed from the data: section…

  - service_template: >-
  {%- if (as_timestamp(states.sun.sun.attributes.next_rising) -86400 < as_timestamp(now()) ) and is_state('light.lenta_gostinaia', 'off') -%}
    service: light.turn_on
    data:
      brightness_pct: '10'
      rgb_color:
      - 255
      - 132
      - 2
  {%- elif (as_timestamp(states.sun.sun.attributes.next_setting) -86400 > as_timestamp(now()) ) and is_state('light.lenta_gostinaia', 'off') -%}
    data:
      brightness_pct: '50'
      rgb_color:
      - 255
      - 255
      - 255
    service: light.turn_on
  {%- else -%}
    data:
    service: light.turn_off
  {%- endif -%}
    entity_id: light.lenta_gostinaia

EDIT: I think it actually needs to removed from the template entirely.

I’m about 75% sure that you can’t combine service and data templates under a service template. I’m looking for some ways to maybe optimize it.

You need to use a service_template and a separate data_template.

The end-result won’t be pretty. The entire if-elif-else-endif structure has to be repeated in the data_template as well.

Not a fan of copying the same argument three times, but this could work.

  - service_template: >-
    {% set ts = as_timestamp(states.sun.sun.attributes.next_rising) %}
    {% set light = is_state('light.lenta_gostinaia', 'off') %}
    {% if ts -86400 < as_timestamp(now()) and light -%}light.turn_on
    {% elif ts -86400 > as_timestamp(now()) and light -%}light.turn_on
    {% else %}light.turn_off
    {% endif %}
    data_template:
      brightness_pct: >
      {% set ts = as_timestamp(states.sun.sun.attributes.next_rising) %}
      {% set light = is_state('light.lenta_gostinaia', 'off') %}
      {% if ts -86400 < as_timestamp(now()) and light -%}10
      {% elif ts -86400 > as_timestamp(now()) and light -%}50
      {% endif %}
      rgb_color: >
      {% set ts = as_timestamp(states.sun.sun.attributes.next_rising) %}
      {% set light = is_state('light.lenta_gostinaia', 'off') %}
      {% if ts -86400 < as_timestamp(now()) and light -%}[255,132,2]
      {% elif ts -86400 > as_timestamp(now()) and light -%}[255,255,255]
      {% endif %}
      entity_id: light.lenta_gostinaia

@renga

Seems to me that the action section is being asked to do a lot of ‘conditional’ work. What’s the rest of this automation doing?

@walrus_parka

Check this out. By tidying up the original code, you’ve revealed the original logic was needlessly verbose.

  • Assume the light is off.

  • Regardless if ts -86400 is less than or greater than as_timestamp(now()), the light will be turned on.

  • Assume the light is on.

  • Both tests are false so the light will be turned off.

    {% set ts = as_timestamp(states.sun.sun.attributes.next_rising) %}
    {% set light = is_state('light.lenta_gostinaia', 'off') %}
    {% if ts -86400 < as_timestamp(now()) and light -%}light.turn_on
    {% elif ts -86400 > as_timestamp(now()) and light -%}light.turn_on
    {% else %}light.turn_off
    {% endif %}

Long story short, this service_template is just toggling the light’s state. So it’s just this:

- service: light.toggle
  entity_id: light.lenta_gostinaia

It’s the data_template that continues to do all the heavy-lifting. I’d like to draw your attention to the following situation.

  • Assume the light is on.
  • Both tests are false but there’s no else to handle this situation therefore brightness_pct will be set to no value at all.
  • Same situation applies to rgb_color.
    data_template:
      brightness_pct: >
      {% set ts = as_timestamp(states.sun.sun.attributes.next_rising) %}
      {% set light = is_state('light.lenta_gostinaia', 'off') %}
      {% if ts -86400 < as_timestamp(now()) and light -%}10
      {% elif ts -86400 > as_timestamp(now()) and light -%}50
      {% endif %}

I realize the light will be turned off so maybe it doesn’t matter. I’m just not sure how Home Assistant will handle this situation where the template returns no value to assign to the option.

Seeing the rest of the automation would definitely help get the bigger picture of what they’re trying to accomplish.

I have a feeling it would throw an error and the automation would fail.

I agree. There probably should be an else that sets the options to something valid.

… but we really need to see the rest of this automation.

The rest of this automation is just a button click.

  trigger:
  - event_data:
      click_type: single
      entity_id: binary_sensor.switch_***************
    event_type: xiaomi_aqara.click
    platform: event

The idea was to dim lights at evening and night.
Now, with @walrus_parka script i have an error with variables.
found character ‘%’ that cannot start any token
in “/home/homeassistant/.homeassistant/automations.yaml”, line 312, column 6

This line points to

{% set ts = as_timestamp(states.sun.sun.attributes.next_rising) %}

This was my fault. This lines must be indented with 2 spaces.
But now i have one more error
2019-04-13 16:22:48 ERROR (MainThread) [homeassistant.components.automation] Error while executing automation automation.gostinaia_knopka_lenta. Invalid data for call_service at pos 1: extra keys not allowed @ data[‘rgb_color’]

So is the button the only thing that turns that light on or off?

@walrus_parka Yes, the button is the only thing.

I would suggest what @123 mentioned. Regardless of the time we are toggling the light.

Adding an else to the brightness_pct for any other time the button is pressed.

Replaced the last elif with else to the rgb_color since it is already full white. If that is not what is desired, add an else with whatever rgb color is needed.

  - service_template: light.toggle
    entity_id: light.lenta_gostinaia
    data_template:
      brightness_pct: >
        {% set ts = as_timestamp(states.sun.sun.attributes.next_rising) %}
        {% set light = is_state('light.lenta_gostinaia', 'off') %}
        {% if ts -86400 < as_timestamp(now()) and light %}10
        {% elif ts -86400 > as_timestamp(now()) and light %}50
        {% else %}255
        {% endif %}
      rgb_color: >
        {% set ts = as_timestamp(states.sun.sun.attributes.next_rising) %}
        {% set light = is_state('light.lenta_gostinaia', 'off') %}
        {% if ts -86400 < as_timestamp(now()) and light %}[255,132,2]
        {% else %}[255,255,255]
        {% endif %}

I’m stuck again.

  - service_template: light.toggle
    entity_id: light.lenta_gostinaia
    data_template:
      brightness: >
        {%- set ts = as_timestamp(states.sun.sun.attributes.next_rising) -%}
        {%- set light = is_state('light.lenta_gostinaia', 'off') -%}
        {% if ts -86400 < as_timestamp(now()) and light %}127
        {% else %}10
        {% endif %}
      rgb_color: >
        {%- set ts = as_timestamp(states.sun.sun.attributes.next_rising) -%}
        {%- set light = is_state('light.lenta_gostinaia', 'off') -%}
        {% if ts -86400 < as_timestamp(now()) and light %}[{{255|int}},{{255|int}},{{255|int}}]
        {% else %}[{{255|int}},{{132|int}},{{2|int}}]
        {% endif %}

I change script a little, in dev_template i see, what i need:

brightness: >10
rgb_color: >[255,132,2]

But when i try to fire an automation, i have an error:
Error while executing automation automation.gostinaia_knopka_lenta. Invalid data for call_service at pos 1: None for dictionary value @ data[‘rgb_color’]

Well, there is one more problem. light_toggle dont pass rgb_color and brightness. It just toggles light on and off

Apparently there is an issue with passing a list in a template. I have limited time at the moment but I can take a better look at it this later.

If the services page is to be believed, you are able to pass any turn_on parameters with a toggle service call.

If you believe light.toggle has limitations then replace the existing service_template with this one:

service_template: "{{ 'light.turn_on' if is_state('light.lenta_gostinaia', 'off') else 'light.turn_off' }}"

I don’t believe, i tested it. Yes, documentation says that it is possible, but when i fire light.toggle with color and brightness parameters, light switch’s on with previous state.

Does it work when you use this template? It doesn’t use light.toggle and selects either light_turn_on or light.turn_off depending on the state of light.lenta_gostinaia.

service_template: "{{ 'light.turn_on' if is_state('light.lenta_gostinaia', 'off') else 'light.turn_off' }}"