Why the heck don't we have global variables?

That would be very nice. I end up using secrets to store constants and be able to have them all on one page. I even use input_text, input numbers, etc so I can use them in templates and set their default value using a Secret.

1 Like

I’ll make a deal with you, we can forget about global variables if you can tell me how to store more than 255 characters and have it survive a restart.

input_text serves as a decent ‘global variable’ because it survives a restart and has a service to set its state. However, it can only store 255 characters which limits its usefulness, especially if you want to store more than one value (like a comma-delimited list of items).

The workaround is to revert to MQTT and publish the data to a topic that’s consumed by an MQTT Sensor’s attributes_template (because, as we all know, attributes don’t have a 255 character limitation). However, that’s a rather long journey to merely store a value (plus the infrastructure of MQTT).

My most recent need involves an automation that restores active timers. Currently it maintains a record of active timers as a comma-delimited list in an input_text (timer name and timestamp). That works to a point until you have more active timers than can fit into 255 characters.

I tried to store the data in an input_select (its options attribute contains a handy python list) and everything looked really good until I realized the options I set aren’t restored after a restart (the original options are used). Too bad because an input_select would make a really nice ‘global list variable’. Each option can hold 255 characters and I don’t know if there’s an upper limit on the number of options but I tried 50 without any complaints.

5 Likes

For me that is a: Yes please. Have a way to manage variables of different types globally. They don’t need to track any state (although a service to change them would be nice).

Currently, I use input_* entities for them, or secrets (while not a secret).

However, once such a thing is created, use for it must be created as well (e.g., easy using in automations and script). So it might be a bit bigger.

But, yeah would love this :+1:

3 Likes

I made a dynamic zone-based notification system that relies on a global array. In the HA front end there are three input_selects in which you select the person, zone, and entering or exiting. Then in an input_text you type the notification you would like to send. With a custom event (fired by pressing a frontend button) you save the information in the inputs as an array entry and clear all of the inputs. Then an automation watches for device_tracker zone changes and sends the notification when the person/zone/position requirements are met. The entry is then removed from the array.

Currently this is only possible in Node Red, because Node Red has a global context in which to store variables.

I’ve used this for the past year and been very happy with it… Just sayin’

I agree with you that setting/getting values is equally important. For the moment, input_text works reasonably well: states() to get and set_value to set plus reload to initialize. Life is good until one bumps into the 255 character ceiling. This can happen when you use an input_text to store comma-delimited lists. However, I do realize this ceiling isn’t likely to be raised any time soon because it has widespread implications.

If an input_text supported attributes and provided a service to set them, well, that would be very useful. However, I’m not sure how that fits into an input_text’s ‘job description’. For simply capturing a user’s input via the UI, you don’t need custom attributes. However, allowing for custom attributes would be a quick and dirty way to improve an input_text usefulness as a ‘global variable’.

As for the input_select, aside from the fact new options are discarded after a restart, it’s impossible to set new options dynamically. Yes, the documentation shows an example of how to set new options “dynamically” with a list but that’s hardly “dynamic”. The list is pre-defined in the automation. To be truly dynamic the list would need to be generated by a template … but Jinja2 can only crank out strings not lists. The workaround is to write a simple python_script that sets the new options … but that’s a step too far for many users.

Ideally, an input_select’s set_options service would accept a comma-delimited string as an argument (and is converted to a list internally). At least then we would have a truly dynamic way of setting options using templates. Of course, this doesn’t address the issue of losing the new options after a restart.

Yeah I’m familiar with that, however, it uses the state engine (it just create entities), which is kinda overkill.

How about just a few things like “input_blob” and “input_list” (think multi select dropdown).
Could just reuse the existing infrastructure for the other inputs

2 Likes

As mentioned above, the problem with input_selects is anything you store in them won’t survive a restart.

I could see this being easily added to the “Helper” UI. It would require a separate entity type.

I never suggested they did. They are only a means to an end.

Not questioning your intentions, just pointing out the fact they don’t make effective global variables because their life ends at the next restart and then they’re reborn with default values on startup. A good global variable can survive a restart (like, for example, an input_text or input_number).

You misunderstood my reply if you think that’s what I was suggesting. The values in the input_selects are all static. The array that they feed is not.

Agree, but in my opinion that is a more like a bug.
The selected value of all inputs should be restored on restart (why the heck are they not? :wink:)

2 Likes

They’re not restored because when you set new options they are not used to change the input_select’s configuration. It’s configuration, as originally defined (be that in configuration.yaml or .storage/core.entity_registry) is what is used to define it on startup. Effectively, the new options you set are not part of the input_select’s default configuration.

What might be a solution is to allow defining an input_select with no options (it disallows that now). The input_select’s new options would be defined dynamically (via the user’s automation) and then Home Assistant would store them along with other values in .storage/core.restore_state (like for input_text, input_boolean, etc). On startup, if an input_select’s configuration contains no options, Home Assistant would refer tocore.restore_state and use whatever options are stored there to configure the input_select. Or something along those lines … because it bends the rules; core.restore_state is for storing entity states and, technically speaking, an input_select’s state is not its list of options.

I’m still struggling why people think they are needed, what problem are they solving exactly? From what I’ve read so far, it is more a WTH on input_* entities. Isn’t more or less everything in home assistant a ‘global variable’?

Can you give a clear example maybe?

Which input_* can you use to store more than 255 characters and the value survives a restart?

I agree that input_* can substitute for global variables but a true global variable:

  • Can have a type other than a string.
  • Isn’t constrained to 255 characters.
  • Survives a restart.
  • Its value can be easily assigned and retrieved (without resorting to the use of python_script).
  • Preferably has no associated Lovelace UI card (i.e. cannot be manually tweaked by a user, only via services).

Nothing I can think of satisfies all these requirements. Either something ought to be invented or an existing input_* enhanced to satisfy most of the requirements. Personally, an input_text supporting custom attributes (and services to set them) would go a long way to meeting all requirements.

As for an example, I mentioned one earlier: to store a list of all active timers. The list is needed on startup to restore all active timers. Currently, I’m using an input_text but 255 characters is a bit too small to handle many timers.

Another use case for me is tracking devices which have no integration. For instance I use tasker to report the location of my car and headphones every time it connects or disconnects from one of those devices via bluetooth. There’s no integration for these so I have to stash the state of these devices in a variable since there are multiple fields to track for devices (location name, latitude, longitude, gps accuracy, other useful data, etc.). Or i can use device_tracker.see but device trackers created that way don’t survive a restart either so its not any better.

Another one I’ve encountered is when trying to write automation to notify me any time there’s a new add-on. Supervisor has an API that returns the list of all currently available add-ons I can poll against but that meant I also had to keep track of my own list of all the add-ons I’d already seen. This way I can diff the two and determine what is new. I resorted to stashing that list in a text file due to the issue described here - HA provides no place to store more then 255 chars of data that survives a restart.

Also tbh, I don’t think @123 has to explain all that much here. Just take a scan through the search results on this forum for rogro82. Rogro82’s hass-variables plugin is the go-to plugin people use to fill this gap and there are tons of posts about people using it or recommending its use. I guess you could make an argument that many of these are workarounds where people are closing gaps in HA’s featureset (like making timers and device trackers survive restarts for instance). That may be true but

a) Not all are
b) HA team has limited time so it would be great to give us this capability in the meantime. If/when they close that gap then we can delete our variable and automation and use OOTB functionality.

1 Like

I have numerous examples in my config, follow the link and CTRL-F “variable”. Generally I use them to store the state of an entity after it has changed. Things that are too irregular or long to store in input booleans or input selects.

There’s also this variable custom component that I maintain (and would be happy to put to rest :sweat:). It has the same inefficiency in that it uses the entity system to store state.

For anyone asking, here’s another use case for storing state: I have an rgb light set to a current rgb value and brightness. I want to flash the light a different color to indicate a notification and then set the light back to its prior setting after the notification has passed. How else to do this but saving the state of the light into some sort of variable?