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

switch on light for x minutes and if no movement switch off


Question

Posted

I have a scene which is triggered by a sensor on movement does this. while it all works nicely the issue i have is if the timer is interupupted the scene starts counting again and this throws an error as this:

[02.01.2022] [17:12:49] [ERROR] [SCENE109]:

 

What would be a better way to run this kind of countdown which would allow a restart from the begining without throwing this error?

 

for k,i in ipairs(GroupToiletOn) do

    if fibaro.getValue(i, "state") == false then

        fibaro.call(i, "turnOn")

    end

end 

--run timer for light   

safeTime = 0

maxTime = SwitchOffImeDelay*60

while safeTime < maxTime do

    fibaro.sleep(1000)

    safeTime = safeTime + 1

    --fibaro.debug("Scene109", "Timer for Toilet light - "..safeTime.." of "..maxTime.." seconds.")

end

--switch off light

for k,i in ipairs(GroupToiletOff) do

    if fibaro.getValue(i, "state") == true then

        fibaro.call(i, "turnOff")

    end

end

20 answers to this question

Recommended Posts

  • 1
Posted

Please login or register to see this code.

 

  • 0
Posted

I don’t think this is the complete scene ?

  • 0
Posted

I don't understand?

 

I don't  think you use that pir for security so..

why not set pir save time to 4 min (or something else)

 

If pir is breached -> light on  if pir is save -> light off

 

 

 

  • 0
Posted

What do you meant by timer interrupted? Is the scene triggered again? if so the previous scene instance is killed and the new instance is starting to run... and it should be like that.

Please post entire scene's code and trigger conditions

  • 0
  • Inquirer
  • Posted

    Trigger:

    {

      conditions = { {

          id = 498,

          isTrigger = true,

          operator = "==",

          property = "value",

          type = "device",

          value = true

        } },

      operator = "any"

    }

     

    Rules:

    --Set Locals

    local jT = json.decode(fibaro.getGlobalVariable("jHomeTable"))

    local currentDate = os.date("*t")

    local currentTime = os.date("%H:%M")

    local SummerTime = currentDate.isdst

    local HumidityDeviceId = jT.Toilet.Humidity 

    local MotionSensorDeviceId = jT.Toilet.MotionSensor

    local LightLevelSensor = jT.Toilet.LightSensor

    local ToiletLight = jT.Toilet.Light --155

    local ToiletFan = jT.Toilet.Fan 

    local ToiletLightState = fibaro.getValue(ToiletLight, "state")

    local HumidityDeviceLevel = fibaro.getValue(HumidityDeviceId, "value")

    local MotionSensorDeviceStatus = fibaro.getValue(MotionSensorDeviceId, "value")

    local ShabbosVariable = fibaro.getGlobalVariable("shabbos")

    local PlagHaminchaVariable = fibaro.getGlobalVariable("plagHamincha")

    local ErevChagVariable = fibaro.getGlobalVariable("erevChag")

    local LuxLevelVariable = tonumber(fibaro.getGlobalVariable("lightLevel"))

    local SwitchOffImeDelay = 5

    local SwitchOffImeDelayFan = 5

    local NightModeStart = "23:00"

    local NightModeEnd = "08:00"

    --Set Lights In To Group And Change Depending On Time

    local GroupToiletOn = {ToiletLight,ToiletFan}

    local GroupToiletOff = {ToiletLight}

    local GroupToiletFan = {ToiletFan}

    --Start Light Control Only run if it not Shabbos

    if (SummerTime == true and (currentDate.wday == 6 or ErevChagVariable == "true") and currentTime >= PlagHaminchaVariable) or ShabbosVariable == "true" then

        --fibaro.debug("Scene109", "Condition Day or Time")

        return

    end

    --Start timer to switch on light and then switch off

    for k,i in ipairs(GroupToiletOn) do

        if fibaro.getValue(i, "state") == false then

            fibaro.call(i, "turnOn")

        end

    end 

    --run timer for light   

    safeTime = 0

    maxTime = SwitchOffImeDelay*60

    while safeTime < maxTime do

        fibaro.sleep(1000)

        safeTime = safeTime + 1

        --fibaro.debug("Scene109", "Timer for Toilet light - "..safeTime.." of "..maxTime.." seconds.")

    end

    --switch off light

    for k,i in ipairs(GroupToiletOff) do

        if fibaro.getValue(i, "state") == true then

            fibaro.call(i, "turnOff")

        end

    end

    --run timer for fan

    safeTime = 0

    maxTime = SwitchOffImeDelayFan*60

    while safeTime < maxTime do

        fibaro.sleep(1000)

        safeTime = safeTime + 1

        --fibaro.debug("Scene109", "Timer for Toilet fan - "..safeTime.." of "..maxTime.." seconds.")

    end

    for k,i in ipairs(GroupToiletFan) do

        if fibaro.getValue(i, "state") == true then

            fibaro.call(i, "turnOff")

        end

    end

        

     

    I understand that it is working as expected by a new scene killing the old running one, which causes a debug error, while it works it does not seem elegant and was looking for a better way to do this.

    • 0
    Posted
    19 minutes ago, Jay Ess said:

    I understand that it is working as expected by a new scene killing the old running one, which causes a debug error, while it works it does not seem elegant and was looking for a better way to do this.

     

    But do you have "Allow to restart a running scene: " setting on "No" ?

    • 0
  • Inquirer
  • Posted

    setting is Yes, as if there is movement within the time span i want the timer to start again

    • 0
    Posted

    Should be "No".

     

    You want the timer to start again, but not the whole scene. 

    • 0
    Posted

    There is a 200+ posts thread on this topic

     

    • 0
  • Inquirer
  • Posted

    how can i trigger the motion remotely to test it? other then running the scene?

    • 0
    Posted
    50 minutes ago, Jay Ess said:

    how can i trigger the motion remotely to test it? other then running the scene?

    You want to  fake the sensor getting breached so your  scene is triggered?

    I would suggest that you move your code over to a QA and use some of the trigger/events libraries to get triggers.

    There you can also post "fake" triggers (like a device being breached) to test your code and logic.

     

    • 0
  • Inquirer
  • Posted (edited)

    thank you am trying to work out your timeout code on the scene above but cant get the logic of it, would you be able to help please. this is what i have so far.

     

    --Set Locals

    local jT = json.decode(fibaro.getGlobalVariable("jHomeTable"))

    local currentDate = os.date("*t")

    local currentTime = os.date("%H:%M")

    local SummerTime = currentDate.isdst

    local HumidityDeviceId = jT.Toilet.Humidity 

    local MotionSensorDeviceId = jT.Toilet.MotionSensor

    local LightLevelSensor = jT.Toilet.LightSensor

    local ToiletLight = jT.Toilet.Light --155

    local ToiletFan = jT.Toilet.Fan 

    local ToiletLightState = fibaro.getValue(ToiletLight, "state")

    local HumidityDeviceLevel = fibaro.getValue(HumidityDeviceId, "value")

    local MotionSensorDeviceStatus = fibaro.getValue(MotionSensorDeviceId, "value")

    local ShabbosVariable = fibaro.getGlobalVariable("shabbos")

    local PlagHaminchaVariable = fibaro.getGlobalVariable("plagHamincha")

    local ErevChagVariable = fibaro.getGlobalVariable("erevChag")

    local LuxLevelVariable = tonumber(fibaro.getGlobalVariable("lightLevel"))

    local SwitchOffImeDelay = 5

    local SwitchOffImeDelayFan = 5

    local NightModeStart = "23:00"

    local NightModeEnd = "08:00"

    --local secs = SwitchOffImeDelay * 60

    local sleepTime = 1

    --Set Lights In To Group And Change Depending On Time

    local GroupToiletOn = {ToiletLight,ToiletFan}

    local GroupToiletOff = {ToiletLight}

    local GroupToiletFan = {ToiletFan}

    --Start Light Control Only run if it not Shabbos

    if (SummerTime == true and (currentDate.wday == 6 or ErevChagVariable == "true") and currentTime >= PlagHaminchaVariable) or ShabbosVariable == "true" then

        --fibaro.debug("Scene109", "Condition Day or Time")

        return

    end

    print(secs,fibaro.getValue(MotionSensorDeviceId,'value'))

    --loopUntil(<loop function>,<end function>,<time in Xseconds>)

     

    function loopUntil(fun,cont,secs)

    print("function",fun,cont,secs)

        local function loop() 

            if not fun() then 

                fibaro.setTimeout(1000*secs,loop) 

            else 

                if cont then cont() end 

            end 

        end

        fibaro.setTimeout(1000*secs,loop)

    end

     

    --Start timer to switch on light and then switch off

    for k,i in ipairs(GroupToiletOn) do

        if fibaro.getValue(i, "state") == false then

            print("Turn On Light")

            --fibaro.call(i, "turnOn")

        end

    end 

    local safeTime = 0

    local mAxTime = SwitchOffImeDelay * 60

    print("Line 57",mAxTime)

    loopUntil(function()                                     -- Loop function

            if safeTime >= maxTime then 

                print("safe time is greater")

                return true 

            end   

            print("We should be checking here")             

            safeTime=safeTime+sleepTime                   -- count up safeTime

            fibaro.debug("Counting up safeTime ",safeTime,maxTime) 

            if fibaro.getValue(MotionSensorDeviceId,'value') > '0' then -- motion breached

                safeTime=0                                 -- reset safeTime

                fibaro.debug("Reset")

            end

        end,

        function()                                     -- Stuff to do after loop finished

            fibaro.debug("Turning off")

            --fibaro.call(light,’turnOff’)    

        end,

        sleepTime                                      -- Time to sleep between loops (in seconds)

    )                                     

    --[[

    fibaro.alert("email", {emailUser}, "Updating Shabbos Time<br>This email is generated from Scene 98.")

     

    --run timer for light   

    safeTime = 0

    maxTime = SwitchOffImeDelay*60

    while safeTime < maxTime do

        fibaro.sleep(1000)

        safeTime = safeTime + 1

        --fibaro.debug("Scene109", "Timer for Toilet light - "..safeTime.." of "..maxTime.." seconds.")

    end

    --switch off light

    for k,i in ipairs(GroupToiletOff) do

        if fibaro.getValue(i, "state") == true then

            --fibaro.call(i, "turnOff")

        end

    end

    --run timer for fan

    safeTime = 0

    maxTime = SwitchOffImeDelayFan*60

    while safeTime < maxTime do

        fibaro.sleep(1000)

        safeTime = safeTime + 1

        --fibaro.debug("Scene109", "Timer for Toilet fan - "..safeTime.." of "..maxTime.." seconds.")

    end

    for k,i in ipairs(GroupToiletFan) do

        if fibaro.getValue(i, "state") == true then

            --fibaro.call(i, "turnOff")

        end

    end

        

    ]]

     

    LOL not completly stupid just trying to get c# module to work with ms access and some thml java at the time as doing this coding and it is frying my brain, too much different lang floating around my head LOL

    thank you for any help provided.

     

    Edited by Jay Ess
    • 0
    Posted

    This works ok. You had a capital A in maxTime and you compared the value from the motion sensor with > '0', but a binary sensor returns true/false

    Please login or register to see this code.

     

    However, I wouldn't recommend this code - you should try the "abstracted code" later in the referred thread. 

    I see  that you also would like to check other stuff, fans etc.

    Then you need to either split it up into multiple  scenes or move over to a QA with an asynchronous event  mechanism.

    • 0
  • Inquirer
  • Posted

    lol was lookinjg through the thread looking for a later version of it but didnt manage to se it can you point me to it please?

    am i correct that settimout is better then sleep?

    • 0
    Posted

     

    isON() and ON() can then easily be extended to check multiple sensors or turn on multiple lights etc.

    • 0
  • Inquirer
  • Posted

    thank you, so it has gone back to using sleep?

    • 0
  • Inquirer
  • Posted

    thank you for your help.

     

    in a nutshell what i need to change is this code, which will loop as long as there is motion and switch off the allow scene to run more then once,

    while safeTime < maxTime do

        fibaro.sleep(sleepTime * 1000)

        safeTime = safeTime + sleepTime

        print("Counting safe time %d para maxTime %d",safeTime,maxTime)

        if fibaro.getValue(MotionSensorDeviceId, "state") == true then

            print("we are checking the state of the motion sensor here")

            safeTime = 0

        end

    end

     

    what is the benifit of running this in a qa? and how would i trigger it to run based on the motion?

    • 0
  • Inquirer
  • Posted

    this is my scene now which seems to be working - if i understand correctly then timeout is less system resource then why not use timeout instead of sleep?

     

    --Set Locals

    local jT = json.decode(fibaro.getGlobalVariable("jHomeTable"))

    local currentDate = os.date("*t")

    local currentTime = os.date("%H:%M")

    local SummerTime = currentDate.isdst

    local HumidityDeviceId = jT.Toilet.Humidity 

    local MotionSensorDeviceId = jT.Toilet.MotionSensor

    local LightLevelSensor = jT.Toilet.LightSensor

    local ToiletLight = jT.Toilet.Light --155

    local ToiletFan = jT.Toilet.Fan 

    local ToiletLightState = fibaro.getValue(ToiletLight, "state")

    local HumidityDeviceLevel = fibaro.getValue(HumidityDeviceId, "value")

    local MotionSensorDeviceStatus = fibaro.getValue(MotionSensorDeviceId, "value")

    local ShabbosVariable = fibaro.getGlobalVariable("shabbos")

    local PlagHaminchaVariable = fibaro.getGlobalVariable("plagHamincha")

    local ErevChagVariable = fibaro.getGlobalVariable("erevChag")

    local LuxLevelVariable = tonumber(fibaro.getGlobalVariable("lightLevel"))

    local SwitchOffImeDelay = 5

    local SwitchOffImeDelayFan = 5

    local safeTime = 0

    local sleepTime = 10

    local maxTime = SwitchOffImeDelay * 60

    local NightModeStart = "23:00"

    local NightModeEnd = "08:00"

    --Set Lights In To Group And Change Depending On Time

    local GroupToiletOn = {ToiletLight,ToiletFan}

    local GroupToiletOff = {ToiletLight}

    local GroupToiletFan = {ToiletFan}

    --Start Light Control Only run if it not Shabbos

    if (SummerTime == true and (currentDate.wday == 6 or ErevChagVariable == "true") and currentTime >= PlagHaminchaVariable) or ShabbosVariable == "true" then

        --fibaro.debug("Scene109", "Condition Day or Time")

        return

    end

    --Start timer to switch on light and then switch off

    for k,i in ipairs(GroupToiletOn) do

        if fibaro.getValue(i, "state") == false then

            fibaro.call(i, "turnOn")

        end

    end 

    while safeTime < maxTime do

        fibaro.sleep(1000*sleepTime)

        safeTime = safeTime + sleepTime 

        if fibaro.getValue(MotionSensorDeviceId, "value") == true then

            safeTime = 0

        end

        print("Counter for light",safeTime,"Motion",fibaro.getValue(MotionSensorDeviceId, "value"))

    end

    ShabbosVariable = fibaro.getGlobalVariable("shabbos")

    if ShabbosVariable == "false" then

        for k,i in ipairs(GroupToiletOff) do

            if fibaro.getValue(i, "state") == true then

                fibaro.call(i, "turnOff")

            end

        end

    end

    --run timer for fan

    safeTime = 0

    maxTime = SwitchOffImeDelayFan*60

    while safeTime < maxTime do

        fibaro.sleep(1000)

        safeTime = safeTime + 1

        --fibaro.debug("Scene109", "Timer for Toilet fan - "..safeTime.." of "..maxTime.." seconds.")

    end

    for k,i in ipairs(GroupToiletFan) do

        if fibaro.getValue(i, "state") == true then

            fibaro.call(i, "turnOff")

        end

    end

     

    • 0
    Posted

    Hi there. I want to ask for your help. I’m using the attached scene to control the lights which works great, but I’d like it to turn off the brightness to 20% for 10 seconds before turning it completely off. If there’s no more movement then the lamp should turn off and if there is movement it should go back back to 99%. Thanks in advance.

     

    local light = 52
    local motion1 = 55
    local maxTime = 3*60
    local sleepTime = 5
    fibaro.debug("","Turning on to 99")
    fibaro.call(light,"setValue","99")
    local safeTime = 0
    while safeTime < maxTime do
    fibaro.sleep(sleepTime*1000)
      safeTime=safeTime+sleepTime
    fibaro.debug("","Counting up safeTime ",
    safeTime,"to maxTime ",maxTime)
    if
    fibaro.getValue(motion1,"value")
    then
    safeTime=0
    fibaro.debug("","Reset")
      end
    end
    fibaro.debug("","Turning off")
    fibaro.call(light,"turnOff")

    • 0
    Posted

    jgab@ Thank you very much :)

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