Logic Machine Forum
RGB relative dimming from KNX - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: RGB relative dimming from KNX (/showthread.php?tid=2948)



RGB relative dimming from KNX - alexll - 01.11.2020

Hi there. I'm trying to relative dimming, from a physical KNX button, a RGB LED strip connected to a DALI controller (https://www.dalcnet.com/en/DALI/15576-DLX1224-4CV-DALI). I'm using an ABB DALI-KNX gateway to control it (https://new.abb.com/products/2CDG110273R0011/dg-s1-64-5-1-dali-gateway-premium-1-fold-mdrc).

Every colour is in 1 byte KNX object (R 1byte - G 1byte - B 1byte). As they are in separate channels, I don't know how to dimmer an specific colour (from LM visu is simple, but I can't find the way to do that from a KNX 4 bit object). 

I have started running this script https://forum.logicmachine.net/showthread.php?tid=1334&pid=8027#pid8027 but I'm stuck in looking for the next step.

Can you help me, please? Thanks in advance!  Rolleyes


RE: RGB relative dimming from KNX - Daniel - 02.11.2020

Pure conversion of this script in to dimming of 3 objects is this but I'm not sure if this is what you need. Most likely you would have to calculate saturation.
Code:
addressbyteoutput1 = '32/1/1'
addressbyteoutput2 = '32/1/2'
addressbyteoutput3 = '32/1/3'

stepsize = 10

value = event.getvalue()

current1 = grp.getvalue(addressbyteoutput1)
current2 = grp.getvalue(addressbyteoutput2)
current3 = grp.getvalue(addressbyteoutput3)
if value < 8 and value ~= 0 then
  log('down',value)
  if current1 <= stepsize then
    output = 0
    if current1 ~= output then
      grp.write(addressbyteoutput1, output)
       end
  else
    output = current1 - stepsize
    if current1 ~= output then
      grp.write(addressbyteoutput1, output)
    end
  end
if current2 <= stepsize then
    output = 0
    if current2 ~= output then
      grp.write(addressbyteoutput2, output)
       end
  else
    output = current2 - stepsize
    if current2 ~= output then
      grp.write(addressbyteoutput2, output)
    end
  end 

if current3 <= stepsize then
    output = 0
    if current3 ~= output then
      grp.write(addressbyteoutput3, output)
       end
  else
    output = current3 - stepsize
    if current3 ~= output then
      grp.write(addressbyteoutput3, output)
    end
  end 
 
 
elseif value > 8 then
  log('up',value)
  if current1 >= (100 - stepsize) then
    output = 100
    if current1 ~= output then
      grp.write(addressbyteoutput1, output)
    end
  else
    output = current1 + stepsize
    if current1 ~= output then
      grp.write(addressbyteoutput1, output)
    end
  end
 


  if current2 >= (100 - stepsize) then
    output = 100
    if current2 ~= output then
      grp.write(addressbyteoutput2, output)
    end
  else
    output = current2 + stepsize
    if current2 ~= output then
      grp.write(addressbyteoutput2, output)
    end
  end
 

  if current3 >= (100 - stepsize) then
    output = 100
    if current3 ~= output then
      grp.write(addressbyteoutput3, output)
    end
  else
    output = current3 + stepsize
    if current3 ~= output then
      grp.write(addressbyteoutput3, output)
    end
  end
end



RE: RGB relative dimming from KNX - alexll - 02.11.2020

(02.11.2020, 14:57)Daniel. Wrote: Pure conversion of this script in to dimming of 3 objects is this but I'm not sure if this is what you need. Most likely you would have to calculate saturation.
Code:
addressbyteoutput1 = '32/1/1'
addressbyteoutput2 = '32/1/2'
addressbyteoutput3 = '32/1/3'

stepsize = 10

value = event.getvalue()

current1 = grp.getvalue(addressbyteoutput1)
current2 = grp.getvalue(addressbyteoutput2)
current3 = grp.getvalue(addressbyteoutput3)
if value < 8 and value ~= 0 then
  log('down',value)
  if current1 <= stepsize then
    output = 0
    if current1 ~= output then
      grp.write(addressbyteoutput1, output)
       end
  else
    output = current1 - stepsize
    if current1 ~= output then
      grp.write(addressbyteoutput1, output)
    end
  end
if current2 <= stepsize then
    output = 0
    if current2 ~= output then
      grp.write(addressbyteoutput2, output)
       end
  else
    output = current2 - stepsize
    if current2 ~= output then
      grp.write(addressbyteoutput2, output)
    end
  end 

if current3 <= stepsize then
    output = 0
    if current3 ~= output then
      grp.write(addressbyteoutput3, output)
       end
  else
    output = current3 - stepsize
    if current3 ~= output then
      grp.write(addressbyteoutput3, output)
    end
  end 
 
 
elseif value > 8 then
  log('up',value)
  if current1 >= (100 - stepsize) then
    output = 100
    if current1 ~= output then
      grp.write(addressbyteoutput1, output)
    end
  else
    output = current1 + stepsize
    if current1 ~= output then
      grp.write(addressbyteoutput1, output)
    end
  end
 


  if current2 >= (100 - stepsize) then
    output = 100
    if current2 ~= output then
      grp.write(addressbyteoutput2, output)
    end
  else
    output = current2 + stepsize
    if current2 ~= output then
      grp.write(addressbyteoutput2, output)
    end
  end
 

  if current3 >= (100 - stepsize) then
    output = 100
    if current3 ~= output then
      grp.write(addressbyteoutput3, output)
    end
  else
    output = current3 + stepsize
    if current3 ~= output then
      grp.write(addressbyteoutput3, output)
    end
  end
end
Thanks for the quick answer. That would work, but like dimming 3 independent lights.

I think the theorical way should be, first, to convert those 3 1byte objects in a 3byte RGB value (232.600). After that, to "dim" that value and, finally, go the other way round.
The problem is I can't achieve that  Undecided .


RE: RGB relative dimming from KNX - alexll - 03.11.2020

No one? How is this supposed to be done? Perhaps I am not approaching the problem correctly...  Sad


RE: RGB relative dimming from KNX - admin - 04.11.2020

To dim a color your need to convert RGB to HSV, change V up/down and then convert back to RGB.
Here are the functions that you can use.
Code:
function rgbtohsv(r, g, b)
  local max, min, d, h, s, v

  max = math.max(r, g, b)
  min = math.min(r, g, b)
  d = max - min
  s = max == 0 and 0 or (d / max)
  v = max / 255

  if max == min then
    h = 0
  elseif max == r then
    h = (g - b) + d * (g < b and 6 or 0)
    h = h / (6 * d)
  elseif max == g then
    h = (b - r) + d * 2
    h = h / (6 * d)
  elseif max == b then
    h = (r - g) + d * 4
    h = h / (6 * d)
  end

  return h, s, v
end

function hsvtorgb(h, s, v)
  local r, g, b, i, f, p, q, t, z

  i = math.floor(h * 6)
  f = h * 6 - i
  p = v * (1 - s)
  q = v * (1 - f * s)
  t = v * (1 - (1 - f) * s)
  z = i % 6

  if z == 0 then
    r = v
    g = t
    b = p
  elseif z == 1 then
    r = q
    g = v
    b = p
  elseif z == 2 then
    r = p
    g = v
    b = t
  elseif z == 3 then
    r = p
    g = q
    b = v
  elseif z == 4 then
    r = t
    g = p
    b = v
  elseif z == 5 then
    r = v
    g = p
    b = q
  end

  r = math.round(r * 255)
  g = math.round(g * 255)
  b = math.round(b * 255)

  return r, g, b
end

function rgbstep(r, g, b, up, step)
  local h, s, v = rgbtohsv(r, g, b)
  local v2 = up and math.min(1, v + step) or math.max(0, v - step)
 
  if v == v2 then
    return
  end

  return hsvtorgb(h, s, v2)
end

rgbstep(r, g, b, up, step) can perform up/down step of current RGB value.
arguments:
  • r, g, b - color components in 0..255 range
  • up - true = step up / false = step down
  • step - step size, V range is 0..1 so the step should be something like 0.1 or 0.05 depending on how many total steps you want
rgbstep will return new RGB values but it might also return nil when further step is not possible.
Code:
-- values from split RGB value
r = 127
g = 255
b = 10
-- step down
up = false
-- maximum 20 steps between min and max
step = 0.05

r, g, b = rgbstep(r, g, b, up, step)
if r then
  -- write new values
else
  -- stop dimming
end



RE: RGB relative dimming from KNX - alexll - 04.11.2020

(04.11.2020, 07:48)admin Wrote: To dim a color your need to convert RGB to HSV, change V up/down and then convert back to RGB.
Here are the functions that you can use.
Code:
function rgbtohsv(r, g, b)
  local max, min, d, h, s, v

  max = math.max(r, g, b)
  min = math.min(r, g, b)
  d = max - min
  s = max == 0 and 0 or (d / max)
  v = max / 255

  if max == min then
    h = 0
  elseif max == r then
    h = (g - b) + d * (g < b and 6 or 0)
    h = h / (6 * d)
  elseif max == g then
    h = (b - r) + d * 2
    h = h / (6 * d)
  elseif max == b then
    h = (r - g) + d * 4
    h = h / (6 * d)
  end

  return h, s, v
end

function hsvtorgb(h, s, v)
  local r, g, b, i, f, p, q, t, z

  i = math.floor(h * 6)
  f = h * 6 - i
  p = v * (1 - s)
  q = v * (1 - f * s)
  t = v * (1 - (1 - f) * s)
  z = i % 6

  if z == 0 then
    r = v
    g = t
    b = p
  elseif z == 1 then
    r = q
    g = v
    b = p
  elseif z == 2 then
    r = p
    g = v
    b = t
  elseif z == 3 then
    r = p
    g = q
    b = v
  elseif z == 4 then
    r = t
    g = p
    b = v
  elseif z == 5 then
    r = v
    g = p
    b = q
  end

  r = math.round(r * 255)
  g = math.round(g * 255)
  b = math.round(b * 255)

  return r, g, b
end

function rgbstep(r, g, b, up, step)
  local h, s, v = rgbtohsv(r, g, b)
  local v2 = up and math.min(1, v + step) or math.max(0, v - step)
 
  if v == v2 then
    return
  end

  return hsvtorgb(h, s, v2)
end

rgbstep(r, g, b, up, step) can perform up/down step of current RGB value.
arguments:
  • r, g, b - color components in 0..255 range
  • up - true = step up / false = step down
  • step - step size, V range is 0..1 so the step should be something like 0.1 or 0.05 depending on how many total steps you want
rgbstep will return new RGB values but it might also return nil when further step is not possible.
Code:
-- values from split RGB value
r = 127
g = 255
b = 10
-- step down
up = false
-- maximum 20 steps between min and max
step = 0.05

r, g, b = rgbstep(r, g, b, up, step)
if r then
  -- write new values
else
  -- stop dimming
end
Thank you very much! So my only doubt is which group addresses I need to define  Blush


RE: RGB relative dimming from KNX - alexll - 07.11.2020

I'm so sorry, but I don't know how to combine that script with the objects I own. I have only three 1 byte KNX groups (R, G and B) in scale format (0-100%). Could someone help me in the next step? Thanks in advance!  Confused


RE: RGB relative dimming from KNX - admin - 09.11.2020

Use this event script for 4-bit object. Change R/G/B addresses as needed and modify step and delay to change the dimming speed and smoothness.

Code:
raddr = '32/1/1' -- red value address
gaddr = '32/1/2' -- green value address
baddr = '32/1/3' -- blue value address
step = 0.05 -- step side
delay = 0.3 -- delay between steps

value = event.getvalue()
up = bit.band(value, 0x08) == 0x08
stop = bit.band(value, 0x07) == 0

if stop then
  return  
end

-- get value and convert from 0..100 to 0..255
r = grp.getvalue(raddr) * 2.55
g = grp.getvalue(gaddr) * 2.55
b = grp.getvalue(baddr) * 2.55

function rgbtohsv(r, g, b)
  local max, min, d, h, s, v

  max = math.max(r, g, b)
  min = math.min(r, g, b)
  d = max - min
  s = max == 0 and 0 or (d / max)
  v = max / 255

  if max == min then
    h = 0
  elseif max == r then
    h = (g - b) + d * (g < b and 6 or 0)
    h = h / (6 * d)
  elseif max == g then
    h = (b - r) + d * 2
    h = h / (6 * d)
  elseif max == b then
    h = (r - g) + d * 4
    h = h / (6 * d)
  end

  return h, s, v
end

function hsvtorgb(h, s, v)
  local r, g, b, i, f, p, q, t, z

  i = math.floor(h * 6)
  f = h * 6 - i
  p = v * (1 - s)
  q = v * (1 - f * s)
  t = v * (1 - (1 - f) * s)
  z = i % 6

  if z == 0 then
    r = v
    g = t
    b = p
  elseif z == 1 then
    r = q
    g = v
    b = p
  elseif z == 2 then
    r = p
    g = v
    b = t
  elseif z == 3 then
    r = p
    g = q
    b = v
  elseif z == 4 then
    r = t
    g = p
    b = v
  elseif z == 5 then
    r = v
    g = p
    b = q
  end

  r = math.round(r * 255)
  g = math.round(g * 255)
  b = math.round(b * 255)

  return r, g, b
end

function rgbstep(r, g, b, up, step)
  local h, s, v = rgbtohsv(r, g, b)
  local v2 = up and math.min(1, v + step) or math.max(0, v - step)
  
  if v == v2 then
    return
  end

  return hsvtorgb(h, s, v2)
end

while true do
  r, g, b = rgbstep(r, g, b, up, step)
  if r then
    grp.write(raddr, r, dt.uint8)
    grp.write(gaddr, g, dt.uint8)
    grp.write(baddr, b, dt.uint8)
  else
    break
  end

  os.sleep(delay)
  newvalue = grp.getvalue(event.dst)
  if value ~= newvalue then
    break
  end
end



RE: RGB relative dimming from KNX - alexll - 09.11.2020

(09.11.2020, 08:56)admin Wrote: Use this event script for 4-bit object. Change R/G/B addresses as needed and modify step and delay to change the dimming speed and smoothness.

Code:
raddr = '32/1/1' -- red value address
gaddr = '32/1/2' -- green value address
baddr = '32/1/3' -- blue value address
step = 0.05 -- step side
delay = 0.3 -- delay between steps

value = event.getvalue()
up = bit.band(value, 0x08) == 0x08
stop = bit.band(value, 0x07) == 0

if stop then
  return 
end

-- get value and convert from 0..100 to 0..255
r = grp.getvalue(raddr) * 2.55
g = grp.getvalue(gaddr) * 2.55
b = grp.getvalue(baddr) * 2.55

function rgbtohsv(r, g, b)
  local max, min, d, h, s, v

  max = math.max(r, g, b)
  min = math.min(r, g, b)
  d = max - min
  s = max == 0 and 0 or (d / max)
  v = max / 255

  if max == min then
    h = 0
  elseif max == r then
    h = (g - b) + d * (g < b and 6 or 0)
    h = h / (6 * d)
  elseif max == g then
    h = (b - r) + d * 2
    h = h / (6 * d)
  elseif max == b then
    h = (r - g) + d * 4
    h = h / (6 * d)
  end

  return h, s, v
end

function hsvtorgb(h, s, v)
  local r, g, b, i, f, p, q, t, z

  i = math.floor(h * 6)
  f = h * 6 - i
  p = v * (1 - s)
  q = v * (1 - f * s)
  t = v * (1 - (1 - f) * s)
  z = i % 6

  if z == 0 then
    r = v
    g = t
    b = p
  elseif z == 1 then
    r = q
    g = v
    b = p
  elseif z == 2 then
    r = p
    g = v
    b = t
  elseif z == 3 then
    r = p
    g = q
    b = v
  elseif z == 4 then
    r = t
    g = p
    b = v
  elseif z == 5 then
    r = v
    g = p
    b = q
  end

  r = math.round(r * 255)
  g = math.round(g * 255)
  b = math.round(b * 255)

  return r, g, b
end

function rgbstep(r, g, b, up, step)
  local h, s, v = rgbtohsv(r, g, b)
  local v2 = up and math.min(1, v + step) or math.max(0, v - step)
 
  if v == v2 then
    return
  end

  return hsvtorgb(h, s, v2)
end

while true do
  r, g, b = rgbstep(r, g, b, up, step)
  if r then
    grp.write(raddr, r, dt.uint8)
    grp.write(gaddr, g, dt.uint8)
    grp.write(baddr, b, dt.uint8)
  else
    break
  end

  os.sleep(delay)
  newvalue = grp.getvalue(event.dst)
  if value ~= newvalue then
    break
  end
end
Awesome! Thank you very much!!