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 +4 -4
- data/lib/openhab/core/items/registry.rb +1 -1
- data/lib/openhab/core/items/semantics.rb +11 -20
- data/lib/openhab/core/provider.rb +1 -1
- data/lib/openhab/core/sitemaps/provider.rb +132 -0
- data/lib/openhab/core/types/quantity_type.rb +45 -35
- data/lib/openhab/dsl/rules/builder.rb +7 -4
- data/lib/openhab/dsl/sitemaps/builder.rb +942 -0
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/dsl.rb +5 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86b3b636fb3b4c119d2ed6a5d6b81bedd731456c750d28f4e16f602d75778e7c
|
4
|
+
data.tar.gz: 673ed9dc1dfba2e38e1a57b01468c3a6d74a3a3fd0141c5bd9f51bc25d84e634
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
#
|
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
|
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
|
-
|
315
|
-
if
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
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,
|
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
|
185
|
-
#
|
186
|
-
#
|
187
|
-
#
|
188
|
-
#
|
189
|
-
#
|
190
|
-
#
|
191
|
-
#
|
192
|
-
#
|
193
|
-
# lhs
|
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,
|
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
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
lhs
|
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,
|
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
|
-
|
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
|
-
|
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
|
1598
|
-
#
|
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
|
-
#
|
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
|
data/lib/openhab/dsl/version.rb
CHANGED
data/lib/openhab/dsl.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openhab-scripting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.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-
|
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
|