This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Staircase script with dimming option
#14
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
Reply


Messages In This Thread
RE: Staircase script with dimming option - by admin - 22.06.2022, 10:29

Forum Jump: