How to use variables in HA

You initially defined devo_annaffiare as a global variable within action.

  action:
    - variables:
        devo_annaffiare: "{{false}}"

In the choose you defined a local variable with the same name:

          sequence:
            - variables:
                devo_annaffiare: "{{ true }}"

You thought you were assigning a new value to the global devo_annaffiare but you didn’t. You defined a new local variable; it doesn’t exist outside of the sequence where it was defined.

Regarding your automation, I believe it may be possible to reduce its complexity. Can you tell me more about sensor.oggi_e_adesso? Does it simply report the current time, date, month, etc? Because if that’s what it does then you can use now() to get the same information more conveniently.

2 Likes

Thanks for your attention.

The creation of the variable devo_annaffiare initially defined on false serves to establish whether, at the end of all the processing choose, the pump should turn on or not

Sure I can!
But at each command you choose that will manage the automation there will be a pump start command, a situation that I wanted to avoid if only for a matter of “elegance” of the code!

I don’t understand (but it’s my problem!)
What is the use of having a variable if you cannot modify its value or use it within the script?

Or maybe what you want to tell me is that I got the syntax of some command wrong?

Here:

I often see models that make use of the now () function shared on the Facebook Home Assistant Italy group and on the official Home Assistant Forum.
. In practice, nothing changes, it is still possible to obtain a customized format, but it must be considered that models of that type are updated every minute.

Surely it is irrelevant in terms of resources used for Home Assistant to update a sensor every minute, but conceptually why do it when we know that the sensor value will not change for 24 hours? Query the value of the sensor.date sensor
and then process it with the timestamp functions
instead, it will ensure that the model is recalculated only at midnight every day, without giving the Home Assistant unnecessary work.

I started like this …

Instead of what home assisant calls variables, is helpers the correct way to store data like this?

No, what I told you is that variables have a scope. You thought you could change the value of a global variable by redefining it with a local variable but you can’t. The scope of a variable defined within a choose statement is not global so it can’t change the value of a variable that was defined outside of of the choose statement.

None of that reasoning applies to the use of now() in an automation’s action. The templates in action are evaluated only when action is processed.

That reasoning applies to the Template integration.

Reference: Template integration - Rate Limiting Updates

I examined your automation and discovered it sends a notification only when tipo_mese is Freddo, not when it’s Caldo. I don’t know if that’s what you intended but here’s a streamlined version that does the same thing. It sends a notification at 08:00 on Monday, Friday, and Sunday but only in the months of January to April and October to December.

- id: "006"
  alias: "GIARDINAGGIO - Routine di irrigazione perimetrale sul lastrico solare"
  description: "Routine di irrigazione perimetrale sul lastrico solare"
  mode: single
  trigger:
    - platform: time
      at: '08:00'
  condition:
    - "{{ now().month in [1, 2, 3, 4, 10, 11, 12] }}"
    - "{{ now().isoweekday() in [1, 5, 7] }}"
  action:
    - service: notify.mobile_app_cellulare_claudio
      data:
        title: "PROVA"
        message: >
          Siamo nel mese di {{state_attr('sensor.oggi_e_adesso', 'mese_lettere')}} che viene da me considerato Freddo.

Of course, automation is still in its infancy …
As I get it to work it will evolve …
Let’s see’

action:
    - variables:
        devo_annaffiare: "{{ true }}"
        tipo_mese: >
          {% set mese =
            [
              {'mese': 'Gennaio', 'considera_come': 'Freddo'},
              {'mese': 'Febbraio', 'considera_come': 'Freddo'},
              {'mese': 'Marzo', 'considera_come': 'Freddo'},
              {'mese': 'Aprile', 'considera_come': 'Freddo'},
              {'mese': 'Maggio', 'considera_come': 'Caldo'},
              {'mese': 'Giugno', 'considera_come': 'Caldo'},
              {'mese': 'Luglio', 'considera_come': 'Caldo'},
              {'mese': 'Agosto', 'considera_come': 'Caldo'},
              {'mese': 'Settembre', 'considera_come': 'Caldo'},
              {'mese': 'Ottobre', 'considera_come': 'Freddo'},
              {'mese': 'Novembre', 'considera_come': 'Freddo'},
              {'mese': 'Dicembre', 'considera_come': 'Freddo'}
            ]
          %}
          {{mese | selectattr('mese', 'eq', states['sensor.oggi_e_adesso'].attributes.mese_lettere) | map(attribute='considera_come') | first}}
    - choose:
        - conditions:
            and:
              # DA OTT AD APR
              - condition: template
                value_template: "{{tipo_mese == 'Freddo'}}"
              # 3 irrigazioni alla settimana
              - condition: template
                value_template: "{{ states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Mercoledì' or states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Venerdì' or states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Domenica'}}"
          sequence:
            - service: notify.mobile_app_cellulare_claudio
              data:
                title: "PROVA"
                message: "{{ devo_annaffiare}} Siamo nel mese di {{states['sensor.oggi_e_adesso'].attributes.mese_lettere}} che viene da me considerato {{tipo_mese}}."
  

devo_annaffiare is a global variable and, as it is textual, is displayed in the sent message.

  action:
    - variables:
        tipo_mese: >
          {% set mese =
            [
              {'mese': 'Gennaio', 'considera_come': 'Freddo'},
              {'mese': 'Febbraio', 'considera_come': 'Freddo'},
              {'mese': 'Marzo', 'considera_come': 'Freddo'},
              {'mese': 'Aprile', 'considera_come': 'Freddo'},
              {'mese': 'Maggio', 'considera_come': 'Caldo'},
              {'mese': 'Giugno', 'considera_come': 'Caldo'},
              {'mese': 'Luglio', 'considera_come': 'Caldo'},
              {'mese': 'Agosto', 'considera_come': 'Caldo'},
              {'mese': 'Settembre', 'considera_come': 'Caldo'},
              {'mese': 'Ottobre', 'considera_come': 'Freddo'},
              {'mese': 'Novembre', 'considera_come': 'Freddo'},
              {'mese': 'Dicembre', 'considera_come': 'Freddo'}
            ]
          %}
          {{mese | selectattr('mese', 'eq', states['sensor.oggi_e_adesso'].attributes.mese_lettere) | map(attribute='considera_come') | first}}
    - choose:
        - conditions:
            and:
              # DA OTT AD APR
              - condition: template
                value_template: "{{tipo_mese == 'Freddo'}}"
              # 3 irrigazioni alla settimana
              - condition: template
                value_template: "{{ states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Mercoledì' or states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Venerdì' or states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Domenica'}}"
          sequence:
            - variables:
                devo_annaffiare: "{{ true }}"
            - service: notify.mobile_app_cellulare_claudio
              data:
                title: "PROVA"
                message: "{{ devo_annaffiare}} Siamo nel mese di {{states['sensor.oggi_e_adesso'].attributes.mese_lettere}} che viene da me considerato {{tipo_mese}}."

devo_annaffiare is a local variable and, as it is textual, is displayed in the sent message.

  action:
    - variables:
        tipo_mese: >
          {% set mese =
            [
              {'mese': 'Gennaio', 'considera_come': 'Freddo'},
              {'mese': 'Febbraio', 'considera_come': 'Freddo'},
              {'mese': 'Marzo', 'considera_come': 'Freddo'},
              {'mese': 'Aprile', 'considera_come': 'Freddo'},
              {'mese': 'Maggio', 'considera_come': 'Caldo'},
              {'mese': 'Giugno', 'considera_come': 'Caldo'},
              {'mese': 'Luglio', 'considera_come': 'Caldo'},
              {'mese': 'Agosto', 'considera_come': 'Caldo'},
              {'mese': 'Settembre', 'considera_come': 'Caldo'},
              {'mese': 'Ottobre', 'considera_come': 'Freddo'},
              {'mese': 'Novembre', 'considera_come': 'Freddo'},
              {'mese': 'Dicembre', 'considera_come': 'Freddo'}
            ]
          %}
          {{mese | selectattr('mese', 'eq', states['sensor.oggi_e_adesso'].attributes.mese_lettere) | map(attribute='considera_come') | first}}
    - choose:
        - conditions:
            and:
              # DA OTT AD APR
              - condition: template
                value_template: "{{tipo_mese == 'Freddo'}}"
              # 3 irrigazioni alla settimana
              - condition: template
                value_template: "{{ states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Mercoledì' or states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Venerdì' or states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Domenica'}}"
          sequence:
            - variables:
                devo_annaffiare: "{{ true }}"
            - if:
                - condition: template
                  value_template: "{{ devo_annaffiare == true }}"
              then:
                - service: notify.mobile_app_cellulare_claudio
                  data:
                    title: "PROVA"
                    message: "{{ devo_annaffiare}} Siamo nel mese di {{states['sensor.oggi_e_adesso'].attributes.mese_lettere}} che viene da me considerato {{tipo_mese}}."

devo_annaffiare is a local variable and the message is sent.

  action:
    - variables:
        devo_annaffiare: "{{ true }}"
        tipo_mese: >
          {% set mese =
            [
              {'mese': 'Gennaio', 'considera_come': 'Freddo'},
              {'mese': 'Febbraio', 'considera_come': 'Freddo'},
              {'mese': 'Marzo', 'considera_come': 'Freddo'},
              {'mese': 'Aprile', 'considera_come': 'Freddo'},
              {'mese': 'Maggio', 'considera_come': 'Caldo'},
              {'mese': 'Giugno', 'considera_come': 'Caldo'},
              {'mese': 'Luglio', 'considera_come': 'Caldo'},
              {'mese': 'Agosto', 'considera_come': 'Caldo'},
              {'mese': 'Settembre', 'considera_come': 'Caldo'},
              {'mese': 'Ottobre', 'considera_come': 'Freddo'},
              {'mese': 'Novembre', 'considera_come': 'Freddo'},
              {'mese': 'Dicembre', 'considera_come': 'Freddo'}
            ]
          %}
          {{mese | selectattr('mese', 'eq', states['sensor.oggi_e_adesso'].attributes.mese_lettere) | map(attribute='considera_come') | first}}
    - choose:
        - conditions:
            and:
              # DA OTT AD APR
              - condition: template
                value_template: "{{tipo_mese == 'Freddo'}}"
              # 3 irrigazioni alla settimana
              - condition: template
                value_template: "{{ states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Mercoledì' or states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Venerdì' or states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Domenica'}}"
          sequence: []
    # MANDA NOTIFICA
    - if:
        - condition: template
          value_template: "{{ devo_annaffiare == true }}"
      then:
        - service: notify.mobile_app_cellulare_claudio
          data:
            title: "PROVA"
            message: "{{devo_annaffiare}} Siamo nel mese di {{states['sensor.oggi_e_adesso'].attributes.mese_lettere}} che viene da me considerato {{tipo_mese}}."

devo_annaffiare is a global variable and the message is sent.

  action:
    - variables:
        tipo_mese: >
          {% set mese =
            [
              {'mese': 'Gennaio', 'considera_come': 'Freddo'},
              {'mese': 'Febbraio', 'considera_come': 'Freddo'},
              {'mese': 'Marzo', 'considera_come': 'Freddo'},
              {'mese': 'Aprile', 'considera_come': 'Freddo'},
              {'mese': 'Maggio', 'considera_come': 'Caldo'},
              {'mese': 'Giugno', 'considera_come': 'Caldo'},
              {'mese': 'Luglio', 'considera_come': 'Caldo'},
              {'mese': 'Agosto', 'considera_come': 'Caldo'},
              {'mese': 'Settembre', 'considera_come': 'Caldo'},
              {'mese': 'Ottobre', 'considera_come': 'Freddo'},
              {'mese': 'Novembre', 'considera_come': 'Freddo'},
              {'mese': 'Dicembre', 'considera_come': 'Freddo'}
            ]
          %}
          {{mese | selectattr('mese', 'eq', states['sensor.oggi_e_adesso'].attributes.mese_lettere) | map(attribute='considera_come') | first}}
    - choose:
        - conditions:
            and:
              # DA OTT AD APR
              - condition: template
                value_template: "{{tipo_mese == 'Freddo'}}"
              # 3 irrigazioni alla settimana
              - condition: template
                value_template: "{{ states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Mercoledì' or states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Venerdì' or states['sensor.oggi_e_adesso'].attributes.giorno_della_settimana == 'Domenica'}}"
          sequence:
            - variables:
                devo_annaffiare: "{{ true }}"
    # MANDA NOTIFICA
    - if:
        - condition: template
          value_template: "{{ devo_annaffiare == true }}"
      then:
        - service: notify.mobile_app_cellulare_claudio
          data:
            title: "PROVA"
            message: "{{devo_annaffiare}} Siamo nel mese di {{states['sensor.oggi_e_adesso'].attributes.mese_lettere}} che viene da me considerato {{tipo_mese}}."

devo_annaffiare is a local variable and the message isn’t sent.

I’m afraid I’ll end up using helpers.
I wanted to avoid it because they are entities that are added to those that must necessarily be in HA.
To ultimately do such a trivial task.
I don’t see other solutions … at least within my reach

1 Like

It is a trivial task but, respectfully, you have chosen a needlessly complicated way of achieving it.

Respectfully, the automation is already awkwardly structured (and reliant on an incorrect use of variables) so further enhancements are likely to make it even more of a mess. For example, you’ve already mentioned adding helpers to what is already far more code than is needed.

The example I presented does the same thing without errors, far less fuss, and it can easily be enhanced to do more. However, if you enjoy creating overly complicated automations, then I can understand why you don’t want to use it.

Good luck.

Helpers aren’t needed unless the data produced by this automation is needed by another automation (or script). The example Pico1965 presented creates data that is referenced exclusively within the automation so a helper isn’t needed. In fact, as I demonstrated in the example I posted above, it doesn’t even need a variable to achieve the desired result.

I’m sorry I gave you the impression of the pedantic.
Your automation does exactly the same thing as mine, certainly more efficiently.
That is, it lights up in the cold months in the established period.
However, there are the warm months and, in them, those in which the temperature exceeds 30 ° C.
There are rains and winds to manage …
All events that I believe should be managed in the action section of the automation.
For this reason I used choose and I started from the simplest case.
I realized, however, that at the end of the choose … checks you have to turn on the pump with the appropriate commands.
And so on to the next choose and the following ones.
I’m sure HA won’t go to the unions for this repetitive job.
I therefore wondered if it was possible to manage the routine in such a way as to use only one pump control at the end of the automation. The “elegance of the code” I was talking about with the friend above.
I remember that in cases like these 40 years ago, support variables were used.
Thanks to your advice I learned that the use of variables in this application is very … residual.
Think … if I had copied some automation here and there on the web I would have had working code that I would not understand anything about.
I also understand that for people like you who handle the code on a daily basis, the word I have represented for you is made of goat’s wool.
You must also understand that for me (or someone like me, if you prefer) the last (trivial) automation I did dates back to about 6 months ago.
This is why every time I decide to develop automation, it’s like starting over. At my age, memory is not at its all-time high.
I share what you wrote in the previous post. I will put a pump command for each choose.
I thank you again for the time you gave me and I hope this post will be of help to other patrons of this community.

We offer examples that are based on the requirements you present, not on the ones you haven’t shared with us.

If you have more requirements, describe them in detail and we can suggest the best solution. What you have described regarding temperature, rain, wind, etc is too vague and requires elaboration.

Maybe, it all depends on the requirements.

Yes, I think so. I recently wrote an automation to schedule radiator thermostats that is a kind of state machine requiring several persistent variables. For example it turns off the heating if you open a window; when you close the window it reverts to the previous manual or scheduled setting, depending what preceded the suspension of heating. I use helpers input_text, input_number and input_datetime. Within an automation, they are set using the appropriate service: input_text:set, input_number:set and input_datetime:datetime. Timers are also a type of global variable.

Helpers have the advantages that they are persistent over a reboot and you can easily add them to dashboards. Disadvantages are that there is no way to stop a user overwriting them in a dashboard, and no way to generate them in a blueprint (you have to create them all by hand for every instance of the blueprint, then identify them to the blueprint when it is invoked).

My suggestion is to make feature requests for
a) global variables that can only be read and written by automations or scripts: global_text, global_number, global_datetime etc.
b) a way of declaring instances of them within the setup of a blueprint, perhaps so that they appear as attributes to the automation entity?

2 Likes

6 posts were split to a new topic: Having issues trying to use a variables, coming from OpenHab

Hi Andy. Just noticed your topic here. Hope it’s not too late for some useful response. You may well already have discovered these things… in which case, my apologies.
You say:

My understanding is that the Helpers now have a Visible option. Select the helper, then its Setting cogwheel and set Visible at the bottom to yes/no. It says “Hidden entities will not be shown on your dashboard or included when indirectly referenced (ie via an area or device). Their history is still tracked and you can still interact with them with services.”
Also, I believe the Helpers can be created in YAML, though the preferred way is via the UI.

Re your feature requests for Variables - yes, several others before and I also have expressed the same arguements. The lack of Variables (except in specific places) and that can be updated within scripts is a pain. See also
https://community.home-assistant.io/t/global-variables-long-lived-variables-in-automations/513746
and
https://community.home-assistant.io/t/how-declare-a-proxy-variable-in-ha/604432/7 where @kameo4242 gives some useful ideas. Thus far I’ve stuck with input_xxx helpers for ‘global’ variables.
You can also pass “Fields” (aka parameters) to scripts and load (your own) Events with your data for Automations to consume, which both have some uses.

1 Like

Don’t forget about trigger-based template sensors as a way to store variables. Here s a particularly slick way of using one sensor for all your variables:

1 Like

Never too late!

My solution uses helpers that are generated in yaml because I need a lot – 12 for each for each automation (defined by a blueprint), and there are 23 of those in my latest implementation. Doing this by hand would be very tedious! I generate the yaml using Microsoft Mall Merge.

Thanks for pointing out the visible option. That could be useful. but I did not yet find any documentation on how to make a variable invisible in yaml. They are visible by default. See for example https://www.home-assistant.io/integrations/input_text/

These are (as I think you are saying) the only variables that are truly variable! ‘Local variables’ defined in scripts or automations, and fields used to pass parameters to scripts are actually constants (!) – you can only set them once.

There are two types of variable available in HACS, but as far as I can see they have no advantage over the built-in helpers.
https://github.com/snarky-snark/home-assistant-variables
https://github.com/rogro82/hass-variables

I also see no advantage in using template trigger sensors as variables, unless they have to be hidden from the UI.

All the above workarounds are essentially the same: you use YAML to define the variables, a service to set the value and a template to read it.

My objections are that I have to both generate all these (12 x 23) variables separately, then tell the blueprint each time I use it which ones they are – that’s 12 extra blueprint parameters I should not need.

What I would like to do is define the 12 global variables that I need within the blueprint, then have the automation generate the 12 global variable entities each time the blueprint is used (by concatenating the name of the automation with the internal name of the variable). I want to choose whether or not they are made visible outside the automation. This method would be less work, less error-prone (linking the wrong variable to the automation) and easier to maintain (if you change the variables now, you have to edit all the automations).

This idea is not new – it is a.k.a. “object-oriented programming” – it just has not yet arrived in HA yet…

Use MQTT discovery to generate the entities…
This one I wrote generates 9 entities.
HA_Blueprints/Automations/Octoprint_Additional_Buttons_Helper.yaml at 695ce9906cbab1101a38dac91f7af5c32499f536 · SirGoodenough/HA_Blueprints · GitHub.
The customer (user of the BP) doesn’t have to create anything.

Plus there is this, vote it up.

for what it’s worth (and on an old thread to boot…) I use if/then logic in template sensors for stuff like this then refer to the sensor in whatever automation or script I want - in a sense it’s a way to make HA a bit modular. I think OPs original complex use case could be more easily managed and tested as a sensor, then automation would simply either run on a schedule, or be triggered by any change to the sensor itself to perform an action.

That certainly works, but if you are trying to package up a blueprint and have everything self-contained for the user to turn on, my way works better.

I dont know why no one is telling you this, but you can actually use global variables in jinja by explicitly defining the scope:

{%- set g = namespace(test_var = 1) %}
{{ g.test_var }}
{% some for loop %}
{% set g.test_var = g.test_var + 1 %}
{% endfor %}
{{ g.test_var }}

And that’s not the scope issues that OP was running into. namespace only solves scoping issues inside a single template. OP was attempting to use variables defined in action sections that were not in scope of the action section they were in.