Do variables persist?

Can I execute LUA code in a scene, set a variable with it, and have that variable’s value persist so I can read it from another scene’s LUA code?

Yes. The variable needs to be declared as global:

local variable:

local = blah blah blah

global variable

= blah blah blah

Scenes and startup LUA code share the same environment, so global variables can be seen from each sides.

But I’m not sure that there is a “global” keyword :
https://www.lua.org/pil/1.2.html

Thanks for the replies.

So, by declaring a variable, it will be global. I would have to use the “local” keyword to PREVENT that behavior (no keyword for global definition). Correct?

yes.

Sometimes, the notation “g_variableName” is used to show that the variable is global.

Couple of other thoughts:

Its a good idea to initialize the global variables in your startup code section. Otherwise, you will need to handle “nil” values in your code.

Also, global variables are lost (reset) whenever Vera reboots, or the LUA engine is reloaded.

To avoid polluting the global space unduly, you might consider simply one global variable, defined in Startup:

g_ember = {
   forty_two = 42,
   my_string = "a useful string",
   -- ...and so on
}

and then simply use in your scenes:

local x = g_ember.number + 1
luup.log (g_ember.my_string)

or more conveniently

local g = g_ember
local x = g.number + 1

Of course, you’re not restricted to the preset values you put in at startup, but can create whatever persistent variables you need whenever you need them

g_ember.new_var = "something else"

Really useful for diagnostics, because if you are using AltUI (and why would you not?) then in Lua Test code the statement

print (pretty(g_ember))

will show you the state of all your globals.

Thanks for the very helpful info. I like the idea of using a singular variable array since it should also require less memory as compared to declaring every variable in its own right.

I do understand the need to initialize them and set them to initial variables and that this has to be done at each restart. What’s the cleanest way to execute some code to initialize these on startup? I have a daily restart for the controller, so it’s important that I re-set these each time it reboots.

Startup LUA (in Apps Section, Develop Apps)
This is run during LUA restart … Globals (NOT LOCALS) are available to LUA in scenes.

You may also want to put all of your code in a .lua module …

See:
http://forum.micasaverde.com/index.php/topic,33226.0.html

That’s actually not the case, but frankly, unless you are doing something quite ludicrous, the memory taken by these variables will be trivial compared to the rest of the system.

What's the cleanest way to execute some code to initialize these on startup? I have a daily restart for the controller, so it's important that I re-set these each time it reboots.

As Richard said, the Starup Lua is the place, and that example I gave for the [tt]g_ember[/tt] variable was exactly the type of initialisation you’d need.

[quote=“RichardTSchaefer, post:9, topic:192759”]Startup LUA (in Apps Section, Develop Apps)
This is run during LUA restart … Globals (NOT LOCALS) are available to LUA in scenes.

You may also want to put all of your code in a .lua module …

See:
http://forum.micasaverde.com/index.php/topic,33226.0.html[/quote]

Richard,

What is the variable_watch indicative of? Is that a way to watch for a variable’s value to change and then take action when it does? Sort of like using a variable being set to a value as a trigger for a scene? Or, am I completely missing the premise?

Yes, luup.variable_watch acts as you anticipated.
But you can’t trigger a scene with it, at least directly.

I’ve made some really good progress with this, but I’ve hit a small issue.

Is there a way for me to write variable information to disk / read variable information from disk? I need a way for variables to persist controller and even LUA restarts.

Thats what device variables are for.

Hmmm.

So, instead of using global variables, instantiate a local variable, read the value from the device, if I change it, write the updated value back to the device.

Yep,
Typically on startup read from Device Variable and save to a Global.

When you need to update it, if it changes, write the device variable and update the global variable.
Access the Global variable as you do now.

Why wouldn’t I just read the variables directly when I need them and write to them when they need to change?

You can … but it’s lower overhead to store the variable as a global instead of reading it every time.

You also need the Global to check to see if the value changes … Writes are very expensive, you do not want to write the same value to the device variable.

Understood.

I supposed I should change it “now”, before I get too much LUA written into the scenes. :slight_smile:

[quote=“akbooer, post:7, topic:192759”]Really useful for diagnostics, because if you are using AltUI (and why would you not?) then in Lua Test code the statement

print (pretty(g_ember))

will show you the state of all your globals.[/quote]

Does this ONLY work in AltUI? It certainly doesn’t seem to do anything but throw an error in the standard UI.