in domoticz I have 2 lua scripts running for the HUE control, 1 time based and one triggered by the device change
next to that I have 1 watchdog script that switches on ID 100 to the node and the node will reply with an off at that ID so the node can be reset if there is no communication
a user variable has to be creased to store the current HUE settings (String)
a dummy text utility has to be created to store the HSV or RGB and dimmer values for the mysensor node to request
The device script contains calculations from HSV to RGB and RGB hex, I tried different formats for fowarding the data to the mysensor node and just kept it in the script in case I might need it later for troubleshooting
-- this script reads the setting of 1 HUE RGB device and forwards this to a mysensor RGB dimmer
-- one script will do this time based and the second script will do this on a device change, in order to capture changed made from domoticz and through the HUE bridge directly
-- HUE stores the values in HSV format where the mysensor node uses RGB values for the RGB LED's so these have to be converted before forwarding
-- a user variable has to be creased to store the current HUE settings (String)
-- a dummy text utility has to be created to store the HSV or RGB and dimmer values for the mysensor node to request
-- additional libraries for lua have to be installed
-- how to do this can be found in the help wiki http://www.domoticz.com/wiki/Upload_energy_data_to_PVoutput#Install_socket_library
-- or from http://www.domoticz.com/forum/viewtopic.php?f=5&t=1847&p=22638#p22638
-- for json processing I use http://regex.info/code/JSON.lua on a raspberry pi
-- on a synology nas dkjson seems to do a better job http://dkolf.de/src/dkjson-lua.fsl/home
-- all need to end up in /usr/local/lib/lua/5.2
commandArray = {}
-- fixed values
base_url = 'http://192.168.2.150/api/fd81c2245c8797cec333e351d01a3' -- hue URL and username
domoticz_url = 'http://192.168.2.140:8080' --URL of domoticz server
HUE_Strip_ID = 6 -- HUE ID of deviced to be replicated
HUE_CURRENT = 'Led_HUE' -- Uservariable (String) to store HUE setting
Source_Name = 'HueStrip' -- Name of the HUE device to be copied in Domoticz
Target_IDX = 229 -- IDX of target device
Target_Name = 'RGB_Led' -- exact device name
Target_IDX_TXT=38 -- IDX for HSV values
ForwardType = 'HSV' -- HSV or RGB to be forwarded to the mysensor node
PRINT_MODE = false -- when true wil print output to log and send notifications
if (devicechanged[Source_Name]) then -- optional and (uservariables['HUE_Forward_LAN']==1)
if (otherdevices[Source_Name] == 'Off') then
-- set copied device to off
commandArray[Target_Name] = 'Off'
else
-- Only load libaries now
http = require('socket.http')
ltn12 = require('ltn12')
json = require('JSON')
io = require('io')
-- set some local variables
device = ''
mode = 'GET'
params = ''
function hueread(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
dataHUE = data .. state.bri ..'|'.. state.hue ..'|'.. state.sat
dataStatus = state.on
-- checking if HUE strip is off
if state.on==false then
if PRINT_MODE == true then
if otherdevices[Target_Name] ~= 'Off' then
print('HUE LED is off, but RGB LED was on')
else
print('HUE LED is off, no action')
end
commandArray[Target_Name] = 'Off'
if PRINT_MODE == true then
print('Sending off switch command just to be sure')
end
end
else
-- checking if HUE strip is on but led strip is off
if state.on==true then
if otherdevices[Target_Name] == 'Off' then
if PRINT_MODE == true then
print('Switching RGB led on')
end
commandArray[Target_Name] = 'On'
if PRINT_MODE == true then
print('Hue ID checked: ' .. i)
print('Status on: On')
print('HUE: ' .. dataHUE)
print('length of encode '..#dataHUE)
end
else
if PRINT_MODE == true then
print('RGB led already on, checking settings')
end
commandArray[Target_Name] = 'On'
if PRINT_MODE == true then
print('Sending on switch command just to be sure')
end
end
-- Collecting color data to compare
Old_data = tostring(uservariables[HUE_CURRENT])
New_data = tostring(dataHUE)
if New_data ~= Old_data then
print('HUE data changed')
if PRINT_MODE == true then
print('New data:' .. New_data)
print('Old data:' ..Old_data)
print('')
end
-- convert HUE values to HSV
H=((state.hue)/65534)
S=((state.sat)/254)
V=((state.bri)/254)
--convert HUE to domoticz values
Hue=tostring(math.floor(H*360))
Sat=tostring(math.floor(S*100))
Bri=tostring(math.floor(V*100))
-- 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
-- Reverse calculations of hue values for validation
Hr, Sr, Vr =RGBtoHSV(R, G, B)
Hrev=round((Hr*65536),0)
Srev=round((Sr*256),0)
Vrev=round((Vr*256),0)
-- print all calculated data
print('Hue Hue light: ' .. state.hue)
print('Sat Hue light: ' .. state.sat)
print('Bright Hue light: ' .. state.bri)
print(' ')
print('Hue domoticz: ' .. Hue)
print('Sat domoticz: ' .. Sat)
print('Bri domoticz: ' .. Bri)
print(' ')
print('H: ' .. H)
print('S: ' .. S)
print('V: ' .. V)
print(' ')
print('R: ' .. R)
print('G: ' .. G)
print('B: ' .. B)
print('RGB: ' .. RGB)
print(' ')
print('Rhex: ' .. Rhex)
print('Ghex: ' .. Ghex)
print('Bhex: ' .. Bhex)
print('RGBhex: ' .. RGBhex)
print(' ')
print('H reversed: ' .. Hrev)
print('S reversed: ' .. Srev)
print('V reversed: ' .. Vrev)
end
-- set LED strip
if (ForwardType=='RGB') then
-- store RGB as text
datanew_TXT=RGBhex..";"..Bri..";"
commandArray['UpdateDevice'] = Target_IDX_TXT .. '|0|' .. tostring(datanew_TXT)
if PRINT_MODE == true then
print('Storing RGB text value:' .. datanew_TXT)
end
end
if (ForwardType=='HSV') then
-- store HSV as text
datanew_HSV=state.hue..";"..state.sat..";"..state.bri..";"
commandArray['UpdateDevice'] = Target_IDX_TXT .. '|0|' .. tostring(datanew_HSV)
if PRINT_MODE == true then
print('Storing HSV text value:' .. datanew_HSV)
end
end
--send HUE values to domoticz
urlRGBLED = 'http://127.0.0.1:8080/json.htm?type=command¶m=setcolbrightnessvalue&idx=' .. Target_IDX .. '&hue=' ..Hue.. '&brightness=' ..Bri..'&saturation=' ..Sat.. '&iswhite=false'
commandArray['OpenURL']= urlRGBLED
-- store new HUE values in variables
commandArray['Variable:Led_HUE'] = New_data
else
print('No change in HUE values')
end
end
end
end
return
end
function HSVtoRGB(h, s, v)
local r, g, b
local i = math.floor(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
end
if i == 1 then r, g, b = q, v, p
end
if i == 2 then r, g, b = p, v, t
end
if i == 3 then r, g, b = p, q, v
end
if i == 4 then r, g, b = t, p, v
end
if i == 5 then r, g, b = v, p, q
end
R=round((r*255),0)
G=round((g*255),0)
B=round((b*255),0)
return R, G, B
end
function RGBtoHSV(r, g, b)
r, g, b = r / 255, g / 255, b / 255
local max, min = math.max(r, g, b), math.min(r, g, b)
local h, s, v
v = max
local d = max - min
if max == 0 then s = 0 else s = d / max end
if max == min then
h = 0 -- achromatic
else
if max == r then
h = (g - b) / d
if g < b then h = h + 6 end
elseif max == g then h = (b - r) / d + 2
elseif max == b then h = (r - g) / d + 4
end
h = h / 6
end
return h, s, v
end
function round(num, idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
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 = hueread(device, params, mode)
processJSON(t)
end
end
return commandArray
The time based lua script
-- this script reads the setting of 1 HUE RGB device and forwards this to a mysensor RGB dimmer
-- one script will do this time based and the second script will do this on a device change, in order to capture changed made from domoticz and through the HUE bridge directly
-- HUE stores the values in HSV format where the mysensor node uses RGB values for the RGB LED's so these have to be converted before forwarding
-- a user variable has to be creased to store the current HUE settings (String)
-- a dummy text utility has to be created to store the HSV or RGB and dimmer values for the mysensor node to request
-- additional libraries for lua have to be installed
-- how to do this can be found in the help wiki http://www.domoticz.com/wiki/Upload_energy_data_to_PVoutput#Install_socket_library
-- or from http://www.domoticz.com/forum/viewtopic.php?f=5&t=1847&p=22638#p22638
-- for json processing I use http://regex.info/code/JSON.lua on a raspberry pi
-- on a synology nas dkjson seems to do a better job http://dkolf.de/src/dkjson-lua.fsl/home
-- all need to end up in /usr/local/lib/lua/5.2
commandArray = {}
-- fixed values
base_url = 'http://192.168.2.150/api/fd81c2245c8797cec333e351d01a3' -- hue URL and username
domoticz_url = 'http://192.168.2.140:8080' --URL of domoticz server
HUE_Strip_ID = 6 -- HUE ID of deviced to be replicated
HUE_CURRENT = 'Led_HUE' -- uservariable (String) to store HUE setting
Source_Name = 'HueStrip' -- Name of the HUE device to be copied in Domoticz
Target_IDX = 229 -- IDX of target device
Target_Name = 'RGB_Led' -- exact device name
Target_IDX_TXT=38 -- IDX for HSV values
ForwardType = 'HSV' -- HSV or RGB to be forwarded to the mysensor node
PRINT_MODE = false -- when true wil print output to log and send notifications
-- Only load libaries now
http = require('socket.http')
ltn12 = require('ltn12')
json = require('JSON')
io = require('io')
-- set some local variables
device = ''
mode = 'GET'
params = ''
function hueread(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
dataHUE = data .. state.bri ..'|'.. state.hue ..'|'.. state.sat
dataStatus = state.on
-- checking if HUE strip is off
if state.on==false then
if PRINT_MODE == true then
if otherdevices[Target_Name] ~= 'Off' then
print('HUE LED is off, but RGB LED was on')
else
print('HUE LED is off, no action')
end
commandArray[Target_Name] = 'Off'
if PRINT_MODE == true then
print('Sending off switch command just to be sure')
end
end
else
-- checking if HUE strip is on but led strip is off
if state.on==true then
if otherdevices[Target_Name] == 'Off' then
if PRINT_MODE == true then
print('Switching RGB led on')
end
commandArray[Target_Name] = 'On'
if PRINT_MODE == true then
print('Hue ID checked: ' .. i)
print('Status on: On')
print('HUE: ' .. dataHUE)
print('length of encode '..#dataHUE)
end
else
if PRINT_MODE == true then
print('RGB led already on, checking settings')
end
commandArray[Target_Name] = 'On'
if PRINT_MODE == true then
print('Sending on switch command just to be sure')
end
end
-- Collecting color data to compare
Old_data = tostring(uservariables[HUE_CURRENT])
New_data = tostring(dataHUE)
if New_data ~= Old_data then
print('HUE data changed')
if PRINT_MODE == true then
print('New data:' .. New_data)
print('Old data:' ..Old_data)
print('')
end
-- convert HUE values to HSV
H=((state.hue)/65534)
S=((state.sat)/254)
V=((state.bri)/254)
--convert HUE to domoticz values
Hue=tostring(math.floor(H*360))
Sat=tostring(math.floor(S*100))
Bri=tostring(math.floor(V*100))
-- 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
-- Reverse calculations of hue values for validation
Hr, Sr, Vr =RGBtoHSV(R, G, B)
Hrev=round((Hr*65536),0)
Srev=round((Sr*256),0)
Vrev=round((Vr*256),0)
-- print all calculated data
print('Hue Hue light: ' .. state.hue)
print('Sat Hue light: ' .. state.sat)
print('Bright Hue light: ' .. state.bri)
print(' ')
print('Hue domoticz: ' .. Hue)
print('Sat domoticz: ' .. Sat)
print('Bri domoticz: ' .. Bri)
print(' ')
print('H: ' .. H)
print('S: ' .. S)
print('V: ' .. V)
print(' ')
print('R: ' .. R)
print('G: ' .. G)
print('B: ' .. B)
print('RGB: ' .. RGB)
print(' ')
print('Rhex: ' .. Rhex)
print('Ghex: ' .. Ghex)
print('Bhex: ' .. Bhex)
print('RGBhex: ' .. RGBhex)
print(' ')
print('H reversed: ' .. Hrev)
print('S reversed: ' .. Srev)
print('V reversed: ' .. Vrev)
end
-- set LED strip
if (ForwardType=='RGB') then
-- store RGB as text
datanew_TXT=RGBhex..";"..Bri..";"
commandArray['UpdateDevice'] = Target_IDX_TXT .. '|0|' .. tostring(datanew_TXT)
if PRINT_MODE == true then
print('Storing RGB text value:' .. datanew_TXT)
end
end
if (ForwardType=='HSV') then
-- store HSV as text
datanew_HSV=state.hue..";"..state.sat..";"..state.bri..";"
commandArray['UpdateDevice'] = Target_IDX_TXT .. '|0|' .. tostring(datanew_HSV)
if PRINT_MODE == true then
print('Storing HSV text value:' .. datanew_HSV)
end
end
--send HUE values to domoticz
urlRGBLED = 'http://127.0.0.1:8080/json.htm?type=command¶m=setcolbrightnessvalue&idx=' .. Target_IDX .. '&hue=' ..Hue.. '&brightness=' ..Bri..'&saturation=' ..Sat.. '&iswhite=false'
commandArray['OpenURL']= urlRGBLED
-- store new HUE values in variables
commandArray['Variable:Led_HUE'] = New_data
else
print('No change in HUE values')
end
end
end
end
return
end
function HSVtoRGB(h, s, v)
local r, g, b
local i = math.floor(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
end
if i == 1 then r, g, b = q, v, p
end
if i == 2 then r, g, b = p, v, t
end
if i == 3 then r, g, b = p, q, v
end
if i == 4 then r, g, b = t, p, v
end
if i == 5 then r, g, b = v, p, q
end
R=round((r*255),0)
G=round((g*255),0)
B=round((b*255),0)
return R, G, B
end
function RGBtoHSV(r, g, b)
r, g, b = r / 255, g / 255, b / 255
local max, min = math.max(r, g, b), math.min(r, g, b)
local h, s, v
v = max
local d = max - min
if max == 0 then s = 0 else s = d / max end
if max == min then
h = 0 -- achromatic
else
if max == r then
h = (g - b) / d
if g < b then h = h + 6 end
elseif max == g then h = (b - r) / d + 2
elseif max == b then h = (r - g) / d + 4
end
h = h / 6
end
return h, s, v
end
function round(num, idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
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 = hueread(device, params, mode)
processJSON(t)
return commandArray
I use a watchdog script, where this is a simplified version of, currently I have 5 ESP units in this watchdog script
commandArray = {}
PRINT_MODE = false -- when true wil print output to log and send notifications
function timedifference (s)
year = string.sub(s, 1, 4)
month = string.sub(s, 6, 7)
day = string.sub(s, 9, 10)
hour = string.sub(s, 12, 13)
minutes = string.sub(s, 15, 16)
seconds = string.sub(s, 18, 19)
t1 = os.time()
t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
difference = os.difftime (t1, t2)
return difference
end
LastupdateESP = otherdevices_lastupdate['HeartbeatESP']
ESPdifference=timedifference (LastupdateESP)
if PRINT_MODE == true then
print('Lastupdate ESP ' .. LastupdateESP)
print('Time difference ' .. ESPdifference)
end
if (ESPdifference>=130) then
if (otherdevices['ESPAlive'] == 'On')then
commandArray['ESPAlive'] = 'Off'
CurrentTime=os.date("%Y-%m-%d %H:%M:%S")
file = io.open("/home/pi/domoticz/www/log/MysensorWatchdog.log", "a")
io.output(file)
io.write(CurrentTime.. " Mysensor ESP connection lost" .. "\n")
io.close(file)
if PRINT_MODE == true then
print('Writing to error log')
end
end
end
if (ESPdifference<130 and otherdevices['ESPAlive'] == 'Off')then
if PRINT_MODE == true then
print('ESP is a live again')
end
commandArray['ESPAlive'] = 'On'
CurrentTime=os.date("%Y-%m-%d %H:%M:%S")
file = io.open("/home/pi/domoticz/www/log/MysensorWatchdog.log", "a")
io.output(file)
io.write(CurrentTime.. " Mysensor ESP connection operational again" .. "\n")
io.close(file)
if PRINT_MODE == true then
print('Writing to error log')
end
end
commandArray['HeartbeatESP'] = 'On'
return commandArray