openhab-scripting 5.25.0 → 5.27.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: 5dd540981ebe38c1c9caa47519ef602482ae3f3f9fb9bdfce0c9f7f82e8354e7
4
- data.tar.gz: f41c35b263ae2806eb7bd0e5c921cf77992c772165b3dd772515f6208682b20e
3
+ metadata.gz: 59deb6289921c0c6d35579783efbb35f75ceac9ff24922e0f74d6652ef575b59
4
+ data.tar.gz: 260ee0993a3ab89775d9b5a2e8f3e40f295dd16ad8f0adf3b003b521cb08a12e
5
5
  SHA512:
6
- metadata.gz: 15c663deb2da069fb03179638b89d7df1068c5dd1f7b16312dce90c81d97a8b949c6b60208855ea2b7c4ec6210aa2dca57ec7a29dc8ddc5abb3cc4ffe7ac4572
7
- data.tar.gz: 67043ce7f88d1c5cacb92f2cb172b7faaeb376d0ad2258901b603e61241e70732f41f5c2abcc05880daac2446fe9031f298112910c29bb69ffbdf81e18c760bc
6
+ metadata.gz: 127b6e33961395b973b8aa543940502530101f30e15526aa598b574e8d3a05ec82c65d79fd0d0d6176a2aa57aed8f244fbd480c76457e3440f94503f92028530
7
+ data.tar.gz: 4949521fcc45fdb1dba17a09c960d4a5e7afd2c964328a9fd8b66b11ac2c773c7e413e6ec2d797f9e6d9f8e9130297c9700af4d46bf968ec064b0dfa2ea6eb32
@@ -47,7 +47,15 @@ module OpenHAB
47
47
  def format_type(command)
48
48
  return command if command.is_a?(Types::DateTimeType)
49
49
  return Types::DateTimeType.new(command.to_zoned_date_time) if command.respond_to?(:to_zoned_date_time)
50
- return Types::DateTimeType.new(DSL.try_parse_time_like(command.to_str)) if command.respond_to?(:to_str)
50
+
51
+ if command.respond_to?(:to_str)
52
+ command = command.to_str
53
+ begin
54
+ return Types::DateTimeType.new(DSL.try_parse_time_like(command))
55
+ rescue ArgumentError
56
+ return Types::DateTimeType.new(command)
57
+ end
58
+ end
51
59
 
52
60
  super
53
61
  end
@@ -176,6 +176,31 @@ module OpenHAB
176
176
  # @return [DecimalType, QuantityType, nil] The standard deviation between `start` and `finish`,
177
177
  # or nil if no states could be found.
178
178
 
179
+ # @!method median_since(timestamp, service = nil)
180
+ # Returns the median of the item's state since the given time
181
+ # @param [#to_zoned_date_time] timestamp The point in time from which to search
182
+ # @param [Symbol, String] service An optional persistence id instead of the default persistence service.
183
+ # @return [DecimalType, QuantityType, nil] The median since `timestamp`,
184
+ # or nil if no previous states could be found.
185
+ # @since openHAB 4.3
186
+
187
+ # @!method median_until(timestamp, service = nil)
188
+ # Returns the median of the item's state beetween now until the given time
189
+ # @param [#to_zoned_date_time] timestamp The point in time until which to search
190
+ # @param [Symbol, String] service An optional persistence id instead of the default persistence service.
191
+ # @return [DecimalType, QuantityType, nil] The median until `timestamp`,
192
+ # or nil if no future states could be found.
193
+ # @since openHAB 4.3
194
+
195
+ # @!method median_between(start, finish, service = nil)
196
+ # Returns the median of the item's state between two points in time
197
+ # @param [#to_zoned_date_time] start The point in time from which to search
198
+ # @param [#to_zoned_date_time] finish The point in time to which to search
199
+ # @param [Symbol, String] service An optional persistence id instead of the default persistence service.
200
+ # @return [DecimalType, QuantityType, nil] The median between `start` and `finish`,
201
+ # or nil if no states could be found.
202
+ # @since openHAB 4.3
203
+
179
204
  # @!method sum_since(timestamp, service = nil)
180
205
  # Returns the sum of the item's state since the given time
181
206
  # @param [#to_zoned_date_time] timestamp The point in time from which to search
@@ -661,6 +686,7 @@ module OpenHAB
661
686
  end
662
687
 
663
688
  def_persistence_methods(:average, quantify: true)
689
+ def_persistence_methods(:median, quantify: true) if OpenHAB::Core.version >= OpenHAB::Core::V4_3
664
690
  def_persistence_methods(:delta, quantify: true)
665
691
  def_persistence_methods(:deviation, quantify: true)
666
692
  def_persistence_methods(:sum, quantify: true)
@@ -97,6 +97,13 @@ module OpenHAB
97
97
  __getobj__.members
98
98
  end
99
99
 
100
+ # @return [String]
101
+ def to_s
102
+ return name if __getobj__.nil?
103
+
104
+ __getobj__.to_s
105
+ end
106
+
100
107
  # @return [String]
101
108
  def inspect
102
109
  return super unless __getobj__.nil?
@@ -12,9 +12,8 @@ module OpenHAB
12
12
  # Provides sitemaps created in Ruby to openHAB
13
13
  #
14
14
  class Provider < Core::Provider
15
- PREFIX = "jruby_"
16
15
  SUFFIX = ".sitemap"
17
- private_constant :PREFIX, :SUFFIX
16
+ private_constant :SUFFIX
18
17
 
19
18
  class << self
20
19
  # @!visibility private
@@ -49,6 +48,7 @@ module OpenHAB
49
48
 
50
49
  # @!visibility private
51
50
  def unregister
51
+ clear
52
52
  @registration.unregister
53
53
  end
54
54
 
@@ -150,13 +150,30 @@ module OpenHAB
150
150
  end
151
151
  end
152
152
 
153
+ #
154
+ # Notify listeners about updated sitemap
155
+ #
156
+ # @param [String, org.openhab.core.model.sitemap.sitemap.Sitemap] sitemap The sitemap to update.
157
+ # @return [void]
158
+ #
159
+ def update(sitemap)
160
+ if sitemap.respond_to?(:to_str)
161
+ sitemap = get(sitemap).tap do |obj|
162
+ raise ArgumentError, "Sitemap #{sitemap} not found" unless obj
163
+ end
164
+ end
165
+ super
166
+ end
167
+
153
168
  #
154
169
  # Remove a sitemap.
155
170
  #
156
- # @param [String] sitemap_name
171
+ # @param [String, org.openhab.core.model.sitemap.sitemap.Sitemap] sitemap
157
172
  # @return [Boolean] If a sitemap was removed
158
- def remove(sitemap_name)
159
- super("#{PREFIX}#{sitemap_name}#{SUFFIX}")
173
+ #
174
+ def remove(sitemap)
175
+ sitemap = sitemap.uid if sitemap.respond_to?(:uid)
176
+ super
160
177
  end
161
178
 
162
179
  private
@@ -169,15 +186,24 @@ module OpenHAB
169
186
  end
170
187
 
171
188
  def notify_listeners_about_added_element(element)
172
- @listeners.each { |l| l.model_changed(element.name, org.openhab.core.model.core.EventType::ADDED) }
189
+ model_name = "#{element.name}#{SUFFIX}"
190
+ @listeners.each do |l|
191
+ l.modelChanged(model_name, org.openhab.core.model.core.EventType::ADDED)
192
+ # Ensure that when a script is reloaded, the sitemap is updated.
193
+ # This is because our listener, org.openhab.core.io.rest.sitemap.SitemapSubscriptionService
194
+ # only handles MODIFIED events in its modelChanged() method.
195
+ l.modelChanged(model_name, org.openhab.core.model.core.EventType::MODIFIED)
196
+ end
173
197
  end
174
198
 
175
199
  def notify_listeners_about_removed_element(element)
176
- @listeners.each { |l| l.model_changed(element.name, org.openhab.core.model.core.EventType::REMOVED) }
200
+ model_name = "#{element.name}#{SUFFIX}"
201
+ @listeners.each { |l| l.modelChanged(model_name, org.openhab.core.model.core.EventType::REMOVED) }
177
202
  end
178
203
 
179
204
  def notify_listeners_about_updated_element(_old_element, element)
180
- @listeners.each { |l| l.model_changed(element.name, org.openhab.core.model.core.EventType::MODIFIED) }
205
+ model_name = "#{element.name}#{SUFFIX}"
206
+ @listeners.each { |l| l.modelChanged(model_name, org.openhab.core.model.core.EventType::MODIFIED) }
181
207
  end
182
208
  end
183
209
  end
@@ -30,6 +30,14 @@ module OpenHAB
30
30
  # # replace ':' with '_' in thing uid
31
31
  # mqtt_broker_mosquitto.online? # is mqtt:broker:mosquitto thing online?
32
32
  #
33
+ # @!attribute label
34
+ # Return the thing label
35
+ # @return [String]
36
+ #
37
+ # @!attribute location
38
+ # Return the thing location
39
+ # @return [String]
40
+ #
33
41
  # @!attribute [r] status
34
42
  # Return the {https://www.openhab.org/docs/concepts/things.html#thing-status thing status}
35
43
  # @return [org.openhab.core.thing.ThingStatus]
@@ -43,7 +51,7 @@ module OpenHAB
43
51
  #
44
52
  # @!attribute [r] bridge_uid
45
53
  # Return the Bridge UID when available.
46
- # @return [ThingUID]
54
+ # @return [ThingUID, nil]
47
55
  #
48
56
  # @!attribute [r] thing_type_uid
49
57
  # @return [ThingTypeUID]
@@ -18,7 +18,13 @@ module OpenHAB
18
18
  remove_method :==
19
19
 
20
20
  extend Forwardable
21
- include Comparable
21
+
22
+ # @deprecated OH 4.2 DateTimeType implements Java's Comparable interface in openHAB 4.3
23
+ if OpenHAB::Core.version >= OpenHAB::Core::V4_3
24
+ include ComparableType
25
+ else
26
+ include Comparable
27
+ end
22
28
 
23
29
  #
24
30
  # Regex expression to identify strings defining a time in hours, minutes and optionally seconds
data/lib/openhab/core.rb CHANGED
@@ -13,6 +13,8 @@ module OpenHAB
13
13
  V4_1 = Gem::Version.new("4.1.0").freeze
14
14
  # @!visibility private
15
15
  V4_2 = Gem::Version.new("4.2.0").freeze
16
+ # @!visibility private
17
+ V4_3 = Gem::Version.new("4.3.0").freeze
16
18
 
17
19
  # @return [Gem::Version] Returns the current openHAB version as a Gem::Version object
18
20
  # Note, this strips off snapshots, milestones and RC versions and returns the release version.
@@ -1302,6 +1302,10 @@ module OpenHAB
1302
1302
  # If `value` is `:day`, `at` can be a {Core::Items::DateTimeItem DateTimeItem}, and
1303
1303
  # the trigger will run every day at the (time only portion of) current state of the
1304
1304
  # item. If the item is {NULL} or {UNDEF}, the trigger will not run.
1305
+ # @param [Duration, Integer, nil] offset Offset the execution time from the time specified in the item.
1306
+ # This can be a negative value to execute the rule before the time specified in the item.
1307
+ # A Duration will be converted to its total length in seconds, with any excess precision information dropped.
1308
+ # @since openHAB 4.3
1305
1309
  # @param [Object] attach Object to be attached to the trigger
1306
1310
  # @return [void]
1307
1311
  #
@@ -1322,12 +1326,6 @@ module OpenHAB
1322
1326
  # run { Light.on }
1323
1327
  # end
1324
1328
  #
1325
- # @example Trigger at the time portion of a DateTime Item
1326
- # rule "Every day at sunset" do
1327
- # every :day, at: Sunset_Time
1328
- # run { logger.info "It's getting dark" }
1329
- # end
1330
- #
1331
1329
  # @example Specific day of the week
1332
1330
  # rule "Weekly" do
1333
1331
  # every :monday, at: '5:15'
@@ -1372,8 +1370,21 @@ module OpenHAB
1372
1370
  # run { logger.info "It's the weekend!" }
1373
1371
  # end
1374
1372
  #
1375
- def every(*values, at: nil, attach: nil)
1373
+ # @example Trigger at the time portion of a DateTime Item
1374
+ # rule "Every day at sunset" do
1375
+ # every :day, at: Sunset_Time
1376
+ # run { logger.info "It's sunset!" }
1377
+ # end
1378
+ #
1379
+ # @example Using DateTime trigger with offset
1380
+ # rule "Every day before sunset" do
1381
+ # every :day, at: Sunset_Time, offset: -20.minutes
1382
+ # run { logger.info "It's almost sunset!" }
1383
+ # end
1384
+ #
1385
+ def every(*values, at: nil, offset: nil, attach: nil)
1376
1386
  raise ArgumentError, "Missing values" if values.empty?
1387
+ raise ArgumentError, "Offset can only be used when 'at' is given a DateTimeItem" if offset && !at.is_a?(Item)
1377
1388
 
1378
1389
  if Cron.all_dow_symbols?(values)
1379
1390
  @ruby_triggers << [:every, values.join(", "), { at: at }]
@@ -1397,7 +1408,10 @@ module OpenHAB
1397
1408
  raise ArgumentError, "Attachments are not supported with dynamic datetime triggers in openHAB 3.x"
1398
1409
  end
1399
1410
 
1400
- return trigger("timer.DateTimeTrigger", itemName: at.name, timeOnly: true, attach: attach)
1411
+ offset ||= 0
1412
+ offset = offset.to_i # Duration#to_i converts it to seconds, but we also want to convert float/string to int
1413
+ @ruby_triggers.last[2][:offset] = offset
1414
+ return trigger("timer.DateTimeTrigger", itemName: at.name, timeOnly: true, offset: offset, attach: attach)
1401
1415
  end
1402
1416
 
1403
1417
  cron_expression = case value
@@ -1797,6 +1811,10 @@ module OpenHAB
1797
1811
  # The `event` passed to run blocks will be a {Core::Events::TimerEvent}.
1798
1812
  #
1799
1813
  # @param [Item, String, Symbol] item The item (or its name)
1814
+ # @param [Duration, Integer, nil] offset Offset the execution time from the time specified in the item.
1815
+ # This can be a negative value to execute the rule before the time specified in the item.
1816
+ # A Duration will be converted to its total length in seconds, with any excess precision information dropped.
1817
+ # @since openHAB 4.3
1800
1818
  # @return [void]
1801
1819
  #
1802
1820
  # @see every
@@ -1817,9 +1835,18 @@ module OpenHAB
1817
1835
  # end
1818
1836
  # end
1819
1837
  #
1820
- def at(item)
1838
+ # @example Using an offset
1839
+ # rule "Turn on lights 15 minutes before sunset" do
1840
+ # at Sunset_Time, offset: -15.minutes
1841
+ # run { Lights.on }
1842
+ # end
1843
+ #
1844
+ def at(item, offset: nil)
1821
1845
  item = item.name if item.is_a?(Item)
1822
- trigger("timer.DateTimeTrigger", itemName: item.to_s)
1846
+ offset ||= 0
1847
+ offset = offset.to_i if offset.is_a?(Duration)
1848
+ @ruby_triggers << [:at, item, { offset: offset }]
1849
+ trigger("timer.DateTimeTrigger", itemName: item.to_s, offset: offset)
1823
1850
  end
1824
1851
 
1825
1852
  #
@@ -8,21 +8,6 @@ module OpenHAB
8
8
  # Contains helper methods for inferring a rule name from its triggers
9
9
  # @!visibility private
10
10
  module NameInference
11
- # Trigger Type UIDs that we know how to generate a name for
12
- KNOWN_TRIGGER_TYPES = [
13
- "core.ChannelEventTrigger",
14
- "core.GenericEventTrigger",
15
- "core.GroupCommandTrigger",
16
- "core.GroupStateChangeTrigger",
17
- "core.GroupStateUpdateTrigger",
18
- "core.ItemCommandTrigger",
19
- "core.ItemStateChangeTrigger",
20
- "core.ItemStateUpdateTrigger",
21
- "core.SystemStartlevelTrigger",
22
- Triggers::Cron::CRON_TRIGGER_MODULE_ID
23
- ].freeze
24
- private_constant :KNOWN_TRIGGER_TYPES
25
-
26
11
  class << self
27
12
  # get the block's source location, and simplify to a simple filename
28
13
  def infer_rule_id_from_block(block)
@@ -33,24 +18,14 @@ module OpenHAB
33
18
 
34
19
  # formulate a readable rule name such as "TestSwitch received command ON" if possible
35
20
  def infer_rule_name(config)
36
- known_triggers, unknown_triggers = config.triggers.partition do |t|
37
- KNOWN_TRIGGER_TYPES.include?(t.type_uid)
38
- end
39
- return nil unless unknown_triggers.empty?
40
-
41
- cron_triggers = known_triggers.select { |t| t.type_uid == "jsr223.jruby.CronTrigger" }
42
- ruby_every_triggers = config.ruby_triggers.select { |t| t.first == :every }
43
-
44
- # makes sure there aren't any true cron triggers cause we can't format them
45
- return nil unless cron_triggers.length == ruby_every_triggers.length
46
- return nil unless config.ruby_triggers.length == 1
47
-
48
- infer_rule_name_from_trigger(*config.ruby_triggers.first)
21
+ infer_rule_name_from_trigger(*config.ruby_triggers.first) if config.ruby_triggers.length == 1
49
22
  end
50
23
 
51
24
  # formulate a readable rule name from a single trigger if possible
52
25
  def infer_rule_name_from_trigger(trigger, items = nil, kwargs = {})
53
26
  case trigger
27
+ when :at
28
+ infer_rule_name_from_at_trigger(items, **kwargs)
54
29
  when :every
55
30
  infer_rule_name_from_every_trigger(items, **kwargs)
56
31
  when :channel
@@ -101,10 +76,18 @@ module OpenHAB
101
76
  name.freeze
102
77
  end
103
78
 
79
+ # formulate a readable rule name from an at-style cron trigger
80
+ def infer_rule_name_from_at_trigger(item, offset: nil)
81
+ name = "At #{item}"
82
+ name += format_offset(offset)
83
+ name
84
+ end
85
+
104
86
  # formulate a readable rule name from an every-style cron trigger
105
- def infer_rule_name_from_every_trigger(value, at:)
87
+ def infer_rule_name_from_every_trigger(value, at:, offset: nil)
106
88
  name = "Every #{value}"
107
89
  name += " at #{at}" if at
90
+ name += format_offset(offset)
108
91
  name
109
92
  end
110
93
 
@@ -175,6 +158,12 @@ module OpenHAB
175
158
 
176
159
  "#{array[0..-2].join(", ")}, or #{array[-1]}"
177
160
  end
161
+
162
+ def format_offset(offset)
163
+ return "" unless offset&.nonzero?
164
+
165
+ " #{offset.positive? ? "+" : ""}#{offset.seconds.to_s.downcase[2..]}" # Remove "PT" from the ISO8601 string
166
+ end
178
167
  end
179
168
  end
180
169
  end
@@ -4,6 +4,6 @@ module OpenHAB
4
4
  module DSL
5
5
  # Version of openHAB helper libraries
6
6
  # @return [String]
7
- VERSION = "5.25.0"
7
+ VERSION = "5.27.0"
8
8
  end
9
9
  end
data/lib/openhab/dsl.rb CHANGED
@@ -1077,7 +1077,7 @@ module OpenHAB
1077
1077
  return string unless string.is_a?(String)
1078
1078
 
1079
1079
  exception = nil
1080
- [java.time.LocalTime, java.time.LocalDate, java.time.MonthDay, java.time.ZonedDateTime].each do |klass|
1080
+ [java.time.LocalTime, java.time.LocalDate, java.time.MonthDay, java.time.ZonedDateTime, Time].each do |klass|
1081
1081
  return klass.parse(string)
1082
1082
  rescue ArgumentError => e
1083
1083
  exception ||= e
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.25.0
4
+ version: 5.27.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-08-20 00:00:00.000000000 Z
13
+ date: 2024-09-08 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.17
493
+ rubygems_version: 3.5.18
494
494
  signing_key:
495
495
  specification_version: 4
496
496
  summary: JRuby Helper Libraries for openHAB Scripting