Page 1 of 1
a sorted table
Posted: Wednesday 16 November 2022 16:17
by pipiche
I'm struggling to implement a generic dzVent script to regulate my heating.
For that I'm planning to use a table with different parameter and a week and weekend schedule.
Here is an exemple.
Code: Select all
["Sdb"] = {
["Setpoint"] = "BT Sdb ThermoSetpoint",
["Motion"] = "Motion Sdb",
["Week_Planning"] = { ["07:30"] = "Confort", ["09:00"] = "Eco", ["12:00"] = "Confort", ["14:00"] = "Eco", ["18:00"] = "Confort", ["21:00"] = "Eco" },
["WeekEnd_planning"] = { ["09:00"] = "Confort", ["21:00"] = "Eco" },
}
My issue is when scrolling the "Week_Planning" entry , the items or not listed in the same order as they are presented here.
Why I need to have this order, is because I'm trying to identify in which period am I based on the current time. But as the items are coming in a different order, I cannot.
Any idea how I should process ?
Re: a sorted table
Posted: Wednesday 16 November 2022 17:03
by waltervl
Re: a sorted table
Posted: Wednesday 16 November 2022 18:38
by pipiche
So did I , but this seems not working as expected
Code: Select all
local function sort_compare( _t1 , _t2 )
local n_t1 = tonumber( string.sub(_t1,4)) + ( tonumber( string.sub(_t1,1,2)) * 3600 )
local n_t2 = tonumber( string.sub(_t2,4)) + ( tonumber( string.sub(_t2,1,2)) * 3600 )
return n_t1 < n_t2
end
Code: Select all
if key == "Week_Planning" and not isWeekEnd( now ) then
table.sort( attribute , sort_compare)
for timeslot, setpoint in pairs( attribute) do
-- hh:mm
if isCurrentTimeAfter( 00, string.sub(timeslot,4) , string.sub(timeslot,1,2) ) then
target_temperature = setpoint
-- dz.log( " Now >= " .. timeslot .. " Setpoint " .. setpoint)
end
-- dz.log(" --> " .. now.time .. ' versus ' .. string.sub(timeslot,1,2) .. ':' .. string.sub(t
end
Re: a sorted table
Posted: Wednesday 16 November 2022 19:40
by pipiche
Did further investigation, and this looks totally random
here is the lua script
Code: Select all
local SCRIPT_NAME = 'Testing table'
local ROOM = { ["07:30"] = "Confort", ["21:00"] = "Eco" }
return {
active = true,
on = {
timer = { 'every 1 minutes' },
},
logging = {
level = domoticz.LOG_INFO,
marker = SCRIPT_NAME,
},
execute = function(dz, item)
-- use to sort the Planning table
local function sort_compare( _t1 , _t2 )
local n_t1 = tonumber( string.sub(_t1,4)) + ( tonumber( string.sub(_t1,1,2)) * 3600 )
local n_t2 = tonumber( string.sub(_t2,4)) + ( tonumber( string.sub(_t2,1,2)) * 3600 )
return n_t1 < n_t2
end
local attribute = ROOM
dz.log( "sort_compare " ..tostring( sort_compare( "07:30", "21:00" )))
table.sort( attribute , sort_compare)
for k,v in pairs( attribute ) do
dz.log( "Key: " .. k .. " Value: " .. tostring(v) )
end
end
}
here are the results
Nov 16 19:37:00 pi3 domoticz[27398]: 2022-11-16 19:37:00.519 Status: dzVents: Info: Testing table: ------ Start external script: testing-table.lua:, trigger: "every 1 minutes"
Nov 16 19:37:00 pi3 domoticz[27398]: 2022-11-16 19:37:00.520 Status: dzVents: Info: Testing table: sort_compare true
Nov 16 19:37:00 pi3 domoticz[27398]: 2022-11-16 19:37:00.520 Status: dzVents: Info: Testing table: Key: 07:30 Value: Confort
Nov 16 19:37:00 pi3 domoticz[27398]: 2022-11-16 19:37:00.520 Status: dzVents: Info: Testing table: Key: 21:00 Value: Eco
Nov 16 19:37:00 pi3 domoticz[27398]: 2022-11-16 19:37:00.520 Status: dzVents: Info: Testing table: ------ Finished testing-table.lua
Nov 16 19:38:00 pi3 domoticz[27398]: 2022-11-16 19:38:00.502 Status: dzVents: Info: Testing table: ------ Start external script: testing-table.lua:, trigger: "every 1 minutes"
Nov 16 19:38:00 pi3 domoticz[27398]: 2022-11-16 19:38:00.502 Status: dzVents: Info: Testing table: sort_compare true
Nov 16 19:38:00 pi3 domoticz[27398]: 2022-11-16 19:38:00.502 Status: dzVents: Info: Testing table: Key: 21:00 Value: Eco
Nov 16 19:38:00 pi3 domoticz[27398]: 2022-11-16 19:38:00.502 Status: dzVents: Info: Testing table: Key: 07:30 Value: Confort
Nov 16 19:38:00 pi3 domoticz[27398]: 2022-11-16 19:38:00.502 Status: dzVents: Info: Testing table: ------ Finished testing-table.lua
Nov 16 19:39:00 pi3 domoticz[27398]: 2022-11-16 19:39:00.536 Status: dzVents: Info: Testing table: ------ Start external script: testing-table.lua:, trigger: "every 1 minutes"
Nov 16 19:39:00 pi3 domoticz[27398]: 2022-11-16 19:39:00.536 Status: dzVents: Info: Testing table: sort_compare true
Nov 16 19:39:00 pi3 domoticz[27398]: 2022-11-16 19:39:00.536 Status: dzVents: Info: Testing table: Key: 07:30 Value: Confort
Nov 16 19:39:00 pi3 domoticz[27398]: 2022-11-16 19:39:00.536 Status: dzVents: Info: Testing table: Key: 21:00 Value: Eco
Nov 16 19:39:00 pi3 domoticz[27398]: 2022-11-16 19:39:00.536 Status: dzVents: Info: Testing table: ------ Finished testing-table.lua
Nov 16 19:40:00 pi3 domoticz[27398]: 2022-11-16 19:40:00.573 Status: dzVents: Info: Testing table: ------ Start external script: testing-table.lua:, trigger: "every 1 minutes"
Nov 16 19:40:00 pi3 domoticz[27398]: 2022-11-16 19:40:00.573 Status: dzVents: Info: Testing table: sort_compare true
Nov 16 19:40:00 pi3 domoticz[27398]: 2022-11-16 19:40:00.573 Status: dzVents: Info: Testing table: Key: 21:00 Value: Eco
Nov 16 19:40:00 pi3 domoticz[27398]: 2022-11-16 19:40:00.573 Status: dzVents: Info: Testing table: Key: 07:30 Value: Confort
Nov 16 19:40:00 pi3 domoticz[27398]: 2022-11-16 19:40:00.573 Status: dzVents: Info: Testing table: ------ Finished testing-table.lua
Re: a sorted table
Posted: Wednesday 16 November 2022 19:52
by pipiche
Ok. I think I found it
lua: If you traverse this table with pairs, the names appear in an arbitrary order.
Re: a sorted table
Posted: Wednesday 16 November 2022 20:35
by waltervl
Perhaps something completely different for your thermostat planning could be this solution:
https://github.com/syrhus/domoticz-weekly-planning
Re: a sorted table
Posted: Wednesday 16 November 2022 21:28
by plugge
pipiche wrote: Wednesday 16 November 2022 19:52
lua: If you traverse this table with pairs, the names appear in an arbitrary order.
Correct, you have to order the keys first in a seperate table/array.
This works fine in Lua and should work similar in dzVents (with some adaption to your variable names)
Code: Select all
t = { ["07:30"] = "Confort", ["09:00"] = "Eco", ["12:00"] = "Confort", ["14:00"] = "Eco", ["18:00"] = "Confort", ["21:00"] = "Eco" }
a = {}
for n in pairs(t) do table.insert(a, n) end
table.sort(a,
function(k1,k2)
return k1 < k2
end
)
for _,value in pairs(a) do
print(value..' - '..t[value])
end
The result is:
Code: Select all
07:30 - Confort
09:00 - Eco
12:00 - Confort
14:00 - Eco
18:00 - Confort
21:00 - Eco
Re: a sorted table
Posted: Wednesday 16 November 2022 21:29
by boum
For that entry, you can use an integer-key array and traverse it with ipairs:
Code: Select all
…
["Week_Planning"] = {
{ time = "07:30", level = "Confort" },
{ time = "09:00", level = "Eco" },
{ time = "12:00", level = "Confort" },
{ time = "14:00", level = "Eco" },
{ time = "18:00", level = "Confort" },
{ time = "21:00", level = "Eco" },
},
…
local planning = t.SdB.Week_Planning
for _,v in ipairs(planning) do
local time = v.time
local levelName = v.level
…
end
Re: a sorted table
Posted: Wednesday 16 November 2022 22:00
by pipiche
Thanks all,
I have sorted out with that
Code: Select all
function pairsByKeys (t, f)
-- https://www.lua.org/pil/19.3.html
-- A common mistake is to try to order the indices of a table.
-- In a table, the indices form a set, and have no order whatsoever.
-- If you want to order them, you have to copy them to an array and then sort the array.
local a = {}
for n in pairs(t) do table.insert(a, n) end
table.sort(a, f)
local i = 0 -- iterator variable
local iter = function () -- iterator function
i = i + 1
if a[i] == nil then return nil
else return a[i], t[a[i]]
end
end
return iter
end
and then doing
Code: Select all
for room, room_attribute in pairsByKeys(THERMOSTATS) d
o