Module: OpenHAB::DSL::Items::TimedCommand
- Included in:
- Core::Items::GenericItem
- Defined in:
- lib/openhab/dsl/items/timed_command.rb
Overview
Extensions for Item to implement timed commands
All items have an implicit timer associated with them, enabling to easily set an item into a specific state for a specified duration and then at the expiration of that duration have the item automatically change to another state. These timed commands are reentrant, meaning if the same timed command is triggered while an outstanding timed command exist, that timed command will be rescheduled rather than creating a distinct timed command.
Timed commands are initiated by using the ‘for:’ argument with the command. This is available on both the ‘command’ method and any command-specific methods, e.g. Core::Items::SwitchItem#on.
The timer will be cancelled, and the item’s state will not be changed to the on_expire state if:
-
The item receives any command within the timed command duration.
-
The item is updated to a different state, even if it is then updated back to the same state.
For example, if you have a Switch on a timer and another rule sends a command to that item, even when it’s commanded to the same state, the timer will be automatically canceled.
Sending a different duration (for:) value for the timed command will reschedule the timed command for that new duration.
Defined Under Namespace
Classes: TimedCommandDetails
Instance Method Summary collapse
-
#command(command, for: nil, on_expire: nil) {|timed_command| ... } ⇒ self
Sends command to an item for specified duration, then on timer expiration sends the expiration command to the item.
Instance Method Details
#command(command, for: nil, on_expire: nil) {|timed_command| ... } ⇒ self
If a block is provided, and the timer is canceled because the item changed state while it was waiting, the block will still be executed. Be sure to check #expired? and/or #cancelled? to determine why the block was called.
Sends command to an item for specified duration, then on timer expiration sends the expiration command to the item
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/openhab/dsl/items/timed_command.rb', line 106 def command(command, for: nil, on_expire: nil, &block) duration = binding.local_variable_get(:for) return super(command) unless duration on_expire = block if block TimedCommand.timed_commands.compute(self) do |_key, timed_command_details| if timed_command_details.nil? # no prior timed command on_expire ||= default_on_expire(command) super(command) create_timed_command(command, duration: duration, on_expire: on_expire) else timed_command_details.mutex.synchronize do if timed_command_details.resolution # timed command that finished, but hadn't removed itself from the map yet # (it doesn't do so under the mutex to prevent a deadlock). # just create a new one on_expire ||= default_on_expire(command) super(command) create_timed_command(command, duration: duration, on_expire: on_expire) else # timed command still pending; reset it logger.trace "Outstanding Timed Command #{timed_command_details} encountered - rescheduling" timed_command_details.on_expire = on_expire unless on_expire.nil? timed_command_details.timer.reschedule(duration) # disable the cancel rule while we send the new command DSL.rules[timed_command_details.rule_uid].disable super(command) DSL.rules[timed_command_details.rule_uid].enable timed_command_details end end end end self end |