openhab-scripting 4.10.0 → 4.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|