Set templated variable globally and pass to script

Hi,

trying to have my announcements in optional languages, Im a little stuck in setting the variable (message) to pass to the script.

the plain announcement would be:

          message: >
            {% set language = states('input_select.intercom_language') %}
            {% set trash = states('sensor.trash_today') %}
            {% set now =  now().strftime('%A %-d %B') %}
            {% if language == 'En' %} It is {{ now}}: today {{trash}} is being picked up!
            {% elif language =='Nl' %} Het is {{ now }}: vandaag wordt {{trash}} opgehaald!
            {% endif %}

passing that as variable is a bit more complex…I need the set part to be global for the translated messages.
this is my script (not yet using a mapper, might do so if more languages are needed…):

      - service: tts.google_say
        data_template:
          language: >
            {{states('input_select.intercom_language')|lower}}
          entity_id: >
            {{states('sensor.intercom')}}
          message: >
            {% set language = states('input_select.intercom_language') %}
            {% if language == 'En' %} {{message_en}}
            {% elif language == 'Nl' %} {{message_nl}}
            {% endif %}

and Im testing this automation:

    action:
      - service: script.intercom_message
        data_template:
          message: >  # is this even necessary here?
            {% set language = states('input_select.intercom_language') %}
            {% set trash = states('sensor.trash_today') %}
            {% set now =  now().strftime('%A %-d %B') %}
            message_nl: 'Het is {{ now }}: vandaag wordt {{trash}} opgehaald!'
            message_en: 'It is {{ now}}: today {{trash}} is being picked up!'

though it shows correctly in this editor, it shows wrongly colored in my text editor:

01

as if the messages are part of the set part…

please have a look?

btw, the script works alright, I have several un-templated message that are passed correctly, like this eg:

  notify_delayed_startup:
    alias: 'Notify delayed startup'
    sequence:
      - service: script.intercom_message
        data_template:
          message_en: >
            It took {{ states('input_number.ha_delayed_startup')|int }} seconds for Home-assistant Main to
            enter Delayed startup.

triggering the automation renders this though:

    action:
      - service: script.intercom_message
        data_template:
          message_nl: >
            {% set language = states('input_select.intercom_language') %}
            {% set trash = states('sensor.trash_today') %}
            {% set now =  now().strftime('%A %-d %B') %}
            'Het is {{ now }}: vandaag wordt {{trash}} opgehaald!'
          message_en: >
            {% set language = states('input_select.intercom_language') %}
            {% set trash = states('sensor.trash_today') %}
            {% set now =  now().strftime('%A %-d %B') %}
            'It is {{ now}}: today {{trash}} is being picked up!'

looks alright, but has everything set twice…

That’s the way it has to be with jinja. You can’t have code work over multiple fields.

But to be honest, I’m not sure why you are doing this. Why separate it? What’s the point? It literally serves no purpose. It’s a layer that is not needed. Always a good rule of thumb: Keep it simple.

      - service: tts.google_say
        data_template:
          language: >
            {{ states('input_select.intercom_language') | lower }}
          entity_id: >
            {{ states('sensor.intercom') }}
          message: >
            {{ message }}

and call it with

    action:
      - service: script.intercom_message
        data_template:
          message: >
            {% set language = states('input_select.intercom_language') %}
            {% set trash = states('sensor.trash_today') %}
            {% set now =  now().strftime('%A %-d %B') %}
            {% if language == 'En' %} It is {{ now }}: today {{ trash }} is being picked up!
            {% elif language =='Nl' %} Het is {{ now }}: vandaag wordt {{ trash }} opgehaald!
            {% endif %}

well, I thought it nice to have each script simply create messages in the format of message_en, message_nl, etc etc, and have the intercom script use the correct format. Have that bit of logic in the main intercom script, would make the serving scripts simpler…

With your suggestion, which was what I had at first, I need to create these bigger if then else templates for each serving script.

If that’s the case, then you have to deal with recreating variables for each field. For simplicities sake…

      - service: tts.google_say
        data_template:
          language: >
            {{states('input_select.intercom_language')|lower}}
          entity_id: >
            {{states('sensor.intercom')}}
          message: >
            {% set language = states('input_select.intercom_language') %}
            {% if language == 'En' %} {{message_en}}
            {% elif language == 'Nl' %} {{message_nl}}
            {% endif %}

you may be able to try this, not sure if it will work

      - service: tts.google_say
        data_template:
          language: >
            {{states('input_select.intercom_language')|lower}}
          entity_id: >
            {{states('sensor.intercom')}}
          message: >
            {% set language = states('input_select.intercom_language') %}
            {{ data['message_'+language] }}

Either way, you can shorten your variable section to this. You don’t need to check or get the language at this point. You also are only using the variables once, so there’s no need to set them.

    action:
      - service: script.intercom_message
        data_template:
          message_nl: >
            Het is {{now().strftime('%A %-d %B')}}: vandaag wordt {{states('sensor.trash_today')}} opgehaald!
          message_en: >
            It is {{now().strftime('%A %-d %B')}}: today {{states('sensor.trash_today')}} is being picked up!
1 Like

oops missed that. thanks for the eagle eye…

      - service: script.intercom_message
        data_template:
          message_nl: >
            Het is {{now().strftime('%A %-d %B')}}: vandaag wordt {{states('sensor.trash_today')}} opgehaald!
          message_en: >
            It is {{now().strftime('%A %-d %B')}}: today {{states('sensor.trash_today')}} will be collected!

might probably be better english? If I presume to be better than Google translate, I need to be precise :wink:

Since I dont have all languages set up yet, and my input_select has 5, I needed an else in the template. hence, I was just experimenting with this:

{% set language = states('input_select.intercom_language') %}
{% if language in [ 'En', 'Nl'] %} {{'message _' + language|lower}}
{% else %} {{message_en}}
{% endif %}

wouldn’t that work also? Need to get the |lower somewhere in it…

update
no it doesn’t… nor does {{message _ + language|lower}} which has google say ‘message_nl’ … lol

and

results in this

2019-07-30 18:13:38 ERROR (MainThread) [homeassistant.helpers.service] Error rendering data template: UndefinedError: 'data' is undefined

Well it looks like you’ll have to have nested if statements anyways because there doesn’t appear to be a way to dynamically call variables. So the second example I gave will never work.