Loop through variables - Trond Hoyem - 11.02.2021
Hi
Is it possible to loop through a set of variables, or maybe determine variable name depending on other values?
I have a project where I need to count the presence for each ventilation system for each floor to be able to calculate the percentage of offices that are in use. For this I need two variables for each system for each floor; one for the number of occupied offices and one for the total number of offices.
In the name and address of the objects I can find both the floor and the ventilation system, so what I want to do is to scan through all the occupied-addresses and add values to the different variables depending on the value of the addresses.
I more or less has it working, but there is a lot of if/elseif and so on to be able to check it all. So I was thinking there must be a more elegant way to do it.
The code is not done yet, I still need to transfer values to group addresses, but this is what I have so far:
Code: obj = db:getall('SELECT name FROM objects WHERE name LIKE "%STATUS_OCCUPIED%"')
calcWeight = false --Bestemmer om vekt skal medregnes i totalt antall OCCUPIED-adresser. Med false vil hver adresse kun telle som 1.
local p1_03_04count = 0
local p1_03_04occ = 0
local p2_03_04count = 0
local p2_03_04occ = 0
local p3_03_04count = 0
local p3_03_04occ = 0
local p4_03_04count = 0
local p4_03_04occ = 0
local p5_03_04count = 0
local p5_03_04occ = 0
local p1_05count = 0
local p1_05occ = 0
local p2_05count = 0
local p2_05occ = 0
local p3_05count = 0
local p3_05occ = 0
local p4_05count = 0
local p4_05occ = 0
local p5_05count = 0
local p5_05occ = 0
local p1_02count = 0
local p1_02occ = 0
local p2_02count = 0
local p2_02occ = 0
local p3_02count = 0
local p3_02occ = 0
local p4_02count = 0
local p4_02occ = 0
for _, name in ipairs(obj) do
adr = grp.find(name.name)
gaWeight = string.gsub(name.name, 'STATUS', 'WEIGHT')
weight = grp.getvalue(gaWeight)
value = toboolean(grp.getvalue(name.name))
if value then value = 1 else value = 0 end
etasje = string.split(adr.address, '/')[2]
agg = string.split(string.split(adr.name, '360.')[2], ' ')[1]
--Oppretter adresse for vekting dersom den ikke finnes og setter vekttallet til 1.
if grp.find(gaWeight) == nil then
address = grp.create({
datatype = dt.uint16,
virtual = true,
name = gaWeight,
comment = '',
})
grp.write(gaWeight, 1)
end
--log(value, etasje, agg, weight)
if etasje == '1' then
if agg == '02' then
log(name.name, value, etasje, agg, weight)
p1_02count = p1_02count + 1
p1_02occ = p1_02occ + (value * weight)
elseif agg == '03_04' then
p1_03_04count = p1_03_04count + 1
p1_03_04occ = p1_03_04occ + (value * weight)
elseif agg == '05' then
p1_05count = p1_05count + 1
p1_05occ = p1_05occ + (value * weight)
end
elseif etasje == '2' then
if agg == '02' then
--log(name.name, value, etasje, agg, weight)
p2_02count = p2_02count + 1
p2_02occ = p2_02occ + (value * weight)
elseif agg == '03_04' then
p2_03_04count = p2_03_04count + 1
p2_03_04occ = p2_03_04occ + (value * weight)
elseif agg == '05' then
p2_05count = p2_05count + 1
p2_05occ = p2_05occ + (value * weight)
end
elseif etasje == '3' then
if agg == '02' then
--log(name.name, value, etasje, agg, weight)
p3_02count = p3_02count + 1
p3_02occ = p3_02occ + (value * weight)
elseif agg == '03_04' then
p3_03_04count = p3_03_04count + 1
p3_03_04occ = p3_03_04occ + (value * weight)
elseif agg == '05' then
p3_05count = p3_05count + 1
p3_05occ = p3_05occ + (value * weight)
end
elseif etasje == '4' then
if agg == '02' then
--log(name.name, value, etasje, agg, weight)
p4_02count = p4_02count + 1
p4_02occ = p4_02occ + (value * weight)
elseif agg == '03_04' then
p4_03_04count = p4_03_04count + 1
p4_03_04occ = p4_03_04occ + (value * weight)
elseif agg == '05' then
p4_05count = p4_05count + 1
p4_05occ = p4_05occ + (value * weight)
end
elseif etasje == '5' then
if agg == '02' then
--log(name.name, value, etasje, agg, weight)
p5_02count = p5_02count + 1
p5_02occ = p5_02occ + (value * weight)
elseif agg == '03_04' then
p5_03_04count = p5_03_04count + 1
p5_03_04occ = p5_03_04occ + (value * weight)
elseif agg == '05' then
p5_05count = p5_05count + 1
p5_05occ = p5_05occ + (value * weight)
end
end
--log(adr.name, etasje, agg)
end
log(p1_02count, p1_02occ)
RE: Loop through variables - admin - 11.02.2021
Use arrays/tables to store data like this. Untested modified version of you code:
Code: obj = db:getall('SELECT name FROM objects WHERE name LIKE "%STATUS_OCCUPIED%"')
data = {}
keys = { '02', '03_04', '05' }
for fid = 1, 5 do
floor = {}
for _, key in ipairs(keys) do
floor[key] = {
count = 0,
occ = 0,
}
end
data[fid] = floor
end
for _, name in ipairs(obj) do
adr = grp.find(name.name)
gaWeight = string.gsub(name.name, 'STATUS', 'WEIGHT')
weight = grp.getvalue(gaWeight)
value = toboolean(grp.getvalue(name.name))
floor = tonumber(string.split(adr.address, '/')[2])
agg = string.split(string.split(adr.name, '360.')[2], ' ')[1]
--Oppretter adresse for vekting dersom den ikke finnes og setter vekttallet til 1.
if grp.find(gaWeight) == nil then
address = grp.create({
datatype = dt.uint16,
virtual = true,
name = gaWeight,
comment = '',
})
grp.write(gaWeight, 1)
weight = 1
end
if data[floor] and data[floor][agg] then
data[floor][agg].count = data[floor][agg].count + 1
if value then
data[floor][agg].occ = data[floor][agg].occ + weight
end
end
end
log(data)
RE: Loop through variables - Trond Hoyem - 11.02.2021
(11.02.2021, 14:28)admin Wrote: Use arrays/tables to store data like this. Untested modified version of you code:
Code: obj = db:getall('SELECT name FROM objects WHERE name LIKE "%STATUS_OCCUPIED%"')
data = {}
keys = { '02', '03_04', '05' }
for fid = 1, 5 do
floor = {}
for _, key in ipairs(keys) do
floor[key] = {
count = 0,
occ = 0,
}
end
data[fid] = floor
end
for _, name in ipairs(obj) do
adr = grp.find(name.name)
gaWeight = string.gsub(name.name, 'STATUS', 'WEIGHT')
weight = grp.getvalue(gaWeight)
value = toboolean(grp.getvalue(name.name))
floor = tonumber(string.split(adr.address, '/')[2])
agg = string.split(string.split(adr.name, '360.')[2], ' ')[1]
--Oppretter adresse for vekting dersom den ikke finnes og setter vekttallet til 1.
if grp.find(gaWeight) == nil then
address = grp.create({
datatype = dt.uint16,
virtual = true,
name = gaWeight,
comment = '',
})
grp.write(gaWeight, 1)
weight = 1
end
if data[floor] and data[floor][agg] then
data[floor][agg].count = data[floor][agg].count + 1
if value then
data[floor][agg].occ = data[floor][agg].occ + weight
end
end
end
log(data)
Great!
I will test this out. It looks a lot more elegant than my solution. I believe I will be needing things like this in many other applications as well.
RE: Loop through variables - Trond Hoyem - 12.02.2021
OK, so I got this finnished and tested. It works very well. I added some extra info to the table to get more data available, other than that I kept most of the code from Admin.
Thanks for the great help in learing to code in this forum! It is always productive and on-the-spot help here!
I wont bother to post the final code as it is very project spesific, and probably not of interest to anyone else.
|