Simple Lua state file utility.

Moderator: leecollings

Post Reply
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Simple Lua state file utility.

Post 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;
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: Simple Lua state file utility.

Post by dannybloe »

Have you seen this project? I believe *cough coug* it does that and a lot more.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: Simple Lua state file utility.

Post 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.
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: Simple Lua state file utility.

Post 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.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
User avatar
Westcott
Posts: 423
Joined: Tuesday 09 December 2014 17:04
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: UK - Glos
Contact:

Re: Simple Lua state file utility.

Post 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.
Zwave - Sigma Z+ stick, Fibaro, Horstmann, Neo Coolcam, EUROtronic
RFlink - IR detectors and temperatures
Wifi - YeeLights, ESP32s, Anoop sockets
Zigbee - lots with zigbee2mqtt and ZbBridge
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: Simple Lua state file utility.

Post 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 :)
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: Simple Lua state file utility.

Post 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....
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
commodore white
Posts: 63
Joined: Sunday 14 July 2013 11:19
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Ipswich, UK
Contact:

Re: Simple Lua state file utility.

Post 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.
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: Simple Lua state file utility.

Post 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.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest