--Simple Timer Logic triggered by TAG "Timer" Version 1 --Created by Erwin van der Zwart --********** SET PARAMETERS *********** -- Set Input and Feedback address of timer duration (Set objects to 3 byte time/day - 10) Address_Time = '1/0/100' --! Needs TAG "Timer" ! (Must be available) Address_Time_Feedback = '1/0/101' -- Can not be used for feedback by Gauge ! DO NOT USE TAG "Timer" ! -- Set input address for Start Timer (send fixed value = 1) ! Needs TAG "Timer" ! (Must be available) Address_Start = '1/0/102' -- Set input address for Reset Timer (send fixed value = 1) ! Needs TAG "Timer" ! (Optional) Address_Reset = '1/0/103' -- Set output address of timer switch (Must be available) Address_Output = '1/1/50' -- Start automaticly on value input Start_On_Input = "FALSE" --Set to TRUE to start Automatic (Start button not needed then) -- Set minimum time for timer Min_Time = 0 --Time MUST be in seconds, cannot be negative, minimum = 0 maximum = 86400 -- Set maximum time for timer Max_Time = 21600 --Time MUST be in seconds, cannot be negative, minimum = 0 maximum = 86400 -- Set unique name for this timer script Storage_Script_Name = 'TMR1' -- Change if this script is used multiple times to make it unique -- Set unique name for timer value of this script Storage_Value_Name = 'TMRV1' -- Change if this script is used multiple times to make it unique --********** END PARAMETERS *********** --Make script only listen to "true" values ValueEvent = event.getvalue() if ValueEvent == false then return -- Exit on "false" end if Max_Time > 21600 then Max_Time = 21600 end if Min_Time < 0 then Min_Time = 0 end function SplitTime(s,re) local i1 = 1 local ls = {} local append = table.insert if not re then re = '%s+' end if re == '' then return {s} end while true do local i2,i3 = s:find(re,i1) if not i2 then local last = s:sub(i1) if last ~= '' then append(ls,last) end if #ls == 1 and ls[1] == '' then return {} else return ls end end append(ls,s:sub(i1,i2-1)) i1 = i3+1 end end function SecToTime (Secvalue) SectoTime = os.date("!%X", Secvalue) TimefromSec = SplitTime(SectoTime, ":") NewTimeTable = {day = 0, hour = TimefromSec[1], minute = TimefromSec[2], second = TimefromSec[3]} return NewTimeTable end Seconds_To_Go = storage.get(Storage_Value_Name) if Seconds_To_Go == nil then Seconds_To_Go = Min_Time end if event.dst == Address_Time then Time_Value = grp.getvalue(Address_Time) if Time_Value.day > 0 then Time_Value.day = 0 end grp.update(Address_Time_Feedback, Time_Value) Seconds_To_Go = (Time_Value.hour * 3600) + (Time_Value.minute * 60) + Time_Value.second --grp.update(Address_Slider_Feedback, Seconds_To_Go) if Seconds_To_Go > Max_Time then Seconds_To_Go = Max_Time end storage.set(Storage_Value_Name, Seconds_To_Go) if Seconds_To_Go == 0 then grp.update(Address_Reset, true) return end if Seconds_To_Go > Min_Time then if Start_On_Input == "TRUE" then grp.update(Address_Start, true) end end return end if event.dst == Address_Start or event.dst == Address_Reset then --check for earlier started scrips --check storage for tpid value tpid = storage.get(Storage_Script_Name) --check if tpid has a value if tpid == nil and event.dst == Address_Start then pid = os.getpid() storage.set(Storage_Script_Name, pid) else pid = os.getpid() -- create new pid for next time to kill storage.set(Storage_Script_Name, pid) -- kill earlier running script os.kill(tpid, signal.SIGKILL) end end if event.dst == Address_Start then if Seconds_To_Go > Min_Time then grp.write(Address_Output, true) repeat Seconds_To_Go = storage.get(Storage_Value_Name) Seconds_To_Go = Seconds_To_Go - 1 storage.set(Storage_Value_Name, Seconds_To_Go) Time_Table = SecToTime(Seconds_To_Go) grp.update(Address_Time_Feedback, Time_Table) os.sleep(1) until Seconds_To_Go == Min_Time grp.write(Address_Output, false) Time_Table = SecToTime(Min_Time) grp.update(Address_Time_Feedback, Time_Table) storage.set(Storage_Value_Name, Min_Time) pid = nil storage.set(Storage_Script_Name, pid) end return end if event.dst == Address_Reset then grp.write(Address_Output, false) Time_Table = SecToTime(Min_Time) grp.update(Address_Time_Feedback, Time_Table) storage.set(Storage_Value_Name, Min_Time) tpid = storage.get(Storage_Script_Name) --check if stpid has a value if tpid == nil then else -- set Storage_Script_Name to nil pid = nil storage.set(Storage_Script_Name, pid) -- kill earlier running script os.kill(tpid, signal.SIGKILL) end return end