openhab-scripting 4.10.0 → 4.11.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 +4 -4
- data/lib/openhab/dsl/between.rb +23 -0
- data/lib/openhab/dsl/dsl.rb +3 -2
- data/lib/openhab/dsl/items/color_item.rb +0 -2
- data/lib/openhab/dsl/items/date_time_item.rb +0 -2
- data/lib/openhab/dsl/items/dimmer_item.rb +0 -2
- data/lib/openhab/dsl/items/location_item.rb +0 -2
- data/lib/openhab/dsl/items/numeric_item.rb +0 -2
- data/lib/openhab/dsl/rules/automation_rule.rb +3 -2
- data/lib/openhab/dsl/rules/rule_config.rb +1 -1
- data/lib/openhab/dsl/rules/triggers/cron.rb +0 -1
- data/lib/openhab/dsl/time/month_day.rb +140 -0
- data/lib/openhab/dsl/{time_of_day.rb → time/time_of_day.rb} +42 -41
- data/lib/openhab/dsl/timers/timer.rb +4 -0
- data/lib/openhab/dsl/types/date_time_type.rb +9 -12
- data/lib/openhab/dsl/types/decimal_type.rb +5 -8
- data/lib/openhab/dsl/types/hsb_type.rb +1 -1
- data/lib/openhab/dsl/types/point_type.rb +12 -7
- data/lib/openhab/dsl/types/quantity_type.rb +8 -13
- data/lib/openhab/dsl/types/string_type.rb +3 -4
- data/lib/openhab/dsl/types/type.rb +13 -4
- data/lib/openhab/version.rb +1 -1
- data/lib/openhab.rb +1 -4
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f4fc0e817de7a0a8ef1892e7e397552afb897bc45983935a73ab39f03975733
|
4
|
+
data.tar.gz: 756291721126083940a335788551a7d1bafdd7643b0bd4cd5cb3bedb7b576ae0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58b0de14c919cdc09bef1d8f37c782052a8a36740feddf797e2a8d38a112b334d795a270b757dbae3938269faf29b117aceb303de2c3878da608214aeb25e7fc
|
7
|
+
data.tar.gz: a0079a59f25d709814f20527045d7b7c57f4b7c702f3618c616be56117e60b7e0920d023d19d2752556f41f2a85b3e617280e00176a2d60513bef07a0067e882
|
@@ -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
|
data/lib/openhab/dsl/dsl.rb
CHANGED
@@ -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/
|
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::
|
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
|
@@ -39,8 +39,6 @@ module OpenHAB
|
|
39
39
|
logger.trace("Coercing #{self} as a request from #{other.class}")
|
40
40
|
return [other, nil] unless state?
|
41
41
|
return [other, state] if other.is_a?(Types::HSBType) || other.respond_to?(:to_str)
|
42
|
-
|
43
|
-
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
44
42
|
end
|
45
43
|
|
46
44
|
# any method that exists on {Types::HSBType} gets forwarded to +state+
|
@@ -40,8 +40,6 @@ module OpenHAB
|
|
40
40
|
logger.trace("Coercing #{self} as a request from #{other.class}")
|
41
41
|
return [other, nil] unless state?
|
42
42
|
return [other, state] if other.is_a?(Types::DateTimeType) || other.respond_to?(:to_time)
|
43
|
-
|
44
|
-
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
45
43
|
end
|
46
44
|
|
47
45
|
# any method that exists on DateTimeType, Java's ZonedDateTime, or
|
@@ -39,8 +39,6 @@ module OpenHAB
|
|
39
39
|
logger.trace("Coercing #{self} as a request from #{other.class}")
|
40
40
|
return [other, nil] unless state?
|
41
41
|
return [other, state] if other.is_a?(Types::PointType) || other.respond_to?(:to_str)
|
42
|
-
|
43
|
-
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
44
42
|
end
|
45
43
|
|
46
44
|
# OpenHAB has this method, but it _only_ accepts PointType, so remove it and delegate
|
@@ -47,8 +47,6 @@ module OpenHAB
|
|
47
47
|
logger.trace("Coercing #{self} as a request from #{other.class}")
|
48
48
|
return [other, nil] unless state?
|
49
49
|
return [other, state] if other.is_a?(Types::NumericType) || other.respond_to?(:to_d)
|
50
|
-
|
51
|
-
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
52
50
|
end
|
53
51
|
|
54
52
|
# strip trailing zeros from commands
|
@@ -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::
|
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::
|
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/
|
13
|
+
require 'openhab/dsl/between'
|
14
14
|
require 'openhab/dsl/dsl'
|
15
15
|
require 'openhab/dsl/timers'
|
16
16
|
|
@@ -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
|
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,
|
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))
|
@@ -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
|
@@ -161,7 +161,8 @@ module OpenHAB
|
|
161
161
|
time_string = "#{time_string}T00:00:00#{zone}" if DATE_ONLY_REGEX.match?(time_string)
|
162
162
|
self <=> DateTimeType.parse(time_string)
|
163
163
|
elsif other.respond_to?(:coerce)
|
164
|
-
lhs, rhs = other.coerce(self)
|
164
|
+
return nil unless (lhs, rhs = other.coerce(self))
|
165
|
+
|
165
166
|
lhs <=> rhs
|
166
167
|
end
|
167
168
|
end
|
@@ -179,13 +180,11 @@ module OpenHAB
|
|
179
180
|
def coerce(other)
|
180
181
|
logger.trace("Coercing #{self} as a request from #{other.class}")
|
181
182
|
if other.is_a?(Items::DateTimeItem)
|
182
|
-
|
183
|
+
return unless other.state?
|
183
184
|
|
184
185
|
[other.state, self]
|
185
186
|
elsif other.respond_to?(:to_time)
|
186
187
|
[DateTimeType.new(other), self]
|
187
|
-
else
|
188
|
-
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
189
188
|
end
|
190
189
|
end
|
191
190
|
|
@@ -195,7 +194,7 @@ module OpenHAB
|
|
195
194
|
# @return [Time] A Time object representing the same instant and timezone
|
196
195
|
#
|
197
196
|
def to_time
|
198
|
-
Time.at(to_i, nsec, :nsec).localtime(utc_offset)
|
197
|
+
::Time.at(to_i, nsec, :nsec).localtime(utc_offset)
|
199
198
|
end
|
200
199
|
|
201
200
|
#
|
@@ -257,7 +256,7 @@ module OpenHAB
|
|
257
256
|
# @!visibility private
|
258
257
|
def respond_to_missing?(method, _include_private = false)
|
259
258
|
return true if zoned_date_time.respond_to?(method)
|
260
|
-
return true if Time.instance_methods.include?(method.to_sym)
|
259
|
+
return true if ::Time.instance_methods.include?(method.to_sym)
|
261
260
|
|
262
261
|
super
|
263
262
|
end
|
@@ -268,7 +267,7 @@ module OpenHAB
|
|
268
267
|
#
|
269
268
|
def method_missing(method, *args, &block)
|
270
269
|
return zoned_date_time.send(method, *args, &block) if zoned_date_time.respond_to?(method)
|
271
|
-
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)
|
272
271
|
|
273
272
|
super
|
274
273
|
end
|
@@ -286,8 +285,7 @@ module OpenHAB
|
|
286
285
|
self + other
|
287
286
|
elsif other.respond_to?(:to_d)
|
288
287
|
DateTimeType.new(zoned_date_time.plusNanos((other.to_d * 1_000_000_000).to_i))
|
289
|
-
elsif other.respond_to?(:coerce)
|
290
|
-
lhs, rhs = other.coerce(to_d)
|
288
|
+
elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
291
289
|
lhs + rhs
|
292
290
|
else
|
293
291
|
raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
|
@@ -320,8 +318,7 @@ module OpenHAB
|
|
320
318
|
self - other
|
321
319
|
elsif other.respond_to?(:to_d)
|
322
320
|
DateTimeType.new(zoned_date_time.minusNanos((other.to_d * 1_000_000_000).to_i))
|
323
|
-
elsif other.respond_to?(:coerce)
|
324
|
-
lhs, rhs = other.coerce(to_d)
|
321
|
+
elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
325
322
|
lhs - rhs
|
326
323
|
else
|
327
324
|
raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
|
@@ -87,7 +87,8 @@ module OpenHAB
|
|
87
87
|
elsif other.respond_to?(:to_d)
|
88
88
|
to_d <=> other.to_d
|
89
89
|
elsif other.respond_to?(:coerce)
|
90
|
-
lhs, rhs = other.coerce(self)
|
90
|
+
return nil unless (lhs, rhs = other.coerce(self))
|
91
|
+
|
91
92
|
lhs <=> rhs
|
92
93
|
end
|
93
94
|
end
|
@@ -109,15 +110,13 @@ module OpenHAB
|
|
109
110
|
logger.trace("Coercing #{self} as a request from #{other.class}")
|
110
111
|
if other.is_a?(Items::NumericItem) ||
|
111
112
|
(other.is_a?(Items::GroupItem) && other.base_item.is_a?(Items::NumericItem))
|
112
|
-
|
113
|
+
return unless other.state?
|
113
114
|
|
114
115
|
[other.state, self]
|
115
116
|
elsif other.is_a?(Type)
|
116
117
|
[other, as(other.class)]
|
117
118
|
elsif other.respond_to?(:to_d)
|
118
119
|
[self.class.new(other.to_d), self]
|
119
|
-
else
|
120
|
-
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
121
120
|
end
|
122
121
|
end
|
123
122
|
|
@@ -150,8 +149,7 @@ module OpenHAB
|
|
150
149
|
# # result could already be a QuantityType
|
151
150
|
# result = self.class.new(result) unless result.is_a?(NumericType)
|
152
151
|
# result
|
153
|
-
# elsif other.respond_to?(:coerce)
|
154
|
-
# lhs, rhs = other.coerce(to_d)
|
152
|
+
# elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
155
153
|
# lhs + rhs
|
156
154
|
# else
|
157
155
|
# raise TypeError, "#{other.class} can't be coerced into #{self.class}"
|
@@ -168,8 +166,7 @@ module OpenHAB
|
|
168
166
|
# result could already be a QuantityType
|
169
167
|
result = self.class.new(result) unless result.is_a?(NumericType)
|
170
168
|
result
|
171
|
-
elsif other.respond_to?(:coerce)
|
172
|
-
lhs, rhs = other.coerce(to_d)
|
169
|
+
elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
173
170
|
lhs #{ruby_op} rhs
|
174
171
|
else
|
175
172
|
raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
|
@@ -133,7 +133,7 @@ module OpenHAB
|
|
133
133
|
logger.trace("Coercing #{self} as a request from #{other.class}")
|
134
134
|
if other.is_a?(Items::NumericItem) ||
|
135
135
|
(other.is_a?(Items::GroupItem) && other.base_item.is_a?(Items::NumericItem))
|
136
|
-
|
136
|
+
return unless other.state?
|
137
137
|
|
138
138
|
[other.state, self]
|
139
139
|
elsif other.respond_to?(:to_str)
|
@@ -64,7 +64,8 @@ module OpenHAB
|
|
64
64
|
elsif other.respond_to?(:to_str)
|
65
65
|
self == PointType.new(other)
|
66
66
|
elsif other.respond_to?(:coerce)
|
67
|
-
lhs, rhs = other.coerce(self)
|
67
|
+
return false unless (lhs, rhs = other.coerce(self))
|
68
|
+
|
68
69
|
lhs == rhs
|
69
70
|
end
|
70
71
|
end
|
@@ -80,7 +81,10 @@ module OpenHAB
|
|
80
81
|
# @return [[PointType, PointType]]
|
81
82
|
#
|
82
83
|
def coerce(other)
|
83
|
-
|
84
|
+
lhs = coerce_single(other)
|
85
|
+
return unless lhs
|
86
|
+
|
87
|
+
[lhs, self]
|
84
88
|
end
|
85
89
|
|
86
90
|
# rename raw methods so we can overwrite them
|
@@ -123,7 +127,10 @@ module OpenHAB
|
|
123
127
|
# @return [QuantityType]
|
124
128
|
def distance_from(other)
|
125
129
|
logger.trace("(#{self}).distance_from(#{other} (#{other.class})")
|
126
|
-
|
130
|
+
other = coerce_single(other)
|
131
|
+
raise TypeError, "#{other.class} can't be coerced into #{self.class}" unless other
|
132
|
+
|
133
|
+
QuantityType.new(raw_distance_from(other), SIUnits::METRE)
|
127
134
|
end
|
128
135
|
alias - distance_from
|
129
136
|
|
@@ -131,18 +138,16 @@ module OpenHAB
|
|
131
138
|
|
132
139
|
# coerce an object to a PointType
|
133
140
|
# @return [PointType]
|
134
|
-
def coerce_single(other)
|
141
|
+
def coerce_single(other)
|
135
142
|
logger.trace("Coercing #{self} as a request from #{other.class}")
|
136
143
|
if other.is_a?(PointType)
|
137
144
|
other
|
138
145
|
elsif other.is_a?(Items::LocationItem)
|
139
|
-
|
146
|
+
return unless other.state?
|
140
147
|
|
141
148
|
other.state
|
142
149
|
elsif other.respond_to?(:to_str)
|
143
150
|
PointType.new(other.to_str)
|
144
|
-
else
|
145
|
-
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
146
151
|
end
|
147
152
|
end
|
148
153
|
end
|
@@ -61,7 +61,8 @@ module OpenHAB
|
|
61
61
|
elsif other.respond_to?(:to_d)
|
62
62
|
compare_to(QuantityType.new(other.to_d.to_java, Units.unit || unit))
|
63
63
|
elsif other.respond_to?(:coerce)
|
64
|
-
lhs, rhs = other.coerce(self)
|
64
|
+
return nil unless (lhs, rhs = other.coerce(self))
|
65
|
+
|
65
66
|
lhs <=> rhs
|
66
67
|
end
|
67
68
|
end
|
@@ -82,7 +83,7 @@ module OpenHAB
|
|
82
83
|
logger.trace("Coercing #{self} as a request from #{other.class}")
|
83
84
|
if other.is_a?(Items::NumericItem) ||
|
84
85
|
(other.is_a?(Items::GroupItem) && other.base_item.is_a?(Items::NumericItem))
|
85
|
-
|
86
|
+
return unless other.state?
|
86
87
|
|
87
88
|
[other.state, self]
|
88
89
|
elsif other.is_a?(Type)
|
@@ -91,8 +92,6 @@ module OpenHAB
|
|
91
92
|
[QuantityType.new(other.to_d.to_java, ONE), self]
|
92
93
|
elsif other.is_a?(String)
|
93
94
|
[QuantityType.new(other), self]
|
94
|
-
else
|
95
|
-
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
96
95
|
end
|
97
96
|
end
|
98
97
|
|
@@ -123,9 +122,8 @@ module OpenHAB
|
|
123
122
|
# elsif other.respond_to?(:to_d)
|
124
123
|
# other = other.to_d.to_java
|
125
124
|
# add_quantity(self.class.new(other, Units.unit || unit))
|
126
|
-
# elsif other.respond_to?(:coerce)
|
127
|
-
# lhs
|
128
|
-
# lhs = rhs
|
125
|
+
# elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
126
|
+
# lhs + rhs
|
129
127
|
# else
|
130
128
|
# raise TypeError, "#{other.class} can't be coerced into #{self.class}"
|
131
129
|
# end
|
@@ -148,8 +146,7 @@ module OpenHAB
|
|
148
146
|
elsif other.respond_to?(:to_d)
|
149
147
|
other = other.to_d.to_java
|
150
148
|
#{java_op}_quantity(#{convert})
|
151
|
-
elsif other.respond_to?(:coerce)
|
152
|
-
lhs, rhs = other.coerce(to_d)
|
149
|
+
elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
153
150
|
lhs #{ruby_op} rhs
|
154
151
|
else
|
155
152
|
raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
|
@@ -179,8 +176,7 @@ module OpenHAB
|
|
179
176
|
# self * self.class.new(other)
|
180
177
|
# elsif other.respond_to?(:to_d)
|
181
178
|
# multiply(other.to_d.to_java)
|
182
|
-
# elsif other.respond_to?(:coerce)
|
183
|
-
# lhs, rhs = other.coerce(to_d)
|
179
|
+
# elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
184
180
|
# lhs * rhs
|
185
181
|
# else
|
186
182
|
# raise TypeError, "#{other.class} can't be coerced into #{self.class}"
|
@@ -202,8 +198,7 @@ module OpenHAB
|
|
202
198
|
self #{ruby_op} self.class.new(other)
|
203
199
|
elsif other.respond_to?(:to_d)
|
204
200
|
#{java_op}(other.to_d.to_java)
|
205
|
-
elsif other.respond_to?(:coerce)
|
206
|
-
lhs, rhs = other.coerce(to_d)
|
201
|
+
elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
207
202
|
lhs #{ruby_op} rhs
|
208
203
|
else
|
209
204
|
raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
|
@@ -52,7 +52,8 @@ module OpenHAB
|
|
52
52
|
elsif other.respond_to?(:to_str)
|
53
53
|
to_str <=> other.to_str
|
54
54
|
elsif other.respond_to?(:coerce)
|
55
|
-
lhs, rhs = other.coerce(self)
|
55
|
+
return nil unless (lhs, rhs = other.coerce(self))
|
56
|
+
|
56
57
|
lhs <=> rhs
|
57
58
|
end
|
58
59
|
end
|
@@ -70,13 +71,11 @@ module OpenHAB
|
|
70
71
|
def coerce(other)
|
71
72
|
logger.trace("Coercing #{self} as a request from #{other.class}")
|
72
73
|
if other.is_a?(Items::StringItem)
|
73
|
-
|
74
|
+
return unless other.state?
|
74
75
|
|
75
76
|
[other.state, self]
|
76
77
|
elsif other.respond_to?(:to_str)
|
77
78
|
[String.new(other.to_str), self]
|
78
|
-
else
|
79
|
-
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
80
79
|
end
|
81
80
|
end
|
82
81
|
|
@@ -28,8 +28,6 @@ module OpenHAB
|
|
28
28
|
def coerce(other)
|
29
29
|
logger.trace("Coercing #{self} (#{self.class}) as a request from #{other.class}")
|
30
30
|
return [other.as(self.class), self] if other.is_a?(Type)
|
31
|
-
|
32
|
-
raise TypeError, "can't convert #{other.class} into #{self.class}"
|
33
31
|
end
|
34
32
|
|
35
33
|
#
|
@@ -49,7 +47,8 @@ module OpenHAB
|
|
49
47
|
# @return [Boolean] if the same value is represented, including
|
50
48
|
# type conversions
|
51
49
|
#
|
52
|
-
def ==(other)
|
50
|
+
def ==(other) # rubocop:disable Metrics
|
51
|
+
logger.trace("(#{self.class}) #{self} == #{other} (#{other.class})")
|
53
52
|
return true if equal?(other)
|
54
53
|
|
55
54
|
# i.e. ON == OFF, REFRESH == ON, ON == REFRESH
|
@@ -60,7 +59,17 @@ module OpenHAB
|
|
60
59
|
return self == other.raw_state if other.is_a?(Items::GenericItem)
|
61
60
|
|
62
61
|
if other.respond_to?(:coerce)
|
63
|
-
|
62
|
+
begin
|
63
|
+
return false unless (lhs, rhs = other.coerce(self))
|
64
|
+
rescue TypeError
|
65
|
+
# this one is a bit odd. 50 (Integer) == ON is internally
|
66
|
+
# flipping the argument and calling this method. but it responds
|
67
|
+
# to coerce, and then raises a TypeError (from Float???) that
|
68
|
+
# it couldn't convert to OnOffType. it probably should have
|
69
|
+
# returned nil. catch it and return false instead
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
|
64
73
|
return lhs == rhs
|
65
74
|
end
|
66
75
|
|
data/lib/openhab/version.rb
CHANGED
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::
|
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.
|
4
|
+
version: 4.11.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: 2021-11-
|
11
|
+
date: 2021-11-05 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/
|
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
|