WORKING SCRIPT
Use this script if you want to change the colors of your Hue lights according to the outside color temperature. This script is based on the EdiSun project.
So, please feel free to use and experiment with the script!
To use this script follow these instructions:
A. Create a virtual sensor, type: custom, with name: 'Mirek' (case sensitive) and label: 'mirek' (see Dummy in hardware).
B. Create a virtual sensor, type: switch, called "HueSun" to toggle the script (or any other name will do, you can change this in the variables in the script)
C. Create a virtual sensor, type: switch, called 'oneTimeTrigger' (any name will do)
D. Get an API key at
https://openweathermap.org/price
E. Make sure you have installed the socket library:
http://www.domoticz.com/wiki/Upload_ene ... et_library
F: Change the variables in the code and activate the script 'Time' based
G: Have fun!
Please tell me what you think of it!
-- last updated script: 13-03-2017 --
Code: Select all
--
-- A. Create a virtual sesnor, type: custom, with name: 'Mirek' (case sensitive) and label: 'mirek'
-- B. Create a virtual sensor, type: switch, called 'HueSun' (any name will do) to toggle the script on/off
-- C. Create a virtual sensor, type: switch, called 'oneTimeTrigger' (any name will do) to run the script when lights are turned on
-- D. Get an API key at https://openweathermap.org/price
-- E. If you havn't already, install the socket library: http://www.domoticz.com/wiki/Upload_energy_data_to_PVoutput#Install_socket_library
-- F: Change the variables in the code and activate the script 'Time' based
--
-- Variables to customize --
local idxMirek = "xxx" -- ID of Dummy 'Mirek'
local hueBridgeIP = "xxx.xxx.xxx.xxx" -- IP Address of your Hue Bridge
local hueAPIID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -- your Bridge User Name
local lightName = nil -- nil or name of the ligt that should be changed in Domoticz, set: nil if you want to change a whole group of lights
local lightID = nil -- nil or enter the HUE(!)light ID - get it at: http://<<yourHueBridgeIP>>/debug/clip.html and fill in: url: http://<<yourHueBridgeIP>>/api/<<your UserName>>/lights/ and hit GET
local groupName = nil -- nil or If you don't want to change one light but a whole group in Domoticz, enter this groups name
local groupID = nil -- nil or enter the HUE(!) group ID - get it at: http://<<yourHueBridgeIP>>/debug/clip.html and fill in: url: http://<<yourHueBridgeIP>>/api/<<your UserName>>/groups/ and hit GET
local city = "city" -- Name of your city
local updateTimeInMin = 1 -- Time between light adjustments (in min)
local openweatherID = "xxxxxxxxxxxxxxxxxxxxxxxxx" -- Get your own (free) API key from https://openweathermap.org/price
local switchName = "HueSun" -- Name to toggle the script on/off
local oneTimeTrigger = "oneTimeTrigger" -- Switch to activate script when lights are turned on.
--
-- change everything below on your own risk --
function getTemp(sunrise, sunset, timenow, mult, defaultTemp)
sunrise = sunrise - 15*60 -- offset sunrise 15 min
sunset = sunset - 30*60 -- offset sunset 30 min
local percentDay = (timenow-sunrise)/(sunset-sunrise)
if (percentDay>=-0.06) and (percentDay<=1.1) then
ct = (6990.5+
percentDay^1*74508+
percentDay^2*-4.5021*10^5+
percentDay^3*9.5966*10^5+
percentDay^4*-8.6916*10^5+
percentDay^5*2.8073*10^5)*mult
return ct
else
return defaultTemp
end
end
function getWeather(city)
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
local config = assert(io.popen('curl "http://api.openweathermap.org/data/2.5/weather?q='..city..'&APPID='..openweatherID..'"'))
local openweather = config:read('*all')
config:close()
local jsonWeather = json:decode(openweather)
local sunrise = jsonWeather.sys.sunrise
local sunset = jsonWeather.sys.sunset
local timenow = os.time(os.date("!*t"))
--Is there extreme weather? If so write a static multiplier
local m = jsonWeather.weather.id
mult = nil
if m ~= nil then
code = m
mult = getMultFromCode(code)
end
--if we don't have a code yet, estimate from cloud cover
if mult == nil then
m = jsonWeather.clouds.all
mult = 1+.4*m/100
end
return sunrise, sunset, timenow, mult
end
function getMultFromCode(code)
if math.floor(code/100)==2 then
return 1.8
elseif math.floor(code/100)==3 then
return 1.3
elseif math.floor(code/100)==5 then
return 1.5
elseif math.floor(code/100)==7 then
return 1.7
else
return nil
end
end
function getMirek(ct)
if ct == nil then
return nil
end
mirek = 1/ct*10^6
commandArray[#commandArray + 1]={['UpdateDevice'] = idxMirek .. '|0|' .. tostring(math.floor(mirek))} -- update dummy 'Mirek' with actual value
if mirek>500 then -- Hue lamps (gen 1 and 2) can only generate colors between the mirek values 153 and 500
mirek = 500
elseif mirek<153 then
mirek = 153
end
return math.floor(mirek)
end
function setLight(whichLight, mirek)
if mirek == nil then
mirek = 500
end
local base_url = 'http://'..hueBridgeIP..'/api/'..hueAPIID..'/'
local http = require('socket.http')
local ltn12 = require('ltn12')
local transitiontime = updateTimeInMin*600 -- Hue uses miliseconds
if (otherdevices_svalues['Mirek'] >= "153" and otherdevices_svalues['Mirek'] <= "500" and math.floor(mirek) - otherdevices_svalues['Mirek'] ~= 0) or otherdevices[oneTimeTrigger] == 'On' then
if lightName ~= nil and otherdevices[lightName] == 'On' then
local id = lightID -- ID lamp
local device = 'lights/'..id..'/state'
local params = '{"ct":'..mirek..', "transitiontime":'..transitiontime..'}'
local url = base_url..device
local req_body = params
local headers = {
["Content-Type"] = "application/x-www-form-urlencoded";
["Content-Length"] = #req_body;
}
--print("url Light= "..url)
--print("Params Light= "..params)
print("Updating light "..whichLight.." with the color temperature from city "..city..". The color temperature is "..math.floor(ct).." and the mirek is "..tostring(mirek))
client, code, headers, status = http.request{url=url, headers=headers, source=ltn12.source.string(req_body), method='PUT'}
end
if groupName ~= nil and otherdevices[groupName] == 'On' then
local id = groupID -- ID groupID
local device = 'groups/'..id..'/action'
local params = '{"ct":'..mirek..', "transitiontime":'..transitiontime..'}'
local url = base_url..device
local req_body = params
local headers = {
["Content-Type"] = "application/x-www-form-urlencoded";
["Content-Length"] = #req_body;
}
--print("url Group= "..url)
--print("Params Group= "..params)
print("Updating group "..whichLight.." with the color temperature from city "..city..". The color temperature is "..math.floor(ct).." and the mirek is "..tostring(mirek))
client, code, headers, status = http.request{url=url, headers=headers, source=ltn12.source.string(req_body), method='PUT'}
end
end
end
function updateLightFromCity(whichLight, city)
sunrise, sunset, timenow, mult = getWeather(city)
ct = getTemp(sunrise, sunset, timenow, mult, 2000)
mirek = getMirek(ct)
setLight(whichLight, mirek)
end
commandArray = {}
time = os.date("*t")
if ((time.min % updateTimeInMin)==0) or otherdevices[oneTimeTrigger] == 'On' then -- update every x minutes or when lights turned on manually
if lightName ~= nil and otherdevices[switchName] == 'On' then
updateLightFromCity(lightName, city)
end
if groupName ~= nil and otherdevices[switchName] == 'On' then
updateLightFromCity(groupName, city)
end
end
return commandArray
And use this code in a second script (this will trigger the script automatically when lights are turned on):
Code: Select all
-- Variables to customize --
local name = "lightName or groupName"
local oneTimeTrigger = "oneTimeTrigger"
--------------------------------
commandArray = {}
if devicechanged[name] == 'On' and otherdevices[oneTimeTrigger] == "Off" then
commandArray[oneTimeTrigger] = 'On FOR 1'
end
return commandArray