03.07.2022, 18:37
(22.06.2022, 10:29)admin Wrote: Updated version with an optional timer on/off object and status monitoring. For this to work the dimmer must have a status output active and should report the status as soon as possible (some dimmers have an option to report status when only after a transition). When the script writes its output value it will ignore the status report for 1 second. This can be lowered (line 53) to prevent possible issues when a manual control is performed at the same moment as the scripted control.
Code:if not client then
timers = {
{
input = '1/1/1', -- binary PIR status
enable = '1/1/2', -- enable timer on/off
output = '1/1/3', -- dimmer control (0..100%)
status = '1/1/4', -- dimmer status (0..100%)
onvaluehigh = 90, -- high output value in %
onvaluelow = 10, -- low output value in %
timeout = 5, -- in seconds
}
}
function setoutputvalue(timer, value)
timer.ignoresec, timer.ignoreusec = os.microtime()
grp.write(timer.output, value, dt.scale)
end
function settimerstate(timer, event)
timer.enabled = busdatatype.decode(event.datahex, dt.bool)
timer.ticks = nil
log('timer enabled', timer.enabled)
end
function setinputvalue(timer, event)
local value = busdatatype.decode(event.datahex, dt.bool)
if not value or not timer.enabled then
return
end
log('pir trigger', timer.statvalue)
if timer.statvalue < timer.onvaluelow then
value = timer.onvaluelow
elseif timer.statvalue < timer.onvaluehigh then
value = timer.onvaluehigh
else
value = nil
end
if not timer.ticks and value then
setoutputvalue(timer, value)
end
timer.ticks = timer.timeout
end
function setstatusvalue(timer, event)
if timer.ignoresec then
local delta = os.udifftime(timer.ignoresec, timer.ignoreusec)
if delta >= 0 and delta <= 1 then
return
end
timer.ignoresec = nil
end
if timer.enabled then
timer.statvalue = busdatatype.decode(event.datahex, dt.scale)
timer.ticks = nil -- stop timer
log('output change', timer.statvalue)
end
end
for _, timer in ipairs(timers) do
timer.statvalue = grp.getvalue(timer.status) or 0
if timer.enable then
timer.enabled = grp.getvalue(timer.enable)
else
timer.enabled = true
end
log('timer init', timer.statvalue, timer.enabled)
end
sender = 'tm'
grp.sender = sender
client = require('localbus').new(0.1)
client:sethandler('groupwrite', function(event)
if event.sender == sender then
return
end
for _, timer in ipairs(timers) do
if event.dst == timer.enable then
settimerstate(timer, event)
elseif event.dst == timer.switch then
setswitchvalue(timer, event)
elseif event.dst == timer.input then
setinputvalue(timer, event)
elseif event.dst == timer.status then
setstatusvalue(timer, event)
end
end
end)
end
client:loop(1)
for _, timer in ipairs(timers) do
if timer.ticks then
timer.ticks = timer.ticks - 1
if timer.ticks == 0 then
log('timer stop', timer.statvalue)
setoutputvalue(timer, timer.statvalue)
timer.ticks = nil
end
end
end
Thank you again!
With this message, I give an update of the status:
I have been using this modified script for some time now. It works far better, but I still cannot get it to work 100% correctly.
I would have liked to explain what is going wrong, but it is not easy since the behaviour of the script changes .
What have I experienced:
Some days the script does not work at all (after restarting, this is then solved).
My family told me that the script also worked the other way around once. So that the lamp went on, while it should have stayed off.
Some additional information:
As enabler I used the status object of the lamp itself. So only if the lamp is already on, it must be made louder.
I have also noticed that the numbers behind CPU/IO at the bottom sometimes turn red for a while. I don't know if that is relevant. I'm reporting it just to be sure.
Additional challenge: Because it is currently light outside for so long, it is also more difficult to see whether the script is working as desired. It is only when it is dark outside that it is noticeable when the lamp is turned up and then down again.
I'm going to gain more experience and as soon as I can describe better what exactly happens, I'll let you know.