We have moved at community.getvera.com

Author Topic: Force light level using the switch with a fibaro dimmer  (Read 9197 times)

Offline psykokwak

  • Jr. Member
  • **
  • Posts: 77
  • Karma: +0/-0
Force light level using the switch with a fibaro dimmer
« on: June 12, 2012, 04:32:19 pm »
You may have noticed that the fibaro dimmer "memorize" their level. So when you do a push of the switch, the light returns to its saved position and to force 100% level, we have to do a quick double press.
Ok but howto force 100% level when we use the switch ? (without not completely disable the dimmer function).

Well I have the solution  ;D

We need to create a scene that will be triggered each time you turn on the light in question. If you have multiple lights (dimmer modules) you can either create a scene by light (but it's not pretty) or create a trigger by light in your scene. This is the solution I will explain here. Once you have created the scene and all triggers, you need to go every Trigger "luup event" and simply write the following line:
Code: [Select]
-- replace the number by the associated device id.
lul_device = 69

This manipulation is to know what device call the scene. Now go to the tab "Luup" of the scene and write the code that will force a 100% light when using the switch.

Code: [Select]
if (lul_device == nil) then
    luup.log("Not triggered from a device")
    return false
end

local dim = luup.variable_get("urn:upnp-org:serviceId:Dimming1", "LoadLevelStatus", lul_device)
local bin = luup.variable_get("urn:upnp-org:serviceId:SwitchPower1", "Status", lul_device)

if dim == nil then dim = -1 end
if bin == nil then bin = -1 end

dim = tonumber(dim)
bin = tonumber(bin)

if (dim == 0 and bin == 1) then -- cette condition n'est vraie que si on allume la lumière depuis l'inter.
    luup.call_action("urn:upnp-org:serviceId:Dimming1", "SetLoadLevelTarget", {newLoadlevelTarget = 100}, lul_device)
end

Et voila :)


It works as follow :
- You turn on the light from the switch
- The light goes to "the saved position"
- The scene is triggered and the luup code is executed
- It forces the light to 100%

Note: If you remove the progressive dimming function (parameter 10 = 0), you will see the light go to the "temporary" position a very short time before the scene is executed. If you left the default ramps, it will be invisible.



Now we can do things even more fun such as changing light level according to the time.
I do not like the light in the morning (or night when I get up to pee), so I completed the scene as follows:

Code: [Select]
local limit = 40

if (lul_device == nil) then
    luup.log("Not triggered from a device")
    return false
end

local dim = luup.variable_get("urn:upnp-org:serviceId:Dimming1", "LoadLevelStatus", lul_device)
local bin = luup.variable_get("urn:upnp-org:serviceId:SwitchPower1", "Status", lul_device)

if dim == nil then dim = -1 end
if bin == nil then bin = -1 end

dim = tonumber(dim)
bin = tonumber(bin)

if (dim == 0 and bin == 1) then
    if (inTime("02:00", "08:30") == 1) then -- between 2 am and 8.30 am I limit the level
        luup.log("C'est la nuit. Brrrr")
        luup.call_action("urn:upnp-org:serviceId:Dimming1", "SetLoadLevelTarget", {newLoadlevelTarget = limit}, lul_device)
    else
        luup.log("C'est le jour")
        luup.call_action("urn:upnp-org:serviceId:Dimming1", "SetLoadLevelTarget", {newLoadlevelTarget = 100}, lul_device)
    end
end

The magic function "inTime(startTime, endTime)" returns 1 if the current time is between startTime and endTime and 0 otherwise.
Put in "Develop apps"> "edit lua startup"
Code: [Select]
function inTime(startTime, endTime)

    local hour = tonumber(startTime:sub( startTime:find("%d+")))
    local minute = tonumber(startTime:sub(-2))
 
    if hour and minute then
        startTime = hour * 100 + minute
    else
        luup.log("inTime: ERROR: invalid start time")
        return 0
    end
 
    hour = tonumber( endTime:sub( endTime:find("%d+") ) )
    minute = tonumber(endTime:sub(-2))
 
    if hour and minute then
        endTime = hour * 100 + minute
    else
        luup.log("inTime: ERROR: invalid end time")
        return 0
    end
 
    local currentTime = os.date("*t")
    currentTime = currentTime.hour * 100 + currentTime.min
 
    local intervalTime = (endTime - startTime) % 2400
    if (((currentTime - startTime) % 2400) < intervalTime) then
        -- I'm in
        return 1
    end

    -- I'm out
    return 0
end


Have fun :)

Offline chevdor

  • Jr. Member
  • **
  • Posts: 79
  • Karma: +0/-0
Re: Force light level using the switch with a fibaro dimmer
« Reply #1 on: June 12, 2012, 05:07:30 pm »
Thanks a lot for this post, nice idea and nice samples commented En Francais  !

Merci a toi since :-)

 2

Offline Throttleman

  • Jr. Member
  • **
  • Posts: 66
  • Karma: +0/-0
Re: Force light level using the switch with a fibaro dimmer
« Reply #2 on: June 12, 2012, 06:00:10 pm »
Very interesting!  8) My home dimmers are all Fibaro.

Offline wezzix

  • Sr. Newbie
  • *
  • Posts: 36
  • Karma: +2/-0
Re: Force light level using the switch with a fibaro dimmer
« Reply #3 on: September 13, 2012, 07:39:30 am »
I've been using this code, and have found an interesting modification. Since two clicks on a switch always sets the level to 100% by hardware, it would be nice if that still works with this code instead of always overriding. I've implemented it by checking the timestamp of LoadLevelStatus and not overriding if it has been changed within the last second (double click).

Code: [Select]
if (lul_device == nil) then
    luup.log("Not triggered from a device")
    return false
end

local dim, updated = luup.variable_get("urn:upnp-org:serviceId:Dimming1", "LoadLevelStatus", lul_device)
local bin = luup.variable_get("urn:upnp-org:serviceId:SwitchPower1", "Status", lul_device)

if dim == nil then dim = -1 end
if bin == nil then bin = -1 end

dim = tonumber(dim)
bin = tonumber(bin)

local timeSinceUpdate = os.time() - updated

if (dim == 0 and bin == 1) and timeSinceUpdate > 1 then
luup.call_action("urn:upnp-org:serviceId:Dimming1", "SetLoadLevelTarget", {newLoadlevelTarget = 50}, lul_device)
end

The above code will set the light to 50% then the light is turned on by the switch regardless of previous value, and 100% on double click as implemented by Fibaro.

Hope this helps someone.

Offline stibbzy

  • Sr. Newbie
  • *
  • Posts: 29
  • Karma: +1/-0
Re: Force light level using the switch with a fibaro dimmer
« Reply #4 on: September 26, 2015, 06:15:11 pm »
For some reason, this works fine to turn the lights on for me with one press. But after about 10 seconds, the lights turn off again :(

Offline conchordian

  • Sr. Member
  • ****
  • Posts: 326
  • Karma: +4/-1
Re: Force light level using the switch with a fibaro dimmer
« Reply #5 on: September 27, 2015, 02:46:46 am »
Another way, if you have a fairly recent firmware is to add something lke this to your startup lua, which looks out for button presses:

Code: [Select]
-- Set up variable-watch for device 308 (Watch for any button press on Light 308)
luup.variable_watch("ButtonPressed308delay","urn:micasaverde-com:serviceId:SceneController1", "sl_SceneActivated",308)

-- Process variable-watch callback for device 308. Run function after 1 second to give LastSceneID a chance to update.
function ButtonPressed308delay()
luup.call_delay("ButtonPressed308", 1)
end

-- Process variable-watch callback for device 308. Run scene 160, if button single clicked (ID:13)
function ButtonPressed308()
if (luup.variable_get("urn:micasaverde-com:serviceId:SceneController1", "LastSceneID", 308) == "13") then
luup.call_action("urn:micasaverde-com:serviceId:HomeAutomationGateway1", "RunScene", {SceneNum = 160}, 0)
end
end

And then just make your scene no. 160 do whatever you want with your lights.

http://forum.micasaverde.com/index.php/topic,15855.msg200101.html#msg200101 has more examples and info.
« Last Edit: September 27, 2015, 02:48:22 am by conchordian »