24.10.2018, 20:08
You can try something like this for all zones. Firstly you could only switch off older scripts and check if this would work same as older but for all zones and in only one script. Maybe when you define your zones in same place you found something.
Code:
------------------------------------------------------
-- DEFINE GLOBAL VARIABLES AND ZONES------------------
------------------------------------------------------
seasonGA = '2/0/100'
zones = {
{
summer = 'pompa_circolazione_giorno_estate',
winter = 'pompa_circolazione_giorno_inverno',
pump = '2/0/1',
offset = 60,
minimum = 30
}
}
------------------------------------------------------
-- DONT CHANGE NOTHING BELOW--------------------------
------------------------------------------------------
season = grp.getvalue(seasonGA)
nextCalculationAfter = 30 -- it will be changed by first zone
function calcOutOfTheSeason(tag)
local opened = false
local firstTimestamp = 0
local valves = grp.tag(tag)
for v = 1, #valves, 1 do
local valve = valves[v]
if valve.value then
opened = true
if firstTimestamp > 0 then
if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
else
firstTimestamp = valve.updatetime
end
end
end
return opened, firstTimestamp
end
function calcDuringTheSeason(tag)
local opened = false
local firstTimestamp = 0
local valves = grp.tag(tag)
valves = grp.tag(tag)
for v = 1, #valves, 1 do
valve = valves[v]
if valve.value then
opened = true
if firstTimestamp > 0 then
if firstTimestamp > valve.updatetime then firstTimestamp = valve.updatetime end
else
firstTimestamp = valve.updatetime
end
end
end
return opened, firstTimestamp
end
for z, zone in ipairs(zones) do
local summerTag = zone.summer
local winterTag = zone.winter
local pumpGA = zone.pump
local openingValveTime = zone.offset
local minInterval = zone.minimum
-- CALCULATE SINGLE
local opened, firstTimestamp = false, 0
-- Calc valve state and firsttimestamp for update
if season then
opened, firstTimestamp = calcDuringTheSeason(winterTag)
else
opened, firstTimestamp = calcOutOfTheSeason(summerTag)
end
-- Find nextZoneCalculationAfter for current zone
local nextZoneCalculationAfter = 0
if opened then
local fullyOpened = os.microtime() - firstTimestamp >= openingValveTime
if fullyOpened then
grp.checkwrite(pumpGA, true)
nextZoneCalculationAfter = minInterval
else
grp.checkwrite(pumpGA, false)
nextZoneCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
end
else
grp.checkwrite(pumpGA, false)
nextZoneCalculationAfter = openingValveTime + 1
end
-- Update nextCalculationAfter (global)
if z == 1 or nextCalculationAfter < nextZoneCalculationAfter then
nextCalculationAfter = nextZoneCalculationAfter
end
end
-- log('Next calculation after: ' .. nextCalculationAfter .. 's.')
if nextCalculationAfter and nextCalculationAfter > 5 then
os.sleep(nextCalculationAfter)
else
os.sleep(30)
end
Done is better than perfect