openhab-scripting 2.16.2 → 2.16.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|