Logic Machine Forum
Staircase timer vs normal operation - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: Staircase timer vs normal operation (/showthread.php?tid=2884)



Staircase timer vs normal operation - Dirk79 - 02.10.2020

Hello, I am using the staircase timer, created by Erwin van der Zwart. Works very good for several PIRs.

Now I have decided that I want to create a staircase timer on the light which is normally on when it is dark outside and this light has to stay on (in a room next to the living room). But sometimes in the morning (when it is still dark outside), we have not put on the lights in de living room. Only in that case (so when the lights are not switched on) I want to use the staircase timer to automatically turn the lights on and off.
When the lights are switched on by the staircase timer, the light button (or the start of a scene) must overrule the staircase logic.

I have tried several things, but i can't realise this. The staircase logic overrules the current state and switches off the lights after the delay.

So what I want: (1) When light is already turned on, staircase logic must not work. And (2) in case the staircase logic turned on the light and is counting down, and during this countdown somebody switches the light on by a button or a scene, the staircase logic must also stop working.

How can I solve my problem?

Thank you very much.
Code:
-- ** Staircase logic with external time object and retriggering on input object Version 3.1 ** --
-- ****************************** Created by Erwin van der Zwart **************************** --
-- ************************************** SET PARAMETERS ************************************ --

-- Set input address
AddressInput = '9/0/7'

-- Set output address
AddressOutput = '0/0/41'

-- Set unique name for staircase timer (to avoid same storage name usage)
StaircaseName = 'PIR_TR2_1'

-- Set external time address (optional)
AddressExternalTime = ''

-- Use time left indication
UseTimeLeft = false -- Set to true if time left indication will be used

-- Set feedback adress of time left indication (optional)
AddressTimeLeft = ''

-- Set time delay (Used when external time is not available)
SetDelay = 120

-- Seconds or Minutes
SetSec = true-- Set to false for Minutes

-- Set factor delay (Multiplies Delay)
SetFac = 1

-- Logic can be turned of by value 0
Off_by_Value_Zero = false

-- ************************************** END PARAMETERS ************************************ --
-- *************************** DON'T CHANGE ANYTHING UNDER THIS LINE ************************ --

inputvalue = event.getvalue
if Off_by_Value_Zero == false and (event.getvalue() == false or event.getvalue() == 0) then
  -- Exit script
  return
end

ValueInput = grp.getvalue(AddressInput)
ValueOutput = grp.getvalue(AddressOutput)
ValueExternalTime = grp.getvalue(AddressExternalTime)
if SetSec == true then
  SetSeconds = 1
else
  SetSeconds = 60
end
if ValueExternalTime == nil then
ValueExternalTime = 0
end
if ValueExternalTime > 0 then
  StairCaseTime = ValueExternalTime * SetSeconds * SetFac
else
  StairCaseTime = SetDelay * SetSeconds * SetFac
end
if ValueInput == true then
  --check for earlier started scrips
  --check storage for stpid value
  stpid = storage.get(StaircaseName) 
  --check if stpid has a value
  if stpid == nil then
    pid = os.getpid()
    storage.set(StaircaseName, pid)
  else
    -- kill earlier running script   
    os.kill(stpid, signal.SIGKILL)
    -- create new pid for next time to kill
    pid = os.getpid() 
    storage.set(StaircaseName, pid)
  end
  if ValueOutput == false then
    grp.write(AddressOutput, true)
    ValueOutput = true
  end
  -- Check time left indication is used
  if UseTimeLeft == true then
    if StairCaseTime > 0 then
        grp.update(AddressTimeLeft, StairCaseTime)
        repeat
          StairCaseTime = StairCaseTime - 1
          grp.update(AddressTimeLeft, StairCaseTime)
          os.sleep(1)
        until StairCaseTime == 0
    end   
  else
    os.sleep(StairCaseTime)
  end
  ValueOutput = grp.getvalue(AddressOutput)
  if ValueOutput == true then
    ValueInput = grp.getvalue(AddressInput)
    if ValueInput == true then
        grp.write(AddressInput, false)
      ValueInput = false
    end
    if Off_by_Value_Zero == false then
      if ValueOutput == true then
            grp.write(AddressOutput, false)
        ValueOutput = false
          end
    else
      -- Do nothing, this will trigger else condition below on next run
    end
  end 
else
  --check for earlier started scrips
  --check storage for stpid value
  stpid = storage.get(StaircaseName) 
  --check if stpid has a value
  if stpid == nil then
  else
    -- kill earlier running script   
    os.kill(stpid, signal.SIGKILL)
    grp.update(AddressTimeLeft, 0)
    pid = nil
    storage.set(StaircaseName, pid)
  end
  if ValueOutput == true then
    grp.write(AddressOutput, false)
  end
end



RE: Staircase timer vs normal operation - admin - 05.10.2020

1. For this you need to use a different group address for manual control. Add this to the beginning of your script so it does not run when 0/0/42 is set to ON.
Code:
if grp.getvalue('0/0/42') then
  return
end

2. Use this event script to stop a running staircase timer:
Code:
StaircaseName = 'PIR_TR2_1'
stpid = storage.get(StaircaseName)
if stpid then
  os.kill(stpid, signal.SIGKILL)
  storage.set(StaircaseName, nil)
end

Another possible solution is to use a scheduler assigned to sunrise/sunset events to check if it's dark outside or not.


RE: Staircase timer vs normal operation - Dirk79 - 16.10.2020

Thank you very much! It works  Smile .