Set Script variable inside of template not working


I’m new to H.A. and still struggling to learn H.A yaml and jinja2 syntaxes because of the horrible documentation… :frowning:

So, what I’m trying to do.
I have a script to execute the open/stop/close commands for my curtains thru RF control.
I’m trying to use some template/code logic to keep it smaller.

Here I wrote a test script, which only send to me a notification with the result, to check if it works.
The jinja2 code works, tested on the template developers page.
However, the variable of the script do not integrate with the variable inside of the template.

First thing is: Where I should run this templating? Since it is a code to set some logic . The wait_template does not appear to be the right place for my objective.

Second: why the variable “persiana_device” wasn’t set when I call this script setting the “persiana” variable with a valid value.

Here is the script.

  alias: teste script
    persiana: persiana
    comando: ono
    persiana_device: onoono
  - choose:
    - conditions: []
      - wait_template: >
          {% set persiana_device = {
          "persiana_quarto_visita"                : "Persiana Quarto visita",
          "persiana_quarto_augusto"               : "Persiana Quarto Augusto",
          "persiana_direita_quarto_suite_master"  : "Persiana Direita Quarto Suite Master",
          "persiana_esquerda_quarto_suite_master" : "Persiana Esquerda Quarto Suite Master",
          "persiana_quarto_inf_rampa"             : "Persiana Quarto inf Rampa",
          "persiana_quarto_inf_casinha_gas"       : "Persiana Quarto inf Casinha Gas"}[persiana] | default("ono") 
          {{ persiana_device != "ono" }} 
        continue_on_timeout: true
      - service: notify.mobile_app_sm_a725m
          message: 'teste comando: {{ persiana }} = {{ persiana_device }} comando
            {{ comando }}'
  mode: single
  icon: mdi:blinds

Here is how I call it :

  - service: script.teste_script
      persiana: persiana_quarto_inf_rampa
      comando: abrir

Checking the trace.
Here they just show the step was completed as true, where I deduce this mean the variable persiana_device was set correctly.


However on the next step, to send me the notification, I see it set with the default value from the script.


What I’m missing here?
I tried a lot of ways , all without success…
Please, if have any documentation to refer where explain how to do this I really like to know.


You have a Choose action with only one option… is that a placeholder or is there some other reason for using that?

I don’t understand why you have used a Wait template… especially since is doesn’t have an entity change or timeout to wait for…

  1. There are no entities in your template. The way a wait for template works is that the template is evaluated immediately, and if it renders true, the script will continue. If not, then it will wait until it is true. Templates are only re-rendered when an entity they are “watching” changes.
  2. You have continue_on_timeout set to true, but no timeout set… Why?

But the main issue is that you defined the variable persiana_device in a “global” sense as onoono. Within the template in the Wait, you give it a new value, but that value’s scope is local to that template only. This can be solved by moving the template to the variables block. This is how I would set up the script, based on the limited information you have provided…

  alias: teste script
      name: Persiana
      example: persiana_quarto_visita
      required: true
      name: Comando
      description: ''
      example: abrir
      required: true
      persiana_quarto_visita: Persiana Quarto visita
      persiana_quarto_augusto: Persiana Quarto Augusto
      persiana_direita_quarto_suite_master: Persiana Direita Quarto Suite Master
      persiana_esquerda_quarto_suite_master: Persiana Esquerda Quarto Suite Master
      persiana_quarto_inf_rampa: Persiana Quarto inf Rampa
      persiana_quarto_inf_casinha_gas: Persiana Quarto inf Casinha Gas
    persiana_device: "{{ persianas.get(persiana) }}" 
    - service: notify.mobile_app_sm_a725m
        message: >
          teste comando: {{ persiana }} = {{ persiana_device }} <br>
          comando: {{ comando }}'
  mode: single
  icon: mdi:blinds

Hi @Didgeridrew ,
Thank you a lot for your answer!!!
Didn’t test yet, but after reading it I think they will solve my situation.

I don’t put more information to keep the post short and try to be objective.
The “persiana_device” is the name of the device I saved using the remote.learn_command.
I have 6 curtains.
So my objective is one script passing the curtain id (internal id, created by me), converting to the device name and the command to send to the curtain.

About your script, please can you just explain to me why set the Field and not keep the variable?
On my tests, appears the variable receives the parameter from the calling script, so, at this point I don’t see the difference between using variable and field.

About use the Wait template, I use it because the solution I found (case statement) was using templating and I not found where to use the template…

Again, is very hard for those who don’t have knowledge of python, yaml, and jinja2 code to discover how to code and resources of functions like you use (variable + get() ) … and the H.A. documentation also is very poor… is very frustration for who want to try by self.
Also, tutorials also are very superficial.

Unfortunately , didn’t work.

It wasn’t recognize the “persianas” variable:

2023-05-14T16:59:20.215310532Z 2023-05-14 13:59:20.211 ERROR (MainThread) [homeassistant.helpers.template] Template variable error: 'persianas' is undefined when rendering '{{ persianas.get(persiana) }}'
2023-05-14T16:59:20.220598901Z 2023-05-14 13:59:20.218 ERROR (MainThread) [homeassistant.components.script.teste_script] teste script: Error rendering variables: UndefinedError: 'persianas' is undefined
2023-05-14T16:59:20.225413183Z 2023-05-14 13:59:20.223 ERROR (MainThread) [homeassistant.components.script.teste_script_main] teste script main: Error executing script. Error rendering template for call_service at pos 1: UndefinedError: 'persianas' is undefined
2023-05-14T16:59:20.236500800Z 2023-05-14 13:59:20.232 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [281472697699344] UndefinedError: 'persianas' is undefined


Just an indention correct and now it works!!

You are correct that the variables passed from your calling script should be received without having either variables or fields blocks. The variables you had really didn’t do anything except provide a default. While not technically necessary, setting fields can provide a default, set requirement criteria, and give you information about the script’s expected variables in the Services tool as well as the Automation and Script editors. As I stated, that’s how I would do it. You will find that there are almost always more than one way to do anything in HA:

Alternative Variables method similar to your original
    persiana_device: > 
      {% set persianas = {
      'persiana_quarto_visita': 'Persiana Quarto visita',
      'persiana_quarto_augusto': 'Persiana Quarto Augusto',
      'persiana_direita_quarto_suite_master': 'Persiana Direita Quarto Suite Master',
      'persiana_esquerda_quarto_suite_master': 'Persiana Esquerda Quarto Suite Master',
      'persiana_quarto_inf_rampa': 'Persiana Quarto inf Rampa',
      'persiana_quarto_inf_casinha_gas': 'Persiana Quarto inf Casinha Gas'} %}
      {{ persianas[persiana] }}

I understand the feeling… I had no coding or CS training when I started out 3 years ago. While the docs’ search function is often unhelpful and a majority of the docs are not written in a beginner-friendly way, they are usually up-to-date and relatively complete.

The information about Variables and Variable Scope can be found in the Script Syntax section of the docs