openhab-scripting 5.31.0 → 5.32.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: 1d1996259cb097848c88f6ed61d4d715710299a6f9ac93e4e8ccf2925b651c7e
4
- data.tar.gz: 4283efc59d3e6e0df288c79f2ab6e8220c64441f4d5bd63474b5075690c1556b
3
+ metadata.gz: c429ef46e5d646b8f63faf413faba1e687c3b02eac385044c85c863e70c9fda1
4
+ data.tar.gz: 4b8f584ce037d55980f4277e35d9ebcf3a7b2a5b1ad14dce3b2c721d453c2af6
5
5
  SHA512:
6
- metadata.gz: 3d9d5ef94c19724d7c4f58e349c41def3c538c7240a4f744c44dd15dd96692b9ffb368e4173ee43dff5f5d56a3128610a03411589d2c668d3a7418c3ad84a52e
7
- data.tar.gz: dcd5c517c8e536f25a629a32d4681ce488168c07c23739c775ea147184d640aa36c1eea3c43ffb8d228051c4d7a19e62b5fb8507c4107b4baa442315ad58ec15
6
+ metadata.gz: d2d281ff53a48073de43d5c9e60c77a3a8b3f5abdb09ece70efdd9f55fa72e3f70a30a27474e01ec671a0c2328261d36d15ad7726a0327daa071bb8f819362f3
7
+ data.tar.gz: 5f897a7f16b1d20f9acc401af93b8b15b3cc8ffe7d02e67255db53ea0d5466300689f98344c11f42d362cb09f11880b85ce41f171b9921de67abee840a6e7d12
@@ -308,7 +308,7 @@ module OpenHAB
308
308
  end
309
309
 
310
310
  # @!attribute [rw] category
311
- # The item's category.
311
+ # The item's category (icon).
312
312
  # @return [String]
313
313
  def category=(value)
314
314
  modify do
@@ -319,6 +319,8 @@ module OpenHAB
319
319
  set_category(value)
320
320
  end
321
321
  end
322
+ alias_method :icon, :category
323
+ alias_method :icon=, :category=
322
324
 
323
325
  # @!attribute [rw] tags
324
326
  # The item's tags
@@ -53,6 +53,30 @@ module OpenHAB
53
53
  super && dimension == other.dimension
54
54
  end
55
55
 
56
+ # @!attribute [r] range
57
+ # Returns the range of values allowed for this item, as defined by its
58
+ # state description.
59
+ #
60
+ # If this item has a {#unit}, it will be applied to the result, returning
61
+ # a range of {QuantityType} instead of BigDecimal.
62
+ # @return [Range, nil]
63
+ # @note State descriptions can be provided by bindings, defined in
64
+ # metadata, or theoretically come from other sources.
65
+ def range
66
+ return unless (sd = state_description)
67
+
68
+ # check if we have a unit, even if the item's metadata doesn't declare
69
+ # it properly
70
+ unit = self.unit || ((s = state) && s.is_a?(QuantityType) && s.unit)
71
+ min = sd.minimum&.to_d
72
+ max = sd.maximum&.to_d
73
+ return nil unless min || max
74
+
75
+ min |= unit if min && unit
76
+ max |= unit if max && unit
77
+ min..max
78
+ end
79
+
56
80
  protected
57
81
 
58
82
  # Adds the unit dimension
@@ -97,6 +97,35 @@ module OpenHAB
97
97
  __getobj__.members
98
98
  end
99
99
 
100
+ # Several methods can just return nil when it's a dummy item
101
+ # This helps when you're doing something like `items.locations.select {}`
102
+ # when items are getting created and removed in a concurrent thread to
103
+ # not have errors because an item disappeared
104
+ %i[
105
+ equipment
106
+ equipment?
107
+ equipment_type
108
+ location
109
+ location?
110
+ location_type
111
+ member_of?
112
+ point?
113
+ point_type
114
+ property_type
115
+ semantic?
116
+ semantic_type
117
+ tagged?
118
+ ].each do |m|
119
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
120
+ def #{m}(*args) # def equipment(*args)
121
+ target = __getobj__ # target = __getobj__
122
+ return nil if target.nil? # return nil if target.nil?
123
+ #
124
+ target.#{m}(*args) # target.equipment(*args)
125
+ end # end
126
+ RUBY
127
+ end
128
+
100
129
  # @return [String]
101
130
  def to_s
102
131
  return name if __getobj__.nil?
@@ -190,11 +190,80 @@ module OpenHAB
190
190
  # @return [[PercentType, PercentType, PercentType]]
191
191
 
192
192
  # @!attribute [r] cct
193
- # @return [QuantityType] The color temperature in Kelvin
193
+ # @return [QuantityType] The correlated color temperature in Kelvin
194
194
  # @since openHAB 4.3
195
+ # @see https://en.wikipedia.org/wiki/Planckian_locus Planckian Locus
195
196
  def cct
196
197
  ColorUtil.xy_to_kelvin(to_xy[0..1].map { |x| x.double_value / 100 }) | "K"
197
198
  end
199
+
200
+ # @!attribute [r] duv
201
+ # The distance that this color is from the planckian locus
202
+ #
203
+ # @return [Float] The delta u, v
204
+ #
205
+ # @see planckian?
206
+ # @see planckian_cct
207
+ # @see https://en.wikipedia.org/wiki/Planckian_locus Planckian Locus
208
+ # @since openHAB 4.3
209
+ def duv
210
+ ColorUtil.xy_to_duv(to_xy[0..1].map { |x| x.double_value / 100 })
211
+ end
212
+
213
+ # Checks if this color is within a certain tolerance of the planckian locus ("white")
214
+ #
215
+ # @param [Float] duv_tolerance The maximum allowed distance from the planckian locus
216
+ # @param [Numeric, PercentType] maximum_saturation The maximum allowed saturation.
217
+ # Some colors (bright green for example) may be close to the planckian locus,
218
+ # but you don't want to treat them as "white" because they are very saturated.
219
+ # @return [true, false]
220
+ #
221
+ # @note The parameters and defaults for this method are subject to change in future
222
+ # releases of this library, and should be considered beta. For now, the default
223
+ # parameters should be sufficient to detect most colors that Apple's HomeKit color
224
+ # temperature color chooser uses as planckian, without detecting most other "real"
225
+ # colors as planckian.
226
+ # @see duv
227
+ # @see planckian_cct
228
+ # @see https://en.wikipedia.org/wiki/Planckian_locus Planckian Locus
229
+ # @since openHAB 4.3
230
+ def planckian?(duv_tolerance: 0.015, maximum_saturation: 75)
231
+ duv.abs < duv_tolerance && saturation < maximum_saturation
232
+ end
233
+ alias_method :white_cct?, :planckian?
234
+
235
+ # Returns the color temperature of this color _if_ it is within a certain tolerance
236
+ # of the planckian locus ("white"), otherwise returns `nil`.
237
+ #
238
+ # @param [Range, NumberItem] range An allowed range to additionally restrict
239
+ # if the CCT should be returned. A NumberItem that represents a CCT channel
240
+ # may be provided, and {NumberItem#range NumberItem#range} will be used instead. If the range
241
+ # does not have units (is {QuantityType}), it is interpreted as being in Kelvin.
242
+ # @return [QuantityType, nil] The color temperature in Kelvin
243
+ # (unless the range is in mireds; then it will be in mireds)
244
+ #
245
+ # @note Additional parameters are forwarded to {#planckian?}
246
+ # @see planckian?
247
+ # @see https://en.wikipedia.org/wiki/Planckian_locus Planckian Locus
248
+ # @since openHAB 4.3
249
+ def planckian_cct(range: nil, **kwargs)
250
+ return unless planckian?(**kwargs)
251
+
252
+ range = range.range if range.is_a?(NumberItem)
253
+ cct = self.cct
254
+ if range
255
+ range_type = range.begin || range.end
256
+ if !range_type.is_a?(QuantityType)
257
+ range = Range.new(range.begin | "K", range.end | "K")
258
+ elsif range_type.unit == Units::MIRED
259
+ cct |= Units::MIRED
260
+ end
261
+ end
262
+ return nil if range && !range.cover?(cct)
263
+
264
+ cct
265
+ end
266
+ alias_method :white_cct, :planckian_cct
198
267
  end
199
268
  end
200
269
  end
@@ -222,6 +222,24 @@ module OpenHAB
222
222
  #
223
223
  # @return [String, nil]
224
224
  attr_accessor :format
225
+ # The valid range for a number item
226
+ # @return [Range, nil]
227
+ attr_accessor :range
228
+ # The step size for a number item
229
+ # @return [Number, nil]
230
+ attr_accessor :step
231
+ # If the item is read-only, and does not accept commands
232
+ # @return [true, false, nil]
233
+ attr_accessor :read_only
234
+ alias_method :read_only?, :read_only
235
+ # A list of valid commands
236
+ # If a hash, keys are commands, and values are labels
237
+ # @return [Hash, Array, nil]
238
+ attr_accessor :command_options
239
+ # A list of valid states
240
+ # If a hash, keys are commands, and values are labels
241
+ # @return [Hash, Array, nil]
242
+ attr_accessor :state_options
225
243
  # The icon to be associated with the item
226
244
  # @return [Symbol, String, nil]
227
245
  attr_accessor :icon
@@ -321,6 +339,11 @@ module OpenHAB
321
339
  dimension: nil,
322
340
  unit: nil,
323
341
  format: nil,
342
+ range: nil,
343
+ step: nil,
344
+ read_only: nil,
345
+ command_options: nil,
346
+ state_options: nil,
324
347
  icon: nil,
325
348
  group: nil,
326
349
  groups: nil,
@@ -358,6 +381,11 @@ module OpenHAB
358
381
  @label = label
359
382
  @dimension = dimension
360
383
  @format = format
384
+ @range = range
385
+ @step = step
386
+ @read_only = read_only
387
+ @command_options = command_options
388
+ @state_options = state_options
361
389
  self.unit = unit
362
390
  @icon = icon
363
391
  @groups = []
@@ -554,8 +582,9 @@ module OpenHAB
554
582
  def unit=(unit)
555
583
  @unit = unit
556
584
 
557
- self.dimension ||= unit && org.openhab.core.types.util.UnitUtils.parse_unit(unit)&.then do |u|
558
- org.openhab.core.types.util.UnitUtils.get_dimension_name(u)
585
+ if (openhab_unit = unit && org.openhab.core.types.util.UnitUtils.parse_unit(unit))
586
+ self.dimension ||= "Temperature" if openhab_unit == Units::MIRED
587
+ self.dimension ||= org.openhab.core.types.util.UnitUtils.get_dimension_name(openhab_unit)
559
588
  end
560
589
  self.format ||= unit && (if Gem::Version.new(Core::VERSION) >= Gem::Version.new("4.0.0.M3")
561
590
  "%s %unit%"
@@ -591,7 +620,35 @@ module OpenHAB
591
620
  end
592
621
  metadata["autoupdate"] = autoupdate.to_s unless autoupdate.nil?
593
622
  metadata["expire"] = expire if expire
594
- metadata["stateDescription"] = { "pattern" => format } if format
623
+ if format || range || step || !read_only.nil? || state_options
624
+ sd = {}
625
+ sd["pattern"] = format if format
626
+ sd["min"] = range.begin&.to_d if range&.begin
627
+ sd["max"] = range.end&.to_d if range&.end
628
+ sd["step"] = step if step
629
+ sd["readOnly"] = read_only unless read_only.nil?
630
+ if state_options
631
+ sd["options"] = if state_options.respond_to?(:to_hash)
632
+ state_options.to_hash.map { |k, v| "#{k}=#{v}" }.join(",")
633
+ elsif state_options.respond_to?(:to_ary)
634
+ state_options.to_ary.join(",")
635
+ else
636
+ state_options.to_s
637
+ end
638
+ end
639
+
640
+ metadata["stateDescription"] = sd
641
+ end
642
+ if command_options
643
+ options = if command_options.respond_to?(:to_hash)
644
+ command_options.to_hash.map { |k, v| "#{k}=#{v}" }.join(",")
645
+ elsif command_options.respond_to?(:to_ary)
646
+ command_options.to_ary.join(",")
647
+ else
648
+ command_options.to_s
649
+ end
650
+ metadata["commandDescription"] = { "options" => options }
651
+ end
595
652
  metadata["unit"] = unit if unit
596
653
  item
597
654
  end
@@ -689,6 +689,33 @@ module OpenHAB
689
689
  end
690
690
  end
691
691
 
692
+ # Builds a `Colortemperaturepicker` element
693
+ # @since openHAB 4.3
694
+ # @see org.openhab.core.model.sitemap.sitemap.Colortemperaturepicker
695
+ class ColortemperaturepickerBuilder < WidgetBuilder
696
+ # Allowed range of the value
697
+ # @return [Range, nil]
698
+ attr_accessor :range
699
+
700
+ # (see WidgetBuilder#initialize)
701
+ # @!method initialize(item: nil, label: nil, icon: nil, static_icon: nil, range: nil, label_color: nil, value_color: nil, icon_color: nil, visibility: nil)
702
+ # @param range [Range, nil] Allowed range of the value (see {ColortemperaturepickerBuilder#range})
703
+ # @!visibility private
704
+ def initialize(type, builder_proxy, range: nil, **kwargs, &block)
705
+ super(type, builder_proxy, **kwargs, &block)
706
+
707
+ @range = range
708
+ end
709
+
710
+ # @!visibility private
711
+ def build
712
+ widget = super
713
+ widget.min_value = range&.begin&.to_d
714
+ widget.max_value = range&.end&.to_d
715
+ widget
716
+ end
717
+ end
718
+
692
719
  # Builds a `Mapview` element
693
720
  # @see https://www.openhab.org/docs/ui/sitemaps.html#element-type-mapview
694
721
  # @see org.openhab.core.model.sitemap.sitemap.Mapview
@@ -1084,6 +1111,23 @@ module OpenHAB
1084
1111
  # visibility: nil)
1085
1112
  # end
1086
1113
  #
1114
+ # # (see ColortemperaturepickerBuilder#initialize)
1115
+ # # Create a new `Colortemperaturepicker` element.
1116
+ # # @since openHAB 4.3
1117
+ # # @yield Block executed in the context of a {ColortemperaturepickerBuilder}
1118
+ # # @return [ColortemperaturepickerBuilder]
1119
+ # # @!visibility public
1120
+ # def colortemperaturepicker(item: nil,
1121
+ # label: nil,
1122
+ # icon: nil,
1123
+ # static_icon: nil,
1124
+ # range: nil,
1125
+ # label_color: nil,
1126
+ # value_color: nil,
1127
+ # icon_color: nil,
1128
+ # visibility: nil)
1129
+ # end
1130
+ #
1087
1131
  # # (see DefaultBuilder#initialize)
1088
1132
  # # Create a new `Default` element.
1089
1133
  # # @yield Block executed in the context of a {DefaultBuilder}
@@ -1116,6 +1160,7 @@ module OpenHAB
1116
1160
  buttongrid
1117
1161
  setpoint
1118
1162
  colorpicker
1163
+ colortemperaturepicker
1119
1164
  default].each do |method|
1120
1165
  class_eval <<~RUBY, __FILE__, __LINE__ + 1
1121
1166
  def #{method}(*args, **kwargs, &block) # def frame(*args, **kwargs, &block)
@@ -4,6 +4,6 @@ module OpenHAB
4
4
  module DSL
5
5
  # Version of openHAB helper libraries
6
6
  # @return [String]
7
- VERSION = "5.31.0"
7
+ VERSION = "5.32.0"
8
8
  end
9
9
  end
data/lib/openhab/log.rb CHANGED
@@ -114,7 +114,7 @@ module OpenHAB
114
114
  # @!visibility private
115
115
  def top_level_file
116
116
  caller_locations.find { |caller| caller.base_label == "<main>" }
117
- .then { |caller| cleanup_path(caller.path) }
117
+ &.then { |caller| cleanup_path(caller.path) }
118
118
  end
119
119
 
120
120
  private
@@ -376,9 +376,10 @@ module OpenHAB
376
376
  return @file_logger unless (rule_uid = Thread.current[:openhab_rule_uid])
377
377
 
378
378
  rule_type = Thread.current[:openhab_rule_type]
379
+ top_level_file = Log.top_level_file&.then { |file| "#{file}." }
379
380
  full_id = "#{rule_type}:#{rule_uid}"
380
381
 
381
- self.class.rule_loggers[full_id] ||= Logger.new("#{Logger::PREFIX}.#{Log.top_level_file}.#{rule_type}.#{rule_uid
382
+ self.class.rule_loggers[full_id] ||= Logger.new("#{Logger::PREFIX}.#{top_level_file}#{rule_type}.#{rule_uid
382
383
  .gsub(/[^A-Za-z0-9_.:-]/, "")}")
383
384
  end
384
385
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "nokogiri"
4
+ require "uri"
4
5
 
5
6
  module OpenHAB
6
7
  module YARD
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.31.0
4
+ version: 5.32.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: 2024-10-03 00:00:00.000000000 Z
13
+ date: 2024-11-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -490,7 +490,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
490
490
  - !ruby/object:Gem::Version
491
491
  version: '0'
492
492
  requirements: []
493
- rubygems_version: 3.5.21
493
+ rubygems_version: 3.5.20
494
494
  signing_key:
495
495
  specification_version: 4
496
496
  summary: JRuby Helper Libraries for openHAB Scripting