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,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenHAB
|
|
4
|
+
module Core
|
|
5
|
+
module Types
|
|
6
|
+
# @interface
|
|
7
|
+
Type = org.openhab.core.types.Type
|
|
8
|
+
|
|
9
|
+
# @interface
|
|
10
|
+
Command = org.openhab.core.types.Command
|
|
11
|
+
|
|
12
|
+
# @interface
|
|
13
|
+
State = org.openhab.core.types.State
|
|
14
|
+
|
|
15
|
+
# This is a parent interface for all {State}s and {Command}s. It
|
|
16
|
+
# was introduced as many states can be commands at the same time and vice
|
|
17
|
+
# versa. E.g. a light can have the state {ON} or {OFF} and one can also
|
|
18
|
+
# send {ON} and {OFF} as commands to the device. This duality is captured
|
|
19
|
+
# by this marker interface and allows implementing classes to be both
|
|
20
|
+
# state and command at the same time.
|
|
21
|
+
module Type
|
|
22
|
+
# can't alias because to_s doesn't exist on Type
|
|
23
|
+
# @!visibility private
|
|
24
|
+
def inspect
|
|
25
|
+
to_s
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#
|
|
29
|
+
# Type Coercion
|
|
30
|
+
#
|
|
31
|
+
# Coerce object to the same Type
|
|
32
|
+
#
|
|
33
|
+
# @param [Type] other object to coerce to the same
|
|
34
|
+
# Type as this one
|
|
35
|
+
#
|
|
36
|
+
# @return [[Type, Type], nil]
|
|
37
|
+
#
|
|
38
|
+
def coerce(other)
|
|
39
|
+
logger.trace("Coercing #{self} (#{self.class}) as a request from #{other.class}")
|
|
40
|
+
return [other.as(self.class), self] if other.is_a?(Type) && other.respond_to?(:as)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
#
|
|
44
|
+
# Check equality without type conversion
|
|
45
|
+
#
|
|
46
|
+
# @return [true,false] if the same value is represented, without type
|
|
47
|
+
# conversion
|
|
48
|
+
def eql?(other)
|
|
49
|
+
return false unless other.instance_of?(self.class)
|
|
50
|
+
|
|
51
|
+
equals(other)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# Case equality
|
|
56
|
+
#
|
|
57
|
+
# @return [true,false] if the values are of the same Type
|
|
58
|
+
# or item state of the same type
|
|
59
|
+
#
|
|
60
|
+
def ===(other)
|
|
61
|
+
logger.trace { "Type (#{self.class}) #{self} === #{other} (#{other.class})" }
|
|
62
|
+
return false unless instance_of?(other.class)
|
|
63
|
+
|
|
64
|
+
eql?(other)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# Check equality, including type conversion
|
|
69
|
+
#
|
|
70
|
+
# @return [true,false] if the same value is represented, including
|
|
71
|
+
# type conversions
|
|
72
|
+
#
|
|
73
|
+
def ==(other)
|
|
74
|
+
logger.trace { "(#{self.class}) #{self} == #{other} (#{other.class})" }
|
|
75
|
+
return true if equal?(other)
|
|
76
|
+
|
|
77
|
+
# i.e. ON == OFF, REFRESH == ON, ON == REFRESH
|
|
78
|
+
# (RefreshType isn't really coercible)
|
|
79
|
+
return equals(other) if other.instance_of?(self.class) || is_a?(RefreshType) || other.is_a?(RefreshType)
|
|
80
|
+
|
|
81
|
+
if other.respond_to?(:coerce)
|
|
82
|
+
begin
|
|
83
|
+
return false unless (lhs, rhs = other.coerce(self))
|
|
84
|
+
rescue TypeError
|
|
85
|
+
# this one is a bit odd. 50 (Integer) == ON is internally
|
|
86
|
+
# flipping the argument and calling this method. but it responds
|
|
87
|
+
# to coerce, and then raises a TypeError (from Float???) that
|
|
88
|
+
# it couldn't convert to OnOffType. it probably should have
|
|
89
|
+
# returned nil. catch it and return false instead
|
|
90
|
+
return false
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
return lhs == rhs
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
super
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
#
|
|
101
|
+
# @!parse
|
|
102
|
+
# # This is a marker interface for all command types.
|
|
103
|
+
# module Command
|
|
104
|
+
# include Type
|
|
105
|
+
# end
|
|
106
|
+
#
|
|
107
|
+
# # This is a marker interface for all state types.
|
|
108
|
+
# module State
|
|
109
|
+
# include Type
|
|
110
|
+
# end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# @!parse
|
|
116
|
+
# Command = OpenHAB::Core::Types::Command
|
|
117
|
+
# State = OpenHAB::Core::Types::State
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "type"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Types
|
|
8
|
+
UnDefType = org.openhab.core.types.UnDefType
|
|
9
|
+
|
|
10
|
+
# There are situations when item states do not have any defined value.
|
|
11
|
+
# This might be because they have not been initialized yet (never
|
|
12
|
+
# received an state update so far) or because their state is ambiguous
|
|
13
|
+
# (e.g. a group item with members whose states do not match will be
|
|
14
|
+
# {NULL}).
|
|
15
|
+
class UnDefType # rubocop:disable Lint/EmptyClass
|
|
16
|
+
# @!parse include State
|
|
17
|
+
|
|
18
|
+
# @!constant NULL
|
|
19
|
+
# Null State
|
|
20
|
+
# @!constant UNDEF
|
|
21
|
+
# Undef State
|
|
22
|
+
|
|
23
|
+
# @!method null?
|
|
24
|
+
# Check if `self == NULL`
|
|
25
|
+
# @return [true,false]
|
|
26
|
+
|
|
27
|
+
# @!method undef?
|
|
28
|
+
# Check if `self == UNDEF`
|
|
29
|
+
# @return [true,false]
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @!parse
|
|
36
|
+
# UnDefType = OpenHAB::Core::Types::UnDefType
|
|
37
|
+
# NULL = OpenHAB::Core::Types::UnDefType::NULL
|
|
38
|
+
# UNDEF = OpenHAB::Core::Types::UnDefType::UNDEF
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "type"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Types
|
|
8
|
+
UpDownType = org.openhab.core.library.types.UpDownType
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Implements the {UP} and {DOWN} commands.
|
|
12
|
+
#
|
|
13
|
+
# Also, {PercentType} can be converted to {UpDownType}
|
|
14
|
+
# for more semantic comparisons. `0` is {UP}, `100` is
|
|
15
|
+
# {DOWN}, and anything in-between is neither.
|
|
16
|
+
#
|
|
17
|
+
class UpDownType
|
|
18
|
+
# @!parse include Command, State
|
|
19
|
+
|
|
20
|
+
# @!constant UP
|
|
21
|
+
# Up Command/State
|
|
22
|
+
# @!constant DOWN
|
|
23
|
+
# Down Command/State
|
|
24
|
+
|
|
25
|
+
# @!method up?
|
|
26
|
+
# Check if `self == UP`
|
|
27
|
+
# @return [true,false]
|
|
28
|
+
|
|
29
|
+
# @!method down?
|
|
30
|
+
# Check if `self == DOWN`
|
|
31
|
+
# @return [true,false]
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# Invert the type
|
|
35
|
+
#
|
|
36
|
+
# @return [UpDownType] {UP} if {down?}, {DOWN} if {up?}
|
|
37
|
+
#
|
|
38
|
+
def !
|
|
39
|
+
return UP if down?
|
|
40
|
+
return DOWN if up?
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @!parse
|
|
48
|
+
# UpDownType = OpenHAB::Core::Types::UpDownType
|
|
49
|
+
# UP = OpenHAB::Core::Types::UpDownType::UP
|
|
50
|
+
# DOWN = OpenHAB::Core::Types::UpDownType::DOWN
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Dir[File.expand_path("types/*.rb", __dir__)].sort.each do |f|
|
|
4
|
+
require f
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
module OpenHAB
|
|
8
|
+
module Core
|
|
9
|
+
#
|
|
10
|
+
# Contains the core types that OpenHAB uses as {State}s for items, and
|
|
11
|
+
# {Command}s to be sent to control them.
|
|
12
|
+
#
|
|
13
|
+
# Types are the specific data types that commands and states are. They can be
|
|
14
|
+
# sent to items, be the current state of an item, or be the `command`, `state`,
|
|
15
|
+
# and `was` field of various
|
|
16
|
+
# {group::OpenHAB::DSL::Rules::Builder::Triggers triggers}.
|
|
17
|
+
# Some types have additional useful methods.
|
|
18
|
+
#
|
|
19
|
+
module Types
|
|
20
|
+
# Hash taking a Enum value, and returning two symbols of
|
|
21
|
+
# predicates to be defined for it. the first is the "command" form,
|
|
22
|
+
# which should be defined on ItemCommandEvent, and on the Type itself.
|
|
23
|
+
# the second is "state" form, which should be defined on the applicable
|
|
24
|
+
# Item, and on the Type itself.
|
|
25
|
+
# @!visibility private
|
|
26
|
+
PREDICATE_ALIASES = Hash.new { |_h, k| [:"#{k.downcase}?"] * 2 }
|
|
27
|
+
.merge({
|
|
28
|
+
"PLAY" => %i[play? playing?],
|
|
29
|
+
"PAUSE" => %i[pause? paused?],
|
|
30
|
+
"REWIND" => %i[rewind? rewinding?],
|
|
31
|
+
"FASTFORWARD" => %i[fast_forward? fast_forwarding?]
|
|
32
|
+
}).freeze
|
|
33
|
+
|
|
34
|
+
# Hash taking a Enum value, and returning an array of symbols
|
|
35
|
+
# of the command to define for it
|
|
36
|
+
# @!visibility private
|
|
37
|
+
COMMAND_ALIASES = Hash.new { |_h, k| k.downcase.to_sym }
|
|
38
|
+
.merge({
|
|
39
|
+
"FASTFORWARD" => :fast_forward
|
|
40
|
+
}).freeze
|
|
41
|
+
|
|
42
|
+
constants.map { |c| const_get(c) }
|
|
43
|
+
.grep(Module)
|
|
44
|
+
.select { |k| k < java.lang.Enum }
|
|
45
|
+
.each do |klass|
|
|
46
|
+
# make sure == from Type is inherited
|
|
47
|
+
klass.remove_method(:==)
|
|
48
|
+
|
|
49
|
+
# dynamically define predicate methods
|
|
50
|
+
klass.values.each do |value| # rubocop:disable Style/HashEachMethods this isn't a Ruby hash
|
|
51
|
+
# include all the aliases that we define for items both command and
|
|
52
|
+
# state aliases (since types can be interrogated as an incoming
|
|
53
|
+
# command, or as the state of an item)
|
|
54
|
+
command = :"#{Types::COMMAND_ALIASES[value.to_s]}?"
|
|
55
|
+
states = Types::PREDICATE_ALIASES[value.to_s]
|
|
56
|
+
|
|
57
|
+
([command] | states).each do |method|
|
|
58
|
+
logger.trace("Defining #{klass}##{method} for #{value}")
|
|
59
|
+
klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
60
|
+
def #{method} # def on?
|
|
61
|
+
self == #{value} # self == ON
|
|
62
|
+
end # end
|
|
63
|
+
RUBY
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenHAB
|
|
4
|
+
module Core
|
|
5
|
+
java_import org.openhab.core.common.AbstractUID
|
|
6
|
+
|
|
7
|
+
# Adds methods to core OpenHAB AbstractUID to make it more natural in Ruby
|
|
8
|
+
class AbstractUID
|
|
9
|
+
# implicit conversion to string
|
|
10
|
+
alias_method :to_str, :to_s
|
|
11
|
+
# inspect result is just the string representation
|
|
12
|
+
alias_method :inspect, :to_s
|
|
13
|
+
|
|
14
|
+
# compares if equal to `other`, including string conversion
|
|
15
|
+
# @return [true, false]
|
|
16
|
+
def ==(other)
|
|
17
|
+
return true if equals(other)
|
|
18
|
+
|
|
19
|
+
to_s == other
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# have to remove == from all descendant classes so that they'll inherit
|
|
24
|
+
# the new implementation
|
|
25
|
+
[org.openhab.core.items.MetadataKey,
|
|
26
|
+
org.openhab.core.thing.UID,
|
|
27
|
+
org.openhab.core.thing.ChannelUID,
|
|
28
|
+
org.openhab.core.thing.ChannelGroupUID,
|
|
29
|
+
org.openhab.core.thing.ThingUID,
|
|
30
|
+
org.openhab.core.thing.ThingTypeUID,
|
|
31
|
+
org.openhab.core.thing.type.ChannelTypeUID,
|
|
32
|
+
org.openhab.core.thing.type.ChannelGroupTypeUID].each do |klass|
|
|
33
|
+
klass.remove_method(:==)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/openhab/core.rb
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Dir[File.expand_path("core/**/*.rb", __dir__)].sort.each do |f|
|
|
4
|
+
require f
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
module OpenHAB
|
|
8
|
+
# Contains classes and modules that wrap actual OpenHAB objects
|
|
9
|
+
module Core
|
|
10
|
+
# The OpenHAB Version. >= 3.3.0 is required.
|
|
11
|
+
# @return [String]
|
|
12
|
+
VERSION = org.openhab.core.OpenHAB.version.freeze
|
|
13
|
+
|
|
14
|
+
unless Gem::Version.new(VERSION) >= Gem::Version.new("3.3.0")
|
|
15
|
+
raise "`openhab-jrubyscripting` requires OpenHAB >= 3.3.0"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @return [Integer] Number of seconds to wait between checks for automation manager
|
|
19
|
+
CHECK_DELAY = 10
|
|
20
|
+
private_constant :CHECK_DELAY
|
|
21
|
+
class << self
|
|
22
|
+
#
|
|
23
|
+
# Wait until OpenHAB engine ready to process
|
|
24
|
+
#
|
|
25
|
+
# @return [void]
|
|
26
|
+
#
|
|
27
|
+
# @!visibility private
|
|
28
|
+
def wait_till_openhab_ready
|
|
29
|
+
logger.trace("Checking readiness of OpenHAB")
|
|
30
|
+
until automation_manager
|
|
31
|
+
logger.trace("Automation manager not loaded, checking again in #{CHECK_DELAY} seconds.")
|
|
32
|
+
sleep CHECK_DELAY
|
|
33
|
+
end
|
|
34
|
+
logger.trace "Automation manager instantiated, OpenHAB ready for rule processing."
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# @!attribute [r] config_folder
|
|
39
|
+
# @return [Pathname] The configuration folder path.
|
|
40
|
+
#
|
|
41
|
+
def config_folder
|
|
42
|
+
Pathname.new(org.openhab.core.OpenHAB.config_folder)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# JRuby isn't respecting $RUBYLIB when run embedded inside of OpenHAB, so do it manually
|
|
47
|
+
#
|
|
48
|
+
# @return [void]
|
|
49
|
+
#
|
|
50
|
+
# @!visibility private
|
|
51
|
+
def add_rubylib_to_load_path
|
|
52
|
+
ENV["RUBYLIB"]&.split(File::PATH_SEPARATOR)&.each do |path|
|
|
53
|
+
next if path.empty?
|
|
54
|
+
|
|
55
|
+
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
#
|
|
60
|
+
# @!attribute [r] automation_manager
|
|
61
|
+
# @return [org.openhab.core.automation.module.script.rulesupport.shared.ScriptedAutomationManager]
|
|
62
|
+
# The OpenHAB Automation manager.
|
|
63
|
+
#
|
|
64
|
+
def automation_manager
|
|
65
|
+
$scriptExtension.get("automationManager")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#
|
|
69
|
+
# @!attribute [r] rule_registry
|
|
70
|
+
# @return [org.openhab.core.automation.RuleRegistry] The OpenHAB rule registry
|
|
71
|
+
#
|
|
72
|
+
def rule_registry
|
|
73
|
+
$scriptExtension.get("ruleRegistry")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
#
|
|
77
|
+
# @!attribute [r] rule_manager
|
|
78
|
+
# @return [org.openhab.core.automation.RuleManager] The OpenHAB rule manager/engine
|
|
79
|
+
#
|
|
80
|
+
def rule_manager
|
|
81
|
+
@rule_manager ||= OSGi.service("org.openhab.core.automation.RuleManager")
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenHAB
|
|
4
|
+
module CoreExt
|
|
5
|
+
module Java
|
|
6
|
+
Duration = java.time.Duration
|
|
7
|
+
|
|
8
|
+
# Extensions to Duration
|
|
9
|
+
class Duration
|
|
10
|
+
# @!parse include TemporalAmount
|
|
11
|
+
|
|
12
|
+
alias_method :to_i, :seconds
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# Convert to number of seconds
|
|
16
|
+
#
|
|
17
|
+
# @return [Float]
|
|
18
|
+
#
|
|
19
|
+
def to_f
|
|
20
|
+
to_i + (nano / 1_000_000_000.0)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
remove_method :==
|
|
24
|
+
|
|
25
|
+
# @return [Integer, nil]
|
|
26
|
+
def <=>(other)
|
|
27
|
+
return to_f <=> other if other.is_a?(Numeric)
|
|
28
|
+
|
|
29
|
+
super
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Converts `other` to {Duration}, if possible.
|
|
34
|
+
#
|
|
35
|
+
# @param [Numeric, Period] other
|
|
36
|
+
# @return [Array, nil]
|
|
37
|
+
#
|
|
38
|
+
def coerce(other)
|
|
39
|
+
return [other.seconds, self] if other.is_a?(Numeric)
|
|
40
|
+
return [other.to_i.seconds, self] if other.is_a?(Period)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
{
|
|
44
|
+
plus: :+,
|
|
45
|
+
minus: :-
|
|
46
|
+
}.each do |java_op, ruby_op|
|
|
47
|
+
# def +(other)
|
|
48
|
+
# if other.is_a?(Duration)
|
|
49
|
+
# plus(other)
|
|
50
|
+
# elsif other.is_a?(Integer)
|
|
51
|
+
# plus_seconds(other)
|
|
52
|
+
# elsif other.is_a?(Numeric)
|
|
53
|
+
# plus(other.seconds)
|
|
54
|
+
# elsif other.respond_to?(:coerce) && (rhs, lhs = other.coerce(self))
|
|
55
|
+
# lhs + rhs
|
|
56
|
+
# else
|
|
57
|
+
# raise TypeError, "#{other.class} can't be coerced into Duration"
|
|
58
|
+
# end
|
|
59
|
+
# end
|
|
60
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1 # rubocop:disable Style/DocumentDynamicEvalDefinition
|
|
61
|
+
def #{ruby_op}(other)
|
|
62
|
+
if other.is_a?(Duration)
|
|
63
|
+
#{java_op}(other)
|
|
64
|
+
elsif other.is_a?(Integer)
|
|
65
|
+
#{java_op}_seconds(other)
|
|
66
|
+
elsif other.is_a?(Numeric)
|
|
67
|
+
#{java_op}(other.seconds)
|
|
68
|
+
elsif other.respond_to?(:coerce) && (rhs, lhs = other.coerce(self))
|
|
69
|
+
lhs #{ruby_op} rhs
|
|
70
|
+
else
|
|
71
|
+
raise TypeError, "\#{other.class} can't be coerced into Duration"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
RUBY
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
{
|
|
78
|
+
multipliedBy: :*,
|
|
79
|
+
dividedBy: :/
|
|
80
|
+
}.each do |java_op, ruby_op|
|
|
81
|
+
# def *(other)
|
|
82
|
+
# if other.is_a?(Integer)
|
|
83
|
+
# multipliedBy(other)
|
|
84
|
+
# elsif other.is_a?(Numeric)
|
|
85
|
+
# Duration.of_seconds(to_f * other)
|
|
86
|
+
# elsif other.is_a?(Duration)
|
|
87
|
+
# Duration.of_seconds(to_f * other.to_f)
|
|
88
|
+
# elsif other.respond_to?(:coerce) && (rhs, lhs = other.coerce(self))
|
|
89
|
+
# lhs * rhs
|
|
90
|
+
# else
|
|
91
|
+
# raise TypeError, "#{other.class} can't be coerced into Duration"
|
|
92
|
+
# end
|
|
93
|
+
# end
|
|
94
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1 # rubocop:disable Style/DocumentDynamicEvalDefinition
|
|
95
|
+
def #{ruby_op}(other)
|
|
96
|
+
if other.is_a?(Integer)
|
|
97
|
+
#{java_op}(other)
|
|
98
|
+
elsif other.is_a?(Numeric)
|
|
99
|
+
Duration.of_seconds(to_f #{ruby_op} other)
|
|
100
|
+
elsif other.is_a?(Duration)
|
|
101
|
+
Duration.of_seconds(to_f #{ruby_op} other.to_f)
|
|
102
|
+
elsif other.respond_to?(:coerce) && (rhs, lhs = other.coerce(self))
|
|
103
|
+
lhs #{ruby_op} rhs
|
|
104
|
+
else
|
|
105
|
+
raise TypeError, "\#{other.class} can't be coerced into Duration"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
RUBY
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# @!parse Duration = OpenHAB::CoreExt::Java::Duration
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "time"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module CoreExt
|
|
7
|
+
module Java
|
|
8
|
+
java_import java.time.LocalDate
|
|
9
|
+
|
|
10
|
+
# Extensions to LocalDate
|
|
11
|
+
class LocalDate
|
|
12
|
+
include Time
|
|
13
|
+
|
|
14
|
+
class << self # rubocop:disable Lint/EmptyClass
|
|
15
|
+
# @!attribute [r] now
|
|
16
|
+
# @return [ZonedDateTime]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @param [TemporalAmount, LocalDate, Numeric] other
|
|
20
|
+
# If other is a Numeric, it's interpreted as days.
|
|
21
|
+
# @return [LocalDate] If other is a TemporalAmount or Numeric
|
|
22
|
+
# @return [Period] If other is a LocalDate
|
|
23
|
+
def -(other)
|
|
24
|
+
case other
|
|
25
|
+
when Date
|
|
26
|
+
Period.of_days(day_of_year - other.yday)
|
|
27
|
+
when MonthDay
|
|
28
|
+
self - other.at_year(year)
|
|
29
|
+
when LocalDate
|
|
30
|
+
Period.of_days(day_of_year - other.day_of_year)
|
|
31
|
+
when Duration
|
|
32
|
+
minus_days(other.to_days)
|
|
33
|
+
when Numeric
|
|
34
|
+
minus_days(other.ceil)
|
|
35
|
+
else
|
|
36
|
+
minus(other)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @param [TemporalAmount, Numeric] other
|
|
41
|
+
# If other is a Numeric, it's interpreted as days.
|
|
42
|
+
# @return [LocalDate]
|
|
43
|
+
def +(other)
|
|
44
|
+
case other
|
|
45
|
+
when Duration
|
|
46
|
+
plus_days(other.to_days)
|
|
47
|
+
when Numeric
|
|
48
|
+
plus_days(other.to_i)
|
|
49
|
+
else
|
|
50
|
+
plus(other)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# Returns the next day
|
|
56
|
+
#
|
|
57
|
+
# @return [LocalDate]
|
|
58
|
+
#
|
|
59
|
+
def succ
|
|
60
|
+
plus_days(1)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @return [Date]
|
|
64
|
+
def to_date
|
|
65
|
+
Date.new(year, month_value, day_of_month)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
alias_method :to_month, :month
|
|
69
|
+
|
|
70
|
+
# @return [MonthDay]
|
|
71
|
+
def to_month_day
|
|
72
|
+
MonthDay.of(month, day_of_month)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @return [self]
|
|
76
|
+
def to_local_date(_context = nil)
|
|
77
|
+
self
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @param [ZonedDateTime, nil] context
|
|
81
|
+
# A {ZonedDateTime} used to fill in missing fields
|
|
82
|
+
# during conversion. {ZonedDateTime.now} is assumed if not given.
|
|
83
|
+
# @return [ZonedDateTime]
|
|
84
|
+
def to_zoned_date_time(context = nil)
|
|
85
|
+
zone = context&.zone || java.time.ZoneId.system_default
|
|
86
|
+
at_start_of_day(zone)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
LocalDate = OpenHAB::CoreExt::Java::LocalDate unless Object.const_defined?(:LocalDate)
|