Page 1 of 1
Simple Lua state file utility.
Posted: Sunday 20 March 2016 18:49
by Westcott
Here's a simple Lua state file utility.
It uses JSON.lua to en/decode the actual file, so that special characters are handled correctly.
To do wish list -
- How to handle Get() for a new state - it has to be Set() first.
Is there a way to auto-close?
Load from built-in editor.
Usage in a Lua file -
Code: Select all
commandArray = {}
package.path = '/home/pi/domoticz/scripts/lua/?.lua;' .. package.path
STATE = require("STATE")
...
value = STATE.Get(stateName)
...
STATE.Set(stateName, value)
...
STATE.Close()
return commandArray
Code is saved in a file called (/home/pi/domoticz/scripts/lua) STATE.lua -
Code: Select all
local State = {};
local opened
local write
local states
function Open()
if not JSON then
-- print("STATE: Loading JSON")
JSON = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
end
file = io.open("state.txt", "r")
json_text = file:read()
states = JSON:decode(json_text)
-- print("STATE: opened")
opened = 1
return states
end
function State.Get(key)
if not opened then Open() end
return states[key]
end
function State.Set(key, value)
if not opened then Open() end
states[key] = value
write = 1
end
function State.Close()
if write then
json_text = JSON:encode(states)
file = io.open("state.txt", "w")
file:write(json_text)
file:close()
-- print("STATE: closed")
end
end
return State;
Re: Simple Lua state file utility.
Posted: Tuesday 22 March 2016 22:04
by dannybloe
Have you seen
this project? I believe *cough coug* it does that and a lot more.
Re: Simple Lua state file utility.
Posted: Wednesday 23 March 2016 0:03
by Westcott
Hi DannyBloe,
Yes, I have been following your project with great interest, and would have loved to use it.
However, I had already written a load of classic Lua, all using a common include file of utilities.
This code was written to hold multiple states between Lua runs, without using lots of user variables, or dummy devices.
Using Json to de/encode the values allows each key to hold nested table data if required.
I'll be using it to hold tables of room temperature histories to predictively turn the heating on and off as rooms cool or warm.
Re: Simple Lua state file utility.
Posted: Wednesday 23 March 2016 12:16
by dannybloe
Ah, I know what you mean. That's exactly on my list as the next feature of dzVents: an easy to use persistent storage for every script including support for automatic history management:
Code: Select all
return {
active = true,
on = { 'bathroomSensor' },
state = {
previousTemperature = { type='string' },
heatingProgram = { type='number' },
bathroomHistory = {
type='history', -- automatically store device attributes in a history list
device='bathroomSensor',
attributes={'temperature', 'humidity'}
maxHistoryItems = 40 -- only store the last 40 states
},
outsideTempHistory = {
type='history',
device='outsideTemperature',
attributes={'temperature'}
maxHistoryItems = 10
}
},
execute = function(domoticz, device, state)
avgT = state.bathroomHistory.average('tempareture')
avgH = state.bathroomHistory.average('tempareture')
max = state.bathroomHistory.max('humidity', 10) -- max over the past 10 stored values
if (state.previousTemperature < 20) then
state.heatingProgram = 5
end
end
}
Just an idea. And of course all these states will be persisted for the next time the script is run.
Re: Simple Lua state file utility.
Posted: Wednesday 23 March 2016 12:54
by Westcott
I like that, especially the maxHistoryItems property.
Can I suggest a maxHistoryTime as well?
Feel free to use any of my code if it helps.
I've hacked it a bit to auto-open the state file, and some more error checking.
Re: Simple Lua state file utility.
Posted: Wednesday 23 March 2016 13:27
by dannybloe
It is totally still an idea. But I was thinking of indeed using json as sort of 'sidecar' files for each script where the snapshot for this state set is stored in.
First I have to get a stable 1.0 release and then I will make this. I'll get to you then perhaps

Re: Simple Lua state file utility.
Posted: Friday 25 March 2016 10:50
by dannybloe
I did some programming and persistent storage per script and global (! over all scripts so no need for uservariables at all now) works in my testing environment (no History classes just yet). I didn't use json for serialization but I serialize it directly to Lua requirable modules to the filesystem so I can load the persisted state using internal Lua functionality (require) which is always much faster than interpreted json parsers. I assume the require method is written in C/native.
So far so good....
Re: Simple Lua state file utility.
Posted: Friday 25 March 2016 21:01
by commodore white
I put my persistent storage system together with the primary requirement of trying to restore a secure state across systems reboots. For example, I didnt want the system to go down with secuity enabled only to have an insecure and inconsistent state on reboot.
In your example, Danny, I'm not sure how I could use a system if things like temperature were restored. In my book there'd have to some "undefined" state so I'd know continuity was lost. I don't really want to re-enter a state that was saved when it was night and start doing night time things if the system was restored in the day.
Never did square that circle.
Re: Simple Lua state file utility.
Posted: Friday 25 March 2016 21:20
by dannybloe
I'm not sure if I understand what you mean. I use persistence mostly to have historical state available like what the previous humidity reading was or what the rise in temperature is over the past few samples or what the target humidity for when I can turn off the ventilator in my bathroom. Right now I have loads of 'uservariables' storing al this information. With dzVents I can do something like this in my scripts(when I'm finished):
Code: Select all
....
-- get minimal temperature over the past 5 measurements
min = domoticz.storage.temperatures.getMin(5)
-- get the rise in temperature over the past 10 samples
delta = domoticz.storage.temperatures.getDeltaSamples(1, 10)
-- or get highest temperature in the past 120 minutes
highest = domoticz.storage.temparatures.getMaxSinceMinutes(120)
if (domoticz.globalStorage.dehumProgramActive and device.humidity >= domoticz.storage.targetHumidity) then
domoticz.devices['Ventilator'].switchOff()
domoticz.globalStorage.dehumProgramActive = false
end
-- store a new value
domoticz.storage.temperatures.store(myDevice.temperature)
....
just some ideas. Have to come up with the best syntax etc.