Store timer values for a bunch of windows/doors (table issue)

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
guenniac
Posts: 23
Joined: Wednesday 27 October 2021 18:13
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Location: Aachen, Germany
Contact:

Store timer values for a bunch of windows/doors (table issue)

Post by guenniac »

Hi,

I'd like to store the open times for my windows/doors. I understood that I need lua tables for this purpose.
The purpose is to remember 'forgotten' open windows/doors. If the timer exceed a TIMEOUT value then an alarm etc should be fired.
I tried this:

Code: Select all

local INTERVAL = 1
local TIMEOUT = 3

local MyDevices = {'Fenster SZ','Tür Balkon OG','Tür Küche','Tür Keller','Testtür'}
local myData = {}
for i,v in ipairs(MyDevices) do
  myData[v] = { initial = 0 } -- put your initial value here if there is one
end


local PROG = 'testArray'

local logToFile = true							-- (Boolean) Set to true if you also wish to log to a file. It might get big by time. 
local tmpLogFile = '/var/log/domoticz/Doors.log'           -- Logging to a file if specified 

return {
    on = {
        devices = MyDevices,
        timer   = {
            'every ' .. INTERVAL .. ' minutes'
        },
    },
	logging = { 
	    level = domoticz.LOG_INFO, 
	    marker = PROG
    },
    data = myData,

	execute = function(dz, item, info)

        local logheader = os.date('%Y-%m-%d %H:%M:%S ',os.time()) .. '-' .. PROG .. '-'
	    if item.isTimer then
            dz.log('is Timer')
            for i,v in pairs(dz.data.myData) do
                logtext = 'i=' .. tostring(i) .. tostring(dz.data.myData[v]) .. ' minutes'
                dz.log(logtext)
                if dz.data.myData[i].state == 'Open' then 
                    if dz.data.myData[v] > TIMEOUT then
                        logtext = 'Alarm: door is open for ' .. tostring(dz.data.myData[v]) .. ' minutes'
                        dz.log(logtext)
                		if logToFile then os.execute('echo ' .. logheader .. logtext .. ' >>' .. tmpLogFile) end
                    else
                        dz.data.myData[v] = dz.data.myData[v] + INTERVAL
                    end
                end
            end
        else
            dz.log('is device ' .. item.name .. ' state=' .. item.state)
            if item.state == 'Open' or item.state == 'On' then 
                dz.log('Door was opened')
            else
                dz.log('Door was closed')
                dz.data.myData[item.name] = 0
            end    
            logtext = ' device=' .. item.name .. ' State= ' .. item.state .. ' ' .. tostring(myData[item.name]) .. ' minutes'
            dz.log(logtext)
    		if logToFile then os.execute('echo ' .. logheader .. logtext .. ' >>' .. tmpLogFile) end
        end
        dz.utils.dumpTable(dz.data.myTable)     

    end
}
Error message is this:
Error: (3.1.7) testArray: ...domoticz/scripts/dzVents/generated_scripts/testArray.lua:34: bad argument #1 to 'pairs' (table expected, got nil)
Line 34 is this:

Code: Select all

            for i,v in pairs(dz.data.myData) do
Can anyone give me a hint?
Raspberry Pi 3B+
Raspbian GNU/Linux 12 (bookworm) / 6.1.61-v7+
Version: 2023.2
Build Hash: 19efd039c
Compile Date: 2023-07-21 17:23:44
dzVents Version: 3.1.8
Python Version: 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0]
guenniac
Posts: 23
Joined: Wednesday 27 October 2021 18:13
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Location: Aachen, Germany
Contact:

Re: Store timer values for a bunch of windows/doors (table issue)

Post by guenniac »

May I ask the experts to look at my example? It seems to be a table issue.

For your convenience I have shrinked the code to the basics.
Maybe this helps.

Code: Select all

local MyDevices = {'Fenster SZ','Tür Balkon OG','Tür Küche','Tür Keller'}
local myData = {}
for i,v in ipairs(MyDevices) do
  myData[v] = { initial = 0 } -- put your initial value here if there is one
end

return {
    on = {
        devices = MyDevices,
        timer   = { 'every minute' },
    },
	logging = { 
	    level = domoticz.LOG_INFO, 
	    marker = 'testArrayV2'
    },
    data = { myData },

	execute = function(dz, item, info)

	    if item.isTimer then
            dz.log('is Timer')
            for i,v in pairs(dz.data.myData) do			<-------------------------------------------------------- error
                logtext = 'i=' .. tostring(i) .. tostring(dz.data.myData[v]) .. ' minutes'
                dz.log(logtext)
           end
        else
            dz.log('is device ' .. item.name .. ' state=' .. item.state)
	        --dz.dump()
            if item.state == 'Open' or item.state == 'On' then 
                dz.log('Door was opened')
            else
                dz.log('Door was closed')
            end    
        end
        dz.utils.dumpTable(dz.data.myData)     

    end
}
Error message:
Error: (3.1.7) testArrayV2: ...moticz/scripts/dzVents/generated_scripts/testArrayV2.lua:22: bad argument #1 to 'pairs' (table expected, got nil)
Raspberry Pi 3B+
Raspbian GNU/Linux 12 (bookworm) / 6.1.61-v7+
Version: 2023.2
Build Hash: 19efd039c
Compile Date: 2023-07-21 17:23:44
dzVents Version: 3.1.8
Python Version: 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0]
User avatar
waltervl
Posts: 5852
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: Store timer values for a bunch of windows/doors (table issue)

Post by waltervl »

I am not an expert but perhaps try to use another initial value like -1 instead of 0 in line

Code: Select all

myData[v] = { initial = 0 }
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
User avatar
waltervl
Posts: 5852
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: Store timer values for a bunch of windows/doors (table issue)

Post by waltervl »

Perhaps try the script that is used in the following topic (has also extra functionality)
viewtopic.php?t=23768
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
guenniac
Posts: 23
Joined: Wednesday 27 October 2021 18:13
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Location: Aachen, Germany
Contact:

Re: Store timer values for a bunch of windows/doors (table issue)

Post by guenniac »

waltervl wrote: Thursday 03 March 2022 16:46 Perhaps try the script that is used in the following topic (has also extra functionality)
viewtopic.php?t=23768
Thanks for the hint.
I used one of these scripts as base and it works. I have to analyze in order to understand why it works and what I did wrong in my approach.
My new code:

Code: Select all

local devicesToCheck = {
--  table with doors to check and the minutes before the first warning is given
	{ ['name'] = 'Fenster SZ', ['threshold'] = 10 },
	{ ['name'] = 'Tür Balkon OG', ['threshold'] = 10 },
	{ ['name'] = 'Tür Keller', ['threshold'] = 2 },
	{ ['name'] = 'Tür Küche', ['threshold'] = 10 },
}
-- number of times you are warned about an open door
local alertCount = 3

return {
	active = true,
	
    on = {
        timer = {'every 5 minutes'},
    },
    logging = {
       level = domoticz.LOG_INFO,
        marker = "POR"
    },    
--  count per door of the number of alerts per door
    data = {
        ['Fenster SZ'] = {initial=0},
        ['Tür Balkon OG'] = {initial=0},
        ['Tür Keller'] = {initial=0},
        ['Tür Küche'] = {initial=0},
        },

	execute = function(domoticz)
		for i, deviceToCheck in pairs(devicesToCheck) do
			local name = deviceToCheck['name']
			local threshold = deviceToCheck['threshold']
			local state = domoticz.devices(name).state
			local minutes = domoticz.devices(name).lastUpdate.minutesAgo
			--domoticz.log('Device ' .. name .. ' status  ' .. state)
			if ( state == 'Open') then 
                domoticz.log('Device ' .. name .. ' steht  ' .. minutes .. ' Minuten offen.')
			    if (minutes > threshold) and (domoticz.data[name] < alertCount) then
                    domoticz.data[name] = domoticz.data[name] + 1
                    domoticz.notify('Tür/Fenster Alarm',
                                     name .. ' steht länger als ' .. minutes .. ' Minuten offen.',
                                     domoticz.PRIORITY_HIGH)
                    domoticz.log('Das ist Meldung ' .. tostring(domoticz.data[name]))
                end
            elseif (domoticz.data[name] > 0) then
                domoticz.notify('Tür/Fenster Alarm',
                                 name .. ' wurde geschlossen.', 
                                 domoticz.PRIORITY_HIGH)
                domoticz.log('Device ' .. name .. ' ist  ' .. minutes .. ' geschlossen.')
			    domoticz.data[name] = 0
			end
		end
	end
}
As soon as I have my original code running I will post it here.
Raspberry Pi 3B+
Raspbian GNU/Linux 12 (bookworm) / 6.1.61-v7+
Version: 2023.2
Build Hash: 19efd039c
Compile Date: 2023-07-21 17:23:44
dzVents Version: 3.1.8
Python Version: 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0]
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest