Logic Machine Forum
Timer with manual stop - 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: Timer with manual stop (/showthread.php?tid=5659)



Timer with manual stop - AndersH - 09.10.2024

Hi.
I need help with a script for a lighting case, i have a spacelynk and Daligw, normal puschbutton to a binary input.
the costumer want to have 2 puschbuttons, 1st to start the light at 80% and after 60 min it will go down to 30 % in 10min and then 0%
the other button start at 80% for 240 min and then 30% in 10min and 0%.
It should be possible to turn off the light manually when the countdown has started, the binary input has 2 outgoing object for each channel (schneider).
Maybe stop/off with long press.

I have tried a Timer made here that`s seams to work, but if i send 0% to the gateway the script is still running and lights up when the lower value start.

The script i tested was this:

Code:
if not client then
  timers = {
    ['12/1/10'] = {
      output = '12/1/12', -- dimmer control (0..100%)
      onvaluehigh = 80, -- high output value in %
      onvaluelow = 30, -- low output value in %
      timeouthigh = 1 * 15, -- time to keep high value (in seconds)
      timeoutlow = 1 * 10, -- time to keep low value (in seconds)
    }
  }

  function timersetstate(timer, state)
    grp.checkwrite(timer.output, timer['onvalue' .. state] or 0)
    timer.state = state
    timer.ticks = timer['timeout' .. state]
  end

  function timertimeout(timer)
    local state = timer.state == 'high' and 'low' or 'off'
    timersetstate(timer, state)
  end

  for _, timer in ipairs(timers) do
    timer.state = 'off'
  end

  grp.sender = 'tm'

  client = require('localbus').new(0.1)
  client:sethandler('groupwrite', function(event)
    local timer = timers[ event.dst ]
    if timer and event.sender ~= grp.sender then
      local value = tonumber(event.datahex, 16) or 0
      if value == 1 then
        timersetstate(timer, 'high')
      end
    end
  end)
end

client:loop(1)

for _, timer in pairs(timers) do
  if timer.ticks then
    timer.ticks = timer.ticks - 1

    if timer.ticks == 0 then
      timertimeout(timer)
    end
  end
end



RE: Timer with manual stop - admin - 10.10.2024

Try this modified script. It allows mapping one output to multiple inputs. When a timer is started all running timers for the same output are stopped. Writing to the output also stops any associated timers.

Code:
if not client then
  timers = {
    ['0/0/1'] = {
      output = '0/0/255', -- dimmer control (0..100%)
      onvaluehigh = 50, -- high output value in %
      onvaluelow = 15, -- low output value in %
      timeouthigh = 8, -- time to keep high value (in seconds)
      timeoutlow = 3, -- time to keep low value (in seconds)
    },
    ['0/0/6'] = {
      output = '0/0/255', -- dimmer control (0..100%)
      onvaluehigh = 80, -- high output value in %
      onvaluelow = 30, -- low output value in %
      timeouthigh = 5, -- time to keep high value (in seconds)
      timeoutlow = 2, -- time to keep low value (in seconds)
    }
  }

  outputs = {}

  function timerreset(addr)
    for _, timer in pairs(timers) do
      if timer.output == addr then
        timer.ticks = nil
        timer.state = 'off'
      end
    end
  end

  function timersetstate(timer, state)
    grp.checkwrite(timer.output, timer['onvalue' .. state] or 0)
    timer.state = state
    timer.ticks = timer['timeout' .. state]
  end

  function timertimeout(timer)
    local state = timer.state == 'high' and 'low' or 'off'
    timersetstate(timer, state)
  end

  for _, timer in pairs(timers) do
    timer.state = 'off'
    outputs[ timer.output ] = true
  end

  grp.sender = 'tm'

  client = require('localbus').new(0.1)
  client:sethandler('groupwrite', function(event)
    if event.sender == grp.sender then
      return
    end

    local addr = event.dst
    local timer = timers[ addr ]

    if timer then
      local value = tonumber(event.datahex, 16) or 0

      if value == 1 then
        timerreset(timer.output)
        timersetstate(timer, 'high')
      end
    elseif outputs[ addr ] then
      timerreset(addr)
    end
  end)
end

client:loop(1)

for _, timer in pairs(timers) do
  if timer.ticks then
    timer.ticks = timer.ticks - 1

    if timer.ticks == 0 then
      timertimeout(timer)
    end
  end
end



RE: Timer with manual stop - AndersH - 10.10.2024

You are absolutely incredible, works immediately.
Thank you very much  Smile