Persistent data as a variable

Easy to use, 100% Lua-based event scripting framework.
Post Reply
wizzard72
Posts: 69
Joined: Friday 20 December 2013 8:45
Target OS: Raspberry Pi
Domoticz version:
Contact:

Persistent data as a variable

Post by wizzard72 » Thursday 07 December 2017 21:35

I'm building a general script. The script stores persistent data.

In the first part of the script I have defined the persistent data:

Code: Select all

return {	
    active = true,
    logging = {
		level = domoticz.LOG_INFO, -- Uncomment to override the dzVents global logging setting
		marker = 'TEST '
	},
	on = {
		devices  = {
			'Wasmachine (W)',
			'Wasmachine',
			'Slaapkamer Paul Schakelaar',
			'Slaapkamer Paul Schakelaar (W)',
			'Dimmer WC 1ste',
			'Dimmer WC 1ste (W)',
			'Dimmer WC BG',
			'Dimmer WC BG (W)',
			'Espressomachine',
			'Espressomachine (W)'
		},
	},
	data = {
        WattWasmachine = { history = true, maxMinutes = 6 },
        WattSlaapkamerPaulSchakelaar = { history = true, maxMinutes = 10 },
        WattDimmerWC1ste = { history = true, maxMinutes = 10 },
        WattDimmerWCBG = { history = true, maxMinutes = 10 },
        WattEspressomachine = { history = true, maxMinutes = 10 }
    },
The main part of the script contains code to store the actual KwH:
domoticz.data.WattWasmachine.add(sensor.WhActual)

This works. But I want more flexibility.

The part 'WattWasmachine' in 'domoticz.data.WattWasmachine.add(sensor.WhActual)' is the part that changes. So for my 5 persistent data entries I have to create 5 lines of code:

Code: Select all

domoticz.data.WattWasmachine.add(sensor.WhActual)
domoticz.data.WattSlaapkamerPaulSchakelaar.add(sensor.WhActual)
domoticz.data.WattDimmerWC1ste.add(sensor.WhActual)
domoticz.data.WattDimmerWCBG.add(sensor.WhActual)
domoticz.data.WattEspressomachine.add(sensor.WhActual)
I would rather have something like this:

Code: Select all

domoticz.data.persistentdata(WattWasmachine).add(sensor.WhActual)
So 'WattWasmachine' becomes more like a variable. With variables I can do cool stuff. Like:

Code: Select all

WattDevice = "Watt" .. string.gsub(device.name, "%s+", "")
domoticz.data.persistentdata(WattDevice).add(sensor.WhActual)
Is something like this possible? Or over time in a new version?

dannybloe
Posts: 1407
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi
Domoticz version:
Location: Ermelo
Contact:

Re: Persistent data as a variable

Post by dannybloe » Thursday 07 December 2017 21:55

There’s no need actually. Just create a table with all your data and put that in your persistent variable. ...data.myvar.add({ a=1, b=2 })

You can access it like: ...data.myVar.a or data.myVar.b.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.

dannybloe
Posts: 1407
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi
Domoticz version:
Location: Ermelo
Contact:

Re: Persistent data as a variable

Post by dannybloe » Thursday 07 December 2017 22:02

Well, it's not entirely correct what I wrote. You are using historical data so that's a bit different:

Adding:

Code: Select all

domoticz.data.myVar.add({ a=1, b=2, c=3})
Using:

Code: Select all

local latest = domoticz.data.myVar.getLatest()
print(latest.b)
-- update
latest.b = latest.b + 1
domoticz.data.myVar.add( latest ) -- add a new table to the history.
But, you only have one history chain for myVar. Not per item in the table. So if you need the historical data then you do need separate variables.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.

wizzard72
Posts: 69
Joined: Friday 20 December 2013 8:45
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Persistent data as a variable

Post by wizzard72 » Thursday 07 December 2017 23:02

I have a little trouble understanding it.

My code:

Code: Select all

return {	
    active = true,
    logging = {
		level = domoticz.LOG_INFO, -- Uncomment to override the dzVents global logging setting
		marker = 'TEST '
	},
	on = {
		devices  = {
			'Wasmachine (W)',
			'Wasmachine',
			'Slaapkamer Paul Schakelaar',
			'Slaapkamer Paul Schakelaar (W)',
			'Dimmer WC 1ste',
			'Dimmer WC 1ste (W)',
			'Dimmer WC BG',
			'Dimmer WC BG (W)',
			'Espressomachine',
			'Espressomachine (W)'
		},
	},
	data = {
        WattWasmachine = { history = true, maxMinutes = 6 },
        WattSlaapkamerPaulSchakelaar = { history = true, maxMinutes = 10 },
        WattDimmerWC1ste = { history = true, maxMinutes = 10 },
        WattDimmerWCBG = { history = true, maxMinutes = 10 },
        WattEspressomachine = { history = true, maxMinutes = 10 }
    },

	-- actual event code
	-- in case of a timer event or security event, device == nil
	execute = function(domoticz, device)
	    -- Variables to customize ------------------------------------------------

        -- Variables -------------------------------------------------------------
        local CurrentTime = os.time()
        -- Function --------------------------------------------------------------

        -- MAIN ------------------------------------------------------------------
        if (device.state == "On") then
            domoticz.notify("ACTIVATE",device.name .. " activated#I let you know when device " .. device.name .. " is turned off",2,SOUND_SIREN)
        elseif (device.state == "Off") then
            domoticz.notify("DEACTIVATED",device.name .. " is deactivated",2,SOUND_SIREN)
        end
        domoticz.changedDevices().forEach(function(device)
            if (device.name == "Wasmachine (W)") then
                -- Store KwH in persistent data
                domoticz.data.WattWasmachine.add(device.WhActual)
                -- calculate average
                local average = domoticz.data.WattWasmachine.avg()
                -- if last 10 reading Watt is 0, then switchoff the device
                if (average == 0) then
                    domoticz.devices('Wasmachine').switchOff().checkFirst()
                end
            elseif (device.name == "Slaapkamer Paul Schakelaar (W)") then
                -- Store KwH in persistent data
                domoticz.data.WattSlaapkamerPaulSchakelaar.add(device.WhActual)
                -- calculate average
                local average = domoticz.data.WattSlaapkamerPaulSchakelaar.avg()
                -- if last 10 reading Watt is 0, then switchoff the device
                if (average == 0) then
                    domoticz.devices('Slaapkamer Paul Schakelaar').switchOff().checkFirst()
                end
            elseif (device.name == "Dimmer WC 1ste (W)") then
                -- Store KwH in persistent data
                domoticz.data.WattDimmerWC1ste.add(device.WhActual)
                -- calculate average
                local average = domoticz.data.WattDimmerWC1ste.avg()
                -- if last 10 reading Watt is 0, then switchoff the device
                if (average == 0) then
                    domoticz.devices('Dimmer WC 1ste').switchOff().checkFirst()
                end
            elseif (device.name == "Dimmer WC BG (W)") then
                -- Store KwH in persistent data
                domoticz.data.WattDimmerWCBG.add(device.WhActual)
                -- calculate average
                local average = domoticz.data.WattDimmerWCBG.avg()
                -- if last 10 reading Watt is 0, then switchoff the device
                if (average == 0) then
                    domoticz.devices("Dimmer WC BG").switchOff().checkFirst()
                end
            elseif (device.name == "Espressomachine (W)") then
                -- Store KwH in persistent data
                domoticz.data.WattEspressomachine.add(device.WhActual)
                -- calculate average
                local average = domoticz.data.WattEspressomachine.avg()
                -- if last 10 reading Watt is 0, then switchoff the device
                if (average == 0) then
                    domoticz.devices('Espressomachine').switchOff().checkFirst()
                end
		        
            end
        end)

end
}
I want to simplify my code. I have a lot of 'elseif' statements. Every 'elseif' statement is almost the same, except the device/sensor name. My logic says that it can be made easyer :-)

dannybloe
Posts: 1407
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi
Domoticz version:
Location: Ermelo
Contact:

Re: Persistent data as a variable

Post by dannybloe » Friday 08 December 2017 9:46

Ok, here is my simplified version (for dzVents 2.3.0). Couple of comments. You don't have to use the changed devices collection anymore (I'm removing it from the documentation for 2.4.0) as there is always only one device in that collection and that's the device that was changed (second parameter of your execute function). So, I created a lookup table to match the energy device to the switch and made sure the persistent variables exactly match the name of the energy device (and removed some unnecessary code and corrected some errors):

Code: Select all

-- create a lookup table that matches a usage
-- device to the accompanying switch
local USAGE_DEVICES = {
	['Wasmachine (W)'] ='Wasmachine',
	['Slaapkamer Paul Schakelaar (W)']= 'Slaapkamer Paul Schakelaar',
	['Dimmer WC 1ste (W)'] = 'Dimmer WC 1ste',
	['Dimmer WC BG (W)'] = 'Dimmer WC BG',
	['Espressomachine (W)'] = 'Espressomachine'
}

return {
	logging = {
		level = domoticz.LOG_INFO, -- Uncomment to override the dzVents global logging setting
		marker = 'TEST '
	},
	on = {
		devices = {
			'Wasmachine (W)',
			'Wasmachine',
			'Slaapkamer Paul Schakelaar',
			'Slaapkamer Paul Schakelaar (W)',
			'Dimmer WC 1ste',
			'Dimmer WC 1ste (W)',
			'Dimmer WC BG',
			'Dimmer WC BG (W)',
			'Espressomachine',
			'Espressomachine (W)'
		},
	},
	data = { -- use exact device names to match USAGE_DEVICES
		['Wasmachine (W)'] = { history = true, maxMinutes = 6 },
		['Slaapkamer Paul Schakelaar (W)'] = { history = true, maxMinutes = 10 },
		['Dimmer WC 1ste (W)'] = { history = true, maxMinutes = 10 },
		['Dimmer WC BG (W)'] = { history = true, maxMinutes = 10 },
		['Espressomachine (W)'] = { history = true, maxMinutes = 10 }
	},

	execute = function(domoticz, device)
		
		if (USAGE_DEVICES[device.name] ~= nil) then
			-- we have a usage sensor here
			
			local switch = domoticz.devices(USAGE_DEVICES[device.name])
			local history = domoticz.data[device.name]
			
			history.add(device)
			
			if (switch.active and history.avg() == 0) then
			 	switch.switchOff()
			end
			
		else
			-- device is a switch
			if (device.active) then
				domoticz.notify(
					"ACTIVATE", 
					device.name .. " activated#I let you know when device " .. device.name .. " is turned off", 
					domoticz.PRIORITY_EMERGENCY, 
					domoticz.SOUND_SIREN
				)
			else
				domoticz.notify(
					"DEACTIVATED", 
					device.name .. " is deactivated",
					domoticz.PRIORITY_EMERGENCY, 
					domoticz.SOUND_SIREN
				)
			end
		end

	end
}
Disclaimer: this is untested code ;)

Side note: I'm wondering what the logic is for this script. If there's no energy usage for a device in the past 10 minutes isn't the device then also switched off? Or doesn't the switch report back to Domoticz its current state (like a Kaku switch)?
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.

wizzard72
Posts: 69
Joined: Friday 20 December 2013 8:45
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Persistent data as a variable

Post by wizzard72 » Friday 08 December 2017 11:05

Thanks for the simplified version. I'm going to analyse your code.

The purpose of the script is to disable devices that don't use any energy. For example: when my washing machine is finished and it uses 0 watt for 6 minutes, the the device is turned off and I get a message when ready. So I can never forget to hang my clothes to dry. I can't assume that one 0 watt means that the washing machine is finished. Sometimes the machine doesn't do anything, the zwave device measure 0 watt, but its not finished yet. Thats why I want a few minutes 0 watt. Then I know for sure its finished.

dannybloe
Posts: 1407
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi
Domoticz version:
Location: Ermelo
Contact:

Re: Persistent data as a variable

Post by dannybloe » Friday 08 December 2017 11:13

Interesting. I can do the same for my washing machine.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.

wizzard72
Posts: 69
Joined: Friday 20 December 2013 8:45
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Persistent data as a variable

Post by wizzard72 » Friday 08 December 2017 13:11

dannybloe wrote:Interesting. I can do the same for my washing machine.
Glad I could help :-)

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest