openhab-scripting 5.21.0 → 5.22.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 756e126e160f646932df226702f4174537f335211766d9eba33c2d44cf1c1c70
4
- data.tar.gz: 6afda8cddcc7a0fd916fe061a2eb2dab4621d46cdcef75138b4c524db05b669d
3
+ metadata.gz: b2c5b8b2a28cbbda196f66340982141af673362693181e88588e89f9c4b1da29
4
+ data.tar.gz: 6a0483d0d94ae2a9492870e8089efd0b2a1afc400337d790a271b6fd9ca05ae3
5
5
  SHA512:
6
- metadata.gz: c57f40667e47bacb3c2a2cc62f6fce829413cf832502e1f743cb82fbbc0e5a962800907b27261bea5513020612a8f7652378a7817aa6b0d924c88220ccca7328
7
- data.tar.gz: 769878c8db809e0ed1815605551fc964de147329209e89517cab012a782b84e8a21e46fa445f3167723eea4f2454bd290a767991e39cfdb6495c742c874d295e
6
+ metadata.gz: 2115e707e47980b212827203b1401aeceb90c3c11fd0b8e91494581f12e728f4bc68d46c7f3b2991ff63a6f3db68ee45eb0b617e1a94ae642f6b2267de797f8c
7
+ data.tar.gz: ba2fd9524d6387287cbde50a8ff6cbc449069889836ced9e5b8cb79d8c7e3a4fe029804387d4866fed7b56b79e6aaba1584180fadc61d424555e0c755666cbbd
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ module Actions
6
+ #
7
+ # Provides methods for {https://next.openhab.org/addons/integrations/openhabcloud/#cloud-notification-actions
8
+ # openHAB Cloud Notification Actions}.
9
+ #
10
+ class Notification
11
+ class << self
12
+ #
13
+ # Send a notification using
14
+ # {https://next.openhab.org/addons/integrations/openhabcloud/#cloud-notification-actions
15
+ # openHAB Cloud Notification Action}.
16
+ #
17
+ # @param msg [String] The message to send.
18
+ # @param email [String, nil] The email address to send to. If `nil`, the message will be broadcasted.
19
+ # @param icon [String, Symbol, nil] The icon name
20
+ # (as described in {https://www.openhab.org/docs/configuration/items.html#icons Items}).
21
+ # @param tag [String, Symbol, nil] a name to group the type or severity of the notification.
22
+ # @param severity [String, Symbol, nil] Deprecated - an alias for `tag` for backwards compatibility.
23
+ # @param title [String, nil] The title of the notification.
24
+ # When `nil`, it defaults to `openHAB` inside the Android and iOS apps.
25
+ # @param id [String, nil] An optional reference ID which can then be used
26
+ # to {hide} or update the notification.
27
+ # Subsequent notifications using the same reference ID will
28
+ # update/overwrite the existing notification with the same ID.
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
31
+ # action syntax}.
32
+ # @param attachment [String, nil] The URL of the media attachment to be displayed with the notification.
33
+ # This URL must be reachable by the push notification client.
34
+ # @param buttons [Array<String>, Hash<String, String>, nil] Buttons to include in the notification.
35
+ # - In array form, each element is specified as `Title=$action`, where `$action` follows the
36
+ # {https://next.openhab.org/addons/integrations/openhabcloud/#action-syntax action syntax}.
37
+ # - In hash form, the keys are the button titles and the values are the actions.
38
+ #
39
+ # The maximum number of buttons is 3.
40
+ # @return [void]
41
+ #
42
+ # @note The parameters `title`, `id`, `on_click`, `attachment`, and `buttons` were added in openHAB 4.2.
43
+ #
44
+ # @see https://www.openhab.org/addons/integrations/openhabcloud/
45
+ #
46
+ # @example Send a broadcast notification via openHAB Cloud
47
+ # rule "Send an alert" do
48
+ # changed Alarm_Triggered, to: ON
49
+ # run { Notification.send "Red Alert!" }
50
+ # end
51
+ #
52
+ # @example Provide action buttons in a notification
53
+ # rule "Doorbell" do
54
+ # changed Doorbell, to: ON
55
+ # run do
56
+ # Notification.send "Someone pressed the doorbell!",
57
+ # title: "Doorbell",
58
+ # attachment: "http://myserver.local/cameras/frontdoor.jpg",
59
+ # buttons: {
60
+ # "Show Camera" => "ui:/basicui/app?w=0001&sitemap=cameras",
61
+ # "Unlock Door" => "command:FrontDoor_Lock:OFF"
62
+ # }
63
+ # end
64
+ # end
65
+ #
66
+ def send(
67
+ msg,
68
+ email: nil,
69
+ icon: nil,
70
+ tag: nil,
71
+ severity: nil,
72
+ id: nil,
73
+ title: nil,
74
+ on_click: nil,
75
+ attachment: nil,
76
+ buttons: nil
77
+ )
78
+ unless Actions.const_defined?(:NotificationAction)
79
+ raise NotImplementedError, "NotificationAction is not available. Please install the openHAB Cloud addon."
80
+ end
81
+
82
+ args = []
83
+ if email
84
+ args.push(:send_notification, email)
85
+ else
86
+ args.push(:send_broadcast_notification)
87
+ end
88
+ tag ||= severity
89
+ args.push(msg.to_s, icon&.to_s, tag&.to_s)
90
+
91
+ # @!deprecated OH 4.1
92
+ if Core.version >= Core::V4_2
93
+ buttons ||= []
94
+ buttons = buttons.map { |title, action| "#{title}=#{action}" } if buttons.is_a?(Hash)
95
+ raise ArgumentError, "buttons must contain (0..3) elements." unless (0..3).cover?(buttons.size)
96
+
97
+ args.push(title&.to_s,
98
+ id&.to_s,
99
+ on_click&.to_s,
100
+ attachment&.to_s,
101
+ buttons[0]&.to_s,
102
+ buttons[1]&.to_s,
103
+ buttons[2]&.to_s)
104
+ end
105
+
106
+ NotificationAction.__send__(*args)
107
+ end
108
+
109
+ #
110
+ # Hide a notification by ID or tag.
111
+ #
112
+ # Either the `id` or `tag` parameter must be provided.
113
+ # When both are provided, two calls will be made to the NotificationAction:
114
+ # - Notifications matching the `id` will be hidden, and
115
+ # - Notifications matching the `tag` will be hidden, independently from the given tag.
116
+ #
117
+ # @param email [String, nil] The email address to hide notifications for.
118
+ # If nil, hide broadcast notifications.
119
+ # @param id [String, nil] hide notifications associated with the given reference ID.
120
+ # @param tag [String, nil] hide notifications associated with the given tag.
121
+ # @return [void]
122
+ #
123
+ def hide(email: nil, id: nil, tag: nil)
124
+ unless Actions.const_defined?(:NotificationAction)
125
+ raise NotImplementedError, "NotificationAction is not available. Please install the openHAB Cloud addon."
126
+ end
127
+
128
+ raise ArgumentError, "Either id or tag must be provided." unless id || tag
129
+
130
+ args = []
131
+ if email
132
+ args.push(email)
133
+ notification = :notification
134
+ else
135
+ notification = :broadcast_notification
136
+ end
137
+
138
+ NotificationAction.__send__(:"hide_#{notification}_by_reference_id", *args, id) if id
139
+ NotificationAction.__send__(:"hide_#{notification}_by_tag", *args, tag) if tag
140
+ end
141
+
142
+ #
143
+ # Sends a log notification.
144
+ #
145
+ # Log notifications do not trigger a notification on the device.
146
+ #
147
+ # @param msg [String] The message to send.
148
+ # @param icon [String, Symbol, nil] The icon name
149
+ # @param tag [String, Symbol, nil] a name to group the type or severity of the notification.
150
+ # @return [void]
151
+ #
152
+ def log(msg, icon: nil, tag: nil)
153
+ NotificationAction.send_log_notification(msg.to_s, icon&.to_s, tag&.to_s)
154
+ end
155
+ end
156
+
157
+ Object.const_set(name.split("::").last, self)
158
+ end
159
+ end
160
+ end
161
+ end
@@ -17,9 +17,8 @@ module OpenHAB
17
17
  # * {Voice}
18
18
  #
19
19
  # From add-ons, e.g.:
20
- # * NotificationAction (from
21
- # [openHAB Cloud Connector](https://www.openhab.org/addons/integrations/openhabcloud/);
22
- # see {notify notify})
20
+ # * {Notification NotificationAction} from
21
+ # [openHAB Cloud Connector](https://www.openhab.org/addons/integrations/openhabcloud/)
23
22
  #
24
23
  # Thing-specific actions can be accessed from the {Things::Thing Thing} object.
25
24
  # See {Things::Thing#actions Thing#actions}.
@@ -51,85 +50,12 @@ module OpenHAB
51
50
  module_function
52
51
 
53
52
  #
54
- # Send a notification using
55
- # {https://next.openhab.org/addons/integrations/openhabcloud/#cloud-notification-actions
56
- # openHAB Cloud Notification Action}.
53
+ # @!method notify(msg, email: nil, icon: nil, tag: nil, severity: nil, id: nil, title: nil, on_click: nil, attachment: nil, buttons: nil)
54
+ # @deprecated Use {Notification.send Notification.send} instead.
57
55
  #
58
- # @param msg [String] The message to send.
59
- # @param email [String, nil] The email address to send to. If `nil`, the message will be broadcast.
60
- # @param icon [String, Symbol, nil] The icon name
61
- # (as described in {https://next.openhab.org/docs/configuration/items.html#icons Items}).
62
- # @param severity [String, Symbol, nil] A description of the severity of the incident.
63
- # @param title [String, nil] The title of the notification.
64
- # When `nil`, it defaults to `openHAB` inside the Android and iOS apps.
65
- # @param on_click [String, nil] The action to be performed when the user clicks on the notification.
66
- # Specified using the {https://next.openhab.org/addons/integrations/openhabcloud/#action-syntax action syntax}.
67
- # @param attachment [String, nil] The URL of the media attachment to be displayed with the notification.
68
- # This URL must be reachable by the push notification client.
69
- # @param buttons [Array<String>, Hash<String, String>, nil] Buttons to include in the notification.
70
- # - In array form, each element is specified as `Title=$action`, where `$action` follows the
71
- # {https://next.openhab.org/addons/integrations/openhabcloud/#action-syntax action syntax}.
72
- # - In hash form, the keys are the button titles and the values are the actions.
73
- #
74
- # The maximum number of buttons is 3.
75
- # @return [void]
76
- #
77
- # @note The parameters `title`, `on_click`, `attachment`, and `buttons` were added in openHAB 4.2.
78
- #
79
- # @see https://www.openhab.org/addons/integrations/openhabcloud/
80
- #
81
- # @example Send a broadcast notification via openHAB Cloud
82
- # rule "Send an alert" do
83
- # changed Alarm_Triggered, to: ON
84
- # run { notify "Red Alert!" }
85
- # end
86
- #
87
- # @example Provide action buttons in a notification
88
- # rule "Doorbell" do
89
- # changed Doorbell, to: ON
90
- # run do
91
- # notify "Someone pressed the doorbell!",
92
- # title: "Doorbell",
93
- # attachment: "http://myserver.local/cameras/frontdoor.jpg",
94
- # buttons: {
95
- # "Show Camera" => "ui:/basicui/app?w=0001&sitemap=cameras",
96
- # "Unlock Door" => "command:FrontDoor_Lock:OFF"
97
- # }
98
- # end
99
- # end
100
- #
101
- def notify(
102
- msg,
103
- email: nil,
104
- icon: nil,
105
- severity: nil,
106
- title: nil,
107
- on_click: nil,
108
- attachment: nil,
109
- buttons: nil
110
- )
111
- unless Actions.const_defined?(:NotificationAction)
112
- raise NotImplementedError, "NotificationAction is not available. Please install the openHAB Cloud addon."
113
- end
114
-
115
- args = []
116
- if email
117
- args.push(:send_notification, email)
118
- else
119
- args.push(:send_broadcast_notification)
120
- end
121
- args.push(msg.to_s, icon&.to_s, severity&.to_s)
122
-
123
- # @!deprecated OH 4.1
124
- if Core.version >= Core::V4_2
125
- buttons ||= []
126
- buttons = buttons.map { |title, action| "#{title}=#{action}" } if buttons.is_a?(Hash)
127
- raise ArgumentError, "buttons must contain (0..3) elements." unless (0..3).cover?(buttons.size)
128
-
129
- args.push(title&.to_s, on_click&.to_s, attachment&.to_s, buttons[0]&.to_s, buttons[1]&.to_s, buttons[2]&.to_s)
130
- end
131
-
132
- NotificationAction.__send__(*args)
56
+ def notify(*args, **kwargs)
57
+ logger.warn("`notify` method is deprecated. Use `Notification.send` instead.")
58
+ Notification.send(*args, **kwargs)
133
59
  end
134
60
  end
135
61
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ module Events
6
+ java_import org.openhab.core.thing.link.events.AbstractItemChannelLinkRegistryEvent,
7
+ org.openhab.core.thing.link.events.ItemChannelLinkAddedEvent,
8
+ org.openhab.core.thing.link.events.ItemChannelLinkRemovedEvent
9
+
10
+ #
11
+ # The {AbstractEvent} sent when an {Things::ItemChannelLink} is added or removed
12
+ # from its registry.
13
+ #
14
+ # @!attribute [r] link
15
+ # @return [DTO::ItemChannelLinkDTO] The link that triggered this event.
16
+ #
17
+ class AbstractItemChannelLinkRegistryEvent < AbstractEvent; end
18
+
19
+ #
20
+ # The {AbstractEvent} sent with an `channel_linked` trigger.
21
+ #
22
+ class ItemChannelLinkAddedEvent < AbstractItemChannelLinkRegistryEvent; end
23
+
24
+ #
25
+ # The {AbstractEvent} sent with an `channel_unlinked` trigger.
26
+ #
27
+ class ItemChannelLinkRemovedEvent < AbstractItemChannelLinkRegistryEvent; end
28
+ end
29
+ end
30
+ end
@@ -25,6 +25,9 @@ module OpenHAB
25
25
  #
26
26
  # The {AbstractEvent} sent with an `item_updated` trigger.
27
27
  #
28
+ # @!attribute [r] old_item
29
+ # @return [DTO::ItemDTO] the old item before the update.
30
+ #
28
31
  class ItemUpdatedEvent < AbstractItemRegistryEvent; end
29
32
 
30
33
  #
@@ -28,6 +28,9 @@ module OpenHAB
28
28
  # The {AbstractEvent} sent with a
29
29
  # {DSL::Rules::BuilderDSL#thing_updated thing_updated trigger}.
30
30
  #
31
+ # @!attribute [r] old_thing
32
+ # @return [DTO::AbstractThingDTO] the old thing before the update.
33
+ #
31
34
  class ThingUpdatedEvent < AbstractThingRegistryEvent; end
32
35
 
33
36
  #
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @deprecated OH3.4 this guard is not needed on OH4
4
+ return unless OpenHAB::Core.version >= OpenHAB::Core::V4_0
5
+
6
+ module OpenHAB
7
+ module Core
8
+ module Events
9
+ java_import org.openhab.core.events.system.StartlevelEvent
10
+
11
+ #
12
+ # The {AbstractEvent} sent when the system start level changed.
13
+ #
14
+ # @!attribute [r] startlevel
15
+ # @return [Integer] The new start level.
16
+ #
17
+ class StartlevelEvent < AbstractEvent; end
18
+ end
19
+ end
20
+ end
@@ -25,6 +25,31 @@ module OpenHAB
25
25
  # UV_Index.average_since(1.hour.ago, :influxdb)
26
26
  # Power_Usage.average_since(12.hours.ago, :rrd4j)
27
27
  #
28
+ # @example Time of day shortcuts
29
+ # # Persistence methods accept any object that responds to #to_zoned_date_time, which includes
30
+ # # LocalTime, LocalDate, and Ruby's Time, Date, and DateTime.
31
+ # # This allows for easy querying of start of day
32
+ # logger.info Power_Usage.average_since(LocalTime::MIDNIGHT)
33
+ # logger.info Power_Usage.average_since(LocalDate.now)
34
+ # # Ruby's Date can be used too
35
+ # logger.info Power_Usage.average_since(Date.today)
36
+ #
37
+ # # Yesterday
38
+ # logger.info Power_Usage.average_between(Date.today - 1, Date.today)
39
+ # # or
40
+ # logger.info Power_Usage.average_between(LocalDate.now - 1, LocalDate.now)
41
+ #
42
+ # # When passing the local time, today's date is assumed
43
+ # logger.info Power_Usage.average_between(LocalTime.parse("4pm"), LocalTime.parse("9pm"))
44
+ # # or
45
+ # logger.info Power_Usage.average_between(Time.parse("4pm"), Time.parse("9pm"))
46
+ #
47
+ # # Beware that Date, LocalDate, and LocalTime arithmetics will produce the same type, so
48
+ # Power_Usage.average_between(LocalTime.parse("4pm") - 1.day, LocalTime.parse("9pm") - 1.day)
49
+ # # Will still give you TODAY's data between 4pm and 9pm
50
+ # # To get yesterday's data, use Time.parse, i.e.
51
+ # Power_Usage.average_between(Time.parse("4pm") - 1.day, Time.parse("9pm") - 1.day)
52
+ #
28
53
  # @example Comparison using Quantity
29
54
  # # Because Power_Usage has a unit, the return value
30
55
  # # from average_since is a QuantityType
@@ -42,10 +67,17 @@ module OpenHAB
42
67
  #
43
68
  # A wrapper for {org.openhab.core.persistence.HistoricItem HistoricItem} that delegates to its state.
44
69
  #
70
+ # A {PersistedState} object can be directly used in arithmetic operations with {State} and
71
+ # other {PersistedState} objects.
72
+ #
45
73
  # @example
46
74
  # max = Power_Usage.maximum_since(LocalTime::MIDNIGHT)
47
75
  # logger.info "Highest power usage: #{max} occurred at #{max.timestamp}" if max > 5 | "kW"
48
76
  #
77
+ # @example Arithmetic operations
78
+ # todays_rate = Energy_Prices.persisted_state(Date.today) # Energy_Prices' unit is "<CURRENCY>/kWh"
79
+ # todays_cost = Daily_Energy_Consumption.state * todays_rate
80
+ #
49
81
  class PersistedState < SimpleDelegator
50
82
  extend Forwardable
51
83
 
@@ -65,6 +97,11 @@ module OpenHAB
65
97
  @historic_item = historic_item
66
98
  super(state || historic_item.state)
67
99
  end
100
+
101
+ # @!visibility private
102
+ def inspect
103
+ "#<#{self.class} #{state} at: #{timestamp} item: #{name}>"
104
+ end
68
105
  end
69
106
 
70
107
  # @deprecated Use {PersistedState} instead
@@ -146,8 +146,8 @@ module OpenHAB
146
146
  # elsif other.is_a?(java.math.BigDecimal)
147
147
  # self.class.new(to_big_decimal.add(other))
148
148
  # elsif other.respond_to?(:to_d)
149
- # result = to_d + other
150
- # # result could already be a QuantityType
149
+ # result = to_d + other.to_d
150
+ # # result could already be a NumericType
151
151
  # result = self.class.new(result) unless result.is_a?(NumericType)
152
152
  # result
153
153
  # elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
@@ -163,8 +163,8 @@ module OpenHAB
163
163
  elsif other.is_a?(java.math.BigDecimal)
164
164
  self.class.new(to_big_decimal.#{java_op}(other, java.math.MathContext::DECIMAL128))
165
165
  elsif other.respond_to?(:to_d)
166
- result = to_d #{ruby_op} other
167
- # result could already be a QuantityType
166
+ result = to_d #{ruby_op} other.to_d
167
+ # result could already be a NumericType
168
168
  result = self.class.new(result) unless result.is_a?(NumericType)
169
169
  result
170
170
  elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
@@ -179,6 +179,7 @@ module OpenHAB
179
179
  class_eval( # rubocop:disable Style/DocumentDynamicEvalDefinition https://github.com/rubocop/rubocop/issues/10179
180
180
  # def +(other)
181
181
  # logger.trace("#{self} + #{other} (#{other.class})")
182
+ # other = other.state if other.is_a?(Core::Items::Persistence::PersistedState)
182
183
  # if other.is_a?(QuantityType)
183
184
  # add_quantity(other)
184
185
  # elsif (thread_unit = DSL.unit(dimension))
@@ -203,6 +204,7 @@ module OpenHAB
203
204
  <<~RUBY, __FILE__, __LINE__ + 1
204
205
  def #{ruby_op}(other)
205
206
  logger.trace("\#{self} #{ruby_op} \#{other} (\#{other.class})")
207
+ other = other.state if other.is_a?(Core::Items::Persistence::PersistedState)
206
208
  if other.is_a?(QuantityType)
207
209
  #{java_op}_quantity(other)
208
210
  elsif (thread_unit = DSL.unit(dimension))
@@ -235,6 +237,7 @@ module OpenHAB
235
237
  class_eval( # rubocop:disable Style/DocumentDynamicEvalDefinition https://github.com/rubocop/rubocop/issues/10179
236
238
  # def *(other)
237
239
  # logger.trace("#{self} * #{other} (#{other.class})")
240
+ # other = other.state if other.is_a?(Core::Items::Persistence::PersistedState)
238
241
  # if other.is_a?(QuantityType)
239
242
  # multiply_quantity(other)
240
243
  # elsif other.is_a?(DecimalType)
@@ -252,6 +255,7 @@ module OpenHAB
252
255
  <<~RUBY, __FILE__, __LINE__ + 1
253
256
  def #{ruby_op}(other)
254
257
  logger.trace("\#{self} #{ruby_op} \#{other} (\#{other.class})")
258
+ other = other.state if other.is_a?(Core::Items::Persistence::PersistedState)
255
259
  if other.is_a?(QuantityType)
256
260
  #{java_op}_quantity(other).unitize
257
261
  elsif other.is_a?(DecimalType)
data/lib/openhab/core.rb CHANGED
@@ -15,9 +15,10 @@ module OpenHAB
15
15
  V4_2 = Gem::Version.new("4.2.0").freeze
16
16
 
17
17
  # @return [Gem::Version] Returns the current openHAB version as a Gem::Version object
18
+ # Note, this strips off snapshots, milestones and RC versions and returns the release version.
18
19
  # @!visibility private
19
20
  def self.version
20
- @version ||= Gem::Version.new(VERSION).freeze
21
+ @version ||= Gem::Version.new(VERSION).release.freeze
21
22
  end
22
23
 
23
24
  raise "`openhab-scripting` requires openHAB >= 3.4.0" unless version >= Gem::Version.new("3.4.0")
@@ -89,6 +89,7 @@ module OpenHAB
89
89
  # @param [Command] command to send to object
90
90
  # @param [Duration] for duration for item to be in command state
91
91
  # @param [Command] on_expire Command to send when duration expires
92
+ # @param [true, false] only_when_ensured if true, only start the timed command if the command was ensured
92
93
  # @yield If a block is provided, `on_expire` is ignored and the block
93
94
  # is expected to set the item to the desired state or carry out some
94
95
  # other action.
@@ -104,27 +105,46 @@ module OpenHAB
104
105
  # @example
105
106
  # Dimmer.on(for: 5.minutes) { |event| Dimmer.off if Light.on? }
106
107
  #
107
- def command(command, for: nil, on_expire: nil, &block)
108
+ # @example Only start a timed command if the command was ensured
109
+ # rule "Motion Detected" do
110
+ # received_command Motion_Sensor, command: ON
111
+ # run do
112
+ # # Start the timer only if the command was ensured
113
+ # # i.e. the light was off before the command was sent
114
+ # # but if the timer was already started, extend it
115
+ # FrontPorchLight.ensure.on for: 30.minutes, only_when_ensured: true
116
+ # end
117
+ # end
118
+ #
119
+ def command(command, for: nil, on_expire: nil, only_when_ensured: false, &block)
108
120
  duration = binding.local_variable_get(:for)
109
121
  return super(command) unless duration
110
122
 
111
123
  on_expire = block if block
112
124
 
125
+ create_ensured_timed_command = proc do
126
+ on_expire ||= default_on_expire(command)
127
+ if only_when_ensured
128
+ DSL.ensure_states do
129
+ create_timed_command(command, duration: duration, on_expire: on_expire) if super(command)
130
+ end
131
+ else
132
+ super(command)
133
+ create_timed_command(command, duration: duration, on_expire: on_expire)
134
+ end
135
+ end
136
+
113
137
  TimedCommand.timed_commands.compute(self) do |_key, timed_command_details|
114
138
  if timed_command_details.nil?
115
139
  # no prior timed command
116
- on_expire ||= default_on_expire(command)
117
- super(command)
118
- create_timed_command(command, duration: duration, on_expire: on_expire)
140
+ create_ensured_timed_command.call
119
141
  else
120
142
  timed_command_details.mutex.synchronize do
121
143
  if timed_command_details.resolution
122
144
  # timed command that finished, but hadn't removed itself from the map yet
123
145
  # (it doesn't do so under the mutex to prevent a deadlock).
124
146
  # just create a new one
125
- on_expire ||= default_on_expire(command)
126
- super(command)
127
- create_timed_command(command, duration: duration, on_expire: on_expire)
147
+ create_ensured_timed_command.call
128
148
  else
129
149
  # timed command still pending; reset it
130
150
  logger.trace "Outstanding Timed Command #{timed_command_details} encountered - rescheduling"
@@ -132,7 +152,7 @@ module OpenHAB
132
152
  timed_command_details.timer.reschedule(duration)
133
153
  # disable the cancel rule while we send the new command
134
154
  DSL.rules[timed_command_details.rule_uid].disable
135
- super(command)
155
+ super(command) # This returns nil when "ensured"
136
156
  DSL.rules[timed_command_details.rule_uid].enable
137
157
  timed_command_details
138
158
  end
@@ -135,7 +135,7 @@ module OpenHAB
135
135
  # # return the script object into a variable
136
136
  # door_check = script "Check all doors", id: "door_check", tags: :security do
137
137
  # open_doors = gDoors.members.select(&:open?).map(&:label).join(", ")
138
- # notify("The following doors are open: #{open_doors}") unless open_doors.empty?
138
+ # Notification.send("The following doors are open: #{open_doors}") unless open_doors.empty?
139
139
  # end
140
140
  #
141
141
  # # run is an alias of trigger
@@ -145,7 +145,7 @@ module OpenHAB
145
145
  # # This script expects to be called with `message` as context/parameter
146
146
  # DESTINATION_EMAIL = "myemail@example.com"
147
147
  # script "Send Notifications", id: "send_alert" do
148
- # notify(message)
148
+ # Notification.send(message)
149
149
  # things["mail:smtp:local"].send_mail(DESTINATION_EMAIL, "OpenHAB Alert", message)
150
150
  # end
151
151
  #
@@ -744,7 +744,7 @@ module OpenHAB
744
744
  # changed Door_State
745
745
  # debounce_for 10.minutes
746
746
  # only_if { Door_State.open? }
747
- # run { notify("The Door has been open for 10 minutes!") }
747
+ # run { Notification.send("The Door has been open for 10 minutes!") }
748
748
  # end
749
749
  #
750
750
  def debounce_for(debounce_time)
@@ -898,6 +898,8 @@ module OpenHAB
898
898
  # supports one or more channels with one or more triggers. `thing` is an optional
899
899
  # parameter that makes it easier to set triggers on multiple channels on the same thing.
900
900
  #
901
+ # The `event` passed to run blocks will be a {Core::Events::ChannelTriggeredEvent}.
902
+ #
901
903
  # @param [String, Core::Things::Channel, Core::Things::ChannelUID] channels
902
904
  # channels to create triggers for in form of 'binding_id:type_id:thing_id#channel_id'
903
905
  # or 'channel_id' if thing is provided.
@@ -992,6 +994,8 @@ module OpenHAB
992
994
  #
993
995
  # Creates a channel linked trigger
994
996
  #
997
+ # The `event` passed to run blocks will be an {Core::Events::ItemChannelLinkAddedEvent}.
998
+ #
995
999
  # @param [Item, String, nil] item The item to create a trigger for. If nil, all items are matched.
996
1000
  # @param [Core::Things::Channel, Core::Things::ChannelUID, String, nil] channel
997
1001
  # The channel to create a trigger for. If nil, all channels are matched.
@@ -1016,6 +1020,8 @@ module OpenHAB
1016
1020
  #
1017
1021
  # Creates a channel unlinked trigger
1018
1022
  #
1023
+ # The `event` passed to run blocks will be an {Core::Events::ItemChannelLinkRemovedEvent}.
1024
+ #
1019
1025
  # Note that the item or the thing it's linked to may no longer exist,
1020
1026
  # so if you try to access those objects they'll be nil.
1021
1027
  #
@@ -1054,7 +1060,7 @@ module OpenHAB
1054
1060
  # {Core::Events::ThingStatusInfoChangedEvent} depending on if the
1055
1061
  # triggering element was an item or a thing.
1056
1062
  #
1057
- # @param [Item, GroupItem::Members, Thing] items Objects to create trigger for.
1063
+ # @param [Item, GroupItem::Members, Thing, ThingUID, Things::Registry] items Objects to create trigger for.
1058
1064
  # @param [State, Array<State>, #===, nil] from
1059
1065
  # Only execute rule if previous state matches `from` state(s).
1060
1066
  # @param [State, Array<State>, #===, nil] to
@@ -1141,6 +1147,14 @@ module OpenHAB
1141
1147
  # run { |event| logger.info("Thing #{event.uid} status <trigger> to #{event.status}") }
1142
1148
  # end
1143
1149
  #
1150
+ # @example Trigger when any Thing changes status
1151
+ # rule "Thing status monitoring" do
1152
+ # changed things, to: :offline
1153
+ # run do |event|
1154
+ # Notification.send("Thing #{event.thing.uid} is offline")
1155
+ # end
1156
+ # end
1157
+ #
1144
1158
  # @example Real World Example
1145
1159
  # rule "Log (or notify) when an exterior door is left open for more than 5 minutes" do
1146
1160
  # changed ExteriorDoors.members, to: OPEN, for: 5.minutes
@@ -1160,11 +1174,13 @@ module OpenHAB
1160
1174
  case item
1161
1175
  when Core::Things::Thing,
1162
1176
  Core::Things::ThingUID,
1177
+ Core::Things::Registry,
1163
1178
  Core::Items::Item,
1164
1179
  Core::Items::GroupItem::Members
1165
1180
  nil
1166
1181
  else
1167
- raise ArgumentError, "items must be an Item, GroupItem::Members, Thing, or ThingUID"
1182
+ raise ArgumentError,
1183
+ "items must be an Item, GroupItem::Members, Thing, ThingUID, or Things::Registry"
1168
1184
  end
1169
1185
 
1170
1186
  logger.trace { "Creating changed trigger for entity(#{item}), to(#{to.inspect}), from(#{from.inspect})" }
@@ -1180,6 +1196,8 @@ module OpenHAB
1180
1196
  #
1181
1197
  # Create a cron trigger
1182
1198
  #
1199
+ # The `event` passed to run blocks will be a {Core::Events::TimerEvent}.
1200
+ #
1183
1201
  # @overload cron(expression, attach: nil)
1184
1202
  # @param [String, nil] expression [openHAB style cron expression](https://www.openhab.org/docs/configuration/rules-dsl.html#time-based-triggers)
1185
1203
  # @param [Object] attach object to be attached to the trigger
@@ -1258,6 +1276,8 @@ module OpenHAB
1258
1276
  #
1259
1277
  # Create a rule that executes at the specified interval.
1260
1278
  #
1279
+ # The `event` passed to run blocks will be a {Core::Events::TimerEvent}.
1280
+ #
1261
1281
  # @param [String,
1262
1282
  # Duration,
1263
1283
  # java.time.MonthDay,
@@ -1400,6 +1420,8 @@ module OpenHAB
1400
1420
  #
1401
1421
  # Creates a trigger that executes when openHAB reaches a certain start level
1402
1422
  #
1423
+ # The `event` passed to run blocks will be a {Core::Events::StartlevelEvent}.
1424
+ #
1403
1425
  # This will only trigger once during openHAB start up. It won't trigger on script reloads.
1404
1426
  #
1405
1427
  # @param [Integer,:rules,:ruleengine,:ui,:things,:complete] at_level
@@ -1570,6 +1592,8 @@ module OpenHAB
1570
1592
  #
1571
1593
  # Creates an item added trigger
1572
1594
  #
1595
+ # The `event` passed to run blocks will be an {Core::Events::ItemAddedEvent}.
1596
+ #
1573
1597
  # @param [String, nil] pattern The pattern to match items against
1574
1598
  # @param [Object] attach object to be attached to the trigger
1575
1599
  # @return [void]
@@ -1591,6 +1615,8 @@ module OpenHAB
1591
1615
  #
1592
1616
  # Creates an item removed trigger
1593
1617
  #
1618
+ # The `event` passed to run blocks will be an {Core::Events::ItemRemovedEvent}.
1619
+ #
1594
1620
  # @param [String, nil] pattern The pattern to match items against
1595
1621
  # @param [Object] attach object to be attached to the trigger
1596
1622
  # @return [void]
@@ -1612,6 +1638,8 @@ module OpenHAB
1612
1638
  #
1613
1639
  # Creates an item updated trigger
1614
1640
  #
1641
+ # The `event` passed to run blocks will be an {Core::Events::ItemUpdatedEvent}.
1642
+ #
1615
1643
  # @param [String, nil] pattern The pattern to match items against
1616
1644
  # @param [Object] attach object to be attached to the trigger
1617
1645
  # @return [void]
@@ -1632,6 +1660,8 @@ module OpenHAB
1632
1660
  #
1633
1661
  # Creates a thing added trigger
1634
1662
  #
1663
+ # The `event` passed to run blocks will be a {Core::Events::ThingAddedEvent}.
1664
+ #
1635
1665
  # @param [String, nil] pattern The pattern to match things against
1636
1666
  # @param [Object] attach object to be attached to the trigger
1637
1667
  # @return [void]
@@ -1653,6 +1683,8 @@ module OpenHAB
1653
1683
  #
1654
1684
  # Creates a thing removed trigger
1655
1685
  #
1686
+ # The `event` passed to run blocks will be a {Core::Events::ThingRemovedEvent}.
1687
+ #
1656
1688
  # @param [String, nil] pattern The pattern to match things against
1657
1689
  # @param [Object] attach object to be attached to the trigger
1658
1690
  # @return [void]
@@ -1674,6 +1706,8 @@ module OpenHAB
1674
1706
  #
1675
1707
  # Creates a thing updated trigger
1676
1708
  #
1709
+ # The event passed to run blocks will be a {Core::Events::ThingUpdatedEvent}.
1710
+ #
1677
1711
  # @param [String, nil] pattern The pattern to match things against
1678
1712
  # @param [Object] attach object to be attached to the trigger
1679
1713
  # @return [void]
@@ -1734,6 +1768,8 @@ module OpenHAB
1734
1768
  # To trigger just on the time portion of the item, use {every} instead, e.g.
1735
1769
  # `every :day, at: MyDateTimeItem`.
1736
1770
  #
1771
+ # The `event` passed to run blocks will be a {Core::Events::TimerEvent}.
1772
+ #
1737
1773
  # @param [Item, String, Symbol] item The item (or its name)
1738
1774
  # @return [void]
1739
1775
  #
@@ -79,6 +79,8 @@ module OpenHAB
79
79
  when Core::Things::Thing,
80
80
  Core::Things::ThingUID
81
81
  thing(thing: item, from: from, to: to)
82
+ when Core::Things::Registry
83
+ thing(thing: "*", from: from, to: to)
82
84
  else
83
85
  item(item: item, from: from, to: to)
84
86
  end
@@ -112,11 +112,11 @@ module OpenHAB
112
112
  #
113
113
  # @example Extend an existing timer, or schedule a new one
114
114
  # # This is technically the same functionality as just calling `after()` with an `id`,
115
- # # but allows you to performa extra steps if the timer is actually scheduled.
115
+ # # but allows you to perform extra steps if the timer is actually scheduled.
116
116
  # timers.schedule(item) do |timer|
117
117
  # next timer.tap(&:reschedule) if timer
118
118
  #
119
- # notify("The lights were turned on")
119
+ # Notification.send("The lights were turned on")
120
120
  #
121
121
  # after(30.seconds) { item.off }
122
122
  # end
@@ -4,6 +4,6 @@ module OpenHAB
4
4
  module DSL
5
5
  # Version of openHAB helper libraries
6
6
  # @return [String]
7
- VERSION = "5.21.0"
7
+ VERSION = "5.22.1"
8
8
  end
9
9
  end
@@ -11,29 +11,47 @@ module OpenHAB
11
11
  email,
12
12
  msg,
13
13
  icon,
14
- severity,
14
+ tag,
15
15
  title = nil,
16
+ id = nil,
16
17
  on_click = nil,
17
18
  attachment = nil,
18
19
  button1 = nil,
19
20
  button2 = nil,
20
21
  button3 = nil
21
22
  )
22
- logger.debug("send_notification: #{email}, #{msg}, #{icon}, #{severity}, #{title}, #{on_click}, #{attachment}, #{button1}, #{button2}, #{button3}") # rubocop:disable Layout/LineLength
23
+ logger.debug("send_notification: #{email}, #{msg}, #{icon}, #{tag}, #{title}, #{id}, #{on_click}, #{attachment}, #{button1}, #{button2}, #{button3}") # rubocop:disable Layout/LineLength
23
24
  end
24
25
 
25
26
  def send_broadcast_notification(
26
27
  msg,
27
28
  icon,
28
- severity,
29
+ tag,
29
30
  title = nil,
31
+ id = nil,
30
32
  on_click = nil,
31
33
  attachment = nil,
32
34
  button1 = nil,
33
35
  button2 = nil,
34
36
  button3 = nil
35
37
  )
36
- logger.debug("send_broadcast_notification: #{msg}, #{icon}, #{severity}, #{title}, #{on_click}, #{attachment}, #{button1}, #{button2}, #{button3}") # rubocop:disable Layout/LineLength
38
+ logger.debug("send_broadcast_notification: #{msg}, #{icon}, #{tag}, #{title}, #{id}, #{on_click}, #{attachment}, #{button1}, #{button2}, #{button3}") # rubocop:disable Layout/LineLength
39
+ end
40
+
41
+ def hide_notification_by_reference_id(email, id)
42
+ logger.debug("hide_notification_by_reference_id: #{email}, #{id}")
43
+ end
44
+
45
+ def hide_notification_by_tag(email, tag)
46
+ logger.debug("hide_notification_by_tag: #{email}, #{tag}")
47
+ end
48
+
49
+ def hide_broadcast_notification_by_reference_id(id)
50
+ logger.debug("hide_broadcast_notification_by_reference_id: #{id}")
51
+ end
52
+
53
+ def hide_broadcast_notification_by_tag(tag)
54
+ logger.debug("hide_broadcast_notification_by_tag: #{tag}")
37
55
  end
38
56
  end
39
57
  end
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.21.0
4
+ version: 5.22.1
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-06-28 00:00:00.000000000 Z
13
+ date: 2024-07-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -238,6 +238,7 @@ files:
238
238
  - lib/openhab/core/actions/ephemeris.rb
239
239
  - lib/openhab/core/actions/exec.rb
240
240
  - lib/openhab/core/actions/http.rb
241
+ - lib/openhab/core/actions/notification.rb
241
242
  - lib/openhab/core/actions/ping.rb
242
243
  - lib/openhab/core/actions/transformation.rb
243
244
  - lib/openhab/core/actions/voice.rb
@@ -250,6 +251,7 @@ files:
250
251
  - lib/openhab/core/entity_lookup.rb
251
252
  - lib/openhab/core/events.rb
252
253
  - lib/openhab/core/events/abstract_event.rb
254
+ - lib/openhab/core/events/abstract_item_channel_link_registry_event.rb
253
255
  - lib/openhab/core/events/abstract_item_registry_event.rb
254
256
  - lib/openhab/core/events/abstract_thing_registry_event.rb
255
257
  - lib/openhab/core/events/channel_triggered_event.rb
@@ -259,6 +261,7 @@ files:
259
261
  - lib/openhab/core/events/item_state_event.rb
260
262
  - lib/openhab/core/events/item_state_updated_event.rb
261
263
  - lib/openhab/core/events/item_time_series_updated_event.rb
264
+ - lib/openhab/core/events/startlevel_event.rb
262
265
  - lib/openhab/core/events/thing_status_info_event.rb
263
266
  - lib/openhab/core/events/timer_event.rb
264
267
  - lib/openhab/core/items.rb