openhab-scripting 4.26.3 → 4.28.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: 392687513a444dec2b461e935da7c333b3796f3b34ca87e38a816d2860ebd91b
4
- data.tar.gz: e855efc99e2a355d28ccc59cacfeb91aef879878a6397ef5532e19e8df91b187
3
+ metadata.gz: 738583da2cd48296525b6b6a2999fe1daba82b0cbb1c410beb7e3575fdf6afbb
4
+ data.tar.gz: e7d4ff645268380636f69bff6eec42d8b8f650784225afe9d456027b44e11d77
5
5
  SHA512:
6
- metadata.gz: 914e0d0ebd4f1291cdff34056f67d3268d405b2d5cfd5c19eb51a69893c86f57169b109e3b925455535d78ac37f2611059ed4315161b61c917ad64b6359a88a5
7
- data.tar.gz: d62197a91e6d3e8a5f393faf8e644d7e92edf4815893a8d26494a531622c12d17dc2bf1e4ed213899b043f2cbd9c1993a77cab09db952ae49e288d41a6fd2d06
6
+ metadata.gz: e06a080cedde9ffbb29983f087c93dff1533fe521112c1036015c1f42f93c5a9d164bd0c307d21109c8f3a6abe7cb74e0f63b144cd21d2f7086a1e03d0b9c545
7
+ data.tar.gz: e23ccc89ee67bc2152efaa91ff33157c74d99d244da3cc11b497b8500b094f40dfc66b61fcb04c18763fe53afaabccba8baa6f2bf05c9f3d5d194915255f8078
@@ -5,6 +5,7 @@ require 'java'
5
5
  require 'set'
6
6
 
7
7
  require 'openhab/log/logger'
8
+ require_relative 'item_proxy'
8
9
 
9
10
  # Automation lookup and injection of OpenHab entities
10
11
 
@@ -91,7 +92,8 @@ module OpenHAB
91
92
  def self.lookup_item(name)
92
93
  logger.trace("Looking up item(#{name})")
93
94
  name = name.to_s if name.is_a? Symbol
94
- $ir.get(name) # rubocop: disable Style/GlobalVars
95
+ item = $ir.get(name) # rubocop: disable Style/GlobalVars
96
+ ItemProxy.new(item) unless item.nil?
95
97
  end
96
98
  end
97
99
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'delegate'
4
+ require 'forwardable'
5
+
6
+ module OpenHAB
7
+ module Core
8
+ # Class is a proxy to underlying item
9
+ class ItemProxy < Delegator
10
+ extend Forwardable
11
+ def_delegators :__getobj__, :class, :is_a?, :kind_of?, :instance_of?
12
+
13
+ #
14
+ # Set the proxy item (called by super)
15
+ #
16
+ def __setobj__(item)
17
+ # Convert name to java version for faster lookups
18
+ @item_name = item.name.to_java
19
+ end
20
+
21
+ #
22
+ # Lookup item from item registry
23
+ #
24
+ def __getobj__
25
+ $ir.get(@item_name) # rubocop:disable Style/GlobalVars
26
+ end
27
+ end
28
+ end
29
+ end
@@ -53,7 +53,11 @@ module OpenHAB
53
53
  # sending the command
54
54
  def command(command)
55
55
  return super unless Thread.current[:ensure_states]
56
- return if command == state
56
+
57
+ logger.trace do
58
+ "#{name} ensure #{command}, format_type_pre: #{format_type_pre(command)}, current state: #{state}"
59
+ end
60
+ return if state == format_type_pre(command)
57
61
 
58
62
  super
59
63
  end
@@ -33,6 +33,13 @@ module OpenHAB
33
33
  def ACCEPTED_DATA_TYPES
34
34
  [org.openhab.core.types.UnDefType.java_class].freeze
35
35
  end
36
+
37
+ #
38
+ # Override to support ItemProxy
39
+ #
40
+ def ===(other)
41
+ other.instance_of?(self)
42
+ end
36
43
  end
37
44
  # rubocop:enable Naming/MethodName
38
45
 
@@ -128,7 +135,7 @@ module OpenHAB
128
135
  # @return [Array<Group>] All groups that this item is part of
129
136
  #
130
137
  def groups
131
- group_names.map { |name| Groups.groups[name] }
138
+ group_names.map { |name| Groups.groups[name] }.compact
132
139
  end
133
140
 
134
141
  # Return the item's thing if this item is linked with a thing. If an item is linked to more than one thing,
@@ -6,11 +6,9 @@ require 'openhab/dsl/types/types'
6
6
  require_relative 'item_registry'
7
7
 
8
8
  require_relative 'generic_item'
9
-
10
9
  require_relative 'switch_item'
11
10
  require_relative 'date_time_item'
12
11
  require_relative 'dimmer_item'
13
-
14
12
  require_relative 'color_item'
15
13
  require_relative 'contact_item'
16
14
  require_relative 'group_item'
@@ -48,7 +48,9 @@ module OpenHAB
48
48
  # @return [StateStorage] item states
49
49
  #
50
50
  def store_states(*items)
51
- items = items.flatten
51
+ items = items.flatten.map do |item|
52
+ item.respond_to?(:__getobj__) ? item.__getobj__ : item
53
+ end
52
54
  states = StateStorage.new(BusEvent.storeStates(*items).to_h)
53
55
  if block_given?
54
56
  yield
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'java'
4
+
3
5
  module OpenHAB
4
6
  module DSL
5
7
  # Support for time related functions
@@ -8,40 +10,21 @@ module OpenHAB
8
10
  module MonthDayRange
9
11
  include OpenHAB::Log
10
12
 
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
13
  # Creates a range that can be compared against MonthDay objects, strings
24
14
  # or anything responding to 'to_date' to see if they are within the range
25
15
  # @return Range object representing a MonthDay Range
26
- # rubocop:disable Metrics/AbcSize
27
- # Range method cannot be broken up cleaner
28
16
  def self.range(range)
29
- logger.trace "Creating MonthDay range from #{range}"
30
17
  raise ArgumentError, 'Supplied object must be a range' unless range.is_a? Range
31
18
 
32
19
  start = MonthDay.parse(range.begin)
33
20
  ending = MonthDay.parse(range.end)
34
21
 
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
22
+ start_range = DayOfYear.new(month_day: start, range: start..ending)
23
+ ending_range = DayOfYear.new(month_day: ending, range: start..ending)
24
+ logger.trace "Month Day Range Start(#{start}) - End (#{ending}) - Created from (#{range})"
39
25
 
40
- start_range = MonthDayRangeElement.new(month_day: start, year: current_year)
41
- ending_range = MonthDayRangeElement.new(month_day: ending, year: ending_year)
42
26
  range.exclude_end? ? (start_range...ending_range) : (start_range..ending_range)
43
27
  end
44
- # rubocop:enable Metrics/AbcSize
45
28
 
46
29
  # Checks if supplied range can be converted to a month day range
47
30
  # @param [Range] range to check begin and end values of
@@ -52,54 +35,80 @@ module OpenHAB
52
35
  MonthDay.day_of_month?(range.begin) && MonthDay.day_of_month?(range.end)
53
36
  end
54
37
 
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
38
+ # Converts a MonthDay to a day of year
39
+ # which is represented as a number from 1 to 732 to support comparisions when the range overlaps a year boundary
40
+ class DayOfYear
59
41
  include Comparable
60
42
  include OpenHAB::Log
61
43
  java_import java.time.LocalDate
62
- java_import java.time.Year
44
+
45
+ attr_accessor :month_day
46
+
47
+ # Number of days in a leap year
48
+ DAYS_IN_YEAR = 366
63
49
 
64
50
  # Create a new MonthDayRange element
65
51
  # @param [MonthDay] MonthDay element
66
- # @param [Lambda] year lambda to calculate year to convert MonthDay to LocalDate
52
+ # @param [Range] Underlying MonthDay range
67
53
  #
68
- def initialize(month_day:, year:)
54
+ def initialize(month_day:, range:)
69
55
  @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)
56
+ @range = range
76
57
  end
77
58
 
78
59
  # Returns the MonthDay advanced by 1 day
79
60
  # Required by Range class
80
61
  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)
62
+ next_day_of_month = @month_day.day_of_month + 1
63
+ next_month = @month_day.month_value
64
+
65
+ if next_day_of_month > @month_day.month.max_length
66
+ next_day_of_month = 1
67
+ next_month = @month_day.month.plus(1).value
68
+ end
69
+
70
+ DayOfYear.new(month_day: MonthDay.of(next_month, next_day_of_month), range: @range)
71
+ end
72
+
73
+ #
74
+ # Offset by 1 year if the range begin is greater than the range end
75
+ # and if the month day is less than the begining of the range
76
+ # @return [Number] 366 if the month_day should be offset by a year
77
+ def offset
78
+ @range.begin > @range.end && month_day < @range.begin ? DAYS_IN_YEAR : 0
79
+ end
80
+
81
+ #
82
+ # Calculate the day within the range for the underlying month day
83
+ # @return [Number] Representation of the MonthDay as a number from 1 to 732
84
+ def day_in_range
85
+ @day_in_range ||= month_day.max_day_of_year + offset
85
86
  end
86
87
 
87
88
  # 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)
89
+ def <=>(other) # rubocop:disable Metrics/AbcSize
91
90
  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))
91
+ when DayOfYear then day_in_range.<=>(other.day_in_range)
92
+ when MonthDay then self.<=>(DayOfYear.new(month_day: other, range: @range))
93
+ when LocalDate then self.<=>(MonthDay.of(other.month_value, other.day_of_month))
94
+ when Date then self.<=>(MonthDay.of(other.month, other.day))
95
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
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
98
 
99
99
  raise "Unable to convert #{other.class} to compare to MonthDay"
100
100
  end
101
101
  end
102
- # rubocop:enable Metrics/AbcSize
102
+ end
103
+ end
104
+
105
+ java_import java.time.Month
106
+ # Extend Month with helper method
107
+ class Month
108
+ # Calcalute and memoize the maximum number of days in a year before this month
109
+ # @return [Number] maximum nummber of days in a year before this month
110
+ def max_days_before
111
+ @max_days_before ||= Month.values.select { |month| month < self }.sum(&:max_length)
103
112
  end
104
113
  end
105
114
 
@@ -108,6 +117,7 @@ module OpenHAB
108
117
  class MonthDay
109
118
  include OpenHAB::Log
110
119
  java_import java.time.format.DateTimeFormatter
120
+ java_import java.time.Month
111
121
 
112
122
  #
113
123
  # Constructor
@@ -117,11 +127,9 @@ module OpenHAB
117
127
  #
118
128
  # @return [Object] MonthDay object
119
129
  #
120
- # rubocop: disable Naming/MethodParameterName
121
- def self.new(m:, d:)
130
+ def self.new(m:, d:) # rubocop:disable Naming/MethodParameterName
122
131
  MonthDay.of(m, d)
123
132
  end
124
- # rubocop: enable Naming/MethodParameterName
125
133
 
126
134
  # Parse MonthDay string as defined with by Monthday class without leading double dash "--"
127
135
  def self.parse(string)
@@ -136,11 +144,23 @@ module OpenHAB
136
144
  /^-*[01][0-9]-[0-3]\d$/.match? obj.to_s
137
145
  end
138
146
 
147
+ # Get the maximum (supports leap years) day of the year this month day could be
148
+ def max_day_of_year
149
+ day_of_month + month.max_days_before
150
+ end
151
+
139
152
  # Remove -- from MonthDay string representation
140
153
  def to_s
141
154
  to_string.delete_prefix('--')
142
155
  end
143
156
 
157
+ # Checks if MonthDay is between the dates of the supplied range
158
+ # @param [Range] range to check against MonthDay
159
+ # @return [true,false] true if the MonthDay falls within supplied range, false otherwise
160
+ def between?(range)
161
+ MonthDayRange.range(range).cover? self
162
+ end
163
+
144
164
  # remove the inherited #== method to use our <=> below
145
165
  remove_method :==
146
166
 
@@ -151,6 +171,9 @@ module OpenHAB
151
171
  case other
152
172
  when String
153
173
  self.<=>(MonthDay.parse(other))
174
+ when OpenHAB::DSL::Between::MonthDayRange::DayOfYear
175
+ # Compare with DayOfYear and invert result
176
+ -other.<=>(self)
154
177
  else
155
178
  super
156
179
  end
@@ -39,7 +39,7 @@ module OpenHAB
39
39
 
40
40
  if timer.respond_to? :id
41
41
  logger.trace("Adding #{timer} with id #{timer.id.inspect} timer ids")
42
- @timer_ids[timer.id] = Set.new unless @timer_ids[timer.id]
42
+ @timer_ids[timer.id] = TimerSet.new unless @timer_ids[timer.id]
43
43
  @timer_ids[timer.id] << timer
44
44
  end
45
45
 
@@ -87,6 +87,19 @@ module OpenHAB
87
87
  @timers.clear
88
88
  end
89
89
  end
90
+
91
+ #
92
+ # Provide additional methods for the timers set
93
+ #
94
+ class TimerSet < Set
95
+ #
96
+ # A shorthand to cancel all the timer objects held within the set
97
+ # so that timers[timer_id].cancel_all is equivalent to timers[timer_id].each(&:cancel)
98
+ #
99
+ def cancel_all
100
+ each(&:cancel)
101
+ end
102
+ end
90
103
  end
91
104
  end
92
105
  end
@@ -5,5 +5,5 @@
5
5
  #
6
6
  module OpenHAB
7
7
  # @return [String] Version of OpenHAB helper libraries
8
- VERSION = '4.26.3'
8
+ VERSION = '4.28.0'
9
9
  end
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.26.3
4
+ version: 4.28.0
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: 2022-01-02 00:00:00.000000000 Z
11
+ date: 2022-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -47,6 +47,7 @@ extra_rdoc_files: []
47
47
  files:
48
48
  - lib/openhab.rb
49
49
  - lib/openhab/core/entity_lookup.rb
50
+ - lib/openhab/core/item_proxy.rb
50
51
  - lib/openhab/core/load_path.rb
51
52
  - lib/openhab/core/openhab_setup.rb
52
53
  - lib/openhab/core/osgi.rb