openhab-scripting 5.17.0 → 5.18.1
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/core/items/semantics/enumerable.rb +2 -2
- data/lib/openhab/core/rules/registry.rb +2 -1
- data/lib/openhab/core/rules/rule.rb +1 -0
- data/lib/openhab/core/types/string_type.rb +1 -1
- data/lib/openhab/core/types/time_series.rb +11 -1
- data/lib/openhab/dsl/items/builder.rb +0 -1
- data/lib/openhab/dsl/items/timed_command.rb +1 -0
- data/lib/openhab/dsl/rules/builder.rb +98 -32
- data/lib/openhab/dsl/rules/name_inference.rb +9 -8
- data/lib/openhab/dsl/rules/property.rb +4 -1
- data/lib/openhab/dsl/rules/rule_triggers.rb +5 -3
- data/lib/openhab/dsl/rules/terse.rb +21 -16
- data/lib/openhab/dsl/rules/triggers/changed.rb +15 -7
- data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +1 -1
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/dsl.rb +24 -2
- data/lib/openhab/rspec/mocks/persistence_service.rb +10 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfc9ae60d0f82fc677a157ac0efd58c12fc597f5ac8f3d79d7aa9c472e2c5d3a
|
4
|
+
data.tar.gz: b8bf1721d064b2f88554722518496aa6c53b89407a9fb212880972725e49901f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e50f4ce2c5832a39b3ab9c7b7a489b22697a23b20ce803a633f28ea9b44ed2661a820cdefd00bc54c71cb212a2c1a1d96c35c413937cd3ac514aec55a4c13da
|
7
|
+
data.tar.gz: a298851e7255074cb21d9fd4e495a8c8dc750425b0db3319ab17353c2e07106e0f669a40912bbe98cc6db9f252ff70ebe68b9c94fb7366c4b257200da13eefda
|
@@ -97,8 +97,8 @@ module Enumerable
|
|
97
97
|
# Send a command to every item in the collection
|
98
98
|
# @return [self, nil] nil when `ensure` is in effect and all the items were already in the same state,
|
99
99
|
# otherwise self
|
100
|
-
def command(command)
|
101
|
-
self if count { |i| i.command(command) }.positive?
|
100
|
+
def command(command, **kwargs)
|
101
|
+
self if count { |i| i.command(command, **kwargs) }.positive?
|
102
102
|
end
|
103
103
|
|
104
104
|
# Send a command to every item in the collection, even when {OpenHAB::DSL.ensure_states! ensure_states!} is in effect.
|
@@ -63,7 +63,8 @@ module OpenHAB
|
|
63
63
|
#
|
64
64
|
def remove(rule_uid)
|
65
65
|
rule_uid = rule_uid.uid if rule_uid.is_a?(Rule)
|
66
|
-
provider = Provider.registry.provider_for(rule_uid)
|
66
|
+
return nil unless (provider = Provider.registry.provider_for(rule_uid))
|
67
|
+
|
67
68
|
unless provider.is_a?(org.openhab.core.common.registry.ManagedProvider)
|
68
69
|
raise "Cannot remove rule #{rule_uid} from non-managed provider #{provider.inspect}"
|
69
70
|
end
|
@@ -149,6 +149,7 @@ module OpenHAB
|
|
149
149
|
r += " #{visibility}" unless visible?
|
150
150
|
r += " #{status || "<detached>"}"
|
151
151
|
r += " (#{status_info.status_detail})" if status_info && status_info.status_detail != RuleStatusDetail::NONE
|
152
|
+
r += " description=#{description.inspect}" if description
|
152
153
|
r += " tags=#{tags.to_a.inspect}" unless tags.empty?
|
153
154
|
r += " configuration=#{configuration.properties.to_h}" if configuration && !configuration.properties.empty?
|
154
155
|
"#{r}>"
|
@@ -101,12 +101,22 @@ module OpenHAB
|
|
101
101
|
# @note This method returns self so it can be chained, unlike the Java version.
|
102
102
|
#
|
103
103
|
# @param [Instant, #to_zoned_date_time, #to_instant] instant An instant for the given state.
|
104
|
-
# @param [State] state The State at the given timestamp.
|
104
|
+
# @param [State, String, Numeric] state The State at the given timestamp.
|
105
|
+
# If a String is given, it will be converted to {StringType}.
|
106
|
+
# If a {Numeric} is given, it will be converted to {DecimalType}.
|
105
107
|
# @return [self]
|
108
|
+
# @raise [ArgumentError] if state is not a {State}, String or {Numeric}
|
106
109
|
#
|
107
110
|
def add(instant, state)
|
108
111
|
instant = instant.to_zoned_date_time if instant.respond_to?(:to_zoned_date_time)
|
109
112
|
instant = instant.to_instant if instant.respond_to?(:to_instant)
|
113
|
+
state = case state
|
114
|
+
when State then state
|
115
|
+
when String then StringType.new(state)
|
116
|
+
when Numeric then DecimalType.new(state)
|
117
|
+
else
|
118
|
+
raise ArgumentError, "state must be a State, String or Numeric, but was #{state.class}"
|
119
|
+
end
|
110
120
|
add_instant(instant, state)
|
111
121
|
self
|
112
122
|
end
|
@@ -672,7 +672,6 @@ module OpenHAB
|
|
672
672
|
# @param (see ItemBuilder#initialize)
|
673
673
|
def initialize(*args, type: nil, function: nil, thing: nil, **kwargs)
|
674
674
|
raise ArgumentError, "invalid function #{function}" if function && !function.match?(FUNCTION_REGEX)
|
675
|
-
raise ArgumentError, "state cannot be set on GroupItems" if kwargs[:state]
|
676
675
|
|
677
676
|
super(type, *args, **kwargs)
|
678
677
|
@function = function
|
@@ -40,7 +40,17 @@ module OpenHAB
|
|
40
40
|
# The rule must have at least one trigger and one execution block.
|
41
41
|
# To create a "script" without any triggers, use {OpenHAB::DSL.script script}.
|
42
42
|
#
|
43
|
+
# When explicit `id` is not provided, the rule's ID will be inferred from the block's source location,
|
44
|
+
# and a suffix will be added to avoid clashing against existing rules.
|
45
|
+
#
|
46
|
+
# When an explicit `id` is provided and an existing rule with the same id already exists,
|
47
|
+
# the rule will not be created, and the method will return nil.
|
48
|
+
#
|
49
|
+
# To ensure that a rule is created even when the same id already exists, use {OpenHAB::DSL.rule!} or call
|
50
|
+
# {Core::Rules::Registry#remove rules.remove} to remove any existing rule prior to creating the new rule.
|
51
|
+
#
|
43
52
|
# @param [String] name The rule name
|
53
|
+
# @param [String] id The rule's ID. This can also be defined in the block using {Rules::BuilderDSL#uid uid}.
|
44
54
|
# @yield Block executed in the context of a {Rules::BuilderDSL}
|
45
55
|
# @yieldparam [Rules::BuilderDSL] rule
|
46
56
|
# Optional parameter to access the rule configuration from within execution blocks and guards.
|
@@ -48,20 +58,26 @@ module OpenHAB
|
|
48
58
|
#
|
49
59
|
# @see OpenHAB::DSL::Rules::BuilderDSL Rule BuilderDSL for details on rule triggers, guards and execution blocks
|
50
60
|
# @see Rules::Terse Terse Rules
|
61
|
+
# @see DSL.rule!
|
51
62
|
#
|
52
63
|
# @example
|
53
|
-
# require "openhab/dsl"
|
54
|
-
#
|
55
64
|
# rule "name" do
|
56
65
|
# <one or more triggers>
|
57
66
|
# <one or more execution blocks>
|
58
67
|
# <zero or more guards>
|
59
68
|
# end
|
60
69
|
#
|
61
|
-
|
70
|
+
# @example Create a rule with an explicit id, deleting any existing rule with the same id
|
71
|
+
# rule! "name", id: "my_happy_day_reminder" do
|
72
|
+
# every :day
|
73
|
+
# run { logger.info "Happy new day!" }
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
def rule(name = nil, id: nil, replace: nil, script: nil, binding: nil, &block)
|
62
77
|
raise ArgumentError, "Block is required" unless block
|
63
78
|
|
64
|
-
|
79
|
+
inferred_id = nil
|
80
|
+
id ||= inferred_id = NameInference.infer_rule_id_from_block(block)
|
65
81
|
script ||= block.source rescue nil # rubocop:disable Style/RescueModifier
|
66
82
|
|
67
83
|
builder = nil
|
@@ -70,6 +86,18 @@ module OpenHAB
|
|
70
86
|
builder = BuilderDSL.new(binding || block.binding)
|
71
87
|
builder.uid(id)
|
72
88
|
builder.instance_exec(builder, &block)
|
89
|
+
|
90
|
+
if replace
|
91
|
+
logger.debug { "Removing existing rule '#{builder.uid}'." } if DSL.rules.remove(builder.uid)
|
92
|
+
elsif replace.nil?
|
93
|
+
id_not_inferred = inferred_id.nil? || inferred_id != builder.uid
|
94
|
+
if id_not_inferred && (existing_rule = $rules.get(builder.uid))
|
95
|
+
logger.warn "Rule '#{builder.uid}' is not created because " \
|
96
|
+
"another rule/script/scene with the same id already exists: #{existing_rule.inspect}."
|
97
|
+
return nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
73
101
|
builder.guard = Guard.new(run_context: builder.caller,
|
74
102
|
only_if: builder.only_if,
|
75
103
|
not_if: builder.not_if)
|
@@ -101,7 +129,7 @@ module OpenHAB
|
|
101
129
|
# @param [String, Symbol, Semantics::Tag, Array<String, Symbol, Semantics::Tag>, nil] tags
|
102
130
|
# Fluent alias for `tag`
|
103
131
|
# @yield [] Block executed when the script is executed.
|
104
|
-
# @return [Core::Rules::Rule]
|
132
|
+
# @return [Core::Rules::Rule, nil]
|
105
133
|
#
|
106
134
|
# @example A simple script
|
107
135
|
# # return the script object into a variable
|
@@ -123,15 +151,26 @@ module OpenHAB
|
|
123
151
|
#
|
124
152
|
# rules.scripts["send_alert"].run(message: "The door is open!")
|
125
153
|
#
|
154
|
+
# @see DSL.rule
|
126
155
|
# @see Core::Rules::Rule#trigger
|
156
|
+
# @see DSL.script!
|
127
157
|
#
|
128
|
-
def script(name = nil, description: nil, id: nil, tag: nil, tags: nil, script: nil, &block)
|
158
|
+
def script(name = nil, description: nil, id: nil, tag: nil, tags: nil, replace: false, script: nil, &block)
|
129
159
|
raise ArgumentError, "Block is required" unless block
|
130
160
|
|
131
|
-
|
161
|
+
inferred_id = nil # rubocop:disable Lint/UselessAssignment it is used below
|
162
|
+
id ||= inferred_id = NameInference.infer_rule_id_from_block(block)
|
132
163
|
name ||= id
|
133
164
|
script ||= block.source rescue nil # rubocop:disable Style/RescueModifier
|
134
165
|
|
166
|
+
if replace
|
167
|
+
logger.debug { "Removing existing rule '#{id}'." } if DSL.rules.remove(id)
|
168
|
+
elsif inferred_id.nil? && (existing_rule = $rules.get(id))
|
169
|
+
logger.warn "Script '#{id}' is not created because " \
|
170
|
+
"another script/scene/rule with the same id already exists: #{existing_rule.inspect}."
|
171
|
+
return nil
|
172
|
+
end
|
173
|
+
|
135
174
|
builder = nil
|
136
175
|
ThreadLocal.thread_local(openhab_rule_type: "script", openhab_rule_uid: id) do
|
137
176
|
builder = BuilderDSL.new(block.binding)
|
@@ -159,15 +198,27 @@ module OpenHAB
|
|
159
198
|
# @param [String, Symbol, Semantics::Tag, Array<String, Symbol, Semantics::Tag>, nil] tags
|
160
199
|
# Fluent alias for `tag`
|
161
200
|
# @yield [] Block executed when the script is executed.
|
162
|
-
# @return [Core::Rules::Rule]
|
201
|
+
# @return [Core::Rules::Rule, nil]
|
202
|
+
#
|
203
|
+
# @see DSL.rule
|
204
|
+
# @see DSL.scene!
|
163
205
|
#
|
164
|
-
def scene(name = nil, description: nil, id: nil, tag: nil, tags: nil, script: nil, &block)
|
206
|
+
def scene(name = nil, description: nil, id: nil, tag: nil, tags: nil, replace: false, script: nil, &block)
|
165
207
|
raise ArgumentError, "Block is required" unless block
|
166
208
|
|
167
|
-
|
209
|
+
inferred_id = nil # rubocop:disable Lint/UselessAssignment
|
210
|
+
id ||= inferred_id = NameInference.infer_rule_id_from_block(block)
|
168
211
|
name ||= id
|
169
212
|
script ||= block.source rescue nil # rubocop:disable Style/RescueModifier
|
170
213
|
|
214
|
+
if replace
|
215
|
+
logger.debug { "Removing existing rule '#{id}'." } if DSL.rules.remove(id)
|
216
|
+
elsif inferred_id.nil? && (existing_rule = $rules.get(id))
|
217
|
+
logger.warn "Scene '#{id}' is not created because " \
|
218
|
+
"another script/scene/rule with the same id already exists: #{existing_rule.inspect}."
|
219
|
+
return nil
|
220
|
+
end
|
221
|
+
|
171
222
|
builder = nil
|
172
223
|
ThreadLocal.thread_local(openhab_rule_type: "script", openhab_rule_uid: id) do
|
173
224
|
builder = BuilderDSL.new(block.binding)
|
@@ -400,7 +451,7 @@ module OpenHAB
|
|
400
451
|
# @param [String] id
|
401
452
|
# @return [void]
|
402
453
|
#
|
403
|
-
prop :
|
454
|
+
prop(:uid) { |id| Thread.current[:openhab_rule_uid] = id }
|
404
455
|
|
405
456
|
#
|
406
457
|
# @!method name(value)
|
@@ -994,13 +1045,20 @@ module OpenHAB
|
|
994
1045
|
# @param [Item, GroupItem::Members, Thing] items Objects to create trigger for.
|
995
1046
|
# @param [State, Array<State>, #===, nil] from
|
996
1047
|
# Only execute rule if previous state matches `from` state(s).
|
997
|
-
# @param [State, Array<State>, #===, nil] to
|
1048
|
+
# @param [State, Array<State>, #===, nil] to
|
998
1049
|
# Only execute rule if new state matches `to` state(s).
|
999
|
-
# @param [java.time.temporal.TemporalAmount] for
|
1000
|
-
# Duration item must remain in the same state before executing the execution blocks.
|
1001
|
-
#
|
1050
|
+
# @param [java.time.temporal.TemporalAmount, Proc, nil] for
|
1051
|
+
# Duration for which the item/thing must remain in the same state before executing the execution blocks.
|
1052
|
+
# When a proc is provided, it will be called when the rule is triggered to get the duration.
|
1053
|
+
# @param [Object, nil] attach object to be attached to the trigger
|
1002
1054
|
# @return [void]
|
1003
1055
|
#
|
1056
|
+
# @example Single item trigger
|
1057
|
+
# rule "Execute rule when a sensor changed" do
|
1058
|
+
# changed FrontMotion_Sensor
|
1059
|
+
# run { |event| logger.info("Motion detected by #{event.item.name}") }
|
1060
|
+
# end
|
1061
|
+
#
|
1004
1062
|
# @example Multiple items can be separated with a comma:
|
1005
1063
|
# rule "Execute rule when either sensor changed" do
|
1006
1064
|
# changed FrontMotion_Sensor, RearMotion_Sensor
|
@@ -1013,23 +1071,15 @@ module OpenHAB
|
|
1013
1071
|
# run { |event| logger.info("Motion detected by #{event.item.name}") }
|
1014
1072
|
# end
|
1015
1073
|
#
|
1016
|
-
# @example `
|
1017
|
-
#
|
1018
|
-
#
|
1019
|
-
# rule "Execute rule when item is changed for specified duration" do
|
1020
|
-
# changed Alarm_Mode, for: -> { Alarm_Delay.state }
|
1021
|
-
# run { logger.info("Alarm Mode Updated") }
|
1022
|
-
# end
|
1023
|
-
#
|
1024
|
-
# @example You can optionally provide `from` and `to` states to restrict the cases in which the rule executes:
|
1025
|
-
# rule "Execute rule when item is changed to specific number, from specific number, for specified duration" do
|
1026
|
-
# changed Alarm_Mode, from: 8, to: [14,12], for: 12.seconds
|
1074
|
+
# @example You can optionally provide `from` and/or `to` states to restrict the cases in which the rule executes:
|
1075
|
+
# rule "Execute rule when item is changed to specific number, from specific number" do
|
1076
|
+
# changed Alarm_Mode, from: 8, to: [14,12]
|
1027
1077
|
# run { logger.info("Alarm Mode Updated") }
|
1028
1078
|
# end
|
1029
1079
|
#
|
1030
1080
|
# @example Works with ranges:
|
1031
|
-
# rule "Execute when item changed to a range of numbers, from a range of numbers
|
1032
|
-
# changed Alarm_Mode, from: 8..10, to: 12..14
|
1081
|
+
# rule "Execute when item changed to a range of numbers, from a range of numbers" do
|
1082
|
+
# changed Alarm_Mode, from: 8..10, to: 12..14
|
1033
1083
|
# run { logger.info("Alarm Mode Updated") }
|
1034
1084
|
# end
|
1035
1085
|
#
|
@@ -1040,14 +1090,14 @@ module OpenHAB
|
|
1040
1090
|
# end
|
1041
1091
|
#
|
1042
1092
|
# @example Works with procs:
|
1043
|
-
# rule "Execute when item state is changed from an odd number, to an even number
|
1044
|
-
# changed Alarm_Mode, from: proc { |from| from.odd? }, to: proc {|to| to.even? }
|
1093
|
+
# rule "Execute when item state is changed from an odd number, to an even number" do
|
1094
|
+
# changed Alarm_Mode, from: proc { |from| from.odd? }, to: proc {|to| to.even? }
|
1045
1095
|
# run { logger.info("Alarm Mode Updated") }
|
1046
1096
|
# end
|
1047
1097
|
#
|
1048
1098
|
# @example Works with lambdas:
|
1049
|
-
# rule "Execute when item state is changed from an odd number, to an even number
|
1050
|
-
# changed Alarm_Mode, from: -> from { from.odd? }, to: -> to { to.even? }
|
1099
|
+
# rule "Execute when item state is changed from an odd number, to an even number" do
|
1100
|
+
# changed Alarm_Mode, from: -> from { from.odd? }, to: -> to { to.even? }
|
1051
1101
|
# run { logger.info("Alarm Mode Updated") }
|
1052
1102
|
# end
|
1053
1103
|
#
|
@@ -1057,6 +1107,22 @@ module OpenHAB
|
|
1057
1107
|
# run { logger.info("Alarm armed") }
|
1058
1108
|
# end
|
1059
1109
|
#
|
1110
|
+
# @example Delay the trigger until the item has been in the same state for 10 seconds
|
1111
|
+
# rule "Execute rule when item is changed for specified duration" do
|
1112
|
+
# changed Closet_Door, to: CLOSED, for: 10.seconds
|
1113
|
+
# run do
|
1114
|
+
# Closet_Light.off
|
1115
|
+
# end
|
1116
|
+
# end
|
1117
|
+
#
|
1118
|
+
# @example `for` parameter can be a proc that returns a duration:
|
1119
|
+
# Alarm_Delay << 20
|
1120
|
+
#
|
1121
|
+
# rule "Execute rule when item is changed for specified duration" do
|
1122
|
+
# changed Alarm_Mode, for: -> { Alarm_Delay.state.to_i.seconds }
|
1123
|
+
# run { logger.info("Alarm Mode Updated") }
|
1124
|
+
# end
|
1125
|
+
#
|
1060
1126
|
# @example Works with Things:
|
1061
1127
|
# rule "Execute rule when thing is changed" do
|
1062
1128
|
# changed things["astro:sun:home"], :from => :online, :to => :uninitialized
|
@@ -26,8 +26,9 @@ module OpenHAB
|
|
26
26
|
class << self
|
27
27
|
# get the block's source location, and simplify to a simple filename
|
28
28
|
def infer_rule_id_from_block(block)
|
29
|
-
file = File.basename(block.source_location.first)
|
30
|
-
"
|
29
|
+
file = File.basename(block.source_location.first, ".rb")
|
30
|
+
file = "script:#{$ctx["ruleUID"]}" if $ctx&.key?("ruleUID") && file == "<script>"
|
31
|
+
"#{file}:#{block.source_location.last}".tr(".", "_")
|
31
32
|
end
|
32
33
|
|
33
34
|
# formulate a readable rule name such as "TestSwitch received command ON" if possible
|
@@ -47,8 +48,6 @@ module OpenHAB
|
|
47
48
|
infer_rule_name_from_trigger(*config.ruby_triggers.first)
|
48
49
|
end
|
49
50
|
|
50
|
-
private
|
51
|
-
|
52
51
|
# formulate a readable rule name from a single trigger if possible
|
53
52
|
def infer_rule_name_from_trigger(trigger, items = nil, kwargs = {})
|
54
53
|
case trigger
|
@@ -71,6 +70,8 @@ module OpenHAB
|
|
71
70
|
end
|
72
71
|
end
|
73
72
|
|
73
|
+
private
|
74
|
+
|
74
75
|
# formulate a readable rule name from an item-type trigger
|
75
76
|
def infer_rule_name_from_item_trigger(trigger, items, kwargs)
|
76
77
|
kwargs.delete(:command) if kwargs[:command] == [nil]
|
@@ -85,10 +86,10 @@ module OpenHAB
|
|
85
86
|
|
86
87
|
trigger_name = trigger.to_s.tr("_", " ")
|
87
88
|
item_names = items.map do |item|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
case item
|
90
|
+
when GroupItem::Members then "#{item.group.name}.members"
|
91
|
+
when Core::Items::Item then item.name
|
92
|
+
else item.to_s
|
92
93
|
end
|
93
94
|
end
|
94
95
|
name = "#{format_array(item_names)} #{trigger_name}"
|
@@ -13,8 +13,10 @@ module OpenHAB
|
|
13
13
|
# and a setter with any number of arguments or a block.
|
14
14
|
#
|
15
15
|
# @param [String] name of the property
|
16
|
+
# @yield Block to call when the property is set
|
17
|
+
# @yieldparam [Object] value the value being set
|
16
18
|
#
|
17
|
-
def prop(name)
|
19
|
+
def prop(name, &assignment_block)
|
18
20
|
# rubocop rules are disabled because this method is dynamically defined on the calling
|
19
21
|
# object making calls to other methods in this module impossible, or if done on methods
|
20
22
|
# in this module than instance variable belong to the module not the calling class
|
@@ -30,6 +32,7 @@ module OpenHAB
|
|
30
32
|
elsif block
|
31
33
|
instance_variable_set(:"@#{name}", block)
|
32
34
|
end
|
35
|
+
assignment_block&.call(instance_variable_get(:"@#{name}"))
|
33
36
|
end
|
34
37
|
end
|
35
38
|
end
|
@@ -41,9 +41,9 @@ module OpenHAB
|
|
41
41
|
#
|
42
42
|
# @return [org.openhab.core.automation.Trigger] openHAB trigger
|
43
43
|
#
|
44
|
-
def append_trigger(type:, config:, attach: nil, conditions: nil)
|
44
|
+
def append_trigger(type:, config:, attach: nil, conditions: nil, label: nil)
|
45
45
|
config.transform_keys!(&:to_s)
|
46
|
-
RuleTriggers.trigger(type: type, config: config).tap do |trigger|
|
46
|
+
RuleTriggers.trigger(type: type, config: config, label: label).tap do |trigger|
|
47
47
|
logger.trace("Appending trigger (#{trigger.inspect}) attach (#{attach}) conditions(#{conditions})")
|
48
48
|
@triggers << trigger
|
49
49
|
@attachments[trigger.id] = attach if attach
|
@@ -56,15 +56,17 @@ module OpenHAB
|
|
56
56
|
#
|
57
57
|
# @param [String] type of trigger
|
58
58
|
# @param [Map] config map
|
59
|
+
# @param [String] label for the trigger
|
59
60
|
#
|
60
61
|
# @return [org.openhab.core.automation.Trigger] configured by type and supplied config
|
61
62
|
#
|
62
|
-
def self.trigger(type:, config:)
|
63
|
+
def self.trigger(type:, config:, label: nil)
|
63
64
|
logger.trace("Creating trigger of type '#{type}' config: #{config}")
|
64
65
|
org.openhab.core.automation.util.TriggerBuilder.create
|
65
66
|
.with_id(uuid)
|
66
67
|
.with_type_uid(type)
|
67
68
|
.with_configuration(Core::Configuration.new(config))
|
69
|
+
.with_label(label)
|
68
70
|
.build
|
69
71
|
end
|
70
72
|
|
@@ -44,22 +44,27 @@ module OpenHAB
|
|
44
44
|
# @see BuilderDSL#$1
|
45
45
|
def def_terse_rule(trigger)
|
46
46
|
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
47
|
-
def #{trigger}(*args, id: nil, name: nil, description: nil,
|
48
|
-
tag: nil, tags: nil, on_load: false, **kwargs, &block)
|
49
|
-
raise ArgumentError, "Block is required" unless block
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
47
|
+
def #{trigger}(*args, id: nil, name: nil, description: nil, # def changed(*args, id: nil, name: nil, description: nil,
|
48
|
+
tag: nil, tags: nil, on_load: false, **kwargs, &block) # tag: nil, tags: nil, on_load: false, **kwargs, &block)
|
49
|
+
raise ArgumentError, "Block is required" unless block # raise ArgumentError, "Block is required" unless block
|
50
|
+
#
|
51
|
+
replace = nil # replace = nil
|
52
|
+
unless id # unless id
|
53
|
+
replace = false # replace = false
|
54
|
+
id = NameInference.infer_rule_id_from_block(block) # id = NameInference.infer_rule_id_from_block(block)
|
55
|
+
end # end
|
56
|
+
script = block.source rescue nil # script = block.source rescue nil
|
57
|
+
caller_binding = block.binding # caller_binding = block.binding
|
58
|
+
rule name, id: id, replace: replace, script: script, # rule name, id: id, replace: replace, script: script
|
59
|
+
binding: caller_binding do # binding: caller_binding do
|
60
|
+
self.on_load if on_load # self.on_load if on_load
|
61
|
+
self.description(description) if description # self.description(description) if description
|
62
|
+
self.tags(*Array.wrap(tag), *Array.wrap(tags)) # self.tags(*Array.wrap(tag), *Array.wrap(tags))
|
63
|
+
#{trigger}(*args, **kwargs) # changed(*args, **kwargs)
|
64
|
+
run(&block) # run(&block)
|
65
|
+
end # end
|
66
|
+
end # end
|
67
|
+
module_function #{trigger.inspect} # module_function :changed
|
63
68
|
RUBY
|
64
69
|
end
|
65
70
|
end
|
@@ -19,18 +19,26 @@ module OpenHAB
|
|
19
19
|
# @param [Core::Items::Item, Core::Items::GroupItem::Members] item item to create trigger for
|
20
20
|
# @param [Core::Types::State, Symbol, #===, nil] from state to restrict trigger to
|
21
21
|
# @param [Core::Types::State, Symbol, #===, nil] to state to restrict trigger to
|
22
|
-
# @param [Duration, nil] duration duration to delay trigger until to state is met
|
22
|
+
# @param [Duration, Proc, nil] duration duration to delay trigger until to state is met
|
23
23
|
# @param [Object] attach object to be attached to the trigger
|
24
24
|
#
|
25
25
|
# @return [org.openhab.core.automation.Trigger] openHAB triggers
|
26
26
|
#
|
27
27
|
def trigger(item:, from:, to:, duration:, attach:)
|
28
28
|
if duration
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
if logger.trace?
|
30
|
+
item_name = item.respond_to?(:name) ? item.name : item.to_s
|
31
|
+
logger.trace("Creating Changed Wait Change Trigger for Item(#{item_name}) Duration(#{duration}) " \
|
32
|
+
"To(#{to}) From(#{from}) Attach(#{attach})")
|
33
|
+
end
|
32
34
|
conditions = Conditions::Duration.new(to: to, from: from, duration: duration)
|
33
|
-
|
35
|
+
label = NameInference.infer_rule_name_from_trigger(:changed,
|
36
|
+
[item],
|
37
|
+
from: from,
|
38
|
+
to: to,
|
39
|
+
duration: duration)
|
40
|
+
|
41
|
+
changed_trigger(item: item, from: nil, to: nil, attach: attach, conditions: conditions, label: label)
|
34
42
|
else
|
35
43
|
# swap from/to w/ nil if from/to need to be processed in Ruby
|
36
44
|
# rubocop:disable Style/ParallelAssignment
|
@@ -64,7 +72,7 @@ module OpenHAB
|
|
64
72
|
# @param [Object] attach object to be attached to the trigger
|
65
73
|
# @return [org.openhab.core.automation.Trigger]
|
66
74
|
#
|
67
|
-
def changed_trigger(item:, from:, to:, attach: nil, conditions: nil)
|
75
|
+
def changed_trigger(item:, from:, to:, attach: nil, conditions: nil, label: nil)
|
68
76
|
type, config = case item
|
69
77
|
when GroupItem::Members
|
70
78
|
group(group: item, from: from, to: to)
|
@@ -74,7 +82,7 @@ module OpenHAB
|
|
74
82
|
else
|
75
83
|
item(item: item, from: from, to: to)
|
76
84
|
end
|
77
|
-
append_trigger(type: type, config: config, attach: attach, conditions: conditions)
|
85
|
+
append_trigger(type: type, config: config, attach: attach, conditions: conditions, label: label)
|
78
86
|
end
|
79
87
|
|
80
88
|
#
|
@@ -301,7 +301,7 @@ module OpenHAB
|
|
301
301
|
Core.automation_manager.add_trigger_type(org.openhab.core.automation.type.TriggerType.new(
|
302
302
|
WATCH_TRIGGER_MODULE_ID,
|
303
303
|
nil,
|
304
|
-
"
|
304
|
+
"a path change event is detected",
|
305
305
|
"Triggers when a path change event is detected",
|
306
306
|
nil,
|
307
307
|
org.openhab.core.automation.Visibility::VISIBLE,
|
data/lib/openhab/dsl/version.rb
CHANGED
data/lib/openhab/dsl.rb
CHANGED
@@ -56,8 +56,14 @@ module OpenHAB
|
|
56
56
|
# @!group Rule Creation
|
57
57
|
|
58
58
|
# (see Rules::Builder#rule)
|
59
|
-
def rule(name = nil, **kwargs, &block)
|
60
|
-
rules.build { rule(name, **kwargs, &block) }
|
59
|
+
def rule(name = nil, id: nil, **kwargs, &block)
|
60
|
+
rules.build { rule(name, id: id, **kwargs, &block) }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Creates a rule that will remove existing rules with the same id, even when the id has been inferred.
|
64
|
+
# @see rule
|
65
|
+
def rule!(name = nil, id: nil, **kwargs, &block)
|
66
|
+
rules.build { rule(name, id: id, replace: true, **kwargs, &block) }
|
61
67
|
end
|
62
68
|
|
63
69
|
# (see Rules::Builder#scene)
|
@@ -65,11 +71,27 @@ module OpenHAB
|
|
65
71
|
rules.build { scene(name, description: description, id: id, tag: tag, tags: tags, **kwargs, &block) }
|
66
72
|
end
|
67
73
|
|
74
|
+
# Creates a scene that will remove existing rules/scenes with the same id, even when the id has been inferred.
|
75
|
+
# @see scene
|
76
|
+
def scene!(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs, &block)
|
77
|
+
rules.build do
|
78
|
+
scene(name, description: description, id: id, tag: tag, tags: tags, replace: true, **kwargs, &block)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
68
82
|
# (see Rules::Builder#script)
|
69
83
|
def script(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs, &block)
|
70
84
|
rules.build { script(name, description: description, id: id, tag: tag, tags: tags, **kwargs, &block) }
|
71
85
|
end
|
72
86
|
|
87
|
+
# Creates a script that will remove existing rules/scripts with the same id, even when the id has been inferred.
|
88
|
+
# @see script
|
89
|
+
def script!(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs, &block)
|
90
|
+
rules.build do
|
91
|
+
script(name, description: description, id: id, tag: tag, tags: tags, replace: true, **kwargs, &block)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
73
95
|
# @!group Rule Support
|
74
96
|
|
75
97
|
# rubocop:disable Layout/LineLength
|
@@ -7,6 +7,15 @@ module OpenHAB
|
|
7
7
|
include org.openhab.core.persistence.ModifiablePersistenceService
|
8
8
|
include Singleton
|
9
9
|
|
10
|
+
OPERATOR_TO_SYMBOL = {
|
11
|
+
EQ: :==,
|
12
|
+
NEQ: :!=,
|
13
|
+
GT: :>,
|
14
|
+
LT: :<,
|
15
|
+
GTE: :>=,
|
16
|
+
LTE: :<=
|
17
|
+
}.freeze
|
18
|
+
|
10
19
|
class HistoricItem
|
11
20
|
include org.openhab.core.persistence.HistoricItem
|
12
21
|
|
@@ -134,9 +143,7 @@ module OpenHAB
|
|
134
143
|
|
135
144
|
range = first_index...last_index
|
136
145
|
|
137
|
-
operator = filter.operator
|
138
|
-
operator = "==" if operator == "="
|
139
|
-
|
146
|
+
operator = OPERATOR_TO_SYMBOL[filter.operator]
|
140
147
|
block = lambda do |i|
|
141
148
|
next if filter.state && !item_history[i].state.send(operator, filter.state)
|
142
149
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openhab-scripting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.18.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian O'Connell
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2024-
|
13
|
+
date: 2024-04-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -485,7 +485,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
485
485
|
- !ruby/object:Gem::Version
|
486
486
|
version: '0'
|
487
487
|
requirements: []
|
488
|
-
rubygems_version: 3.5.
|
488
|
+
rubygems_version: 3.5.7
|
489
489
|
signing_key:
|
490
490
|
specification_version: 4
|
491
491
|
summary: JRuby Helper Libraries for openHAB Scripting
|