Class: OpenHAB::DSL::TimerManager

Inherits:
Object
  • Object
show all
Defined in:
lib/openhab/dsl/timer_manager.rb

Overview

Manages timers created by after, or #schedule.

Instance Method Summary collapse

Instance Method Details

#cancel(id) ⇒ true, false

Cancel a single timer by id

Parameters:

  • id (Object)

Returns:

  • (true, false)

    if the timer was able to be cancelled



69
70
71
72
73
74
75
76
77
78
# File 'lib/openhab/dsl/timer_manager.rb', line 69

def cancel(id)
  result = false
  @timers_by_id.compute_if_present(id) do |_key, timer|
    result = timer.cancel!
    @timers.remove(timer)

    nil
  end
  result
end

#cancel_allvoid

This method returns an undefined value.

Cancels all active timers in the current script/UI rule

Including timers with or without an id.



192
193
194
195
196
197
198
199
200
201
# File 'lib/openhab/dsl/timer_manager.rb', line 192

def cancel_all
  logged = false
  # don't use #each, in case timers are scheduling more timers
  until @timers.empty?
    logger.trace { "Canceling #{@timers.length} timers" } unless logged
    logged = true
    timer = @timers.keys.first
    timer.cancel
  end
end

#include?(id) ⇒ true, false Also known as: key?, member?

Note:

This method is not recommended for normal use in rules. Timers are prone to race conditions if accessed from multiple rules, or from timers themselves. Rescheduling, canceling, or scheduling a new timer based on the results of this method may cause problems, since the state may have changed in the meantime. Instead, use after with an id, #cancel, #reschedule, or #schedule to perform those actions atomically.

Checks if a timer exists by id

Parameters:

  • id (Object)

Returns:

  • (true, false)


179
180
181
# File 'lib/openhab/dsl/timer_manager.rb', line 179

def include?(id)
  @timers_by_id.key?(id)
end

#reschedule(id, duration = nil) ⇒ Core::Timer?

Note:

Only timers that are still active can be rescheduled by their id. Once a timer is finished executing or cancelled, it is no longer maintained by TimerManager, and calling this method will do nothing. To reschedule a possibly expired or cancelled timer, either call the Core::Timer#reschedule method of the timer object, or use #schedule.

Reschedule a single timer by id.

Parameters:

  • id (Object)
  • duration (java.time.temporal.TemporalAmount, #to_zoned_date_time, Proc, nil) (defaults to: nil)

    When to reschedule the timer for. nil to retain its current interval.

Returns:

  • (Core::Timer, nil)

    the timer if it was rescheduled, otherwise nil



94
95
96
97
98
# File 'lib/openhab/dsl/timer_manager.rb', line 94

def reschedule(id, duration = nil)
  @timers_by_id.compute_if_present(id) do |_key, timer|
    timer.reschedule(duration)
  end
end

#schedule(id) {|timer| ... } ⇒ Core::Timer?

Schedule a timer by id

Schedules a timer by id, but passes the current timer -- if it exists -- to the block so that you can decide how you want to proceed based on that state. The timer is created in a thread-safe manner.

Examples:

Extend an existing timer, or schedule a new one

# This is technically the same functionality as just calling `after()` with an `id`,
# but allows you to perform extra steps if the timer is actually scheduled.
timers.schedule(item) do |timer|
  next timer.tap(&:reschedule) if timer

  Notification.send("The lights were turned on")

  after(30.seconds) { item.off }
end

Keep trying to turn something on, up to 5 times

timers.schedule(item) do |timer|
  next if timer # don't interrupt a retry cycle if it already exists

  retries = 5
  after(2.seconds) do |inner_timer|
    next if (retries -= 1).zero?
    next inner_timer.reschedule unless item.on?

    item.on
  end
end

Parameters:

  • id (Object)

Yield Parameters:

  • timer (Core::Timer, nil)

    The existing timer with this id, if one exists.

Yield Returns:

  • (Core::Timer, nil)

    A new timer to associate with this id, the existing timer, or nil. If nil, any existing timer will be cancelled.

Returns:



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/openhab/dsl/timer_manager.rb', line 137

def schedule(id)
  @timers_by_id.compute(id) do |_key, timer|
    new_timer = yield timer
    raise ArgumentError, "Block must return a timer or nil" unless new_timer.is_a?(Core::Timer) || new_timer.nil?

    if !new_timer.equal?(timer) && new_timer&.id
      raise ArgumentError,
            "Do not schedule a new timer with an ID inside a #schedule block"
    end

    if new_timer&.cancelled?
      new_timer = nil
    elsif new_timer.nil? && timer && !timer.cancelled?
      timer.cancel!
      @timers.remove(timer)
    end
    next unless new_timer

    new_timer.id ||= id
    if new_timer.id != id
      raise ArgumentError,
            "The new timer cannot have a different ID than what you're attempting to schedule"
    end

    new_timer
  end
end