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


  • 1

Need script/scene to keep lights on, extend or restart the original safe period if motion sensor is breached


Fiberik

Question

Hi,

 

I am new to Fibaro Home Center and LUA scripts.

 
I need a script, or block scene(s) if possible, to do the following:
 
Any of three Fibaro motion sensors are to turn lights on (plugs) when breached. The lights are to stay on for X seconds. If any of the three sensors are breached during this period, the original timer/countdown are to start over again (“safe” period is to start over again). If none of the sensors are breached during the safe period/the countdown, the lights turn off. The problem is that the Home Center 2 creates new instances of scenes instead of starting them over again when the sensors are breached, as far as I can see.
 
I would be very great full if someone would share such a LUA script or create one, must also be others that need this.
 
 
Edited by Fiberik
Link to comment
Share on other sites

Recommended Posts

  • 0
On 5/31/2018 at 6:40 AM, Fiberik said:

Thanks! I will try out your scripts.

 

PS. I am not very experienced with scripting. 

 

‘localLightID’ will be the ID’s of the lights to be turned on/off. Do I separate them by commas like this: 15, 17, 19, 22, 24? Put them in brackets or leave out the spaces?

 

I use scenes to switch several lights, “a group of lights”, at the same time. I can reference a scene in the same manner, as far as I understand, by using ‘sceneID=129’?

Ok, here is a more generalized version that checks many sensor and turn off/on several lights.

Add light IDs and sensor IDs to the local tables in the beginning of the script.

Please login or register to see this code.

A side note just to emphasize how tricky this seemingly easy scene is: This scene actually leverages the fact that multiple instances are started when triggers change state. When all sensors are safe it starts a scene instance that sleeps waiting for the time to expire so that it can turn off the lights. If a sensor is breached during that time, a new scene instance is started that kill all instances, itself and the 'sleeping' instance. Then later when all sensors turn safe again a new 'sleeping' instance is started.

So the scene is toggling between two states, sleeping and killing, and there can never be two sleeping instances at the same time. 

This is important because if one needs to add extra conditions, like do not turn on lights if global variable  "onlyDogIsHome" is true, I would recommend that it would be a test before the call to the "switch" command

Please login or register to see this code.

...and leave the rest of the logic intact. If that test is done in the beginning of the scene and just aborts the scene it's easy to "get out of sync" with the state changes, and maybe end up with two sleeping instances (if that global change value) etc. So it looks simple but is tricky to generalize.

I often see "looping and sleeping" scenes with extra tests thrown in (and sometimes a 'fibaro:countScenes' for an extra "safety" measure) and I get dizzy trying to understand the (mostly unintended)  instance interaction going on -- and there is no wonder that once in a while (that can seem random because it's usually timing dependent) there is unintended consequences and people suspect gremlins in their HC2s... :-) 

(Btw, It would be cool if scene instances could share Lua global vars (_ENV) between them... would allow for some powerful syncing between instances, but of course would be even more tricky to to get right... )

Edited by jgab
  • Like 2
Link to comment
Share on other sites

  • 0

@Fiberik  this is how I stop my living room air conditioner.  I use another scene to just turn air con on.

 

i'm sure it is not perfectly coded but it works perfectly so far. The logic is pretty much same as yours. 313 336 327 are those motion sensors.

 

You can ignore PresentState.  It is just the way to turn my air con off is different between people are home and away.

 

Please login or register to see this code.

 

Edited by Sirhideo
Link to comment
Share on other sites

  • 0
On 5/30/2018 at 1:35 AM, Fiberik said:

Hi,

 

I am new to Fibaro Home Center and LUA scripts.

 
I need a script, or block scene(s) if possible, to do the following:
 
Any of three Fibaro motion sensors are to turn lights on (plugs) when breached. The lights are to stay on for X seconds. If any of the three sensors are breached during this period, the original timer/countdown are to start over again (“safe” period is to start over again). If none of the sensors are breached during the safe period/the countdown, the lights turn off. The problem is that the Home Center 2 creates new instances of scenes instead of starting them over again when the sensors are breached, as far as I can see.
 
I would be very great full if someone would share such a LUA script or create one, must also be others that need this.
 
 

 

You are right that the new instances spawned by the HC2 makes it a bit tricky. In your case the below would work

Please login or register to see this code.

The logic being if all sensor are safe, go into a sleep for X sec and then turn off the light. If any sensor is breached turn on light and kill all instances of the scene including the sleeping instance.

You could add a check if the light is already on/off to avoid turning it on/off.

 I've seen the @Sirhideo approach in many scripts and it works but one needs to poll the sensors with intervals shorter than the "blind" time of the sensor, and it takes some resources with a lot of these scenes...

 

Many of these "idioms" come back in home automation rules. Those that deal with things that should be done when a condition have been true for a certain amount of time is tricky, especially if you need to combine many of those. The 

Please login or register to see this link.

 framework handles this well and I have made my

Please login or register to see this link.

where I can express such rules very concisely and combine many of them in the same scene.Ex.

Please login or register to see this code.

 

Edited by jgab
Missed that the light should be turned on when sensors breached...
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

  • 0

@jgab How to achieve "if any of the three sensors are breached during this period, the original timer/countdown are to start over again" while scene is sleeping for 1000 * 3 * 60?

Edited by Sirhideo
Link to comment
Share on other sites

  • 0

Well, anytime a sensor is breached the scene(s) are killed (and the light is turned on). If that happens when the light is already on there is no change (that is kind of your "start over again while scene is sleeping", but the scene only sleep when all sensors are safe).

So, when the sensors change state so that all are safe the "sleep timer" starts again, and if nothing happens (e.g. being killed by a sensor being breached) within the specified time the light is turned on.

 

This works because the scene is triggered whenever a sensor change state (to breached or safe), and we only start the timer when all is safe, and we kill all scenes including the sleep, when any sensor is breached.

Edited by jgab
Link to comment
Share on other sites

  • 0
  • Inquirer
  • Thanks! I will try out your scripts.

     

    PS. I am not very experienced with scripting. 

     

    ‘localLightID’ will be the ID’s of the lights to be turned on/off. Do I separate them by commas like this: 15, 17, 19, 22, 24? Put them in brackets or leave out the spaces?

     

    I use scenes to switch several lights, “a group of lights”, at the same time. I can reference a scene in the same manner, as far as I understand, by using ‘sceneID=129’?

    Link to comment
    Share on other sites

    • 0

    @Fiberik

    You can define local variable like this

    local kitchenLight = xxx

    local toiletLight = xxx

     

    so when you turn it on/off

     

    fibaro:call(kitchenLight, "turnOff") or turnOn

    fibaro:call(toiletLight, "turnOn")

     

    without local variable, you need to type the ID everytime.

     

    fibaro:call(123, "turnOff")

    fibaro:call(234, "turnOff")

     

    if you want to run other scene from this scene:

     

    fibaro:startScenes(129)

     

     

    Edited by Sirhideo
    Link to comment
    Share on other sites

    • 0
    On 6/1/2018 at 10:42 AM, Sirhideo said:

    That is too hard for beginner haha.. nice to have something learnt.

    Yes, if I were Fibaro I would be hesitant to open up for Lua coding the way they have done. True they have sandboxed it, but that is mostly limiting coding more advanced stuff that beginners would not do anyway (like co-routines). However, they have also chosen a highly asynchronous model with scene instances that complicates things when trying to do things beyond trivial tasks.

    I suspect a lot of random scene issues people have are due to race conditions and timing issues.... and it is very hard to track down as it is typical issues that may appear once a month when all the stars are lined up...in the wrong way. 

    I would have chosen an event/message based model like typical window managers/GUI frameworks been using for decades. It's still asynchronous but it is easier to overlay a "synchronous thinking" on such a model. Imagine if Windows would spawn a new window manager instance for each new event...

    In an event model there would still be a lot of mistakes made but I think it would be easier to track down the  bugs...

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

    • 0
    On 5/30/2018 at 3:30 PM, jgab said:

    This works because the scene is triggered whenever a sensor change state (to breached or safe), and we only start the timer when all is safe, and we kill all scenes including the sleep, when any sensor is breached.

     

    Hi @jgab , yes the scene does work perfectly.  I am using it to control my air conditioner now instead of the one I posted up top.  Yours suggested scene reduces significant of CPU load.  Thank you.

     

    I would like to understand behind theory about killScenes(__fibaroSceneId).  When sensor is safe it starts to sleep.  When it is sleeping the scene is considered "running".  When any sensor breached again how can a running scene start over again and kill itself? Is it a second instance spawned? If so,  it must be set at 2 on general tab "Max running instances"? Thanks

    Edited by Sirhideo
    Link to comment
    Share on other sites

    • 0
    55 minutes ago, Sirhideo said:

     

    Hi @jgab , yes the scene does work perfectly.  I am using it to control my air conditioner now instead of the one I posted up top.  Yours suggested scene reduces significant of CPU load.  Thank you.

     

    I would like to understand behind theory about killScenes(__fibaroSceneId).  When sensor is safe it starts to sleep.  When it is sleeping the scene is considered "running".  When any sensor breached again how can a running scene start over again and kill itself? Is it a second instance spawned? If so,  it must be set at 2 on general tab "Max running instances"? Thanks

     

    Yes, you are right. Whenever a sensor change state a new instance is always spawned. This means that you need to set at least 2 in 'max running instances'. In reality you need to set 1+number of sensors, to be on the safe side (when one instance is sleeping all triggers could be triggered at the same time). fibaro:killScenes(__fibaroSceneId) is like fibaro:abort(), but abort just kills the scene instance that calls abort, whereas the former kills all running instances of the scene including itself. __fibaroSceneId is an "undocumented" variable in scenes that is set to the ID of the scene.

    Link to comment
    Share on other sites

    • 0

    Right again, it could be removed. However, I suspect Fibaro uses the variable in the block scene code generator. Here is a previous discussion about it with some elaborate ways to code your own getSelfId()...

     

    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • On ‎6‎/‎1‎/‎2018 at 10:36 AM, jgab said:

    Ok, here is a more generalized version that checks many sensor and turn off/on several lights.

    Add light IDs and sensor IDs to the local tables in the beginning of the script.

    Please login or register to see this code.

    A side note just to emphasize how tricky this seemingly easy scene is: This scene actually leverages the fact that multiple instances are started when triggers change state. When all sensors are safe it starts a scene instance that sleeps waiting for the time to expire so that it can turn off the lights. If a sensor is breached during that time, a new scene instance is started that kill all instances, itself and the 'sleeping' instance. Then later when all sensors turn safe again a new 'sleeping' instance is started.

    So the scene is toggling between two states, sleeping and killing, and there can never be two sleeping instances at the same time. 

    This is important because if one needs to add extra conditions, like do not turn on lights if global variable  "onlyDogIsHome" is true, I would recommend that it would be a test before the call to the "switch" command

    Please login or register to see this code.

    ...and leave the rest of the logic intact. If that test is done in the beginning of the scene and just aborts the scene it's easy to "get out of sync" with the state changes, and maybe end up with two sleeping instances (if that global change value) etc. So it looks simple but is tricky to generalize.

    I often see "looping and sleeping" scenes with extra tests thrown in (and sometimes a 'fibaro:countScenes' for an extra "safety" measure) and I get dizzy trying to understand the (mostly unintended)  instance interaction going on -- and there is no wonder that once in a while (that can seem random because it's usually timing dependent) there is unintended consequences and people suspect gremlins in their HC2s... :-) 

    (Btw, It would be cool if scene instances could share Lua global vars (_ENV) between them... would allow for some powerful syncing between instances, but of course would be even more tricky to to get right... )

     

    This seems to be just what I wanted to achieve. At first, I just allowed for 1 instance of the scene to be running but realized that it had to be at least 3 (actually 3+1, as you explained). I appreciate your effort. Thanks for helping me out!

    I will try to find a way, when I get some time, to make a condition for two particular lights (I switch five lights/lamps using this script):

    I will still like these two lights to turn on when the sensor is breached, but only if lux is below 250.

    Link to comment
    Share on other sites

    • 0
    On 6/5/2018 at 12:46 AM, Fiberik said:

     

    This seems to be just what I wanted to achieve. At first, I just allowed for 1 instance of the scene to be running but realized that it had to be at least 3 (actually 3+1, as you explained). I appreciate your effort. Thanks for helping me out!

     

    I will try to find a way, when I get some time, to make a condition for two particular lights (I switch five lights/lamps using this script):

     

    I will still like these two lights to turn on when the sensor is breached, but only if lux is below 250.

     

     

    I guess I should leave that as an exercise for you... but I can't help myself.

    I would probably divide up the lights in two tables, one with lights not depending on lux, and one depending on lux

    Please login or register to see this code.

    and then later when lights are switched on make the appropriate test for lux value

    Please login or register to see this code.

    However, that test for lux < 250 could be done in many ways. It could be the mean,median,max, or min value of all sensors or just the lux value of some specific sensor - all depending on your setup and floor layout.

    Coding these tests means looping over all sensor and get their lux values and do some calculations. Two functions that are convenient when doing that is 'map' and 'reduce'

    'map' is defined as map(f, {x1,x2,...xn}) == {f(x1),f(x2),...,f(xn)}

    and 'reduce' as reduce(f, {x1,x2,...xn}) == f(f(f(x1,x2),..),xn)

    Having those we can easily write switch,max,average etc,

    Please login or register to see this code.

    and the whole scene with some of the many different possible options becomes

    Please login or register to see this code.

    This I guess is also why ready made light scenes can't please everyone. Every setup is different in some way or another and there are always special conditions.

    Wouldn't it be easier to train an ML model with everything that's going on in the house {sensors, switches, time,date,weather} so after a while you don't have to turn on any switches because the house would know what you would have done given any specific state change...?

    Edited by jgab
    Forgot to separate out lux sensors
    Link to comment
    Share on other sites

    • 0

    An additional note. This scene can not be generalized to cover different areas/rooms in the same scene. The way to solve that is to create separate scenes for different areas/rooms.  The reason is of course that we can only have one sleeping instance with this model as a breach kills all instances. The problem with spreading out the same code in many scenes is of course to maintain the code...

    Anyway, this use case is very common and that's why a framework like  

    Please login or register to see this link.

     or my 

    Please login or register to see this link.

     is useful because many rules can co-exist in one scene in a concise way and still provide a lot of flexibility (even if the actual framework is many lines of code). The alternative is some of the light control scenes posted in this forum, and the options they provide for various conditions.

    Ex. the rules for two areas/rooms with a lux limit on some lights would look like thisthe way I code it in my own framework:

    Please login or register to see this code.

     

    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • Thank you for helping me out. I really appreciate it. I ran into some problems:

     

    [removed by inquirer]

     

    This is the configuration of the script that I am trying to run:

     

    [removed by inquirer]

     

    What am I doing wrong?

     

    Edited by Fiberik
    Superfluous
    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • Hi

     

    I am currently using alt. 5 and it seems to work. I will use this instead of alt. 6.

     

    Thanks again.

    Link to comment
    Share on other sites

    • 0
    1 hour ago, Fiberik said:

    Hi

     

    I am currently using alt. 5 and it seems to work. I will use this instead of alt. 6.

     

    Thanks again.

    Sorry, never tested 6 as it was the easiest alternative :-) 

    Of course need to convert result from getValue to a number (always returns strings) to compare it with luxLimit. The other bug was that 'switch' takes a table as first argument (to be able to switch many lights)

    Line 38/39 thus becomes

    Please login or register to see this code.

     

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