openhab-scripting 5.35.0 → 5.36.0
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/console/irb.rb +105 -0
- data/lib/openhab/console/jline.rb +104 -0
- data/lib/openhab/console/registry.rb +12 -0
- data/lib/openhab/console/stdio.rb +178 -0
- data/lib/openhab/console.rb +5 -0
- data/lib/openhab/core/emulate_hash.rb +11 -11
- data/lib/openhab/core/entity_lookup.rb +2 -4
- data/lib/openhab/core/events/item_state_updated_event.rb +0 -3
- data/lib/openhab/core/events/item_time_series_updated_event.rb +0 -3
- data/lib/openhab/core/events/startlevel_event.rb +0 -3
- data/lib/openhab/core/events/timer_event.rb +0 -3
- data/lib/openhab/core/items/generic_item.rb +14 -154
- data/lib/openhab/core/items/group_item.rb +3 -3
- data/lib/openhab/core/items/image_item.rb +5 -21
- data/lib/openhab/core/items/item.rb +161 -7
- data/lib/openhab/core/items/persistence.rb +8 -10
- data/lib/openhab/core/items/provider.rb +1 -1
- data/lib/openhab/core/items/proxy.rb +33 -94
- data/lib/openhab/core/items/registry.rb +2 -2
- data/lib/openhab/core/items/semantics/enumerable.rb +1 -1
- data/lib/openhab/core/items/semantics/provider.rb +1 -5
- data/lib/openhab/core/items/semantics/semantic_tag.rb +1 -4
- data/lib/openhab/core/items/semantics.rb +105 -141
- data/lib/openhab/core/items/switch_item.rb +1 -1
- data/lib/openhab/core/items.rb +22 -22
- data/lib/openhab/core/lazy_array.rb +4 -4
- data/lib/openhab/core/profile_factory.rb +16 -25
- data/lib/openhab/core/provider.rb +3 -4
- data/lib/openhab/core/proxy.rb +160 -4
- data/lib/openhab/core/registry.rb +2 -15
- data/lib/openhab/core/rules/registry.rb +2 -2
- data/lib/openhab/core/rules/rule.rb +4 -8
- data/lib/openhab/core/script_handling.rb +2 -2
- data/lib/openhab/core/sitemaps/provider.rb +1 -1
- data/lib/openhab/core/things/channel.rb +0 -28
- data/lib/openhab/core/things/profile_callback.rb +3 -3
- data/lib/openhab/core/things/proxy.rb +8 -51
- data/lib/openhab/core/things/registry.rb +1 -1
- data/lib/openhab/core/things/thing.rb +3 -5
- data/lib/openhab/core/types/command_description.rb +31 -0
- data/lib/openhab/core/types/date_time_type.rb +5 -10
- data/lib/openhab/core/types/decimal_type.rb +1 -1
- data/lib/openhab/core/types/hsb_type.rb +3 -5
- data/lib/openhab/core/types/point_type.rb +1 -1
- data/lib/openhab/core/types/quantity_type.rb +35 -2
- data/lib/openhab/core/types/raw_type.rb +10 -4
- data/lib/openhab/core/types/state_description.rb +54 -0
- data/lib/openhab/core/types/time_series.rb +0 -3
- data/lib/openhab/core/types.rb +2 -2
- data/lib/openhab/core/value_cache.rb +3 -3
- data/lib/openhab/core.rb +3 -5
- data/lib/openhab/core_ext/java/duration.rb +27 -8
- data/lib/openhab/core_ext/java/list.rb +1 -1
- data/lib/openhab/core_ext/java/local_date.rb +6 -2
- data/lib/openhab/core_ext/java/local_time.rb +4 -2
- data/lib/openhab/core_ext/java/map.rb +2 -2
- data/lib/openhab/core_ext/java/period.rb +9 -6
- data/lib/openhab/core_ext/java/temporal_amount.rb +5 -0
- data/lib/openhab/core_ext/java/zoned_date_time.rb +12 -6
- data/lib/openhab/core_ext/ruby/date.rb +8 -7
- data/lib/openhab/core_ext/ruby/date_time.rb +2 -2
- data/lib/openhab/core_ext/ruby/time.rb +2 -2
- data/lib/openhab/core_ext.rb +1 -1
- data/lib/openhab/dsl/config_description/builder.rb +1 -1
- data/lib/openhab/dsl/items/builder.rb +15 -17
- data/lib/openhab/dsl/items/ensure.rb +3 -5
- data/lib/openhab/dsl/items/timed_command.rb +4 -4
- data/lib/openhab/dsl/rules/automation_rule.rb +3 -3
- data/lib/openhab/dsl/rules/builder.rb +40 -52
- data/lib/openhab/dsl/rules/rule_triggers.rb +1 -1
- data/lib/openhab/dsl/rules/triggers/changed.rb +16 -15
- data/lib/openhab/dsl/rules/triggers/channel.rb +1 -1
- data/lib/openhab/dsl/rules/triggers/command.rb +2 -2
- data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +4 -4
- data/lib/openhab/dsl/rules/triggers/cron/cron.rb +4 -14
- data/lib/openhab/dsl/rules/triggers/updated.rb +6 -6
- data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +69 -124
- data/lib/openhab/dsl/sitemaps/builder.rb +7 -17
- data/lib/openhab/dsl/things/builder.rb +8 -8
- data/lib/openhab/dsl/timer_manager.rb +2 -2
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/dsl.rb +14 -15
- data/lib/openhab/log.rb +3 -3
- data/lib/openhab/osgi.rb +1 -1
- data/lib/openhab/rspec/helpers.rb +3 -3
- data/lib/openhab/rspec/hooks.rb +2 -8
- data/lib/openhab/rspec/jruby.rb +1 -1
- data/lib/openhab/rspec/karaf.rb +5 -27
- data/lib/openhab/rspec/mocks/persistence_service.rb +7 -7
- data/lib/openhab/yard/html_helper.rb +1 -1
- data/lib/openhab/yard.rb +1 -1
- metadata +18 -13
- data/lib/openhab/core/items/semantics/tag_class_methods.rb +0 -73
- data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +0 -118
@@ -13,7 +13,7 @@ module OpenHAB
|
|
13
13
|
class GenericItem
|
14
14
|
# @!parse include Item
|
15
15
|
|
16
|
-
# rubocop:disable Naming/MethodName these mimic Java fields, which are
|
16
|
+
# rubocop:disable Naming/MethodName -- these mimic Java fields, which are
|
17
17
|
# actually methods
|
18
18
|
class << self
|
19
19
|
# manually define this, since the Java side doesn't
|
@@ -38,24 +38,6 @@ module OpenHAB
|
|
38
38
|
def ===(other)
|
39
39
|
other.is_a?(self)
|
40
40
|
end
|
41
|
-
|
42
|
-
# @!visibility private
|
43
|
-
def item_states_event_builder
|
44
|
-
@item_states_event_builder ||=
|
45
|
-
OpenHAB::OSGi.service("org.openhab.core.io.rest.sse.internal.SseItemStatesEventBuilder")&.tap do |builder|
|
46
|
-
m = builder.class.java_class.get_declared_method("getDisplayState", Item, java.util.Locale)
|
47
|
-
m.accessible = true
|
48
|
-
builder.instance_variable_set(:@getDisplayState, m)
|
49
|
-
# Disable "singleton on non-persistent Java type"
|
50
|
-
original_verbose = $VERBOSE
|
51
|
-
$VERBOSE = nil
|
52
|
-
def builder.get_display_state(item)
|
53
|
-
@getDisplayState.invoke(self, item, nil)
|
54
|
-
end
|
55
|
-
ensure
|
56
|
-
$VERBOSE = original_verbose
|
57
|
-
end
|
58
|
-
end
|
59
41
|
end
|
60
42
|
# rubocop:enable Naming/MethodName
|
61
43
|
|
@@ -89,21 +71,6 @@ module OpenHAB
|
|
89
71
|
!raw_state.is_a?(Types::UnDefType)
|
90
72
|
end
|
91
73
|
|
92
|
-
# @!attribute [r] formatted_state
|
93
|
-
#
|
94
|
-
# Format the item's state according to its state description
|
95
|
-
#
|
96
|
-
# This may include running a transformation.
|
97
|
-
#
|
98
|
-
# @return [String] The formatted state
|
99
|
-
#
|
100
|
-
# @example
|
101
|
-
# logger.info(Exterior_WindDirection.formatted_state) # => "NE (36°)"
|
102
|
-
#
|
103
|
-
def formatted_state
|
104
|
-
GenericItem.item_states_event_builder.get_display_state(self)
|
105
|
-
end
|
106
|
-
|
107
74
|
#
|
108
75
|
# @!attribute [r] state
|
109
76
|
# @return [State, nil]
|
@@ -124,124 +91,6 @@ module OpenHAB
|
|
124
91
|
# Check if the item state == {UNDEF}
|
125
92
|
# @return [true,false]
|
126
93
|
|
127
|
-
#
|
128
|
-
# Send a command to this item
|
129
|
-
#
|
130
|
-
# When this method is chained after the {OpenHAB::DSL::Items::Ensure::Ensurable#ensure ensure}
|
131
|
-
# method, or issued inside an {OpenHAB::DSL.ensure_states ensure_states} block, or after
|
132
|
-
# {OpenHAB::DSL.ensure_states! ensure_states!} have been called,
|
133
|
-
# the command will only be sent if the item is not already in the same state.
|
134
|
-
#
|
135
|
-
# The similar method `command!`, however, will always send the command regardless of the item's state.
|
136
|
-
#
|
137
|
-
# @param [Command, #to_s] command command to send to the item.
|
138
|
-
# When given a {Command} argument, it will be passed directly.
|
139
|
-
# Otherwise, the result of `#to_s` will be parsed into a {Command}.
|
140
|
-
# @param [String, nil] source Optional string to identify what sent the event.
|
141
|
-
# @return [self, nil] nil when `ensure` is in effect and the item was already in the same state,
|
142
|
-
# otherwise the item.
|
143
|
-
#
|
144
|
-
# @see DSL::Items::TimedCommand#command Timed Command
|
145
|
-
# @see OpenHAB::DSL.ensure_states ensure_states
|
146
|
-
# @see OpenHAB::DSL.ensure_states! ensure_states!
|
147
|
-
# @see DSL::Items::Ensure::Ensurable#ensure ensure
|
148
|
-
#
|
149
|
-
# @example Sending a {Command} to an item
|
150
|
-
# MySwitch.command(ON) # The preferred method is `MySwitch.on`
|
151
|
-
# Garage_Door.command(DOWN) # The preferred method is `Garage_Door.down`
|
152
|
-
# SetTemperature.command 20 | "°C"
|
153
|
-
#
|
154
|
-
# @example Sending a plain number to a {NumberItem}
|
155
|
-
# SetTemperature.command(22.5) # if it accepts a DecimalType
|
156
|
-
#
|
157
|
-
# @example Sending a string to a dimensioned {NumberItem}
|
158
|
-
# SetTemperature.command("22.5 °C") # The string will be parsed and converted to a QuantityType
|
159
|
-
#
|
160
|
-
def command(command, source: nil)
|
161
|
-
command = format_command(command)
|
162
|
-
logger.trace { "Sending Command #{command} to #{name}" }
|
163
|
-
if source
|
164
|
-
Events.publisher.post(Events::ItemEventFactory.create_command_event(name, command, source.to_s))
|
165
|
-
else
|
166
|
-
$events.send_command(self, command)
|
167
|
-
end
|
168
|
-
Proxy.new(self)
|
169
|
-
end
|
170
|
-
alias_method :command!, :command
|
171
|
-
|
172
|
-
# not an alias to allow easier stubbing and overriding
|
173
|
-
def <<(command)
|
174
|
-
command(command)
|
175
|
-
end
|
176
|
-
|
177
|
-
# @!parse alias_method :<<, :command
|
178
|
-
|
179
|
-
# @!method refresh
|
180
|
-
# Send the {REFRESH} command to the item
|
181
|
-
# @return [Item] `self`
|
182
|
-
|
183
|
-
#
|
184
|
-
# Send an update to this item
|
185
|
-
#
|
186
|
-
# @param [State, #to_s, nil] state the state to update the item.
|
187
|
-
# When given a {State} argument, it will be passed directly.
|
188
|
-
# Otherwise, the result of `#to_s` will be parsed into a {State} first.
|
189
|
-
# If `nil` is passed, the item will be updated to {NULL}.
|
190
|
-
# @return [self, nil] nil when `ensure` is in effect and the item was already in the same state,
|
191
|
-
# otherwise the item.
|
192
|
-
#
|
193
|
-
# @example Updating to a {State}
|
194
|
-
# DoorStatus.update(OPEN)
|
195
|
-
# InsideTemperature.update 20 | "°C"
|
196
|
-
#
|
197
|
-
# @example Updating to {NULL}, the two following are equivalent:
|
198
|
-
# DoorStatus.update(nil)
|
199
|
-
# DoorStatus.update(NULL)
|
200
|
-
#
|
201
|
-
# @example Updating with a plain number
|
202
|
-
# PeopleCount.update(5) # A plain NumberItem
|
203
|
-
#
|
204
|
-
# @example Updating with a string to a dimensioned {NumberItem}
|
205
|
-
# InsideTemperature.update("22.5 °C") # The string will be parsed and converted to a QuantityType
|
206
|
-
#
|
207
|
-
def update(state)
|
208
|
-
state = format_update(state)
|
209
|
-
logger.trace { "Sending Update #{state} to #{name}" }
|
210
|
-
$events.post_update(self, state)
|
211
|
-
Proxy.new(self)
|
212
|
-
end
|
213
|
-
alias_method :update!, :update
|
214
|
-
|
215
|
-
# @!visibility private
|
216
|
-
def format_command(command)
|
217
|
-
command = format_type(command)
|
218
|
-
return command if command.is_a?(Types::Command)
|
219
|
-
|
220
|
-
command = command.to_s
|
221
|
-
org.openhab.core.types.TypeParser.parse_command(getAcceptedCommandTypes, command) || command
|
222
|
-
end
|
223
|
-
|
224
|
-
# @!visibility private
|
225
|
-
def format_update(state)
|
226
|
-
state = format_type(state)
|
227
|
-
return state if state.is_a?(Types::State)
|
228
|
-
|
229
|
-
state = state.to_s
|
230
|
-
org.openhab.core.types.TypeParser.parse_state(getAcceptedDataTypes, state) || StringType.new(state)
|
231
|
-
end
|
232
|
-
|
233
|
-
# formats a {Types::Type} to send to the event bus
|
234
|
-
# @!visibility private
|
235
|
-
def format_type(type)
|
236
|
-
# actual Type types can be sent directly without conversion
|
237
|
-
# make sure to use Type, because this method is used for both
|
238
|
-
# #update and #command
|
239
|
-
return type if type.is_a?(Types::Type)
|
240
|
-
return NULL if type.nil?
|
241
|
-
|
242
|
-
type.to_s
|
243
|
-
end
|
244
|
-
|
245
94
|
#
|
246
95
|
# @method time_series=(time_series)
|
247
96
|
# Set a new time series.
|
@@ -263,6 +112,7 @@ module OpenHAB
|
|
263
112
|
# knowingly and intentionally though, so an escape hatch is provided to allow runtime
|
264
113
|
# modifications.
|
265
114
|
# @yield
|
115
|
+
# @yieldparam [Item] self The item
|
266
116
|
# @return [Object] the block's return value
|
267
117
|
#
|
268
118
|
# @example Modify label and tags for an item
|
@@ -271,9 +121,19 @@ module OpenHAB
|
|
271
121
|
# MySwitch.tags = :labeled
|
272
122
|
# end
|
273
123
|
#
|
124
|
+
# @example Using the block argument to access the item
|
125
|
+
# MySwitch.modify do |item|
|
126
|
+
# item.label = "New Label"
|
127
|
+
# item.icon = :switch
|
128
|
+
# item.tags = Semantics::Switch, Semantics::Light
|
129
|
+
# end
|
130
|
+
#
|
274
131
|
def modify(force: false)
|
275
132
|
raise ArgumentError, "you must pass a block to modify" unless block_given?
|
276
|
-
|
133
|
+
|
134
|
+
proxied_self = Proxy.new(self)
|
135
|
+
|
136
|
+
return yield(proxied_self) if instance_variable_defined?(:@modifying) && @modifying
|
277
137
|
|
278
138
|
begin
|
279
139
|
provider = self.provider
|
@@ -286,7 +146,7 @@ module OpenHAB
|
|
286
146
|
@modified = false
|
287
147
|
@modifying = true
|
288
148
|
|
289
|
-
r = yield
|
149
|
+
r = yield(proxied_self)
|
290
150
|
|
291
151
|
provider&.update(self) if @modified
|
292
152
|
r
|
@@ -120,7 +120,7 @@ module OpenHAB
|
|
120
120
|
# @return [String]
|
121
121
|
def inspect
|
122
122
|
r = "#<OpenHAB::Core::Items::GroupItems::Members #{name}"
|
123
|
-
r += " #{map(&:name).inspect}
|
123
|
+
r += " #{map(&:name).inspect}" unless @group.__getobj__.nil?
|
124
124
|
"#{r}>"
|
125
125
|
end
|
126
126
|
alias_method :to_s, :inspect
|
@@ -202,8 +202,8 @@ module OpenHAB
|
|
202
202
|
# Command methods and predicate methods for GroupItem are performed here
|
203
203
|
# instead of being statically defined in items.rb
|
204
204
|
# because base_item is needed to determine the command/data types but is not available in the static context
|
205
|
-
|
206
|
-
return base_item.__send__(method,
|
205
|
+
def method_missing(method, ...)
|
206
|
+
return base_item.__send__(method, ...) if base_item&.respond_to?(method) # rubocop:disable Lint/RedundantSafeNavigation -- nil responds to :to_a
|
207
207
|
|
208
208
|
super
|
209
209
|
end
|
@@ -41,11 +41,10 @@ module OpenHAB
|
|
41
41
|
# @param [String] file location
|
42
42
|
# @param [String] mime_type of image
|
43
43
|
#
|
44
|
-
#
|
45
44
|
def update_from_file(file, mime_type: nil)
|
46
45
|
file_data = File.binread(file)
|
47
46
|
mime_type ||= Marcel::MimeType.for(Pathname.new(file)) || Marcel::MimeType.for(file_data)
|
48
|
-
update_from_bytes(file_data, mime_type:
|
47
|
+
update_from_bytes(file_data, mime_type:)
|
49
48
|
end
|
50
49
|
|
51
50
|
#
|
@@ -53,14 +52,13 @@ module OpenHAB
|
|
53
52
|
#
|
54
53
|
# @param [String] uri location of image
|
55
54
|
#
|
56
|
-
#
|
57
55
|
def update_from_url(uri)
|
58
56
|
logger.trace { "Downloading image from #{uri}" }
|
59
57
|
response = Net::HTTP.get_response(URI(uri))
|
60
58
|
mime_type = response["content-type"]
|
61
59
|
bytes = response.body
|
62
|
-
mime_type ||= detect_mime_from_bytes(bytes:
|
63
|
-
update_from_bytes(bytes, mime_type:
|
60
|
+
mime_type ||= detect_mime_from_bytes(bytes:)
|
61
|
+
update_from_bytes(bytes, mime_type:)
|
64
62
|
end
|
65
63
|
|
66
64
|
#
|
@@ -69,27 +67,13 @@ module OpenHAB
|
|
69
67
|
# @param [String] mime_type of image
|
70
68
|
# @param [Object] bytes image data
|
71
69
|
#
|
72
|
-
#
|
73
70
|
def update_from_bytes(bytes, mime_type: nil)
|
74
|
-
mime_type ||= detect_mime_from_bytes(bytes:
|
75
|
-
|
76
|
-
update(base_64_image)
|
71
|
+
mime_type ||= detect_mime_from_bytes(bytes:)
|
72
|
+
update(RawType.new(bytes.to_java_bytes, mime_type))
|
77
73
|
end
|
78
74
|
|
79
75
|
private
|
80
76
|
|
81
|
-
#
|
82
|
-
# Encode image information in the format required by openHAB
|
83
|
-
#
|
84
|
-
# @param [String] mime_type for image
|
85
|
-
# @param [Object] bytes image data
|
86
|
-
#
|
87
|
-
# @return [String] openHAB image format with image data Base64 encoded
|
88
|
-
#
|
89
|
-
def encode_image(mime_type:, bytes:)
|
90
|
-
"data:#{mime_type};base64,#{Base64.strict_encode64(bytes)}"
|
91
|
-
end
|
92
|
-
|
93
77
|
#
|
94
78
|
# Detect the mime type based on bytes
|
95
79
|
#
|
@@ -19,6 +19,24 @@ module OpenHAB
|
|
19
19
|
other.is_a?(self)
|
20
20
|
end
|
21
21
|
|
22
|
+
# @!visibility private
|
23
|
+
def item_states_event_builder
|
24
|
+
@item_states_event_builder ||=
|
25
|
+
OpenHAB::OSGi.service("org.openhab.core.io.rest.sse.internal.SseItemStatesEventBuilder")&.tap do |builder|
|
26
|
+
m = builder.class.java_class.get_declared_method("getDisplayState", Item, java.util.Locale)
|
27
|
+
m.accessible = true
|
28
|
+
builder.instance_variable_set(:@getDisplayState, m)
|
29
|
+
# Disable "singleton on non-persistent Java type"
|
30
|
+
original_verbose = $VERBOSE
|
31
|
+
$VERBOSE = nil
|
32
|
+
def builder.get_display_state(item)
|
33
|
+
@getDisplayState.invoke(self, item, nil)
|
34
|
+
end
|
35
|
+
ensure
|
36
|
+
$VERBOSE = original_verbose
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
22
40
|
private
|
23
41
|
|
24
42
|
# @!macro def_type_predicate
|
@@ -46,6 +64,12 @@ module OpenHAB
|
|
46
64
|
# @!attribute [r] accepted_data_types
|
47
65
|
# @return [Array<Class>] An array of {State}s that can be sent as commands to this item
|
48
66
|
|
67
|
+
# @!attribute [r] state_description
|
68
|
+
# @return [Types::StateDescription, nil]
|
69
|
+
|
70
|
+
# @!attribute [r] command_description
|
71
|
+
# @return [Types::CommandDescription, nil]
|
72
|
+
|
49
73
|
#
|
50
74
|
# The item's {GenericItem#label label} if one is defined, otherwise its {#name}.
|
51
75
|
#
|
@@ -55,6 +79,139 @@ module OpenHAB
|
|
55
79
|
label || name
|
56
80
|
end
|
57
81
|
|
82
|
+
# @!attribute [r] formatted_state
|
83
|
+
#
|
84
|
+
# Format the item's state according to its state description
|
85
|
+
#
|
86
|
+
# This may include running a transformation.
|
87
|
+
#
|
88
|
+
# @return [String] The formatted state
|
89
|
+
#
|
90
|
+
# @example
|
91
|
+
# logger.info(Exterior_WindDirection.formatted_state) # => "NE (36°)"
|
92
|
+
#
|
93
|
+
def formatted_state
|
94
|
+
Item.item_states_event_builder.get_display_state(self)
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Send a command to this item
|
99
|
+
#
|
100
|
+
# When this method is chained after the {OpenHAB::DSL::Items::Ensure::Ensurable#ensure ensure}
|
101
|
+
# method, or issued inside an {OpenHAB::DSL.ensure_states ensure_states} block, or after
|
102
|
+
# {OpenHAB::DSL.ensure_states! ensure_states!} have been called,
|
103
|
+
# the command will only be sent if the item is not already in the same state.
|
104
|
+
#
|
105
|
+
# The similar method `command!`, however, will always send the command regardless of the item's state.
|
106
|
+
#
|
107
|
+
# @param [Command, #to_s] command command to send to the item.
|
108
|
+
# When given a {Command} argument, it will be passed directly.
|
109
|
+
# Otherwise, the result of `#to_s` will be parsed into a {Command}.
|
110
|
+
# @param [String, nil] source Optional string to identify what sent the event.
|
111
|
+
# @return [self, nil] nil when `ensure` is in effect and the item was already in the same state,
|
112
|
+
# otherwise the item.
|
113
|
+
#
|
114
|
+
# @see DSL::Items::TimedCommand#command Timed Command
|
115
|
+
# @see OpenHAB::DSL.ensure_states ensure_states
|
116
|
+
# @see OpenHAB::DSL.ensure_states! ensure_states!
|
117
|
+
# @see DSL::Items::Ensure::Ensurable#ensure ensure
|
118
|
+
#
|
119
|
+
# @example Sending a {Command} to an item
|
120
|
+
# MySwitch.command(ON) # The preferred method is `MySwitch.on`
|
121
|
+
# Garage_Door.command(DOWN) # The preferred method is `Garage_Door.down`
|
122
|
+
# SetTemperature.command 20 | "°C"
|
123
|
+
#
|
124
|
+
# @example Sending a plain number to a {NumberItem}
|
125
|
+
# SetTemperature.command(22.5) # if it accepts a DecimalType
|
126
|
+
#
|
127
|
+
# @example Sending a string to a dimensioned {NumberItem}
|
128
|
+
# SetTemperature.command("22.5 °C") # The string will be parsed and converted to a QuantityType
|
129
|
+
#
|
130
|
+
def command(command, source: nil)
|
131
|
+
command = format_command(command)
|
132
|
+
logger.trace { "Sending Command #{command} to #{name}" }
|
133
|
+
if source
|
134
|
+
Events.publisher.post(Events::ItemEventFactory.create_command_event(name, command, source.to_s))
|
135
|
+
else
|
136
|
+
$events.send_command(self, command)
|
137
|
+
end
|
138
|
+
Proxy.new(self)
|
139
|
+
end
|
140
|
+
alias_method :command!, :command
|
141
|
+
|
142
|
+
# not an alias to allow easier stubbing and overriding
|
143
|
+
def <<(command)
|
144
|
+
command(command)
|
145
|
+
end
|
146
|
+
|
147
|
+
# @!parse alias_method :<<, :command
|
148
|
+
|
149
|
+
# @!method refresh
|
150
|
+
# Send the {REFRESH} command to the item
|
151
|
+
# @return [Item] `self`
|
152
|
+
|
153
|
+
#
|
154
|
+
# Send an update to this item
|
155
|
+
#
|
156
|
+
# @param [State, #to_s, nil] state the state to update the item.
|
157
|
+
# When given a {State} argument, it will be passed directly.
|
158
|
+
# Otherwise, the result of `#to_s` will be parsed into a {State} first.
|
159
|
+
# If `nil` is passed, the item will be updated to {NULL}.
|
160
|
+
# @return [self, nil] nil when `ensure` is in effect and the item was already in the same state,
|
161
|
+
# otherwise the item.
|
162
|
+
#
|
163
|
+
# @example Updating to a {State}
|
164
|
+
# DoorStatus.update(OPEN)
|
165
|
+
# InsideTemperature.update 20 | "°C"
|
166
|
+
#
|
167
|
+
# @example Updating to {NULL}, the two following are equivalent:
|
168
|
+
# DoorStatus.update(nil)
|
169
|
+
# DoorStatus.update(NULL)
|
170
|
+
#
|
171
|
+
# @example Updating with a plain number
|
172
|
+
# PeopleCount.update(5) # A plain NumberItem
|
173
|
+
#
|
174
|
+
# @example Updating with a string to a dimensioned {NumberItem}
|
175
|
+
# InsideTemperature.update("22.5 °C") # The string will be parsed and converted to a QuantityType
|
176
|
+
#
|
177
|
+
def update(state)
|
178
|
+
state = format_update(state)
|
179
|
+
logger.trace { "Sending Update #{state} to #{name}" }
|
180
|
+
$events.post_update(self, state)
|
181
|
+
Proxy.new(self)
|
182
|
+
end
|
183
|
+
alias_method :update!, :update
|
184
|
+
|
185
|
+
# @!visibility private
|
186
|
+
def format_command(command)
|
187
|
+
command = format_type(command)
|
188
|
+
return command if command.is_a?(Types::Command)
|
189
|
+
|
190
|
+
command = command.to_s
|
191
|
+
org.openhab.core.types.TypeParser.parse_command(getAcceptedCommandTypes, command) || command
|
192
|
+
end
|
193
|
+
|
194
|
+
# @!visibility private
|
195
|
+
def format_update(state)
|
196
|
+
state = format_type(state)
|
197
|
+
return state if state.is_a?(Types::State)
|
198
|
+
|
199
|
+
state = state.to_s
|
200
|
+
org.openhab.core.types.TypeParser.parse_state(getAcceptedDataTypes, state) || StringType.new(state)
|
201
|
+
end
|
202
|
+
|
203
|
+
# formats a {Types::Type} to send to the event bus
|
204
|
+
# @!visibility private
|
205
|
+
def format_type(type)
|
206
|
+
# actual Type types can be sent directly without conversion
|
207
|
+
# make sure to use Type, because this method is used for both
|
208
|
+
# #update and #command
|
209
|
+
return type if type.is_a?(Types::Type)
|
210
|
+
return NULL if type.nil?
|
211
|
+
|
212
|
+
type.to_s
|
213
|
+
end
|
214
|
+
|
58
215
|
#
|
59
216
|
# @!attribute [r] groups
|
60
217
|
#
|
@@ -63,7 +220,7 @@ module OpenHAB
|
|
63
220
|
# @return [Array<GroupItem>] All groups that this item is part of
|
64
221
|
#
|
65
222
|
def groups
|
66
|
-
group_names.
|
223
|
+
group_names.filter_map { |name| EntityLookup.lookup_item(name) }
|
67
224
|
end
|
68
225
|
|
69
226
|
#
|
@@ -79,7 +236,7 @@ module OpenHAB
|
|
79
236
|
groups.map! do |group|
|
80
237
|
group.is_a?(GroupItem) ? group.name : group
|
81
238
|
end
|
82
|
-
|
239
|
+
!!group_names.intersect?(groups)
|
83
240
|
end
|
84
241
|
|
85
242
|
#
|
@@ -239,16 +396,13 @@ module OpenHAB
|
|
239
396
|
#
|
240
397
|
def tagged?(*tags)
|
241
398
|
tags.map! do |tag|
|
242
|
-
|
243
|
-
if tag.is_a?(Module)
|
244
|
-
tag.simple_name
|
245
|
-
elsif defined?(Semantics::SemanticTag) && tag.is_a?(Semantics::SemanticTag)
|
399
|
+
if tag.is_a?(Semantics::SemanticTag)
|
246
400
|
tag.name
|
247
401
|
else
|
248
402
|
tag
|
249
403
|
end
|
250
404
|
end
|
251
|
-
|
405
|
+
!!self.tags.to_a.intersect?(tags)
|
252
406
|
end
|
253
407
|
|
254
408
|
# @!attribute thing [r]
|
@@ -62,7 +62,7 @@ module OpenHAB
|
|
62
62
|
# logger.info("Max power usage today: #{max}, at: #{max.timestamp})
|
63
63
|
#
|
64
64
|
module Persistence
|
65
|
-
|
65
|
+
Item.prepend(self)
|
66
66
|
|
67
67
|
#
|
68
68
|
# A wrapper for {org.openhab.core.persistence.HistoricItem HistoricItem} that delegates to its state.
|
@@ -667,10 +667,10 @@ module OpenHAB
|
|
667
667
|
method = method.to_s.dup
|
668
668
|
suffix = method.delete_suffix!("?") && "?"
|
669
669
|
|
670
|
-
def_persistence_method("#{method}_since#{suffix}", quantify:
|
670
|
+
def_persistence_method("#{method}_since#{suffix}", quantify:)
|
671
671
|
# @deprecated OH 4.1 remove if guard, keeping the content, when dropping OH 4.1
|
672
672
|
if OpenHAB::Core.version >= OpenHAB::Core::V4_2
|
673
|
-
def_persistence_method("#{method}_until#{suffix}", quantify:
|
673
|
+
def_persistence_method("#{method}_until#{suffix}", quantify:)
|
674
674
|
end
|
675
675
|
|
676
676
|
method = "#{method}_between"
|
@@ -710,12 +710,10 @@ module OpenHAB
|
|
710
710
|
def_persistence_methods(:minimum, quantify: true)
|
711
711
|
def_persistence_methods(:updated?)
|
712
712
|
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
alias_method :all_states_between, :get_all_states_between
|
718
|
-
end
|
713
|
+
def_persistence_methods(:get_all_states, quantify: true)
|
714
|
+
alias_method :all_states_since, :get_all_states_since
|
715
|
+
alias_method :all_states_until, :get_all_states_until if OpenHAB::Core.version >= OpenHAB::Core::V4_2
|
716
|
+
alias_method :all_states_between, :get_all_states_between
|
719
717
|
|
720
718
|
if OpenHAB::Core.version >= OpenHAB::Core::V4_2
|
721
719
|
def_persistence_method(:persisted_state) # already quantified in core
|
@@ -791,7 +789,7 @@ module OpenHAB
|
|
791
789
|
when org.openhab.core.persistence.HistoricItem
|
792
790
|
PersistedState.new(result, quantify ? quantify(result.state) : nil)
|
793
791
|
when java.util.Collection, Array
|
794
|
-
result.to_a.map { |historic_item| wrap_result(historic_item, quantify:
|
792
|
+
result.to_a.map { |historic_item| wrap_result(historic_item, quantify:) }
|
795
793
|
else
|
796
794
|
return quantify(result) if quantify
|
797
795
|
|
@@ -27,7 +27,7 @@ module OpenHAB
|
|
27
27
|
# @param [true, false] recursive
|
28
28
|
# @return [Item, nil] The removed item, if found.
|
29
29
|
#
|
30
|
-
def remove(item_name, recursive = false) # rubocop:disable Style/OptionalBooleanParameter matches Java method
|
30
|
+
def remove(item_name, recursive = false) # rubocop:disable Style/OptionalBooleanParameter -- matches Java method
|
31
31
|
return nil unless @elements.key?(item_name)
|
32
32
|
|
33
33
|
item = super(item_name)
|