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,28 @@
|
|
|
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.StringItem
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# A {StringItem} can be used for any kind of string to either send or
|
|
12
|
+
# receive from a device.
|
|
13
|
+
#
|
|
14
|
+
# @!attribute [r] state
|
|
15
|
+
# @return [StringType, nil]
|
|
16
|
+
#
|
|
17
|
+
# @example
|
|
18
|
+
# # StringOne has a current state of "Hello"
|
|
19
|
+
# StringOne << StringOne + " World!"
|
|
20
|
+
# # StringOne will eventually have a state of 'Hello World!'
|
|
21
|
+
#
|
|
22
|
+
class StringItem < GenericItem
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @!parse StringItem = OpenHAB::Core::Items::StringItem
|
|
@@ -0,0 +1,78 @@
|
|
|
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.SwitchItem
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# A SwitchItem represents a normal switch that can be ON or OFF.
|
|
12
|
+
# Useful for normal lights, presence detection etc.
|
|
13
|
+
#
|
|
14
|
+
# @!attribute [r] state
|
|
15
|
+
# @return [OnOffType, nil]
|
|
16
|
+
#
|
|
17
|
+
#
|
|
18
|
+
# @example Turn on all switches in a `Group:Switch` called Switches
|
|
19
|
+
# Switches.on
|
|
20
|
+
#
|
|
21
|
+
# @example Turn on all switches in a group called Switches that are off
|
|
22
|
+
# Switches.select(&:off?).each(&:on)
|
|
23
|
+
#
|
|
24
|
+
# @example Switches accept booelan commands (true/false)
|
|
25
|
+
# # Turn on switch
|
|
26
|
+
# SwitchItem << true
|
|
27
|
+
#
|
|
28
|
+
# # Turn off switch
|
|
29
|
+
# SwitchItem << false
|
|
30
|
+
#
|
|
31
|
+
# # Turn off switch if any in another group is on
|
|
32
|
+
# SwitchItem << Switches.any?(&:on?)
|
|
33
|
+
#
|
|
34
|
+
# @example Invert all Switches
|
|
35
|
+
# items.grep(SwitchItem)
|
|
36
|
+
# .each(&:toggle)
|
|
37
|
+
#
|
|
38
|
+
class SwitchItem < GenericItem
|
|
39
|
+
# Convert boolean commands to ON/OFF
|
|
40
|
+
# @!visibility private
|
|
41
|
+
def format_type(command)
|
|
42
|
+
return Types::OnOffType.from(command) if [true, false].include?(command)
|
|
43
|
+
|
|
44
|
+
super
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
#
|
|
48
|
+
# Send a command to invert the state of the switch
|
|
49
|
+
#
|
|
50
|
+
# @return [self]
|
|
51
|
+
#
|
|
52
|
+
def toggle
|
|
53
|
+
return on unless state?
|
|
54
|
+
|
|
55
|
+
command(!state)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @!method on?
|
|
59
|
+
# Check if the item state == {ON}
|
|
60
|
+
# @return [true,false]
|
|
61
|
+
|
|
62
|
+
# @!method off?
|
|
63
|
+
# Check if the item state == {OFF}
|
|
64
|
+
# @return [true,false]
|
|
65
|
+
|
|
66
|
+
# @!method on
|
|
67
|
+
# Send the {ON} command to the item
|
|
68
|
+
# @return [SwitchItem] `self`
|
|
69
|
+
|
|
70
|
+
# @!method off
|
|
71
|
+
# Send the {OFF} command to the item
|
|
72
|
+
# @return [SwitchItem] `self`
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @!parse SwitchItem = OpenHAB::Core::Items::SwitchItem
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "types"
|
|
4
|
+
|
|
5
|
+
Dir[File.expand_path("items/*.rb", __dir__)].sort.each do |f|
|
|
6
|
+
require f
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module OpenHAB
|
|
10
|
+
module Core
|
|
11
|
+
#
|
|
12
|
+
# Contains the core types that OpenHAB uses to represent items.
|
|
13
|
+
# Items have states from the {Types} module.
|
|
14
|
+
#
|
|
15
|
+
# You may use an item or group name anywhere {DSL} (or just {Core::EntityLookup})
|
|
16
|
+
# is available, and it will automatically be loaded.
|
|
17
|
+
#
|
|
18
|
+
module Items
|
|
19
|
+
class << self
|
|
20
|
+
# Imports all of the item classes into the global namespace
|
|
21
|
+
# for convenient access.
|
|
22
|
+
def import_into_global_namespace
|
|
23
|
+
concrete_item_classes.each do |k|
|
|
24
|
+
const_name = k.java_class.simple_name
|
|
25
|
+
Object.const_set(const_name, k) unless Object.const_defined?(const_name)
|
|
26
|
+
end
|
|
27
|
+
Object.const_set(:GenericItem, GenericItem) unless Object.const_defined?(:GenericItem)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# takes an array of Type java classes and returns
|
|
33
|
+
# all the Enum values, in a flat array
|
|
34
|
+
def values_for_enums(enums)
|
|
35
|
+
enums.map(&:ruby_class)
|
|
36
|
+
.select { |k| k < java.lang.Enum }
|
|
37
|
+
.flat_map(&:values)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# define predicates for checking if an item is in one of the Enum states
|
|
41
|
+
def def_predicate_methods(klass)
|
|
42
|
+
values_for_enums(klass.ACCEPTED_DATA_TYPES).each do |state|
|
|
43
|
+
_command_predicate, state_predicate = Types::PREDICATE_ALIASES[state.to_s]
|
|
44
|
+
next if klass.instance_methods.include?(state_predicate)
|
|
45
|
+
|
|
46
|
+
logger.trace("Defining #{klass}##{state_predicate} for #{state}")
|
|
47
|
+
klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
48
|
+
def #{state_predicate} # def on?
|
|
49
|
+
raw_state == #{state} # raw_state == ON
|
|
50
|
+
end # end
|
|
51
|
+
RUBY
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# define methods for commanding an item to one of the Enum states
|
|
56
|
+
# as well as predicates for if an ItemCommandEvent is one of those commands
|
|
57
|
+
def def_command_methods(klass)
|
|
58
|
+
values_for_enums(klass.ACCEPTED_COMMAND_TYPES).each do |value|
|
|
59
|
+
command = Types::COMMAND_ALIASES[value.to_s]
|
|
60
|
+
next if klass.instance_methods.include?(command)
|
|
61
|
+
|
|
62
|
+
logger.trace("Defining #{klass}##{command} for #{value}")
|
|
63
|
+
klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
64
|
+
def #{command}(for: nil, on_expire: nil, &block) # def on(for: nil, on_expire: nil, &block )
|
|
65
|
+
command(#{value}, for: binding.local_variable_get(:for), on_expire: on_expire, &block) # command(ON, for: nil, expire: nil, &block)
|
|
66
|
+
end # end
|
|
67
|
+
RUBY
|
|
68
|
+
|
|
69
|
+
logger.trace("Defining Enumerable##{command} for #{value}")
|
|
70
|
+
Enumerable.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
71
|
+
def #{command} # def on
|
|
72
|
+
each(&:#{command}) # each(&:on)
|
|
73
|
+
end # end
|
|
74
|
+
RUBY
|
|
75
|
+
|
|
76
|
+
# Override the inherited methods from Enumerable and send it to the base_item
|
|
77
|
+
GroupItem.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
78
|
+
def #{command} # def on
|
|
79
|
+
method_missing(:#{command}) # method_missing(:on)
|
|
80
|
+
end # end
|
|
81
|
+
RUBY
|
|
82
|
+
|
|
83
|
+
logger.trace("Defining ItemCommandEvent##{command}? for #{value}")
|
|
84
|
+
Events::ItemCommandEvent.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
85
|
+
def #{command}? # def refresh?
|
|
86
|
+
command == #{value} # command == REFRESH
|
|
87
|
+
end # end
|
|
88
|
+
RUBY
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def concrete_item_classes
|
|
93
|
+
constants.map { |c| const_get(c) }
|
|
94
|
+
.grep(Module)
|
|
95
|
+
.select { |k| k < GenericItem }
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# sort classes by hierarchy so we define methods on parent classes first
|
|
100
|
+
constants.map { |c| const_get(c) }
|
|
101
|
+
.grep(Module)
|
|
102
|
+
.select { |k| k <= GenericItem && k != GroupItem && k != StringItem }
|
|
103
|
+
.sort { |a, b| a < b ? 1 : -1 }
|
|
104
|
+
.each do |klass|
|
|
105
|
+
klass.field_reader :ACCEPTED_COMMAND_TYPES, :ACCEPTED_DATA_TYPES unless klass == GenericItem
|
|
106
|
+
|
|
107
|
+
def_predicate_methods(klass)
|
|
108
|
+
def_command_methods(klass)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
prepend_accepted_data_types
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenHAB
|
|
4
|
+
module Core
|
|
5
|
+
# Common base class for array-like collections that have lookup
|
|
6
|
+
# methods to avoid instantiating the elements if you only use
|
|
7
|
+
# the lookup method
|
|
8
|
+
#
|
|
9
|
+
# your class should implement to_a
|
|
10
|
+
#
|
|
11
|
+
module LazyArray
|
|
12
|
+
include Enumerable
|
|
13
|
+
|
|
14
|
+
# @!visibility private
|
|
15
|
+
def self.included(klass)
|
|
16
|
+
klass.undef_method :inspect
|
|
17
|
+
klass.undef_method :to_s
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Calls the given block once for each object, passing that object as a
|
|
21
|
+
# parameter. Returns self.
|
|
22
|
+
#
|
|
23
|
+
# If no block is given, an Enumerator is returned.
|
|
24
|
+
def each(&block)
|
|
25
|
+
to_a.each(&block)
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Implicitly convertible to array
|
|
30
|
+
#
|
|
31
|
+
# @return [Array]
|
|
32
|
+
#
|
|
33
|
+
def to_ary
|
|
34
|
+
to_a
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Delegate any other methods to the actual array, exclude mutating methods
|
|
38
|
+
def method_missing(method, *args, &block)
|
|
39
|
+
return to_a.send(method, *args, &block) if method[-1] != "!" && Array.instance_methods.include?(method)
|
|
40
|
+
|
|
41
|
+
super
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @!visibility private
|
|
45
|
+
def respond_to_missing?(method, include_private = false)
|
|
46
|
+
return true if method[-1] != "!" && Array.instance_methods.include?(method.to_sym)
|
|
47
|
+
|
|
48
|
+
super
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "singleton"
|
|
4
|
+
|
|
5
|
+
require_relative "script_handling"
|
|
6
|
+
|
|
7
|
+
module OpenHAB
|
|
8
|
+
module Core
|
|
9
|
+
# @!visibility private
|
|
10
|
+
class ProfileFactory
|
|
11
|
+
include org.openhab.core.thing.profiles.ProfileFactory
|
|
12
|
+
include Singleton
|
|
13
|
+
|
|
14
|
+
# rubocop:disable Naming/MethodName
|
|
15
|
+
class Profile
|
|
16
|
+
include org.openhab.core.thing.profiles.StateProfile
|
|
17
|
+
|
|
18
|
+
def initialize(callback, context, uid, thread_locals, block)
|
|
19
|
+
unless callback.class.ancestors.include?(Things::ProfileCallback)
|
|
20
|
+
callback.class.prepend(Things::ProfileCallback)
|
|
21
|
+
callback.class.field_reader :link
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
@callback = callback
|
|
25
|
+
@context = context
|
|
26
|
+
@uid = uid
|
|
27
|
+
@thread_locals = thread_locals
|
|
28
|
+
@block = block
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @!visibility private
|
|
32
|
+
def getProfileTypeUID
|
|
33
|
+
@uid
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @!visibility private
|
|
37
|
+
def onCommandFromItem(command)
|
|
38
|
+
return unless process_event(:command_from_item, command: command) == true
|
|
39
|
+
|
|
40
|
+
logger.trace("Forwarding original command")
|
|
41
|
+
@callback.handle_command(command)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @!visibility private
|
|
45
|
+
def onStateUpdateFromHandler(state)
|
|
46
|
+
return unless process_event(:state_from_handler, state: state) == true
|
|
47
|
+
|
|
48
|
+
logger.trace("Forwarding original update")
|
|
49
|
+
@callback.send_update(state)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @!visibility private
|
|
53
|
+
def onCommandFromHandler(command)
|
|
54
|
+
return unless process_event(:command_from_handler, command: command) == true
|
|
55
|
+
|
|
56
|
+
logger.trace("Forwarding original command")
|
|
57
|
+
callback.send_command(command)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# @!visibility private
|
|
61
|
+
def onStateUpdateFromItem(state)
|
|
62
|
+
process_event(:state_from_item, state: state)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def process_event(event, **params)
|
|
68
|
+
logger.trace("Handling event #{event.inspect} in profile #{@uid} with param #{params.values.first.inspect}.")
|
|
69
|
+
|
|
70
|
+
params[:callback] = @callback
|
|
71
|
+
params[:context] = @context
|
|
72
|
+
params[:config] = @context.configuration
|
|
73
|
+
params[:link] = @callback.link
|
|
74
|
+
params[:item] = @callback.link.item
|
|
75
|
+
params[:channel_uid] = @callback.link.linked_uid
|
|
76
|
+
|
|
77
|
+
kwargs = {}
|
|
78
|
+
@block.parameters.each do |(param_type, name)|
|
|
79
|
+
case param_type
|
|
80
|
+
when :keyreq, :key
|
|
81
|
+
kwargs[name] = params[name] if params.key?(name)
|
|
82
|
+
when :keyrest
|
|
83
|
+
kwargs = params
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
DSL::ThreadLocal.thread_local(**@thread_locals) do
|
|
88
|
+
@block.call(event, **kwargs)
|
|
89
|
+
rescue Exception => e
|
|
90
|
+
@block.binding.eval("self").logger.log_exception(e)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
private_constant :Profile
|
|
95
|
+
# rubocop:enable Naming/MethodName
|
|
96
|
+
|
|
97
|
+
def initialize
|
|
98
|
+
@profiles = {}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# @!visibility private
|
|
102
|
+
def register(uid, block)
|
|
103
|
+
@profiles[uid] = [DSL::ThreadLocal.persist, block]
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def createProfile(type, callback, context) # rubocop:disable Naming/MethodName
|
|
107
|
+
@profiles[type].then { |(thread_locals, block)| Profile.new(callback, context, type, thread_locals, block) }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def getSupportedProfileTypeUIDs # rubocop:disable Naming/MethodName
|
|
111
|
+
@profiles.keys
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
registration = OSGi.register_service(ProfileFactory.instance)
|
|
116
|
+
ScriptHandlingCallbacks.script_unloaded_hooks << -> { registration.unregister }
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenHAB
|
|
4
|
+
module Core
|
|
5
|
+
#
|
|
6
|
+
# Manages script loading and unloading
|
|
7
|
+
#
|
|
8
|
+
# @!visibility private
|
|
9
|
+
module ScriptHandlingCallbacks
|
|
10
|
+
class << self
|
|
11
|
+
#
|
|
12
|
+
# Return script_loaded_hooks
|
|
13
|
+
#
|
|
14
|
+
# @!visibility private
|
|
15
|
+
def script_loaded_hooks
|
|
16
|
+
@script_loaded_hooks ||= []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# Return script_unloaded_hooks
|
|
21
|
+
#
|
|
22
|
+
# @!visibility private
|
|
23
|
+
def script_unloaded_hooks
|
|
24
|
+
@script_unloaded_hooks ||= []
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#
|
|
29
|
+
# Executed when OpenHAB unloads a script file
|
|
30
|
+
#
|
|
31
|
+
def scriptUnloaded # rubocop:disable Naming/MethodName method name dictated by OpenHAB
|
|
32
|
+
logger.trace("Script unloaded")
|
|
33
|
+
ScriptHandlingCallbacks.script_unloaded_hooks.each do |hook|
|
|
34
|
+
hook.call
|
|
35
|
+
rescue => e
|
|
36
|
+
logger.error("Failed to call script_unloaded hook #{hook}: #{e}")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
#
|
|
41
|
+
# Executed when OpenHAB loads a script file
|
|
42
|
+
#
|
|
43
|
+
def scriptLoaded(filename) # rubocop:disable Naming/MethodName method name dictated by OpenHAB
|
|
44
|
+
logger.trace("Script loaded: #{filename}")
|
|
45
|
+
ScriptHandlingCallbacks.script_loaded_hooks.each do |hook|
|
|
46
|
+
hook.call
|
|
47
|
+
rescue => e
|
|
48
|
+
logger.error("Failed to call script_loaded hook #{hook}: #{e}")
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
singleton_class.include(OpenHAB::Core::ScriptHandlingCallbacks)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "forwardable"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Things
|
|
8
|
+
java_import org.openhab.core.thing.Channel
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# {Channel} is a part of a {Thing} that represents a functionality of it.
|
|
12
|
+
# Therefore {GenericItem Items} can be linked a to a channel.
|
|
13
|
+
#
|
|
14
|
+
# @!attribute [r] item
|
|
15
|
+
# (see ChannelUID#item)
|
|
16
|
+
#
|
|
17
|
+
# @!attribute [r] items
|
|
18
|
+
# (see ChannelUID#items)
|
|
19
|
+
#
|
|
20
|
+
# @!attribute [r] thing
|
|
21
|
+
# (see ChannelUID#thing)
|
|
22
|
+
#
|
|
23
|
+
# @!attribute [r] uid
|
|
24
|
+
# @return [ChannelUID]
|
|
25
|
+
#
|
|
26
|
+
class Channel
|
|
27
|
+
extend Forwardable
|
|
28
|
+
|
|
29
|
+
delegate %i[item items thing] => :uid
|
|
30
|
+
|
|
31
|
+
# @return [String]
|
|
32
|
+
def inspect
|
|
33
|
+
r = "#<OpenHAB::Core::Things::Channel #{uid}"
|
|
34
|
+
r += " #{label.inspect}" if label
|
|
35
|
+
r += " auto_update_policy=#{auto_update_policy}" if auto_update_policy
|
|
36
|
+
r += " configuration=#{configuration.properties.to_h}" unless configuration.properties.empty?
|
|
37
|
+
r += " properties=#{properties.to_h}" unless properties.empty?
|
|
38
|
+
"#{r}>"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [String]
|
|
42
|
+
def to_s
|
|
43
|
+
uid.to_s
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "forwardable"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Things
|
|
8
|
+
java_import org.openhab.core.thing.ChannelUID
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# {ChannelUID} represents a unique identifier for {Channel channels}.
|
|
12
|
+
#
|
|
13
|
+
class ChannelUID
|
|
14
|
+
#
|
|
15
|
+
# @attribute [r] thing
|
|
16
|
+
#
|
|
17
|
+
# Return the thing this channel is associated with.
|
|
18
|
+
#
|
|
19
|
+
# @return [Thing, nil]
|
|
20
|
+
#
|
|
21
|
+
def thing
|
|
22
|
+
EntityLookup.lookup_thing(thing_uid)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# @attribute [r] item
|
|
27
|
+
#
|
|
28
|
+
# Return the item if this channel is linked with an item. If a channel is linked to more than one item,
|
|
29
|
+
# this method only returns the first item.
|
|
30
|
+
#
|
|
31
|
+
# @return [GenericItem, nil]
|
|
32
|
+
#
|
|
33
|
+
def item
|
|
34
|
+
items.first
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# @attribute [r] items
|
|
39
|
+
#
|
|
40
|
+
# Returns all of the channel's linked items.
|
|
41
|
+
#
|
|
42
|
+
# @return [Array<GenericItem>] An array of things or an empty array
|
|
43
|
+
#
|
|
44
|
+
def items
|
|
45
|
+
registry = OSGi.service("org.openhab.core.thing.link.ItemChannelLinkRegistry")
|
|
46
|
+
registry.get_linked_items(self).map { |i| Items::Proxy.new(i) }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenHAB
|
|
4
|
+
module Core
|
|
5
|
+
module Things
|
|
6
|
+
java_import org.openhab.core.thing.link.ItemChannelLink
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# Represents the link between a {GenericItem} and a {Thing Thing's}
|
|
10
|
+
# {Channel}.
|
|
11
|
+
#
|
|
12
|
+
# @!attribute [r] thing
|
|
13
|
+
# @return [Thing]
|
|
14
|
+
#
|
|
15
|
+
# @!attribute [r] channel_uid
|
|
16
|
+
# @return [ChannelUID]
|
|
17
|
+
#
|
|
18
|
+
class ItemChannelLink
|
|
19
|
+
extend Forwardable
|
|
20
|
+
|
|
21
|
+
def_delegator :linked_uid, :thing
|
|
22
|
+
|
|
23
|
+
# @!attribute [r] item
|
|
24
|
+
# @return [GenericItem]
|
|
25
|
+
def item
|
|
26
|
+
DSL.items[item_name]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
alias_method :channel_uid, :linked_uid
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenHAB
|
|
4
|
+
module Core
|
|
5
|
+
module Things
|
|
6
|
+
#
|
|
7
|
+
# Contains methods for {OpenHAB::DSL.profile profile}'s callback to forward commands between items
|
|
8
|
+
# and channels.
|
|
9
|
+
#
|
|
10
|
+
module ProfileCallback
|
|
11
|
+
class << self
|
|
12
|
+
#
|
|
13
|
+
# Wraps the parent class's method to format non-Types.
|
|
14
|
+
#
|
|
15
|
+
# @!macro def_state_parsing_method
|
|
16
|
+
# @!method $1($2)
|
|
17
|
+
# @return [void]
|
|
18
|
+
# @!visibility private
|
|
19
|
+
def def_state_parsing_method(method, param_name)
|
|
20
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
21
|
+
def #{method}(type) # def handle_command(type)
|
|
22
|
+
type = link.item.format_#{param_name == :state ? :update : param_name}(type) # type = link.item.format_command(type)
|
|
23
|
+
super(type) # super(type)
|
|
24
|
+
end # end
|
|
25
|
+
RUBY
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
# Forward the given command to the respective thing handler.
|
|
31
|
+
#
|
|
32
|
+
# @param [Command] command
|
|
33
|
+
#
|
|
34
|
+
def_state_parsing_method(:handle_command, :command)
|
|
35
|
+
|
|
36
|
+
#
|
|
37
|
+
# Send a command to the framework.
|
|
38
|
+
#
|
|
39
|
+
# @param [Command] command
|
|
40
|
+
#
|
|
41
|
+
def_state_parsing_method(:send_command, :command)
|
|
42
|
+
|
|
43
|
+
#
|
|
44
|
+
# Send a state update to the framework.
|
|
45
|
+
#
|
|
46
|
+
# @param [State] state
|
|
47
|
+
#
|
|
48
|
+
def_state_parsing_method(:send_update, :state)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "delegate"
|
|
4
|
+
require "forwardable"
|
|
5
|
+
|
|
6
|
+
module OpenHAB
|
|
7
|
+
module Core
|
|
8
|
+
module Things
|
|
9
|
+
# Class is a proxy to underlying thing
|
|
10
|
+
# @!visibility private
|
|
11
|
+
class Proxy < Delegator
|
|
12
|
+
extend Forwardable
|
|
13
|
+
def_delegators :__getobj__, :class, :is_a?, :kind_of?
|
|
14
|
+
|
|
15
|
+
# Returns the list of channels associated with this Thing
|
|
16
|
+
#
|
|
17
|
+
# @note This is defined on this class, and not on {Thing}, because
|
|
18
|
+
# that's the interface and if you define it there, it will be hidden
|
|
19
|
+
# by the method on ThingImpl.
|
|
20
|
+
#
|
|
21
|
+
# @return [Array] channels
|
|
22
|
+
def channels
|
|
23
|
+
Thing::ChannelsArray.new(super.to_a)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Set the proxy item (called by super)
|
|
28
|
+
#
|
|
29
|
+
def __setobj__(thing)
|
|
30
|
+
@uid = thing.uid
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# Lookup thing from thing registry
|
|
35
|
+
#
|
|
36
|
+
def __getobj__
|
|
37
|
+
$things.get(@uid)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
#
|
|
41
|
+
# Need to check if `self` _or_ the delegate is an instance of the
|
|
42
|
+
# given class
|
|
43
|
+
#
|
|
44
|
+
# So that {#==} can work
|
|
45
|
+
#
|
|
46
|
+
# @return [true, false]
|
|
47
|
+
#
|
|
48
|
+
# @!visibility private
|
|
49
|
+
def instance_of?(klass)
|
|
50
|
+
__getobj__.instance_of?(klass) || super
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# Check if delegates are equal for comparison
|
|
55
|
+
#
|
|
56
|
+
# Otherwise items can't be used in Java maps
|
|
57
|
+
#
|
|
58
|
+
# @return [true, false]
|
|
59
|
+
#
|
|
60
|
+
# @!visibility private
|
|
61
|
+
def ==(other)
|
|
62
|
+
return __getobj__ == other.__getobj__ if other.instance_of?(Proxy)
|
|
63
|
+
|
|
64
|
+
super
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|