Hue lights to reflect the sunlight

Moderator: leecollings

Post Reply
Dropshot
Posts: 44
Joined: Tuesday 20 December 2016 22:29
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Hue lights to reflect the sunlight

Post by Dropshot »

-- disclaimer: I'm new to this forum, so if I misplaced this question, please mod it to a correct place. --

I've been experimenting with creating events in Domoticz to control my Hue lights. Although I've achieved running event based scripts, I would like to have a script running on the background to control the color and intensity of the lights. To be more exact, to reflect the color of the sun, so white during the day and orange/red during the sunset and in the evening. I want this to be smooth, so you wont notice the change.

To achieve this, I've found an android app that does this, the sunn app, but I don't like to have an app on my mobile to control this (for instance, it should also work when I'm not around). Since I've running my Raspberry Pi with Domoticz 24/7, I would like this to control the lights.

My question therefore is, would it be possible to create a script that does this using my Raspberry Pi? Or does there exist another way to create this effect?
trixwood

Re: Hue lights to reflect the sunlight

Post by trixwood »

http://www.domoticz.com/wiki/Real-time_ ... structions

(and search the forum for thread)

I would suggest you use that... you now have sensors which shows the sun altitude and azimuth... on the sun altitude sensor add an devicechanged lua event to it, which controls the light colour based on the height of the sun. I think minus angle is night,and positive angle is day)

which colour to choose and how to slowly move from one colour to another exercise :-)

But it gives you a start :-)
sion
Posts: 113
Joined: Friday 08 January 2016 12:32
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Hue lights to reflect the sunlight

Post by sion »

I do something like this.
The lights gradually dim up, over 45 mins, from off - to a fairly bright white - starting about 45 mins before sunset.

I created the bright scene on the hue hub, then set a hue timer for 1 min - with a 45 min fade.
This timer can be accessed from devices in domoticz, and triggered with a script at the desired time.
I just set a dummy switch, and linked the script to the on action - then set a timer for on 45 mins before sunset.

Then on sunset, I do the same thing- that gradually turns the lights down to my standard evening scene.

For the rest, I just use the hue hub.
At 9.30 pm they fade a bit warmer over the next hour.
Then between 10.30 and 11.30 they fade down quite time, and a mix of warm orange and red.

Seems to work well for us :)
running domoticz 3.4834 on rpi2, with
Hue bridge / bulbs.
lightwave rf sockets, mood controlers, sensors & contacts.
Home bridge / Siri.
Ha bridge / echo Alexa.
Hard wired alarm system - setting home / away status.

Next: harmony hub.
Dropshot
Posts: 44
Joined: Tuesday 20 December 2016 22:29
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Hue lights to reflect the sunlight

Post by Dropshot »

trixwood wrote:http://www.domoticz.com/wiki/Real-time_ ... structions

(and search the forum for thread)

I would suggest you use that... you now have sensors which shows the sun altitude and azimuth... on the sun altitude sensor add an devicechanged lua event to it, which controls the light colour based on the height of the sun. I think minus angle is night,and positive angle is day)

which colour to choose and how to slowly move from one colour to another exercise :-)

But it gives you a start :-)
Trixwood, thank you for your response. I've these sensors working now, but I've no experience with creating Lua scripts myself, so if someone has made or found a script that uses these sensors to change the colors and brightness of the lights, please share this with me, I would be really grateful!
trixwood

Re: Hue lights to reflect the sunlight

Post by trixwood »

To change color you can execute the following command in lua (os.execute):

you have to replace the value's, ip and lamp id... and adapt the values in relation to the other sensors you want to use, with some logic.

Code: Select all

curl --request PUT --data "{\"on\": true,\"bri\":254,\"hue\": 53247,\"sat\":255,\"transitiontime\":0}" http://10.0.0.90/api/NfiepRsgYOURUSERNAMEFROMHARDWAREpRsg/lights/17/state
you can try this command in the terminal...

You can look here for the color value's

https://www.developers.meethue.com/docu ... e-concepts
Dropshot
Posts: 44
Joined: Tuesday 20 December 2016 22:29
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Hue lights to reflect the sunlight

Post by Dropshot »

I found this, its written in Julia language, but it does what I meant to achieve: https://www.hackster.io/team-edisun/edi ... 9&offset=4

I'll try to make a Lua script to do something similar, but since I've no experience in doing so, I'm secretly hoping someone wants to create this too and can help me get started.. :)
Dropshot
Posts: 44
Joined: Tuesday 20 December 2016 22:29
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Hue lights to reflect the sunlight

Post by Dropshot »

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
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest