openhab-scripting 2.17.0 → 2.18.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: e194635ad3998d2bfb2cb5326522012655b2197a4083ee3def1e5ec572af1bc4
4
- data.tar.gz: b8b1d13fab2d7bcbfcf8599e22bf7c51d88e27434d385dc6db22cf5127476569
3
+ metadata.gz: 44145354fe523ea40a69c6cf2ba81f2684e9982580fe5bc3996f07ab56202e71
4
+ data.tar.gz: ac579ab41fe3f005d7e5a87df7d18c7f32efa9f49c40f251e07620f238b9e65f
5
5
  SHA512:
6
- metadata.gz: 2c924211ea0801f90fcd0b1829f932b5c4a4c7629f00a82212c2188351e6848d9deb94a6d0c20edf4202fdb77a661c64a9ad69cf779ae06e4deffc95aa6c7cca
7
- data.tar.gz: 175c047b5703f52f2e8edbcd7b8df127f19561e35cbe61a31afba9c48199606cf3fdd4b4372f292eb8dc34c4bf700c6171851fc20e976d3d2eb9cc7df693f2fe
6
+ metadata.gz: 00026266f68f7d1c9b1ba442ffe0933ac90b5dbe80b61aa2db25470bf3c166c3f5f73067fbba4c292ad31eaeb6913e56299fc9c3625b1e7ce3efc8aaeac69665
7
+ data.tar.gz: 497fee2e97d90f9e64bd2ba324b9612ed44becb0aec7eb51d4706f1414e3313afeeb3242b5ece884be2fb15525c190a753116548fc2a022c0d4159cff2a8f559
@@ -7,6 +7,7 @@ require 'openhab/dsl/group'
7
7
  require 'openhab/log/logger'
8
8
  require 'openhab/dsl/items/number_item'
9
9
  require 'openhab/dsl/items/string_item'
10
+ require 'openhab/dsl/items/datetime_item'
10
11
 
11
12
  # Automation lookup and injection of OpenHab entities
12
13
  java_import org.openhab.core.items.GroupItem
@@ -84,6 +85,8 @@ module OpenHAB
84
85
  #
85
86
  # @return [Object] the ruby wrapper for the item
86
87
  #
88
+ # rubocop: disable Metrics/MethodLength
89
+ # Method length check disabled - case dispatch pattern
87
90
  private_class_method def self.decorate_item(item)
88
91
  case item
89
92
  when GroupItem
@@ -92,10 +95,13 @@ module OpenHAB
92
95
  OpenHAB::DSL::Items::NumberItem.new(item)
93
96
  when Java::Org.openhab.core.library.items::StringItem
94
97
  OpenHAB::DSL::Items::StringItem.new(item)
98
+ when Java::Org.openhab.core.library.items::DateTimeItem
99
+ OpenHAB::DSL::Items::DateTimeItem.new(item)
95
100
  else
96
101
  item
97
102
  end
98
103
  end
104
+ # rubocop: enable Metrics/MethodLength
99
105
 
100
106
  #
101
107
  # Looks up a Thing in the OpenHAB registry replacing '_' with ':'
@@ -13,11 +13,13 @@ require 'openhab/dsl/timers'
13
13
  require 'openhab/dsl/group'
14
14
  require 'openhab/dsl/things'
15
15
  require 'openhab/dsl/items/items'
16
+ require 'openhab/dsl/items/datetime_item'
16
17
  require 'openhab/dsl/items/number_item'
17
18
  require 'openhab/dsl/time_of_day'
18
19
  require 'openhab/dsl/gems'
19
20
  require 'openhab/dsl/persistence'
20
21
  require 'openhab/dsl/units'
22
+ require 'openhab/dsl/types/datetime'
21
23
  require 'openhab/dsl/types/quantity'
22
24
  require 'openhab/dsl/states'
23
25
 
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'java'
5
+ require 'time'
6
+ require 'openhab/dsl/types/datetime'
7
+
8
+ module OpenHAB
9
+ module DSL
10
+ module Items
11
+ #
12
+ # Delegation to OpenHAB DateTime Item
13
+ #
14
+ # @author Anders Alfredsson
15
+ #
16
+ class DateTimeItem
17
+ extend Forwardable
18
+ include Comparable
19
+
20
+ def_delegator :@datetime_item, :to_s
21
+
22
+ #
23
+ # Create a new DateTimeItem
24
+ #
25
+ # @param [Java::org::openhab::core::libarary::items::DateTimeItem] datetime_item Openhab DateTimeItem to
26
+ # delegate to
27
+ #
28
+ def initialize(datetime_item)
29
+ @datetime_item = datetime_item
30
+ end
31
+
32
+ #
33
+ # Return an instance of DateTime that wraps the DateTimeItem's state
34
+ #
35
+ # @return [OpenHAB::DSL::Types::DateTime] Wrapper for the Item's state, or nil if it has no state
36
+ #
37
+ def to_dt
38
+ OpenHAB::DSL::Types::DateTime.new(@datetime_item.state) if state?
39
+ end
40
+
41
+ #
42
+ # Compare the Item's state to another Item or object that can be compared
43
+ #
44
+ # @param [Object] other Other objet to compare against
45
+ #
46
+ # @return [Integer] -1, 0 or 1 depending on the result of the comparison
47
+ #
48
+ def <=>(other)
49
+ return unless state?
50
+
51
+ logger.trace("Comparing self (#{self.class}) to #{other} (#{other.class})")
52
+ other = other.to_dt if other.is_a? DateTimeItem
53
+ to_dt <=> other
54
+ end
55
+
56
+ #
57
+ # Get the time zone of the Item
58
+ #
59
+ # @return [String] The timezone in `[+-]hh:mm(:ss)` format or nil if the Item has no state
60
+ #
61
+ def zone
62
+ to_dt.zone if state?
63
+ end
64
+
65
+ #
66
+ # Check if missing method can be delegated to other contained objects
67
+ #
68
+ # @param [String, Symbol] meth The method name to check for
69
+ #
70
+ # @return [Boolean] true if DateTimeItem or DateTime responds to the method, false otherwise
71
+ #
72
+ def respond_to_missing?(meth, *)
73
+ @datetime_item.respond_to?(meth) || to_dt.respond_to?(meth)
74
+ end
75
+
76
+ #
77
+ # Forward missing methods to the OpenHAB Item, or a DateTime object wrapping its state
78
+ #
79
+ # @param [String] meth method name
80
+ # @param [Array] args arguments for method
81
+ # @param [Proc] block <description>
82
+ #
83
+ # @return [Object] Value from delegated method in OpenHAB NumberItem
84
+ #
85
+ def method_missing(meth, *args, &block)
86
+ if @datetime_item.respond_to?(meth)
87
+ @datetime_item.__send__(meth, *args, &block)
88
+ elsif state?
89
+ to_dt.send(meth, *args, &block)
90
+ else
91
+ raise NoMethodError, "undefined method `#{meth}' for #{self.class}"
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -4,4 +4,5 @@
4
4
  require 'openhab/dsl/monkey_patch/ruby/range'
5
5
  require 'openhab/dsl/monkey_patch/ruby/number'
6
6
  require 'openhab/dsl/monkey_patch/ruby/string'
7
+ require 'openhab/dsl/monkey_patch/ruby/time'
7
8
  require 'bigdecimal/util'
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module DSL
5
+ module MonkeyPatch
6
+ module Ruby
7
+ #
8
+ # Extend Time to make to_s return string parseable by OpenHAB
9
+ #
10
+ module TimeExtensions
11
+ include OpenHAB::Core
12
+
13
+ #
14
+ # Convert to ISO 8601 format
15
+ #
16
+ # @return [Java::JavaTime::Duration] Duration with number of units from self
17
+ #
18
+ def to_s
19
+ strftime '%FT%T.%N%:z'
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ #
28
+ # Extend Time class with to_s method
29
+ #
30
+ class Time
31
+ prepend OpenHAB::DSL::MonkeyPatch::Ruby::TimeExtensions
32
+ end
@@ -2,8 +2,9 @@
2
2
 
3
3
  require 'java'
4
4
  require 'openhab/log/logger'
5
+ require 'openhab/dsl/items/datetime_item'
6
+ require 'openhab/dsl/types/datetime'
5
7
  require 'time'
6
- require 'date'
7
8
 
8
9
  module OpenHAB
9
10
  module DSL
@@ -172,8 +173,9 @@ module OpenHAB
172
173
  case object
173
174
  when TimeOfDay then adjust_second_of_day(object.local_time.to_second_of_day)
174
175
  when String then adjust_second_of_day(TimeOfDay.parse(object).local_time.to_second_of_day)
175
- when Time then adjust_second_of_day(TimeOfDay.new(h: object.hour, m: object.min,
176
- s: object.sec).local_time.to_second_of_day)
176
+ when Time, OpenHAB::DSL::Types::DateTime, OpenHAB::DSL::Items::DateTimeItem
177
+ adjust_second_of_day(TimeOfDay.new(h: object.hour, m: object.min, s: object.sec)
178
+ .local_time.to_second_of_day)
177
179
  when TimeOfDayRangeElement then object.sod
178
180
  else raise ArgumentError, 'Supplied argument cannot be converted into Time Of Day Object'
179
181
  end
@@ -216,6 +218,8 @@ module OpenHAB
216
218
  private_class_method def to_time_of_day(object)
217
219
  case object
218
220
  when String then TimeOfDay.parse(object)
221
+ when Time, OpenHAB::DSL::Types::DateTime, OpenHAB::DSL::Items::DateTimeItem
222
+ TimeOfDay.new(h: object.hour, m: object.min, s: object.sec)
219
223
  else object
220
224
  end
221
225
  end
@@ -0,0 +1,326 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+ require 'forwardable'
5
+ require 'time'
6
+
7
+ module OpenHAB
8
+ module DSL
9
+ module Types
10
+ #
11
+ # Ruby implementation for OpenHAB DateTimeType
12
+ #
13
+ # @author Anders Alfredsson
14
+ #
15
+ # rubocop: disable Metrics/ClassLength
16
+ # Disabled because this class has a single responsibility, there does not appear a logical
17
+ # way of breaking it up into multiple classes
18
+ class DateTime
19
+ extend Forwardable
20
+ include Comparable
21
+ include OpenHAB::Log
22
+
23
+ def_delegator :datetime, :to_s
24
+ def_delegator :zoned_date_time, :month_value, :month
25
+ def_delegator :zoned_date_time, :minute, :min
26
+ def_delegator :zoned_date_time, :second, :sec
27
+ def_delegator :zoned_date_time, :nano, :nsec
28
+ def_delegator :zoned_date_time, :to_epoch_second, :to_i
29
+ alias inspect to_s
30
+
31
+ java_import Java::OrgOpenhabCoreLibraryTypes::DateTimeType
32
+ java_import java.time.ZonedDateTime
33
+ java_import java.time.Instant
34
+ java_import java.time.ZoneId
35
+ java_import java.time.ZoneOffset
36
+ java_import java.time.Duration
37
+
38
+ #
39
+ # Regex expression to identify strings defining a time in hours, minutes and optionally seconds
40
+ #
41
+ TIME_ONLY_REGEX = /\A\d\d:\d\d(:\d\d)?\Z/.freeze
42
+
43
+ #
44
+ # Regex expression to identify strings defining a time in hours, minutes and optionally seconds
45
+ #
46
+ DATE_ONLY_REGEX = /\A\d{4}-\d\d-\d\d\Z/.freeze
47
+
48
+ attr_reader :datetime
49
+
50
+ #
51
+ # Create a new DateTime instance wrapping an OpenHAB DateTimeType
52
+ #
53
+ # @param [Java::org::openhab::core::library::types::DateTimeType] datetime The DateTimeType instance to
54
+ # delegate to, or an object that can be converted to a DateTimeType
55
+ #
56
+ def initialize(datetime)
57
+ @datetime = case datetime
58
+ when DateTimeType
59
+ datetime
60
+ when ZonedDateTime
61
+ DateTimeType.new(datetime)
62
+ else
63
+ raise "Unexpected type #{datetime.class} provided to DateTime initializer"
64
+ end
65
+ end
66
+
67
+ #
68
+ # Compare thes DateTime object to another
69
+ #
70
+ # @param [Object] other Other object to compare against
71
+ #
72
+ # @return [Integer] -1, 0 or 1 depending on the outcome
73
+ #
74
+ def <=>(other)
75
+ case other
76
+ when DateTime, DateTimeType, DateTimeItem
77
+ zoned_date_time.to_instant.compare_to(other.zoned_date_time.to_instant)
78
+ when TimeOfDay::TimeOfDay, TimeOfDay::TimeOfDayRangeElement
79
+ to_tod <=> other
80
+ when String
81
+ self <=> DateTime.parse(DATE_ONLY_REGEX =~ other ? "#{other}'T'00:00:00#{zone}" : other)
82
+ else
83
+ self <=> DateTime.from(other)
84
+ end
85
+ end
86
+
87
+ #
88
+ # Adds another object to this DateTime
89
+ #
90
+ # @param [Object] other Object to add to this. Can be a Numeric, another DateTime/Time/DateTimeType, a
91
+ # Duration or a String that can be parsed into a DateTimeType or Time object
92
+ #
93
+ # @return [DateTime] A new DateTime object representing the result of the calculation
94
+ #
95
+ def +(other)
96
+ logger.trace("Adding #{other} (#{other.class}) to #{self}")
97
+ case other
98
+ when Numeric then DateTime.from(to_time + other)
99
+ when DateTime, Time then self + other.to_f
100
+ when DateTimeType, String then self + DateTime.from(other).to_f
101
+ when Duration then DateTime.new(zoned_date_time.plus(other))
102
+ end
103
+ end
104
+
105
+ #
106
+ # Subtracts another object from this DateTime
107
+ #
108
+ # @param [Object] other Object to subtract fom this. Can be a Numeric, another DateTime/Time/DateTimeType, a
109
+ # Duration or a String that can be parsed into a DateTimeType or Time object
110
+ #
111
+ # @return [DateTime, Float] A new DateTime object representing the result of the calculation, or a Float
112
+ # representing the time difference in seconds if the subtraction is between two time objects
113
+ #
114
+ def -(other)
115
+ logger.trace("Subtracting #{other} (#{other.class}) from self")
116
+ case other
117
+ when Numeric then DateTime.from(to_time - other)
118
+ when String
119
+ dt = DateTime.parse(other)
120
+ TIME_ONLY_REGEX =~ other ? self - dt.to_f : time_diff(dt)
121
+ when Duration then DateTime.new(zoned_date_time.minus(other))
122
+ when Time, DateTime, DateTimeType, DateTimeItem then time_diff(other)
123
+ end
124
+ end
125
+
126
+ #
127
+ # Convert this DateTime to a ruby Time object
128
+ #
129
+ # @return [Time] A Time object representing the same instant and timezone
130
+ #
131
+ def to_time
132
+ Time.at(to_i, nsec, :nsec).localtime(utc_offset)
133
+ end
134
+
135
+ #
136
+ # Convert the time part of this DateTime to a TimeOfDay object
137
+ #
138
+ # @return [TimeOfDay] A TimeOfDay object representing the time
139
+ #
140
+ def to_time_of_day
141
+ TimeOfDay::TimeOfDay.new(h: hour, m: minute, s: second)
142
+ end
143
+
144
+ alias to_tod to_time_of_day
145
+
146
+ #
147
+ # Returns the value of time as a floating point number of seconds since the Epoch
148
+ #
149
+ # @return [Float] Number of seconds since the Epoch, with nanosecond presicion
150
+ #
151
+ def to_f
152
+ zoned_date_time.to_epoch_second + zoned_date_time.nano / 1_000_000_000
153
+ end
154
+
155
+ #
156
+ # The ZonedDateTime representing the state
157
+ #
158
+ # @return [Java::java::time::ZonedDateTime] ZonedDateTime representing the state
159
+ #
160
+ def zoned_date_time
161
+ @datetime.zonedDateTime
162
+ end
163
+
164
+ alias to_zdt zoned_date_time
165
+
166
+ #
167
+ # The offset in seconds from UTC
168
+ #
169
+ # @return [Integer] The offset from UTC, in seconds
170
+ #
171
+ def utc_offset
172
+ zoned_date_time.offset.total_seconds
173
+ end
174
+
175
+ #
176
+ # Returns true if time represents a time in UTC (GMT)
177
+ #
178
+ # @return [Boolean] true if utc_offset == 0, false otherwise
179
+ #
180
+ def utc?
181
+ utc_offset.zero?
182
+ end
183
+
184
+ #
185
+ # The timezone
186
+ #
187
+ # @return [String] The timezone in `[+-]hh:mm(:ss)` format ('Z' for UTC) or nil if the Item has no state
188
+ #
189
+ def zone
190
+ zoned_date_time.zone.id
191
+ end
192
+
193
+ #
194
+ # Check if missing method can be delegated to other contained objects
195
+ #
196
+ # @param [String, Symbol] meth the method name to check for
197
+ #
198
+ # @return [Boolean] true if DateTimeType, ZonedDateTime or Time responds to the method, false otherwise
199
+ #
200
+ def respond_to_missing?(meth, *)
201
+ @datetime.respond_to?(meth) ||
202
+ zoned_date_time.respond_to?(meth) ||
203
+ Time.instance_methods.include?(meth.to_sym)
204
+ end
205
+
206
+ #
207
+ # Forward missing methods to the OpenHAB DateTimeType, its ZonedDateTime object or a ruby Time
208
+ # object representing the same instant
209
+ #
210
+ # @param [String] meth method name
211
+ # @param [Array] args arguments for method
212
+ # @param [Proc] block <description>
213
+ #
214
+ # @return [Object] Value from delegated method in OpenHAB NumberItem
215
+ #
216
+ def method_missing(meth, *args, &block)
217
+ if @datetime.respond_to?(meth)
218
+ @datetime.__send__(meth, *args, &block)
219
+ elsif zoned_date_time.respond_to?(meth)
220
+ zoned_date_time.__send__(meth, *args, &block)
221
+ elsif Time.instance_methods.include?(meth.to_sym)
222
+ to_time.send(meth, *args, &block)
223
+ else
224
+ raise NoMethodError, "undefined method `#{meth}' for #{self.class}"
225
+ end
226
+ end
227
+
228
+ #
229
+ # Converts other objects to a DateTimeType
230
+ #
231
+ # @param [String, Numeric, Time] datetime an object that can be parsed or converted into
232
+ # a DateTimeType
233
+ #
234
+ # @return [Java::org::openhab::core::library::types::DateTimeType] Object representing the same time
235
+ #
236
+ def self.from(datetime)
237
+ case datetime
238
+ when String
239
+ parse(datetime)
240
+ when Numeric
241
+ from_numeric(datetime)
242
+ when Time
243
+ from_time(datetime)
244
+ else
245
+ raise "Cannot convert #{datetime.class} to DateTime"
246
+ end
247
+ end
248
+
249
+ #
250
+ # Converts a Numeric into a DateTimeType
251
+ #
252
+ # @param [Numeric] numeric A Integer or Float representing the number of seconds since the epoch
253
+ #
254
+ # @return [Java::org::openhab::core::library::types::DateTimeType] Object representing the same time
255
+ #
256
+ def self.from_numeric(numeric)
257
+ case numeric
258
+ when Integer
259
+ DateTime.new(ZonedDateTime.ofInstant(Instant.ofEpochSecond(datetime), ZoneId.systemDefault))
260
+ else
261
+ DateTime.new(ZonedDateTime.ofInstant(Instant.ofEpochSecond(datetime.to_i,
262
+ ((datetime % 1) * 1_000_000_000).to_i),
263
+ ZoneId.systemDefault))
264
+ end
265
+ end
266
+
267
+ #
268
+ # Converts a ruby Time object to an OpenHAB DateTimeType
269
+ #
270
+ # @param [Time] time The Time object to be converted
271
+ #
272
+ # @return [Java::org::openhab::core::library::types::DateTimeType] Object representing the same time
273
+ #
274
+ def self.from_time(time)
275
+ instant = Instant.ofEpochSecond(time.to_i, time.nsec)
276
+ zone_id = ZoneId.of_offset('UTC', ZoneOffset.of_total_seconds(time.utc_offset))
277
+ DateTime.new(ZonedDateTime.ofInstant(instant, zone_id))
278
+ end
279
+
280
+ #
281
+ # Parses a string representing a time into an OpenHAB DateTimeType. First tries to parse it
282
+ # using the DateTimeType's parser, then falls back to the ruby Time.parse
283
+ #
284
+ # @param [String] time_string The string to be parsed
285
+ #
286
+ # @return [Java::org::openhab::core::library::types::DateTimeType] Object representing the same time
287
+ #
288
+ def self.parse(time_string)
289
+ time_string += 'Z' if TIME_ONLY_REGEX =~ time_string
290
+ DateTime.new(DateTimeType.new(time_string))
291
+ rescue Java::JavaLang::StringIndexOutOfBoundsException, Java::JavaLang::IllegalArgumentException
292
+ # Try ruby's Time.parse if OpenHAB's DateTimeType parser fails
293
+ begin
294
+ time = Time.parse(time_string)
295
+ DateTime.from(time)
296
+ rescue ArgumentError
297
+ raise "Unable to parse #{time_string} into a DateTime"
298
+ end
299
+ end
300
+
301
+ private
302
+
303
+ #
304
+ # Calculates the difference in time between this instance and another time object
305
+ #
306
+ # @param [Time, DateTime, DateTimeItem, Java::org::openhab::core::library::types::DateTimeType] time_obj
307
+ # The other time object to subtract from self
308
+ #
309
+ # @return [Float] The time difference between the two objects, in seconds
310
+ #
311
+ def time_diff(time_obj)
312
+ logger.trace("Calculate time difference between #{self} and #{time_obj}")
313
+ case time_obj
314
+ when Time
315
+ to_time - time_obj
316
+ when DateTime, DateTimeItem
317
+ self - time_obj.to_time
318
+ when DateTimeType
319
+ self - DateTime.new(time_obj).to_time
320
+ end
321
+ end
322
+ end
323
+ end
324
+ end
325
+ end
326
+ # rubocop: enable Metrics/ClassLength
@@ -5,5 +5,5 @@
5
5
  #
6
6
  module OpenHAB
7
7
  # @return [String] Version of OpenHAB helper libraries
8
- VERSION = '2.17.0'
8
+ VERSION = '2.18.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: 2.17.0
4
+ version: 2.18.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-02-12 00:00:00.000000000 Z
11
+ date: 2021-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -39,6 +39,7 @@ files:
39
39
  - lib/openhab/dsl/dsl.rb
40
40
  - lib/openhab/dsl/gems.rb
41
41
  - lib/openhab/dsl/group.rb
42
+ - lib/openhab/dsl/items/datetime_item.rb
42
43
  - lib/openhab/dsl/items/items.rb
43
44
  - lib/openhab/dsl/items/number_item.rb
44
45
  - lib/openhab/dsl/items/string_item.rb
@@ -59,6 +60,7 @@ files:
59
60
  - lib/openhab/dsl/monkey_patch/ruby/range.rb
60
61
  - lib/openhab/dsl/monkey_patch/ruby/ruby.rb
61
62
  - lib/openhab/dsl/monkey_patch/ruby/string.rb
63
+ - lib/openhab/dsl/monkey_patch/ruby/time.rb
62
64
  - lib/openhab/dsl/monkey_patch/types/decimal_type.rb
63
65
  - lib/openhab/dsl/monkey_patch/types/on_off_type.rb
64
66
  - lib/openhab/dsl/monkey_patch/types/open_closed_type.rb
@@ -81,6 +83,7 @@ files:
81
83
  - lib/openhab/dsl/things.rb
82
84
  - lib/openhab/dsl/time_of_day.rb
83
85
  - lib/openhab/dsl/timers.rb
86
+ - lib/openhab/dsl/types/datetime.rb
84
87
  - lib/openhab/dsl/types/quantity.rb
85
88
  - lib/openhab/dsl/units.rb
86
89
  - lib/openhab/log/configuration.rb