Class: OpenHAB::DSL::Rules::Builder

Inherits:
Object
  • Object
show all
Includes:
Core::EntityLookup, Terse
Defined in:
lib/openhab/dsl/rules/builder.rb

Overview

A rules builder allows you to create openHAB rules.

Note that all methods on this module are also availabe directly on OpenHAB::DSL.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Core::EntityLookup

#items, #method_missing, #things

Methods included from Terse

#changed, #channel, #channel_linked, #channel_unlinked, #cron, #every, #item_added, #item_removed, #item_updated, #on_start, #received_command, #thing_added, #thing_removed, #thing_updated, #updated

Constructor Details

#initialize(provider) ⇒ Builder

Returns a new instance of Builder.



33
34
35
# File 'lib/openhab/dsl/rules/builder.rb', line 33

def initialize(provider)
  @provider = Core::Rules::Provider.current(provider)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class OpenHAB::Core::EntityLookup

Instance Attribute Details

#providerorg.openhab.core.automation.RuleProvider (readonly)

Returns:

  • (org.openhab.core.automation.RuleProvider)


31
32
33
# File 'lib/openhab/dsl/rules/builder.rb', line 31

def provider
  @provider
end

Instance Method Details

#rule(name = nil, id: nil, replace: nil, script: nil, binding: nil) {|rule| ... } ⇒ Core::Rules::Rule?

Create a new rule

The rule must have at least one trigger and one execution block. To create a “script” without any triggers, use script.

When explicit ‘id` is not provided, the rule’s ID will be inferred from the block’s source location, and a suffix will be added to avoid clashing against existing rules.

When an explicit ‘id` is provided and an existing rule with the same id already exists, the rule will not be created, and the method will return nil.

To ensure that a rule is created even when the same id already exists, use OpenHAB::DSL.rule! or call rules.remove to remove any existing rule prior to creating the new rule.

Examples:

rule "name" do
  <one or more triggers>
  <one or more execution blocks>
  <zero or more guards>
end

Create a rule with an explicit id, deleting any existing rule with the same id

rule! "name", id: "my_happy_day_reminder" do
  every :day
  run { logger.info "Happy new day!" }
end

Parameters:

  • name (String) (defaults to: nil)

    The rule name

  • id (String) (defaults to: nil)

    The rule’s ID. This can also be defined in the block using uid.

Yields:

Yield Parameters:

  • rule (Rules::BuilderDSL)

    Optional parameter to access the rule configuration from within execution blocks and guards.

Returns:

Raises:

  • (ArgumentError)

See Also:



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/openhab/dsl/rules/builder.rb', line 76

def rule(name = nil, id: nil, replace: nil, script: nil, binding: nil, &block)
  raise ArgumentError, "Block is required" unless block

  inferred_id = nil
  id ||= inferred_id = NameInference.infer_rule_id_from_block(block)
  script ||= block.source rescue nil # rubocop:disable Style/RescueModifier

  builder = nil

  ThreadLocal.thread_local(openhab_rule_type: "rule", openhab_rule_uid: id) do
    builder = BuilderDSL.new(binding || block.binding)
    builder.uid(id)
    builder.instance_exec(builder, &block)

    if replace
      logger.debug { "Removing existing rule '#{builder.uid}'." } if DSL.rules.remove(builder.uid)
    elsif replace.nil?
      id_not_inferred = inferred_id.nil? || inferred_id != builder.uid
      if id_not_inferred && (existing_rule = $rules.get(builder.uid))
        logger.warn "Rule '#{builder.uid}' is not created because " \
                    "another rule/script/scene with the same id already exists: #{existing_rule.inspect}."
        return nil
      end
    end

    builder.guard = Guard.new(run_context: builder.caller,
                              only_if: builder.only_if,
                              not_if: builder.not_if)

    name ||= NameInference.infer_rule_name(builder)
    name ||= id

    builder.name(name)
    logger.trace { builder.inspect }
    builder.build(provider, script)
  end
end

#scene(name = nil, description: nil, id: nil, tag: nil, tags: nil, replace: false, script: nil) { ... } ⇒ Core::Rules::Rule?

Create a new scene

A scene is a rule with no triggers. It can be called by various other actions, such as the Run Rules action.

Parameters:

Yields:

  • Block executed when the script is executed.

Returns:

Raises:

  • (ArgumentError)

See Also:



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/openhab/dsl/rules/builder.rb', line 206

def scene(name = nil, description: nil, id: nil, tag: nil, tags: nil, replace: false, script: nil, &block)
  raise ArgumentError, "Block is required" unless block

  inferred_id = nil # rubocop:disable Lint/UselessAssignment
  id ||= inferred_id = NameInference.infer_rule_id_from_block(block)
  name ||= id
  script ||= block.source rescue nil # rubocop:disable Style/RescueModifier

  if replace
    logger.debug { "Removing existing rule '#{id}'." } if DSL.rules.remove(id)
  elsif inferred_id.nil? && (existing_rule = $rules.get(id))
    logger.warn "Scene '#{id}' is not created because " \
                "another script/scene/rule with the same id already exists: #{existing_rule.inspect}."
    return nil
  end

  builder = nil
  ThreadLocal.thread_local(openhab_rule_type: "script", openhab_rule_uid: id) do
    builder = BuilderDSL.new(block.binding)
    builder.uid(id)
    builder.tags("Scene", *Array.wrap(tag), *Array.wrap(tags))
    builder.name(name)
    builder.description(description)
    builder.script(&block)
    logger.trace { builder.inspect }
    builder.build(provider, script)
  end
end

#script(name = nil, description: nil, id: nil, tag: nil, tags: nil, replace: false, script: nil) { ... } ⇒ Core::Rules::Rule?

Create a new script

A script is a rule with no triggers. It can be called by various other actions, such as the Run Rules action, or by calling Core::Rules::Rule#trigger.

Scripts can be executed with some additional context, similar to method parameters (see Core::Rules::Rule#trigger). The context can be accessed from within the script’s execution block as a “local” variable.

Examples:

A simple script

# return the script object into a variable
door_check = script "Check all doors", id: "door_check", tags: :security do
  open_doors = gDoors.members.select(&:open?).map(&:label).join(", ")
  Notification.send("The following doors are open: #{open_doors}") unless open_doors.empty?
end

# run is an alias of trigger
door_check.run

A script with context

# This script expects to be called with `message` as context/parameter
DESTINATION_EMAIL = "[email protected]"
script "Send Notifications", id: "send_alert" do
  Notification.send(message)
  things["mail:smtp:local"].send_mail(DESTINATION_EMAIL, "OpenHAB Alert", message)
end

rules.scripts["send_alert"].run(message: "The door is open!")

Parameters:

Yields:

  • Block executed when the script is executed.

Returns:

Raises:

  • (ArgumentError)

See Also:



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/openhab/dsl/rules/builder.rb', line 158

def script(name = nil, description: nil, id: nil, tag: nil, tags: nil, replace: false, script: nil, &block)
  raise ArgumentError, "Block is required" unless block

  inferred_id = nil # rubocop:disable Lint/UselessAssignment it is used below
  id ||= inferred_id = NameInference.infer_rule_id_from_block(block)
  name ||= id
  script ||= block.source rescue nil # rubocop:disable Style/RescueModifier

  if replace
    logger.debug { "Removing existing rule '#{id}'." } if DSL.rules.remove(id)
  elsif inferred_id.nil? && (existing_rule = $rules.get(id))
    logger.warn "Script '#{id}' is not created because " \
                "another script/scene/rule with the same id already exists: #{existing_rule.inspect}."
    return nil
  end

  builder = nil
  ThreadLocal.thread_local(openhab_rule_type: "script", openhab_rule_uid: id) do
    builder = BuilderDSL.new(block.binding)
    builder.uid(id)
    builder.tags("Script", *Array.wrap(tag), *Array.wrap(tags))
    builder.name(name)
    builder.description(description)
    builder.script(&block)
    logger.trace { builder.inspect }
    builder.build(provider, script)
  end
end