Jump to content

Welcome to Smart Home Forum by FIBARO

Dear Guest,

 

as you can notice parts of Smart Home Forum by FIBARO is not available for you. You have to register in order to view all content and post in our community. Don't worry! Registration is a simple free process that requires minimal information for you to sign up. Become a part of of Smart Home Forum by FIBARO by creating an account.

 

As a member you can:

  •     Start new topics and reply to others
  •     Follow topics and users to get email updates
  •     Get your own profile page and make new friends
  •     Send personal messages
  •     ... and learn a lot about our system!

 

Regards,

Smart Home Forum by FIBARO Team


  • 3

Lua script for Motion sensor and auto light


MDC

Question

Hello, can somebody share a script for auto turn on lights when motion sensor breaks and keeps on during motion detected? And lux setting also.

i have a script currently buy some time happen to crash.

 

thanks

Link to comment
Share on other sites

Recommended Posts

  • 0

Hi

@Wegerhoff thanks for sharing. I like the idea. Did u tried it on practice? I mean, is there a chance for the light to remain ON when it should be turned OFF already? (like bad signal etc etc)

Link to comment
Share on other sites

  • 0
26 minutes ago, jack.daniels said:

Did u tried it on practice?

more than 1y - like a charm

 

proof

 

Please login or register to see this spoiler.

 

  • Thanks 1
Link to comment
Share on other sites

  • 0

@10der I was curious about the association solution. The scene solution works fine for sure (but I suspect starting scenes may cuase  503 or lethal death of the STM controller of HCL). Facing this pretty much often last monthes.

Link to comment
Share on other sites

  • 0

Yes, 503 was occupied two times this month and once when I was in work trip in Kharkiv...:(

Edited by 10der
  • Like 1
Link to comment
Share on other sites

  • 0
6 hours ago, jack.daniels said:

Did u tried it on practice? I mean, is there a chance for the light to remain ON when it should be turned OFF already? (like bad signal etc etc)

 

Using this with 5 motion sensors. Lights is always switched off like it should be.

Another advantage: Associations work without HC2, means still working when HC2 is missing or crashes.

  • Like 1
Link to comment
Share on other sites

  • 0
  • Inquirer
  • 2 hours ago, Wegerhoff said:

     

    Using this with 5 motion sensors. Lights is always switched off like it should be.

    Another advantage: Associations work without HC2, means still working when HC2 is missing or crashes.

     

    Confirm, work great but i use LUA code, has many options.

    7 hours ago, 10der said:

    Yes, 503 was occupied two times this month and once when I was in work trip in Kharkiv...:(

     

    I buy from aliexpress a smart gsm socket, in case of failure just give a sms and reset.

    Also you can use gsm relay, but socket is easy to install just put sim inside and plug hc2.

    I use also for server and router, has 3 plugs.

     

    Please login or register to see this link.

    Edited by MDC
    • Thanks 1
    Link to comment
    Share on other sites

    • 0
    5 hours ago, MDC said:

    I buy from aliexpress

    Omg, yes! I have SonOff (~10$) and yes we can cut power and back again

    but! sometimes HC2 booting  to recovery mode and stay here while user press continue button...

     

    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • On 11/18/2018 at 8:41 AM, 10der said:

    some comments here

    you may schedule lights (and level light) by weekday also.

     

    for example, I am a Jew, for example,:) I have on Friday for Shabbat. :)

    so, 

    Please login or register to see this code.

    Mo-Th from 18:00 till 6 morning

    Fr and Sat from Sunset till 23:35

    and Su back to normal

     

     

    if you do not want to control lights by LUX simple make Ids is empty

     

    Please login or register to see this code.

    if you wanna control lights by many motions simple add Ids by a comma

     

    Please login or register to see this code.

    if you wanna  lights many lights simple add Ids by a comma

     

    Please login or register to see this code.

    quick update.

     

    now you may control all lights in house via single scene

     

     

    Hello,

    I find something i'm not sure if it' a feature or a bug in your code.

     

    I have module ID 100 for example and set your code to turn light on between sunset and sunrise, it's work like a charm, BUT, i if i'm before sunset and try to turn on light from switch of fibaro app, your code auto turn it off. So i deduce that code let that ID 100 that i set for to be on only in interval mentioned above. In rest turn it off.

     

    Same whit lux level, if i set level to 50 and lux sensor is below 50 i can turn on by app/ switch and also turn on on movement, but if lux go above 50 an i try to turn on, will turn off in 1 second.

     

     

    Link to comment
    Share on other sites

    • 0

    no manual checks.developed.

     

    ok. I can provide my full script here.

     

    Please login or register to see this code.

     

    Link to comment
    Share on other sites

    • 0
  • Inquirer
  •  

     you lose me here:)) it's to complex

    Can be done to check if manual operated to bypass auto?

     

     

    Edited by MDC
    Link to comment
    Share on other sites

    • 0

    PS:

    door_ignore - if you use a sensor is a door sensor and you forgot to close the door - can ignore this fact.:)

    exclusion - no light if some devices in this array if "on". for example you have a big room with lighting (deviceId 123) and backside light lamp triggering by motion (deviceId 321)  so, if 123 is lighting no needing turn on the single lamp by motion.  

    exclusion = { 123  }

    timeout_manual - if set then can be used as timeout when user turn light by a switch (or app) manually otherwise used default timeout

    manual = true - no sensors at all. just check timeout when user turn device manually

     

        Fence = {
            name = "sddsds",
            sensors = {},
            powers = {679},
            timeout = 60 * 30,
            manual = true
        },
     

     

    about

    Bathroom_WC = {
           name = "WC - ground floor",
            sensors = {891, 732},
            powers = {1094},
            door_ignore = true,
            timeout = 60 * 5,
            times = {
                ["$Sunset..$SunriseTwilight"] = {
                    timeout = 60 * 15
                },
            },
        },

     

    I used two sensors here

    732 - its door sensor

    891 - motion sensor

    door_ignore = true - cuz my wife forget to close the door... without this param lighting will wait for closing the door!

    timeout = default timeout, so if you turning light on at the day it turned off after 5 min

    times - no comments

    why timeout again? it's overriding. so, in the evening and the night timeout = 15 min.

    also, for example, you may any others override params. for example, timeout_manual... and if you turn on at the night manually script turned off after a this period...

     

     

     

     

     

     

    about predefined values.

     

    you can use on;y $Sunset and $Sunrise. also use can add or sub minutes.

    times = "$Sunset-15..$Sunrise+15"

     

    also you can use own any predefined values (string in time format HH:MM) but you must init this values via global values panel and keep it actually.

    for example

    you create global value "Night" set value 23:00

    now you can use it in script

    times = "$Sunset-15..$Night"

     

     

     

    Edited by 10der
    Link to comment
    Share on other sites

    • 0

    Hi Folks,

     

    @10der I really need your help. Your first script looks to be a PERFECT solution for me and I have been struggling with my bath light for weeks! Honestly I'm close to throw HC2 out of the window. so... I used your script and nothing is turning on...  I just have this message

    Please login or register to see this attachment.

    Please login or register to see this attachment.

     

    What I have done wrong? 

    Begging for help :)

    Link to comment
    Share on other sites

    • 0
    1 hour ago, TripleZulu said:

    Hi Folks,

     

    @10der I really need your help. Your first script looks to be a PERFECT solution for me and I have been struggling with my bath light for weeks! Honestly I'm close to throw HC2 out of the window. so... I used your script and nothing is turning on...  I just have this message

    Please login or register to see this attachment.

    Please login or register to see this attachment.

     

    What I have done wrong? 

    Begging for help :)

     

    1) I have updated script you script is old

    2) please fix my bug find min_lux and change tp dev.min_lux

    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • 41 minutes ago, 10der said:

     

    1) I have updated script you script is old

    2) please fix my bug find min_lux and change tp dev.min_lux

     

    2 hours ago, TripleZulu said:

    Hi Folks,

     

    @10der I really need your help. Your first script looks to be a PERFECT solution for me and I have been struggling with my bath light for weeks! Honestly I'm close to throw HC2 out of the window. so... I used your script and nothing is turning on...  I just have this message

    Please login or register to see this attachment.

    Please login or register to see this attachment.

     

    What I have done wrong? 

    Begging for help :)

     

    Can you give use more details for NEST ?

    You have a lua script, plugin....

     

     

    Please login or register to see this attachment.

    Link to comment
    Share on other sites

    • 0

    Dear 10der. 

    First of all, thanks for prompt replay.... but it's still not working

    Now I have this [DEBUG] 16:25:04: 2018-11-23 16:25:04.483997 [ fatal] Unknown exception: /opt/fibaro/scenes/63.lua:197: attempt to compare number with nil

    Here is the entire code :

     


    --[[
    %% autostart
    %% properties
    %% weather
    %% events
    %% globals
    --]]

    local lighting = {
        Bathroom_WC = {
            -- timeout in minutes
            timeout = 15,
            -- motion sensors IDs
            sensors = {
                95
            },
            -- luxs IDs
            luxs = {
                97
            },
            -- lights IDs
            lights = {
                -- 941
                57,181,190
            },
            -- minumum lux for lighting
            min_lux = 20,
            -- when
            time_interval = "13:00..06:00",
            -- from dusk till dawn
            --time_interval = "$Sunset-15..$Sunrise+10"

            -- for dimmers + time
            --time_interval = {
            --    ["18:00..06:00"] = 99,
            --    ["06:00..18:00"] = 20
            --},

            -- for dimmer you can set default level here
           -- light_level = 99
        },
        Another_room = {
            -- own params here
        }
    }

    -- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    if require then
        require("fibaro")
    end

    local function between(timestr)
        local dayMap = {
            ["1"] = 1,
            ["2"] = 2,
            ["3"] = 3,
            ["4"] = 4,
            ["5"] = 5,
            ["6"] = 6,
            ["7"] = 7
        }

        --
        local smap = {
            ["Sunset"] = "sunsetHour",
            ["Sunrise"] = "sunriseHour",
            ["Evening"] = "sunsetHour",
            ["Morning"] = "sunriseHour"
        }

        local function trim(s)
            return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
        end

        local function offset(s, o, p)
            if (not (o and p)) or o == "" then
                return s
            end
            local h, m = s:match("(%d+):(%d+)")
            local t = 60 * h + m + (o == "+" and p or -tonumber(p))
            return string.format("%02d:%02d", math.floor(t / 60), t % 60)
        end

        local function sec2hmStr(hms)
            local h, m, s = math.floor(hms / 3600), math.floor((hms % 3600) / 60), hms % 60
            return string.format("%02d:%02d", h, m)
        end

        local function betw(interv)
            local dt, start, stop = os.date("*t"), interv:match("^([%S%a0-9%.%:]+) ?(.*)")
            stop = stop == "" and start or stop
            local d1, h1, m1 = start:match("^([%S%a%.]-)%.?(%d+):(%d+)$")
            local d2, h2, m2 = stop:match("^([%S%a]-)%.?(%d+):(%d+)$")

            d1 = d1 == "" and (dt.wday == 1 and 7 or dt.wday - 1) or dayMap[d1]
            d2 = d2 == "" and d1 or dayMap[d2]
            local d = dt.wday == 1 and 7 or dt.wday - 1
            if not (d >= d1 and d <= d2) then
                return false
            end
            m1, m2, t = h1 * 60 + m1, h2 * 60 + m2, dt.hour * 60 + dt.min
            if (m1 <= m2) then
                return m1 <= t and t <= m2 -- 01:00-02:00
            else
                return m1 <= t or t <= m2 -- 23:00-21:00
            end
        end
        timestr =
            timestr:gsub(
            "$(%w+)([%+%-]?)(%d*)",
            function(s, o, p)
                return offset(smap and fibaro:getValue(1, smap) or fibaro:getGlobal(s), o, p)
            end
        )
        for _, interv in ipairs(split(timestr, ",")) do
            if betw(trim(string.gsub(interv, "%.%.", " "))) then
                return true
            end
        end
        return false
    end

    local function inArray(needle, haystack)
        for i, n in ipairs(haystack) do
            if (tonumber(needle) == tonumber(n)) then
                return true
            end
        end
        return false
    end

    local function getLux(dev)
        local totalLux = 0
        local averigeLux = 0
        if #dev.luxs > 0 then
            for i = 1, #dev.luxs do
                totalLux = totalLux + tonumber(fibaro:getValue(dev.luxs, "value"))
            end
            averigeLux = math.floor(totalLux / #dev.luxs)
        else
            averigeLux = 1000
        end
        return averigeLux
    end

    local function getMotionStatus(dev)
        if dev.sensors then
            for i, n in ipairs(dev.sensors) do
                if (tonumber(fibaro:getValue(n, "value")) > 0) then
                    return 1
                end
            end
            return 0
        else
            return 0
        end
    end

    local function getLastBreach(dev)
        local breach = 0
        if dev.sensors then
            for i, n in ipairs(dev.sensors) do
                local value = tonumber(fibaro:getValue(n, "lastBreached"))
                if (value > breach) then
                    breach = value
                end
            end
        end
        return breach
    end

    local function getLlght(dev)
        if dev.lights then
            for i, n in ipairs(dev.lights) do
                local value = tonumber(fibaro:getValue(n, "value"))
                if (value > 0) then
                    return value
                end
            end
        end
        return 0
    end

    local function setLlght(dev, value)
        for i, n in ipairs(dev.lights) do
            local lightType = fibaro:getType(n)
            if (lightType == "com.fibaro.multilevelSwitch" or lightType == "com.fibaro.FGD212") then
                -- dimmer
                fibaro:call(n, "setValue", value)
            elseif (lightType == "com.fibaro.FGRGBW441M") then
                -- RGBW
                -- TDOD:
                local r, g, b, w = 0, 0, 0, 255
                fibaro:call(n, "setColor", r, g, b, w)
            else
                -- switch
                if value > 0 then                <------- line 197
                    fibaro:call(n, "turnOn")
                else
                    fibaro:call(n, "turnOff")
                end
            end
        end
    end

    local function isTime(dev)
        if dev.time_interval then
            if type(dev.time_interval) == "table" then
                for k, v in pairs(dev.time_interval) do
                    if between(k) then
                        dev.light_level = v
                        return true
                    end
                end
                return false
            else
                return between(dev.time_interval)
            end
        else
            return true
        end
    end

    while true do
        for k, dev in pairs(lighting) do
            if isTime(dev) and getMotionStatus(dev) > 0 then
                local lux = getLux(dev)
                if lux < dev.min_lux then
                    if getLlght(dev) == 0 then
                        setLlght(dev, light_level)
                    end
                end
            else
                if os.time() - getLastBreach(dev) > 60 * (dev.timeout or 60) then
                    if getLlght(dev) > 0 then
                        setLlght(dev, 0)
                    end
                end
            end
        end
        fibaro:sleep(1000)
    end

     

     

    26 minutes ago, MDC said:

     

     

    Can you give use more details for NEST ?

    You have a lua script, plugin....

     

     

     

    5

    I've found the lua code somwhere in the net. I guess it was

    Please login or register to see this link.

     

    Please login or register to see this link.

     

    Does NOT work as I expected! but.... I'm a newbie so maybe I did something wrong.

    I can send you the lua but I guess you will find on his website more explanation.  

    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • 6 minutes ago, TripleZulu said:
    • Please login or register to see this link.

    • Please login or register to see this link.

    • Please login or register to see this link.

    • Please login or register to see this link.

    Dear 10der. 

    First of all, thanks for prompt replay.... but it's still not working

    Now I have this [DEBUG] 16:25:04: 2018-11-23 16:25:04.483997 [ fatal] Unknown exception: /opt/fibaro/scenes/63.lua:197: attempt to compare number with nil

    Here is the entire code :

     


    --[[
    %% autostart
    %% properties
    %% weather
    %% events
    %% globals
    --]]

    local lighting = {
        Bathroom_WC = {
            -- timeout in minutes
            timeout = 15,
            -- motion sensors IDs
            sensors = {
                95
            },
            -- luxs IDs
            luxs = {
                97
            },
            -- lights IDs
            lights = {
                -- 941
                57,181,190
            },
            -- minumum lux for lighting
            min_lux = 20,
            -- when
            time_interval = "13:00..06:00",
            -- from dusk till dawn
            --time_interval = "$Sunset-15..$Sunrise+10"

            -- for dimmers + time
            --time_interval = {
            --    ["18:00..06:00"] = 99,
            --    ["06:00..18:00"] = 20
            --},

            -- for dimmer you can set default level here
           -- light_level = 99
        },
        Another_room = {
            -- own params here
        }
    }

    -- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    if require then
        require("fibaro")
    end

    local function between(timestr)
        local dayMap = {
            ["1"] = 1,
            ["2"] = 2,
            ["3"] = 3,
            ["4"] = 4,
            ["5"] = 5,
            ["6"] = 6,
            ["7"] = 7
        }

        --
        local smap = {
            ["Sunset"] = "sunsetHour",
            ["Sunrise"] = "sunriseHour",
            ["Evening"] = "sunsetHour",
            ["Morning"] = "sunriseHour"
        }

        local function trim(s)
            return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
        end

        local function offset(s, o, p)
            if (not (o and p)) or o == "" then
                return s
            end
            local h, m = s:match("(%d+):(%d+)")
            local t = 60 * h + m + (o == "+" and p or -tonumber(p))
            return string.format("%02d:%02d", math.floor(t / 60), t % 60)
        end

        local function sec2hmStr(hms)
            local h, m, s = math.floor(hms / 3600), math.floor((hms % 3600) / 60), hms % 60
            return string.format("%02d:%02d", h, m)
        end

        local function betw(interv)
            local dt, start, stop = os.date("*t"), interv:match("^([%S%a0-9%.%:]+) ?(.*)")
            stop = stop == "" and start or stop
            local d1, h1, m1 = start:match("^([%S%a%.]-)%.?(%d+):(%d+)$")
            local d2, h2, m2 = stop:match("^([%S%a]-)%.?(%d+):(%d+)$")

            d1 = d1 == "" and (dt.wday == 1 and 7 or dt.wday - 1) or dayMap[d1]
            d2 = d2 == "" and d1 or dayMap[d2]
            local d = dt.wday == 1 and 7 or dt.wday - 1
            if not (d >= d1 and d <= d2) then
                return false
            end
            m1, m2, t = h1 * 60 + m1, h2 * 60 + m2, dt.hour * 60 + dt.min
            if (m1 <= m2) then
                return m1 <= t and t <= m2 -- 01:00-02:00
            else
                return m1 <= t or t <= m2 -- 23:00-21:00
            end
        end
        timestr =
            timestr:gsub(
            "$(%w+)([%+%-]?)(%d*)",
            function(s, o, p)
                return offset(smap and fibaro:getValue(1, smap) or fibaro:getGlobal(s), o, p)
            end
        )
        for _, interv in ipairs(split(timestr, ",")) do
            if betw(trim(string.gsub(interv, "%.%.", " "))) then
                return true
            end
        end
        return false
    end

    local function inArray(needle, haystack)
        for i, n in ipairs(haystack) do
            if (tonumber(needle) == tonumber(n)) then
                return true
            end
        end
        return false
    end

    local function getLux(dev)
        local totalLux = 0
        local averigeLux = 0
        if #dev.luxs > 0 then
            for i = 1, #dev.luxs do
                totalLux = totalLux + tonumber(fibaro:getValue(dev.luxs, "value"))
            end
            averigeLux = math.floor(totalLux / #dev.luxs)
        else
            averigeLux = 1000
        end
        return averigeLux
    end

    local function getMotionStatus(dev)
        if dev.sensors then
            for i, n in ipairs(dev.sensors) do
                if (tonumber(fibaro:getValue(n, "value")) > 0) then
                    return 1
                end
            end
            return 0
        else
            return 0
        end
    end

    local function getLastBreach(dev)
        local breach = 0
        if dev.sensors then
            for i, n in ipairs(dev.sensors) do
                local value = tonumber(fibaro:getValue(n, "lastBreached"))
                if (value > breach) then
                    breach = value
                end
            end
        end
        return breach
    end

    local function getLlght(dev)
        if dev.lights then
            for i, n in ipairs(dev.lights) do
                local value = tonumber(fibaro:getValue(n, "value"))
                if (value > 0) then
                    return value
                end
            end
        end
        return 0
    end

    local function setLlght(dev, value)
        for i, n in ipairs(dev.lights) do
            local lightType = fibaro:getType(n)
            if (lightType == "com.fibaro.multilevelSwitch" or lightType == "com.fibaro.FGD212") then
                -- dimmer
                fibaro:call(n, "setValue", value)
            elseif (lightType == "com.fibaro.FGRGBW441M") then
                -- RGBW
                -- TDOD:
                local r, g, b, w = 0, 0, 0, 255
                fibaro:call(n, "setColor", r, g, b, w)
            else
                -- switch
                if value > 0 then                <------- line 197
                    fibaro:call(n, "turnOn")
                else
                    fibaro:call(n, "turnOff")
                end
            end
        end
    end

    local function isTime(dev)
        if dev.time_interval then
            if type(dev.time_interval) == "table" then
                for k, v in pairs(dev.time_interval) do
                    if between(k) then
                        dev.light_level = v
                        return true
                    end
                end
                return false
            else
                return between(dev.time_interval)
            end
        else
            return true
        end
    end

    while true do
        for k, dev in pairs(lighting) do
            if isTime(dev) and getMotionStatus(dev) > 0 then
                local lux = getLux(dev)
                if lux < dev.min_lux then
                    if getLlght(dev) == 0 then
                        setLlght(dev, light_level)
                    end
                end
            else
                if os.time() - getLastBreach(dev) > 60 * (dev.timeout or 60) then
                    if getLlght(dev) > 0 then
                        setLlght(dev, 0)
                    end
                end
            end
        end
        fibaro:sleep(1000)
    end

     

     

     

    • Please login or register to see this link.

    • Please login or register to see this link.

    • Please login or register to see this link.

    • Please login or register to see this link.

    I've found the lua code somwhere in the net. I guess it was

    Please login or register to see this link.

     

    Please login or register to see this link.

     

    Does NOT work as I expected! but.... I'm a newbie so maybe I did something wrong.

    I can send you the lua but I guess you will find on his website more explanation.  

     

    Please share whit us.

    Thanks

    Link to comment
    Share on other sites

    • 0
    5 minutes ago, MDC said:

     

    Please share whit us.

    Thanks

     

    not a problem :)

    as I remember correctly you have to create variable temp first and token from IFTTT

     

    --[[
    %% properties
    %% events
    %% globals
    temp
    --]]


    local param1 = fibaro:getGlobal("temp")
    local key = “Yb2P3z**************zVCKE”  < ----  your token from ifttt 
    local event = 'temp'

    local url = 'https://maker.ifttt.com/trigger/'..event..'/with/key/'..key..'?value1='..param1
    print (url)

    local http = net.HTTPClient()  
      http:request(url, {
          success = function(resp)
            if resp.status == 200 then
            
              fibaro:debug(resp.status)
              
            else
              fibaro:debug(resp.status)
           
            end
          end
        })

     

    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • 3 minutes ago, 10der said:

    @MDC ok. I'll create a new post with clear script!

     

     

    Link please

     

    Link to comment
    Share on other sites

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.

    Guest
    Answer this question...

    ×   Pasted as rich text.   Paste as plain text instead

      Only 75 emoji are allowed.

    ×   Your link has been automatically embedded.   Display as a link instead

    ×   Your previous content has been restored.   Clear editor

    ×   You cannot paste images directly. Upload or insert images from URL.

    ×
    ×
    • Create New...