Code:
[valvesInSummer]
* table:
[1]
* table:
[value]
* bool: false
[firstTimestamp]
* number: 0
[name]
* string: T7 FB Heating floor attic valve
[opened]
* bool: false
[opened]
* bool: false
26.10.2018 16:37:22
Valve 'T7 FB Heating floor attic valve' is closed
Pump is turned off. Scripts waits 61s because minimum fully open time is 60s.
26.10.2018 16:38:23
Valve 'T7 FB Heating floor attic valve' is not fully opened
Pump is turned off. Script waits another 46s when valve will be fully opened.
What you can do further:
1. Replace grp.checkwrite() with grp.write()
2. Log grp.find() of pump after writing value to it.
Below updated script.
Code:
------------------------------------------------------
-- DEFINE GLOBAL VARIABLES AND ZONES ------------------
------------------------------------------------------
seasonGA = '2/0/100'
logging = true
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
if logging then logs = {season = season} end -- #TO DELETE
function calcOutOfTheSeason(tag)
local opened = false
local firstTimestamp = 0
local valves = grp.tag(tag)
if logging then logs.zones[#logs.zones]valvesInWinter = {} end -- #TO DELETE
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
if logging then logs.zones[#logs.zones]valvesInWinter[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
end
return opened, firstTimestamp
end
function calcDuringTheSeason(tag)
local opened = false
local firstTimestamp = 0
local valves = grp.tag(tag)
if logging then logs.zones[#logs.zones]valvesInSummer = {} end -- #TO DELETE
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
if logging then logs.zones[#logs.zones]valvesInSummer[v] = {name = valve.name, value = valve.value, tags = valve.tags, opened = opened, firstTimestamp = firstTimestamp} end -- #TO DELETE
end
return opened, firstTimestamp
end
if logging then
logs.season = season
logs.zones = {}
end -- #TO DELETE
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
if logging then
logs.zones[z] = {
settings = {
summerTag = summerTag,
winterTag = winterTag,
pumpGA = pumpGA,
pumpBeforeCmd = grp.getvalue(pumpGA),
openingValveTime = openingValveTime,
minInterval = minInterval
}
}
end -- #TO DELETE
-- 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
if logging then
logs.zones[z].opened = opened
logs.zones[z].firstTimestamp = firstTimestamp
end -- # TO DELETE
-- Find nextZoneCalculationAfter for current zone
local nextZoneCalculationAfter = 0
if logging then
local pump = grp.find(pumpGA)
local pumpState = { name = pump.name, value = pump.value, lastupdate = os.time() - pump.updatetime }
logs.zones[z].pumpState = {before = pumpState}
end
if opened then
local fullyOpened = os.microtime() - firstTimestamp >= openingValveTime
if fullyOpened then
grp.write(pumpGA, true)
nextZoneCalculationAfter = minInterval
if logging then logs.zones[z].info = 'Turn on pump because valve is fully opened. Next calculation after ' .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
else
grp.write(pumpGA, false)
nextZoneCalculationAfter = openingValveTime + 1 - (os.microtime() - firstTimestamp) -- run a little after possible change
if logging then logs.zones[z].info = "Turn off pump because valve isn't yet fully opened. Next calculation after " .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
end
else
grp.write(pumpGA, false)
nextZoneCalculationAfter = openingValveTime + 1
if logging then logs.zones[z].info = 'Turn off pump because valve is closed. Next calculation after ' .. nextZoneCalculationAfter .. 's.' end -- # TO DELETE
end
if logging then
local pump = grp.find(pumpGA)
local pumpState = { name = pump.name, value = pump.value, lastupdate = os.time() - pump.updatetime }
logs.zones[z].pumpState.after = pumpState
end
-- Update nextCalculationAfter (global)
if z == 1 or nextCalculationAfter < nextZoneCalculationAfter then
nextCalculationAfter = nextZoneCalculationAfter
if logging then logs.zones[z].info = logs.zones[z].info .. ' Variable nextCalculationAfter was changed to ' .. nextZoneCalculationAfter .. '.' end -- # TO DELETE
end
end
-- log('Next calculation after: ' .. nextCalculationAfter .. 's.')
if nextCalculationAfter and nextCalculationAfter > 5 then
if logging then
logs.sleepDescription = 'Calculated ' .. nextCalculationAfter .. 's'
log(logs)
end -- # TO DELETE
os.sleep(nextCalculationAfter)
else
if logging then
logs.sleepDescription = 'Default ' .. nextCalculationAfter .. 's (calculated value is 0 or other equal to false)'
log(logs)
end -- # TO DELETE
os.sleep(30)
end
Done is better than perfect