-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
generic_item.rb
229 lines (196 loc) · 6.28 KB
/
generic_item.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# frozen_string_literal: true
require 'delegate'
require 'forwardable'
require_relative 'metadata'
require_relative 'persistence'
require_relative 'semantics'
require_relative 'item_equality'
module OpenHAB
module DSL
module Items
java_import org.openhab.core.items.GenericItem
# Adds methods to core OpenHAB GenericItem type to make it more natural in
# Ruby
#
# @see https://www.openhab.org/javadoc/latest/org/openhab/core/items/genericitem
class GenericItem
include Log
include ItemEquality
prepend Metadata
prepend Persistence
include Semantics
# rubocop:disable Naming/MethodName these mimic Java fields, which are
# actually methods
class << self
# manually define this, since the Java side doesn't
# @!visibility private
def ACCEPTED_COMMAND_TYPES
[org.openhab.core.types.RefreshType.java_class].freeze
end
# manually define this, since the Java side doesn't
# @!visibility private
def ACCEPTED_DATA_TYPES
[org.openhab.core.types.UnDefType.java_class].freeze
end
#
# Override to support ItemProxy
#
def ===(other)
other.instance_of?(self)
end
end
# rubocop:enable Naming/MethodName
alias hash hash_code
# Get the raw item state.
#
# The state of the item, including possibly +NULL+ or +UNDEF+
#
# @return [Types::Type]
#
alias raw_state state
remove_method(:==)
#
# Send a command to this item
#
# @param [Types::Type] command to send to object
#
#
def command(command)
command = format_type_pre(command)
logger.trace "Sending Command #{command} to #{id}"
org.openhab.core.model.script.actions.BusEvent.sendCommand(self, command)
self
end
alias << command
#
# Send an update to this item
#
# @param [Types::Type] update the item
#
#
def update(update)
update = format_type_pre(update)
logger.trace "Sending Update #{update} to #{id}"
org.openhab.core.model.script.actions.BusEvent.postUpdate(self, update)
self
end
#
# Check if the item has a state (not +UNDEF+ or +NULL+)
#
# @return [Boolean]
#
def state?
!raw_state.is_a?(Types::UnDefType)
end
alias truthy? state?
#
# Get the item state
#
# @return [Types::Type, nil]
# OpenHAB item state if state is not +UNDEF+ or +NULL+, nil otherwise
#
def state
raw_state if state?
end
#
# Get an ID for the item, using the item label if set, otherwise item name
#
# @return [String] label if set otherwise name
#
def id
label || name
end
#
# Get the string representation of the state of the item
#
# @return [String] State of the item as a string
#
def to_s
raw_state.to_s # call the super state to include UNDEF/NULL
end
#
# Inspect the item
#
# @return [String] details of the item
#
def inspect
to_string
end
#
# Return all groups that this item is part of
#
# @return [Array<Group>] All groups that this item is part of
#
def groups
group_names.map { |name| Groups.groups[name] }.compact
end
# Return the item's thing if this item is linked with a thing. If an item is linked to more than one thing,
# this method only returns the first thing.
#
# @return [Thing] The thing associated with this item or nil
def thing
all_linked_things.first
end
alias linked_thing thing
# Returns all of the item's linked things.
#
# @return [Array] An array of things or an empty array
def things
registry = OpenHAB::Core::OSGI.service('org.openhab.core.thing.link.ItemChannelLinkRegistry')
channels = registry.get_bound_channels(name).to_a
channels.map(&:thing_uid).uniq.map { |tuid| OpenHAB::DSL::Things.things[tuid] }
end
alias all_linked_things things
#
# Check equality without type conversion
#
# @return [Boolean] if the same Item is represented, without checking
# state
def eql?(other)
other.instance_of?(self.class) && hash == other.hash
end
#
# A method to indicate that item comparison is requested instead of state comparison
#
# Example: Item1.item == items['Item1'].item should return true
#
# See ItemEquality#==
#
def item
@item ||= GenericItemObject.new(self)
end
# @!method null?
# Check if the item state == +NULL+
# @return [Boolean]
# @!method undef?
# Check if the item state == +UNDEF+
# @return [Boolean]
# @!method refresh
# Send the +REFRESH+ command to the item
# @return [GenericItem] +self+
# formats a {Types::Type} to send to the event bus
# @!visibility private
def format_type(command)
# actual Type types can be sent directly without conversion
return command if command.is_a?(Types::Type)
command.to_s
end
private
# convert items to their state before formatting, so that subclasses
# only have to deal with Types
def format_type_pre(command)
command = command.state if command.is_a?(GenericItem)
format_type(command)
end
end
end
# A helper class to flag that item comparison is wanted instead of state comparison
# It is used by ItemEquality#===
class GenericItemObject < SimpleDelegator
extend Forwardable
include Log
include OpenHAB::DSL::Items::ItemEquality
def_delegator :__getobj__, :instance_of? # instance_of? is used by GenericItem#eql? to check for item equality
end
end
end