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 +4 -4
- data/lib/openhab/core/actions/notification.rb +161 -0
- data/lib/openhab/core/actions.rb +7 -81
- data/lib/openhab/core/events/abstract_item_channel_link_registry_event.rb +30 -0
- data/lib/openhab/core/events/abstract_item_registry_event.rb +3 -0
- data/lib/openhab/core/events/abstract_thing_registry_event.rb +3 -0
- data/lib/openhab/core/events/startlevel_event.rb +20 -0
- data/lib/openhab/core/items/persistence.rb +37 -0
- data/lib/openhab/core/types/decimal_type.rb +4 -4
- data/lib/openhab/core/types/quantity_type.rb +4 -0
- data/lib/openhab/core.rb +2 -1
- data/lib/openhab/dsl/items/timed_command.rb +28 -8
- data/lib/openhab/dsl/rules/builder.rb +41 -5
- data/lib/openhab/dsl/rules/triggers/changed.rb +2 -0
- data/lib/openhab/dsl/timer_manager.rb +2 -2
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/rspec/openhab/core/actions.rb +22 -4
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2c5b8b2a28cbbda196f66340982141af673362693181e88588e89f9c4b1da29
|
4
|
+
data.tar.gz: 6a0483d0d94ae2a9492870e8089efd0b2a1afc400337d790a271b6fd9ca05ae3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/openhab/core/actions.rb
CHANGED
@@ -17,9 +17,8 @@ module OpenHAB
|
|
17
17
|
# * {Voice}
|
18
18
|
#
|
19
19
|
# From add-ons, e.g.:
|
20
|
-
# * NotificationAction
|
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
|
-
#
|
55
|
-
# {
|
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
|
-
|
59
|
-
|
60
|
-
|
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
|
@@ -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
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
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
|
-
#
|
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 {
|
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,
|
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
|
#
|
@@ -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
|
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
|
-
#
|
119
|
+
# Notification.send("The lights were turned on")
|
120
120
|
#
|
121
121
|
# after(30.seconds) { item.off }
|
122
122
|
# end
|
data/lib/openhab/dsl/version.rb
CHANGED
@@ -11,29 +11,47 @@ module OpenHAB
|
|
11
11
|
email,
|
12
12
|
msg,
|
13
13
|
icon,
|
14
|
-
|
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}, #{
|
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
|
-
|
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}, #{
|
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.
|
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
|
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
|