openhab-scripting 2.16.2 → 2.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/openhab.rb +12 -16
- data/lib/openhab/core/entity_lookup.rb +162 -0
- data/lib/openhab/core/openhab_setup.rb +31 -0
- data/lib/openhab/core/osgi.rb +61 -0
- data/lib/openhab/dsl/actions.rb +105 -0
- data/lib/openhab/dsl/dsl.rb +47 -0
- data/lib/openhab/{core/dsl → dsl}/gems.rb +0 -1
- data/lib/openhab/dsl/group.rb +100 -0
- data/lib/openhab/dsl/items/items.rb +46 -0
- data/lib/openhab/dsl/items/number_item.rb +352 -0
- data/lib/openhab/dsl/items/string_item.rb +120 -0
- data/lib/openhab/dsl/monkey_patch/actions/actions.rb +4 -0
- data/lib/openhab/dsl/monkey_patch/actions/script_thing_actions.rb +32 -0
- data/lib/openhab/dsl/monkey_patch/events/events.rb +5 -0
- data/lib/openhab/dsl/monkey_patch/events/item_command.rb +23 -0
- data/lib/openhab/dsl/monkey_patch/events/item_state_changed.rb +35 -0
- data/lib/openhab/dsl/monkey_patch/events/thing_status_info.rb +33 -0
- data/lib/openhab/dsl/monkey_patch/items/contact_item.rb +61 -0
- data/lib/openhab/dsl/monkey_patch/items/dimmer_item.rb +193 -0
- data/lib/openhab/dsl/monkey_patch/items/group_item.rb +37 -0
- data/lib/openhab/dsl/monkey_patch/items/items.rb +133 -0
- data/lib/openhab/dsl/monkey_patch/items/metadata.rb +281 -0
- data/lib/openhab/dsl/monkey_patch/items/persistence.rb +70 -0
- data/lib/openhab/dsl/monkey_patch/items/switch_item.rb +95 -0
- data/lib/openhab/dsl/monkey_patch/ruby/number.rb +39 -0
- data/lib/openhab/dsl/monkey_patch/ruby/range.rb +47 -0
- data/lib/openhab/dsl/monkey_patch/ruby/ruby.rb +7 -0
- data/lib/openhab/dsl/monkey_patch/ruby/string.rb +41 -0
- data/lib/openhab/dsl/monkey_patch/types/decimal_type.rb +70 -0
- data/lib/openhab/dsl/monkey_patch/types/on_off_type.rb +51 -0
- data/lib/openhab/dsl/monkey_patch/types/open_closed_type.rb +36 -0
- data/lib/openhab/dsl/monkey_patch/types/percent_type.rb +32 -0
- data/lib/openhab/dsl/monkey_patch/types/quantity_type.rb +69 -0
- data/lib/openhab/dsl/monkey_patch/types/types.rb +8 -0
- data/lib/openhab/dsl/persistence.rb +25 -0
- data/lib/openhab/dsl/rules/automation_rule.rb +342 -0
- data/lib/openhab/dsl/rules/guard.rb +134 -0
- data/lib/openhab/dsl/rules/property.rb +102 -0
- data/lib/openhab/dsl/rules/rule.rb +116 -0
- data/lib/openhab/dsl/rules/rule_config.rb +151 -0
- data/lib/openhab/dsl/rules/triggers/changed.rb +143 -0
- data/lib/openhab/dsl/rules/triggers/channel.rb +53 -0
- data/lib/openhab/dsl/rules/triggers/command.rb +104 -0
- data/lib/openhab/dsl/rules/triggers/cron.rb +177 -0
- data/lib/openhab/dsl/rules/triggers/trigger.rb +124 -0
- data/lib/openhab/dsl/rules/triggers/updated.rb +98 -0
- data/lib/openhab/dsl/states.rb +61 -0
- data/lib/openhab/dsl/things.rb +91 -0
- data/lib/openhab/dsl/time_of_day.rb +228 -0
- data/lib/openhab/dsl/timers.rb +77 -0
- data/lib/openhab/dsl/types/quantity.rb +290 -0
- data/lib/openhab/dsl/units.rb +39 -0
- data/lib/openhab/log/configuration.rb +21 -0
- data/lib/openhab/log/logger.rb +172 -0
- data/lib/openhab/version.rb +1 -1
- metadata +55 -58
- data/lib/openhab/configuration.rb +0 -16
- data/lib/openhab/core/cron.rb +0 -27
- data/lib/openhab/core/debug.rb +0 -34
- data/lib/openhab/core/dsl.rb +0 -51
- data/lib/openhab/core/dsl/actions.rb +0 -107
- data/lib/openhab/core/dsl/entities.rb +0 -147
- data/lib/openhab/core/dsl/group.rb +0 -102
- data/lib/openhab/core/dsl/items/items.rb +0 -51
- data/lib/openhab/core/dsl/items/number_item.rb +0 -323
- data/lib/openhab/core/dsl/items/string_item.rb +0 -122
- data/lib/openhab/core/dsl/monkey_patch/actions/actions.rb +0 -4
- data/lib/openhab/core/dsl/monkey_patch/actions/script_thing_actions.rb +0 -22
- data/lib/openhab/core/dsl/monkey_patch/events.rb +0 -5
- data/lib/openhab/core/dsl/monkey_patch/events/item_command.rb +0 -13
- data/lib/openhab/core/dsl/monkey_patch/events/item_state_changed.rb +0 -25
- data/lib/openhab/core/dsl/monkey_patch/events/thing_status_info.rb +0 -26
- data/lib/openhab/core/dsl/monkey_patch/items/contact_item.rb +0 -54
- data/lib/openhab/core/dsl/monkey_patch/items/dimmer_item.rb +0 -182
- data/lib/openhab/core/dsl/monkey_patch/items/group_item.rb +0 -27
- data/lib/openhab/core/dsl/monkey_patch/items/items.rb +0 -132
- data/lib/openhab/core/dsl/monkey_patch/items/metadata.rb +0 -283
- data/lib/openhab/core/dsl/monkey_patch/items/persistence.rb +0 -72
- data/lib/openhab/core/dsl/monkey_patch/items/switch_item.rb +0 -87
- data/lib/openhab/core/dsl/monkey_patch/ruby/number.rb +0 -41
- data/lib/openhab/core/dsl/monkey_patch/ruby/range.rb +0 -47
- data/lib/openhab/core/dsl/monkey_patch/ruby/ruby.rb +0 -7
- data/lib/openhab/core/dsl/monkey_patch/ruby/string.rb +0 -43
- data/lib/openhab/core/dsl/monkey_patch/types/decimal_type.rb +0 -60
- data/lib/openhab/core/dsl/monkey_patch/types/on_off_type.rb +0 -41
- data/lib/openhab/core/dsl/monkey_patch/types/open_closed_type.rb +0 -25
- data/lib/openhab/core/dsl/monkey_patch/types/percent_type.rb +0 -23
- data/lib/openhab/core/dsl/monkey_patch/types/quantity_type.rb +0 -58
- data/lib/openhab/core/dsl/monkey_patch/types/types.rb +0 -8
- data/lib/openhab/core/dsl/persistence.rb +0 -27
- data/lib/openhab/core/dsl/property.rb +0 -96
- data/lib/openhab/core/dsl/rule/automation_rule.rb +0 -345
- data/lib/openhab/core/dsl/rule/guard.rb +0 -136
- data/lib/openhab/core/dsl/rule/rule.rb +0 -117
- data/lib/openhab/core/dsl/rule/rule_config.rb +0 -153
- data/lib/openhab/core/dsl/rule/triggers/changed.rb +0 -145
- data/lib/openhab/core/dsl/rule/triggers/channel.rb +0 -55
- data/lib/openhab/core/dsl/rule/triggers/command.rb +0 -106
- data/lib/openhab/core/dsl/rule/triggers/cron.rb +0 -160
- data/lib/openhab/core/dsl/rule/triggers/trigger.rb +0 -126
- data/lib/openhab/core/dsl/rule/triggers/updated.rb +0 -100
- data/lib/openhab/core/dsl/states.rb +0 -63
- data/lib/openhab/core/dsl/things.rb +0 -93
- data/lib/openhab/core/dsl/time_of_day.rb +0 -231
- data/lib/openhab/core/dsl/timers.rb +0 -79
- data/lib/openhab/core/dsl/types/quantity.rb +0 -292
- data/lib/openhab/core/dsl/units.rb +0 -41
- data/lib/openhab/core/log.rb +0 -170
- data/lib/openhab/core/patch_load_path.rb +0 -7
- data/lib/openhab/core/startup_delay.rb +0 -23
- data/lib/openhab/osgi.rb +0 -59
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'openhab/dsl/rules/property'
|
|
4
|
+
require 'openhab/log/logger'
|
|
5
|
+
|
|
6
|
+
module OpenHAB
|
|
7
|
+
module DSL
|
|
8
|
+
module Rules
|
|
9
|
+
#
|
|
10
|
+
# Guards for rules
|
|
11
|
+
#
|
|
12
|
+
module Guard
|
|
13
|
+
include OpenHAB::DSL::Rules::Property
|
|
14
|
+
|
|
15
|
+
prop_array(:only_if) do |item|
|
|
16
|
+
unless item.is_a?(Proc) || item.respond_to?(:truthy?)
|
|
17
|
+
raise ArgumentError, "Object passed to only_if must respond_to 'truthy?'"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
prop_array(:not_if) do |item|
|
|
22
|
+
unless item.is_a?(Proc) || item.respond_to?(:truthy?)
|
|
23
|
+
raise ArgumentError, "Object passed to not_if must respond_to 'truthy?'"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# Guard that can prevent execute of a rule if not satisfied
|
|
29
|
+
#
|
|
30
|
+
class Guard
|
|
31
|
+
include OpenHAB::Log
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# Create a new Guard
|
|
35
|
+
#
|
|
36
|
+
# @param [Object] only_if Item or Proc to use as guard
|
|
37
|
+
# @param [Object] not_if Item or Proc to use as guard
|
|
38
|
+
#
|
|
39
|
+
def initialize(only_if: nil, not_if: nil)
|
|
40
|
+
@only_if = only_if
|
|
41
|
+
@not_if = not_if
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
# Convert the guard into a string
|
|
46
|
+
#
|
|
47
|
+
# @return [String] describing the only_of and not_if guards
|
|
48
|
+
#
|
|
49
|
+
def to_s
|
|
50
|
+
"only_if: #{@only_if}, not_if: #{@not_if}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# Checks if a guard should run
|
|
55
|
+
#
|
|
56
|
+
# @param [OpenHAB Trigger Event] event OpenHAB Trigger Event
|
|
57
|
+
#
|
|
58
|
+
# @return [Boolean] True if guard is satisfied, false otherwise
|
|
59
|
+
#
|
|
60
|
+
def should_run?(event)
|
|
61
|
+
logger.trace("Checking guards #{self}")
|
|
62
|
+
check(@only_if, check_type: :only_if, event: event) && check(@not_if, check_type: :not_if, event: event)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# Check if guard is satisfied
|
|
69
|
+
#
|
|
70
|
+
# @param [Array] conditions to check
|
|
71
|
+
# @param [Symbol] check_type type of check to perform (:only_if or :not_if)
|
|
72
|
+
# @param [Event] event OpenHAB event to see if it satisfies the guard
|
|
73
|
+
#
|
|
74
|
+
# @return [Boolean] True if guard is satisfied, false otherwise
|
|
75
|
+
#
|
|
76
|
+
def check(conditions, check_type:, event:)
|
|
77
|
+
return true if conditions.nil? || conditions.empty?
|
|
78
|
+
|
|
79
|
+
procs, items = conditions.flatten.partition { |condition| condition.is_a? Proc }
|
|
80
|
+
logger.trace("Procs: #{procs} Items: #{items}")
|
|
81
|
+
|
|
82
|
+
items.each { |item| logger.trace("#{item} truthy? #{item.truthy?}") }
|
|
83
|
+
|
|
84
|
+
process_check(check_type: check_type, event: event, items: items, procs: procs)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
#
|
|
88
|
+
# Execute the guard check
|
|
89
|
+
#
|
|
90
|
+
# @param [Symbol] check_type :only_if or :not_if to check
|
|
91
|
+
# @param [OpenHAB Event] event event to check if meets guard
|
|
92
|
+
# @param [Array<Item>] items to check if satisfy criteria
|
|
93
|
+
# @param [Array] procs to check if satisfy criteria
|
|
94
|
+
#
|
|
95
|
+
# @return [Boolean] True if criteria are satisfied, false otherwise
|
|
96
|
+
#
|
|
97
|
+
def process_check(check_type:, event:, items:, procs:)
|
|
98
|
+
case check_type
|
|
99
|
+
when :only_if then process_only_if(event, items, procs)
|
|
100
|
+
when :not_if then process_not_if(event, items, procs)
|
|
101
|
+
else raise ArgumentError, "Unexpected check type: #{check_type}"
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
#
|
|
106
|
+
# Check not_if guard
|
|
107
|
+
#
|
|
108
|
+
# @param [OpenHAB Event] event event to check if meets guard
|
|
109
|
+
# @param [Array<Item>] items to check if satisfy criteria
|
|
110
|
+
# @param [Array] procs to check if satisfy criteria
|
|
111
|
+
#
|
|
112
|
+
# @return [Boolean] True if criteria are satisfied, false otherwise
|
|
113
|
+
#
|
|
114
|
+
def process_not_if(event, items, procs)
|
|
115
|
+
items.none?(&:truthy?) && procs.none? { |proc| proc.call(event) }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
#
|
|
119
|
+
# Check only_if guard
|
|
120
|
+
#
|
|
121
|
+
# @param [OpenHAB Event] event event to check if meets guard
|
|
122
|
+
# @param [Array<Item>] items to check if satisfy criteria
|
|
123
|
+
# @param [Array] procs to check if satisfy criteria
|
|
124
|
+
#
|
|
125
|
+
# @return [Boolean] True if criteria are satisfied, false otherwise
|
|
126
|
+
#
|
|
127
|
+
def process_only_if(event, items, procs)
|
|
128
|
+
items.all?(&:truthy?) && procs.all? { |proc| proc.call(event) }
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'openhab/log/logger'
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module DSL
|
|
7
|
+
module Rules
|
|
8
|
+
#
|
|
9
|
+
# Provides methods to support DSL properties
|
|
10
|
+
#
|
|
11
|
+
module Property
|
|
12
|
+
include OpenHAB::Log
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# Extend the calling object with the property methods
|
|
16
|
+
#
|
|
17
|
+
# @param [Object] base object to extend
|
|
18
|
+
#
|
|
19
|
+
#
|
|
20
|
+
def self.included(base)
|
|
21
|
+
base.extend PropertyMethods
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Methods that support creating properties in the DSL
|
|
26
|
+
#
|
|
27
|
+
module PropertyMethods
|
|
28
|
+
#
|
|
29
|
+
# Dynamically creates a property that acts and an accessor with no arguments
|
|
30
|
+
# and a setter with any number of arguments or a block.
|
|
31
|
+
#
|
|
32
|
+
# @param [String] name of the property
|
|
33
|
+
#
|
|
34
|
+
#
|
|
35
|
+
# rubocop:disable Metrics/MethodLength
|
|
36
|
+
# rubocop:disable Metrics/AbcSize
|
|
37
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
38
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
39
|
+
def prop(name)
|
|
40
|
+
# rubocop rules are disabled because this method is dynamically defined on the calling
|
|
41
|
+
# object making calls to other methods in this module impossible, or if done on methods
|
|
42
|
+
# in this module than instance variable belong to the module not the calling class
|
|
43
|
+
define_method(name) do |*args, &block|
|
|
44
|
+
if args.length.zero? && block.nil? == true
|
|
45
|
+
instance_variable_get("@#{name}")
|
|
46
|
+
else
|
|
47
|
+
logger.trace("Property '#{name}' called with args(#{args}) and block(#{block})")
|
|
48
|
+
if args.length == 1
|
|
49
|
+
instance_variable_set("@#{name}", args.first)
|
|
50
|
+
elsif args.length > 1
|
|
51
|
+
instance_variable_set("@#{name}", args)
|
|
52
|
+
elsif block
|
|
53
|
+
instance_variable_set("@#{name}", block)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
#
|
|
60
|
+
# Dynamically creates a property array acts and an accessor with no arguments
|
|
61
|
+
# and a pushes any number of arguments or a block onto they property array
|
|
62
|
+
# You can provide a block to this method which can be used to check if the provided value is acceptable.
|
|
63
|
+
#
|
|
64
|
+
# @param [String] name of the property
|
|
65
|
+
# @param [String] array_name name of the array to use, defaults to name of property
|
|
66
|
+
# @param [Class] wrapper object to put around elements added to the array
|
|
67
|
+
#
|
|
68
|
+
def prop_array(name, array_name: nil, wrapper: nil)
|
|
69
|
+
define_method(name) do |*args, &block|
|
|
70
|
+
array_name ||= name
|
|
71
|
+
if args.length.zero? && block.nil? == true
|
|
72
|
+
instance_variable_get("@#{array_name}")
|
|
73
|
+
else
|
|
74
|
+
logger.trace("Property '#{name}' called with args(#{args}) and block(#{block})")
|
|
75
|
+
if args.length == 1
|
|
76
|
+
insert = args.first
|
|
77
|
+
elsif args.length > 1
|
|
78
|
+
insert = args
|
|
79
|
+
elsif block
|
|
80
|
+
insert = block
|
|
81
|
+
end
|
|
82
|
+
yield insert if block_given?
|
|
83
|
+
insert = wrapper.new(insert) if wrapper
|
|
84
|
+
instance_variable_set("@#{array_name}", (instance_variable_get("@#{array_name}") || []) << insert)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
return unless array_name
|
|
89
|
+
|
|
90
|
+
define_method(array_name) do
|
|
91
|
+
instance_variable_get("@#{array_name}")
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
# rubocop:enable Metrics/MethodLength
|
|
96
|
+
# rubocop:enable Metrics/AbcSize
|
|
97
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
98
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'openhab/dsl/rules/rule_config'
|
|
4
|
+
require 'openhab/dsl/rules/automation_rule'
|
|
5
|
+
require 'openhab/dsl/rules/guard'
|
|
6
|
+
|
|
7
|
+
module OpenHAB
|
|
8
|
+
#
|
|
9
|
+
# Contains code to create an OpenHAB DSL
|
|
10
|
+
#
|
|
11
|
+
module DSL
|
|
12
|
+
#
|
|
13
|
+
# Creates and manages OpenHAB Rules
|
|
14
|
+
#
|
|
15
|
+
module Rules
|
|
16
|
+
#
|
|
17
|
+
# Create a new rule
|
|
18
|
+
#
|
|
19
|
+
# @param [String] rule_name <description>
|
|
20
|
+
# @yield [] Block executed in context of a RuleConfig
|
|
21
|
+
#
|
|
22
|
+
#
|
|
23
|
+
def rule(rule_name, &block)
|
|
24
|
+
@rule_name = rule_name
|
|
25
|
+
config = RuleConfig.new(rule_name, block.binding)
|
|
26
|
+
config.instance_eval(&block)
|
|
27
|
+
config.guard = Guard::Guard.new(only_if: config.only_if, not_if: config.not_if)
|
|
28
|
+
logger.trace { config.inspect }
|
|
29
|
+
process_rule_config(config)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Create a logger where name includes rule name if name is set
|
|
34
|
+
#
|
|
35
|
+
# @return [Log::Logger] Logger with name that appended with rule name if rule name is set
|
|
36
|
+
#
|
|
37
|
+
def logger
|
|
38
|
+
if @rule_name
|
|
39
|
+
Log.logger(@rule_name.chomp.gsub(/\s+/, '_'))
|
|
40
|
+
else
|
|
41
|
+
super
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
#
|
|
48
|
+
# Process a rule based on the supplied configuration
|
|
49
|
+
#
|
|
50
|
+
# @param [RuleConfig] config for rule
|
|
51
|
+
#
|
|
52
|
+
#
|
|
53
|
+
def process_rule_config(config)
|
|
54
|
+
return unless create_rule?(config)
|
|
55
|
+
|
|
56
|
+
rule = AutomationRule.new(config: config)
|
|
57
|
+
add_rule(rule)
|
|
58
|
+
rule.execute if config.on_start?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# Should a rule be created based on rule configuration
|
|
63
|
+
#
|
|
64
|
+
# @param [RuleConfig] config to check
|
|
65
|
+
#
|
|
66
|
+
# @return [Boolean] true if it should be created, false otherwise
|
|
67
|
+
#
|
|
68
|
+
def create_rule?(config)
|
|
69
|
+
if !triggers?(config)
|
|
70
|
+
logger.warn "Rule '#{config.name}' has no triggers, not creating rule"
|
|
71
|
+
elsif !execution_blocks?(config)
|
|
72
|
+
logger.warn "Rule '#{config.name}' has no execution blocks, not creating rule"
|
|
73
|
+
elsif !config.enabled
|
|
74
|
+
logger.debug "Rule '#{config.name}' marked as disabled, not creating rule."
|
|
75
|
+
else
|
|
76
|
+
return true
|
|
77
|
+
end
|
|
78
|
+
false
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# Check if the rule has any triggers
|
|
83
|
+
#
|
|
84
|
+
# @param [RuleConfig] config to check for triggers
|
|
85
|
+
#
|
|
86
|
+
# @return [Boolean] True if rule has triggers, false otherwise
|
|
87
|
+
#
|
|
88
|
+
def triggers?(config)
|
|
89
|
+
config.on_start? || config.triggers.length.positive?
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
#
|
|
93
|
+
# Check if the rule has any execution blocks
|
|
94
|
+
#
|
|
95
|
+
# @param [RuleConfig] config to check for triggers
|
|
96
|
+
#
|
|
97
|
+
# @return [Boolean] True if rule has execution blocks, false otherwise
|
|
98
|
+
#
|
|
99
|
+
def execution_blocks?(config)
|
|
100
|
+
(config.run || []).length.positive?
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
#
|
|
104
|
+
# Add a rule to the automation managed
|
|
105
|
+
#
|
|
106
|
+
# @param [Java::OrgOpenhabCoreAutomationModuleScriptRulesupportSharedSimple::SimpleRule] rule to add
|
|
107
|
+
#
|
|
108
|
+
#
|
|
109
|
+
def add_rule(rule)
|
|
110
|
+
# rubocop: disable Style/GlobalVars
|
|
111
|
+
$scriptExtension.get('automationManager').addRule(rule)
|
|
112
|
+
# rubocop: enable Style/GlobalVars
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'java'
|
|
4
|
+
require 'pp'
|
|
5
|
+
require 'openhab/dsl/rules/property'
|
|
6
|
+
require 'openhab/dsl/rules/triggers/cron'
|
|
7
|
+
require 'openhab/dsl/rules/triggers/changed'
|
|
8
|
+
require 'openhab/dsl/rules/triggers/channel'
|
|
9
|
+
require 'openhab/dsl/rules/triggers/command'
|
|
10
|
+
require 'openhab/dsl/rules/triggers/updated'
|
|
11
|
+
require 'openhab/dsl/rules/guard'
|
|
12
|
+
require 'openhab/core/entity_lookup'
|
|
13
|
+
require 'openhab/dsl/time_of_day'
|
|
14
|
+
require 'openhab/dsl/dsl'
|
|
15
|
+
require 'openhab/dsl/timers'
|
|
16
|
+
|
|
17
|
+
module OpenHAB
|
|
18
|
+
module DSL
|
|
19
|
+
#
|
|
20
|
+
# Creates and manages OpenHAB Rules
|
|
21
|
+
#
|
|
22
|
+
module Rules
|
|
23
|
+
#
|
|
24
|
+
# Rule configuration for OpenHAB Rules engine
|
|
25
|
+
#
|
|
26
|
+
class RuleConfig
|
|
27
|
+
include OpenHAB::Log
|
|
28
|
+
include OpenHAB::Core::EntityLookup
|
|
29
|
+
include OpenHAB::DSL::Rules::Triggers
|
|
30
|
+
include OpenHAB::DSL::Rules::Guard
|
|
31
|
+
include OpenHAB::DSL::Rules::Property
|
|
32
|
+
extend OpenHAB::DSL
|
|
33
|
+
|
|
34
|
+
java_import org.openhab.core.library.items.SwitchItem
|
|
35
|
+
|
|
36
|
+
# @return [Array] Of triggers
|
|
37
|
+
attr_reader :triggers
|
|
38
|
+
|
|
39
|
+
# @return [Array] Of trigger delays
|
|
40
|
+
attr_reader :trigger_delays
|
|
41
|
+
|
|
42
|
+
# @return [Array] Of trigger guards
|
|
43
|
+
attr_accessor :guard
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# Struct holding a run block
|
|
47
|
+
#
|
|
48
|
+
Run = Struct.new(:block)
|
|
49
|
+
|
|
50
|
+
#
|
|
51
|
+
# Struct holding a Triggered block
|
|
52
|
+
#
|
|
53
|
+
Trigger = Struct.new(:block)
|
|
54
|
+
|
|
55
|
+
#
|
|
56
|
+
# Struct holding an otherwise block
|
|
57
|
+
#
|
|
58
|
+
Otherwise = Struct.new(:block)
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
# Struct holding rule delays
|
|
62
|
+
#
|
|
63
|
+
Delay = Struct.new(:duration)
|
|
64
|
+
|
|
65
|
+
prop_array :run, array_name: :run_queue, wrapper: Run
|
|
66
|
+
prop_array :triggered, array_name: :run_queue, wrapper: Trigger
|
|
67
|
+
prop_array :delay, array_name: :run_queue, wrapper: Delay
|
|
68
|
+
prop_array :otherwise, array_name: :run_queue, wrapper: Otherwise
|
|
69
|
+
|
|
70
|
+
prop :name
|
|
71
|
+
prop :description
|
|
72
|
+
prop :enabled
|
|
73
|
+
prop :between
|
|
74
|
+
|
|
75
|
+
#
|
|
76
|
+
# Create a new RuleConfig
|
|
77
|
+
#
|
|
78
|
+
# @param [Object] caller_binding The object initializing this configuration.
|
|
79
|
+
# Used to execute within the object's context
|
|
80
|
+
#
|
|
81
|
+
def initialize(rule_name, caller_binding)
|
|
82
|
+
@triggers = []
|
|
83
|
+
@trigger_delays = {}
|
|
84
|
+
@caller = caller_binding.eval 'self'
|
|
85
|
+
enabled(true)
|
|
86
|
+
on_start(false)
|
|
87
|
+
name(rule_name)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
#
|
|
91
|
+
# Start this rule on system startup
|
|
92
|
+
#
|
|
93
|
+
# @param [Boolean] run_on_start Run this rule on start, defaults to True
|
|
94
|
+
#
|
|
95
|
+
#
|
|
96
|
+
# rubocop: disable Style/OptionalBooleanParameter
|
|
97
|
+
# Disabled cop due to use in a DSL
|
|
98
|
+
def on_start(run_on_start = true)
|
|
99
|
+
@on_start = run_on_start
|
|
100
|
+
end
|
|
101
|
+
# rubocop: enable Style/OptionalBooleanParameter
|
|
102
|
+
|
|
103
|
+
#
|
|
104
|
+
# Checks if this rule should run on start
|
|
105
|
+
#
|
|
106
|
+
# @return [Boolean] True if rule should run on start, false otherwise.
|
|
107
|
+
#
|
|
108
|
+
def on_start?
|
|
109
|
+
@on_start
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
#
|
|
113
|
+
# Run the supplied block inside the object instance of the object that created the rule config
|
|
114
|
+
#
|
|
115
|
+
# @yield [] Block executed in context of the object creating the rule config
|
|
116
|
+
#
|
|
117
|
+
#
|
|
118
|
+
def my(&block)
|
|
119
|
+
@caller.instance_eval(&block)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
#
|
|
123
|
+
# Create a logger where name includes rule name if name is set
|
|
124
|
+
#
|
|
125
|
+
# @return [Log::Logger] Logger with name that appended with rule name if rule name is set
|
|
126
|
+
#
|
|
127
|
+
def logger
|
|
128
|
+
if name
|
|
129
|
+
Log.logger(name.chomp.gsub(/\s+/, '_'))
|
|
130
|
+
else
|
|
131
|
+
super
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
#
|
|
136
|
+
# Inspect the config object
|
|
137
|
+
#
|
|
138
|
+
# @return [String] details of the config object
|
|
139
|
+
#
|
|
140
|
+
def inspect
|
|
141
|
+
"Name: (#{name}) " \
|
|
142
|
+
"Triggers: (#{triggers}) " \
|
|
143
|
+
"Run blocks: (#{run}) " \
|
|
144
|
+
"on_start: (#{on_start?}) " \
|
|
145
|
+
"Trigger Waits: #{trigger_delays} " \
|
|
146
|
+
"Trigger UIDs: #{triggers.map(&:id).join(', ')}"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|