openhab-jrubyscripting 5.0.0.rc5 → 5.0.0.rc6
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/actions.rb +6 -6
- data/lib/openhab/core/dependency_tracking.rb +34 -0
- data/lib/openhab/core/entity_lookup.rb +132 -78
- data/lib/openhab/core/events/item_channel_link.rb +2 -2
- data/lib/openhab/core/events/item_command_event.rb +1 -1
- data/lib/openhab/core/events/item_event.rb +2 -2
- data/lib/openhab/core/events/item_state_changed_event.rb +1 -1
- data/lib/openhab/core/events/thing.rb +1 -1
- data/lib/openhab/core/items/accepted_data_types.rb +2 -2
- data/lib/openhab/core/items/contact_item.rb +1 -1
- data/lib/openhab/core/items/dimmer_item.rb +2 -2
- data/lib/openhab/core/items/generic_item.rb +45 -224
- data/lib/openhab/core/items/group_item.rb +5 -3
- data/lib/openhab/core/items/image_item.rb +2 -2
- data/lib/openhab/core/items/item.rb +219 -0
- data/lib/openhab/core/items/metadata/hash.rb +1 -1
- data/lib/openhab/core/items/persistence.rb +4 -5
- data/lib/openhab/core/items/provider.rb +2 -2
- data/lib/openhab/core/items/proxy.rb +68 -7
- data/lib/openhab/core/items/registry.rb +6 -6
- data/lib/openhab/core/items/semantics/enumerable.rb +6 -6
- data/lib/openhab/core/items/semantics.rb +8 -7
- data/lib/openhab/core/items.rb +2 -1
- data/lib/openhab/core/provider.rb +14 -7
- data/lib/openhab/core/rules/registry.rb +2 -2
- data/lib/openhab/core/rules.rb +1 -1
- data/lib/openhab/core/script_handling.rb +6 -6
- data/lib/openhab/core/things/channel.rb +1 -1
- data/lib/openhab/core/things/channel_uid.rb +2 -2
- data/lib/openhab/core/things/item_channel_link.rb +2 -2
- data/lib/openhab/core/things/links/provider.rb +2 -2
- data/lib/openhab/core/things/registry.rb +1 -1
- data/lib/openhab/core/things/thing.rb +1 -1
- data/lib/openhab/core/types/date_time_type.rb +4 -4
- data/lib/openhab/core/types/hsb_type.rb +2 -2
- data/lib/openhab/core/types/quantity_type.rb +1 -1
- data/lib/openhab/core/types.rb +1 -1
- data/lib/openhab/core/uid.rb +1 -1
- data/lib/openhab/core/value_cache.rb +188 -0
- data/lib/openhab/core.rb +57 -15
- data/lib/openhab/core_ext/ruby/symbol.rb +7 -0
- data/lib/openhab/dsl/items/builder.rb +17 -10
- data/lib/openhab/dsl/items/ensure.rb +5 -5
- data/lib/openhab/dsl/items/timed_command.rb +4 -4
- data/lib/openhab/dsl/rules/automation_rule.rb +53 -39
- data/lib/openhab/dsl/rules/builder.rb +128 -79
- data/lib/openhab/dsl/rules/guard.rb +5 -5
- data/lib/openhab/dsl/rules/name_inference.rb +20 -1
- data/lib/openhab/dsl/rules/rule_triggers.rb +3 -3
- data/lib/openhab/dsl/rules/terse.rb +1 -0
- data/lib/openhab/dsl/rules/triggers/changed.rb +26 -23
- data/lib/openhab/dsl/rules/triggers/command.rb +6 -5
- data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +2 -2
- data/lib/openhab/dsl/rules/triggers/cron/cron.rb +2 -2
- data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +6 -6
- data/lib/openhab/dsl/rules/triggers/updated.rb +5 -5
- data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +11 -12
- data/lib/openhab/dsl/things/builder.rb +73 -14
- data/lib/openhab/dsl/version.rb +2 -2
- data/lib/openhab/dsl.rb +43 -17
- data/lib/openhab/log.rb +5 -5
- data/lib/openhab/rspec/configuration.rb +5 -5
- data/lib/openhab/rspec/example_group.rb +1 -1
- data/lib/openhab/rspec/helpers.rb +4 -4
- data/lib/openhab/rspec/hooks.rb +19 -1
- data/lib/openhab/rspec/karaf.rb +12 -19
- data/lib/openhab/rspec/suspend_rules.rb +2 -1
- data/lib/openhab/yard/base_helper.rb +46 -0
- data/lib/openhab/yard/markdown_directive.rb +125 -0
- data/lib/openhab/yard/markdown_helper.rb +99 -0
- metadata +10 -3
@@ -10,15 +10,9 @@ module OpenHAB
|
|
10
10
|
#
|
11
11
|
# @see https://www.openhab.org/javadoc/latest/org/openhab/core/items/genericitem
|
12
12
|
#
|
13
|
-
# @!attribute [r] name
|
14
|
-
# The item's name.
|
15
|
-
# @return [String]
|
16
|
-
#
|
17
|
-
# @!attribute [r] label
|
18
|
-
# The item's descriptive label.
|
19
|
-
# @return [String, nil]
|
20
|
-
#
|
21
13
|
class GenericItem
|
14
|
+
# @!parse include Item
|
15
|
+
|
22
16
|
# rubocop:disable Naming/MethodName these mimic Java fields, which are
|
23
17
|
# actually methods
|
24
18
|
class << self
|
@@ -36,7 +30,10 @@ module OpenHAB
|
|
36
30
|
|
37
31
|
# @!visibility private
|
38
32
|
#
|
39
|
-
# Override to support Proxy
|
33
|
+
# Override to support {Proxy}
|
34
|
+
#
|
35
|
+
# Item.=== isn't actually included (on the Ruby side) into
|
36
|
+
# {GenericItem}
|
40
37
|
#
|
41
38
|
def ===(other)
|
42
39
|
other.is_a?(self)
|
@@ -44,11 +41,13 @@ module OpenHAB
|
|
44
41
|
end
|
45
42
|
# rubocop:enable Naming/MethodName
|
46
43
|
|
47
|
-
# @!attribute [r]
|
48
|
-
#
|
44
|
+
# @!attribute [r] name
|
45
|
+
# The item's name.
|
46
|
+
# @return [String]
|
49
47
|
|
50
|
-
# @!attribute [r]
|
51
|
-
#
|
48
|
+
# @!attribute [r] label
|
49
|
+
# The item's descriptive label.
|
50
|
+
# @return [String, nil]
|
52
51
|
|
53
52
|
alias_method :hash, :hash_code
|
54
53
|
|
@@ -62,6 +61,35 @@ module OpenHAB
|
|
62
61
|
#
|
63
62
|
alias_method :raw_state, :state
|
64
63
|
|
64
|
+
#
|
65
|
+
# Check if the item has a state (not {UNDEF} or {NULL})
|
66
|
+
#
|
67
|
+
# @return [true, false]
|
68
|
+
#
|
69
|
+
def state?
|
70
|
+
!raw_state.is_a?(Types::UnDefType)
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# @!attribute [r] state
|
75
|
+
# @return [State, nil]
|
76
|
+
# openHAB item state if state is not {UNDEF} or {NULL}, nil otherwise.
|
77
|
+
# This makes it easy to use with the
|
78
|
+
# [Ruby safe navigation operator `&.`](https://ruby-doc.org/core-2.6/doc/syntax/calling_methods_rdoc.html)
|
79
|
+
# Use {#undef?} or {#null?} to check for those states.
|
80
|
+
#
|
81
|
+
def state
|
82
|
+
raw_state if state?
|
83
|
+
end
|
84
|
+
|
85
|
+
# @!method null?
|
86
|
+
# Check if the item state == {NULL}
|
87
|
+
# @return [true,false]
|
88
|
+
|
89
|
+
# @!method undef?
|
90
|
+
# Check if the item state == {UNDEF}
|
91
|
+
# @return [true,false]
|
92
|
+
|
65
93
|
#
|
66
94
|
# Send a command to this item
|
67
95
|
#
|
@@ -91,6 +119,10 @@ module OpenHAB
|
|
91
119
|
|
92
120
|
# @!parse alias_method :<<, :command
|
93
121
|
|
122
|
+
# @!method refresh
|
123
|
+
# Send the {REFRESH} command to the item
|
124
|
+
# @return [Item] `self`
|
125
|
+
|
94
126
|
#
|
95
127
|
# Send an update to this item
|
96
128
|
#
|
@@ -105,200 +137,6 @@ module OpenHAB
|
|
105
137
|
Proxy.new(self)
|
106
138
|
end
|
107
139
|
|
108
|
-
#
|
109
|
-
# Check if the item has a state (not {UNDEF} or {NULL})
|
110
|
-
#
|
111
|
-
# @return [true, false]
|
112
|
-
#
|
113
|
-
def state?
|
114
|
-
!raw_state.is_a?(Types::UnDefType)
|
115
|
-
end
|
116
|
-
|
117
|
-
#
|
118
|
-
# @!attribute [r] state
|
119
|
-
# @return [State, nil]
|
120
|
-
# OpenHAB item state if state is not {UNDEF} or {NULL}, nil otherwise.
|
121
|
-
# This makes it easy to use with the
|
122
|
-
# [Ruby safe navigation operator `&.`](https://ruby-doc.org/core-2.6/doc/syntax/calling_methods_rdoc.html)
|
123
|
-
# Use {#undef?} or {#null?} to check for those states.
|
124
|
-
#
|
125
|
-
def state
|
126
|
-
raw_state if state?
|
127
|
-
end
|
128
|
-
|
129
|
-
#
|
130
|
-
# The item's {#label} if one is defined, otherwise it's {#name}.
|
131
|
-
#
|
132
|
-
# @return [String]
|
133
|
-
#
|
134
|
-
def to_s
|
135
|
-
label || name
|
136
|
-
end
|
137
|
-
|
138
|
-
#
|
139
|
-
# @!attribute [r] groups
|
140
|
-
#
|
141
|
-
# Return all groups that this item is part of
|
142
|
-
#
|
143
|
-
# @return [Array<Group>] All groups that this item is part of
|
144
|
-
#
|
145
|
-
def groups
|
146
|
-
group_names.map { |name| EntityLookup.lookup_item(name) }.compact
|
147
|
-
end
|
148
|
-
|
149
|
-
# rubocop:disable Layout/LineLength
|
150
|
-
|
151
|
-
# @!attribute [r] metadata
|
152
|
-
# @return [Metadata::NamespaceHash]
|
153
|
-
#
|
154
|
-
# Access to the item's metadata.
|
155
|
-
#
|
156
|
-
# Both the return value of this method as well as the individual
|
157
|
-
# namespaces can be treated as Hashes.
|
158
|
-
#
|
159
|
-
# Examples assume the following items:
|
160
|
-
#
|
161
|
-
# ```xtend
|
162
|
-
# Switch Item1 { namespace1="value" [ config1="foo", config2="bar" ] }
|
163
|
-
# String StringItem1
|
164
|
-
# ```
|
165
|
-
#
|
166
|
-
# @example Check namespace's existence
|
167
|
-
# Item1.metadata["namespace"].nil?
|
168
|
-
# Item1.metadata.key?("namespace")
|
169
|
-
#
|
170
|
-
# @example Access item's metadata value
|
171
|
-
# Item1.metadata["namespace1"].value
|
172
|
-
#
|
173
|
-
# @example Access namespace1's configuration
|
174
|
-
# Item1.metadata["namespace1"]["config1"]
|
175
|
-
#
|
176
|
-
# @example Safely search for the specified value - no errors are raised, only nil returned if a key in the chain doesn"t exist
|
177
|
-
# Item1.metadata.dig("namespace1", "config1") # => "foo"
|
178
|
-
# Item1.metadata.dig("namespace2", "config1") # => nil
|
179
|
-
#
|
180
|
-
# @example Set item's metadata value, preserving its config
|
181
|
-
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
182
|
-
# Item1.metadata["namespace1"].value = "new value"
|
183
|
-
# # Item1's metadata after: {"namespace1"=>["new value", {"config1"=>"foo", "config2"=>"bar"]}}
|
184
|
-
#
|
185
|
-
# @example Set item's metadata config, preserving its value
|
186
|
-
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
187
|
-
# Item1.metadata["namespace1"].replace({ "scooby"=>"doo" })
|
188
|
-
# # Item1's metadata after: {"namespace1"=>["value", {scooby="doo"}]}
|
189
|
-
#
|
190
|
-
# @example Set a namespace to a new value and config in one line
|
191
|
-
# # Item1's metadata before: {"namespace1"=>"value", {"config1"=>"foo", "config2"=>"bar"}}
|
192
|
-
# Item1.metadata["namespace1"] = "new value", { "scooby"=>"doo" }
|
193
|
-
# # Item1's metadata after: {"namespace1"=>["new value", {scooby="doo"}]}
|
194
|
-
#
|
195
|
-
# @example Set item's metadata value and clear its previous config
|
196
|
-
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
197
|
-
# Item1.metadata["namespace1"] = "new value"
|
198
|
-
# # Item1's metadata after: {"namespace1"=>"value" }
|
199
|
-
#
|
200
|
-
# @example Set item's metadata config, set its value to nil, and wiping out previous config
|
201
|
-
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
202
|
-
# Item1.metadata["namespace1"] = { "newconfig"=>"value" }
|
203
|
-
# # Item1's metadata after: {"namespace1"=>{"config1"=>"foo", "config2"=>"bar"}}
|
204
|
-
#
|
205
|
-
# @example Update namespace1's specific configuration, preserving its value and other config
|
206
|
-
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
207
|
-
# Item1.metadata["namespace1"]["config1"] = "doo"
|
208
|
-
# # Item1's metadata will be: {"namespace1"=>["value", {"config1"=>"doo", "config2"=>"bar"}]}
|
209
|
-
#
|
210
|
-
# @example Add a new configuration to namespace1
|
211
|
-
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
212
|
-
# Item1.metadata["namespace1"]["config3"] = "boo"
|
213
|
-
# # Item1's metadata after: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar", config3="boo"}]}
|
214
|
-
#
|
215
|
-
# @example Delete a config
|
216
|
-
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
217
|
-
# Item1.metadata["namespace1"].delete("config2")
|
218
|
-
# # Item1's metadata after: {"namespace1"=>["value", {"config1"=>"foo"}]}
|
219
|
-
#
|
220
|
-
# @example Add a namespace and set it to a value
|
221
|
-
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
222
|
-
# Item1.metadata["namespace2"] = "qx"
|
223
|
-
# # Item1's metadata after: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}], "namespace2"=>"qx"}
|
224
|
-
#
|
225
|
-
# @example Add a namespace and set it to a value and config
|
226
|
-
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
227
|
-
# Item1.metadata["namespace2"] = "qx", { "config1"=>"doo" }
|
228
|
-
# # Item1's metadata after: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}], "namespace2"=>["qx", {"config1"=>"doo"}]}
|
229
|
-
#
|
230
|
-
# @example Enumerate Item1's namespaces
|
231
|
-
# Item1.metadata.each { |namespace, metadata| logger.info("Item1's namespace: #{namespace}=#{metadata}") }
|
232
|
-
#
|
233
|
-
# @example Add metadata from a hash
|
234
|
-
# Item1.metadata.merge!({"namespace1"=>{"foo", {"config1"=>"baz"} ], "namespace2"=>{"qux", {"config"=>"quu"} ]})
|
235
|
-
#
|
236
|
-
# @example Merge Item2's metadata into Item1's metadata
|
237
|
-
# Item1.metadata.merge!(Item2.metadata)
|
238
|
-
#
|
239
|
-
# @example Delete a namespace
|
240
|
-
# Item1.metadata.delete("namespace1")
|
241
|
-
#
|
242
|
-
# @example Delete all metadata of the item
|
243
|
-
# Item1.metadata.clear
|
244
|
-
#
|
245
|
-
# @example Does this item have any metadata?
|
246
|
-
# Item1.metadata.any?
|
247
|
-
#
|
248
|
-
# @example Store another item's state
|
249
|
-
# StringItem1.update "TEST"
|
250
|
-
# Item1.metadata["other_state"] = StringItem1.state
|
251
|
-
#
|
252
|
-
# @example Store event's state
|
253
|
-
# rule "save event state" do
|
254
|
-
# changed StringItem1
|
255
|
-
# run { |event| Item1.metadata["last_event"] = event.was }
|
256
|
-
# end
|
257
|
-
#
|
258
|
-
# @example If the namespace already exists: Update the value of a namespace but preserve its config; otherwise create a new namespace with the given value and nil config.
|
259
|
-
# Item1.metadata["namespace"] = "value", Item1.metadata["namespace"]
|
260
|
-
#
|
261
|
-
# @example Copy another namespace
|
262
|
-
# # Item1's metadata before: {"namespace2"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
263
|
-
# Item1.metadata["namespace"] = Item1.metadata["namespace2"]
|
264
|
-
# # Item1's metadata after: {"namespace2"=>["value", {"config1"=>"foo", "config2"=>"bar"}], "namespace"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
265
|
-
#
|
266
|
-
def metadata
|
267
|
-
@metadata ||= Metadata::NamespaceHash.new(name)
|
268
|
-
end
|
269
|
-
# rubocop:enable Layout/LineLength
|
270
|
-
|
271
|
-
# Return the item's thing if this item is linked with a thing. If an item is linked to more than one thing,
|
272
|
-
# this method only returns the first thing.
|
273
|
-
#
|
274
|
-
# @return [Thing] The thing associated with this item or nil
|
275
|
-
def thing
|
276
|
-
all_linked_things.first
|
277
|
-
end
|
278
|
-
alias_method :linked_thing, :thing
|
279
|
-
|
280
|
-
# Returns all of the item's linked things.
|
281
|
-
#
|
282
|
-
# @return [Array<Thing>] An array of things or an empty array
|
283
|
-
def things
|
284
|
-
registry = OSGi.service("org.openhab.core.thing.link.ItemChannelLinkRegistry")
|
285
|
-
channels = registry.get_bound_channels(name).to_a
|
286
|
-
channels.map(&:thing_uid).uniq.map { |tuid| EntityLookup.lookup_thing(tuid) }.compact
|
287
|
-
end
|
288
|
-
alias_method :all_linked_things, :things
|
289
|
-
|
290
|
-
# @!method null?
|
291
|
-
# Check if the item state == {NULL}
|
292
|
-
# @return [true,false]
|
293
|
-
|
294
|
-
# @!method undef?
|
295
|
-
# Check if the item state == {UNDEF}
|
296
|
-
# @return [true,false]
|
297
|
-
|
298
|
-
# @!method refresh
|
299
|
-
# Send the {REFRESH} command to the item
|
300
|
-
# @return [GenericItem] `self`
|
301
|
-
|
302
140
|
# @!visibility private
|
303
141
|
def format_command(command)
|
304
142
|
command = format_type(command)
|
@@ -327,23 +165,6 @@ module OpenHAB
|
|
327
165
|
|
328
166
|
type.to_s
|
329
167
|
end
|
330
|
-
|
331
|
-
# @return [String]
|
332
|
-
def inspect
|
333
|
-
s = "#<OpenHAB::Core::Items::#{type}Item#{type_details} #{name} #{label.inspect} state=#{raw_state.inspect}"
|
334
|
-
s += " category=#{category.inspect}" if category
|
335
|
-
s += " tags=#{tags.to_a.inspect}" unless tags.empty?
|
336
|
-
s += " groups=#{group_names}" unless group_names.empty?
|
337
|
-
meta = metadata.to_h
|
338
|
-
s += " metadata=#{meta.inspect}" unless meta.empty?
|
339
|
-
"#{s}>"
|
340
|
-
end
|
341
|
-
|
342
|
-
private
|
343
|
-
|
344
|
-
# Allows sub-classes to append additional details to the type in an inspect string
|
345
|
-
# @return [String]
|
346
|
-
def type_details; end
|
347
168
|
end
|
348
169
|
end
|
349
170
|
end
|
@@ -33,7 +33,7 @@ module OpenHAB
|
|
33
33
|
# ```
|
34
34
|
#
|
35
35
|
# @!attribute [r] base_item
|
36
|
-
# @return [
|
36
|
+
# @return [Item, nil] A typed item if the group has a particular type.
|
37
37
|
#
|
38
38
|
# @example Operate on items in a group using enumerable methods
|
39
39
|
# logger.info("Total Temperatures: #{Temperatures.members.count}")
|
@@ -99,7 +99,9 @@ module OpenHAB
|
|
99
99
|
|
100
100
|
# @return [String]
|
101
101
|
def inspect
|
102
|
-
"#<OpenHAB::Core::Items::GroupItems::Members #{name}
|
102
|
+
r = "#<OpenHAB::Core::Items::GroupItems::Members #{name}"
|
103
|
+
r += " #{map(&:name).inspect}>" unless @group.__getobj__.nil?
|
104
|
+
"#{r}>"
|
103
105
|
end
|
104
106
|
alias_method :to_s, :inspect
|
105
107
|
end
|
@@ -120,7 +122,7 @@ module OpenHAB
|
|
120
122
|
# @see Enumerable
|
121
123
|
#
|
122
124
|
def members
|
123
|
-
Members.new(self)
|
125
|
+
Members.new(Proxy.new(self))
|
124
126
|
end
|
125
127
|
|
126
128
|
#
|
@@ -79,12 +79,12 @@ module OpenHAB
|
|
79
79
|
private
|
80
80
|
|
81
81
|
#
|
82
|
-
# Encode image information in the format required by
|
82
|
+
# Encode image information in the format required by openHAB
|
83
83
|
#
|
84
84
|
# @param [String] mime_type for image
|
85
85
|
# @param [Object] bytes image data
|
86
86
|
#
|
87
|
-
# @return [String]
|
87
|
+
# @return [String] openHAB image format with image data Base64 encoded
|
88
88
|
#
|
89
89
|
def encode_image(mime_type:, bytes:)
|
90
90
|
"data:#{mime_type};base64,#{Base64.strict_encode64(bytes)}"
|
@@ -0,0 +1,219 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module Core
|
5
|
+
module Items
|
6
|
+
# @interface
|
7
|
+
java_import org.openhab.core.items.Item
|
8
|
+
|
9
|
+
#
|
10
|
+
# The core features of an openHAB item.
|
11
|
+
#
|
12
|
+
module Item
|
13
|
+
class << self
|
14
|
+
# @!visibility private
|
15
|
+
#
|
16
|
+
# Override to support {Proxy}
|
17
|
+
#
|
18
|
+
def ===(other)
|
19
|
+
other.is_a?(self)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# @!attribute [r] name
|
24
|
+
# The item's name.
|
25
|
+
# @return [String]
|
26
|
+
|
27
|
+
# @!attribute [r] label
|
28
|
+
# The item's descriptive label.
|
29
|
+
# @return [String, nil]
|
30
|
+
|
31
|
+
# @!attribute [r] accepted_command_types
|
32
|
+
# @return [Array<Class>] An array of {Command}s that can be sent as commands to this item
|
33
|
+
|
34
|
+
# @!attribute [r] accepted_data_types
|
35
|
+
# @return [Array<Class>] An array of {State}s that can be sent as commands to this item
|
36
|
+
|
37
|
+
#
|
38
|
+
# The item's {#label} if one is defined, otherwise it's {#name}.
|
39
|
+
#
|
40
|
+
# @return [String]
|
41
|
+
#
|
42
|
+
def to_s
|
43
|
+
label || name
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# @!attribute [r] groups
|
48
|
+
#
|
49
|
+
# Return all groups that this item is part of
|
50
|
+
#
|
51
|
+
# @return [Array<Group>] All groups that this item is part of
|
52
|
+
#
|
53
|
+
def groups
|
54
|
+
group_names.map { |name| EntityLookup.lookup_item(name) }.compact
|
55
|
+
end
|
56
|
+
|
57
|
+
# rubocop:disable Layout/LineLength
|
58
|
+
|
59
|
+
# @!attribute [r] metadata
|
60
|
+
# @return [Metadata::NamespaceHash]
|
61
|
+
#
|
62
|
+
# Access to the item's metadata.
|
63
|
+
#
|
64
|
+
# Both the return value of this method as well as the individual
|
65
|
+
# namespaces can be treated as Hashes.
|
66
|
+
#
|
67
|
+
# Examples assume the following items:
|
68
|
+
#
|
69
|
+
# ```xtend
|
70
|
+
# Switch Item1 { namespace1="value" [ config1="foo", config2="bar" ] }
|
71
|
+
# String StringItem1
|
72
|
+
# ```
|
73
|
+
#
|
74
|
+
# @example Check namespace's existence
|
75
|
+
# Item1.metadata["namespace"].nil?
|
76
|
+
# Item1.metadata.key?("namespace")
|
77
|
+
#
|
78
|
+
# @example Access item's metadata value
|
79
|
+
# Item1.metadata["namespace1"].value
|
80
|
+
#
|
81
|
+
# @example Access namespace1's configuration
|
82
|
+
# Item1.metadata["namespace1"]["config1"]
|
83
|
+
#
|
84
|
+
# @example Safely search for the specified value - no errors are raised, only nil returned if a key in the chain doesn"t exist
|
85
|
+
# Item1.metadata.dig("namespace1", "config1") # => "foo"
|
86
|
+
# Item1.metadata.dig("namespace2", "config1") # => nil
|
87
|
+
#
|
88
|
+
# @example Set item's metadata value, preserving its config
|
89
|
+
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
90
|
+
# Item1.metadata["namespace1"].value = "new value"
|
91
|
+
# # Item1's metadata after: {"namespace1"=>["new value", {"config1"=>"foo", "config2"=>"bar"]}}
|
92
|
+
#
|
93
|
+
# @example Set item's metadata config, preserving its value
|
94
|
+
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
95
|
+
# Item1.metadata["namespace1"].replace({ "scooby"=>"doo" })
|
96
|
+
# # Item1's metadata after: {"namespace1"=>["value", {scooby="doo"}]}
|
97
|
+
#
|
98
|
+
# @example Set a namespace to a new value and config in one line
|
99
|
+
# # Item1's metadata before: {"namespace1"=>"value", {"config1"=>"foo", "config2"=>"bar"}}
|
100
|
+
# Item1.metadata["namespace1"] = "new value", { "scooby"=>"doo" }
|
101
|
+
# # Item1's metadata after: {"namespace1"=>["new value", {scooby="doo"}]}
|
102
|
+
#
|
103
|
+
# @example Set item's metadata value and clear its previous config
|
104
|
+
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
105
|
+
# Item1.metadata["namespace1"] = "new value"
|
106
|
+
# # Item1's metadata after: {"namespace1"=>"value" }
|
107
|
+
#
|
108
|
+
# @example Set item's metadata config, set its value to nil, and wiping out previous config
|
109
|
+
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
110
|
+
# Item1.metadata["namespace1"] = { "newconfig"=>"value" }
|
111
|
+
# # Item1's metadata after: {"namespace1"=>{"config1"=>"foo", "config2"=>"bar"}}
|
112
|
+
#
|
113
|
+
# @example Update namespace1's specific configuration, preserving its value and other config
|
114
|
+
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
115
|
+
# Item1.metadata["namespace1"]["config1"] = "doo"
|
116
|
+
# # Item1's metadata will be: {"namespace1"=>["value", {"config1"=>"doo", "config2"=>"bar"}]}
|
117
|
+
#
|
118
|
+
# @example Add a new configuration to namespace1
|
119
|
+
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
120
|
+
# Item1.metadata["namespace1"]["config3"] = "boo"
|
121
|
+
# # Item1's metadata after: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar", config3="boo"}]}
|
122
|
+
#
|
123
|
+
# @example Delete a config
|
124
|
+
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
125
|
+
# Item1.metadata["namespace1"].delete("config2")
|
126
|
+
# # Item1's metadata after: {"namespace1"=>["value", {"config1"=>"foo"}]}
|
127
|
+
#
|
128
|
+
# @example Add a namespace and set it to a value
|
129
|
+
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
130
|
+
# Item1.metadata["namespace2"] = "qx"
|
131
|
+
# # Item1's metadata after: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}], "namespace2"=>"qx"}
|
132
|
+
#
|
133
|
+
# @example Add a namespace and set it to a value and config
|
134
|
+
# # Item1's metadata before: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
135
|
+
# Item1.metadata["namespace2"] = "qx", { "config1"=>"doo" }
|
136
|
+
# # Item1's metadata after: {"namespace1"=>["value", {"config1"=>"foo", "config2"=>"bar"}], "namespace2"=>["qx", {"config1"=>"doo"}]}
|
137
|
+
#
|
138
|
+
# @example Enumerate Item1's namespaces
|
139
|
+
# Item1.metadata.each { |namespace, metadata| logger.info("Item1's namespace: #{namespace}=#{metadata}") }
|
140
|
+
#
|
141
|
+
# @example Add metadata from a hash
|
142
|
+
# Item1.metadata.merge!({"namespace1"=>{"foo", {"config1"=>"baz"} ], "namespace2"=>{"qux", {"config"=>"quu"} ]})
|
143
|
+
#
|
144
|
+
# @example Merge Item2's metadata into Item1's metadata
|
145
|
+
# Item1.metadata.merge!(Item2.metadata)
|
146
|
+
#
|
147
|
+
# @example Delete a namespace
|
148
|
+
# Item1.metadata.delete("namespace1")
|
149
|
+
#
|
150
|
+
# @example Delete all metadata of the item
|
151
|
+
# Item1.metadata.clear
|
152
|
+
#
|
153
|
+
# @example Does this item have any metadata?
|
154
|
+
# Item1.metadata.any?
|
155
|
+
#
|
156
|
+
# @example Store another item's state
|
157
|
+
# StringItem1.update "TEST"
|
158
|
+
# Item1.metadata["other_state"] = StringItem1.state
|
159
|
+
#
|
160
|
+
# @example Store event's state
|
161
|
+
# rule "save event state" do
|
162
|
+
# changed StringItem1
|
163
|
+
# run { |event| Item1.metadata["last_event"] = event.was }
|
164
|
+
# end
|
165
|
+
#
|
166
|
+
# @example If the namespace already exists: Update the value of a namespace but preserve its config; otherwise create a new namespace with the given value and nil config.
|
167
|
+
# Item1.metadata["namespace"] = "value", Item1.metadata["namespace"]
|
168
|
+
#
|
169
|
+
# @example Copy another namespace
|
170
|
+
# # Item1's metadata before: {"namespace2"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
171
|
+
# Item1.metadata["namespace"] = Item1.metadata["namespace2"]
|
172
|
+
# # Item1's metadata after: {"namespace2"=>["value", {"config1"=>"foo", "config2"=>"bar"}], "namespace"=>["value", {"config1"=>"foo", "config2"=>"bar"}]}
|
173
|
+
#
|
174
|
+
def metadata
|
175
|
+
@metadata ||= Metadata::NamespaceHash.new(name)
|
176
|
+
end
|
177
|
+
# rubocop:enable Layout/LineLength
|
178
|
+
|
179
|
+
# Return the item's thing if this item is linked with a thing. If an item is linked to more than one thing,
|
180
|
+
# this method only returns the first thing.
|
181
|
+
#
|
182
|
+
# @return [Thing] The thing associated with this item or nil
|
183
|
+
def thing
|
184
|
+
all_linked_things.first
|
185
|
+
end
|
186
|
+
alias_method :linked_thing, :thing
|
187
|
+
|
188
|
+
# Returns all of the item's linked things.
|
189
|
+
#
|
190
|
+
# @return [Array<Thing>] An array of things or an empty array
|
191
|
+
def things
|
192
|
+
registry = OSGi.service("org.openhab.core.thing.link.ItemChannelLinkRegistry")
|
193
|
+
channels = registry.get_bound_channels(name).to_a
|
194
|
+
channels.map(&:thing_uid).uniq.map { |tuid| EntityLookup.lookup_thing(tuid) }.compact
|
195
|
+
end
|
196
|
+
alias_method :all_linked_things, :things
|
197
|
+
|
198
|
+
# @return [String]
|
199
|
+
def inspect
|
200
|
+
s = "#<OpenHAB::Core::Items::#{type}Item#{type_details} #{name} #{label.inspect} state=#{raw_state.inspect}"
|
201
|
+
s += " category=#{category.inspect}" if category
|
202
|
+
s += " tags=#{tags.to_a.inspect}" unless tags.empty?
|
203
|
+
s += " groups=#{group_names}" unless group_names.empty?
|
204
|
+
meta = metadata.to_h
|
205
|
+
s += " metadata=#{meta.inspect}" unless meta.empty?
|
206
|
+
"#{s}>"
|
207
|
+
end
|
208
|
+
|
209
|
+
private
|
210
|
+
|
211
|
+
# Allows sub-classes to append additional details to the type in an inspect string
|
212
|
+
# @return [String]
|
213
|
+
def type_details; end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# @!parse Item = OpenHAB::Core::Items::Item
|
@@ -9,7 +9,7 @@ module OpenHAB
|
|
9
9
|
module Items
|
10
10
|
#
|
11
11
|
# Items extensions to support
|
12
|
-
# {https://www.openhab.org/docs/configuration/persistence.html
|
12
|
+
# {https://www.openhab.org/docs/configuration/persistence.html openHAB's Persistence} feature.
|
13
13
|
#
|
14
14
|
# @see OpenHAB::DSL.persistence Persistence Block
|
15
15
|
#
|
@@ -87,7 +87,7 @@ module OpenHAB
|
|
87
87
|
# @!method last_update(service = nil)
|
88
88
|
# Return the time the item was last updated.
|
89
89
|
# @param [Symbol, String] service An optional persistence id instead of the default persistence service.
|
90
|
-
# @return [ZonedDateTime] The timestamp of the last update
|
90
|
+
# @return [ZonedDateTime, nil] The timestamp of the last update
|
91
91
|
|
92
92
|
# @!method average_since(timestamp, service = nil)
|
93
93
|
# Return the average value of the item's state since the given time
|
@@ -255,7 +255,7 @@ module OpenHAB
|
|
255
255
|
def previous_state(service = nil, skip_equal: false)
|
256
256
|
service ||= persistence_service
|
257
257
|
result = Actions::PersistenceExtensions.previous_state(self, skip_equal, service&.to_s)
|
258
|
-
HistoricState.new(quantify(result.state), result)
|
258
|
+
HistoricState.new(quantify(result.state), result) if result
|
259
259
|
end
|
260
260
|
|
261
261
|
PERSISTENCE_METHODS.each do |method|
|
@@ -317,8 +317,7 @@ module OpenHAB
|
|
317
317
|
#
|
318
318
|
def wrap_result(result, method)
|
319
319
|
if result.is_a?(org.openhab.core.persistence.HistoricItem)
|
320
|
-
return HistoricState.new(quantify(result.state),
|
321
|
-
result)
|
320
|
+
return HistoricState.new(quantify(result.state), result)
|
322
321
|
end
|
323
322
|
return quantify(result) if QUANTITY_METHODS.include?(method)
|
324
323
|
|
@@ -4,7 +4,7 @@ module OpenHAB
|
|
4
4
|
module Core
|
5
5
|
module Items
|
6
6
|
#
|
7
|
-
# Provides {
|
7
|
+
# Provides {Item Items} created in Ruby to openHAB
|
8
8
|
#
|
9
9
|
class Provider < Core::Provider
|
10
10
|
include org.openhab.core.items.ItemProvider
|
@@ -25,7 +25,7 @@ module OpenHAB
|
|
25
25
|
#
|
26
26
|
# @param [String] item_name
|
27
27
|
# @param [true, false] recursive
|
28
|
-
# @return [
|
28
|
+
# @return [Item, nil] The removed item, if found.
|
29
29
|
#
|
30
30
|
def remove(item_name, recursive = false) # rubocop:disable Style/OptionalBooleanParameter matches Java method
|
31
31
|
return nil unless @elements.key?(item_name)
|