Class: OpenHAB::DSL::Rules::BuilderDSL
- Inherits:
-
Object
- Object
- OpenHAB::DSL::Rules::BuilderDSL
- Includes:
- Core::EntityLookup, OpenHAB::DSL
- Defined in:
- lib/openhab/dsl/rules/builder.rb
Overview
Rule configuration for openHAB Rules engine
Constant Summary
Constants included from OpenHAB::DSL
Execution Blocks collapse
-
#delay(duration) ⇒ void
Add a wait between or after run blocks.
-
#otherwise {|event| ... } ⇒ Object
Add a block that will be passed event data, to be run if guards are not satisfied.
-
#run {|event| ... } ⇒ void
Add a block that will be passed event data.
-
#triggered {|item| ... } ⇒ void
Add a block that will be passed the triggering item.
Configuration collapse
-
#dependencies(trigger_types = %i[changed updated]) ⇒ Array<Item, GroupItem::Members>
Returns all Items (or GroupItem::Members) referenced by the specified trigger types in this rule.
-
#description(value) ⇒ void
Set the rule's description.
-
#enabled(value) ⇒ void
Enable or disable the rule from executing.
-
#name(value) ⇒ void
Set the rule's name.
-
#tags(*tags) ⇒ void
Set the rule's tags.
-
#uid(id) ⇒ void
Set the rule's UID.
Guards collapse
Guards exist to only permit rules to run if certain conditions are
satisfied. Think of these as declarative if
statements that keep
the run block free of conditional logic, although you can of course
still use conditional logic in run blocks if you prefer.
#Guard Combination
Multiple guards can be used on the same rule. All must be satisfied for a rule to execute.
-
#between(range) ⇒ void
Only execute rule if the current time is between the supplied time ranges.
-
#debounce_for(debounce_time) ⇒ void
Waits until triggers have stopped firing for a period of time before executing the rule.
-
#not_if {|event| ... } ⇒ void
Prevents execution of rules when the block's result is true and allows it when it's true.
-
#only_every(interval) ⇒ void
Executes the rule then ignores subsequent triggers for a given duration.
-
#only_if {|event| ... } ⇒ void
Allows rule execution when the block's result is true and prevents it when it's false.
-
#throttle_for(duration) ⇒ void
Rate-limits rule executions by delaying triggers and executing the last trigger within the given duration.
Triggers collapse
The trigger attachment feature is not available for UI rules.
Triggers specify what will cause the execution blocks to run. Multiple triggers can be defined within the same rule.
#Trigger Attachments
All triggers support event attachments that enable the association of an object to a trigger. This enables one to use the same rule and take different actions if the trigger is different. The attached object is passed to the execution block through the OpenHAB::Core::Events::AbstractEvent#attachment accessor.
-
#at(item, offset: nil) ⇒ void
Creates a trigger based on the date and time stored in a DateTimeItem.
-
#changed(*items, to: nil, from: nil, for: nil, attach: nil) ⇒ void
Creates a trigger when an item, member of a group, or a thing changed states.
-
#channel(*channels, thing: nil, triggered: nil, attach: nil) ⇒ void
Creates a channel trigger.
-
#channel_linked(item: nil, channel: nil, attach: nil) ⇒ void
Creates a channel linked trigger.
-
#channel_unlinked(item: nil, channel: nil, attach: nil) ⇒ void
Creates a channel unlinked trigger.
-
#cron(expression = nil, attach: nil, **fields) ⇒ void
Create a cron trigger.
-
#event(topic, source: nil, types: nil, attach: nil) ⇒ void
Creates a trigger on events coming through the event bus.
-
#every(*values, at: nil, offset: nil, attach: nil) ⇒ void
Create a rule that executes at the specified interval.
-
#item_added(pattern = "*", attach: nil) ⇒ void
Creates an item added trigger.
-
#item_removed(pattern = "*", attach: nil) ⇒ void
Creates an item removed trigger.
-
#item_updated(pattern = "*", attach: nil) ⇒ void
Creates an item updated trigger.
-
#on_load(delay: nil, attach: nil) ⇒ void
Creates a trigger that executes when the script is loaded.
-
#on_start(at_level: nil, at_levels: nil, attach: nil) ⇒ void
Creates a trigger that executes when openHAB reaches a certain start level.
-
#received_command(*items, command: nil, commands: nil, attach: nil) ⇒ void
Creates a trigger for when an item or group receives a command.
-
#thing_added(pattern = "*", attach: nil) ⇒ void
Creates a thing added trigger.
-
#thing_removed(pattern = "*", attach: nil) ⇒ void
Creates a thing removed trigger.
-
#thing_updated(pattern = "*", attach: nil) ⇒ void
Creates a thing updated trigger.
-
#time_series_updated(*items, attach: nil) ⇒ void
Creates a time series updated trigger.
-
#trigger(type, attach: nil, **configuration) ⇒ void
Create a generic trigger given the trigger type uid and a configuration hash.
-
#updated(*items, to: nil, attach: nil) ⇒ void
Create a trigger when item, group or thing is updated.
-
#watch(path, glob: "*", for: %i[created deleted modified], attach: nil) ⇒ void
Create a trigger to watch a path.
Instance Method Summary collapse
Methods included from OpenHAB::DSL
after, between, config_description, debounce_for, ensure_states, ensure_states!, holiday_file, holiday_file!, items, only_every, persistence, persistence!, profile, provider, provider!, rule, rule!, rules, scene, scene!, script, script!, shared_cache, sitemaps, store_states, things, throttle_for, timers, transform, unit, unit!
Methods included from Core::ScriptHandling
script_loaded, script_unloaded
Methods included from Core::Actions
Methods included from Core::EntityLookup
#items, #method_missing, #things
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class OpenHAB::DSL
Instance Method Details
#at(item, offset: nil) ⇒ void
This method returns an undefined value.
Creates a trigger based on the date and time stored in a DateTimeItem
The trigger will dynamically update whenever the state of the item changes. If the item is NULL or UNDEF, the trigger will not run.
To trigger just on the time portion of the item, use #every instead, e.g.
every :day, at: MyDateTimeItem
.
The event
passed to run blocks will be a Core::Events::TimerEvent.
1844 1845 1846 1847 1848 1849 1850 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1844 def at(item, offset: nil) item = item.name if item.is_a?(Item) offset ||= 0 offset = offset.to_i if offset.is_a?(Duration) @ruby_triggers << [:at, item, { offset: offset }] trigger("timer.DateTimeTrigger", itemName: item.to_s, offset: offset) end |
#between(range) ⇒ void
This method returns an undefined value.
Only execute rule if the current time is between the supplied time ranges.
If the range is of strings, it will be parsed to an appropriate time class.
609 |
# File 'lib/openhab/dsl/rules/builder.rb', line 609 prop :between |
#changed(*items, to: nil, from: nil, for: nil, attach: nil) ⇒ void
This method returns an undefined value.
Creates a trigger when an item, member of a group, or a thing changed states.
When the changed element is a Thing, the from
and to
values will accept symbols and strings, where the symbol'
matches the
supported status.
The event
passed to run blocks will be an
Core::Events::ItemStateChangedEvent or a
Core::Events::ThingStatusInfoChangedEvent depending on if the
triggering element was an item or a thing.
1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1164 def changed(*items, to: nil, from: nil, for: nil, attach: nil) changed = Changed.new(rule_triggers: @rule_triggers) # for is a reserved word in ruby, so use local_variable_get :for duration = binding.local_variable_get(:for) @ruby_triggers << [:changed, items, { to: to, from: from, duration: duration }] from = [nil] if from.nil? to = [nil] if to.nil? items.each do |item| case item when Core::Things::Thing, Core::Things::ThingUID, Core::Things::Registry, Core::Items::Item, Core::Items::GroupItem::Members nil else raise ArgumentError, "items must be an Item, GroupItem::Members, Thing, ThingUID, or Things::Registry" end logger.trace { "Creating changed trigger for entity(#{item}), to(#{to.inspect}), from(#{from.inspect})" } Array.wrap(from).each do |from_state| Array.wrap(to).each do |to_state| changed.trigger(item: item, from: from_state, to: to_state, duration: duration, attach: attach) end end end end |
#channel(*channels, thing: nil, triggered: nil, attach: nil) ⇒ void
This method returns an undefined value.
Creates a channel trigger
The channel trigger executes rule when a specific channel is triggered. The syntax
supports one or more channels with one or more triggers. thing
is an optional
parameter that makes it easier to set triggers on multiple channels on the same thing.
The event
passed to run blocks will be a Core::Events::ChannelTriggeredEvent.
982 983 984 985 986 987 988 989 990 991 992 |
# File 'lib/openhab/dsl/rules/builder.rb', line 982 def channel(*channels, thing: nil, triggered: nil, attach: nil) channel_trigger = Channel.new(rule_triggers: @rule_triggers) flattened_channels = Channel.channels(channels: channels, thing: thing) triggers = [triggered].flatten @ruby_triggers << [:channel, flattened_channels, { triggers: triggers }] flattened_channels.each do |channel| triggers.each do |trigger| channel_trigger.trigger(channel: channel, trigger: trigger, attach: attach) end end end |
#channel_linked(item: nil, channel: nil, attach: nil) ⇒ void
This method returns an undefined value.
Creates a channel linked trigger
The event
passed to run blocks will be an Core::Events::ItemChannelLinkAddedEvent.
1014 1015 1016 1017 1018 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1014 def channel_linked(item: nil, channel: nil, attach: nil) pattern = (item.nil? && channel.nil?) ? "*" : "#{item || "*"}-#{channel || "*"}" @ruby_triggers << [:channel_linked, pattern] event("openhab/links/#{pattern}/added", types: "ItemChannelLinkAddedEvent", attach: attach) end |
#channel_unlinked(item: nil, channel: nil, attach: nil) ⇒ void
This method returns an undefined value.
Creates a channel unlinked trigger
The event
passed to run blocks will be an Core::Events::ItemChannelLinkRemovedEvent.
Note that the item or the thing it's linked to may no longer exist, so if you try to access those objects they'll be nil.
1043 1044 1045 1046 1047 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1043 def channel_unlinked(item: nil, channel: nil, attach: nil) pattern = (item.nil? && channel.nil?) ? "*" : "#{item || "*"}-#{channel || "*"}" @ruby_triggers << [:channel_unlinked, pattern] event("openhab/links/#{pattern}/removed", types: "ItemChannelLinkRemovedEvent", attach: attach) end |
#cron(expression, attach: nil) ⇒ void #cron(second: nil, minute: nil, hour: nil, dom: nil, month: nil, dow: nil, year: nil, attach: nil) ⇒ void
This method returns an undefined value.
Create a cron trigger
The event
passed to run blocks will be a Core::Events::TimerEvent.
1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1262 def cron(expression = nil, attach: nil, **fields) if fields.any? raise ArgumentError, "Cron elements cannot be used with a cron expression" if expression cron_expression = Cron.from_fields(fields) return cron(cron_expression, attach: attach) end raise ArgumentError, "Missing cron expression or elements" unless expression cron = Cron.new(rule_triggers: @rule_triggers) cron.trigger(config: { "cronExpression" => expression }, attach: attach) end |
#debounce_for(debounce_time) ⇒ void
This method returns an undefined value.
Waits until triggers have stopped firing for a period of time before executing the rule.
It ignores triggers that are "bouncing around" (rapidly firing) by ignoring them until they have quiesced (stopped triggering for a while).
#Comparison Table
Guard | Triggers Immediately | Description |
---|---|---|
#debounce_for | No | Waits until there is a minimum interval between triggers. |
#throttle_for | No | Rate-limits the executions to a minimum interval, regardless of the interval between triggers. Waits until the end of the period before executing, ignores any leading triggers. |
#only_every | Yes | Rate-limits the executions to a minimum interval. Immediately executes the first trigger, then ignores subsequent triggers for the period. |
#Timing Diagram
The following timing diagram illustrates the difference between #debounce_for, #throttle_for, and #only_every guards:
TIME INDEX ===> 1 1 2 2 3 3 4 4
0 5 0 5 0 5 0 5 0 5
Triggers : "X.X...X...X..XX.X.X....X.XXXXXXXXXXX....X....."
debounce_for 5 : "|......................X.|..............X....."
debounce_for 5..5 : "|....X|....X.|....X....|....X|....X|....X....X"
debounce_for 5..6 : "|.....X...|.....X.|....X.|.....X|.....X.|....X"
debounce_for 5..7 : "|......X..|......X|....X.|......X|......X....."
debounce_for 5..8 : "|.......X.|.......X....|.......X|.......X....."
debounce_for 5..20: "|...................X..|................X....."
# throttle_for will fire every 5 intervals after the "first" trigger
throttle_for 5 : "|....X|....X.|....X....|....X|....X|....X....."
only_every 5 : "X.....X......X....X....X....X....X......X....."
Triggers : "X.X...X...X..XX.X.X..X...XXXXXXXXXXX.X..X.X..."
debounce_for 5..44: "|...........................................X."
# Notice above, triggers keep firing with intervals less than 5, so
# debouncer keeps waiting, but puts a stop at 44 (the end of range).
750 751 752 753 |
# File 'lib/openhab/dsl/rules/builder.rb', line 750 def debounce_for(debounce_time) idle_time = debounce_time.is_a?(Range) ? debounce_time.begin : debounce_time debounce(for: debounce_time, idle_time: idle_time) end |
#delay(duration) ⇒ void
This method returns an undefined value.
Add a wait between or after run blocks.
The delay property is a non thread-blocking element that is executed after, before, or between run blocks.
418 |
# File 'lib/openhab/dsl/rules/builder.rb', line 418 prop_array :delay, array_name: :run_queue, wrapper: Delay |
#dependencies(trigger_types = %i[changed updated]) ⇒ Array<Item, GroupItem::Members>
Returns all Items (or GroupItem::Members) referenced by the specified trigger types in this rule.
520 521 522 523 524 525 526 527 528 |
# File 'lib/openhab/dsl/rules/builder.rb', line 520 def dependencies(trigger_types = %i[changed updated]) trigger_types = Array.wrap(trigger_types) ruby_triggers.flat_map do |t| next [] unless trigger_types.include?(t.first) t[1].select { |i| i.is_a?(Item) || i.is_a?(GroupItem::Members) } end.uniq end |
#description(value) ⇒ void
This method returns an undefined value.
Set the rule's description.
474 |
# File 'lib/openhab/dsl/rules/builder.rb', line 474 prop :description |
#enabled(value) ⇒ void
This method returns an undefined value.
Enable or disable the rule from executing
504 |
# File 'lib/openhab/dsl/rules/builder.rb', line 504 prop :enabled |
#event(topic, source: nil, types: nil, attach: nil) ⇒ void
This method returns an undefined value.
Creates a trigger on events coming through the event bus
1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1788 def event(topic, source: nil, types: nil, attach: nil) types = types.join(",") if types.is_a?(Enumerable) # @deprecated OH3.4 - OH3 config uses eventXXX vs OH4 uses `topic`, `source`, and `types` # See https://github.com/openhab/openhab-core/pull/3299 trigger("core.GenericEventTrigger", eventTopic: topic, eventSource: source, eventTypes: types, # @deprecated OH3.4 topic: topic, source: source, types: types, attach: attach) end |
#every(*values, at: nil, offset: nil, attach: nil) ⇒ void
This method returns an undefined value.
Create a rule that executes at the specified interval.
The event
passed to run blocks will be a Core::Events::TimerEvent.
For a more complex schedule, use #cron.
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1385 def every(*values, at: nil, offset: nil, attach: nil) raise ArgumentError, "Missing values" if values.empty? raise ArgumentError, "Offset can only be used when 'at' is given a DateTimeItem" if offset && !at.is_a?(Item) if Cron.all_dow_symbols?(values) @ruby_triggers << [:every, values.join(", "), { at: at }] return cron(Cron.from_dow_symbols(values, at), attach: attach) end if values.size != 1 raise ArgumentError, "Multiple values are only allowed for day-of-week. " \ "Otherwise only one value is allowed, given: #{values.size}" end value = values.first value = java.time.MonthDay.parse(value.to_str) if value.respond_to?(:to_str) @ruby_triggers << [:every, value, { at: at }] if value == :day && at.is_a?(Item) # @deprecated OH 3.4 - attachments are supported in OH 4.0+ if Core.version <= Core::V4_0 && !attach.nil? raise ArgumentError, "Attachments are not supported with dynamic datetime triggers in openHAB 3.x" end offset ||= 0 offset = offset.to_i # Duration#to_i converts it to seconds, but we also want to convert float/string to int @ruby_triggers.last[2][:offset] = offset return trigger("timer.DateTimeTrigger", itemName: at.name, timeOnly: true, offset: offset, attach: attach) end cron_expression = case value when Symbol then Cron.from_symbol(value, at) when Duration then Cron.from_duration(value, at) when java.time.MonthDay then Cron.from_monthday(value, at) else raise ArgumentError, "Unknown interval" end cron(cron_expression, attach: attach) end |
#inspect ⇒ String
2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 |
# File 'lib/openhab/dsl/rules/builder.rb', line 2136 def inspect <<~TEXT.tr("\n", " ") #<OpenHAB::DSL::Rules::Builder: #{uid} triggers=#{triggers.inspect}, run blocks=#{run.inspect}, on_load=#{!@on_load.nil?}, Trigger Conditions=#{trigger_conditions.inspect}, Trigger UIDs=#{triggers.map(&:id).inspect}, Attachments=#{attachments.inspect} > TEXT end |
#item_added(pattern = "*", attach: nil) ⇒ void
This method returns an undefined value.
Creates an item added trigger
The event
passed to run blocks will be an Core::Events::ItemAddedEvent.
1650 1651 1652 1653 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1650 def item_added(pattern = "*", attach: nil) @ruby_triggers << [:item_added, pattern] event("openhab/items/#{pattern}/added", types: "ItemAddedEvent", attach: attach) end |
#item_removed(pattern = "*", attach: nil) ⇒ void
This method returns an undefined value.
Creates an item removed trigger
The event
passed to run blocks will be an Core::Events::ItemRemovedEvent.
1673 1674 1675 1676 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1673 def item_removed(pattern = "*", attach: nil) @ruby_triggers << [:item_removed, pattern] event("openhab/items/#{pattern}/removed", types: "ItemRemovedEvent", attach: attach) end |
#item_updated(pattern = "*", attach: nil) ⇒ void
This method returns an undefined value.
Creates an item updated trigger
The event
passed to run blocks will be an Core::Events::ItemUpdatedEvent.
1695 1696 1697 1698 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1695 def item_updated(pattern = "*", attach: nil) @ruby_triggers << [:item_updated, pattern] event("openhab/items/#{pattern}/updated", types: "ItemUpdatedEvent", attach: attach) end |
#name(value) ⇒ void
This method returns an undefined value.
Set the rule's name.
464 |
# File 'lib/openhab/dsl/rules/builder.rb', line 464 prop :name |
#not_if {|event| ... } ⇒ void
This method returns an undefined value.
Prevents execution of rules when the block's result is true and allows it when it's true.
670 671 672 |
# File 'lib/openhab/dsl/rules/builder.rb', line 670 prop_array(:not_if) do |item| raise ArgumentError, "Object passed to not_if must be a proc" unless item.is_a?(Proc) end |
#on_load(delay: nil, attach: nil) ⇒ void
This method returns an undefined value.
Creates a trigger that executes when the script is loaded
Execute the rule whenever the script is first loaded, including on openHAB start up, and on subsequent reloads on file modifications. This is useful to perform initialization routines, especially when combined with other triggers.
1452 1453 1454 1455 1456 1457 1458 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1452 def on_load(delay: nil, attach: nil) # prevent overwriting @on_load raise ArgumentError, "on_load can only be used once within a rule" if @on_load @on_load = { module: SecureRandom.uuid, delay: delay } attachments[@on_load[:module]] = attach end |
#on_start(at_level: nil, at_levels: nil, attach: nil) ⇒ void
This method returns an undefined value.
Creates a trigger that executes when openHAB reaches a certain start level
The event
passed to run blocks will be a Core::Events::StartlevelEvent.
This will only trigger once during openHAB start up. It won't trigger on script reloads.
1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1507 def on_start(at_level: nil, at_levels: nil, attach: nil) levels = Array.wrap(at_level) | Array.wrap(at_levels) levels = [100] if levels.empty? levels.map! do |level| next level unless level.is_a?(Symbol) begin klass = org.openhab.core.service.StartLevelService.java_class klass.declared_field("STARTLEVEL_#{level.upcase}").get_int(klass) rescue java.lang.NoSuchFieldException raise ArgumentError, "Invalid symbol for at_level: :#{level}" end end @ruby_triggers << [:on_start, levels] levels.each do |level| logger.warn "Rule engine doesn't start until start level 40" if level < 40 config = { startlevel: level } logger.trace { "Creating a SystemStartlevelTrigger with startlevel=#{level}" } Triggers::Trigger.new(rule_triggers: @rule_triggers) .append_trigger(type: "core.SystemStartlevelTrigger", config: config, attach: attach) end end |
#only_every(interval) ⇒ void
This method returns an undefined value.
Executes the rule then ignores subsequent triggers for a given duration.
Additional triggers that occur within the given duration after the rule execution will be ignored. This results in executions happening only at the specified interval or more.
Unlike #throttle_for, this guard will execute the rule as soon as a new trigger occurs instead of waiting for the specified duration. This is ideal for triggers such as a door bell where the rule should run as soon as a new trigger is detected but ignore subsequent triggers if they occur too soon after.
849 850 851 852 |
# File 'lib/openhab/dsl/rules/builder.rb', line 849 def only_every(interval) interval = 1.send(interval) if %i[second minute hour day].include?(interval) debounce(for: interval, leading: true) end |
#only_if {|event| ... } ⇒ void
This method returns an undefined value.
Allows rule execution when the block's result is true and prevents it when it's false.
642 643 644 |
# File 'lib/openhab/dsl/rules/builder.rb', line 642 prop_array(:only_if) do |item| raise ArgumentError, "Object passed to only_if must be a proc" unless item.is_a?(Proc) end |
#otherwise {|event| ... } ⇒ Object
Add a block that will be passed event data, to be run if guards are not satisfied.
The #otherwise property is the automation code that is executed when a rule is triggered and guards are not satisfied. This property accepts a block of code and executes it. The block is automatically passed an event object which can be used to access multiple properties about the triggering event.
442 |
# File 'lib/openhab/dsl/rules/builder.rb', line 442 prop_array :otherwise, array_name: :run_queue, wrapper: Otherwise |
#received_command(*items, command: nil, commands: nil, attach: nil) ⇒ void
This method returns an undefined value.
Creates a trigger for when an item or group receives a command.
The command/commands parameters are replicated for DSL fluency.
The event
passed to run blocks will be an
Core::Events::ItemCommandEvent.
1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1606 def received_command(*items, command: nil, commands: nil, attach: nil) command_trigger = Command.new(rule_triggers: @rule_triggers) # if neither command nor commands is specified, ensure that we create # a trigger that isn't looking for a specific command. commands = [nil] if command.nil? && commands.nil? commands = Array.wrap(command) | Array.wrap(commands) @ruby_triggers << [:received_command, items, { command: commands }] items.each do |item| case item when Core::Items::Item, Core::Items::GroupItem::Members nil else raise ArgumentError, "items must be an Item or GroupItem::Members" end commands.each do |cmd| logger.trace { "Creating received command trigger for items #{item.inspect} and commands #{cmd.inspect}" } command_trigger.trigger(item: item, command: cmd, attach: attach) end end end |
#run {|event| ... } ⇒ void
This method returns an undefined value.
Add a block that will be passed event data.
The run property is the automation code that is executed when a rule is triggered. This property accepts a block of code and executes it. The block is automatically passed an event object which can be used to access multiple properties about the triggering event. The code for the automation can be entirely within the run block and can call methods defined in the Ruby script.
321 |
# File 'lib/openhab/dsl/rules/builder.rb', line 321 prop_array :run, array_name: :run_queue, wrapper: Run |
#tags(*tags) ⇒ void
This method returns an undefined value.
Set the rule's tags.
489 |
# File 'lib/openhab/dsl/rules/builder.rb', line 489 prop :tags |
#thing_added(pattern = "*", attach: nil) ⇒ void
This method returns an undefined value.
Creates a thing added trigger
The event
passed to run blocks will be a Core::Events::ThingAddedEvent.
1718 1719 1720 1721 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1718 def thing_added(pattern = "*", attach: nil) @ruby_triggers << [:thing_added, pattern] event("openhab/things/#{pattern}/added", types: "ThingAddedEvent", attach: attach) end |
#thing_removed(pattern = "*", attach: nil) ⇒ void
This method returns an undefined value.
Creates a thing removed trigger
The event
passed to run blocks will be a Core::Events::ThingRemovedEvent.
1741 1742 1743 1744 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1741 def thing_removed(pattern = "*", attach: nil) @ruby_triggers << [:thing_removed, pattern] event("openhab/things/#{pattern}/removed", types: "ThingRemovedEvent", attach: attach) end |
#thing_updated(pattern = "*", attach: nil) ⇒ void
This method returns an undefined value.
Creates a thing updated trigger
The event passed to run blocks will be a Core::Events::ThingUpdatedEvent.
1765 1766 1767 1768 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1765 def thing_updated(pattern = "*", attach: nil) @ruby_triggers << [:thing_updated, pattern] event("openhab/things/#{pattern}/updated", types: "ThingUpdatedEvent", attach: attach) end |
#throttle_for(duration) ⇒ void
This method returns an undefined value.
Rate-limits rule executions by delaying triggers and executing the last trigger within the given duration.
When a new trigger occurs, it will hold the execution and start a fixed timer for the given duration. Should more triggers occur during this time, keep holding and once the wait time is over, execute the latest trigger.
#throttle_for will execute rules after it had waited for the given duration, regardless of how frequently the triggers were occuring. In contrast, #debounce_for will wait until there is a minimum interval between two triggers.
#throttle_for is ideal in situations where regular status updates need to be made for frequently changing values. It is also useful when a rule responds to triggers from multiple related items that are updated at around the same time. Instead of executing the rule multiple times, #throttle_for will wait for a pre-set amount of time since the first group of triggers occurred before executing the rule.
801 802 803 |
# File 'lib/openhab/dsl/rules/builder.rb', line 801 def throttle_for(duration) debounce(for: duration) end |
#time_series_updated(*items, attach: nil) ⇒ void
This method returns an undefined value.
Creates a time series updated trigger
The event
passed to run blocks will be a Core::Events::ItemTimeSeriesUpdatedEvent
2025 2026 2027 2028 2029 2030 2031 2032 |
# File 'lib/openhab/dsl/rules/builder.rb', line 2025 def time_series_updated(*items, attach: nil) @ruby_triggers << [:time_series_updated, items] items.map do |item| raise ArgumentError, "items must be an Item or GroupItem::Members" unless item.is_a?(Core::Items::Item) event("openhab/items/#{item.name}/timeseriesupdated", types: "ItemTimeSeriesUpdatedEvent", attach: attach) end end |
#trigger(type, attach: nil, **configuration) ⇒ void
This method returns an undefined value.
Create a generic trigger given the trigger type uid and a configuration hash
This provides the ability to create a trigger type not already covered by the other methods.
1888 1889 1890 1891 1892 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1888 def trigger(type, attach: nil, **configuration) logger.trace { "Creating trigger (#{type}) with configuration(#{configuration})" } Triggers::Trigger.new(rule_triggers: @rule_triggers) .append_trigger(type: type, config: configuration, attach: attach) end |
#triggered {|item| ... } ⇒ void
This method returns an undefined value.
Add a block that will be passed the triggering item.
This property is the same as the #run property except rather than
passing an event object to the automation block the triggered item is
passed. This enables optimizations for simple cases and supports
Ruby's pretzel colon &:
operator..
371 |
# File 'lib/openhab/dsl/rules/builder.rb', line 371 prop_array :triggered, array_name: :run_queue, wrapper: Trigger |
#uid(id) ⇒ void
This method returns an undefined value.
Set the rule's UID.
454 |
# File 'lib/openhab/dsl/rules/builder.rb', line 454 prop(:uid) { |id| Thread.current[:openhab_rule_uid] = id } |
#updated(*items, to: nil, attach: nil) ⇒ void
This method returns an undefined value.
Create a trigger when item, group or thing is updated
The event
passed to run blocks will be an
Core::Events::ItemStateEvent or a
Core::Events::ThingStatusInfoEvent depending on if the triggering
element was an item or a thing.
1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 |
# File 'lib/openhab/dsl/rules/builder.rb', line 1978 def updated(*items, to: nil, attach: nil) updated = Updated.new(rule_triggers: @rule_triggers) @ruby_triggers << [:updated, items, { to: to }] items.map do |item| case item when Core::Things::Thing, Core::Things::ThingUID, Core::Items::Item, Core::Items::GroupItem::Members nil else raise ArgumentError, "items must be an Item, GroupItem::Members, Thing, or ThingUID" end logger.trace { "Creating updated trigger for item(#{item}) to(#{to})" } [to].flatten.map do |to_state| updated.trigger(item: item, to: to_state, attach: attach) end end.flatten end |
#watch(path, glob: "*", for: %i[created deleted modified], attach: nil) ⇒ void
This method returns an undefined value.
Create a trigger to watch a path
It provides the ability to create a trigger on file and directory changes.
If a file or a path that does not exist is supplied as the argument
to watch, the parent directory will be watched and the file or
non-existent part of the supplied path will become the glob. For
example, if the path given is /tmp/foo/bar
and /tmp/foo
exists but bar
does not exist inside of of /tmp/foo
then the
directory /tmp/foo
will be watched for any files that match
*/bar
.
If the last part of the path contains any glob characters e.g.
/tmp/foo/*bar
, the parent directory will be watched and the last
part of the path will be treated as if it was passed as the glob
argument. In other words, watch '/tmp/foo/*bar'
is equivalent to
watch '/tmp/foo', glob: '*bar'
#Watching inside subdirectories
Subdirectories aren't watched unless:
- One of the glob patterns include the recursive match pattern
**
, or - The glob patterns include subdirectories, see examples below.
The event
passed to run blocks will be a Events::WatchEvent.
2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 |
# File 'lib/openhab/dsl/rules/builder.rb', line 2120 def watch(path, glob: "*", for: %i[created deleted modified], attach: nil) types = [binding.local_variable_get(:for)].flatten WatchHandler::WatchTriggerHandlerFactory.instance # ensure it's registered trigger(WatchHandler::WATCH_TRIGGER_MODULE_ID, path: path.to_s, types: types.map(&:to_s), glob: glob.to_s, attach: attach) end |