Using variables to form an entity name inside a template

Hi, I have been looking here, on the docs, on jinja docs, debugging on the developers tools and on the log but cannot get it right…

I am trying to create a generic script to test and act on a number of switches so I need to test it against a template condition on a choose statement and then use it on a formula for a variable to another script. But I cannot evaluate the expressions:

value_template: "{{ ( position | int ) > (states('sensor.{{ shade }}')|int + 9)|int}}"

and

                variables:
                  deltaporcento: "{{ (position | int) - (states('sensor.{{ shade }}') | int ) | int }}"

Is there a way I can do it? I assumed so as I can use the entity formed for other tests…
Can someone please please help me as this string/code mix is making me crazy?

I can also publish the complete script section if there should be another way to accomplish that…

in order to use blanket variable names like ‘position’, or ‘shade’, you need to declare them ahead of time unless the docs say they are ‘in the environment’ already.

{% set shade = 'my_shade' %}
{% set postion = 4 %}

Then after you can perform tests in the template editor, however your tests are incorrect. When accessing variables, you don’t need extra {{ }} or {% %}. {{ }} returns a whole line of code as a string. {% %} executes a line of code without returning anything.

Also, when you’re trying to combine values, you need to combine them properly. Combining strings can be done using + or ~. Typically ~ is the safest bet.

Lastly, you only need to convert strings to other types. Using |int will convert whatever you’re using to an integer. Typically predefined variables in templates are already declared as a specific type, so you don’t need to convert it. Using states(), you do because it will always return a string.

{{ position - states('sensor.' ~ shade) | int }}

I believe your biggest hindrance right now is understanding types in code. I recommend doing a short interactive online python tutorial. That should familiarize yourself with typing. Then use the jinja documents once you understand that. If you can find a jinja tutorial, great, do that. But those are harder to find.

10 Likes

Thank you very much for your response!

30+ years ago I did some programming and I did it on strongly typed languages. What I am very new to are undeclared variables and objects. I will try to find a tutorial for python types handling, thanks.
I know I am “filtering” too much to int, but that is exactly because I dont know what type they are and I am afraid! Position, which seems to be a pre-defined value for the cover entity, is float, but I could not find this info anywhere…

Anyway, your example saved my day! Pointed me the boundaries!

The ~ did the trick there and everything is working now.

I will leave my code beneath as this explanation might help someone as others have helped me.

Thank you again and I too owe you one!

cover:
  - platform: template
    covers:
      suite_shades:
        device_class: shade
        friendly_name: "Suite Shades"
        position_template: "{{ states('sensor.shades') }}"
        open_cover:
          service: script.open_shades
          data:
            shade: Shades
        close_cover:
          service: script.close_shades
          data:
            shade: Shades
        stop_cover:
          service: script.stop_shades
          data:
            shade: Shades
        set_cover_position:
          service: script.posiciona_shades
          data_template:
            position: "{{ position }}"
            shade: shades

And scripts.yaml:

  close_shades:
    mode: single
    sequence:
      - service: script.turn_on
        data:
          entity_id:
            - script.lower_shades
        data_template:
          variables:
            deltaporcento: 100
            shade: "{{ shade }}"
      - service: mqtt.publish
        data:
          topic: "void/Shades/Position"
          payload: 0

  open_shades:
    mode: single
    sequence:
      - service: script.turn_on
        data:
          entity_id:
            - script.rise_shades
        data_template:
          variables:
            deltaporcento: 100
            shade: "{{ shade }}"
      - service: mqtt.publish
        data:
          topic: "void/Shades/Position"
          payload: 100

  posiciona_shades:
    mode: single
    sequence:
#      - service: system_log.write
#        data_template:
#          message: "{{ ( position | int ) - ( states('sensor.'~shade) | int ) }}"
      - choose:
        # IF must open_shades
        - conditions:
            - condition: template
              value_template: "{{ ( position | int ) > (states('sensor.'~shade)|int + 9) }}" #min 10% change
          sequence:
            - service: script.turn_on
              entity_id:
                - script.rise_shades 
              data_template:
                variables:
                  deltaporcento: "{{ ( position | int ) - ( states('sensor.'~shade) ) | int }}"
                  shade: "{{ shade }}"
            - service: mqtt.publish
              data:
                topic: "void/Shades/Position"
              data_template:
                payload: "{{ position }}"
      # ELSEIF must close_shades
        - conditions:
            - condition: template
              value_template: "{{ ( position | int ) < ( states('sensor.'~shade) ) | int - 9 }}" #min 10% change
          sequence:
#            - service: script.lower_shades
            - service: script.turn_on
              entity_id:
                - script.lower_shades
              data_template:
                variables:
                  deltaporcento: "{{ ( ( states('sensor.'~shade) ) | int ) - ( position | int ) }}"
                  shade: "{{ shade }}"
            - service: mqtt.publish
              data:
                topic: "void/Shades/Position"
              data_template:
                payload: "{{ position }}"

  lower_shades:
    mode: single
    sequence:
      - service: switch.turn_off
        data_template:
          entity_id: "switch.{{ shade }}"
      - delay:
          milliseconds: 1000
      - service: switch.turn_on
        data_template:
          entity_id: "switch.{{ shade }}_up"
      - delay:
          milliseconds: 1000
      - service: switch.turn_on
        data_template:
          entity_id: "switch.{{ shade }}"
      - delay: 
          milliseconds: "{{ deltaporcento|int * 140 }}" # Takes 14s to close
      - service: switch.turn_off
        data_template:
          entity_id: "switch.{{ shade }}"

  rise_shades:
    mode: single
    sequence:
      - service: switch.turn_off
        data_template:
          entity_id: "switch.{{ shade }}"
      - delay:
          milliseconds: 1000
      - service: switch.turn_off
        data_template:
          entity_id: "switch.{{ shade }}_up"
      - delay:
          milliseconds: 1000
      - service: switch.turn_on
        data_template:
          entity_id: "switch.{{ shade }}"
      - delay: 
          milliseconds: "{{ deltaporcento|int * 150 }}" # Takes 15s to open
      - service: switch.turn_off
        data_template:
          entity_id: "switch.{{ shade }}"
  stop_shades:
  # TODO: treat position on stop_shades
    sequence:
      - service: switch.turn_off
        data_template:
          entity_id: "switch.{{ shade }}"

4 Likes

Hi @petro!
I was trying something similar, but couldn’t figure it out. I wanted to go from this
{% set lc = as_timestamp('states.sensor.xy_linkquality.last_changed') | int %}
to this:

{% set entity = 'xy_linkquality' %}
{% set lc = as_timestamp(states.sensor. ~ entity.last_changed) | int %}

but unfortunately a string doesn’t work in this case with the state object. Is there a way to integrate the variable?

1 Like

you don’t need to cast the int and you just need to access the state object properly

{% set entity = 'xy_linkquality' %}
{% set lc = as_timestamp(states.sensor[entity].last_changed) %}
1 Like

Thank you very much!
May I ask, where is something like using these brackets "[ ]"for variables documented? Couldn’t find anything.
P.S.: the int was useful for my code :slight_smile:

It’s not documented anywhere in HA, it’s documented in Jinja’s docs as this is basic jinja functionality.

https://jinja.palletsprojects.com/en/3.0.x/templates/#variables

1 Like