openhab-scripting 5.26.0 → 5.27.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: 5c898bc5ce08126c859ea18fa49311cb13db576df162bdad7b223d0a969af295
4
- data.tar.gz: 667905c4ce354563a439ad31c2449a9d93e321871ab64983ea6a9a108f664096
3
+ metadata.gz: 59deb6289921c0c6d35579783efbb35f75ceac9ff24922e0f74d6652ef575b59
4
+ data.tar.gz: 260ee0993a3ab89775d9b5a2e8f3e40f295dd16ad8f0adf3b003b521cb08a12e
5
5
  SHA512:
6
- metadata.gz: 9c8db7176dfcf4fceb4b6ab9b796c0bcaea2357e539992d8671bd63392f99deca570237ab9591b956cabb4066889eba63b85d7d4c26fbf911d16d027d2efd845
7
- data.tar.gz: 621e91b24ecb04685e308df788982df4b66245bbb3f1fe28a1e221173c3bc63c8308d913ddd1d8162bf540fad8c9617b4c0fa01e08266db4ee4ba92cfa4987b9
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
@@ -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
@@ -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
@@ -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.26.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.26.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-25 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