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