openhab-jrubyscripting 5.0.0.rc1
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 +7 -0
- data/lib/openhab/core/actions.rb +163 -0
- data/lib/openhab/core/entity_lookup.rb +144 -0
- data/lib/openhab/core/events/abstract_event.rb +17 -0
- data/lib/openhab/core/events/item_channel_link.rb +36 -0
- data/lib/openhab/core/events/item_command_event.rb +78 -0
- data/lib/openhab/core/events/item_event.rb +22 -0
- data/lib/openhab/core/events/item_state_changed_event.rb +52 -0
- data/lib/openhab/core/events/item_state_event.rb +51 -0
- data/lib/openhab/core/events/thing.rb +29 -0
- data/lib/openhab/core/events/thing_status_info_event.rb +53 -0
- data/lib/openhab/core/events.rb +10 -0
- data/lib/openhab/core/items/accepted_data_types.rb +29 -0
- data/lib/openhab/core/items/color_item.rb +52 -0
- data/lib/openhab/core/items/contact_item.rb +52 -0
- data/lib/openhab/core/items/date_time_item.rb +58 -0
- data/lib/openhab/core/items/dimmer_item.rb +148 -0
- data/lib/openhab/core/items/generic_item.rb +344 -0
- data/lib/openhab/core/items/group_item.rb +174 -0
- data/lib/openhab/core/items/image_item.rb +109 -0
- data/lib/openhab/core/items/location_item.rb +34 -0
- data/lib/openhab/core/items/metadata/hash.rb +390 -0
- data/lib/openhab/core/items/metadata/namespace_hash.rb +469 -0
- data/lib/openhab/core/items/metadata.rb +11 -0
- data/lib/openhab/core/items/number_item.rb +62 -0
- data/lib/openhab/core/items/numeric_item.rb +22 -0
- data/lib/openhab/core/items/persistence.rb +327 -0
- data/lib/openhab/core/items/player_item.rb +66 -0
- data/lib/openhab/core/items/proxy.rb +59 -0
- data/lib/openhab/core/items/registry.rb +66 -0
- data/lib/openhab/core/items/rollershutter_item.rb +68 -0
- data/lib/openhab/core/items/semantics/enumerable.rb +152 -0
- data/lib/openhab/core/items/semantics.rb +476 -0
- data/lib/openhab/core/items/state_storage.rb +53 -0
- data/lib/openhab/core/items/string_item.rb +28 -0
- data/lib/openhab/core/items/switch_item.rb +78 -0
- data/lib/openhab/core/items.rb +114 -0
- data/lib/openhab/core/lazy_array.rb +52 -0
- data/lib/openhab/core/profile_factory.rb +118 -0
- data/lib/openhab/core/script_handling.rb +55 -0
- data/lib/openhab/core/things/channel.rb +48 -0
- data/lib/openhab/core/things/channel_uid.rb +51 -0
- data/lib/openhab/core/things/item_channel_link.rb +33 -0
- data/lib/openhab/core/things/profile_callback.rb +52 -0
- data/lib/openhab/core/things/proxy.rb +69 -0
- data/lib/openhab/core/things/registry.rb +46 -0
- data/lib/openhab/core/things/thing.rb +194 -0
- data/lib/openhab/core/things.rb +22 -0
- data/lib/openhab/core/timer.rb +128 -0
- data/lib/openhab/core/types/comparable_type.rb +23 -0
- data/lib/openhab/core/types/date_time_type.rb +259 -0
- data/lib/openhab/core/types/decimal_type.rb +192 -0
- data/lib/openhab/core/types/hsb_type.rb +183 -0
- data/lib/openhab/core/types/increase_decrease_type.rb +34 -0
- data/lib/openhab/core/types/next_previous_type.rb +34 -0
- data/lib/openhab/core/types/numeric_type.rb +52 -0
- data/lib/openhab/core/types/on_off_type.rb +46 -0
- data/lib/openhab/core/types/open_closed_type.rb +41 -0
- data/lib/openhab/core/types/percent_type.rb +95 -0
- data/lib/openhab/core/types/play_pause_type.rb +38 -0
- data/lib/openhab/core/types/point_type.rb +117 -0
- data/lib/openhab/core/types/quantity_type.rb +327 -0
- data/lib/openhab/core/types/raw_type.rb +26 -0
- data/lib/openhab/core/types/refresh_type.rb +27 -0
- data/lib/openhab/core/types/rewind_fastforward_type.rb +38 -0
- data/lib/openhab/core/types/stop_move_type.rb +34 -0
- data/lib/openhab/core/types/string_type.rb +76 -0
- data/lib/openhab/core/types/type.rb +117 -0
- data/lib/openhab/core/types/un_def_type.rb +38 -0
- data/lib/openhab/core/types/up_down_type.rb +50 -0
- data/lib/openhab/core/types.rb +69 -0
- data/lib/openhab/core/uid.rb +36 -0
- data/lib/openhab/core.rb +85 -0
- data/lib/openhab/core_ext/java/duration.rb +115 -0
- data/lib/openhab/core_ext/java/local_date.rb +93 -0
- data/lib/openhab/core_ext/java/local_time.rb +106 -0
- data/lib/openhab/core_ext/java/month.rb +59 -0
- data/lib/openhab/core_ext/java/month_day.rb +105 -0
- data/lib/openhab/core_ext/java/period.rb +103 -0
- data/lib/openhab/core_ext/java/temporal_amount.rb +34 -0
- data/lib/openhab/core_ext/java/time.rb +58 -0
- data/lib/openhab/core_ext/java/unit.rb +15 -0
- data/lib/openhab/core_ext/java/zoned_date_time.rb +116 -0
- data/lib/openhab/core_ext/ruby/array.rb +21 -0
- data/lib/openhab/core_ext/ruby/class.rb +15 -0
- data/lib/openhab/core_ext/ruby/date.rb +89 -0
- data/lib/openhab/core_ext/ruby/numeric.rb +190 -0
- data/lib/openhab/core_ext/ruby/range.rb +70 -0
- data/lib/openhab/core_ext/ruby/time.rb +104 -0
- data/lib/openhab/core_ext.rb +18 -0
- data/lib/openhab/dsl/events/watch_event.rb +18 -0
- data/lib/openhab/dsl/events.rb +9 -0
- data/lib/openhab/dsl/gems.rb +3 -0
- data/lib/openhab/dsl/items/builder.rb +618 -0
- data/lib/openhab/dsl/items/ensure.rb +93 -0
- data/lib/openhab/dsl/items/timed_command.rb +236 -0
- data/lib/openhab/dsl/rules/automation_rule.rb +308 -0
- data/lib/openhab/dsl/rules/builder.rb +1373 -0
- data/lib/openhab/dsl/rules/guard.rb +115 -0
- data/lib/openhab/dsl/rules/name_inference.rb +160 -0
- data/lib/openhab/dsl/rules/property.rb +76 -0
- data/lib/openhab/dsl/rules/rule_triggers.rb +96 -0
- data/lib/openhab/dsl/rules/terse.rb +63 -0
- data/lib/openhab/dsl/rules/triggers/changed.rb +169 -0
- data/lib/openhab/dsl/rules/triggers/channel.rb +57 -0
- data/lib/openhab/dsl/rules/triggers/command.rb +107 -0
- data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +161 -0
- data/lib/openhab/dsl/rules/triggers/conditions/proc.rb +164 -0
- data/lib/openhab/dsl/rules/triggers/cron/cron.rb +195 -0
- data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +127 -0
- data/lib/openhab/dsl/rules/triggers/trigger.rb +56 -0
- data/lib/openhab/dsl/rules/triggers/updated.rb +130 -0
- data/lib/openhab/dsl/rules/triggers/watch/watch.rb +55 -0
- data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +155 -0
- data/lib/openhab/dsl/rules/triggers.rb +12 -0
- data/lib/openhab/dsl/rules.rb +29 -0
- data/lib/openhab/dsl/script_handling.rb +55 -0
- data/lib/openhab/dsl/things/builder.rb +263 -0
- data/lib/openhab/dsl/thread_local.rb +48 -0
- data/lib/openhab/dsl/timer_manager.rb +191 -0
- data/lib/openhab/dsl/version.rb +9 -0
- data/lib/openhab/dsl.rb +686 -0
- data/lib/openhab/log.rb +348 -0
- data/lib/openhab/osgi.rb +70 -0
- data/lib/openhab/rspec/configuration.rb +56 -0
- data/lib/openhab/rspec/example_group.rb +90 -0
- data/lib/openhab/rspec/helpers.rb +439 -0
- data/lib/openhab/rspec/hooks.rb +93 -0
- data/lib/openhab/rspec/jruby.rb +46 -0
- data/lib/openhab/rspec/karaf.rb +811 -0
- data/lib/openhab/rspec/mocks/bundle_install_support.rb +25 -0
- data/lib/openhab/rspec/mocks/bundle_resolver.rb +30 -0
- data/lib/openhab/rspec/mocks/event_admin.rb +146 -0
- data/lib/openhab/rspec/mocks/metadata_provider.rb +75 -0
- data/lib/openhab/rspec/mocks/persistence_service.rb +140 -0
- data/lib/openhab/rspec/mocks/safe_caller.rb +40 -0
- data/lib/openhab/rspec/mocks/synchronous_executor.rb +56 -0
- data/lib/openhab/rspec/mocks/thing_handler.rb +76 -0
- data/lib/openhab/rspec/mocks/timer.rb +95 -0
- data/lib/openhab/rspec/openhab/core/actions.rb +26 -0
- data/lib/openhab/rspec/openhab/core/items/proxy.rb +27 -0
- data/lib/openhab/rspec/openhab/core/things/proxy.rb +27 -0
- data/lib/openhab/rspec/shell.rb +31 -0
- data/lib/openhab/rspec/suspend_rules.rb +60 -0
- data/lib/openhab/rspec.rb +17 -0
- data/lib/openhab/yard/cli/stats.rb +23 -0
- data/lib/openhab/yard/code_objects/group_object.rb +17 -0
- data/lib/openhab/yard/code_objects/java/base.rb +31 -0
- data/lib/openhab/yard/code_objects/java/class_object.rb +11 -0
- data/lib/openhab/yard/code_objects/java/field_object.rb +15 -0
- data/lib/openhab/yard/code_objects/java/interface_object.rb +15 -0
- data/lib/openhab/yard/code_objects/java/package_object.rb +11 -0
- data/lib/openhab/yard/code_objects/java/proxy.rb +23 -0
- data/lib/openhab/yard/handlers/jruby/base.rb +49 -0
- data/lib/openhab/yard/handlers/jruby/class_handler.rb +18 -0
- data/lib/openhab/yard/handlers/jruby/constant_handler.rb +18 -0
- data/lib/openhab/yard/handlers/jruby/java_import_handler.rb +27 -0
- data/lib/openhab/yard/handlers/jruby/mixin_handler.rb +23 -0
- data/lib/openhab/yard/html_helper.rb +44 -0
- data/lib/openhab/yard/tags/constant_directive.rb +20 -0
- data/lib/openhab/yard/tags/group_directive.rb +24 -0
- data/lib/openhab/yard/tags/library.rb +3 -0
- data/lib/openhab/yard.rb +32 -0
- metadata +504 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openhab/core/lazy_array"
|
|
4
|
+
|
|
5
|
+
require_relative "generic_item"
|
|
6
|
+
|
|
7
|
+
module OpenHAB
|
|
8
|
+
module Core
|
|
9
|
+
module Items
|
|
10
|
+
java_import org.openhab.core.items.GroupItem
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# A group behaves like a regular item, but also has {#members} which are
|
|
14
|
+
# nested items that can be enumerated.
|
|
15
|
+
#
|
|
16
|
+
# If the group has a particular type, the methods from that type are
|
|
17
|
+
# directly available.
|
|
18
|
+
#
|
|
19
|
+
#
|
|
20
|
+
# The examples all assume the following items exist.
|
|
21
|
+
# ```xtend
|
|
22
|
+
# Group House
|
|
23
|
+
# // Location perspective
|
|
24
|
+
# Group GroundFloor (House)
|
|
25
|
+
# Group Livingroom (GroundFloor)
|
|
26
|
+
# // Functional perspective
|
|
27
|
+
# Group Sensors (House)
|
|
28
|
+
# Group Temperatures (Sensors)
|
|
29
|
+
#
|
|
30
|
+
# Number Livingroom_Temperature "Living Room temperature" (Livingroom, Temperatures)
|
|
31
|
+
# Number Bedroom_Temp "Bedroom temperature" (GroundFloor, Temperatures)
|
|
32
|
+
# Number Den_Temp "Den temperature" (GroundFloor, Temperatures)
|
|
33
|
+
# ```
|
|
34
|
+
#
|
|
35
|
+
# @!attribute [r] base_item
|
|
36
|
+
# @return [GenericItem, nil] A typed item if the group has a particular type.
|
|
37
|
+
#
|
|
38
|
+
# @example Operate on items in a group using enumerable methods
|
|
39
|
+
# logger.info("Total Temperatures: #{Temperatures.members.count}")
|
|
40
|
+
# # Total Temperatures: 3
|
|
41
|
+
# logger.info("Temperatures: #{House.members.map(&:name).sort.join(', ')}")
|
|
42
|
+
# # Temperatures: GroundFloor, Sensors
|
|
43
|
+
#
|
|
44
|
+
# @example Access to the methods and attributes like any item
|
|
45
|
+
# logger.info("Group: #{Temperatures.name}" # Group: Temperatures'
|
|
46
|
+
#
|
|
47
|
+
# @example Operates on items in nested groups using enumerable methods
|
|
48
|
+
# logger.info("House Count: #{House.all_members.count}")
|
|
49
|
+
# # House Count: 7
|
|
50
|
+
# logger.info("Items: #{House.all_members.grep_v(GroupItem).map(&:label).sort.join(', ')}")
|
|
51
|
+
# # Items: Bedroom temperature, Den temperature, Living Room temperature
|
|
52
|
+
#
|
|
53
|
+
# @example Iterate through the direct members of the group
|
|
54
|
+
# Temperatures.members.each do |item|
|
|
55
|
+
# logger.info("#{item.label} is: #{item.state}")
|
|
56
|
+
# end
|
|
57
|
+
# # Living Room temperature is 22
|
|
58
|
+
# # Bedroom temperature is 21
|
|
59
|
+
# # Den temperature is 19
|
|
60
|
+
#
|
|
61
|
+
# @example
|
|
62
|
+
# rule 'Turn off any switch that changes' do
|
|
63
|
+
# changed Switches.members
|
|
64
|
+
# triggered(&:off)
|
|
65
|
+
# end
|
|
66
|
+
#
|
|
67
|
+
# @example Built in {Enumerable} functions can be applied to groups.
|
|
68
|
+
# logger.info("Max is #{Temperatures.members.map(&:state).max}")
|
|
69
|
+
# logger.info("Min is #{Temperatures.members.map(&:state).min}")
|
|
70
|
+
#
|
|
71
|
+
class GroupItem < GenericItem
|
|
72
|
+
#
|
|
73
|
+
# Class for indicating to triggers that a group trigger should be used
|
|
74
|
+
#
|
|
75
|
+
class Members
|
|
76
|
+
include LazyArray
|
|
77
|
+
|
|
78
|
+
# @return [GroupItem]
|
|
79
|
+
attr_reader :group
|
|
80
|
+
|
|
81
|
+
# @!visibility private
|
|
82
|
+
def initialize(group_item)
|
|
83
|
+
@group = group_item
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Explicit conversion to Array
|
|
87
|
+
#
|
|
88
|
+
# @return [Array]
|
|
89
|
+
def to_a
|
|
90
|
+
group.get_members.map { |i| Proxy.new(i) }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Name of the group
|
|
94
|
+
#
|
|
95
|
+
# @return [String]
|
|
96
|
+
def name
|
|
97
|
+
group.name
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# @return [String]
|
|
101
|
+
def inspect
|
|
102
|
+
"#<OpenHAB::Core::Items::GroupItems::Members #{name} #{map(&:name).inspect}>"
|
|
103
|
+
end
|
|
104
|
+
alias_method :to_s, :inspect
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Override because we want to send them to the base item if possible
|
|
108
|
+
%i[command update].each do |method|
|
|
109
|
+
define_method(method) do |command|
|
|
110
|
+
return base_item.__send__(method, command) if base_item
|
|
111
|
+
|
|
112
|
+
super(command)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
#
|
|
117
|
+
# @!attribute [r] members
|
|
118
|
+
# @return [Members] Get an Array-like object representing the members of the group
|
|
119
|
+
#
|
|
120
|
+
# @see Enumerable
|
|
121
|
+
#
|
|
122
|
+
def members
|
|
123
|
+
Members.new(self)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
#
|
|
127
|
+
# @!attribute [r] all_members
|
|
128
|
+
# @return [Array] Get all non-group members of the group recursively.
|
|
129
|
+
#
|
|
130
|
+
# @see Enumerable
|
|
131
|
+
#
|
|
132
|
+
def all_members
|
|
133
|
+
getAllMembers.map { |m| Proxy.new(m) }
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# give the base item type a chance to format commands
|
|
137
|
+
# @!visibility private
|
|
138
|
+
def format_type(command)
|
|
139
|
+
return super unless base_item
|
|
140
|
+
|
|
141
|
+
base_item.format_type(command)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
private
|
|
145
|
+
|
|
146
|
+
# Add base type and function details
|
|
147
|
+
def type_details
|
|
148
|
+
r = ""
|
|
149
|
+
r += ":#{base_item.type}#{base_item.__send__(:type_details)}" if base_item
|
|
150
|
+
if function && (fn = function.class.java_class.simple_name.upcase) != "EQUALITY"
|
|
151
|
+
r += ":#{fn}"
|
|
152
|
+
r += "(#{function.parameters.map(&:inspect).join(",")})" unless function.parameters.empty?
|
|
153
|
+
end
|
|
154
|
+
r
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Delegate missing methods to {base_item} if possible
|
|
158
|
+
def method_missing(method, *args, &block)
|
|
159
|
+
return base_item.__send__(method, *args, &block) if base_item&.respond_to?(method) # rubocop:disable Lint/RedundantSafeNavigation nil responds to :to_a
|
|
160
|
+
|
|
161
|
+
super
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def respond_to_missing?(method, include_private = false)
|
|
165
|
+
return true if base_item&.respond_to?(method) # rubocop:disable Lint/RedundantSafeNavigation
|
|
166
|
+
|
|
167
|
+
super
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# @!parse GroupItem = OpenHAB::Core::Items::GroupItem
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "base64"
|
|
4
|
+
require "pathname"
|
|
5
|
+
require "net/http"
|
|
6
|
+
require "marcel"
|
|
7
|
+
|
|
8
|
+
require_relative "generic_item"
|
|
9
|
+
|
|
10
|
+
module OpenHAB
|
|
11
|
+
module Core
|
|
12
|
+
module Items
|
|
13
|
+
java_import org.openhab.core.library.items.ImageItem
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# An {ImageItem} holds the binary image data as its state.
|
|
17
|
+
#
|
|
18
|
+
# @!attribute [r] state
|
|
19
|
+
# @return [RawType, nil]
|
|
20
|
+
#
|
|
21
|
+
# @example Update from a base 64 encode image string
|
|
22
|
+
# Image.update("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=")
|
|
23
|
+
#
|
|
24
|
+
# @example Update from image bytes and mime type
|
|
25
|
+
# Image.update_from_bytes(File.binread(File.join(Dir.tmpdir,'1x1.png')), mime_type: 'image/png')
|
|
26
|
+
#
|
|
27
|
+
# @example Update from URL
|
|
28
|
+
# Image.update_from_url('https://raw.githubusercontent.com/boc-tothefuture/openhab-jruby/main/features/assets/1x1.png')
|
|
29
|
+
#
|
|
30
|
+
# @example Update from File
|
|
31
|
+
# Image.update_from_file('/tmp/1x1.png')
|
|
32
|
+
#
|
|
33
|
+
# @example Log image data
|
|
34
|
+
# logger.info("Mime type: #{Image.state.mime_type}")
|
|
35
|
+
# logger.info("Number of bytes: #{Image.state.bytes.length}")
|
|
36
|
+
#
|
|
37
|
+
class ImageItem < GenericItem
|
|
38
|
+
#
|
|
39
|
+
# Update image from file
|
|
40
|
+
#
|
|
41
|
+
# @param [String] file location
|
|
42
|
+
# @param [String] mime_type of image
|
|
43
|
+
#
|
|
44
|
+
#
|
|
45
|
+
def update_from_file(file, mime_type: nil)
|
|
46
|
+
file_data = File.binread(file)
|
|
47
|
+
mime_type ||= Marcel::MimeType.for(Pathname.new(file)) || Marcel::MimeType.for(file_data)
|
|
48
|
+
update_from_bytes(file_data, mime_type: mime_type)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
# Update image from image at URL
|
|
53
|
+
#
|
|
54
|
+
# @param [String] uri location of image
|
|
55
|
+
#
|
|
56
|
+
#
|
|
57
|
+
def update_from_url(uri)
|
|
58
|
+
logger.trace("Downloading image from #{uri}")
|
|
59
|
+
response = Net::HTTP.get_response(URI(uri))
|
|
60
|
+
mime_type = response["content-type"]
|
|
61
|
+
bytes = response.body
|
|
62
|
+
mime_type ||= detect_mime_from_bytes(bytes: bytes)
|
|
63
|
+
update_from_bytes(bytes, mime_type: mime_type)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#
|
|
67
|
+
# Update image from image bytes
|
|
68
|
+
#
|
|
69
|
+
# @param [String] mime_type of image
|
|
70
|
+
# @param [Object] bytes image data
|
|
71
|
+
#
|
|
72
|
+
#
|
|
73
|
+
def update_from_bytes(bytes, mime_type: nil)
|
|
74
|
+
mime_type ||= detect_mime_from_bytes(bytes: bytes)
|
|
75
|
+
base_64_image = encode_image(mime_type: mime_type, bytes: bytes)
|
|
76
|
+
update(base_64_image)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# Encode image information in the format required by OpenHAB
|
|
83
|
+
#
|
|
84
|
+
# @param [String] mime_type for image
|
|
85
|
+
# @param [Object] bytes image data
|
|
86
|
+
#
|
|
87
|
+
# @return [String] OpenHAB image format with image data Base64 encoded
|
|
88
|
+
#
|
|
89
|
+
def encode_image(mime_type:, bytes:)
|
|
90
|
+
"data:#{mime_type};base64,#{Base64.strict_encode64(bytes)}"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
#
|
|
94
|
+
# Detect the mime type based on bytes
|
|
95
|
+
#
|
|
96
|
+
# @param [Array] bytes representing image data
|
|
97
|
+
#
|
|
98
|
+
# @return [String] mime type if it can be detected, nil otherwise
|
|
99
|
+
#
|
|
100
|
+
def detect_mime_from_bytes(bytes:)
|
|
101
|
+
logger.trace("Detecting mime type from file image contents")
|
|
102
|
+
Marcel::MimeType.for(bytes)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# @!parse ImageItem = OpenHAB::Core::Items::ImageItem
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "generic_item"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Items
|
|
8
|
+
java_import org.openhab.core.library.items.LocationItem
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# A LocationItem can be used to store GPS related information, addresses
|
|
12
|
+
# etc.
|
|
13
|
+
#
|
|
14
|
+
# This is useful for location awareness related functions
|
|
15
|
+
#
|
|
16
|
+
# @!attribute [r] state
|
|
17
|
+
# @return [PointType, nil]
|
|
18
|
+
#
|
|
19
|
+
# @example Send point commands
|
|
20
|
+
# Location << '30,20' # latitude of 30, longitude of 20
|
|
21
|
+
# Location << '30,20,80' # latitude of 30, longitude of 20, altitude of 80
|
|
22
|
+
# Location << PointType.new('40,20')
|
|
23
|
+
#
|
|
24
|
+
# @example Determine the distance between two locations
|
|
25
|
+
# logger.info "Distance from Location 1 to Location 2: #{Location1.state - Location2.state}"
|
|
26
|
+
# logger.info "Distance from Location 1 to Location 2: #{Location1.state - PointType.new('40,20')}"
|
|
27
|
+
#
|
|
28
|
+
class LocationItem < GenericItem
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @!parse LocationItem = OpenHAB::Core::Items::LocationItem
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "forwardable"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Items
|
|
8
|
+
module Metadata
|
|
9
|
+
#
|
|
10
|
+
# {Hash} represents the configuration for a single metadata namespace.
|
|
11
|
+
#
|
|
12
|
+
# It implements the entire interface of {::Hash}.
|
|
13
|
+
#
|
|
14
|
+
# All keys are converted to strings.
|
|
15
|
+
#
|
|
16
|
+
# @!attribute [rw] value
|
|
17
|
+
# @return [String] The main value for the metadata namespace.
|
|
18
|
+
#
|
|
19
|
+
class Hash
|
|
20
|
+
java_import org.openhab.core.items.Metadata
|
|
21
|
+
private_constant :Metadata
|
|
22
|
+
|
|
23
|
+
include Enumerable
|
|
24
|
+
|
|
25
|
+
extend Forwardable
|
|
26
|
+
def_delegators :@metadata, :configuration, :hash, :to_s, :uid, :value
|
|
27
|
+
protected :configuration
|
|
28
|
+
|
|
29
|
+
# @!method to_hash
|
|
30
|
+
# Implicit conversion to {::Hash}.
|
|
31
|
+
# @return [::Hash]
|
|
32
|
+
|
|
33
|
+
# Make it act like a Hash; some methods can be handled by
|
|
34
|
+
# java.util.Map, others we have to convert to a Ruby Hash first, and
|
|
35
|
+
# still others (mutators) must be manually implemented below.
|
|
36
|
+
def_delegators :configuration,
|
|
37
|
+
:any?,
|
|
38
|
+
:default,
|
|
39
|
+
:default_proc,
|
|
40
|
+
:each,
|
|
41
|
+
:each_key,
|
|
42
|
+
:each_pair,
|
|
43
|
+
:each_value,
|
|
44
|
+
:empty?,
|
|
45
|
+
:filter,
|
|
46
|
+
:flatten,
|
|
47
|
+
:has_value?,
|
|
48
|
+
:keys,
|
|
49
|
+
:length,
|
|
50
|
+
:rassoc,
|
|
51
|
+
:reject,
|
|
52
|
+
:select,
|
|
53
|
+
:shift,
|
|
54
|
+
:size,
|
|
55
|
+
:to_a,
|
|
56
|
+
:to_h,
|
|
57
|
+
:to_hash,
|
|
58
|
+
:value?
|
|
59
|
+
def_delegators :to_h, :invert, :merge, :transform_keys, :transform_values
|
|
60
|
+
|
|
61
|
+
class << self
|
|
62
|
+
# @!visibility private
|
|
63
|
+
def from_item(item_name, namespace, value)
|
|
64
|
+
namespace = namespace.to_s
|
|
65
|
+
value = case value
|
|
66
|
+
when Hash
|
|
67
|
+
return value if value.uid.item_name == item_name && value.uid.namespace == namespace
|
|
68
|
+
|
|
69
|
+
[value.value, value.send(:configuration)]
|
|
70
|
+
when Array
|
|
71
|
+
raise ArgumentError, "Array must contain 2 elements: value, config" if value.length != 2
|
|
72
|
+
|
|
73
|
+
[value.first, (value.last || {}).transform_keys(&:to_s)]
|
|
74
|
+
when ::Hash then ["", value.transform_keys(&:to_s)]
|
|
75
|
+
else [value, {}]
|
|
76
|
+
end
|
|
77
|
+
new(Metadata.new(org.openhab.core.items.MetadataKey.new(namespace.to_s, item_name), *value))
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @!visibility private
|
|
81
|
+
def from_value(namespace, value)
|
|
82
|
+
from_item("-", namespace, value)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @!visibility private
|
|
87
|
+
def initialize(metadata)
|
|
88
|
+
@metadata = metadata
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @!visibility private
|
|
92
|
+
def dup
|
|
93
|
+
new(Metadata.new(org.openhab.core.items.MetadataKey.new(uid.namespace, "-"), value, configuration))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Is this object attached to an actual Item?
|
|
97
|
+
# @return [true,false]
|
|
98
|
+
def attached?
|
|
99
|
+
uid.item_name != "-"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# @!attribute [r] item
|
|
103
|
+
# @return [GenericItem, nil] The item this namespace is attached to.
|
|
104
|
+
def item
|
|
105
|
+
return nil unless attached?
|
|
106
|
+
|
|
107
|
+
DSL.items[uid.item_name]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# @!visibility private
|
|
111
|
+
def create
|
|
112
|
+
NamespaceHash.registry.add(@metadata) if attached?
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# @!visibility private
|
|
116
|
+
def commit
|
|
117
|
+
NamespaceHash.registry.update(@metadata) if attached?
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# @!visibility private
|
|
121
|
+
def eql?(other)
|
|
122
|
+
return true if equal?(other)
|
|
123
|
+
return false unless other.is_a?(Hash)
|
|
124
|
+
return false unless value == other.value
|
|
125
|
+
|
|
126
|
+
configuration == other.configuration
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
#
|
|
130
|
+
# Set the metadata value
|
|
131
|
+
#
|
|
132
|
+
def value=(value)
|
|
133
|
+
@metadata = org.openhab.core.items.Metadata.new(uid, value.to_s, configuration)
|
|
134
|
+
commit
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# @!visibility private
|
|
138
|
+
def <(other)
|
|
139
|
+
if other.is_a?(Hash)
|
|
140
|
+
return false if attached? && uid == other.uid
|
|
141
|
+
return false unless value == other.value
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
to_h < other
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# @!visibility private
|
|
148
|
+
def <=(other)
|
|
149
|
+
if other.is_a?(Hash)
|
|
150
|
+
return true if attached? && uid == other.uid
|
|
151
|
+
return false unless value == other.value
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
to_h <= other
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# @!visibility private
|
|
158
|
+
def ==(other)
|
|
159
|
+
if other.is_a?(Hash)
|
|
160
|
+
return false unless value == other.value
|
|
161
|
+
|
|
162
|
+
return configuration == other.configuration
|
|
163
|
+
elsif value.empty? && other.respond_to?(:to_hash)
|
|
164
|
+
return configuration.to_h == other.to_hash
|
|
165
|
+
end
|
|
166
|
+
false
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# @!visibility private
|
|
170
|
+
def >(other)
|
|
171
|
+
if other.is_a?(Hash)
|
|
172
|
+
return false if attached? && uid == other.uid
|
|
173
|
+
return false unless value == other.value
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
to_h > other
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# @!visibility private
|
|
180
|
+
def >=(other)
|
|
181
|
+
if other.is_a?(Hash)
|
|
182
|
+
return true if attached? && uid == other.uid
|
|
183
|
+
return false unless value == other.value
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
to_h >= other
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# @!visibility private
|
|
190
|
+
def [](key)
|
|
191
|
+
configuration[key.to_s]
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# @!visibility private
|
|
195
|
+
def []=(key, value)
|
|
196
|
+
key = key.to_s
|
|
197
|
+
new_config = to_h
|
|
198
|
+
new_config[key] = value
|
|
199
|
+
replace(new_config)
|
|
200
|
+
value # rubocop:disable Lint/Void
|
|
201
|
+
end
|
|
202
|
+
alias_method :store, :[]=
|
|
203
|
+
|
|
204
|
+
# @!visibility private
|
|
205
|
+
def assoc(key)
|
|
206
|
+
configuration.assoc(key.to_s)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# @!visibility private
|
|
210
|
+
def clear
|
|
211
|
+
replace({})
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# @!visibility private
|
|
215
|
+
alias_method :compact, :to_h
|
|
216
|
+
|
|
217
|
+
# @!visibility private
|
|
218
|
+
def compact!
|
|
219
|
+
# no action; impossible to have nil keys
|
|
220
|
+
self
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# @!visibility private
|
|
224
|
+
def compare_by_identity
|
|
225
|
+
raise NotImplementedError
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# @!visibility private
|
|
229
|
+
def compare_by_identity?
|
|
230
|
+
false
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# @!visibility private
|
|
234
|
+
def deconstruct_keys
|
|
235
|
+
self
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# @!visibility private
|
|
239
|
+
def default=(*)
|
|
240
|
+
raise NotImplementedError
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# @!visibility private
|
|
244
|
+
def default_proc=(*)
|
|
245
|
+
raise NotImplementedError
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# @!visibility private
|
|
249
|
+
def delete(key)
|
|
250
|
+
key = key.to_s
|
|
251
|
+
new_config = to_h
|
|
252
|
+
return yield(key) if block_given? && !new_config.key?(key)
|
|
253
|
+
|
|
254
|
+
old_value = new_config.delete(key)
|
|
255
|
+
replace(new_config)
|
|
256
|
+
old_value
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# @!visibility private
|
|
260
|
+
def delete_if(&block)
|
|
261
|
+
raise NotImplementedError unless block
|
|
262
|
+
|
|
263
|
+
replace(to_h.delete_if(block))
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# @!visibility private
|
|
267
|
+
def dig(key, *keys)
|
|
268
|
+
configuration.dig(key.to_s, *keys)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# @!visibility private
|
|
272
|
+
def except(*keys)
|
|
273
|
+
to_h.except(*keys.map(&:to_s))
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# @!visibility private
|
|
277
|
+
def fetch(key, &block)
|
|
278
|
+
configuration.fetch(key.to_s, &block)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# @!visibility private
|
|
282
|
+
def fetch_values(*keys, &block)
|
|
283
|
+
configuration.fetch_values(*keys.map(&:to_s), &block)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# @!visibility private
|
|
287
|
+
def keep_if(&block)
|
|
288
|
+
select!(&block)
|
|
289
|
+
self
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# @!visibility private
|
|
293
|
+
def key(value)
|
|
294
|
+
rassoc(value)&.first
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# @!visibility private
|
|
298
|
+
def key?(key)
|
|
299
|
+
configuration.key?(key.to_s)
|
|
300
|
+
end
|
|
301
|
+
alias_method :include?, :key?
|
|
302
|
+
alias_method :has_key?, :key?
|
|
303
|
+
alias_method :member?, :key?
|
|
304
|
+
|
|
305
|
+
# @!visibility private
|
|
306
|
+
def merge!(*others, &block)
|
|
307
|
+
return self if others.empty?
|
|
308
|
+
|
|
309
|
+
new_config = to_h
|
|
310
|
+
others.each do |h|
|
|
311
|
+
new_config.merge!(h.transform_keys(&:to_s), &block)
|
|
312
|
+
end
|
|
313
|
+
replace(new_config)
|
|
314
|
+
end
|
|
315
|
+
alias_method :update, :merge!
|
|
316
|
+
|
|
317
|
+
# @!visibility private
|
|
318
|
+
def reject!(&block)
|
|
319
|
+
raise NotImplementedError unless block
|
|
320
|
+
|
|
321
|
+
r = to_h.reject!(&block)
|
|
322
|
+
replace(r) if r
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
#
|
|
326
|
+
# Replace the configuration with a new {::Hash}.
|
|
327
|
+
#
|
|
328
|
+
# @param [::Hash] new_config
|
|
329
|
+
# @return [self]
|
|
330
|
+
#
|
|
331
|
+
def replace(new_config)
|
|
332
|
+
@metadata = org.openhab.core.items.Metadata.new(uid, value, new_config.transform_keys(&:to_s))
|
|
333
|
+
commit
|
|
334
|
+
self
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# @!visibility private
|
|
338
|
+
def select!(&block)
|
|
339
|
+
raise NotImplementedError unless block?
|
|
340
|
+
|
|
341
|
+
r = to_h.select!(&block)
|
|
342
|
+
replace(r) if r
|
|
343
|
+
end
|
|
344
|
+
alias_method :filter!, :select!
|
|
345
|
+
|
|
346
|
+
# @!visibility private
|
|
347
|
+
def slice(*keys)
|
|
348
|
+
to_h.slice(*keys.map(&:to_s))
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# @!visibility private
|
|
352
|
+
def to_proc
|
|
353
|
+
->(k) { self[k] }
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
# @!visibility private
|
|
357
|
+
def transform_keys!(*args, &block)
|
|
358
|
+
replace(transform_keys(*args, &block))
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
# @!visibility private
|
|
362
|
+
def transform_values!(&block)
|
|
363
|
+
raise NotImplementedError unless block
|
|
364
|
+
|
|
365
|
+
replace(transform_values(&block))
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# @!visibility private
|
|
369
|
+
def values
|
|
370
|
+
configuration.values.to_a
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
# @!visibility private
|
|
374
|
+
def values_at(*keys)
|
|
375
|
+
configuration.values_at(*keys.map(&:to_s))
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
# @!visibility private
|
|
379
|
+
def inspect
|
|
380
|
+
return to_h.inspect if value.empty?
|
|
381
|
+
return value.inspect if configuration.empty?
|
|
382
|
+
|
|
383
|
+
[value, to_h].inspect
|
|
384
|
+
end
|
|
385
|
+
alias_method :to_s, :inspect
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
end
|