openhab-scripting 5.27.2 → 5.29.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: 55919e4e10099bb160e0f64578c398caef457c330e88df280a20ed20ffec6310
4
- data.tar.gz: 2052d4bcd4dc3bcd7b2be5c4bb7b995fcaebc7101b93e24fd2db0e849b80ff36
3
+ metadata.gz: 795ee1035ecfb1a7f38f50243ed0d28af8a578e7d586eedd97c8362d6f4cd03d
4
+ data.tar.gz: d1785eb66e599bb3b78a3ab473618a080bffa117a53ddaf13c506e298806d8ad
5
5
  SHA512:
6
- metadata.gz: 1c39a9d29033bf7844d1f5666f57be9ae99ae595a8d5f85e4464b6077c0171e4f4e9e19d933f17a0e190c2081dae57dc29136bb4c3e295f2d83e8e1d88374ce1
7
- data.tar.gz: 5a828c34365b2d8fcef74c46fe19e94fc30dbb0c4fd17fcef7bc717a95ccb2e0b51cfadf701447d9a97c58057baebe77d8186811886479112096b46e16749a28
6
+ metadata.gz: 3af8371312fdf0dce313b87513db7540545639ef440358c1256f03fe8018768c33636f5aff09bcc1cdceb9a04988492921651fd4ed269f824b18a330feec8088
7
+ data.tar.gz: 698841f7a0fd45ca777e1561b915e9c695c309ba9ac802d7a319733f6501539959d55ce2d6ddae8fd9cbee4c35d8d089da74d74fa6011c9b6978b68028449b1c
@@ -4,14 +4,14 @@ module OpenHAB
4
4
  module Core
5
5
  module Actions
6
6
  #
7
- # Provides methods for {https://next.openhab.org/addons/integrations/openhabcloud/#cloud-notification-actions
7
+ # Provides methods for {https://www.openhab.org/addons/integrations/openhabcloud/#cloud-notification-actions
8
8
  # openHAB Cloud Notification Actions}.
9
9
  #
10
10
  class Notification
11
11
  class << self
12
12
  #
13
13
  # Send a notification using
14
- # {https://next.openhab.org/addons/integrations/openhabcloud/#cloud-notification-actions
14
+ # {https://www.openhab.org/addons/integrations/openhabcloud/#cloud-notification-actions
15
15
  # openHAB Cloud Notification Action}.
16
16
  #
17
17
  # @param msg [String] The message to send.
@@ -27,7 +27,7 @@ module OpenHAB
27
27
  # Subsequent notifications using the same reference ID will
28
28
  # update/overwrite the existing notification with the same ID.
29
29
  # @param on_click [String, nil] The action to be performed when the user clicks on the notification.
30
- # Specified using the {https://next.openhab.org/addons/integrations/openhabcloud/#action-syntax
30
+ # Specified using the {https://www.openhab.org/addons/integrations/openhabcloud/#action-syntax
31
31
  # action syntax}.
32
32
  # @param attachment [String, Item, nil] The URL of the media attachment to be displayed with the notification.
33
33
  # This can either be a fully qualified URL, prefixed with
@@ -36,7 +36,7 @@ module OpenHAB
36
36
  # or an image item.
37
37
  # @param buttons [Array<String>, Hash<String, String>, nil] Buttons to include in the notification.
38
38
  # - In array form, each element is specified as `Title=$action`, where `$action` follows the
39
- # {https://next.openhab.org/addons/integrations/openhabcloud/#action-syntax action syntax}.
39
+ # {https://www.openhab.org/addons/integrations/openhabcloud/#action-syntax action syntax}.
40
40
  # - In hash form, the keys are the button titles and the values are the actions.
41
41
  #
42
42
  # The maximum number of buttons is 3.
@@ -91,7 +91,7 @@ module OpenHAB
91
91
  tag ||= severity
92
92
  args.push(msg.to_s, icon&.to_s, tag&.to_s)
93
93
 
94
- # @!deprecated OH 4.1
94
+ # @deprecated OH 4.1
95
95
  if Core.version >= Core::V4_2
96
96
  buttons ||= []
97
97
  buttons = buttons.map { |title, action| "#{title}=#{action}" } if buttons.is_a?(Hash)
@@ -13,9 +13,6 @@ module OpenHAB
13
13
  # it must be replaced with an underscore `_`. So to access `astro:sun:home`, use `astro_sun_home`
14
14
  # as an alternative to `things["astro:sun:home"]`
15
15
  #
16
- # @see OpenHAB::DSL.items items[]
17
- # @see OpenHAB::DSL.things things[]
18
- #
19
16
  # @example Accessing Items and Groups
20
17
  # gAll_Lights # Access the gAll_Lights group. It is the same as items["gAll_Lights"]
21
18
  # Kitchen_Light.on # The openHAB object for the Kitchen_Light item and send an ON command
@@ -66,6 +63,61 @@ module OpenHAB
66
63
  end
67
64
  end
68
65
 
66
+ #
67
+ # Fetches all items from the item registry
68
+ #
69
+ # @return [Core::Items::Registry]
70
+ #
71
+ # The examples all assume the following items exist.
72
+ #
73
+ # ```xtend
74
+ # Dimmer DimmerTest "Test Dimmer"
75
+ # Switch SwitchTest "Test Switch"
76
+ # ```
77
+ #
78
+ # @example
79
+ # logger.info("Item Count: #{items.count}") # Item Count: 2
80
+ # logger.info("Items: #{items.map(&:label).sort.join(', ')}") # Items: Test Dimmer, Test Switch'
81
+ # logger.info("DimmerTest exists? #{items.key?('DimmerTest')}") # DimmerTest exists? true
82
+ # logger.info("StringTest exists? #{items.key?('StringTest')}") # StringTest exists? false
83
+ #
84
+ # @example
85
+ # rule 'Use dynamic item lookup to increase related dimmer brightness when switch is turned on' do
86
+ # changed SwitchTest, to: ON
87
+ # triggered { |item| items[item.name.gsub('Switch','Dimmer')].brighten(10) }
88
+ # end
89
+ #
90
+ # @example
91
+ # rule 'search for a suitable item' do
92
+ # on_load
93
+ # triggered do
94
+ # # Send ON to DimmerTest if it exists, otherwise send it to SwitchTest
95
+ # (items['DimmerTest'] || items['SwitchTest'])&.on
96
+ # end
97
+ # end
98
+ #
99
+ def items
100
+ Core::Items::Registry.instance
101
+ end
102
+
103
+ #
104
+ # Get all things known to openHAB
105
+ #
106
+ # @return [Core::Things::Registry] all Thing objects known to openHAB
107
+ #
108
+ # @example
109
+ # things.each { |thing| logger.info("Thing: #{thing.uid}")}
110
+ # logger.info("Thing: #{things['astro:sun:home'].uid}")
111
+ # homie_things = things.select { |t| t.thing_type_uid == "mqtt:homie300" }
112
+ # zwave_things = things.select { |t| t.binding_id == "zwave" }
113
+ # homeseer_dimmers = zwave_things.select { |t| t.thing_type_uid.id == "homeseer_hswd200_00_000" }
114
+ # things['zwave:device:512:node90'].uid.bridge_ids # => ["512"]
115
+ # things['mqtt:topic:4'].uid.bridge_ids # => []
116
+ #
117
+ def things
118
+ Core::Things::Registry.instance
119
+ end
120
+
69
121
  #
70
122
  # Automatically looks up openHAB items and things in appropriate registries
71
123
  #
@@ -34,6 +34,29 @@ module OpenHAB
34
34
  payload&.[](:itemName)&.then { |item_name| EntityLookup.lookup_item(item_name) }
35
35
  end
36
36
 
37
+ #
38
+ # @!attribute [r] time_only?
39
+ # @return [Boolean]
40
+ # `true` when this event was triggered by a {Core::Items::DateTimeItem DateTimeItem} with `timeOnly` set.
41
+ # `false` when this event wasn't triggered by a DateTimeItem or the `timeOnly` flag is not set.
42
+ # @see DSL::Rules::BuilderDSL::every #every trigger
43
+ # @see DSL::Rules::BuilderDSL::at #at trigger
44
+ # @since openHAB 4.3
45
+ #
46
+ def time_only?
47
+ !!payload&.[](:timeOnly)
48
+ end
49
+
50
+ #
51
+ # @!attribute [r] offset
52
+ # @return [Duration, nil] The offset from the configured time for this DateTime trigger event.
53
+ # `nil` when this event wasn't triggered by a DateTime trigger.
54
+ # @since openHAB 4.3
55
+ #
56
+ def offset
57
+ payload&.[](:offset)&.seconds
58
+ end
59
+
37
60
  #
38
61
  # @!attribute [r] time
39
62
  # @return [LocalTime, nil] The configured time for this TimeOfDay trigger event.
@@ -51,6 +51,17 @@ module OpenHAB
51
51
  zoned_date_time
52
52
  end
53
53
 
54
+ # @!visibility private
55
+ def to_instant(_context = nil)
56
+ # @deprecated OH 3.4 getInstant() was added in OH 4.0
57
+ return get_instant if respond_to?(:get_instant)
58
+
59
+ zoned_date_time.to_instant
60
+ end
61
+
62
+ # @!method to_instant
63
+ # @return [Instant]
64
+
54
65
  # act like a Ruby Time
55
66
  def_delegator :zoned_date_time, :month_value, :month
56
67
  def_delegator :zoned_date_time, :day_of_month, :mday
@@ -1,12 +1,148 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "forwardable"
4
+
5
+ require_relative "time"
6
+
3
7
  module OpenHAB
4
8
  module CoreExt
5
9
  module Java
6
- java_import java.time.Instant
10
+ Instant = java.time.Instant
7
11
 
8
12
  # Extensions to {java.time.Instant}
9
- class Instant < java.lang.Object; end
13
+ class Instant < java.lang.Object
14
+ extend Forwardable
15
+ include Time
16
+ include Between
17
+
18
+ class << self # rubocop:disable Lint/EmptyClass
19
+ # @!scope class
20
+
21
+ # @!attribute [r] now
22
+ # @return [Instant]
23
+
24
+ # @!method parse(text, formatter = nil)
25
+ # Parses a string into an Instant object.
26
+ #
27
+ # @param [String] text The text to parse.
28
+ # @param [java.time.format.DateTimeFormatter] formatter The formatter to use.
29
+ # @return [Instant]
30
+ end
31
+
32
+ # @!scope instance
33
+
34
+ # @!method to_local_time
35
+ # @return [LocalTime]
36
+ # @!method to_local_date
37
+ # @return [LocalDate]
38
+ # @!method to_month_day
39
+ # @return [MonthDay]
40
+ # @!method to_date
41
+ # @return [Date]
42
+ # @!method to_month
43
+ # @return [Month]
44
+ # @!method yesterday?
45
+ # (see OpenHAB::CoreExt::Java::ZonedDateTime#yesterday?)
46
+ # @!method today?
47
+ # (see OpenHAB::CoreExt::Java::ZonedDateTime#today?)
48
+ # @!method tomorrow?
49
+ # (see OpenHAB::CoreExt::Java::ZonedDateTime#tomorrow?)
50
+ def_delegators :to_zoned_date_time,
51
+ :to_local_time,
52
+ :to_local_date,
53
+ :to_date,
54
+ :to_month_day,
55
+ :to_month,
56
+ :yesterday?,
57
+ :today?,
58
+ :tomorrow?
59
+
60
+ # @param [TemporalAmount, #to_instant, #to_zoned_date_time, Numeric] other
61
+ # If other is a Numeric, it's interpreted as seconds.
62
+ # @return [Duration] If other responds to #to_zoned_date_time
63
+ # @return [Instant] If other is a TemporalAmount
64
+ def -(other)
65
+ if other.is_a?(Instant)
66
+ java.time.Duration.between(other, self)
67
+ elsif other.respond_to?(:to_instant)
68
+ java.time.Duration.between(other.to_instant, self)
69
+ elsif other.respond_to?(:to_zoned_date_time)
70
+ java.time.Duration.between(other.to_zoned_date_time.to_instant, self)
71
+ elsif other.is_a?(Numeric)
72
+ minus(other.seconds)
73
+ else
74
+ minus(other)
75
+ end
76
+ end
77
+
78
+ # @param [TemporalAmount, Numeric] other
79
+ # If other is a Numeric, it's interpreted as seconds.
80
+ # @return [Instant]
81
+ def +(other)
82
+ return plus(other.seconds) if other.is_a?(Numeric)
83
+
84
+ plus(other)
85
+ end
86
+
87
+ #
88
+ # The number of seconds since the Unix epoch.
89
+ # @return [Integer]
90
+ #
91
+ def to_i
92
+ epoch_second
93
+ end
94
+
95
+ #
96
+ # The number of seconds since the Unix epoch.
97
+ # @return [Float]
98
+ #
99
+ def to_f
100
+ ((epoch_second * 1_000_000_000) + nano).fdiv(1_000_000_000.0)
101
+ end
102
+
103
+ # This comes from JRuby
104
+
105
+ # @!method to_time
106
+ # @return [Time]
107
+
108
+ # @return [Integer, nil]
109
+ def <=>(other)
110
+ logger.trace { "(#{self.class}) #{self} <=> #{other} (#{other.class})" }
111
+ # compare instants, otherwise it will differ by timezone, which we don't want
112
+ # (use eql? if you care about that)
113
+ if other.respond_to?(:to_instant)
114
+ logger.trace { "Comparing #{self} to #{other.to_instant}" }
115
+ compare_to(other.to_instant(to_zoned_date_time))
116
+ elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(self))
117
+ lhs <=> rhs
118
+ end
119
+ end
120
+
121
+ # @param [ZonedDateTime, nil] context A {ZonedDateTime} used to match the zone id. Defaults to UTC.
122
+ # @return [ZonedDateTime]
123
+ def to_zoned_date_time(context = nil)
124
+ zone = context&.zone || java.time.ZoneOffset::UTC
125
+ at_zone(zone)
126
+ end
127
+
128
+ # @!visibility private
129
+ def to_instant(_context = nil)
130
+ self
131
+ end
132
+
133
+ #
134
+ # Converts `other` to {Instant}, if possible
135
+ #
136
+ # @param [#to_instant] other
137
+ # @return [Array, nil]
138
+ #
139
+ def coerce(other)
140
+ logger.trace { "Coercing #{self} as a request from #{other.class}" }
141
+ return [other.to_instant(to_zoned_date_time), self] if other.respond_to?(:to_instant)
142
+
143
+ [other.to_zoned_date_time(zoned_date_time).to_instant, self] if other.respond_to?(:to_zoned_date_time)
144
+ end
145
+ end
10
146
  end
11
147
  end
12
148
  end
@@ -96,6 +96,15 @@ module OpenHAB
96
96
  zone = context&.zone || java.time.ZoneId.system_default
97
97
  at_start_of_day(zone)
98
98
  end
99
+
100
+ # @param [ZonedDateTime, nil] context
101
+ # A {ZonedDateTime} used to fill in missing fields
102
+ # during conversion. {ZonedDateTime.now} is assumed if not given.
103
+ # @return [Instant]
104
+ def to_instant(context = nil)
105
+ zone = context&.zone || java.time.ZoneOffset::UTC
106
+ at_start_of_day(zone).to_instant
107
+ end
99
108
  end
100
109
  end
101
110
  end
@@ -111,6 +111,15 @@ module OpenHAB
111
111
  context ||= ZonedDateTime.now
112
112
  context.with(self)
113
113
  end
114
+
115
+ # @param [ZonedDateTime, nil] context
116
+ # A {ZonedDateTime} used to fill in missing fields
117
+ # during conversion. {ZonedDateTime.now} is assumed if not given.
118
+ # @return [Instant]
119
+ def to_instant(context = nil)
120
+ context ||= Instant.now.to_zoned_date_time
121
+ to_zoned_date_time(context).to_instant
122
+ end
114
123
  end
115
124
  end
116
125
  end
@@ -62,6 +62,16 @@ module OpenHAB
62
62
  def to_zoned_date_time(context = nil)
63
63
  to_local_date(context).to_zoned_date_time(context)
64
64
  end
65
+
66
+ # @param [ZonedDateTime, nil] context
67
+ # A {ZonedDateTime} used to fill in the year during conversion,
68
+ # with the date set to the first day of the month.
69
+ # {Instant.now} is assumed if not given.
70
+ # @return [Instant]
71
+ def to_instant(context = nil)
72
+ context ||= Instant.now.to_zoned_date_time
73
+ to_local_date(context).to_instant
74
+ end
65
75
  end
66
76
  end
67
77
  end
@@ -112,6 +112,15 @@ module OpenHAB
112
112
  def to_zoned_date_time(context = nil)
113
113
  to_local_date(context).to_zoned_date_time(context)
114
114
  end
115
+
116
+ # @param [ZonedDateTime, nil] context
117
+ # A {ZonedDateTime} used to fill in missing year during conversion,
118
+ # {ZonedDateTime.now} is assumed if not given.
119
+ # @return [Instant]
120
+ def to_instant(context = nil)
121
+ context ||= Instant.now.to_zoned_date_time
122
+ to_local_date(context).to_instant
123
+ end
115
124
  end
116
125
  end
117
126
  end
@@ -38,6 +38,7 @@ module OpenHAB
38
38
  # less than, equal to, or greater than self
39
39
  #
40
40
  def <=>(other)
41
+ logger.trace { "(#{self.class}) #{self} <=> #{other} (#{other.class})" }
41
42
  if other.is_a?(self.class)
42
43
  compare_to(other)
43
44
  elsif other.respond_to?(:coerce)
@@ -50,6 +51,7 @@ module OpenHAB
50
51
  # Convert `other` to this class, if possible
51
52
  # @return [Array, nil]
52
53
  def coerce(other)
54
+ logger.trace { "Coercing #{self} as a request from #{other.class}" }
53
55
  coercion_method = self.class.coercion_method
54
56
  return unless other.respond_to?(coercion_method)
55
57
  return [other.send(coercion_method), self] if other.method(coercion_method).arity.zero?
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "forwardable"
4
+
3
5
  require_relative "time"
4
6
 
5
7
  module OpenHAB
@@ -9,6 +11,7 @@ module OpenHAB
9
11
 
10
12
  # Extensions to {java.time.ZonedDateTime}
11
13
  class ZonedDateTime
14
+ extend Forwardable
12
15
  include Time
13
16
  include Between
14
17
 
@@ -60,20 +63,20 @@ module OpenHAB
60
63
  end
61
64
 
62
65
  #
66
+ # @!method to_i
63
67
  # The number of seconds since the Unix epoch.
64
68
  #
65
69
  # @return [Integer]
66
- def to_i
67
- to_instant.epoch_second
68
- end
70
+ #
69
71
 
70
72
  #
73
+ # @!method to_f
71
74
  # The number of seconds since the Unix epoch.
72
75
  #
73
76
  # @return [Float]
74
- def to_f
75
- to_instant.to_epoch_milli / 1000.0
76
- end
77
+ #
78
+
79
+ delegate %i[to_i to_f] => :to_instant
77
80
 
78
81
  # @return [Date]
79
82
  def to_date
@@ -103,6 +106,36 @@ module OpenHAB
103
106
  self
104
107
  end
105
108
 
109
+ #
110
+ # Returns true if the date, converted to the system time zone, is yesterday.
111
+ #
112
+ # @return [true, false]
113
+ #
114
+ def yesterday?
115
+ with_zone_same_instant(ZoneId.system_default).to_local_date == LocalDate.now - 1
116
+ end
117
+
118
+ #
119
+ # Returns true if the date, converted to the system time zone, is today.
120
+ #
121
+ # This is the equivalent of checking if the current datetime is between midnight and end of the day
122
+ # of the system time zone.
123
+ #
124
+ # @return [true, false]
125
+ #
126
+ def today?
127
+ with_zone_same_instant(ZoneId.system_default).to_local_date == LocalDate.now
128
+ end
129
+
130
+ #
131
+ # Returns true if the date, converted to the system time zone, is tomorrow.
132
+ #
133
+ # @return [true, false]
134
+ #
135
+ def tomorrow?
136
+ with_zone_same_instant(ZoneId.system_default).to_local_date == LocalDate.now + 1
137
+ end
138
+
106
139
  # @group Ephemeris Methods
107
140
  # (see CoreExt::Ephemeris)
108
141
 
@@ -196,6 +229,20 @@ module OpenHAB
196
229
  end
197
230
  end
198
231
 
232
+ # @!visibility private
233
+ alias_method :raw_to_instant, :to_instant
234
+
235
+ # @!visibility private
236
+ def to_instant(_context = nil)
237
+ raw_to_instant
238
+ end
239
+
240
+ #
241
+ # @!method to_instant
242
+ # Converts this object to an {Instant}
243
+ # @return [Instant]
244
+ #
245
+
199
246
  #
200
247
  # Converts `other` to {ZonedDateTime}, if possible
201
248
  #
@@ -203,6 +250,7 @@ module OpenHAB
203
250
  # @return [Array, nil]
204
251
  #
205
252
  def coerce(other)
253
+ logger.trace { "Coercing #{self} as a request from #{other.class}" }
206
254
  [other.to_zoned_date_time(self), self] if other.respond_to?(:to_zoned_date_time)
207
255
  end
208
256
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "forwardable"
3
4
  require "date"
4
5
 
5
6
  # Extensions to Date
6
7
  class Date
8
+ extend Forwardable
7
9
  include OpenHAB::CoreExt::Between
8
10
  include OpenHAB::CoreExt::Ephemeris
9
11
 
@@ -53,6 +55,14 @@ class Date
53
55
  java.time.MonthDay.of(month, day)
54
56
  end
55
57
 
58
+ # @!method yesterday?
59
+ # (see OpenHAB::CoreExt::Java::ZonedDateTime#yesterday?)
60
+ # @!method today?
61
+ # (see OpenHAB::CoreExt::Java::ZonedDateTime#today?)
62
+ # @!method tomorrow?
63
+ # (see OpenHAB::CoreExt::Java::ZonedDateTime#tomorrow?)
64
+ def_delegators :to_zoned_date_time, :yesterday?, :today?, :tomorrow?
65
+
56
66
  # @param [ZonedDateTime, nil] context
57
67
  # A {ZonedDateTime} used to fill in missing fields during conversion.
58
68
  # {OpenHAB::CoreExt::Java::ZonedDateTime.now ZonedDateTime.now} is assumed
@@ -62,6 +72,16 @@ class Date
62
72
  to_local_date.to_zoned_date_time(context)
63
73
  end
64
74
 
75
+ # @param [ZonedDateTime, nil] context
76
+ # A {ZonedDateTime} used to fill in missing fields during conversion.
77
+ # {OpenHAB::CoreExt::Java::ZonedDateTime.now ZonedDateTime.now} is assumed
78
+ # if not given.
79
+ # @return [Instant]
80
+ def to_instant(context = nil)
81
+ context ||= Instant.now.to_zoned_date_time
82
+ to_zoned_date_time(context).to_instant
83
+ end
84
+
65
85
  # @return [Integer, nil]
66
86
  def compare_with_coercion(other)
67
87
  return compare_without_coercion(other) if other.is_a?(self.class)
@@ -84,6 +104,7 @@ class Date
84
104
  # @return [Array, nil]
85
105
  #
86
106
  def coerce(other)
107
+ logger.trace { "Coercing #{self} as a request from #{other.class}" }
87
108
  return nil unless other.respond_to?(:to_date)
88
109
  return [other.to_date, self] if other.method(:to_date).arity.zero?
89
110
 
@@ -45,8 +45,14 @@ class DateTime < Date
45
45
  to_java(ZonedDateTime)
46
46
  end
47
47
 
48
+ # @return [Instant]
49
+ def to_instant(_context = nil)
50
+ to_java(Instant)
51
+ end
52
+
48
53
  # (see Time#coerce)
49
54
  def coerce(other)
55
+ logger.trace { "Coercing #{self} as a request from #{other.class}" }
50
56
  return unless other.respond_to?(:to_zoned_date_time)
51
57
 
52
58
  zdt = to_zoned_date_time
@@ -84,6 +84,14 @@ class Time
84
84
  java.time.MonthDay.of(month, day)
85
85
  end
86
86
 
87
+ # @!method yesterday?
88
+ # (see OpenHAB::CoreExt::Java::ZonedDateTime#yesterday?)
89
+ # @!method today?
90
+ # (see OpenHAB::CoreExt::Java::ZonedDateTime#today?)
91
+ # @!method tomorrow?
92
+ # (see OpenHAB::CoreExt::Java::ZonedDateTime#tomorrow?)
93
+ def_delegators :to_zoned_date_time, :yesterday?, :today?, :tomorrow?
94
+
87
95
  # @param [ZonedDateTime, nil] context
88
96
  # A {ZonedDateTime} used to fill in missing fields
89
97
  # during conversion. Not used in this class.
@@ -92,8 +100,8 @@ class Time
92
100
  to_java(java.time.ZonedDateTime)
93
101
  end
94
102
 
95
- # @return [java.time.Instant]
96
- def to_instant
103
+ # @return [Instant]
104
+ def to_instant(_context = nil)
97
105
  to_java(java.time.Instant)
98
106
  end
99
107
 
@@ -105,6 +113,7 @@ class Time
105
113
  # @return [Array, nil]
106
114
  #
107
115
  def coerce(other)
116
+ logger.trace { "Coercing #{self} as a request from #{other.class}" }
108
117
  return unless other.respond_to?(:to_zoned_date_time)
109
118
 
110
119
  zdt = to_zoned_date_time
@@ -85,7 +85,11 @@ module OpenHAB
85
85
  # @return [void]
86
86
  #
87
87
  def resume
88
- self.resolution = nil
88
+ if expired?
89
+ logger.warn "Cannot resume a timed command that has expired. Use reschedule instead."
90
+ else
91
+ self.resolution = nil
92
+ end
89
93
  end
90
94
  end
91
95
 
@@ -216,22 +220,25 @@ module OpenHAB
216
220
  DSL.after(duration) do
217
221
  timed_command_details.mutex.synchronize do
218
222
  logger.trace "Timed command expired - #{timed_command_details}"
223
+ DSL.rules[timed_command_details.rule_uid].disable
219
224
  timed_command_details.resolution = :expired
220
225
  case timed_command_details.on_expire
221
226
  when Proc
222
227
  logger.trace "Invoking block #{timed_command_details.on_expire} after timed command for #{name} expired"
223
228
  timed_command_details.on_expire.call(timed_command_details)
224
- if timed_command_details.resolution.nil?
225
- logger.trace { "Block rescheduled the timer to #{timed_command_details.timer.execution_time}" }
226
- end
227
229
  when Core::Types::UnDefType
228
230
  update(timed_command_details.on_expire)
229
231
  else
230
232
  command(timed_command_details.on_expire)
231
233
  end
234
+ # The on_expire block can call timed_command_details.reschedule, which sets resolution to nil
235
+ # to prevent removal of the timed command
232
236
  if timed_command_details.resolution
233
237
  DSL.rules.remove(timed_command_details.rule_uid)
234
238
  TimedCommand.timed_commands.delete(timed_command_details.item)
239
+ else
240
+ DSL.rules[timed_command_details.rule_uid].enable
241
+ logger.trace { "Block rescheduled the timer to #{timed_command_details.timer.execution_time}" }
235
242
  end
236
243
  end
237
244
  end
@@ -1403,7 +1403,7 @@ module OpenHAB
1403
1403
  @ruby_triggers << [:every, value, { at: at }]
1404
1404
 
1405
1405
  if value == :day && at.is_a?(Item)
1406
- # @!deprecated OH 3.4 - attachments are supported in OH 4.0+
1406
+ # @deprecated OH 3.4 - attachments are supported in OH 4.0+
1407
1407
  if Core.version <= Core::V4_0 && !attach.nil?
1408
1408
  raise ArgumentError, "Attachments are not supported with dynamic datetime triggers in openHAB 3.x"
1409
1409
  end
@@ -127,7 +127,12 @@ module OpenHAB
127
127
  # One or more value color rules (see {#value_color})
128
128
  # @param icon_color [String, Hash<String, String>, Hash<Array<String>, String>, nil]
129
129
  # One or more icon color rules (see {#icon_color})
130
- # @param visibility [String, Array<String>, Array<Array<String>>, nil]
130
+ # @param visibility [String,
131
+ # Core::Types::State,
132
+ # Array<String>,
133
+ # Array<Core::Types::State>,
134
+ # Array<Array<String>>,
135
+ # nil]
131
136
  # One or more visibility rules (see {#visibility})
132
137
  # @!visibility private
133
138
  def initialize(type,
@@ -286,8 +291,12 @@ module OpenHAB
286
291
  supports_and_conditions = SitemapBuilder.factory.respond_to?(:create_condition)
287
292
 
288
293
  Array.wrap(conditions).each do |c|
294
+ c = c.to_s if c.is_a?(Core::Types::State)
295
+ unless c.is_a?(String) || c.is_a?(Symbol)
296
+ raise ArgumentError, "#{c.inspect} is not a valid condition data type for #{inspect}"
297
+ end
289
298
  unless (match = CONDITION_PATTERN.match(c))
290
- raise ArgumentError, "Syntax error in condition #{c.inspect}"
299
+ raise ArgumentError, "Syntax error in condition #{c.inspect} for #{inspect}"
291
300
  end
292
301
 
293
302
  condition = supports_and_conditions ? SitemapBuilder.factory.create_condition : container
@@ -1206,7 +1215,7 @@ module OpenHAB
1206
1215
  REQUIRED_BUTTON_ARGS = %i[row column click].freeze
1207
1216
  private_constant :REQUIRED_BUTTON_ARGS
1208
1217
 
1209
- # @!deprecated OH 4.1 in OH 4.1, Buttongrid is not a LinkableWidget.
1218
+ # @deprecated OH 4.1 in OH 4.1, Buttongrid is not a LinkableWidget.
1210
1219
  # Pretend that the buttons property is its children so we can add to it in LinkableWidgetBuilder#build
1211
1220
  if (Core::V4_1...Core::V4_2).cover?(Core.version)
1212
1221
  java_import org.openhab.core.model.sitemap.sitemap.Buttongrid
@@ -4,6 +4,6 @@ module OpenHAB
4
4
  module DSL
5
5
  # Version of openHAB helper libraries
6
6
  # @return [String]
7
- VERSION = "5.27.2"
7
+ VERSION = "5.29.0"
8
8
  end
9
9
  end
data/lib/openhab/dsl.rb CHANGED
@@ -51,6 +51,8 @@ module OpenHAB
51
51
 
52
52
  @debouncers = java.util.concurrent.ConcurrentHashMap.new
53
53
 
54
+ module_function :items, :things
55
+
54
56
  module_function
55
57
 
56
58
  # @!group Rule Creation
@@ -229,6 +231,13 @@ module OpenHAB
229
231
 
230
232
  # @!group Object Access
231
233
 
234
+ # @!parse
235
+ # # (see Core::EntityLookup#items)
236
+ # def items; end
237
+ #
238
+ # # (see Core::EntityLookup#things)
239
+ # def things; end
240
+
232
241
  #
233
242
  # (see Core::ValueCache)
234
243
  #
@@ -249,66 +258,11 @@ module OpenHAB
249
258
  Core::Rules::Registry.instance
250
259
  end
251
260
 
252
- #
253
- # Fetches all items from the item registry
254
- #
255
- # @return [Core::Items::Registry]
256
- #
257
- # The examples all assume the following items exist.
258
- #
259
- # ```xtend
260
- # Dimmer DimmerTest "Test Dimmer"
261
- # Switch SwitchTest "Test Switch"
262
- # ```
263
- #
264
- # @example
265
- # logger.info("Item Count: #{items.count}") # Item Count: 2
266
- # logger.info("Items: #{items.map(&:label).sort.join(', ')}") # Items: Test Dimmer, Test Switch'
267
- # logger.info("DimmerTest exists? #{items.key?('DimmerTest')}") # DimmerTest exists? true
268
- # logger.info("StringTest exists? #{items.key?('StringTest')}") # StringTest exists? false
269
- #
270
- # @example
271
- # rule 'Use dynamic item lookup to increase related dimmer brightness when switch is turned on' do
272
- # changed SwitchTest, to: ON
273
- # triggered { |item| items[item.name.gsub('Switch','Dimmer')].brighten(10) }
274
- # end
275
- #
276
- # @example
277
- # rule 'search for a suitable item' do
278
- # on_load
279
- # triggered do
280
- # # Send ON to DimmerTest if it exists, otherwise send it to SwitchTest
281
- # (items['DimmerTest'] || items['SwitchTest'])&.on
282
- # end
283
- # end
284
- #
285
- def items
286
- Core::Items::Registry.instance
287
- end
288
-
289
261
  # @return [Core::Sitemaps::Provider]
290
262
  def sitemaps
291
263
  Core::Sitemaps::Provider.instance
292
264
  end
293
265
 
294
- #
295
- # Get all things known to openHAB
296
- #
297
- # @return [Core::Things::Registry] all Thing objects known to openHAB
298
- #
299
- # @example
300
- # things.each { |thing| logger.info("Thing: #{thing.uid}")}
301
- # logger.info("Thing: #{things['astro:sun:home'].uid}")
302
- # homie_things = things.select { |t| t.thing_type_uid == "mqtt:homie300" }
303
- # zwave_things = things.select { |t| t.binding_id == "zwave" }
304
- # homeseer_dimmers = zwave_things.select { |t| t.thing_type_uid.id == "homeseer_hswd200_00_000" }
305
- # things['zwave:device:512:node90'].uid.bridge_ids # => ["512"]
306
- # things['mqtt:topic:4'].uid.bridge_ids # => []
307
- #
308
- def things
309
- Core::Things::Registry.instance
310
- end
311
-
312
266
  #
313
267
  # Provides access to timers created by {after after}
314
268
  #
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openhab-scripting
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.27.2
4
+ version: 5.29.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian O'Connell
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-09-11 00:00:00.000000000 Z
13
+ date: 2024-09-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -490,7 +490,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
490
490
  - !ruby/object:Gem::Version
491
491
  version: '0'
492
492
  requirements: []
493
- rubygems_version: 3.5.18
493
+ rubygems_version: 3.5.19
494
494
  signing_key:
495
495
  specification_version: 4
496
496
  summary: JRuby Helper Libraries for openHAB Scripting