Short/long press dimming

Short/long press dimming #

This script works as a standard KNX push-button where short press sends either ON or OFF and long press performs 4-bit dimming.

For this to work the control button must have a start-stop behaviour - ON is sent when the button is pressed, OFF is sent when it is released.

Create a resident script with 0 sleep time, modify the timeout and mapping variables as needed. Default long press time is 1 seconds.

In this example there are two input objects - 0/0/3 and 0/0/4.

If 0/0/3 is pressed and released within 1 second then OFF is sent to 0/0/1 (short press on/off). Otherwise DIM DOWN is sent to 0/0/2 (long press dimming). When the button is released then DIM STOP is sent to 0/0/2.

If 0/0/4 is pressed and released within 1 second then ON is sent to 0/0/1 (short press on/off). Otherwise DIM UP is sent to 0/0/2 (long press dimming). When the button is released then DIM STOP is sent to 0/0/2.

if not client then
  timeout = 1 -- long press in seconds

  mapping = {
    ['0/0/3'] = { onoff = '0/0/1', dim = '0/0/2', on = false },
    ['0/0/4'] = { onoff = '0/0/1', dim = '0/0/2', on = true },
  }

  timerstep = timeout / 4

  function eventhandler(event)
    local object = mapping[ event.dst ]
    if not object then
      return
    end

    local value = busdatatype.decode(event.datahex, dt.bool)

    if value then
      object.timer = timeout
    elseif object.timer then
      if object.timer == 0 then
        grp.write(object.dim, object.on and 8 or 0, dt.bit4)
      else
        grp.write(object.onoff, object.on, dt.bool)
      end

      object.timer = nil
    end
  end

  client = require('localbus').new(1)
  clientfd = socket.fdmaskset(client:getfd(), 'r')
  client:sethandler('groupwrite', eventhandler)

  timer = require('timerfd').new(timerstep)
  timerfd = socket.fdmaskset(timer:getfd(), 'r')
end

res, clientstat, timerstat = socket.selectfds(10, clientfd, timerfd)

if res then
  if clientstat then
    client:step()
  end

  if timerstat then
    timer:read()

    for addr, object in pairs(mapping) do
      timervalue = object.timer

      if timervalue and timervalue > 0 then
        timervalue = math.max(0, timervalue - timerstep)

        if timervalue == 0 then
          grp.write(object.dim, object.on and 9 or 1, dt.bit4)
        end

        object.timer = timervalue
      end
    end
  end
end