openhab-scripting 5.6.0 → 5.7.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/core/actions/audio.rb +5 -2
- data/lib/openhab/core/items/registry.rb +1 -1
- data/lib/openhab/core/items/semantics.rb +12 -19
- data/lib/openhab/core/provider.rb +1 -1
- data/lib/openhab/core/sitemaps/provider.rb +132 -0
- data/lib/openhab/core/things/proxy.rb +2 -1
- data/lib/openhab/core/types/date_time_type.rb +2 -1
- data/lib/openhab/core/types/open_closed_type.rb +2 -1
- data/lib/openhab/core/types/quantity_type.rb +45 -35
- data/lib/openhab/core/types/string_type.rb +1 -1
- data/lib/openhab/core/types/up_down_type.rb +2 -1
- data/lib/openhab/core/value_cache.rb +5 -4
- data/lib/openhab/core_ext/java/duration.rb +2 -1
- data/lib/openhab/core_ext/java/local_time.rb +8 -6
- data/lib/openhab/core_ext/java/month_day.rb +2 -1
- data/lib/openhab/core_ext/java/period.rb +1 -1
- data/lib/openhab/core_ext/ruby/numeric.rb +1 -0
- data/lib/openhab/dsl/items/builder.rb +3 -1
- data/lib/openhab/dsl/rules/builder.rb +54 -23
- data/lib/openhab/dsl/rules/triggers/conditions/generic.rb +1 -1
- data/lib/openhab/dsl/rules/triggers/cron/cron.rb +33 -14
- data/lib/openhab/dsl/sitemaps/builder.rb +942 -0
- data/lib/openhab/dsl/things/builder.rb +4 -2
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/dsl.rb +5 -0
- data/lib/openhab/osgi.rb +1 -1
- data/lib/openhab/rspec/karaf.rb +5 -2
- data/lib/openhab/rspec/openhab/core/actions.rb +0 -3
- metadata +11 -23
@@ -0,0 +1,942 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module DSL
|
5
|
+
#
|
6
|
+
# Contains the various builders for sitemap elements.
|
7
|
+
#
|
8
|
+
module Sitemaps
|
9
|
+
# @!visibility private
|
10
|
+
org.openhab.core.model.sitemap.sitemap.impl.SitemapImpl.alias_method :uid, :name
|
11
|
+
|
12
|
+
# Base sitemap builder DSL
|
13
|
+
class Builder
|
14
|
+
# @!visibility private
|
15
|
+
def initialize(provider)
|
16
|
+
@provider = provider
|
17
|
+
end
|
18
|
+
|
19
|
+
# (see SitemapBuilder#initialize)
|
20
|
+
# @yield Block executed in the context of a {SitemapBuilder}
|
21
|
+
# @return [SitemapBuilder]
|
22
|
+
# @!visibility public
|
23
|
+
def sitemap(name, label = nil, icon: nil, &block)
|
24
|
+
sitemap = SitemapBuilder.new(name, label, icon: icon)
|
25
|
+
sitemap.instance_eval_with_dummy_items(&block) if block
|
26
|
+
@provider.add(sitemap.build)
|
27
|
+
sitemap
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Base class for all widgets
|
32
|
+
# @see org.openhab.core.model.sitemap.sitemap.Widget
|
33
|
+
class WidgetBuilder
|
34
|
+
# rubocop:disable Layout/LineLength, Lint/MixedRegexpCaptureTypes
|
35
|
+
# These are copied directly out of UIComponentSitemapProvider.java
|
36
|
+
VISIBILITY_PATTERN = /(?<item>[A-Za-z]\w*)\s*(?<condition>==|!=|<=|>=|<|>)\s*(?<sign>\+|-)?(?<state>\S+)/.freeze
|
37
|
+
COLOR_PATTERN = /((?<item>[A-Za-z]\w*)?\s*((?<condition>==|!=|<=|>=|<|>)\s*(?<sign>\+|-)?(?<state>\S+))?\s*=)?\s*(?<arg>\S+)/.freeze
|
38
|
+
# rubocop:enable Layout/LineLength, Lint/MixedRegexpCaptureTypes
|
39
|
+
private_constant :VISIBILITY_PATTERN, :COLOR_PATTERN
|
40
|
+
|
41
|
+
# @return [String, nil]
|
42
|
+
attr_accessor :label
|
43
|
+
# The item whose state to show
|
44
|
+
# @return [String, Core::Items::Item, nil]
|
45
|
+
attr_accessor :item
|
46
|
+
# @return [String, nil]
|
47
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#icons
|
48
|
+
attr_accessor :icon
|
49
|
+
# Label color rules
|
50
|
+
# @return [Array<String>]
|
51
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#label-value-and-icon-colors
|
52
|
+
attr_reader :label_colors
|
53
|
+
# Value color rules
|
54
|
+
# @return [Array<String>]
|
55
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#label-value-and-icon-colors
|
56
|
+
attr_reader :value_colors
|
57
|
+
# Icon color rules
|
58
|
+
# @return [Array<String>]
|
59
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#label-value-and-icon-colors
|
60
|
+
attr_reader :icon_colors
|
61
|
+
# Visibility rules
|
62
|
+
# @return [Array<String>]
|
63
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#visibility
|
64
|
+
attr_reader :visibilities
|
65
|
+
|
66
|
+
# @param item [String, Core::Items::Item, nil] The item whose state to show (see {#item})
|
67
|
+
# @param label [String, nil] (see {#label})
|
68
|
+
# @param icon [String, nil] (see {#icon})
|
69
|
+
# @param label_color [String, Array<String>, nil] One or more label color rules (see {#label_color})
|
70
|
+
# @param value_color [String, Array<String>, nil] One or more value color rules (see {#value_color})
|
71
|
+
# @param icon_color [String, Array<String>, nil] One or more icon color rules (see {#icon_color})
|
72
|
+
# @param visibility [String, Array<String>, nil] One or more visibility rules (see {#visibility})
|
73
|
+
# @!visibility private
|
74
|
+
def initialize(type,
|
75
|
+
item: nil,
|
76
|
+
label: nil,
|
77
|
+
icon: nil,
|
78
|
+
label_color: nil,
|
79
|
+
value_color: nil,
|
80
|
+
icon_color: nil,
|
81
|
+
visibility: nil)
|
82
|
+
unless SitemapBuilder.factory.respond_to?("create_#{type}")
|
83
|
+
raise ArgumentError,
|
84
|
+
"#{type} is not a valid widget type"
|
85
|
+
end
|
86
|
+
|
87
|
+
@type = type
|
88
|
+
@item = item
|
89
|
+
@label = label
|
90
|
+
@icon = icon
|
91
|
+
@visibilities = []
|
92
|
+
@label_colors = []
|
93
|
+
@value_colors = []
|
94
|
+
@icon_colors = []
|
95
|
+
|
96
|
+
self.label_color(*label_color) if label_color
|
97
|
+
self.value_color(*value_color) if value_color
|
98
|
+
self.icon_color(*icon_color) if icon_color
|
99
|
+
self.visibility(*visibility) if visibility
|
100
|
+
end
|
101
|
+
|
102
|
+
# Adds one or more new rules for setting the label color
|
103
|
+
# @return [Array<String>] the current rules
|
104
|
+
def label_color(*rules)
|
105
|
+
@label_colors.concat(rules)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Adds one or more new rules for setting the value color
|
109
|
+
# @return [Array<String>] the current rules
|
110
|
+
def value_color(*rules)
|
111
|
+
@value_colors.concat(rules)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Adds one or more new rules for setting the icon color
|
115
|
+
# @return [Array<String>] the current rules
|
116
|
+
def icon_color(*rules)
|
117
|
+
@icon_colors.concat(rules)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Adds one or more new visibility rules
|
121
|
+
# @return [Array<String>] the current rules
|
122
|
+
def visibility(*rules)
|
123
|
+
@visibilities.concat(rules)
|
124
|
+
end
|
125
|
+
|
126
|
+
# @!visibility private
|
127
|
+
def build
|
128
|
+
widget = SitemapBuilder.factory.send("create_#{@type}")
|
129
|
+
item = @item
|
130
|
+
item = item.name if item.respond_to?(:name)
|
131
|
+
widget.item = item if item
|
132
|
+
widget.label = @label
|
133
|
+
widget.icon = @icon
|
134
|
+
|
135
|
+
add_color(widget.label_color, label_colors) unless label_colors.empty?
|
136
|
+
add_color(widget.value_color, value_colors) unless value_colors.empty?
|
137
|
+
add_color(widget.icon_color, icon_colors) unless icon_colors.empty?
|
138
|
+
|
139
|
+
visibilities.each do |v|
|
140
|
+
unless (match = VISIBILITY_PATTERN.match(v))
|
141
|
+
raise ArgumentError, "Syntax error in visibility rule #{v.inspect}"
|
142
|
+
end
|
143
|
+
|
144
|
+
rule = SitemapBuilder.factory.create_visibility_rule
|
145
|
+
rule.item = match["item"]
|
146
|
+
rule.condition = match["condition"]
|
147
|
+
rule.sign = match["sign"]
|
148
|
+
rule.state = match["state"]
|
149
|
+
widget.visibility.add(rule)
|
150
|
+
end
|
151
|
+
|
152
|
+
widget
|
153
|
+
end
|
154
|
+
|
155
|
+
# @!visibility private
|
156
|
+
def inspect
|
157
|
+
s = +"#<OpenHAB::DSL::Sitemaps::#{@type.capitalize}Builder "
|
158
|
+
s << (instance_variables - [:@children]).map do |iv|
|
159
|
+
"#{iv}=#{instance_variable_get(iv).inspect}"
|
160
|
+
end.join(" ")
|
161
|
+
s << ">"
|
162
|
+
s.freeze
|
163
|
+
end
|
164
|
+
|
165
|
+
private
|
166
|
+
|
167
|
+
def add_color(widget_color, colors)
|
168
|
+
colors.each do |c|
|
169
|
+
unless (match = COLOR_PATTERN.match(c))
|
170
|
+
raise ArgumentError, "Syntax error in color rule #{c.inspect}"
|
171
|
+
end
|
172
|
+
|
173
|
+
rule = SitemapBuilder.factory.create_color_array
|
174
|
+
rule.item = match["item"]
|
175
|
+
rule.condition = match["condition"]
|
176
|
+
rule.sign = match["sign"]
|
177
|
+
rule.state = match["state"]
|
178
|
+
rule.arg = match["arg"]
|
179
|
+
widget_color.add(color)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Builds a `Switch` element
|
185
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-switch
|
186
|
+
# @see org.openhab.core.model.sitemap.sitemap.Switch
|
187
|
+
class SwitchBuilder < WidgetBuilder
|
188
|
+
# Mappings from command to label
|
189
|
+
#
|
190
|
+
# Keys can be any {Core::Types::Command command}, values are strings.
|
191
|
+
# If an array is given, the same value is used for both command and label.
|
192
|
+
# @return [Hash, Array, nil]
|
193
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#mappings
|
194
|
+
attr_accessor :mappings
|
195
|
+
|
196
|
+
# (see WidgetBuilder#initialize)
|
197
|
+
# @!method initialize(item: nil, label: nil, icon: nil, mappings: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
198
|
+
# @param mappings [Hash, Array, nil] Mappings from command to label (see {SwitchBuilder#mappings})
|
199
|
+
# @!visibility private
|
200
|
+
def initialize(type, mappings: nil, **kwargs)
|
201
|
+
super(type, **kwargs)
|
202
|
+
|
203
|
+
@mappings = mappings
|
204
|
+
end
|
205
|
+
|
206
|
+
# @!visibility private
|
207
|
+
def build
|
208
|
+
widget = super
|
209
|
+
mappings&.each do |cmd, label|
|
210
|
+
mapping = SitemapBuilder.factory.create_mapping
|
211
|
+
mapping.cmd = cmd.to_s
|
212
|
+
mapping.label = label&.to_s || cmd.to_s
|
213
|
+
widget.mappings.add(mapping)
|
214
|
+
end
|
215
|
+
widget
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# Builds a `Selection` element
|
220
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-selection
|
221
|
+
# @see org.openhab.core.model.sitemap.sitemap.Selection
|
222
|
+
class SelectionBuilder < SwitchBuilder
|
223
|
+
end
|
224
|
+
|
225
|
+
# Builds a `Setpoint` element
|
226
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-setpoint
|
227
|
+
# @see org.openhab.core.model.sitemap.sitemap.Setpoint
|
228
|
+
class SetpointBuilder < WidgetBuilder
|
229
|
+
# Allowed range of the value
|
230
|
+
# @return [Range, nil]
|
231
|
+
attr_accessor :range
|
232
|
+
# How far the value will change with each button press
|
233
|
+
# @return [Numeric, nil]
|
234
|
+
attr_accessor :step
|
235
|
+
|
236
|
+
# (see WidgetBuilder#initialize)
|
237
|
+
# @!method initialize(item: nil, label: nil, icon: nil, range: nil, step: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
238
|
+
# @param range [Range, nil] Allowed range of the value (see {SetpointBuilder#range})
|
239
|
+
# @param step [Numeric,nil] How far the value will change with each button press (see {SetpointBuilder#step})
|
240
|
+
# @!visibility private
|
241
|
+
def initialize(type, range: nil, step: nil, **kwargs)
|
242
|
+
super(type, **kwargs)
|
243
|
+
|
244
|
+
@range = range
|
245
|
+
@step = step
|
246
|
+
end
|
247
|
+
|
248
|
+
# @!visibility private
|
249
|
+
def build
|
250
|
+
widget = super
|
251
|
+
widget.min_value = range&.begin&.to_d
|
252
|
+
widget.max_value = range&.end&.to_d
|
253
|
+
widget.step = step&.to_d
|
254
|
+
widget
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
# Builds a `Slider` element
|
259
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-slider
|
260
|
+
# @see org.openhab.core.model.sitemap.sitemap.Slider
|
261
|
+
class SliderBuilder < SetpointBuilder
|
262
|
+
# How often to send requests (in seconds)
|
263
|
+
# @return [Numeric, nil]
|
264
|
+
attr_accessor :frequency
|
265
|
+
# A short press on the item toggles the item on or off
|
266
|
+
# @return [true, false, nil]
|
267
|
+
# @note This parameter only works on Android
|
268
|
+
attr_writer :switch
|
269
|
+
|
270
|
+
# (see SetpointBuilder#initialize)
|
271
|
+
# @!method initialize(item: nil, label: nil, icon: nil, range: nil, step: nil, switch: nil, frequency: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
272
|
+
# @param switch [true, false, nil]
|
273
|
+
# A short press on the item toggles the item on or off (see {SliderBuilder#switch=})
|
274
|
+
# @param frequency [Numeric, nil]
|
275
|
+
# How often to send requests (in seconds) (see {SliderBuilder#frequency})
|
276
|
+
# @!visibility private
|
277
|
+
def initialize(type, switch: nil, frequency: nil, **kwargs)
|
278
|
+
super(type, **kwargs)
|
279
|
+
|
280
|
+
@switch = switch
|
281
|
+
@frequency = frequency
|
282
|
+
end
|
283
|
+
|
284
|
+
# (see #switch=)
|
285
|
+
def switch?
|
286
|
+
@switch_enabled
|
287
|
+
end
|
288
|
+
|
289
|
+
# @!visibility private
|
290
|
+
def build
|
291
|
+
widget = super
|
292
|
+
widget.switch_enabled = switch?
|
293
|
+
widget.send_frequency = (frequency * 1000).to_i if frequency
|
294
|
+
widget
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# Builds a `Video` element
|
299
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-video
|
300
|
+
# @see org.openhab.core.model.sitemap.sitemap.Video
|
301
|
+
class VideoBuilder < WidgetBuilder
|
302
|
+
# Valid {#encoding} values
|
303
|
+
VALID_ENCODINGS = %i[mjpeg hls].freeze
|
304
|
+
|
305
|
+
# @return [String, nil]
|
306
|
+
attr_accessor :url
|
307
|
+
# @return [:mjpeg, :hls, nil]
|
308
|
+
attr_reader :encoding
|
309
|
+
|
310
|
+
# (see WidgetBuilder#initialize)
|
311
|
+
# @!method initialize(item: nil, label: nil, icon: nil, url: nil, encoding: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
312
|
+
# @param [String, nil] url (see {VideoBuilder#url})
|
313
|
+
# @param [:mjpeg, :hls, nil] encoding (see {VideoBuilder#encoding})
|
314
|
+
# @!visibility private
|
315
|
+
def initialize(type, url: nil, encoding: nil, **kwargs)
|
316
|
+
super(type, **kwargs)
|
317
|
+
|
318
|
+
@url = url
|
319
|
+
self.encoding = encoding
|
320
|
+
end
|
321
|
+
|
322
|
+
def encoding=(value)
|
323
|
+
raise ArgumentError, "#{value} is not a valid encoding" if value && !VALID_ENCODINGS.include?(value)
|
324
|
+
|
325
|
+
@encoding = value
|
326
|
+
end
|
327
|
+
|
328
|
+
# @!visibility private
|
329
|
+
def build
|
330
|
+
widget = super
|
331
|
+
widget.url = url
|
332
|
+
widget.encoding = encoding&.to_s
|
333
|
+
widget
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
# Builds a `Chart` element
|
338
|
+
# See https://www.openhab.org/docs/ui/sitemaps.html#element-type-chart
|
339
|
+
# @see org.openhab.core.model.sitemap.sitemap.Chart
|
340
|
+
class ChartBuilder < WidgetBuilder
|
341
|
+
# Valid {#period} values
|
342
|
+
VALID_PERIODS = %i[h 4h 8h 12h D 2D 3D W 2W M 2M 4M Y].freeze
|
343
|
+
|
344
|
+
# The persistence service to use
|
345
|
+
# @return [String, nil]
|
346
|
+
attr_accessor :service
|
347
|
+
# How often to refresh the chart (in seconds)
|
348
|
+
# @return [Numeric, nil]
|
349
|
+
attr_accessor :refresh
|
350
|
+
# Time axis scale
|
351
|
+
# @return [:h, :"4h", :"8h", :"12h", :D, :"2D", :"3D", :W, :"2W", :M, :"2M", :"4M", :Y, nil]
|
352
|
+
attr_reader :period
|
353
|
+
# Always show the legend, never show the legend, or automatically show
|
354
|
+
# the legend if there is more than one series in the chart.
|
355
|
+
# @return [true, false, nil]
|
356
|
+
attr_writer :legend
|
357
|
+
# Show the value of a {Core::Items::GroupItem GroupItem} instead of
|
358
|
+
# showing a graph for each member (which is the default).
|
359
|
+
# @return [true, false, nil]
|
360
|
+
attr_writer :group
|
361
|
+
# Formatting string for values on the y axis.
|
362
|
+
# @return [String, nil]
|
363
|
+
# @example
|
364
|
+
# "#.##" # => formats a number with two decimals.
|
365
|
+
# @see https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/text/DecimalFormat.html DecimalFormat
|
366
|
+
attr_accessor :y_axis_pattern
|
367
|
+
|
368
|
+
# (see WidgetBuilder#initialize)
|
369
|
+
# @!method initialize(item: nil, label: nil, icon: nil, service: nil, refresh: nil, period: nil, legend: nil, group: nil, y_axis_pattern: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
370
|
+
# @param service [String, nil]
|
371
|
+
# The persistence service to use (see {ChartBuilder#service})
|
372
|
+
# @param refresh [Numeric, nil)]
|
373
|
+
# How often to refresh the chart (in seconds) (see {ChartBuilder#refresh})
|
374
|
+
# @param period [:h, :"4h", :"8h", :"12h", :D, :"2D", :"3D", :W, :"2W", :M, :"2M", :"4M", :Y, nil]
|
375
|
+
# Time axis scale (see {ChartBuilder#period})
|
376
|
+
# @param legend [true, false, nil]
|
377
|
+
# Always show the legend (see {ChartBuilder#legend=})
|
378
|
+
# @param group [true, false, nil]
|
379
|
+
# Show the value of a group item, instead of its members (see {ChartBuilder#group=})
|
380
|
+
# @param y_axis_pattern [String, nil]
|
381
|
+
# Formatting string for values on the y axis (see {ChartBuilder#y_axis_pattern})
|
382
|
+
# @!visibility private
|
383
|
+
def initialize(type,
|
384
|
+
service: nil,
|
385
|
+
refresh: nil,
|
386
|
+
period: nil,
|
387
|
+
legend: nil,
|
388
|
+
group: nil,
|
389
|
+
y_axis_pattern: nil,
|
390
|
+
**kwargs)
|
391
|
+
super(type, **kwargs)
|
392
|
+
|
393
|
+
@service = service
|
394
|
+
self.refresh = refresh
|
395
|
+
@period = period
|
396
|
+
@legend = legend
|
397
|
+
@group = group
|
398
|
+
@y_axis_pattern = y_axis_pattern
|
399
|
+
end
|
400
|
+
|
401
|
+
def period=(value)
|
402
|
+
value = value&.to_sym
|
403
|
+
raise ArgumentError, "#{value} is not a valid period" if value && !VALID_PERIODS.include?(value)
|
404
|
+
|
405
|
+
@period = value
|
406
|
+
end
|
407
|
+
|
408
|
+
# (see #legend=)
|
409
|
+
def legend?
|
410
|
+
@legend
|
411
|
+
end
|
412
|
+
|
413
|
+
# (see #group=)
|
414
|
+
def group?
|
415
|
+
@group
|
416
|
+
end
|
417
|
+
|
418
|
+
# @!visibility private
|
419
|
+
def build
|
420
|
+
widget = super
|
421
|
+
widget.service = service
|
422
|
+
widget.period = period&.to_s
|
423
|
+
widget.legend = legend?
|
424
|
+
widget.force_as_item = group?
|
425
|
+
widget.yaxis_decimal_pattern = y_axis_pattern
|
426
|
+
widget
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
# Builds a `Default` element
|
431
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-default
|
432
|
+
# @see org.openhab.core.model.sitemap.sitemap.Default
|
433
|
+
class DefaultBuilder < WidgetBuilder
|
434
|
+
# @return [Integer] The number of element rows to fill
|
435
|
+
attr_accessor :height
|
436
|
+
|
437
|
+
# (see WidgetBuilder#initialize)
|
438
|
+
# @!method initialize(item: nil, label: nil, icon: nil, height: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
439
|
+
# @param height [Integer] The number of element rows to fill (see {DefaultBuilder#height})
|
440
|
+
# @!visibility private
|
441
|
+
def initialize(type, height: nil, **kwargs)
|
442
|
+
super(type, **kwargs)
|
443
|
+
|
444
|
+
@height = height
|
445
|
+
end
|
446
|
+
|
447
|
+
# @!visibility private
|
448
|
+
def build
|
449
|
+
widget = super
|
450
|
+
widget.height = height
|
451
|
+
widget
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
# Builds a `Webview` element
|
456
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-webview
|
457
|
+
# @see org.openhab.core.model.sitemap.sitemap.Webview
|
458
|
+
class WebviewBuilder < DefaultBuilder
|
459
|
+
# @return [String, nil]
|
460
|
+
attr_accessor :url
|
461
|
+
|
462
|
+
# (see DefaultBuilder#initialize)
|
463
|
+
# @!method initialize(item: nil, label: nil, icon: nil, url: nil, height: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
464
|
+
# @param url [String, nil] (see {WebviewBuilder#url})
|
465
|
+
# @!visibility private
|
466
|
+
def initialize(type, url: nil, **kwargs)
|
467
|
+
super(type, **kwargs)
|
468
|
+
|
469
|
+
@url = url
|
470
|
+
end
|
471
|
+
|
472
|
+
# @!visibility private
|
473
|
+
def build
|
474
|
+
widget = super
|
475
|
+
widget.url = url
|
476
|
+
widget
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
# Builds a `Colorpicker` element
|
481
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-colorpicker
|
482
|
+
# @see org.openhab.core.model.sitemap.sitemap.Colorpicker
|
483
|
+
class ColorpickerBuilder < WidgetBuilder
|
484
|
+
# @return [Numeric, nil]
|
485
|
+
# How often to send requests (in seconds)
|
486
|
+
attr_accessor :frequency
|
487
|
+
|
488
|
+
# (see WidgetBuilder#initialize)
|
489
|
+
# @!method initialize(item: nil, label: nil, icon: nil, frequency: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
490
|
+
# @param frequency [Numeric, nil] How often to send requests (see {ColorpickerBuilder#frequency})
|
491
|
+
# @!visibility private
|
492
|
+
def initialize(type, frequency: nil, **kwargs)
|
493
|
+
super(type, **kwargs)
|
494
|
+
|
495
|
+
@frequency = frequency
|
496
|
+
end
|
497
|
+
|
498
|
+
# @!visibility private
|
499
|
+
def build
|
500
|
+
widget = super
|
501
|
+
widget.frequency = (frequency * 1000).to_i if frequency
|
502
|
+
widget
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
# Builds a `Mapview` element
|
507
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-mapview
|
508
|
+
# @see org.openhab.core.model.sitemap.sitemap.Mapview
|
509
|
+
class MapviewBuilder < DefaultBuilder
|
510
|
+
end
|
511
|
+
|
512
|
+
# Builds an `Input` element
|
513
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-input
|
514
|
+
# @see org.openhab.core.model.sitemap.sitemap.Input
|
515
|
+
class InputBuilder < WidgetBuilder
|
516
|
+
# Valid {#hint} values
|
517
|
+
VALID_HINTS = %i[text number date time datetime].freeze
|
518
|
+
|
519
|
+
# @return [:text, :number, :date, :time, :datetime, nil]
|
520
|
+
# Gives a hint to the user interface to use a widget adapted to a specific use
|
521
|
+
attr_reader :hint
|
522
|
+
|
523
|
+
# (see WidgetBuilder#initialize)
|
524
|
+
# @!method initialize(item: nil, label: nil, icon: nil, hint: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
525
|
+
# @param [:text, :number, :date, :time, :datetime, nil] hint
|
526
|
+
# Gives a hint to the user interface to use a widget adapted to a specific use (see {InputBuilder#hint})
|
527
|
+
# @!visibility private
|
528
|
+
def initialize(type, hint: nil, **kwargs)
|
529
|
+
super(type, **kwargs)
|
530
|
+
|
531
|
+
self.hint = hint
|
532
|
+
end
|
533
|
+
|
534
|
+
def hint=(value)
|
535
|
+
value = value&.to_sym
|
536
|
+
raise ArgumentError, "#{value.inspect} is not a valid hint" if value && !VALID_HINTS.include?(value)
|
537
|
+
|
538
|
+
@hint = value
|
539
|
+
end
|
540
|
+
|
541
|
+
# @!visibility private
|
542
|
+
def build
|
543
|
+
widget = super
|
544
|
+
widget.input_hint = hint&.to_s
|
545
|
+
widget
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
# Parent class for builders of widgets that can contain other widgets.
|
550
|
+
# @see org.openhab.core.model.sitemap.sitemap.LinkableWidget
|
551
|
+
class LinkableWidgetBuilder < WidgetBuilder
|
552
|
+
include Core::EntityLookup
|
553
|
+
|
554
|
+
# allow referring to items that don't exist yet
|
555
|
+
self.create_dummy_items = true
|
556
|
+
|
557
|
+
# @return [Array<WidgetBuilder>]
|
558
|
+
# @!visibility private
|
559
|
+
attr_reader :children
|
560
|
+
|
561
|
+
# @!parse
|
562
|
+
# # (see WidgetBuilder#initialize)
|
563
|
+
# # Create a new `Frame` element.
|
564
|
+
# # @yield Block executed in the context of a {FrameBuilder}
|
565
|
+
# # @return [FrameBuilder]
|
566
|
+
# # @!visibility public
|
567
|
+
# def frame(item: nil,
|
568
|
+
# label: nil,
|
569
|
+
# icon: nil,
|
570
|
+
# label_color: nil,
|
571
|
+
# value_color: nil,
|
572
|
+
# icon_color: nil,
|
573
|
+
# visibility: nil)
|
574
|
+
# end
|
575
|
+
#
|
576
|
+
# # (see WidgetBuilder#initialize)
|
577
|
+
# # Create a new `Text` element.
|
578
|
+
# # @yield Block executed in the context of a {TextBuilder}
|
579
|
+
# # @return [TextBuilder]
|
580
|
+
# # @!visibility public
|
581
|
+
# def text(item: nil,
|
582
|
+
# label: nil,
|
583
|
+
# icon: nil,
|
584
|
+
# label_color: nil,
|
585
|
+
# value_color: nil,
|
586
|
+
# icon_color: nil,
|
587
|
+
# visibility: nil)
|
588
|
+
# end
|
589
|
+
#
|
590
|
+
# # (see WidgetBuilder#initialize)
|
591
|
+
# # Create a new `Group` element.
|
592
|
+
# # @yield Block executed in the context of a {GroupBuilder}
|
593
|
+
# # @return [GroupBuilder]
|
594
|
+
# # @!visibility public
|
595
|
+
# def group(item: nil,
|
596
|
+
# label: nil,
|
597
|
+
# icon: nil,
|
598
|
+
# label_color: nil,
|
599
|
+
# value_color: nil,
|
600
|
+
# icon_color: nil,
|
601
|
+
# visibility: nil)
|
602
|
+
# end
|
603
|
+
#
|
604
|
+
# # (see ImageBuilder#initialize)
|
605
|
+
# # Create a new `Image` element.
|
606
|
+
# # @yield Block executed in the context of an {ImageBuilder}
|
607
|
+
# # @return [ImageBuilder]
|
608
|
+
# # @!visibility public
|
609
|
+
# def image(item: nil,
|
610
|
+
# label: nil,
|
611
|
+
# icon: nil,
|
612
|
+
# url: nil,
|
613
|
+
# refresh: nil,
|
614
|
+
# label_color: nil,
|
615
|
+
# value_color: nil,
|
616
|
+
# icon_color: nil,
|
617
|
+
# visibility: nil)
|
618
|
+
# end
|
619
|
+
#
|
620
|
+
# # (see VideoBuilder#initialize)
|
621
|
+
# # Create a new `Video` element.
|
622
|
+
# # @yield Block executed in the context of a {VideoBuilder}
|
623
|
+
# # @return [VideoBuilder]
|
624
|
+
# # @!visibility public
|
625
|
+
# def video(item: nil,
|
626
|
+
# label: nil,
|
627
|
+
# icon: nil,
|
628
|
+
# url: nil,
|
629
|
+
# encoding: nil,
|
630
|
+
# label_color: nil,
|
631
|
+
# value_color: nil,
|
632
|
+
# icon_color: nil,
|
633
|
+
# visibility: nil)
|
634
|
+
# end
|
635
|
+
#
|
636
|
+
# # (see ChartBuilder#initialize)
|
637
|
+
# # Create a new `Chart` element.
|
638
|
+
# # @yield Block executed in the context of a {ChartBuilder}
|
639
|
+
# # @return [ChartBuilder]
|
640
|
+
# # @!visibility public
|
641
|
+
# def chart(item: nil,
|
642
|
+
# label: nil,
|
643
|
+
# icon: nil,
|
644
|
+
# service: nil,
|
645
|
+
# refresh: nil,
|
646
|
+
# period: nil,
|
647
|
+
# legend: nil,
|
648
|
+
# group: nil,
|
649
|
+
# y_axis_pattern: nil,
|
650
|
+
# label_color: nil,
|
651
|
+
# value_color: nil,
|
652
|
+
# icon_color: nil,
|
653
|
+
# visibility: nil)
|
654
|
+
# end
|
655
|
+
#
|
656
|
+
# # (see WebviewBuilder#initialize)
|
657
|
+
# # Create a new `Webview` element.
|
658
|
+
# # @yield Block executed in the context of a {WebviewBuilder}
|
659
|
+
# # @return [WebviewBuilder]
|
660
|
+
# # @!visibility public
|
661
|
+
# def webview(item: nil,
|
662
|
+
# label: nil,
|
663
|
+
# icon: nil,
|
664
|
+
# url: nil,
|
665
|
+
# height: nil,
|
666
|
+
# label_color: nil,
|
667
|
+
# value_color: nil,
|
668
|
+
# icon_color: nil,
|
669
|
+
# visibility: nil)
|
670
|
+
# end
|
671
|
+
#
|
672
|
+
# # (see SwitchBuilder#initialize)
|
673
|
+
# # Create a new `Switch` element.
|
674
|
+
# # @yield Block executed in the context of a {SwitchBuilder}
|
675
|
+
# # @return [SwitchBuilder]
|
676
|
+
# # @!visibility public
|
677
|
+
# def switch(item: nil,
|
678
|
+
# label: nil,
|
679
|
+
# icon: nil,
|
680
|
+
# mappings: nil,
|
681
|
+
# label_color: nil,
|
682
|
+
# value_color: nil,
|
683
|
+
# icon_color: nil,
|
684
|
+
# visibility: nil)
|
685
|
+
# end
|
686
|
+
#
|
687
|
+
# # (see MapviewBuilder#initialize)
|
688
|
+
# # Create a new `Mapview` element.
|
689
|
+
# # @yield Block executed in the context of a {MapviewBuilder}
|
690
|
+
# # @return [MapviewBuilder]
|
691
|
+
# # @!visibility public
|
692
|
+
# def mapview(item: nil,
|
693
|
+
# label: nil,
|
694
|
+
# icon: nil,
|
695
|
+
# height: nil,
|
696
|
+
# label_color: nil,
|
697
|
+
# value_color: nil,
|
698
|
+
# icon_color: nil,
|
699
|
+
# visibility: nil)
|
700
|
+
# end
|
701
|
+
#
|
702
|
+
# # (see SliderBuilder#initialize)
|
703
|
+
# # Create a new `Slider` element.
|
704
|
+
# # @yield Block executed in the context of a {SliderBuilder}
|
705
|
+
# # @return [SliderBuilder]
|
706
|
+
# # @!visibility public
|
707
|
+
# def slider(item: nil,
|
708
|
+
# label: nil,
|
709
|
+
# icon: nil,
|
710
|
+
# range: nil,
|
711
|
+
# step: nil,
|
712
|
+
# switch: nil,
|
713
|
+
# frequency: nil,
|
714
|
+
# label_color: nil,
|
715
|
+
# value_color: nil,
|
716
|
+
# icon_color: nil,
|
717
|
+
# visibility: nil)
|
718
|
+
# end
|
719
|
+
#
|
720
|
+
# # (see SelectionBuilder#initialize)
|
721
|
+
# # Create a new `Selection` element.
|
722
|
+
# # @yield Block executed in the context of a {SelectionBuilder}
|
723
|
+
# # @return [SelectionBuilder]
|
724
|
+
# # @!visibility public
|
725
|
+
# def selection(item: nil,
|
726
|
+
# label: nil,
|
727
|
+
# icon: nil,
|
728
|
+
# mappings: nil,
|
729
|
+
# label_color: nil,
|
730
|
+
# value_color: nil,
|
731
|
+
# icon_color: nil,
|
732
|
+
# visibility: nil)
|
733
|
+
# end
|
734
|
+
#
|
735
|
+
# # (see InputBuilder#initialize)
|
736
|
+
# # Create a new `Input` element.
|
737
|
+
# # @yield Block executed in the context of an {InputBuilder}
|
738
|
+
# # @return [InputBuilder]
|
739
|
+
# # @since openHAB 4.0
|
740
|
+
# # @!visibility public
|
741
|
+
# def input(item: nil,
|
742
|
+
# label: nil,
|
743
|
+
# icon: nil,
|
744
|
+
# hint: nil,
|
745
|
+
# label_color: nil,
|
746
|
+
# value_color: nil,
|
747
|
+
# icon_color: nil,
|
748
|
+
# visibility: nil)
|
749
|
+
# end
|
750
|
+
#
|
751
|
+
# # (see SetpointBuilder#initialize)
|
752
|
+
# # Create a new `Setpoint` element.
|
753
|
+
# # @yield Block executed in the context of a {SetpointBuilder}
|
754
|
+
# # @return [SetpointBuilder]
|
755
|
+
# # @!visibility public
|
756
|
+
# def setpoint(item: nil,
|
757
|
+
# label: nil,
|
758
|
+
# icon: nil,
|
759
|
+
# range: nil,
|
760
|
+
# step: nil,
|
761
|
+
# label_color: nil,
|
762
|
+
# value_color: nil,
|
763
|
+
# icon_color: nil,
|
764
|
+
# visibility: nil)
|
765
|
+
# end
|
766
|
+
#
|
767
|
+
# # (see ColorpickerBuilder#initialize)
|
768
|
+
# # Create a new `Colorpicker` element.
|
769
|
+
# # @yield Block executed in the context of a {ColorpickerBuilder}
|
770
|
+
# # @return [ColorpickerBuilder]
|
771
|
+
# # @!visibility public
|
772
|
+
# def colorpicker(item: nil,
|
773
|
+
# label: nil,
|
774
|
+
# icon: nil,
|
775
|
+
# frequency: nil,
|
776
|
+
# label_color: nil,
|
777
|
+
# value_color: nil,
|
778
|
+
# icon_color: nil,
|
779
|
+
# visibility: nil)
|
780
|
+
# end
|
781
|
+
#
|
782
|
+
# # (see DefaultBuilder#initialize)
|
783
|
+
# # Create a new `Default` element.
|
784
|
+
# # @yield Block executed in the context of a {DefaultBuilder}
|
785
|
+
# # @return [DefaultBuilder]
|
786
|
+
# # @!visibility public
|
787
|
+
# def default(item: nil,
|
788
|
+
# label: nil,
|
789
|
+
# icon: nil,
|
790
|
+
# height: nil,
|
791
|
+
# label_color: nil,
|
792
|
+
# value_color: nil,
|
793
|
+
# icon_color: nil,
|
794
|
+
# visibility: nil)
|
795
|
+
# end
|
796
|
+
#
|
797
|
+
|
798
|
+
%i[frame
|
799
|
+
text
|
800
|
+
group
|
801
|
+
image
|
802
|
+
video
|
803
|
+
chart
|
804
|
+
webview
|
805
|
+
switch
|
806
|
+
mapview
|
807
|
+
slider
|
808
|
+
selection
|
809
|
+
input
|
810
|
+
setpoint
|
811
|
+
colorpicker
|
812
|
+
default].each do |method|
|
813
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
814
|
+
def #{method}(*args, **kwargs, &block) # def frame(*args, **kwargs, &block)
|
815
|
+
widget = #{method.capitalize}Builder.new(#{method.inspect}, # widget = FrameBuilder.new(:frame,
|
816
|
+
*args, # *args,
|
817
|
+
**kwargs) # **kwargs)
|
818
|
+
widget.instance_eval_with_dummy_items(&block) if block # widget.instance_eval_with_dummy_items(&block) if block
|
819
|
+
children << widget # children << widget
|
820
|
+
widget # widget
|
821
|
+
end # end
|
822
|
+
RUBY
|
823
|
+
end
|
824
|
+
|
825
|
+
# (see WidgetBuilder#initialize)
|
826
|
+
# @!method initialize(item: nil, label: nil, icon: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
827
|
+
# @!visibility private
|
828
|
+
def initialize(*, **)
|
829
|
+
super
|
830
|
+
|
831
|
+
@children = []
|
832
|
+
end
|
833
|
+
|
834
|
+
# @!visibility private
|
835
|
+
def build
|
836
|
+
widget = super
|
837
|
+
|
838
|
+
children.each do |child|
|
839
|
+
widget.children.add(child.build)
|
840
|
+
end
|
841
|
+
|
842
|
+
widget
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
846
|
+
# Builds a `Text` element
|
847
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-text
|
848
|
+
# @see org.openhab.core.model.sitemap.sitemap.Text
|
849
|
+
class TextBuilder < LinkableWidgetBuilder
|
850
|
+
end
|
851
|
+
|
852
|
+
# Builds a `Group` element
|
853
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-group
|
854
|
+
# @see org.openhab.core.model.sitemap.sitemap.Group
|
855
|
+
class GroupBuilder < LinkableWidgetBuilder
|
856
|
+
end
|
857
|
+
|
858
|
+
# Builds an `Image` element
|
859
|
+
#
|
860
|
+
# {WidgetBuilder#item item} can refer to either an
|
861
|
+
# {Core::Items::ImageItem ImageItem} whose state is the raw data of the
|
862
|
+
# image, or a {Core::Items::StringItem StringItem} whose state is a URL
|
863
|
+
# that points to an image.
|
864
|
+
#
|
865
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-image
|
866
|
+
# @see org.openhab.core.model.sitemap.sitemap.Image
|
867
|
+
class ImageBuilder < LinkableWidgetBuilder
|
868
|
+
# @return [String, nil]
|
869
|
+
# The default URL for the image, if there is no associated item, or
|
870
|
+
# if the associated item's state is not a URL
|
871
|
+
attr_accessor :url
|
872
|
+
# @return [Numeric, nil] How often to refresh the image (in seconds)
|
873
|
+
attr_accessor :refresh
|
874
|
+
|
875
|
+
# (see LinkableWidgetBuilder#initialize)
|
876
|
+
# @!method initialize(item: nil, label: nil, icon: nil, url: nil, refresh: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
|
877
|
+
# @param url [String, nil] The URL for the image (see {ImageBuilder#url})
|
878
|
+
# @param refresh [Numeric, nil] How often to refresh the image (see {ImageBuilder#refresh})
|
879
|
+
# @!visibility private
|
880
|
+
def initialize(type, url: nil, refresh: nil, **kwargs)
|
881
|
+
super(type, **kwargs)
|
882
|
+
|
883
|
+
@url = url
|
884
|
+
@refresh = refresh
|
885
|
+
end
|
886
|
+
|
887
|
+
# @!visibility private
|
888
|
+
def build
|
889
|
+
widget = super
|
890
|
+
widget.url = url
|
891
|
+
widget.refresh = (refresh * 1_000).to_i if refresh
|
892
|
+
widget
|
893
|
+
end
|
894
|
+
end
|
895
|
+
|
896
|
+
# Builds a `Frame` element
|
897
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-frame
|
898
|
+
# @see org.openhab.core.model.sitemap.sitemap.Frame
|
899
|
+
class FrameBuilder < LinkableWidgetBuilder
|
900
|
+
end
|
901
|
+
|
902
|
+
# Builds a `Sitemap`
|
903
|
+
# @see https://www.openhab.org/docs/ui/sitemaps.html
|
904
|
+
# @see org.openhab.core.model.sitemap.sitemap.Sitemap
|
905
|
+
class SitemapBuilder < LinkableWidgetBuilder
|
906
|
+
class << self
|
907
|
+
# @!visibility private
|
908
|
+
def factory
|
909
|
+
org.openhab.core.model.sitemap.sitemap.SitemapFactory.eINSTANCE
|
910
|
+
end
|
911
|
+
end
|
912
|
+
|
913
|
+
# @return [String]
|
914
|
+
attr_accessor :name
|
915
|
+
|
916
|
+
private :label_colors, :value_colors, :icon_colors, :visibilities
|
917
|
+
|
918
|
+
undef_method :item, :item=
|
919
|
+
undef_method :label_color
|
920
|
+
undef_method :value_color
|
921
|
+
undef_method :icon_color
|
922
|
+
undef_method :visibility
|
923
|
+
undef_method :method_missing, :respond_to_missing?
|
924
|
+
|
925
|
+
# @param name [String]
|
926
|
+
# @param label [String, nil]
|
927
|
+
# @param icon [String, nil]
|
928
|
+
# @!visibility private
|
929
|
+
def initialize(name, label = nil, icon: nil)
|
930
|
+
super(:sitemap, label: label, icon: icon)
|
931
|
+
|
932
|
+
@name = name
|
933
|
+
end
|
934
|
+
|
935
|
+
# @!visibility private
|
936
|
+
def build
|
937
|
+
super.tap { |sitemap| sitemap.name = name }
|
938
|
+
end
|
939
|
+
end
|
940
|
+
end
|
941
|
+
end
|
942
|
+
end
|