openhab-scripting 5.31.0 → 5.32.0

Sign up to get free protection for your applications and to get access to all the features.
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