Data_template not working

Hi,

can anybody tell me why this is not working:

  AktiviereSzene:
    speech:
      type: plain
      text: 'Gern!'
    action:
     - service_template: >
         {% if whichScene == 'Aus' %}
         light.turn_off
         {% else %}
         hue.hue_activate_scene
         {% endif %}
       data_template: >
         {% if whichScene == 'Aus' %}
         entitiy_id: '{{ whichGroup }}'
         {% else %}
         group_name: '{{ whichGroup }}'
         scene_name: '{{ whichScene }}'
         {% endif %}

Invalid config for [intent_script]: expected a dictionary for dictionary value @ data[‘intent_script’][‘AktiviereSzene’][‘action’][0][‘data_template’]. Got “{% if whichScene == ‘Aus’ %} entitiy_id: ‘{{ whichGroup }}’ {% else %} group_name: ‘{{ whichGroup }}’ scene_name: ‘{{ whichScene }}’ {% endif %}\n”. (See /config/configuration.yaml, line 29). Please check the docs at Intent Script - Home Assistant

For the service_template same syntaxt is working?

because you’re mixing services and data that can’t be mixed.You’d best write 2 scripts ( 1 for the light turn_off action, and 1 for the hue_activate scene action), with their respective data, and then call these scripts in the service_template

1 Like

Thank you, I will give that a try!

Yay, it’s working now:

scripts.yaml:

setze_szene:
  alias: Szene setzen
  sequence:
    - service: hue.hue_activate_scene
      data_template:
         group_name: '{{ tempGroup }}'
         scene_name: '{{ tempScene }}'

licht_aus:
  alias: Licht aus
  sequence:
   - service: light.turn_off
     data_template:
       entity_id: light.{{ tempGroup | lower }}

cnfiguration.yaml

intent_script:
  AktiviereSzene:
    speech:
      type: plain
      text: 'Gern!'
    action:
     - service_template: >
         {% if whichScene == 'Aus' %}
         script.licht_aus
         {% else %}
         script.setze_szene
         {% endif %}
       data_template:
         tempGroup: '{{ whichGroup }}'
         tempScene: '{{ whichScene }}'

Now I have no need for an “Aus” scene on the bridge anymore. Will put this in my lovelace hue scene script, too. Maybe I will also put an additional slot to the intent and expand it to be able to set lights to X% and colors…but I mostly use scenes anyways.

Okay, I got it working that way but the whole topic is still not clear to me.

Look at this:

licht_an:
  alias: Licht an
  sequence:
   - service: light.turn_on
     data_template: >
       entity_id: light.{{ temp_group | lower }}
       {% if temp_brightness is defined %}
       brightness_pct: {{ temp_brightness }}
       {% endif %}
       {% if temp_color is defined %}
       color_name: {{ temp_color }}
       {% endif %}

Error on check:

Invalid config for [script]: expected a dictionary for dictionary value @ data[‘script’][‘licht_an’][‘sequence’][0][‘data_template’]. Got ‘entity_id: light.{{ temp_group | lower }} {% if temp_brightness is defined %} brightness_pct: {{ temp_brightness }} {% endif %} {% if temp_color is defined %} color_name: {{ temp_color }} {% endif %}\n’. (See /config/configuration.yaml, line 15). Please check the docs at Scripts - Home Assistant

Without the ifs I can use it like that, or to say it different: All possible outputs of that if / else would be valid for light.turn_on - so that means there can’t be a problem with mixing data types or something.

What I expect: When the if is true, the according line will be printed below data template, when not than not.

To me it looks like all the if else stuff is only working behind the parameters:

       data_template:
         brightness_pct: '{% if bla bla %}...{% endif %}'

and not right after data_template: to make those parameters optional. The problem is when I pass the brightness_pct to light.turn_on it insists in getting a float, an empty value will result in an error. It makes zero sense to me that I can’t option out whole lines in the data_template.

I mean those parameters are optional, why can’t they be an option in my data_templates. It also makes the syntax absolutely inconsistent wit service_template for my feeling (and many others feel the same when I search the forum for this issue).

I could solve this by creating additional scripts, one that includes the brightness, one that includes the color and one with both and call them accordingly but how stupid is that?

Do I have a general lack of understanding here??

At least you’ve got some yaml syntax mixed up. Dont know about your entities or variables, but you could try this:

   - service: light.turn_on
     data_template: >
       entity_id: light.{{ temp_group | lower }}
       brightness_pct: >
         {% if temp_brightness is defined %} {{ temp_brightness }}
         {% endif %}
       color_name: >
         {% if temp_color is defined %} {{ temp_color }}
         {% endif %}

having said that, you dont have an else clause in the templates, which is necessary for the situation the ‘if’ doesnt render a valid outcome.

Hi Marius,

thanks for taking the time.

I have that exact same syntax in a service template and there it is working. However I’m still learning and if this is not the best way to do it, I will work on it.

I don’t have an else for a simple reason: I don’t want any rendered outcome if the if or elif is not fulfilled. I would still have the entity_id:, which is enough to turn a light on.

I gave your code a try but the problem remains:

brightness_pct: is optional but if you put it in the data_template and don’t pass a float (because you don’t want to change brightness) you get:

2019-10-01 19:02:58 WARNING (MainThread) [homeassistant.helpers.intent] Received invalid slot info for LightControl: expected float for dictionary value @ data[‘brightness_pct’]
2019-10-01 19:02:58 ERROR (MainThread) [homeassistant.components.snips] Error while handling intent: LightControl.

My conclusion was to put the if before brightness_pct, right after data_template (like it is normal in service templates). But that led to the problem shown in the initial post.

I don’t want the brightness_pct: there at all when brightness is not defined.

Is that even possible?

Looking at all other posts around this topic, I come to the conclusion that it is just not possible to put an if before the attribute:.

That means I have to create 4 scripts:

  • One to just turn on
  • One to change the color
  • One to change the brightness
  • One to change both

Total overkill while a if condition in the right place could do that (if it was allowed there).

Got it working with 4 scripts (plus two for off and select hue scene) :smiley:

intent_script:
  LightControl:
    speech:
      type: plain
      text: 'Gern!'
    action:
     - service_template: >
         {% if whichScene == 'Aus' %}
         script.licht_aus
         {% elif whichBrightness is defined and whichColor is defined %}
         script.licht_hell_farbe
         {% elif whichBrightness is defined %}
         script.licht_hell
         {% elif whichColor is defined %}
         script.licht_farbe
         {% elif whichScene == 'An' %}
         script.licht_an
         {% else %}
         script.setze_szene
         {% endif %}
       data_template:
         temp_group: '{{ whichGroup }}'
         temp_scene: '{{ whichScene }}'
         temp_brightness: '{{whichBrightness }}'
         temp_color: '{{ whichColor }}'

scripts.yaml:

setze_szene:
  sequence:
    - service: hue.hue_activate_scene
      data_template:
         group_name: '{{ temp_group }}'
         scene_name: '{{ temp_scene }}'

licht_aus:
  alias: Licht aus
  sequence:
   - service: light.turn_off
     data_template:
       entity_id: light.{{ temp_group | lower }}

licht_hell_farbe:
  alias: Licht Helligkeit und Farbe
  sequence:
   - service: light.turn_on
     data_template:
       entity_id: light.{{ temp_group | lower }}
       brightness_pct: '{{ temp_brightness }}'
       color_name: '{{ temp_color }}'

licht_hell:
  alias: Licht Helligkeit
  sequence:
   - service: light.turn_on
     data_template:
       entity_id: light.{{ temp_group | lower }}
       brightness_pct: '{{ temp_brightness }}'

licht_farbe:
  alias: Licht Farbe
  sequence:
   - service: light.turn_on
     data_template:
       entity_id: light.{{ temp_group | lower }}
       color_name: '{{ temp_color }}'

licht_an:
  alias: Licht an
  sequence:
   - service: light.turn_on
     data_template:
       entity_id: light.{{ temp_group | lower }}

Understand what you want, but you should really have an else catch. You can do what you want but you’d need to split it up in 2 little scripts. 1 with the brightness and color settings, and the second with only the entity_id, without further settings.

as for the error you get: you should always give it what it asks for (you’re now feeding it a string probably in stead of a number), though I would think an int would do, as I’ve never seen brightness_pct being a float… its a number between 0 and 100:


or see here:

edit

posted this replying to your mention, without having seen the progress you made above. Thats how it should be done indeed. That is, talking about the automation/script usage, not about the light settings themselves. I do wonder if that couldn’t be easier :wink:

I must confess I am somewhat amazed this works as you say it does, because you are feeding the scripts the same variables, while they aren’t used in all scripts/services. For what my experience has learned me, I always use the exact same entities and data per script. You mixing that here is quite an interesting development…

1 Like

Yeah I was in doubt if tht would work, too but it does - like a charm.

For sure most of the stuff could be easier or more beautiful but there is too much I still have to do. Will be reviewed later once it works :wink:

Also added use if site_id when no location is provided, works great with the satellite.

Thank you for your input!