openhab-scripting 5.6.0 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c8baeb1d9f83c584fd3affe173ceecd5d00fedb8547701c134cc7f1e7e8b924
4
- data.tar.gz: b202b62cba639b270e60a73c405b6de5ede001a8bd6ee4fa065363156497b396
3
+ metadata.gz: 86b3b636fb3b4c119d2ed6a5d6b81bedd731456c750d28f4e16f602d75778e7c
4
+ data.tar.gz: 673ed9dc1dfba2e38e1a57b01468c3a6d74a3a3fd0141c5bd9f51bc25d84e634
5
5
  SHA512:
6
- metadata.gz: 06a58a345353b826ca398943d50295dd54a137b42d6fb803058507f6df19e673a27cacdfdaf7f7fa445d881468122535178e0a0f4f00eaa831ebe78bb4b060de
7
- data.tar.gz: 5572ccf8e1e094d7b1eec9415e8d39b1f18b468e99d661b25f4064b1fde0d34a89d85163c4ce77b7f97b32f1532249d66cff310377e0850de0a1388f1e7f44a3
6
+ metadata.gz: 5974cf573c9fe03b1cd8df81cd312a6be70e3175c1a157d19db5dee17db2ecf8afae6619b5a3f81f91a2fce1834c7c24f7fbc7a6bf3166e60106050892d4f9ca
7
+ data.tar.gz: 9cced687ace50ae3bcab50ee9ad421e9bd34cabf5338b7d927c4415f540148bf2f8033f8e72b43814a0b8a94ad399b3119a3b3ea953a1215fbc8be3e915a77f5
@@ -23,8 +23,11 @@ module OpenHAB
23
23
  #
24
24
  def play_sound(filename, sink: nil, volume: nil)
25
25
  volume = PercentType.new(volume) unless volume.is_a?(PercentType) || volume.nil?
26
- java_send :playSound, [java.lang.String, java.lang.String, PercentType.java_class],
27
- sink, filename.to_s, volume
26
+ java_send :playSound,
27
+ [java.lang.String, java.lang.String, PercentType.java_class],
28
+ sink,
29
+ filename.to_s,
30
+ volume
28
31
  end
29
32
 
30
33
  #
@@ -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.
@@ -308,26 +308,19 @@ module OpenHAB
308
308
  raise ArgumentError, "Additional options can only be specified when creating one tag"
309
309
  end
310
310
 
311
- synonyms = Array.wrap(synonyms).map(&:to_s).map(&:strip)
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}", label, description,
321
- synonyms)
322
- Provider.instance.add(new_tag)
323
- lookup(name)
324
- else
325
- parent_is_tag = parent.respond_to?(:java_class) && parent.java_class < Tag.java_class
326
- parent = parent_is_tag ? parent.java_class : parent.to_s
327
- org.openhab.core.semantics.SemanticTags
328
- .add(name.to_s, parent, label, synonyms.join(","), description)
329
- &.then { lookup(name) }
330
- 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)
331
324
  end.compact
332
325
  end
333
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
@@ -13,7 +13,8 @@ module OpenHAB
13
13
  def_delegators :__getobj__, :class, :is_a?, :kind_of?
14
14
 
15
15
  # @!visibility private
16
- EVENTS = [Events::ThingAddedEvent::TYPE, Events::ThingUpdatedEvent::TYPE,
16
+ EVENTS = [Events::ThingAddedEvent::TYPE,
17
+ Events::ThingUpdatedEvent::TYPE,
17
18
  Events::ThingRemovedEvent::TYPE].freeze
18
19
  # @!visibility private
19
20
  UID_METHOD = :uid
@@ -144,7 +144,8 @@ module OpenHAB
144
144
  def coerce(other)
145
145
  logger.trace("Coercing #{self} as a request from #{other.class}")
146
146
  return [other, zoned_date_time] if other.respond_to?(:to_zoned_date_time)
147
- return [DateTimeType.new(other), self] if other.respond_to?(:to_time)
147
+
148
+ [DateTimeType.new(other), self] if other.respond_to?(:to_time)
148
149
  end
149
150
 
150
151
  #
@@ -28,7 +28,8 @@ module OpenHAB
28
28
  # @return [OpenClosedType] {OPEN} if {closed?}, {CLOSED} if {open?}
29
29
  def !
30
30
  return CLOSED if open?
31
- return OPEN if closed?
31
+
32
+ OPEN if closed?
32
33
  end
33
34
  end
34
35
  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
@@ -63,7 +63,7 @@ module OpenHAB
63
63
  #
64
64
  def coerce(other)
65
65
  logger.trace("Coercing #{self} as a request from #{other.class}")
66
- return [other.to_str, self] if other.respond_to?(:to_str)
66
+ [other.to_str, self] if other.respond_to?(:to_str)
67
67
  end
68
68
 
69
69
  # any method that exists on String gets forwarded to to_s
@@ -37,7 +37,8 @@ module OpenHAB
37
37
  #
38
38
  def !
39
39
  return UP if down?
40
- return DOWN if up?
40
+
41
+ DOWN if up?
41
42
  end
42
43
  end
43
44
  end
@@ -107,10 +107,11 @@ module OpenHAB
107
107
 
108
108
  # @see https://docs.ruby-lang.org/en/master/Hash.html#method-i-assoc Hash#assoc
109
109
  def assoc(key)
110
- [key, fetch(key) do
111
- # return nil directly, without storing a value to the cache
112
- return nil
113
- end]
110
+ [key,
111
+ fetch(key) do
112
+ # return nil directly, without storing a value to the cache
113
+ return nil
114
+ end]
114
115
  end
115
116
 
116
117
  # @see https://docs.ruby-lang.org/en/master/Hash.html#method-i-dig Hash#dig
@@ -64,7 +64,8 @@ module OpenHAB
64
64
  #
65
65
  def coerce(other)
66
66
  return [other.seconds, self] if other.is_a?(Numeric)
67
- return [other.to_i.seconds, self] if other.is_a?(Period)
67
+
68
+ [other.to_i.seconds, self] if other.is_a?(Period)
68
69
  end
69
70
 
70
71
  {
@@ -56,12 +56,14 @@ module OpenHAB
56
56
  return raw_parse(string, formatter) if formatter
57
57
 
58
58
  format = /(am|pm)$/i.match?(string) ? "h[:mm[:ss][.S]][ ]a" : "H[:mm[:ss][.S]]"
59
- java_send(:parse, [java.lang.CharSequence, java.time.format.DateTimeFormatter],
60
- string, java.time.format.DateTimeFormatterBuilder.new
61
- .parse_case_insensitive
62
- .parse_lenient
63
- .append_pattern(format)
64
- .to_formatter(java.util.Locale::ENGLISH))
59
+ java_send(:parse,
60
+ [java.lang.CharSequence, java.time.format.DateTimeFormatter],
61
+ string,
62
+ java.time.format.DateTimeFormatterBuilder.new
63
+ .parse_case_insensitive
64
+ .parse_lenient
65
+ .append_pattern(format)
66
+ .to_formatter(java.util.Locale::ENGLISH))
65
67
  end
66
68
  end
67
69
 
@@ -21,7 +21,8 @@ module OpenHAB
21
21
  #
22
22
  def parse(string)
23
23
  logger.trace("#{self.class}.parse #{string} (#{string.class})")
24
- java_send(:parse, [java.lang.CharSequence, java.time.format.DateTimeFormatter],
24
+ java_send(:parse,
25
+ [java.lang.CharSequence, java.time.format.DateTimeFormatter],
25
26
  string.to_s,
26
27
  java.time.format.DateTimeFormatter.ofPattern("[--]M-d"))
27
28
  end
@@ -47,7 +47,7 @@ module OpenHAB
47
47
  # @return [Array, nil]
48
48
  #
49
49
  def coerce(other)
50
- return [other.seconds, to_i.seconds] if other.is_a?(Numeric)
50
+ [other.seconds, to_i.seconds] if other.is_a?(Numeric)
51
51
  end
52
52
 
53
53
  {
@@ -190,6 +190,7 @@ module OpenHAB
190
190
  # Integer already has #|, so we have to prepend it here
191
191
  ::Integer.prepend(QuantityTypeConversion)
192
192
  ::Numeric.include(Numeric)
193
+ java.math.BigDecimal.include(QuantityTypeConversion)
193
194
  end
194
195
  end
195
196
  end
@@ -270,7 +270,9 @@ module OpenHAB
270
270
  # Homekit metadata (see {ItemBuilder#homekit})
271
271
  # @param metadata [Hash<String, Hash>] Generic metadata (see {ItemBuilder#metadata})
272
272
  # @param state [State] Initial state
273
- def initialize(type, name = nil, label = nil,
273
+ def initialize(type,
274
+ name = nil,
275
+ label = nil,
274
276
  provider:,
275
277
  dimension: nil,
276
278
  unit: nil,
@@ -70,7 +70,8 @@ module OpenHAB
70
70
  builder = BuilderDSL.new(binding || block.binding)
71
71
  builder.uid(id)
72
72
  builder.instance_exec(builder, &block)
73
- builder.guard = Guard.new(run_context: builder.caller, only_if: builder.only_if,
73
+ builder.guard = Guard.new(run_context: builder.caller,
74
+ only_if: builder.only_if,
74
75
  not_if: builder.not_if)
75
76
 
76
77
  name ||= NameInference.infer_rule_name(builder)
@@ -1075,28 +1076,50 @@ module OpenHAB
1075
1076
  #
1076
1077
  # @overload cron(second: nil, minute: nil, hour: nil, dom: nil, month: nil, dow: nil, year: nil, attach: nil)
1077
1078
  # The trigger can be created by specifying each field as keyword arguments.
1078
- # Omitted fields will default to `*` or `?` as appropriate.
1079
+ #
1080
+ # When certain fields were omitted:
1081
+ # - The more specific fields will default to `0` for `hour`, `minute`, and `second`,
1082
+ # to `MON` for `dow`, and to `1` for `dom` and `month`.
1083
+ # - The less specific fields will default to `*` or `?` as appropriate.
1079
1084
  #
1080
1085
  # Each field is optional, but at least one must be specified.
1081
1086
  #
1082
1087
  # The same rules for the standard
1083
1088
  # [cron expression](https://www.quartz-scheduler.org/documentation/quartz-2.2.2/tutorials/tutorial-lesson-06.html)
1084
1089
  # apply for each field. For example, multiple values can be separated
1085
- # with a comma within a string.
1086
- #
1087
- # @param [Integer, String, nil] second
1088
- # @param [Integer, String, nil] minute
1089
- # @param [Integer, String, nil] hour
1090
- # @param [Integer, String, nil] dom
1091
- # @param [Integer, String, nil] month
1092
- # @param [Integer, String, nil] dow
1093
- # @param [Integer, String, nil] year
1090
+ # with a comma within a string, and ranges can be specified with a dash or with
1091
+ # a Ruby Range.
1092
+ #
1093
+ # @param [Integer, String, Range, nil] second
1094
+ # @param [Integer, String, Range, nil] minute
1095
+ # @param [Integer, String, Range, nil] hour
1096
+ # @param [Integer, String, Symbol, Range, nil] dom
1097
+ # @param [Integer, String, Symbol, Range, nil] month
1098
+ # @param [Integer, String, Symbol, Range, nil] dow
1099
+ # @param [Integer, String, Range, nil] year
1094
1100
  # @param [Object] attach object to be attached to the trigger
1095
- # @example
1101
+ #
1102
+ # @example Using String values
1096
1103
  # # Run every 3 minutes on Monday to Friday
1097
1104
  # # equivalent to the cron expression "0 */3 * ? * MON-FRI *"
1098
1105
  # rule "Using cron fields" do
1099
- # cron second: 0, minute: "*/3", dow: "MON-FRI"
1106
+ # cron minute: "*/3", dow: "MON-FRI"
1107
+ # run { logger.info "Cron rule executed" }
1108
+ # end
1109
+ #
1110
+ # @example Defaults for unspecified fields
1111
+ # # Run at midnight on the first day of January, February, and March
1112
+ # # equivalent to the cron expression "0 0 0 1 JAN-MAR ? *"
1113
+ # rule "Using cron fields" do
1114
+ # cron month: "JAN-MAR"
1115
+ # run { logger.info "Cron rule executed" }
1116
+ # end
1117
+ #
1118
+ # @example Using Ruby Range values
1119
+ # # Run on the hour, every hour between 1pm and 5pm
1120
+ # # equivalent to the cron expression "0 0 13-17 ? * ? *"
1121
+ # rule "Using cron fields" do
1122
+ # cron hour: 13..17
1100
1123
  # run { logger.info "Cron rule executed" }
1101
1124
  # end
1102
1125
  #
@@ -1559,18 +1582,25 @@ module OpenHAB
1559
1582
  # @deprecated OH3.4 - OH3 config uses eventXXX vs OH4 uses `topic`, `source`, and `types`
1560
1583
  # See https://github.com/openhab/openhab-core/pull/3299
1561
1584
  trigger("core.GenericEventTrigger",
1562
- eventTopic: topic, eventSource: source, eventTypes: types, # @deprecated OH3.4
1563
- topic: topic, source: source, types: types,
1585
+ eventTopic: topic,
1586
+ eventSource: source,
1587
+ eventTypes: types, # @deprecated OH3.4
1588
+ topic: topic,
1589
+ source: source,
1590
+ types: types,
1564
1591
  attach: attach)
1565
1592
  end
1566
1593
 
1567
1594
  #
1568
- # 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
+ #
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.
1569
1599
  #
1570
- # The trigger will dynamically update any time the state of the item
1571
- # changes. If the item is {NULL} or {UNDEF}, the trigger will not run.
1600
+ # To trigger just on the time portion of the item, use {every} instead, e.g.
1601
+ # `every :day, at: MyDateTimeItem`.
1572
1602
  #
1573
- # @param [Item, String, Symbol] item The item (or it's name)
1603
+ # @param [Item, String, Symbol] item The item (or its name)
1574
1604
  # @return [void]
1575
1605
  #
1576
1606
  # @example
@@ -1831,10 +1861,11 @@ module OpenHAB
1831
1861
  types = [binding.local_variable_get(:for)].flatten
1832
1862
 
1833
1863
  WatchHandler::WatchTriggerHandlerFactory.instance # ensure it's registered
1834
- trigger(WatchHandler::WATCH_TRIGGER_MODULE_ID, path: path.to_s,
1835
- types: types.map(&:to_s),
1836
- glob: glob.to_s,
1837
- attach: attach)
1864
+ trigger(WatchHandler::WATCH_TRIGGER_MODULE_ID,
1865
+ path: path.to_s,
1866
+ types: types.map(&:to_s),
1867
+ glob: glob.to_s,
1868
+ attach: attach)
1838
1869
  end
1839
1870
 
1840
1871
  # @!endgroup
@@ -29,7 +29,7 @@ module OpenHAB
29
29
  # @param [Hash] inputs inputs from trigger
30
30
  # @return [true, false] if the conditions passed (and therefore the block was run)
31
31
  #
32
- def process(mod:, inputs:) # rubocop:disable Lint/UnusedMethodArgument - mod is unused here but required
32
+ def process(mod:, inputs:)
33
33
  logger.trace("Checking #{inputs} against condition trigger #{self}")
34
34
  unless check_value(Conditions.old_state_from(inputs), @from) &&
35
35
  check_value(Conditions.new_state_from(inputs), @to) &&