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


  • 0

Question

Posted

Hi all,

 

I'm writing a scene for full automation of windows blinds.

 

I need to check a value against all the values in a table if it is smaller or not.

 

So far I have come up with:

 

local StateAll = { }
  StateAll = { value1, value2, value3, value4, value5, valu6, value7, value8, value9, value10, value11}
local Status1= 0
for i = 1, 11 do
    if value1<= StateAll then
      Status1= Status1+ 1
      end
end

if Status1== 11 then
    local Trigger1= true
    fibaro:setGlobal('Trigger1', true)
      else
        local Trigger1= false
        fibaro:setGlobal(''Trigger1', false)
end

 

I works but I think it is not the proper way to do that check. 

 

Can anyone suggest an easier code?

 

Thank you

Recommended Posts

  • 0
Posted

These two are more elegant and generic approaches:

Please login or register to see this code.

or

Please login or register to see this code.

  • 0
  • Inquirer
  • Posted

    Yes something like this I was looking for.  More elegant

    Please login or register to see this image.

    /emoticons/default_smile.png" alt=":)" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" />

     

    But the first one returns something like [ERROR] 21:04:01: line 116: '}' expected (to close '{' at line 114) near 'for'

     

    And the second option also returns a '}' expected to close

     

    Any thoughts ?

    • 0
  • Inquirer
  • Posted

    My bad. Was a "{" inserted somewhere by mistake... functions seem to be working

    Please login or register to see this image.

    /emoticons/default_smile.png" alt=":)" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" /> Thank you very much

    Please login or register to see this image.

    /emoticons/default_smile.png" alt=":)" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" />

     

    A question thou if I may:

    table.sort(StateAll)

    if v < StateAll [1]

     

    [1] is the step ? meaning if I put 2 will it check only every other value?

    What if I would like to check only against value9, value10 and value11 ?

     

    Regards

    • 0
    Posted

    I'm not sure I understand the question, so I've used my imagination to produce 3 versions. The are build on the work of Brick.

     

    Please login or register to see this code.

    • 0
    Posted

    Please login or register to see this code.

    function isLowerThan(threshold, ...)

    lowest=true

    for _,v in pairs({...}) do

    if v <= threshold then

    lowest=false

    break

    end

    end

    return lowest

    end

    function setTrigger1(threshold, ...)

    if isLowerThan(threshold, ...) then

    fibaro:debug("threshold is lower than any table value.")

    fibaro:setGlobal('Trigger1', true)

    else

    fibaro:debug("Some table value is lower than threshold.")

    fibaro:setGlobal('Trigger1', false)

    end

    end

    setTrigger1(23, 21,24)

    setTrigger1(23, 24,25,26,24) -- any number of arguments!

    • 0
    Posted

    Please login or register to see this code.

    values = {21,22,23,24,25,24,21} -- any number of values.

    function isLowerThan(threshold, valueTable, ...)

    lowest=true

    for _,v in pairs({...}) do

    if valueTable[v] <= threshold then

    lowest=false

    break

    end

    end

    return lowest

    end

    -- Arguments: a numerical value to compare with,

    -- a table containing numerical values,

    -- followed by any number of arguments that

    -- function as indexes into the "values" table.

    function setTrigger1(threshold, valueTable, ...)

    if isLowerThan(threshold, valueTable, ...) then

    fibaro:debug("threshold is lower than any table value.")

    fibaro:setGlobal('Trigger1', true)

    else

    fibaro:debug("Some table value is lower than threshold.")

    fibaro:setGlobal('Trigger1', false)

    end

    end

    setTrigger1(23,values, 1,4) -- check element 1 and 4 ("21 and 24")

    setTrigger1(23,values, 4,5) -- check element 4 and 5 ("24 and 25")

    -- Special case: if you do not specify an index to compare with,

    -- the fuction acts as if threshold is lower than any element

    setTrigger1(23,values) -- check element 4 and 5 ("24 and 25")

    • 0
  • Inquirer
  • Posted

    wow this is very advanced LUA , for me at least

    Please login or register to see this image.

    /emoticons/default_smile.png" alt=":)" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" />

     

    To clarify my question: I wanted to be able to also check the table only against certain values from it.

     

    From the first original example:

     

    v= your  value to check

    StateAll = { value1, value2, value3, value4, value5, valu6, value7, value8, value9, value10, value11}

    for i=1 , #StateAll do

    m=math.min(StateAll [i],m or StateAll [1])

    end

     

    if v<

    then    fibaro:setGlobal('Trigger1', true)

    else    fibaro:setGlobal(''Trigger1', false) end

     

     

    I found out that if I put i=4 for example it will check v only against value4 to value11.

     

    But what if I would like to check v only against value1 and value5 for example?  setting i=1,5 doesn't work

    Please login or register to see this image.

    /emoticons/default_sad.png" alt=":(" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" />

     

    Regards

    • 0
    Posted

    No, "for i=1 , 5 do" means "from 1 to 5" - not "1 and 5". If you want to do 1 and 5, you need "solution 3". I'll see if I can make a solution that is easier to understand for you, solution 3 contains "varargs" and that is something you never see on this forum. BTW your original question is "not runnable code". And I always like to test my code, so please give me a minute to convert that into "runnable code".

    • 0
    Posted

    Please login or register to see this code.

    v=23 -- your value to check

    StateAll={21,22,23,24,25,24,21}

    -- StateAll={ value1, value2, value3, value4, value5, valu6, value7, value8, value9, value10, value11}

    -- A table containing the indices of the values you want to check...

    -- So 1 means "value1" and 2 means "value2" and so on.

    check={1,5}

    for _,i in ipairs(check) do

    m=math.min(StateAll, m or StateAll)

    end

    if v<m

    then fibaro:setGlobal('Trigger1', true)

    else fibaro:setGlobal('Trigger1', false) end

    • 0
  • Inquirer
  • Posted

    Ah i understand

    Please login or register to see this image.

    /emoticons/default_smile.png" alt=":)" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" />  will test this soon:) Thank you

    • 0
  • Inquirer
  • Posted

    Hi,

     

    I did check and is working. sort of. 

    Point is that all the LUA codes with the "math.min" work as soon as i save the scene, but after some time like 1-2 hours they start to return the same number - like they get stuck somewhere.

     

    But the LUA with table.sort and just checking against the first value from the sorted table works as expected without getting stuck.

     

    weird.

     

    Regards

    • 0
    Posted

    Please login or register to see this code.

    v=23 -- your value to check

    StateAll={21,22,23,24,25,24,21}

    -- StateAll={ value1, value2, value3, value4, value5, valu6, value7, value8, value9, value10, value11}

    -- A table containing the indices of the values you want to check...

    -- So 1 means "value1" and 2 means "value2" and so on.

    check={1,5}

    m=nil -- without this, m retains value if you loop this code

    for _,i in ipairs(check) do

    m=math.min(StateAll, m or StateAll)

    end

    if v<m

    then fibaro:setGlobal('Trigger1', true)

    else fibaro:setGlobal('Trigger1', false) end

    • 0
  • Inquirer
  • Posted

    HI Peter,

     

     

    I made this script  -runnable this time -  based on some examples from this forum.

     

    What the script does: it checks the status of different kind of sensors in the house and stores the result in some tables, with the device id and value of the sensor.

    There is also a table with the device id and the last status change.

     

    From the debug it seems to be working.

     

    What I would like now is to be able to find out the smallest value from the FibaroMotionSensorsState table.  I will create after tables for the state of the other sensor types.

     

    Also the scene seems to be kinda slow... I wonder what impact would it have on HC2 if I run it every 3 minutes.

     

    Could you test it please?

     

    Regards

     

    --[[
    %% properties

    %% globals
    --]]

       
       FibaroMotionSensors = {}
       FibaroMotionSensorsState = {}
       FibaroDoorSensors = {}
       UBSMotionSensor = {}
       for i = 0, 300 do
          if   fibaro:getType(i) == 'com.fibaro.doorSensor' then
             value = fibaro:getValue(i, 'value')
             model = fibaro:getType(i)
             FibaroDoorSensors = value
             --FibaroMotionSensors = model    
        else
        if  fibaro:getType(i) == 'com.fibaro.FGMS001' then
              value = fibaro:getValue(i, 'value')
             model = fibaro:getType(i)
             FibaroMotionSensors = value
             FibaroMotionSensorsState =  tonumber(os.time() - fibaro:getModificationTime(i, 'value'))  
          else
         if  fibaro:getType(i) == 'com.fibaro.motionSensor' then
             value = fibaro:getValue(i, 'value')
             model = fibaro:getType(i)
             UBSMotionSensor = value 
     
          end
          end
          end
       end

    for k, v in pairs(FibaroMotionSensors) do
      fibaro:debug("Motion Sensor Device ID:  "..k.."  Device Value : "..v)
    end

    for k, v in pairs(FibaroMotionSensorsState) do
      fibaro:debug("Motion Sensor State Device ID:  "..k.."  Device Value : "..v)
    end

    for k, v in pairs(FibaroDoorSensors) do
      fibaro:debug("Door Sensor Device ID:  "..k.."  Device Value : "..v)
    end

    for k, v in pairs(UBSMotionSensor) do
      fibaro:debug("UBS Motion Sensor Device ID:  "..k.."  Device Value : "..v)
    end

    fibaro:sleep(300*1000)

    • 0
    Posted

    I'm not an expert, but was curious what the script would do (I'm affraid I don't know what this is

    Please login or register to see this image.

    /emoticons/default_tongue.png" alt=":P" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" />)

    It runs a bit slow in my opinion indeed.

     

    My output:

    Please login or register to see this code.

    • 0
  • Inquirer
  • Posted

    The script -for me at least- opens up a ton of possibilities.

     

    For example: I can check if last sensor breached was the one in the garage and if so arm all the sensors and close all the blinds.  Also allows me to open all the blinds in the morning if the first sensor breached is the one in my bedroom.  

    And anything else where one would check sensor values and/or last modification time. 

     

    when you have a lot of devices it is quite hard to make scenes where you write each sensor all over again. This way you would have all of them in a table

    Please login or register to see this image.

    /emoticons/default_smile.png" alt=":)" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" /> 

    • 0
    Posted

    Ah sound great

    Please login or register to see this image.

    /emoticons/default_smile.png" alt=":)" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" /> But I'm not that far with programming

    Please login or register to see this image.

    /emoticons/default_icon_wink.gif" alt=";-)" />

    • 0
    Posted

    I take the challenge

    Please login or register to see this image.

    /emoticons/default_icon_smile.gif" alt=":-)" />

    Give me some time...

    • 0
  • Inquirer
  • Posted

    thank you:)

     

    I think I found a way, maybe not the cleanest..  Now the script returns the device ID and state of the last breached sensors in each category. Just a matter of using the data now:)

     

    --[[
    %% properties

    %% globals
    --]]

       FibaroMotionSensors = {}
       FibaroMotionSensorsState = {}
       FibaroDoorSensors = {}
       FibaroDoorState ={}
       UBSMotionSensor = {}
       UBSState =  {}
       for i = 0, 500 do
          if   fibaro:getType(i) == 'com.fibaro.doorSensor' then
             value = fibaro:getValue(i, 'value')
             model = fibaro:getType(i)
             FibaroDoorSensors = value
             FibaroDoorState =  tonumber(os.time() - fibaro:getModificationTime(i, 'value'))  
             --FibaroMotionSensors = model    
        else
        if  fibaro:getType(i) == 'com.fibaro.FGMS001' then
             value = fibaro:getValue(i, 'value')
             model = fibaro:getType(i)
             FibaroMotionSensors = value
             FibaroMotionSensorsState =  tonumber(os.time() - fibaro:getModificationTime(i, 'value'))  
          else
         if  fibaro:getType(i) == 'com.fibaro.motionSensor' then
             value = fibaro:getValue(i, 'value')
             model = fibaro:getType(i)
             UBSMotionSensor = value 
             UBSState =  tonumber(os.time() - fibaro:getModificationTime(i, 'value'))  
          end
          end
          end
       end

    for k, v in pairs(FibaroMotionSensors) do
      fibaro:debug("Motion Sensor Device ID:  "..k.."  Device Value : "..v)
    end

    local FibaroMotionID = next(FibaroMotionSensorsState)
    local FibaroMin = FibaroMotionSensorsState[FibaroMotionID]
    for k, v in pairs(FibaroMotionSensorsState) do
      fibaro:debug("Motion Sensor State Device ID:  "..k.."  Device Value : "..v)
        if FibaroMotionSensorsState[k] <= FibaroMin then
            FibaroMotionID, FibaroMin = k, v
          end
    end
    fibaro:debug("Last FibaroMotionSensor breached device ID: "..FibaroMotionID.." and it was "..FibaroMin.." seconds ago")

    for k, v in pairs(FibaroDoorSensors) do
      fibaro:debug("Door Sensor Device ID:  "..k.."  Device Value : "..v)
    end

    local FibaroDoorID = next(FibaroDoorState)
    local DoorMin = FibaroDoorState[FibaroDoorID]
    for k, v in pairs(FibaroDoorState) do
        if FibaroDoorState[k] <= DoorMin then
            FibaroDoorID, DoorMin = k, v
          end
    end
    fibaro:debug("Last FibaroDoor breached device ID: "..FibaroDoorID.." and it was "..DoorMin.." seconds ago")

    for k, v in pairs(UBSMotionSensor) do
      fibaro:debug("UBS Motion Sensor Device ID:  "..k.."  Device Value : "..v)
    end

    local FibaroUBSID = next(UBSState)
    local UBSMin = UBSState[FibaroUBSID]
    for k, v in pairs(UBSState) do
        if UBSState[k] <= UBSMin then
            FibaroUBSID, UBSMin = k, v
          end
    end
    fibaro:debug("Last UBSSensor breached device ID: "..FibaroUBSID.." and it was "..UBSMin.." seconds ago")

    fibaro:sleep(300*1000)

    • 0
    Posted

    Well... yes, OK! For fun and pleasure, and because I wanted to try out a new debugging technique, I've polished the code a bit. Not meant as criticism. Code is part syntax and part personal style. See comments in the code, they start with PGBR.

     

    Please login or register to see this code.

    • 0
  • Inquirer
  • Posted

    are you kidding me ?

    Please login or register to see this image.

    /emoticons/default_smile.png" alt=":)" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" /> your changes made the code run almost 5 seconds faster. That is huge

    Please login or register to see this image.

    /emoticons/default_smile.png" alt=":)" srcset="https://forum.fibaro.com/uploads/emoticons/[email protected] 2x" width="20" height="20" />

    And I'm always up for constructive criticism. How else would we learn.

     

    Besides I'm just a beginner at this; was happy I could make it work lol

     

    Now that this part is done, do you think it is safe to run it every 2 or 3 minutes ? won't impact the HC2 to much ?

    What if I include all my devices in such tables and try to make scenes that operate all devices of one kind be independent of adding/removing devices ? Would save me quite a bit of work every time I have to reset a device etc..

     

     

    Regards

    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...