openhab-scripting 2.16.2 → 2.19.0
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.rb +12 -16
- data/lib/openhab/core/entity_lookup.rb +173 -0
- data/lib/openhab/core/openhab_setup.rb +31 -0
- data/lib/openhab/core/osgi.rb +61 -0
- data/lib/openhab/dsl/actions.rb +105 -0
- data/lib/openhab/dsl/dsl.rb +49 -0
- data/lib/openhab/{core/dsl → dsl}/gems.rb +0 -1
- data/lib/openhab/dsl/group.rb +100 -0
- data/lib/openhab/dsl/items/datetime_item.rb +97 -0
- data/lib/openhab/dsl/items/items.rb +46 -0
- data/lib/openhab/dsl/items/number_item.rb +352 -0
- data/lib/openhab/dsl/items/rollershutter_item.rb +179 -0
- data/lib/openhab/dsl/items/string_item.rb +120 -0
- data/lib/openhab/dsl/monkey_patch/actions/actions.rb +4 -0
- data/lib/openhab/dsl/monkey_patch/actions/script_thing_actions.rb +32 -0
- data/lib/openhab/dsl/monkey_patch/events/events.rb +5 -0
- data/lib/openhab/dsl/monkey_patch/events/item_command.rb +23 -0
- data/lib/openhab/dsl/monkey_patch/events/item_state_changed.rb +35 -0
- data/lib/openhab/dsl/monkey_patch/events/thing_status_info.rb +33 -0
- data/lib/openhab/dsl/monkey_patch/items/contact_item.rb +61 -0
- data/lib/openhab/dsl/monkey_patch/items/dimmer_item.rb +193 -0
- data/lib/openhab/dsl/monkey_patch/items/group_item.rb +37 -0
- data/lib/openhab/dsl/monkey_patch/items/items.rb +133 -0
- data/lib/openhab/dsl/monkey_patch/items/metadata.rb +281 -0
- data/lib/openhab/dsl/monkey_patch/items/persistence.rb +70 -0
- data/lib/openhab/dsl/monkey_patch/items/switch_item.rb +95 -0
- data/lib/openhab/dsl/monkey_patch/ruby/number.rb +39 -0
- data/lib/openhab/dsl/monkey_patch/ruby/range.rb +47 -0
- data/lib/openhab/dsl/monkey_patch/ruby/ruby.rb +8 -0
- data/lib/openhab/dsl/monkey_patch/ruby/string.rb +41 -0
- data/lib/openhab/dsl/monkey_patch/ruby/time.rb +32 -0
- data/lib/openhab/dsl/monkey_patch/types/decimal_type.rb +70 -0
- data/lib/openhab/dsl/monkey_patch/types/on_off_type.rb +51 -0
- data/lib/openhab/dsl/monkey_patch/types/open_closed_type.rb +36 -0
- data/lib/openhab/dsl/monkey_patch/types/percent_type.rb +32 -0
- data/lib/openhab/dsl/monkey_patch/types/quantity_type.rb +69 -0
- data/lib/openhab/dsl/monkey_patch/types/types.rb +9 -0
- data/lib/openhab/dsl/monkey_patch/types/up_down_type.rb +33 -0
- data/lib/openhab/dsl/persistence.rb +25 -0
- data/lib/openhab/dsl/rules/automation_rule.rb +342 -0
- data/lib/openhab/dsl/rules/guard.rb +134 -0
- data/lib/openhab/dsl/rules/property.rb +102 -0
- data/lib/openhab/dsl/rules/rule.rb +116 -0
- data/lib/openhab/dsl/rules/rule_config.rb +151 -0
- data/lib/openhab/dsl/rules/triggers/changed.rb +143 -0
- data/lib/openhab/dsl/rules/triggers/channel.rb +53 -0
- data/lib/openhab/dsl/rules/triggers/command.rb +104 -0
- data/lib/openhab/dsl/rules/triggers/cron.rb +177 -0
- data/lib/openhab/dsl/rules/triggers/trigger.rb +124 -0
- data/lib/openhab/dsl/rules/triggers/updated.rb +98 -0
- data/lib/openhab/dsl/states.rb +61 -0
- data/lib/openhab/dsl/things.rb +91 -0
- data/lib/openhab/dsl/time_of_day.rb +232 -0
- data/lib/openhab/dsl/timers.rb +77 -0
- data/lib/openhab/dsl/types/datetime.rb +326 -0
- data/lib/openhab/dsl/types/quantity.rb +290 -0
- data/lib/openhab/dsl/units.rb +39 -0
- data/lib/openhab/log/configuration.rb +21 -0
- data/lib/openhab/log/logger.rb +172 -0
- data/lib/openhab/version.rb +1 -1
- metadata +60 -58
- data/lib/openhab/configuration.rb +0 -16
- data/lib/openhab/core/cron.rb +0 -27
- data/lib/openhab/core/debug.rb +0 -34
- data/lib/openhab/core/dsl.rb +0 -51
- data/lib/openhab/core/dsl/actions.rb +0 -107
- data/lib/openhab/core/dsl/entities.rb +0 -147
- data/lib/openhab/core/dsl/group.rb +0 -102
- data/lib/openhab/core/dsl/items/items.rb +0 -51
- data/lib/openhab/core/dsl/items/number_item.rb +0 -323
- data/lib/openhab/core/dsl/items/string_item.rb +0 -122
- data/lib/openhab/core/dsl/monkey_patch/actions/actions.rb +0 -4
- data/lib/openhab/core/dsl/monkey_patch/actions/script_thing_actions.rb +0 -22
- data/lib/openhab/core/dsl/monkey_patch/events.rb +0 -5
- data/lib/openhab/core/dsl/monkey_patch/events/item_command.rb +0 -13
- data/lib/openhab/core/dsl/monkey_patch/events/item_state_changed.rb +0 -25
- data/lib/openhab/core/dsl/monkey_patch/events/thing_status_info.rb +0 -26
- data/lib/openhab/core/dsl/monkey_patch/items/contact_item.rb +0 -54
- data/lib/openhab/core/dsl/monkey_patch/items/dimmer_item.rb +0 -182
- data/lib/openhab/core/dsl/monkey_patch/items/group_item.rb +0 -27
- data/lib/openhab/core/dsl/monkey_patch/items/items.rb +0 -132
- data/lib/openhab/core/dsl/monkey_patch/items/metadata.rb +0 -283
- data/lib/openhab/core/dsl/monkey_patch/items/persistence.rb +0 -72
- data/lib/openhab/core/dsl/monkey_patch/items/switch_item.rb +0 -87
- data/lib/openhab/core/dsl/monkey_patch/ruby/number.rb +0 -41
- data/lib/openhab/core/dsl/monkey_patch/ruby/range.rb +0 -47
- data/lib/openhab/core/dsl/monkey_patch/ruby/ruby.rb +0 -7
- data/lib/openhab/core/dsl/monkey_patch/ruby/string.rb +0 -43
- data/lib/openhab/core/dsl/monkey_patch/types/decimal_type.rb +0 -60
- data/lib/openhab/core/dsl/monkey_patch/types/on_off_type.rb +0 -41
- data/lib/openhab/core/dsl/monkey_patch/types/open_closed_type.rb +0 -25
- data/lib/openhab/core/dsl/monkey_patch/types/percent_type.rb +0 -23
- data/lib/openhab/core/dsl/monkey_patch/types/quantity_type.rb +0 -58
- data/lib/openhab/core/dsl/monkey_patch/types/types.rb +0 -8
- data/lib/openhab/core/dsl/persistence.rb +0 -27
- data/lib/openhab/core/dsl/property.rb +0 -96
- data/lib/openhab/core/dsl/rule/automation_rule.rb +0 -345
- data/lib/openhab/core/dsl/rule/guard.rb +0 -136
- data/lib/openhab/core/dsl/rule/rule.rb +0 -117
- data/lib/openhab/core/dsl/rule/rule_config.rb +0 -153
- data/lib/openhab/core/dsl/rule/triggers/changed.rb +0 -145
- data/lib/openhab/core/dsl/rule/triggers/channel.rb +0 -55
- data/lib/openhab/core/dsl/rule/triggers/command.rb +0 -106
- data/lib/openhab/core/dsl/rule/triggers/cron.rb +0 -160
- data/lib/openhab/core/dsl/rule/triggers/trigger.rb +0 -126
- data/lib/openhab/core/dsl/rule/triggers/updated.rb +0 -100
- data/lib/openhab/core/dsl/states.rb +0 -63
- data/lib/openhab/core/dsl/things.rb +0 -93
- data/lib/openhab/core/dsl/time_of_day.rb +0 -231
- data/lib/openhab/core/dsl/timers.rb +0 -79
- data/lib/openhab/core/dsl/types/quantity.rb +0 -292
- data/lib/openhab/core/dsl/units.rb +0 -41
- data/lib/openhab/core/log.rb +0 -170
- data/lib/openhab/core/patch_load_path.rb +0 -7
- data/lib/openhab/core/startup_delay.rb +0 -23
- data/lib/openhab/osgi.rb +0 -59
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'java'
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module DSL
|
|
7
|
+
module MonkeyPatch
|
|
8
|
+
#
|
|
9
|
+
# Patches OpenHAB items
|
|
10
|
+
#
|
|
11
|
+
module Items
|
|
12
|
+
java_import Java::OrgOpenhabCoreLibraryItems::DimmerItem
|
|
13
|
+
java_import Java::OrgOpenhabCoreItems::GenericItem
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Alias class for is_a? testing
|
|
17
|
+
#
|
|
18
|
+
::Dimmer = DimmerItem
|
|
19
|
+
|
|
20
|
+
#
|
|
21
|
+
# Monkey Patch DimmerItem
|
|
22
|
+
#
|
|
23
|
+
class DimmerItem
|
|
24
|
+
include Comparable
|
|
25
|
+
java_import Java::OrgOpenhabCoreLibraryTypes::DecimalType
|
|
26
|
+
java_import Java::OrgOpenhabCoreLibraryTypes::IncreaseDecreaseType
|
|
27
|
+
|
|
28
|
+
#
|
|
29
|
+
# Add the current dimmer value to the supplied object
|
|
30
|
+
#
|
|
31
|
+
# @param [Object] other object to add the dimmer value to
|
|
32
|
+
#
|
|
33
|
+
# @return [Integer] Current dimmer value plus value of supplied object
|
|
34
|
+
#
|
|
35
|
+
def +(other)
|
|
36
|
+
return unless state?
|
|
37
|
+
|
|
38
|
+
state.to_big_decimal.intValue + other
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
#
|
|
42
|
+
# Subtract the supplied object from the current value of the dimmer
|
|
43
|
+
#
|
|
44
|
+
# @param [Object] other object to subtract from the dimmer value
|
|
45
|
+
#
|
|
46
|
+
# @return [Integer] Current dimmer value minus value of supplied object
|
|
47
|
+
#
|
|
48
|
+
def -(other)
|
|
49
|
+
return unless state?
|
|
50
|
+
|
|
51
|
+
state.to_big_decimal.intValue - other
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# Dim the dimmer
|
|
56
|
+
#
|
|
57
|
+
# @param [Integer] amount to dim by
|
|
58
|
+
#
|
|
59
|
+
# @return [Integer] level target for dimmer
|
|
60
|
+
#
|
|
61
|
+
def dim(amount = 1)
|
|
62
|
+
return unless state?
|
|
63
|
+
|
|
64
|
+
target = [state.to_big_decimal.intValue - amount, 0].max
|
|
65
|
+
|
|
66
|
+
if amount == 1
|
|
67
|
+
command(IncreaseDecreaseType::DECREASE)
|
|
68
|
+
else
|
|
69
|
+
command(target)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
target
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
#
|
|
76
|
+
# Brighten the dimmer
|
|
77
|
+
#
|
|
78
|
+
# @param [Integer] amount to brighten by
|
|
79
|
+
#
|
|
80
|
+
# @return [Integer] level target for dimmer
|
|
81
|
+
#
|
|
82
|
+
def brighten(amount = 1)
|
|
83
|
+
return unless state?
|
|
84
|
+
|
|
85
|
+
target = state.to_big_decimal.intValue + amount
|
|
86
|
+
|
|
87
|
+
if amount == 1
|
|
88
|
+
command(IncreaseDecreaseType::INCREASE)
|
|
89
|
+
else
|
|
90
|
+
command(target)
|
|
91
|
+
end
|
|
92
|
+
target
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
#
|
|
96
|
+
# Compare DimmerItem to supplied object
|
|
97
|
+
#
|
|
98
|
+
# @param [Object] other object to compare to
|
|
99
|
+
#
|
|
100
|
+
# @return [Integer] -1,0,1 or nil depending on value supplied,
|
|
101
|
+
# nil comparison to supplied object is not possible.
|
|
102
|
+
#
|
|
103
|
+
def <=>(other)
|
|
104
|
+
logger.trace("Comparing #{self} to #{other}")
|
|
105
|
+
case other
|
|
106
|
+
when GenericItem, NumberItem then state <=> other.state
|
|
107
|
+
when DecimalType then state <=> other
|
|
108
|
+
when Numeric then state.to_big_decimal.to_d <=> other.to_d
|
|
109
|
+
else compare_to(other)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
#
|
|
114
|
+
# Coerce objects into a DimmerItem
|
|
115
|
+
#
|
|
116
|
+
# @param [Object] other object to coerce to a DimmerItem if possible
|
|
117
|
+
#
|
|
118
|
+
# @return [Object] Numeric when applicable
|
|
119
|
+
#
|
|
120
|
+
def coerce(other)
|
|
121
|
+
logger.trace("Coercing #{self} as a request from #{other.class}")
|
|
122
|
+
case other
|
|
123
|
+
when Numeric
|
|
124
|
+
[other, state.to_big_decimal.to_d]
|
|
125
|
+
else
|
|
126
|
+
[other, state]
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
#
|
|
131
|
+
# Compare DimmerItem to supplied object.
|
|
132
|
+
# The == operator needs to be overridden because the parent java object
|
|
133
|
+
# has .equals which overrides the <=> operator above
|
|
134
|
+
#
|
|
135
|
+
# @param [Object] other object to compare to
|
|
136
|
+
#
|
|
137
|
+
# @return [Integer] true if the two objects contain the same value, false otherwise
|
|
138
|
+
#
|
|
139
|
+
def ==(other)
|
|
140
|
+
(self <=> other).zero?
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
#
|
|
144
|
+
# Check if dimmer has a state and state is not zero
|
|
145
|
+
#
|
|
146
|
+
# @return [Boolean] True if dimmer is not NULL or UNDEF and value is not 0
|
|
147
|
+
#
|
|
148
|
+
def truthy?
|
|
149
|
+
state? && state != DecimalType::ZERO
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
#
|
|
153
|
+
# Value of dimmer
|
|
154
|
+
#
|
|
155
|
+
# @return [Integer] Value of dimmer or nil if state is UNDEF or NULL
|
|
156
|
+
#
|
|
157
|
+
def to_i
|
|
158
|
+
state&.to_big_decimal&.intValue
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
alias to_int to_i
|
|
162
|
+
|
|
163
|
+
#
|
|
164
|
+
# Return the string representation of the dimmer item
|
|
165
|
+
#
|
|
166
|
+
# @return [String] String version of the dimmer value
|
|
167
|
+
#
|
|
168
|
+
def to_s
|
|
169
|
+
to_i.to_s
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
#
|
|
173
|
+
# Check if dimmer is on
|
|
174
|
+
#
|
|
175
|
+
# @return [Boolean] True if item is not UNDEF or NULL and has a value greater than 0
|
|
176
|
+
#
|
|
177
|
+
def on?
|
|
178
|
+
state&.to_big_decimal&.intValue&.positive?
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
#
|
|
182
|
+
# Check if dimmer is off
|
|
183
|
+
#
|
|
184
|
+
# @return [Boolean] True if item is not UNDEF or NULL and has a state of 0
|
|
185
|
+
#
|
|
186
|
+
def off?
|
|
187
|
+
state&.to_big_decimal&.intValue&.zero?
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenHAB
|
|
4
|
+
module DSL
|
|
5
|
+
module MonkeyPatch
|
|
6
|
+
#
|
|
7
|
+
# Patches OpenHAB items
|
|
8
|
+
#
|
|
9
|
+
module Items
|
|
10
|
+
java_import Java::OrgOpenhabCoreItems::GroupItem
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# Monkey patch Group Item
|
|
14
|
+
#
|
|
15
|
+
class GroupItem
|
|
16
|
+
#
|
|
17
|
+
# Get all items in a group
|
|
18
|
+
#
|
|
19
|
+
# @return [Array] Array of items in the group
|
|
20
|
+
#
|
|
21
|
+
def items
|
|
22
|
+
to_a
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Get all items in the group as an Array
|
|
27
|
+
#
|
|
28
|
+
# @return [Array] All items in the group
|
|
29
|
+
#
|
|
30
|
+
def to_a
|
|
31
|
+
all_members.each_with_object([]) { |item, arr| arr << item }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'java'
|
|
4
|
+
require 'openhab/log/logger'
|
|
5
|
+
require 'bigdecimal'
|
|
6
|
+
|
|
7
|
+
# Monkey patch items
|
|
8
|
+
require 'openhab/dsl/monkey_patch/items/metadata'
|
|
9
|
+
require 'openhab/dsl/monkey_patch/items/persistence'
|
|
10
|
+
require 'openhab/dsl/monkey_patch/items/contact_item'
|
|
11
|
+
require 'openhab/dsl/monkey_patch/items/dimmer_item'
|
|
12
|
+
require 'openhab/dsl/monkey_patch/items/switch_item'
|
|
13
|
+
require 'openhab/dsl/monkey_patch/items/group_item'
|
|
14
|
+
|
|
15
|
+
module OpenHAB
|
|
16
|
+
module DSL
|
|
17
|
+
module MonkeyPatch
|
|
18
|
+
#
|
|
19
|
+
# Monkeypatches Items
|
|
20
|
+
#
|
|
21
|
+
module Items
|
|
22
|
+
#
|
|
23
|
+
# Extensions for Items
|
|
24
|
+
#
|
|
25
|
+
module ItemExtensions
|
|
26
|
+
include OpenHAB::Log
|
|
27
|
+
java_import Java::OrgOpenhabCoreModelScriptActions::BusEvent
|
|
28
|
+
java_import Java::OrgOpenhabCoreTypes::UnDefType
|
|
29
|
+
|
|
30
|
+
#
|
|
31
|
+
# Send a command to this item
|
|
32
|
+
#
|
|
33
|
+
# @param [Object] command to send to object
|
|
34
|
+
#
|
|
35
|
+
#
|
|
36
|
+
def command(command)
|
|
37
|
+
command = command.to_java.strip_trailing_zeros if command.is_a? BigDecimal
|
|
38
|
+
logger.trace "Sending Command #{command} to #{id}"
|
|
39
|
+
BusEvent.sendCommand(self, command.to_s)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
alias << command
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
# Send an update to this item
|
|
46
|
+
#
|
|
47
|
+
# @param [Object] update the item
|
|
48
|
+
#
|
|
49
|
+
#
|
|
50
|
+
def update(update)
|
|
51
|
+
logger.trace "Sending Update #{update} to #{id}"
|
|
52
|
+
BusEvent.postUpdate(self, update.to_s)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
#
|
|
56
|
+
# Check if the item state == UNDEF
|
|
57
|
+
#
|
|
58
|
+
# @return [Boolean] True if the state is UNDEF, false otherwise
|
|
59
|
+
#
|
|
60
|
+
def undef?
|
|
61
|
+
# Need to explicitly call the super method version because this state will never return UNDEF
|
|
62
|
+
method(:state).super_method.call == UnDefType::UNDEF
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
#
|
|
66
|
+
# Check if the item state == NULL
|
|
67
|
+
#
|
|
68
|
+
# @return [Boolean] True if the state is NULL, false otherwise
|
|
69
|
+
def null?
|
|
70
|
+
# Need to explicitly call the super method version because this state will never return NULL
|
|
71
|
+
method(:state).super_method.call == UnDefType::NULL
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
#
|
|
75
|
+
# Check if the item has a state (not UNDEF or NULL)
|
|
76
|
+
#
|
|
77
|
+
# @return [Boolean] True if state is not UNDEF or NULL
|
|
78
|
+
#
|
|
79
|
+
def state?
|
|
80
|
+
undef? == false && null? == false
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Get the item state
|
|
85
|
+
#
|
|
86
|
+
# @return [State] OpenHAB item state if state is not UNDEF or NULL, nil otherwise
|
|
87
|
+
#
|
|
88
|
+
def state
|
|
89
|
+
super if state?
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
#
|
|
93
|
+
# Get an ID for the item, using the item label if set, otherwise item name
|
|
94
|
+
#
|
|
95
|
+
# @return [String] label if set otherwise name
|
|
96
|
+
#
|
|
97
|
+
def id
|
|
98
|
+
label || name
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
#
|
|
102
|
+
# Get the string representation of the state of the item
|
|
103
|
+
#
|
|
104
|
+
# @return [String] State of the item as a string if not UNDEF or NULL, nil otherwise
|
|
105
|
+
#
|
|
106
|
+
def to_s
|
|
107
|
+
state&.to_s
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
# Inspect the item
|
|
112
|
+
#
|
|
113
|
+
# @return [String] details of the item
|
|
114
|
+
#
|
|
115
|
+
def inspect
|
|
116
|
+
toString
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
java_import Java::OrgOpenhabCoreItems::GenericItem
|
|
121
|
+
|
|
122
|
+
#
|
|
123
|
+
# Monkey patches all OpenHAB items
|
|
124
|
+
#
|
|
125
|
+
class GenericItem
|
|
126
|
+
prepend OpenHAB::DSL::MonkeyPatch::Items::ItemExtensions
|
|
127
|
+
prepend OpenHAB::DSL::MonkeyPatch::Items::Metadata
|
|
128
|
+
prepend OpenHAB::DSL::MonkeyPatch::Items::Persistence
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'java'
|
|
4
|
+
require 'delegate'
|
|
5
|
+
require 'pp'
|
|
6
|
+
require 'forwardable'
|
|
7
|
+
require 'openhab/core/osgi'
|
|
8
|
+
require 'openhab/log/logger'
|
|
9
|
+
|
|
10
|
+
module OpenHAB
|
|
11
|
+
module DSL
|
|
12
|
+
module MonkeyPatch
|
|
13
|
+
module Items
|
|
14
|
+
#
|
|
15
|
+
# Metadata extension for Items
|
|
16
|
+
#
|
|
17
|
+
module Metadata
|
|
18
|
+
include OpenHAB::Log
|
|
19
|
+
|
|
20
|
+
java_import Java::OrgOpenhabCoreItems::Metadata
|
|
21
|
+
java_import Java::OrgOpenhabCoreItems::MetadataKey
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# Provide the interface to access namespace's value and configuration
|
|
25
|
+
#
|
|
26
|
+
class MetadataItem < SimpleDelegator
|
|
27
|
+
extend Forwardable
|
|
28
|
+
|
|
29
|
+
def_delegator :@metadata, :value
|
|
30
|
+
|
|
31
|
+
def initialize(metadata: nil, key: nil, value: nil, config: nil)
|
|
32
|
+
@metadata = metadata || Metadata.new(key || MetadataKey.new('', ''), value, config)
|
|
33
|
+
super(@metadata&.configuration)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
#
|
|
37
|
+
# Updates the metadata configuration associated with the key
|
|
38
|
+
#
|
|
39
|
+
def []=(key, value)
|
|
40
|
+
configuration = {}.merge(@metadata&.configuration || {}).merge({ key => value })
|
|
41
|
+
metadata = Metadata.new(@metadata&.uID, @metadata&.value, configuration)
|
|
42
|
+
NamespaceAccessor.registry.update(metadata) if @metadata&.uID
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# Delete the configuration with the given key
|
|
47
|
+
#
|
|
48
|
+
# @return [Java::Org::openhab::core::items::Metadata] the old metadata
|
|
49
|
+
#
|
|
50
|
+
def delete(key)
|
|
51
|
+
configuration = {}.merge(@metadata&.configuration || {})
|
|
52
|
+
configuration.delete(key)
|
|
53
|
+
metadata = Metadata.new(@metadata&.uID, @metadata&.value, configuration)
|
|
54
|
+
NamespaceAccessor.registry.update(metadata) if @metadata&.uID
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Set the metadata value
|
|
59
|
+
#
|
|
60
|
+
# @return [Java::Org::openhab::core::items::Metadata] the old metadata
|
|
61
|
+
#
|
|
62
|
+
def value=(value)
|
|
63
|
+
raise ArgumentError, 'Value must be a string' unless value.is_a? String
|
|
64
|
+
|
|
65
|
+
metadata = Metadata.new(@metadata&.uID, value, @metadata&.configuration)
|
|
66
|
+
NamespaceAccessor.registry.update(metadata) if @metadata&.uID
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
#
|
|
70
|
+
# Set the entire configuration to a hash
|
|
71
|
+
#
|
|
72
|
+
# @return [Java::Org::openhab::core::items::Metadata] the old metadata
|
|
73
|
+
#
|
|
74
|
+
def config=(config)
|
|
75
|
+
raise ArgumentError, 'Configuration must be a hash' unless config.is_a? Hash
|
|
76
|
+
|
|
77
|
+
metadata = Metadata.new(@metadata&.uID, @metadata&.value, config)
|
|
78
|
+
NamespaceAccessor.registry.update(metadata) if @metadata&.uID
|
|
79
|
+
end
|
|
80
|
+
alias configuration= config=
|
|
81
|
+
|
|
82
|
+
#
|
|
83
|
+
# Convert the metadata to an array
|
|
84
|
+
#
|
|
85
|
+
# @return [Array[2]] An array of [value, configuration]
|
|
86
|
+
#
|
|
87
|
+
def to_a
|
|
88
|
+
[@metadata&.value, @metadata&.configuration || {}]
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
#
|
|
93
|
+
# Provide the interface to access item metadata
|
|
94
|
+
#
|
|
95
|
+
class NamespaceAccessor
|
|
96
|
+
include Enumerable
|
|
97
|
+
|
|
98
|
+
def initialize(item_name:)
|
|
99
|
+
@item_name = item_name
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
#
|
|
103
|
+
# Return the metadata namespace
|
|
104
|
+
#
|
|
105
|
+
# @return [OpenHAB::DSL::MonkeyPatch::Items::MetadataItem], or nil if the namespace doesn't exist
|
|
106
|
+
#
|
|
107
|
+
def [](namespace)
|
|
108
|
+
logger.trace("Namespaces (#{NamespaceAccessor.registry.getAll})")
|
|
109
|
+
logger.trace("Namespace (#{NamespaceAccessor.registry.get(MetadataKey.new(namespace, @item_name))})")
|
|
110
|
+
metadata = NamespaceAccessor.registry.get(MetadataKey.new(namespace, @item_name))
|
|
111
|
+
MetadataItem.new(metadata: metadata) if metadata
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
#
|
|
115
|
+
# Set the metadata namespace. If the namespace does not exist, it will be created
|
|
116
|
+
#
|
|
117
|
+
# @param value [Object] The assigned value can be a OpenHAB::DSL::MonkeyPatch::Items::MetadataItem,
|
|
118
|
+
# Java::Org::openhab::core::items::Metadata, Array[2] of [value, configuration],
|
|
119
|
+
# A String to set the value and clear the configuration,
|
|
120
|
+
# or a Hash to set the configuration and set the value to nil
|
|
121
|
+
#
|
|
122
|
+
# @return [OpenHAB::DSL::MonkeyPatch::Items::MetadataItem]
|
|
123
|
+
#
|
|
124
|
+
def []=(namespace, value)
|
|
125
|
+
meta_value, configuration = update_from_value(value)
|
|
126
|
+
|
|
127
|
+
key = MetadataKey.new(namespace, @item_name)
|
|
128
|
+
metadata = Metadata.new(key, meta_value, configuration)
|
|
129
|
+
# registry.get can be omitted, but registry.update will log a warning for nonexistent metadata
|
|
130
|
+
if NamespaceAccessor.registry.get(key)
|
|
131
|
+
NamespaceAccessor.registry.update(metadata)
|
|
132
|
+
else
|
|
133
|
+
NamespaceAccessor.registry.add(metadata)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
#
|
|
138
|
+
# Enumerates through all the namespaces
|
|
139
|
+
#
|
|
140
|
+
def each
|
|
141
|
+
return unless block_given?
|
|
142
|
+
|
|
143
|
+
NamespaceAccessor.registry.getAll.each do |meta|
|
|
144
|
+
yield meta.uID.namespace, meta.value, meta.configuration if meta.uID.itemName == @item_name
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
#
|
|
149
|
+
# Remove all the namespaces
|
|
150
|
+
#
|
|
151
|
+
def clear
|
|
152
|
+
NamespaceAccessor.registry.removeItemMetadata @item_name
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
#
|
|
156
|
+
# Delete a specific namespace
|
|
157
|
+
#
|
|
158
|
+
# @param namespace [String] The namespace to delete
|
|
159
|
+
#
|
|
160
|
+
def delete(namespace)
|
|
161
|
+
NamespaceAccessor.registry.remove(MetadataKey.new(namespace, @item_name))
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
alias delete_all clear
|
|
165
|
+
|
|
166
|
+
#
|
|
167
|
+
# @return [Boolean] True if the given namespace exists, false otherwise
|
|
168
|
+
#
|
|
169
|
+
def key?(namespace)
|
|
170
|
+
!NamespaceAccessor.registry.get(MetadataKey.new(namespace, @item_name)).nil?
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
alias has_key? key?
|
|
174
|
+
alias include? key?
|
|
175
|
+
|
|
176
|
+
#
|
|
177
|
+
# Merge the given hash with the current metadata. Existing namespace that matches the name
|
|
178
|
+
# of the new namespace will be overwritten. Others will be added.
|
|
179
|
+
#
|
|
180
|
+
def merge!(*others)
|
|
181
|
+
return self if others.empty?
|
|
182
|
+
|
|
183
|
+
others.each do |other|
|
|
184
|
+
case other
|
|
185
|
+
when Hash then merge_hash!(other)
|
|
186
|
+
when self.class then merge_metadata!(other)
|
|
187
|
+
else raise ArgumentError, "merge only supports Hash, or another item's metadata"
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
self
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
#
|
|
194
|
+
# @return [String] the string representation of all the namespaces with their value and config
|
|
195
|
+
#
|
|
196
|
+
def to_s
|
|
197
|
+
namespaces = []
|
|
198
|
+
each { |ns, value, config| namespaces << "\"#{ns}\"=>[\"#{value}\",#{config}]" }
|
|
199
|
+
"{#{namespaces.join(',')}}"
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
#
|
|
203
|
+
# @return [Java::org::openhab::core::items::MetadataRegistry]
|
|
204
|
+
#
|
|
205
|
+
def self.registry
|
|
206
|
+
@registry ||= OpenHAB::Core::OSGI.service('org.openhab.core.items.MetadataRegistry')
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
private
|
|
210
|
+
|
|
211
|
+
#
|
|
212
|
+
# perform an updated based on the supplied value
|
|
213
|
+
#
|
|
214
|
+
# @param [MetadataItem,Metadata,Array,Hash] value to perform update from
|
|
215
|
+
#
|
|
216
|
+
# @return [Array<Object,Hash>] Array containing the value and configuration based on the
|
|
217
|
+
# the supplied object
|
|
218
|
+
#
|
|
219
|
+
def update_from_value(value)
|
|
220
|
+
case value
|
|
221
|
+
when MetadataItem then [value.value, value.__getobj__]
|
|
222
|
+
when Metadata then [value.value, value.configuration]
|
|
223
|
+
when Array
|
|
224
|
+
raise ArgumentError, 'Array must contain 2 elements: value, config' if value.length != 2
|
|
225
|
+
|
|
226
|
+
value
|
|
227
|
+
when Hash then [nil, value]
|
|
228
|
+
else [value, nil]
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
#
|
|
233
|
+
# Merge the metadata from the supplied other metadata object
|
|
234
|
+
#
|
|
235
|
+
# @param [Hash] other metadata object to merge
|
|
236
|
+
# @yield [key, current_metadata, new_meta] to process merge
|
|
237
|
+
#
|
|
238
|
+
#
|
|
239
|
+
def merge_metadata!(other)
|
|
240
|
+
other.each do |key, new_value, new_config|
|
|
241
|
+
new_meta = new_value, new_config
|
|
242
|
+
if block_given?
|
|
243
|
+
current_meta = self[key]&.to_a
|
|
244
|
+
new_meta = yield key, current_meta, new_meta unless current_meta.nil?
|
|
245
|
+
end
|
|
246
|
+
self[key] = new_meta
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
#
|
|
251
|
+
# Merge a hash into the metadata
|
|
252
|
+
#
|
|
253
|
+
# @param [Hash] other to merge into metadata
|
|
254
|
+
# @yield [key, current_metadata, new_meta] to process merge
|
|
255
|
+
#
|
|
256
|
+
#
|
|
257
|
+
def merge_hash!(other)
|
|
258
|
+
other.each do |key, new_meta|
|
|
259
|
+
if block_given?
|
|
260
|
+
current_meta = self[key]&.to_a
|
|
261
|
+
new_meta = yield key, current_meta, new_meta unless current_meta.nil?
|
|
262
|
+
end
|
|
263
|
+
self[key] = new_meta
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
#
|
|
269
|
+
# Accessor to the item's metadata
|
|
270
|
+
#
|
|
271
|
+
# @return [NamespaceAccessor] an Enumerable object to access item's namespaces
|
|
272
|
+
#
|
|
273
|
+
def meta
|
|
274
|
+
@meta ||= NamespaceAccessor.new(item_name: name)
|
|
275
|
+
end
|
|
276
|
+
alias metadata meta
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|