openhab-scripting 5.6.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d58174285c7861dfffd3bdb108f6d9c01af149a4f53aab9b9dd331be7f0f022
4
- data.tar.gz: 6bdb6e115927aea3396ca05be97ecb1ee9d8afc9bc493689c32f7fcd19a7e71a
3
+ metadata.gz: 86b3b636fb3b4c119d2ed6a5d6b81bedd731456c750d28f4e16f602d75778e7c
4
+ data.tar.gz: 673ed9dc1dfba2e38e1a57b01468c3a6d74a3a3fd0141c5bd9f51bc25d84e634
5
5
  SHA512:
6
- metadata.gz: 454fb750a412b8e153ce7df0320738b1f9729e1313d6d8e9aaaaa7c720c8c0cda7f704a35d78952705e7f21718551daae2c01e0dcf0b7e26c1fbfa2481d5ab6b
7
- data.tar.gz: 0a1e62ecb2bcce48a207bed5899bd0e7913492836a5c953a4b22756fa149b353ee8db229e3b5b71f48d503db1d7bfaa4f8baa94abe92469047b386ab3d438da6
6
+ metadata.gz: 5974cf573c9fe03b1cd8df81cd312a6be70e3175c1a157d19db5dee17db2ecf8afae6619b5a3f81f91a2fce1834c7c24f7fbc7a6bf3166e60106050892d4f9ca
7
+ data.tar.gz: 9cced687ace50ae3bcab50ee9ad421e9bd34cabf5338b7d927c4415f540148bf2f8033f8e72b43814a0b8a94ad399b3119a3b3ea953a1215fbc8be3e915a77f5
@@ -48,7 +48,7 @@ module OpenHAB
48
48
  # @yield Block executed in the context of a {DSL::Items::Builder}
49
49
  # @return [Object] The return value of the block.
50
50
  #
51
- # (see Items::Builder)
51
+ # @see DSL::Items::Builder
52
52
  #
53
53
  def build(preferred_provider = nil, &block)
54
54
  DSL::Items::BaseBuilderDSL.new(preferred_provider).instance_eval_with_dummy_items(&block)
@@ -262,7 +262,7 @@ module OpenHAB
262
262
  # @deprecated OH3.4 cannot add a tag
263
263
  # this not in the class << self block above because YARD doesn't figure out
264
264
  # it's a class method with the conditional
265
- if Provider.registry || org.openhab.core.semantics.SemanticTags.respond_to?(:add)
265
+ if Provider.registry
266
266
  class << self
267
267
  #
268
268
  # Adds custom semantic tags.
@@ -311,25 +311,16 @@ module OpenHAB
311
311
  synonyms = Array.wrap(synonyms).map { |s| s.to_s.strip }
312
312
 
313
313
  tags.map do |name, parent|
314
- # @deprecated OH4.0.0.M4 missing registry
315
- if Provider.registry
316
- parent = lookup(parent) unless parent.is_a?(SemanticTag)
317
- next if lookup(name)
318
- next unless parent
319
-
320
- new_tag = org.openhab.core.semantics.SemanticTagImpl.new("#{parent.uid}_#{name}",
321
- label,
322
- description,
323
- synonyms)
324
- Provider.instance.add(new_tag)
325
- lookup(name)
326
- else
327
- parent_is_tag = parent.respond_to?(:java_class) && parent.java_class < Tag.java_class
328
- parent = parent_is_tag ? parent.java_class : parent.to_s
329
- org.openhab.core.semantics.SemanticTags
330
- .add(name.to_s, parent, label, synonyms.join(","), description)
331
- &.then { lookup(name) }
332
- end
314
+ parent = lookup(parent) unless parent.is_a?(SemanticTag)
315
+ next if lookup(name)
316
+ next unless parent
317
+
318
+ new_tag = org.openhab.core.semantics.SemanticTagImpl.new("#{parent.uid}_#{name}",
319
+ label,
320
+ description,
321
+ synonyms)
322
+ Provider.instance.add(new_tag)
323
+ lookup(name)
333
324
  end.compact
334
325
  end
335
326
  end
@@ -44,6 +44,7 @@ module OpenHAB
44
44
 
45
45
  # Known supported provider types
46
46
  # @return [Array<Symbol>]
47
+ # @!visibility private
47
48
  KNOWN_TYPES = %i[items metadata things links].freeze
48
49
 
49
50
  class << self
@@ -223,7 +224,6 @@ module OpenHAB
223
224
  def initialize(unload_priority: nil)
224
225
  super()
225
226
  @elements = java.util.concurrent.ConcurrentHashMap.new
226
- # @deprecated OH3.4 safe navigation only required for missing Semantics registry
227
227
  self.class.registry&.add_provider(self)
228
228
  ScriptHandling.script_unloaded(priority: unload_priority) { unregister }
229
229
  end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "singleton"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ #
8
+ # Contains sitemap related classes.
9
+ #
10
+ module Sitemaps
11
+ #
12
+ # Provides sitemaps created in Ruby to openHAB
13
+ #
14
+ class Provider < Core::Provider
15
+ PREFIX = "jruby_"
16
+ SUFFIX = ".sitemap"
17
+ private_constant :PREFIX, :SUFFIX
18
+
19
+ class << self
20
+ # @!visibility private
21
+ def registry
22
+ nil
23
+ end
24
+ end
25
+
26
+ include org.openhab.core.model.sitemap.SitemapProvider
27
+
28
+ # @!visibility private
29
+ alias_method :getSitemap, :get
30
+
31
+ # rubocop:disable Naming/MethodName
32
+
33
+ # @!visibility private
34
+ def getSitemapNames
35
+ @elements.key_set
36
+ end
37
+
38
+ # @!visibility private
39
+ def addModelChangeListener(listener)
40
+ @listeners.add(listener)
41
+ end
42
+
43
+ # @!visibility private
44
+ def removeModelChangeListener(listener)
45
+ @listeners.remove(listener)
46
+ end
47
+
48
+ # rubocop:enable Naming/MethodName
49
+
50
+ # @!visibility private
51
+ def unregister
52
+ @registration.unregister
53
+ end
54
+
55
+ # rubocop:disable Layout/LineLength
56
+
57
+ #
58
+ # Enter the Sitemap Builder DSL.
59
+ #
60
+ # @yield Block executed in the context of a {DSL::Sitemaps::Builder}
61
+ # @return [void]
62
+ #
63
+ # @see DSL::Sitemaps::Builder
64
+ #
65
+ # @example
66
+ # sitemaps.build do
67
+ # sitemap "default", "My Residence" do
68
+ # frame label: "Control" do
69
+ # text label: "Climate", icon: "if:mdi:home-thermometer-outline" do
70
+ # frame label: "Main Floor" do
71
+ # text item: MainFloor_AmbTemp
72
+ # switch item: MainFloorThermostat_TargetMode, label: "Mode", mappings: %w[off auto cool heat]
73
+ # setpoint item: MainFloorThermostate_SetPoint, label: "Set Point", visibility: "MainFloorThermostat_TargetMode!=off"
74
+ # end
75
+ # frame label: "Basement" do
76
+ # text item: Basement_AmbTemp
77
+ # switch item: BasementThermostat_TargetMode, label: "Mode", mappings: { OFF: "off", COOL: "cool", HEAT: "heat" }
78
+ # setpoint item: BasementThermostate_SetPoint, label: "Set Point", visibility: "BasementThermostat_TargetMode!=off"
79
+ # end
80
+ # end
81
+ # end
82
+ # end
83
+ # end
84
+ #
85
+ def build(&block)
86
+ DSL::Sitemaps::Builder.new(self).instance_eval(&block)
87
+ end
88
+ # rubocop:enable Layout/LineLength
89
+
90
+ # For use in specs
91
+ # @!visibility private
92
+ def clear
93
+ elements = @elements
94
+ @elements = java.util.concurrent.ConcurrentHashMap.new
95
+ elements.each_value do |v|
96
+ notify_listeners_about_removed_element(v)
97
+ end
98
+ end
99
+
100
+ #
101
+ # Remove a sitemap.
102
+ #
103
+ # @param [String] sitemap_name
104
+ # @return [Boolean] If a sitemap was removed
105
+ def remove(sitemap_name)
106
+ super("#{PREFIX}#{sitemap_name}#{SUFFIX}")
107
+ end
108
+
109
+ private
110
+
111
+ def initialize
112
+ super
113
+ @listeners = java.util.concurrent.CopyOnWriteArraySet.new
114
+
115
+ @registration = OSGi.register_service(self, org.openhab.core.model.sitemap.SitemapProvider)
116
+ end
117
+
118
+ def notify_listeners_about_added_element(element)
119
+ @listeners.each { |l| l.model_changed(element.name, org.openhab.core.model.core.EventType::ADDED) }
120
+ end
121
+
122
+ def notify_listeners_about_removed_element(element)
123
+ @listeners.each { |l| l.model_changed(element.name, org.openhab.core.model.core.EventType::REMOVED) }
124
+ end
125
+
126
+ def notify_listeners_about_updated_element(element)
127
+ @listeners.each { |l| l.model_changed(element.name, org.openhab.core.model.core.EventType::MODIFIED) }
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -174,25 +174,30 @@ module OpenHAB
174
174
  add: :+,
175
175
  subtract: :-
176
176
  }.each do |java_op, ruby_op|
177
- convert = "self.class.new(other, DSL.unit(dimension) || unit)"
177
+ convert = "self.class.new(other, thread_unit)"
178
178
 
179
179
  class_eval( # rubocop:disable Style/DocumentDynamicEvalDefinition https://github.com/rubocop/rubocop/issues/10179
180
180
  # def +(other)
181
181
  # logger.trace("#{self} + #{other} (#{other.class})")
182
182
  # if other.is_a?(QuantityType)
183
183
  # add_quantity(other)
184
- # elsif other.is_a?(DecimalType)
185
- # other = other.to_big_decimal
186
- # add_quantity(self.class.new(other, DSL.unit(dimension) || unit))
187
- # elsif other.is_a?(java.math.BigDecimal)
188
- # add_quantity(self.class.new(other, DSL.unit(dimension) || unit))
189
- # elsif other.respond_to?(:to_d)
190
- # other = other.to_d.to_java
191
- # add_quantity(self.class.new(other, DSL.unit(dimension) || unit))
192
- # elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
193
- # lhs + rhs
184
+ # elsif (thread_unit = DSL.unit(dimension))
185
+ # if other.is_a?(DecimalType)
186
+ # other = other.to_big_decimal
187
+ # add_quantity(self.class.new(other, thread_unit))
188
+ # elsif other.is_a?(java.math.BigDecimal)
189
+ # add_quantity(self.class.new(other, thread_unit))
190
+ # elsif other.respond_to?(:to_d)
191
+ # other = other.to_d.to_java
192
+ # add_quantity(self.class.new(other, thread_unit))
193
+ # elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
194
+ # lhs + rhs
195
+ # else
196
+ # raise TypeError, "#{other.class} can't be coerced into #{self.class}"
197
+ # end
194
198
  # else
195
- # raise TypeError, "#{other.class} can't be coerced into #{self.class}"
199
+ # raise TypeError,
200
+ # "#{self.class} can only be added with another #{self.class} outside a unit block"
196
201
  # end
197
202
  # end
198
203
  <<~RUBY, __FILE__, __LINE__ + 1
@@ -200,18 +205,23 @@ module OpenHAB
200
205
  logger.trace("\#{self} #{ruby_op} \#{other} (\#{other.class})")
201
206
  if other.is_a?(QuantityType)
202
207
  #{java_op}_quantity(other)
203
- elsif other.is_a?(DecimalType)
204
- other = other.to_big_decimal
205
- #{java_op}_quantity(#{convert})
206
- elsif other.is_a?(java.math.BigDecimal)
207
- #{java_op}_quantity(#{convert})
208
- elsif other.respond_to?(:to_d)
209
- other = other.to_d.to_java
210
- #{java_op}_quantity(#{convert})
211
- elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
212
- lhs #{ruby_op} rhs
208
+ elsif (thread_unit = DSL.unit(dimension))
209
+ if other.is_a?(DecimalType)
210
+ other = other.to_big_decimal
211
+ #{java_op}_quantity(#{convert})
212
+ elsif other.is_a?(java.math.BigDecimal)
213
+ #{java_op}_quantity(#{convert})
214
+ elsif other.respond_to?(:to_d)
215
+ other = other.to_d.to_java
216
+ #{java_op}_quantity(#{convert})
217
+ elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
218
+ lhs #{ruby_op} rhs
219
+ else
220
+ raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
221
+ end
213
222
  else
214
- raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
223
+ raise TypeError,
224
+ "\#{self.class} can only be #{java_op}ed with another \#{self.class} outside a unit block"
215
225
  end
216
226
  end
217
227
  RUBY
@@ -243,13 +253,13 @@ module OpenHAB
243
253
  def #{ruby_op}(other)
244
254
  logger.trace("\#{self} #{ruby_op} \#{other} (\#{other.class})")
245
255
  if other.is_a?(QuantityType)
246
- #{java_op}_quantity(other)
256
+ #{java_op}_quantity(other).unitize
247
257
  elsif other.is_a?(DecimalType)
248
- #{java_op}(other.to_big_decimal)
258
+ #{java_op}(other.to_big_decimal).unitize
249
259
  elsif other.is_a?(java.math.BigDecimal)
250
- #{java_op}(other)
260
+ #{java_op}(other).unitize
251
261
  elsif other.respond_to?(:to_d)
252
- #{java_op}(other.to_d.to_java)
262
+ #{java_op}(other.to_d.to_java).unitize
253
263
  elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
254
264
  lhs #{ruby_op} rhs
255
265
  else
@@ -262,7 +272,7 @@ module OpenHAB
262
272
 
263
273
  # if it's a dimensionless quantity, change the unit to match other_unit
264
274
  # @!visibility private
265
- def unitize(other_unit = unit)
275
+ def unitize(other_unit = unit, relative: false)
266
276
  # prefer converting to the thread-specified unit if there is one
267
277
  other_unit = DSL.unit(dimension) || other_unit
268
278
  logger.trace("Converting #{self} to #{other_unit}")
@@ -273,7 +283,7 @@ module OpenHAB
273
283
  when other_unit
274
284
  self
275
285
  else
276
- to_unit(other_unit)
286
+ relative ? to_unit_relative(other_unit) : to_unit(other_unit)
277
287
  end
278
288
  end
279
289
 
@@ -288,16 +298,16 @@ module OpenHAB
288
298
 
289
299
  private
290
300
 
291
- # do addition directly against a QuantityType while ensuring we unitize
292
- # both sides
301
+ # do addition directly against a QuantityType while ensuring we unitize both sides
293
302
  def add_quantity(other)
294
- unitize(other.unit).add(other.unitize(unit))
303
+ self_unit = (unit == Units::ONE && DSL.unit(other.dimension)) || unit
304
+ unitize(self_unit).add(other.unitize(relative: true))
295
305
  end
296
306
 
297
- # do subtraction directly against a QuantityType while ensuring we
298
- # unitize both sides
307
+ # do subtraction directly against a QuantityType while ensuring we unitize both sides
299
308
  def subtract_quantity(other)
300
- unitize(other.unit).subtract(other.unitize(unit))
309
+ self_unit = (unit == Units::ONE && DSL.unit(other.dimension)) || unit
310
+ unitize(self_unit).subtract(other.unitize(relative: true))
301
311
  end
302
312
 
303
313
  # do multiplication directly against a QuantityType while ensuring
@@ -1592,12 +1592,15 @@ module OpenHAB
1592
1592
  end
1593
1593
 
1594
1594
  #
1595
- # Creates a trigger based on the time stored in a {DateTimeItem}
1595
+ # Creates a trigger based on the date and time stored in a {DateTimeItem}
1596
1596
  #
1597
- # The trigger will dynamically update any time the state of the item
1598
- # changes. If the item is {NULL} or {UNDEF}, the trigger will not run.
1597
+ # The trigger will dynamically update whenever the state of the item changes.
1598
+ # If the item is {NULL} or {UNDEF}, the trigger will not run.
1599
1599
  #
1600
- # @param [Item, String, Symbol] item The item (or it's name)
1600
+ # To trigger just on the time portion of the item, use {every} instead, e.g.
1601
+ # `every :day, at: MyDateTimeItem`.
1602
+ #
1603
+ # @param [Item, String, Symbol] item The item (or its name)
1601
1604
  # @return [void]
1602
1605
  #
1603
1606
  # @example
@@ -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
@@ -4,6 +4,6 @@ module OpenHAB
4
4
  module DSL
5
5
  # Version of openHAB helper libraries
6
6
  # @return [String]
7
- VERSION = "5.6.1"
7
+ VERSION = "5.7.0"
8
8
  end
9
9
  end
data/lib/openhab/dsl.rb CHANGED
@@ -214,6 +214,11 @@ module OpenHAB
214
214
  Core::Items::Registry.instance
215
215
  end
216
216
 
217
+ # @return [Core::Sitemaps::Provider]
218
+ def sitemaps
219
+ Core::Sitemaps::Provider.instance
220
+ end
221
+
217
222
  #
218
223
  # Get all things known to openHAB
219
224
  #
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openhab-scripting
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.6.1
4
+ version: 5.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian O'Connell
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-09-12 00:00:00.000000000 Z
13
+ date: 2023-09-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -442,6 +442,7 @@ files:
442
442
  - lib/openhab/core/rules/rule.rb
443
443
  - lib/openhab/core/rules/tagged_array.rb
444
444
  - lib/openhab/core/script_handling.rb
445
+ - lib/openhab/core/sitemaps/provider.rb
445
446
  - lib/openhab/core/things.rb
446
447
  - lib/openhab/core/things/channel.rb
447
448
  - lib/openhab/core/things/channel_uid.rb
@@ -530,6 +531,7 @@ files:
530
531
  - lib/openhab/dsl/rules/triggers/trigger.rb
531
532
  - lib/openhab/dsl/rules/triggers/updated.rb
532
533
  - lib/openhab/dsl/rules/triggers/watch/watch_handler.rb
534
+ - lib/openhab/dsl/sitemaps/builder.rb
533
535
  - lib/openhab/dsl/things/builder.rb
534
536
  - lib/openhab/dsl/thread_local.rb
535
537
  - lib/openhab/dsl/timer_manager.rb