Page 1 of 1

converting HUE (HSV) to RGB and hex

Posted: Monday 14 March 2016 14:48
by franzelare
I was trying to copy the settings of a HUE ledstrip to a RGB mysensor node and made a script to convert the values
In the end I don't need this but thought the script might be usefull to someone?

Later I will post the entire project of how to copy the settings of a HUE led strip to an mysensor node with RGB ledstrip attached
This will be based on an ESP12 unit with a cheap 12V RGB ledstrip

The HUE led strip I copy is called HueStrip and had ID 6 on the HUE bridge in this script
The script reads the settings of a selected HUE ID on the bridge when the status is changed according to domoticz
The script can return the following color formats
Hue/brightness/saturation
HSV
HSV (in domoticz format)
RGB
RGB(hex)

Code: Select all

commandArray =  {}

PRINT_MODE = false					-- when true wil print output to log and send notifications
STORE = false		--when true will store the calculated values as uservariables

if (devicechanged['HueStrip']) then
	if PRINT_MODE == true then
	print('strip changed')
	end
	if (otherdevices['HueStrip'] == 'Off') then
		if PRINT_MODE == true then
		print('strip off')
		end	

	else
	if PRINT_MODE == true then
	print('strip on, collecting settings')
	end


-- fixed values
base_url = 'http://HUE_Bridge_IP/api/HUE_Username' 	-- hue URL and username
domoticz_url = 'http://Domoticz_server_IP:Domoticz_server_Port' 				--URL of domoticz server
HUE_Strip_ID = 6 				-- HUE ID on the HUE bridge of deviced to be replicated

-- Only load libaries now
http = require('socket.http')
ltn12 = require('ltn12')
json = require('json')

-- set some local variables
device = ''
mode = 'GET'
params = ''
 
      function hueit(device, operation, mode)
         local t = {}
         local url = base_url .. device
         local req_body = operation
	if PRINT_MODE == true then
        	 print(url)
	         print(req_body)
	end
         local headers = {
            ["Content-Type"] = "application/json";
            ["Content-Length"] = #req_body;
          }
          client, code, headers, status = http.request{url=url, headers=headers, source=ltn12.source.string(req_body), sink = ltn12.sink.table(t), method=mode}
	if PRINT_MODE == true then
        	 print(status)
	end
         return t
      end


 
   function processJSON(t)
      obj, pos, err = json:decode(table.concat(t),1,nil)
	if PRINT_MODE == true then
        	print(table.concat(t))
		print("check for error")
	end
        if err then
            print ("Error for HUE Bridge:", err)
        else
	if PRINT_MODE == true then
        	    print("no error")
	end
                data = ''
		i=HUE_Strip_ID
        state=obj.lights[tostring(i)].state
               dataHSV = data .. state.bri ..'|'.. state.hue ..'|'.. state.sat
               dataXY = data .. state.xy[1] ..'|'.. state.xy[2]

		if PRINT_MODE == true then
			print('Hue ID checked: ' .. i)
			print('HSV: ' .. dataHSV)        
			print('XY: ' .. dataXY)        
		         print('length of encode '..#dataHSV + #dataXY)
		end
         end

-- convert HUE values to RGB (hex)
	H=(state.hue/65536)
	S=(state.sat/256)
	V=(state.bri/256)

-- convert HUE values to Domoticz values
	Hdom=math.floor(H*360)
	Sdom=math.floor(S*100)
	Vdom=math.floor(V*100)
	if Hdom == 239 then Hdom=Hdom+1 end -- some correction for rounding issues in domoticz
	if Sdom== 99 then Sdom=Sdom+1 end -- some correction for rounding issues in domoticz
	if Vdom== 99 then Vdom=Vdom+1 end -- some correction for rounding issues in domoticz

if STORE == true then
-- store HUE and RGB values in variables
	commandArray['Variable:Led_HUE'] = tostring(stuffHSV)
	commandArray['Variable:Hue'] = tostring(Hdom)
	commandArray['Variable:Sat'] = tostring(Sdom)
	commandArray['Variable:Bri'] = tostring(Vdom)
end

	print('Hdom: ' .. Hdom)
	print('Sdom: ' .. Sdom)
	print('Vdom: ' .. Vdom)

-- convert HSV to RGB and RGB hex values

	R, G, B =HSVtoRGB(H, S, V) 
	if R >= 16 then
		Rhex=num2hex(R)
	else
		Rhex='0'.. num2hex(R)
	end

	if G >= 16 then
		Ghex=num2hex(G)
	else
		Ghex='0'.. num2hex(G)
	end
	
	if B >= 16 then
		Bhex=num2hex(B)
	else
		Bhex='0'.. num2hex(B)
	end


	RGB= R ..'|'.. G ..'|'.. B
	RGBhex= Rhex ..''.. Ghex ..''.. Bhex

if PRINT_MODE == true then
	print('Hue: ' .. state.hue)
	print('Sat: ' .. state.sat)
	print('Bright: ' .. state.bri)
	print('H: ' .. H)
	print('S: ' .. S)
	print('V: ' .. V)
	print('R: ' .. R)
	print('G: ' .. G)
	print('B: ' .. B)
	print('RGB: ' .. RGB)
	print('Rhex: ' .. Rhex)
	print('Ghex: ' .. Ghex)
	print('Bhex: ' .. Bhex)
	print('RGBhex: ' .. RGBhex)
end

if STORE == true then
-- store HUE and RGB values in variables
	commandArray['Variable:Led_Red'] = tostring(Rhex)
	commandArray['Variable:Led_Green'] = tostring(Ghex)
	commandArray['Variable:Led_Blue'] = tostring(Bhex)
end

   return
end

function HSVtoRGB(h, s, v)
  local r, g, b
  local  R1, G1, B1

  local i = h * 6
  local f = h * 6 - i
  local p = v * (1 - s)
  local q = v * (1 - f * s)
  local t = v * (1 - (1 - f) * s)

  i = i % 6
  if i == 0 then r, g, b = v, t, p
    elseif i > 0 and i <= 1 then r, g, b = q, v, p
    elseif i > 1 and i <= 2 then r, g, b = p, v, t
    elseif i > 2 and i <= 3 then r, g, b = p, q, v
    elseif i > 3 and i <= 4 then r, g, b = t, p, v
    elseif i > 4 and i <= 5 then r, g, b = v, p, q
  end
  R1 = math.floor(r * 255)
  G1 = math.floor(g * 255)
  B1 = math.floor(b * 255)

  return R1, G1, B1
end
 
function num2hex(num)
    local hexstr = '0123456789abcdef'
    local s = ''
    while num > 0 do
        local mod = math.fmod(num, 16)
        s = string.sub(hexstr, mod+1, mod+1) .. s
        num = math.floor(num / 16)
    end
    if s == '' then s = '0' end
    return s
end

t = hueit(device, params, mode)
processJSON(t)

 end
end

return commandArray