openhab-scripting 4.10.1 → 4.11.1

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: d06a02d7b0f2d02ed4e0ac6fdb06b61ef109b2eacb68cbc4c84c4ca766b94b9b
4
- data.tar.gz: 69863d7d2d8a7c1f578a5eceeb949aa19ff09d23e1e7910aafad54f69eab3661
3
+ metadata.gz: 3264a393d9e32d434336802a9dcfd97f2d296b1f54cb3060650fd29ab7103b91
4
+ data.tar.gz: 786046dd908aaa43250b374947b01dcbfb7455eb72105b504bb29e0cffe48545
5
5
  SHA512:
6
- metadata.gz: 9bb723993916a3382b1795526c9b2373cc7017f8983e04e388c8fc655a427607eeb2564cf973769d0852306207c52b7540c4298034482b23cc6d9cfd588c7b8d
7
- data.tar.gz: 234f9e2fc4752707ec7e4290745cca0eececfcbd0bb868feff6cb44850ff97df5eca6f0c2d755a350063aa7e8475db698d6efe9fd617d76f6971f33b77474ce7
6
+ metadata.gz: d7c4684def0b1c2dd97d9bce9f191bcfb58c5e3bf07313916d240385dc0d891f987b30d92c38f27578e432e10c8318e2167dd92942f6b6d426e77e1d7c3f2be4
7
+ data.tar.gz: '058b81f95f7d86e8cf35a30f8576679c49fab4181a1f7e1634f9d5997cb45a6f96c4cf35efc00627d954d4a71c2626bd4a82df527c0233685fd9c2e52061f6f6'
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'time/time_of_day'
4
+ require_relative 'time/month_day'
5
+
6
+ module OpenHAB
7
+ module DSL
8
+ # Supports between range syntax
9
+ module Between
10
+ # Creates a range that can be compared against time of day/month days or strings
11
+ # to see if they are within the range
12
+ # @since 2.4.0
13
+ # @return Range object representing a TimeOfDay Range
14
+ def between(range)
15
+ raise ArgumentError, 'Supplied object must be a range' unless range.is_a? Range
16
+
17
+ return OpenHAB::DSL::Between::MonthDayRange.range(range) if OpenHAB::DSL::Between::MonthDayRange.range?(range)
18
+
19
+ OpenHAB::DSL::Between::TimeOfDay.between(range)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -15,7 +15,7 @@ require 'openhab/dsl/actions'
15
15
  require 'openhab/dsl/timers'
16
16
  require 'openhab/dsl/group'
17
17
  require 'openhab/dsl/things'
18
- require 'openhab/dsl/time_of_day'
18
+ require 'openhab/dsl/between'
19
19
  require 'openhab/dsl/gems'
20
20
  require 'openhab/dsl/persistence'
21
21
  require 'openhab/dsl/units'
@@ -31,6 +31,7 @@ module OpenHAB
31
31
  # rubocop:disable Metrics/MethodLength
32
32
  def self.extended(base)
33
33
  base.send :include, OpenHAB::DSL::Actions
34
+ base.send :include, OpenHAB::DSL::Between
34
35
  base.send :include, OpenHAB::DSL::Groups
35
36
  base.send :include, OpenHAB::DSL::Items
36
37
  base.send :include, OpenHAB::DSL::Persistence
@@ -39,7 +40,7 @@ module OpenHAB
39
40
  base.send :include, OpenHAB::DSL::States
40
41
  base.send :include, OpenHAB::DSL::Things
41
42
  base.send :include, OpenHAB::DSL::Timers
42
- base.send :include, OpenHAB::DSL::TimeOfDay
43
+ base.send :include, OpenHAB::DSL::Between
43
44
  base.send :include, OpenHAB::DSL::Types
44
45
  base.send :include, OpenHAB::DSL::Units
45
46
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'openhab/dsl/time_of_day'
4
-
5
3
  require_relative 'numeric_item'
6
4
 
7
5
  module OpenHAB
@@ -4,6 +4,7 @@ require 'java'
4
4
  require 'set'
5
5
  require 'openhab/core/thread_local'
6
6
  require 'openhab/log/logger'
7
+ require 'openhab/dsl/between'
7
8
 
8
9
  require_relative 'item_event'
9
10
 
@@ -22,7 +23,7 @@ module OpenHAB
22
23
  class AutomationRule < Java::OrgOpenhabCoreAutomationModuleScriptRulesupportSharedSimple::SimpleRule
23
24
  include OpenHAB::Log
24
25
  include OpenHAB::Core::ThreadLocal
25
- include OpenHAB::DSL::TimeOfDay
26
+ include OpenHAB::DSL::Between
26
27
  java_import java.time.ZonedDateTime
27
28
 
28
29
  #
@@ -42,7 +43,7 @@ module OpenHAB
42
43
  @run_queue = config.run
43
44
  @guard = config.guard
44
45
  between = config.between&.yield_self { between(config.between) }
45
- @between = between || OpenHAB::DSL::TimeOfDay::ALL_DAY
46
+ @between = between || OpenHAB::DSL::Between::ALL_DAY
46
47
  # Convert between to correct range or nil if not set
47
48
  @trigger_delays = config.trigger_delays
48
49
  @attachments = config.attachments
@@ -10,7 +10,7 @@ require 'openhab/dsl/rules/triggers/command'
10
10
  require 'openhab/dsl/rules/triggers/updated'
11
11
  require 'openhab/dsl/rules/guard'
12
12
  require 'openhab/core/entity_lookup'
13
- require 'openhab/dsl/time_of_day'
13
+ require 'openhab/dsl/between'
14
14
  require 'openhab/dsl/dsl'
15
15
  require 'openhab/dsl/timers'
16
16
 
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'java'
4
- require 'openhab/dsl/time_of_day'
5
4
 
6
5
  module OpenHAB
7
6
  module DSL
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ # Support for time related functions
6
+ module Between
7
+ # Manages Month Day Ranges
8
+ module MonthDayRange
9
+ include OpenHAB::Log
10
+
11
+ java_import java.time.Year
12
+
13
+ # Lambdas are used to calculate the year for the month day
14
+ # which must happen during evaluation time to support that rules
15
+ # creation and evaluation for execution are done in distinct phases
16
+ @current_year = -> { return Year.now }
17
+ @next_year = -> { return Year.now.plus_years(1) }
18
+
19
+ class << self
20
+ attr_reader :current_year, :next_year
21
+ end
22
+
23
+ # Creates a range that can be compared against MonthDay objects, strings
24
+ # or anything responding to 'to_date' to see if they are within the range
25
+ # @return Range object representing a MonthDay Range
26
+ # rubocop:disable Metrics/AbcSize
27
+ # Range method cannot be broken up cleaner
28
+ def self.range(range)
29
+ logger.trace "Creating MonthDay range from #{range}"
30
+ raise ArgumentError, 'Supplied object must be a range' unless range.is_a? Range
31
+
32
+ start = MonthDay.parse(range.begin)
33
+ ending = MonthDay.parse(range.end)
34
+
35
+ logger.trace "Month Day Range Start(#{start}) - End (#{ending})"
36
+
37
+ # Wrap to next year if ending day of month is before starting day of month
38
+ ending_year = ending < start ? next_year : current_year
39
+
40
+ start_range = MonthDayRangeElement.new(month_day: start, year: current_year)
41
+ ending_range = MonthDayRangeElement.new(month_day: ending, year: ending_year)
42
+ range.exclude_end? ? (start_range...ending_range) : (start_range..ending_range)
43
+ end
44
+ # rubocop:enable Metrics/AbcSize
45
+
46
+ # Checks if supplied range can be converted to a month day range
47
+ # @param [Range] range to check begin and end values of
48
+ # @return [Boolean] Returns true if supplied range can be converted to a month day range
49
+ def self.range?(range)
50
+ return false unless range.is_a? Range
51
+
52
+ MonthDay.day_of_month?(range.begin) && MonthDay.day_of_month?(range.end)
53
+ end
54
+
55
+ # Represents a range element for a MonthDay object
56
+ # The LocalDate (MonthDay + Year) is dynamically calculated to allow for
57
+ # being used as a guard during rule evaluation
58
+ class MonthDayRangeElement
59
+ include Comparable
60
+ include OpenHAB::Log
61
+ java_import java.time.LocalDate
62
+ java_import java.time.Year
63
+
64
+ # Create a new MonthDayRange element
65
+ # @param [MonthDay] MonthDay element
66
+ # @param [Lambda] year lambda to calculate year to convert MonthDay to LocalDate
67
+ #
68
+ def initialize(month_day:, year:)
69
+ @month_day = month_day
70
+ @year = year
71
+ end
72
+
73
+ # Convert into a LocalDate using year lambda supplied in initializer
74
+ def to_local_date
75
+ @year.call.at_month_day(@month_day)
76
+ end
77
+
78
+ # Returns the MonthDay advanced by 1 day
79
+ # Required by Range class
80
+ def succ
81
+ next_date = to_local_date.plus_days(1)
82
+ # Handle rollover to next year
83
+ year = -> { Year.from(next_date) }
84
+ MonthDayRangeElement.new(month_day: MonthDay.from(next_date), year: year)
85
+ end
86
+
87
+ # Compare MonthDayRangeElement to other objects as required by Range class
88
+ # rubocop:disable Metrics/AbcSize
89
+ # Case statement needs to work against multiple types
90
+ def <=>(other)
91
+ case other
92
+ when LocalDate then to_local_date.compare_to(other)
93
+ when Date then self.<=>(LocalDate.of(other.year, other.month, other.day))
94
+ when MonthDay then self.<=>(MonthDayRange.current_year.call.at_month_day(other))
95
+ else
96
+ return self.<=>(other.to_local_date) if other.respond_to? :to_local_date
97
+ return self.<=>(other.to_date) if other.respond_to? :to_date
98
+
99
+ raise "Unable to convert #{other.class} to compare to MonthDay"
100
+ end
101
+ end
102
+ # rubocop:enable Metrics/AbcSize
103
+ end
104
+ end
105
+
106
+ java_import java.time.MonthDay
107
+ # Extend MonthDay java object with some helper methods
108
+ class MonthDay
109
+ include OpenHAB::Log
110
+ # Parse MonthDay string as defined with by Monthday class without leading double dash "--"
111
+ def self.parse(string)
112
+ ## string = "--#{string}" unless string.to_s.start_with? '--'
113
+ java_send :parse, [java.lang.CharSequence], "--#{string}"
114
+ end
115
+
116
+ # Can the supplied object be parsed into a MonthDay
117
+ def self.day_of_month?(obj)
118
+ /^-*[01][0-9]-[0-3]\d$/.match? obj.to_s
119
+ end
120
+
121
+ # Remove -- from MonthDay string representation
122
+ def to_s
123
+ to_string.delete_prefix('--')
124
+ end
125
+
126
+ # Extends MonthDay comparison to support Strings
127
+ # Necessary to support mixed ranges of Strings and MonthDay types
128
+ # @return [Number, nil] -1,0,1 if other MonthDay is less than, equal to, or greater than this MonthDay
129
+ def <=>(other)
130
+ case other
131
+ when String
132
+ self.<=>(MonthDay.parse(other))
133
+ else
134
+ super
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -10,7 +10,7 @@ module OpenHAB
10
10
  # Times without specific dates e.g. 6:00:00
11
11
  # @author Brian O'Connell
12
12
  # @since 0.0.1
13
- module TimeOfDay
13
+ module Between
14
14
  java_import java.time.LocalTime
15
15
  java_import java.time.format.DateTimeFormatterBuilder
16
16
  java_import java.util.Locale
@@ -123,6 +123,41 @@ module OpenHAB
123
123
  -(other <=> self)
124
124
  end
125
125
  end
126
+
127
+ # Creates a range that can be compared against time of day objects or strings
128
+ # to see if they are within the range
129
+ # @since 2.4.0
130
+ # @return Range object representing a TimeOfDay Range
131
+ def self.between(range)
132
+ raise ArgumentError, 'Supplied object must be a range' unless range.is_a? Range
133
+
134
+ start = to_time_of_day(range.begin)
135
+ ending = to_time_of_day(range.end)
136
+
137
+ start_sod = start.local_time.to_second_of_day
138
+ ending_sod = ending.local_time.to_second_of_day
139
+ ending_sod += TimeOfDayRangeElement::NUM_SECONDS_IN_DAY if ending_sod < start_sod
140
+
141
+ start_range = TimeOfDayRangeElement.new(sod: start_sod, range_begin: start_sod)
142
+ ending_range = TimeOfDayRangeElement.new(sod: ending_sod, range_begin: start_sod)
143
+ range.exclude_end? ? (start_range...ending_range) : (start_range..ending_range)
144
+ end
145
+
146
+ #
147
+ # Convert object to TimeOfDay object
148
+ #
149
+ # @param [Object] object TimeOfDay or String to be converted
150
+ #
151
+ # @return [TimeOfDay] TimeOfDay created from supplied object
152
+ #
153
+ def self.to_time_of_day(object)
154
+ case object
155
+ when String then TimeOfDay.parse(object)
156
+ when Time, OpenHAB::DSL::Types::DateTimeType, OpenHAB::DSL::Items::DateTimeItem
157
+ TimeOfDay.new(h: object.hour, m: object.min, s: object.sec)
158
+ else object
159
+ end
160
+ end
126
161
  end
127
162
 
128
163
  # Modules that refines the Ruby Range object cover? and include? methods to support TimeOfDay ranges
@@ -168,17 +203,20 @@ module OpenHAB
168
203
  #
169
204
  # @return [Integer] seconds of day represented by supplied object
170
205
  #
206
+ # rubocop:disable Metrics/AbcSize
207
+ # case statement needs to compare against multiple types
171
208
  def to_second_of_day(object)
172
209
  case object
173
210
  when TimeOfDay then adjust_second_of_day(object.local_time.to_second_of_day)
174
211
  when String then adjust_second_of_day(TimeOfDay.parse(object).local_time.to_second_of_day)
175
- when Time, OpenHAB::DSL::Types::DateTimeType, OpenHAB::DSL::Items::DateTimeItem
212
+ when ::Time, OpenHAB::DSL::Types::DateTimeType, OpenHAB::DSL::Items::DateTimeItem
176
213
  adjust_second_of_day(TimeOfDay.new(h: object.hour, m: object.min, s: object.sec)
177
214
  .local_time.to_second_of_day)
178
215
  when TimeOfDayRangeElement then object.sod
179
- else raise ArgumentError, 'Supplied argument cannot be converted into Time Of Day Object'
216
+ else raise ArgumentError, "Supplied argument #{object.class} cannot be converted into Time Of Day Object"
180
217
  end
181
218
  end
219
+ # rubocop:enable Metrics/AbcSize
182
220
 
183
221
  def adjust_second_of_day(second_of_day)
184
222
  second_of_day += NUM_SECONDS_IN_DAY if second_of_day < @range_begin
@@ -186,46 +224,9 @@ module OpenHAB
186
224
  end
187
225
  end
188
226
 
189
- # Creates a range that can be compared against time of day objects or strings
190
- # to see if they are within the range
191
- # @since 2.4.0
192
- # @return Range object representing a TimeOfDay Range
193
- module_function
194
-
195
- def between(range)
196
- raise ArgumentError, 'Supplied object must be a range' unless range.is_a? Range
197
-
198
- start = to_time_of_day(range.begin)
199
- ending = to_time_of_day(range.end)
200
-
201
- start_sod = start.local_time.to_second_of_day
202
- ending_sod = ending.local_time.to_second_of_day
203
- ending_sod += TimeOfDayRangeElement::NUM_SECONDS_IN_DAY if ending_sod < start_sod
204
-
205
- start_range = TimeOfDayRangeElement.new(sod: start_sod, range_begin: start_sod)
206
- ending_range = TimeOfDayRangeElement.new(sod: ending_sod, range_begin: start_sod)
207
- range.exclude_end? ? (start_range...ending_range) : (start_range..ending_range)
208
- end
209
-
210
- #
211
- # Convert object to TimeOfDay object
212
- #
213
- # @param [Object] object TimeOfDay or String to be converted
214
- #
215
- # @return [TimeOfDay] TimeOfDay created from supplied object
216
- #
217
- private_class_method def to_time_of_day(object)
218
- case object
219
- when String then TimeOfDay.parse(object)
220
- when Time, OpenHAB::DSL::Types::DateTimeType, OpenHAB::DSL::Items::DateTimeItem
221
- TimeOfDay.new(h: object.hour, m: object.min, s: object.sec)
222
- else object
223
- end
224
- end
225
-
226
227
  MIDNIGHT = TimeOfDay.midnight
227
228
  NOON = TimeOfDay.noon
228
- ALL_DAY = between(TimeOfDay.new(h: 0, m: 0, s: 0)..TimeOfDay.new(h: 23, m: 59, s: 59))
229
+ ALL_DAY = TimeOfDay.between(TimeOfDay.new(h: 0, m: 0, s: 0)..TimeOfDay.new(h: 23, m: 59, s: 59))
229
230
  end
230
231
  end
231
232
  end
@@ -59,6 +59,10 @@ module OpenHAB
59
59
  # @return [Timer] Rescheduled timer instances
60
60
  #
61
61
  def reschedule(duration = nil)
62
+ unless duration.nil? || duration.is_a?(Java::JavaTimeTemporal::TemporalAmount)
63
+ raise ArgumentError, 'Supplied argument must be a duration'
64
+ end
65
+
62
66
  duration ||= @duration
63
67
  Timers.timer_manager.add(self)
64
68
  @timer.reschedule(ZonedDateTime.now.plus(duration))
@@ -58,11 +58,11 @@ module OpenHAB
58
58
  timer = @timer_manager.reentrant_timer(id: id, &block)
59
59
  if timer
60
60
  logger.trace("Reentrant timer found - #{timer}")
61
- timer.reschedule
61
+ timer.cancel
62
62
  else
63
63
  logger.trace('No reentrant timer found, creating new timer')
64
- ReentrantTimer.new(duration: duration, id: id, &block)
65
64
  end
65
+ ReentrantTimer.new(duration: duration, id: id, &block)
66
66
  end
67
67
  end
68
68
  end
@@ -59,7 +59,7 @@ module OpenHAB
59
59
  rescue java.lang.StringIndexOutOfBoundsException, java.lang.IllegalArgumentException
60
60
  # Try ruby's Time.parse if OpenHAB's DateTimeType parser fails
61
61
  begin
62
- DateTimeType.new(Time.parse(time_string))
62
+ DateTimeType.new(::Time.parse(time_string))
63
63
  rescue ArgumentError
64
64
  raise ArgumentError, "Unable to parse #{time_string} into a DateTimeType"
65
65
  end
@@ -194,7 +194,7 @@ module OpenHAB
194
194
  # @return [Time] A Time object representing the same instant and timezone
195
195
  #
196
196
  def to_time
197
- Time.at(to_i, nsec, :nsec).localtime(utc_offset)
197
+ ::Time.at(to_i, nsec, :nsec).localtime(utc_offset)
198
198
  end
199
199
 
200
200
  #
@@ -256,7 +256,7 @@ module OpenHAB
256
256
  # @!visibility private
257
257
  def respond_to_missing?(method, _include_private = false)
258
258
  return true if zoned_date_time.respond_to?(method)
259
- return true if Time.instance_methods.include?(method.to_sym)
259
+ return true if ::Time.instance_methods.include?(method.to_sym)
260
260
 
261
261
  super
262
262
  end
@@ -267,7 +267,7 @@ module OpenHAB
267
267
  #
268
268
  def method_missing(method, *args, &block)
269
269
  return zoned_date_time.send(method, *args, &block) if zoned_date_time.respond_to?(method)
270
- return to_time.send(method, *args, &block) if Time.instance_methods.include?(method.to_sym)
270
+ return to_time.send(method, *args, &block) if ::Time.instance_methods.include?(method.to_sym)
271
271
 
272
272
  super
273
273
  end
@@ -5,5 +5,5 @@
5
5
  #
6
6
  module OpenHAB
7
7
  # @return [String] Version of OpenHAB helper libraries
8
- VERSION = '4.10.1'
8
+ VERSION = '4.11.1'
9
9
  end
data/lib/openhab.rb CHANGED
@@ -19,7 +19,6 @@ module OpenHAB
19
19
  # @param [Object] base Object to decorate with DSL and helper methods
20
20
  #
21
21
  #
22
- # rubocop:disable Metrics/MethodLength
23
22
  # Number of extensions and includes requires more lines
24
23
  def self.extended(base)
25
24
  OpenHAB::Core.wait_till_openhab_ready
@@ -27,16 +26,14 @@ module OpenHAB
27
26
  base.extend OpenHAB::Core::ScriptHandling
28
27
  base.extend OpenHAB::Core::EntityLookup
29
28
  base.extend OpenHAB::DSL
30
- base.extend OpenHAB::DSL::TimeOfDay
29
+ base.extend OpenHAB::DSL::Between
31
30
 
32
- base.send :include, OpenHAB::DSL::TimeOfDay
33
31
  base.send :include, OpenHAB::DSL::Items
34
32
  base.send :include, OpenHAB::DSL::Types
35
33
  logger.info "OpenHAB JRuby Scripting Library Version #{OpenHAB::VERSION} Loaded"
36
34
 
37
35
  OpenHAB::Core.add_rubylib_to_load_path
38
36
  end
39
- # rubocop:enable Metrics/MethodLength
40
37
  end
41
38
 
42
39
  # Extend caller with OpenHAB methods
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openhab-scripting
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.10.1
4
+ version: 4.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian O'Connell
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-02 00:00:00.000000000 Z
11
+ date: 2021-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,6 +53,7 @@ files:
53
53
  - lib/openhab/core/script_handling.rb
54
54
  - lib/openhab/core/thread_local.rb
55
55
  - lib/openhab/dsl/actions.rb
56
+ - lib/openhab/dsl/between.rb
56
57
  - lib/openhab/dsl/dsl.rb
57
58
  - lib/openhab/dsl/gems.rb
58
59
  - lib/openhab/dsl/group.rb
@@ -106,7 +107,8 @@ files:
106
107
  - lib/openhab/dsl/rules/triggers/updated.rb
107
108
  - lib/openhab/dsl/states.rb
108
109
  - lib/openhab/dsl/things.rb
109
- - lib/openhab/dsl/time_of_day.rb
110
+ - lib/openhab/dsl/time/month_day.rb
111
+ - lib/openhab/dsl/time/time_of_day.rb
110
112
  - lib/openhab/dsl/timers.rb
111
113
  - lib/openhab/dsl/timers/manager.rb
112
114
  - lib/openhab/dsl/timers/reentrant_timer.rb