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,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "type"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Types
|
|
8
|
+
PlayPauseType = org.openhab.core.library.types.PlayPauseType
|
|
9
|
+
|
|
10
|
+
# Implements {PLAY} and {PAUSE} commands and states.
|
|
11
|
+
class PlayPauseType # rubocop:disable Lint/EmptyClass
|
|
12
|
+
# @!parse include Command, State
|
|
13
|
+
|
|
14
|
+
# @!constant PLAY
|
|
15
|
+
# Play Command/Playing State
|
|
16
|
+
# @!constant PAUSE
|
|
17
|
+
# Pause Command/Paused State
|
|
18
|
+
|
|
19
|
+
# @!method playing?
|
|
20
|
+
# Check if `self == PLAY`
|
|
21
|
+
# @return [true,false]
|
|
22
|
+
|
|
23
|
+
# @!parse alias play? playing?
|
|
24
|
+
|
|
25
|
+
# @!method paused?
|
|
26
|
+
# Check if `self == PAUSE`
|
|
27
|
+
# @return [true,false]
|
|
28
|
+
|
|
29
|
+
# @!parse alias pause? paused?
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @!parse
|
|
36
|
+
# PlayPauseType = OpenHAB::Core::Types::PlayPauseType
|
|
37
|
+
# PLAY = OpenHAB::Core::Types::PlayPauseType::PLAY
|
|
38
|
+
# PAUSE = OpenHAB::Core::Types::PlayPauseType::PAUSE
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "type"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Types
|
|
8
|
+
PointType = org.openhab.core.library.types.PointType
|
|
9
|
+
|
|
10
|
+
# {PointType} can be used for items that are dealing with GPS or location awareness functionality.
|
|
11
|
+
class PointType
|
|
12
|
+
# @!parse include Command, State
|
|
13
|
+
|
|
14
|
+
# @overload initialize(latitude, longitude, altitude)
|
|
15
|
+
# @param [DecimalType, QuantityType, StringType, Numeric] latitude
|
|
16
|
+
# @param [DecimalType, QuantityType, StringType, Numeric] longitude
|
|
17
|
+
# @param [DecimalType, QuantityType, StringType, Numeric] altitude
|
|
18
|
+
def initialize(*args)
|
|
19
|
+
if (2..3).cover?(args.length)
|
|
20
|
+
args = args.each_with_index.map do |value, index|
|
|
21
|
+
if value.is_a?(DecimalType) || value.is_a?(StringType)
|
|
22
|
+
value
|
|
23
|
+
elsif value.is_a?(QuantityType)
|
|
24
|
+
unit = index == 2 ? DSL.unit(SIUnits::METRE.dimension) || SIUnits::METRE : Units::DEGREE_ANGLE
|
|
25
|
+
DecimalType.new(value.to_unit(unit).to_big_decimal)
|
|
26
|
+
elsif value.respond_to?(:to_str)
|
|
27
|
+
StringType.new(value.to_str)
|
|
28
|
+
elsif value.respond_to?(:to_d)
|
|
29
|
+
DecimalType.new(value)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
super(*args)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# Check equality without type conversion
|
|
39
|
+
#
|
|
40
|
+
# @return [true,false] if the same value is represented, without type
|
|
41
|
+
# conversion
|
|
42
|
+
def eql?(other)
|
|
43
|
+
return false unless other.instance_of?(self.class)
|
|
44
|
+
|
|
45
|
+
equals(other)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
#
|
|
49
|
+
# Check equality with type conversion
|
|
50
|
+
#
|
|
51
|
+
# @param [PointType, String]
|
|
52
|
+
# other object to compare to
|
|
53
|
+
#
|
|
54
|
+
# @return [true,false]
|
|
55
|
+
#
|
|
56
|
+
def ==(other)
|
|
57
|
+
logger.trace { "(#{self.class}) #{self} == #{other} (#{other.class})" }
|
|
58
|
+
if other.instance_of?(self.class)
|
|
59
|
+
equals(other)
|
|
60
|
+
elsif other.respond_to?(:coerce)
|
|
61
|
+
return false unless (lhs, rhs = other.coerce(self))
|
|
62
|
+
|
|
63
|
+
lhs == rhs
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# rename raw methods so we can overwrite them
|
|
68
|
+
# @!visibility private
|
|
69
|
+
alias_method :raw_latitude, :latitude
|
|
70
|
+
# .
|
|
71
|
+
# @!visibility private
|
|
72
|
+
alias_method :raw_longitude, :longitude
|
|
73
|
+
# .
|
|
74
|
+
# @!visibility private
|
|
75
|
+
alias_method :raw_altitude, :altitude
|
|
76
|
+
# .
|
|
77
|
+
# @!visibility private
|
|
78
|
+
alias_method :raw_distance_from, :distance_from
|
|
79
|
+
|
|
80
|
+
# @!attribute [r] latitude
|
|
81
|
+
# @return [QuantityType]
|
|
82
|
+
def latitude
|
|
83
|
+
QuantityType.new(raw_latitude.to_big_decimal, SIUnits::DEGREE_ANGLE)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @!attribute [r] longitude
|
|
87
|
+
# @return [QuantityType]
|
|
88
|
+
def longitude
|
|
89
|
+
QuantityType.new(raw_longitude.to_big_decimal, SIUnits::DEGREE_ANGLE)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @!attribute [r] altitude
|
|
93
|
+
# @return [QuantityType]
|
|
94
|
+
def altitude
|
|
95
|
+
QuantityType.new(raw_altitude.to_big_decimal, Units::METRE)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
# Calculate the distance in meters from other, ignoring altitude.
|
|
100
|
+
#
|
|
101
|
+
# This algorithm also ignores the oblate spheroid shape of Earth and
|
|
102
|
+
# assumes a perfect sphere, so results are inexact.
|
|
103
|
+
#
|
|
104
|
+
# @return [QuantityType]
|
|
105
|
+
def distance_from(other)
|
|
106
|
+
logger.trace("(#{self}).distance_from(#{other} (#{other.class})")
|
|
107
|
+
raise TypeError, "#{other.class} can't be coerced into #{self.class}" unless other.is_a?(PointType)
|
|
108
|
+
|
|
109
|
+
QuantityType.new(raw_distance_from(other), SIUnits::METRE)
|
|
110
|
+
end
|
|
111
|
+
alias_method :-, :distance_from
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# @!parse PointType = OpenHAB::Core::Types::PointType
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "numeric_type"
|
|
4
|
+
require_relative "type"
|
|
5
|
+
|
|
6
|
+
module OpenHAB
|
|
7
|
+
module Core
|
|
8
|
+
module Types
|
|
9
|
+
QuantityType = org.openhab.core.library.types.QuantityType
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# {QuantityType} extends {DecimalType} to handle physical unit measurement.
|
|
13
|
+
#
|
|
14
|
+
# {QuantityType} is part of the [Units of Measurement](https://www.openhab.org/docs/concepts/units-of-measurement.html)
|
|
15
|
+
# framework in OpenHAB. It is represented as a decimal number with a unit.
|
|
16
|
+
# You can construct a {QuantityType} object by using the pipe operator with any Numeric.
|
|
17
|
+
#
|
|
18
|
+
# @example QuantityTypes can perform math operations between them.
|
|
19
|
+
# (50 | "°F") + (-25 | "°F") # => 25.0 °F
|
|
20
|
+
# (100 | "°F") / (2 | "°F") # => 50
|
|
21
|
+
# (50 | "°F") - (25 | "°F") # => 25 °F
|
|
22
|
+
# (50 | "°F") + (50 | "°F") # => 100 °F
|
|
23
|
+
#
|
|
24
|
+
# @example If the operand is a number, it will be unit-less, but the result of the operation will have a unit. This only works for multiplication and division.
|
|
25
|
+
# (50 | "°F") * 2 # => 100 °F
|
|
26
|
+
# (100 | "°F") / 2 # => 50 °F
|
|
27
|
+
#
|
|
28
|
+
# @example If the operand is a dimensioned NumberItem it will automatically be converted to a quantity for the operation.
|
|
29
|
+
# # NumberF = "2 °F"
|
|
30
|
+
# # NumberC = "2 °C"
|
|
31
|
+
# (50 | "°F") + NumberF.state # => 52.0 °F
|
|
32
|
+
# (50 | "°F") + NumberC.state # => 85.60 °F
|
|
33
|
+
#
|
|
34
|
+
# @example If the operand is a non-dimensioned NumberItem it can be used only in multiplication and division operations.
|
|
35
|
+
# # Number Dimensionless = 2
|
|
36
|
+
# (50 | "°F") * Dimensionless.state # => 100 °F
|
|
37
|
+
# (50 | "°F") / Dimensionless.state # => 25 °F
|
|
38
|
+
#
|
|
39
|
+
# @example Quantities can be compared, if they have comparable units.
|
|
40
|
+
# (50 | "°F") > (25 | "°F")
|
|
41
|
+
# (50 | "°F") > (525 | "°F")
|
|
42
|
+
# (50 | "°F") >= (50 | "°F")
|
|
43
|
+
# (50 | "°F") == (50 | "°F")
|
|
44
|
+
# (50 | "°F") < (25 | "°C")
|
|
45
|
+
#
|
|
46
|
+
# @example A Range can be used with QuantityType:
|
|
47
|
+
# ((0 | "°C")..(100 | "°C")).cover?(NumberC)
|
|
48
|
+
#
|
|
49
|
+
# @example A Range can also be used in a case statement for a dimensioned item:
|
|
50
|
+
# description = case NumberC.state
|
|
51
|
+
# when (-20 | "°C")...(18 | "°C") then "too cold"
|
|
52
|
+
# when (18 | "°C")...(25 | "°C") then "comfortable"
|
|
53
|
+
# when (25 | "°C")...(40 | "°C") then "too warm"
|
|
54
|
+
# else "out of range"
|
|
55
|
+
# end
|
|
56
|
+
#
|
|
57
|
+
# @example Dimensioned Number Items can be converted to quantities with other units using the | operator
|
|
58
|
+
# # NumberC = "23 °C"
|
|
59
|
+
#
|
|
60
|
+
# # Using a unit
|
|
61
|
+
# logger.info("In Fahrenheit #{NumberC.state | ImperialUnits::FAHRENHEIT }")
|
|
62
|
+
#
|
|
63
|
+
# # Using a string
|
|
64
|
+
# logger.info("In Fahrenheit #{NumberC.state | "°F"}")
|
|
65
|
+
#
|
|
66
|
+
# @example Dimensionless Number Items can be converted to quantities with units using the | operator
|
|
67
|
+
# # Dimensionless = 70
|
|
68
|
+
#
|
|
69
|
+
# # Using a unit
|
|
70
|
+
# logger.info("In Fahrenheit #{Dimensionless.state | ImperialUnits::FAHRENHEIT }")
|
|
71
|
+
#
|
|
72
|
+
# # Using a string
|
|
73
|
+
# logger.info("In Fahrenheit #{Dimensionless.state | "°F"}")
|
|
74
|
+
#
|
|
75
|
+
# @example Dimensioned Number Items automatically use their units and convert automatically for math operations
|
|
76
|
+
# # Number:Temperature NumberC = 23 °C
|
|
77
|
+
# # Number:Temperature NumberF = 70 °F
|
|
78
|
+
# NumberC.state - NumberF.state # => 1.88 °C
|
|
79
|
+
# NumberF.state + NumberC.state # => 143.40 °F
|
|
80
|
+
#
|
|
81
|
+
# @example Dimensionless Number Items can be used for multiplication and division.
|
|
82
|
+
# # Number Dimensionless = 2
|
|
83
|
+
# # Number:Temperature NumberF = 70 °F
|
|
84
|
+
# NumberF.state * Dimensionless.state # => 140.0 °F
|
|
85
|
+
# NumberF.state / Dimensionless.state # => 35.0 °F
|
|
86
|
+
# Dimensionless.state * NumberF.state # => 140.0 °F
|
|
87
|
+
# 2 * NumberF.state # => 140.0 °F
|
|
88
|
+
#
|
|
89
|
+
# @example Comparisons work on dimensioned number items with different, but comparable units.
|
|
90
|
+
# # Number:Temperature NumberC = 23 °C
|
|
91
|
+
# # Number:Temperature NumberF = 70 °F
|
|
92
|
+
# NumberC.state > NumberF.state # => true
|
|
93
|
+
#
|
|
94
|
+
# @example For certain unit types, such as temperature, all unit needs to be normalized to the comparator for all operations when combining comparison operators with dimensioned numbers.
|
|
95
|
+
# (NumberC.state | "°F") - (NumberF.state | "°F") < 4 | "°F"
|
|
96
|
+
#
|
|
97
|
+
class QuantityType
|
|
98
|
+
# @!parse include Command, State
|
|
99
|
+
include NumericType
|
|
100
|
+
include ComparableType
|
|
101
|
+
|
|
102
|
+
# @!parse
|
|
103
|
+
# #
|
|
104
|
+
# # Convert this {QuantityType} into another unit.
|
|
105
|
+
# #
|
|
106
|
+
# # @param [String, javax.measure.units.Unit] unit
|
|
107
|
+
# # @return [QuantityType]
|
|
108
|
+
# #
|
|
109
|
+
# # @example
|
|
110
|
+
# # NumberC.state | ImperialUnits::FAHRENHEIT
|
|
111
|
+
# #
|
|
112
|
+
# def to_unit(unit); end
|
|
113
|
+
|
|
114
|
+
alias_method :|, :to_unit
|
|
115
|
+
|
|
116
|
+
#
|
|
117
|
+
# Comparison
|
|
118
|
+
#
|
|
119
|
+
# Comparisons against Numeric and DecimalType are allowed only within a
|
|
120
|
+
# {OpenHAB::DSL.unit unit} block to avoid unit ambiguities.
|
|
121
|
+
# Comparisons against other types may be done if supported by that type's coercion.
|
|
122
|
+
#
|
|
123
|
+
# @param [QuantityType, DecimalType, Numeric, Object]
|
|
124
|
+
# other object to compare to
|
|
125
|
+
#
|
|
126
|
+
# @return [Integer, nil] -1, 0, +1 depending on whether `other` is
|
|
127
|
+
# less than, equal to, or greater than self
|
|
128
|
+
#
|
|
129
|
+
# `nil` is returned if the two values are incomparable.
|
|
130
|
+
#
|
|
131
|
+
def <=>(other)
|
|
132
|
+
logger.trace("(#{self.class}) #{self} <=> #{other} (#{other.class})")
|
|
133
|
+
case other
|
|
134
|
+
when self.class
|
|
135
|
+
return unitize(other.unit).compare_to(other) if unit == Units::ONE
|
|
136
|
+
return compare_to(other.unitize(unit)) if other.unit == Units::ONE
|
|
137
|
+
|
|
138
|
+
return compare_to(other)
|
|
139
|
+
when Numeric, DecimalType
|
|
140
|
+
if (unit = OpenHAB::DSL.unit(dimension))
|
|
141
|
+
return compare_to(QuantityType.new(other, unit))
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
return nil # don"t allow comparison with numeric outside a unit block
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
return nil unless other.respond_to?(:coerce)
|
|
148
|
+
|
|
149
|
+
other.coerce(self)&.then { |lhs, rhs| lhs <=> rhs }
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
#
|
|
153
|
+
# Type Coercion
|
|
154
|
+
#
|
|
155
|
+
# Coerce object to a {QuantityType}
|
|
156
|
+
#
|
|
157
|
+
# @param [Numeric, Type] other object to coerce to a {QuantityType}
|
|
158
|
+
#
|
|
159
|
+
# if `other` is a {Type}, `self` will instead be coerced
|
|
160
|
+
# to that type to accomodate comparison with things such as {OnOffType}
|
|
161
|
+
#
|
|
162
|
+
# @return [Array<(QuantityType, QuantityType)>, nil]
|
|
163
|
+
def coerce(other)
|
|
164
|
+
logger.trace("Coercing #{self} as a request from #{other.class}")
|
|
165
|
+
if other.is_a?(Type)
|
|
166
|
+
[other, as(other.class)]
|
|
167
|
+
elsif other.respond_to?(:to_d)
|
|
168
|
+
[QuantityType.new(other.to_d.to_java, Units::ONE), self]
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# arithmetic operators
|
|
173
|
+
alias_method :-@, :negate
|
|
174
|
+
|
|
175
|
+
{
|
|
176
|
+
add: :+,
|
|
177
|
+
subtract: :-
|
|
178
|
+
}.each do |java_op, ruby_op|
|
|
179
|
+
convert = "self.class.new(other, DSL.unit(dimension) || unit)"
|
|
180
|
+
|
|
181
|
+
class_eval( # rubocop:disable Style/DocumentDynamicEvalDefinition https://github.com/rubocop/rubocop/issues/10179
|
|
182
|
+
# def +(other)
|
|
183
|
+
# logger.trace("#{self} + #{other} (#{other.class})")
|
|
184
|
+
# if other.is_a?(QuantityType)
|
|
185
|
+
# add_quantity(other)
|
|
186
|
+
# elsif other.is_a?(DecimalType)
|
|
187
|
+
# other = other.to_big_decimal
|
|
188
|
+
# add_quantity(self.class.new(other, DSL.unit(dimension) || unit))
|
|
189
|
+
# elsif other.is_a?(java.math.BigDecimal)
|
|
190
|
+
# add_quantity(self.class.new(other, DSL.unit(dimension) || unit))
|
|
191
|
+
# elsif other.respond_to?(:to_d)
|
|
192
|
+
# other = other.to_d.to_java
|
|
193
|
+
# add_quantity(self.class.new(other, DSL.unit(dimension) || unit))
|
|
194
|
+
# elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
|
195
|
+
# lhs + rhs
|
|
196
|
+
# else
|
|
197
|
+
# raise TypeError, "#{other.class} can't be coerced into #{self.class}"
|
|
198
|
+
# end
|
|
199
|
+
# end
|
|
200
|
+
<<~RUBY, __FILE__, __LINE__ + 1
|
|
201
|
+
def #{ruby_op}(other)
|
|
202
|
+
logger.trace("\#{self} #{ruby_op} \#{other} (\#{other.class})")
|
|
203
|
+
if other.is_a?(QuantityType)
|
|
204
|
+
#{java_op}_quantity(other)
|
|
205
|
+
elsif other.is_a?(DecimalType)
|
|
206
|
+
other = other.to_big_decimal
|
|
207
|
+
#{java_op}_quantity(#{convert})
|
|
208
|
+
elsif other.is_a?(java.math.BigDecimal)
|
|
209
|
+
#{java_op}_quantity(#{convert})
|
|
210
|
+
elsif other.respond_to?(:to_d)
|
|
211
|
+
other = other.to_d.to_java
|
|
212
|
+
#{java_op}_quantity(#{convert})
|
|
213
|
+
elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
|
214
|
+
lhs #{ruby_op} rhs
|
|
215
|
+
else
|
|
216
|
+
raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
RUBY
|
|
220
|
+
)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
{
|
|
224
|
+
multiply: :*,
|
|
225
|
+
divide: :/
|
|
226
|
+
}.each do |java_op, ruby_op|
|
|
227
|
+
class_eval( # rubocop:disable Style/DocumentDynamicEvalDefinition https://github.com/rubocop/rubocop/issues/10179
|
|
228
|
+
# def *(other)
|
|
229
|
+
# logger.trace("#{self} * #{other} (#{other.class})")
|
|
230
|
+
# if other.is_a?(QuantityType)
|
|
231
|
+
# multiply_quantity(other)
|
|
232
|
+
# elsif other.is_a?(DecimalType)
|
|
233
|
+
# multiply(other.to_big_decimal)
|
|
234
|
+
# elsif other.is_a?(java.math.BigDecimal)
|
|
235
|
+
# multiply(other)
|
|
236
|
+
# elsif other.respond_to?(:to_d)
|
|
237
|
+
# multiply(other.to_d.to_java)
|
|
238
|
+
# elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
|
239
|
+
# lhs * rhs
|
|
240
|
+
# else
|
|
241
|
+
# raise TypeError, "#{other.class} can't be coerced into #{self.class}"
|
|
242
|
+
# end
|
|
243
|
+
# end
|
|
244
|
+
<<~RUBY, __FILE__, __LINE__ + 1
|
|
245
|
+
def #{ruby_op}(other)
|
|
246
|
+
logger.trace("\#{self} #{ruby_op} \#{other} (\#{other.class})")
|
|
247
|
+
if other.is_a?(QuantityType)
|
|
248
|
+
#{java_op}_quantity(other)
|
|
249
|
+
elsif other.is_a?(DecimalType)
|
|
250
|
+
#{java_op}(other.to_big_decimal)
|
|
251
|
+
elsif other.is_a?(java.math.BigDecimal)
|
|
252
|
+
#{java_op}(other)
|
|
253
|
+
elsif other.respond_to?(:to_d)
|
|
254
|
+
#{java_op}(other.to_d.to_java)
|
|
255
|
+
elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(to_d))
|
|
256
|
+
lhs #{ruby_op} rhs
|
|
257
|
+
else
|
|
258
|
+
raise TypeError, "\#{other.class} can't be coerced into \#{self.class}"
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
RUBY
|
|
262
|
+
)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# if it's a dimensionless quantity, change the unit to match other_unit
|
|
266
|
+
# @!visibility private
|
|
267
|
+
def unitize(other_unit = unit)
|
|
268
|
+
# prefer converting to the thread-specified unit if there is one
|
|
269
|
+
other_unit = DSL.unit(dimension) || other_unit
|
|
270
|
+
logger.trace("Converting #{self} to #{other_unit}")
|
|
271
|
+
|
|
272
|
+
case unit
|
|
273
|
+
when Units::ONE
|
|
274
|
+
QuantityType.new(to_big_decimal, other_unit)
|
|
275
|
+
when other_unit
|
|
276
|
+
self
|
|
277
|
+
else
|
|
278
|
+
to_unit(other_unit)
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# if unit is {org.openhab.core.library.unit.Units.ONE}, return a plain
|
|
283
|
+
# Java BigDecimal
|
|
284
|
+
# @!visibility private
|
|
285
|
+
def deunitize
|
|
286
|
+
return to_big_decimal if unit == Units::ONE
|
|
287
|
+
|
|
288
|
+
self
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
private
|
|
292
|
+
|
|
293
|
+
# do addition directly against a QuantityType while ensuring we unitize
|
|
294
|
+
# both sides
|
|
295
|
+
def add_quantity(other)
|
|
296
|
+
unitize(other.unit).add(other.unitize(unit))
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# do subtraction directly against a QuantityType while ensuring we
|
|
300
|
+
# unitize both sides
|
|
301
|
+
def subtract_quantity(other)
|
|
302
|
+
unitize(other.unit).subtract(other.unitize(unit))
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# do multiplication directly against a QuantityType while ensuring
|
|
306
|
+
# we deunitize both sides, and also invert the operation if one side
|
|
307
|
+
# isn't actually a unit
|
|
308
|
+
def multiply_quantity(other)
|
|
309
|
+
lhs = deunitize
|
|
310
|
+
rhs = other.deunitize
|
|
311
|
+
# reverse the arguments if it's multiplication and the LHS isn"t a QuantityType
|
|
312
|
+
lhs, rhs = rhs, lhs if lhs.is_a?(java.math.BigDecimal)
|
|
313
|
+
# what a waste... using a QuantityType to multiply two dimensionless quantities
|
|
314
|
+
# have to make sure lhs is still a QuantityType in order to return a new
|
|
315
|
+
# QuantityType that's still dimensionless
|
|
316
|
+
lhs = other if lhs.is_a?(java.math.BigDecimal)
|
|
317
|
+
|
|
318
|
+
lhs.multiply(rhs)
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
alias_method :divide_quantity, :divide
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
# @!parse QuantityType = OpenHAB::Core::Types::QuantityType
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "type"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Types
|
|
8
|
+
RawType = org.openhab.core.library.types.RawType
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# This type can be used for all binary data such as images, documents, sounds etc.
|
|
12
|
+
#
|
|
13
|
+
class RawType # rubocop:disable Lint/EmptyClass
|
|
14
|
+
# @!parse include State
|
|
15
|
+
|
|
16
|
+
# @!method mime_type
|
|
17
|
+
# @return [String]
|
|
18
|
+
|
|
19
|
+
# @!method bytes
|
|
20
|
+
# @return [String]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @!parse RawType = OpenHAB::Core::Types::RawType
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "type"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Types
|
|
8
|
+
RefreshType = org.openhab.core.types.RefreshType
|
|
9
|
+
|
|
10
|
+
# Implements the {REFRESH} command.
|
|
11
|
+
class RefreshType # rubocop:disable Lint/EmptyClass
|
|
12
|
+
# @!parse include Command
|
|
13
|
+
|
|
14
|
+
# @!constant REFRESH
|
|
15
|
+
# Refresh Command
|
|
16
|
+
|
|
17
|
+
# @!method refresh?
|
|
18
|
+
# Check if `self == REFRESH`
|
|
19
|
+
# @return [true,false]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @!parse
|
|
26
|
+
# RefreshType = OpenHAB::Core::Types::RefreshType
|
|
27
|
+
# REFRESH = OpenHAB::Core::Types::RefreshType::REFRESH
|
|
@@ -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
|
+
RewindFastforwardType = org.openhab.core.library.types.RewindFastforwardType
|
|
9
|
+
|
|
10
|
+
# Implements the {REWIND} and {FASTFORWARD} commands and states.
|
|
11
|
+
class RewindFastforwardType # rubocop:disable Lint/EmptyClass
|
|
12
|
+
# @!parse include Command, State
|
|
13
|
+
|
|
14
|
+
# @!constant REWIND
|
|
15
|
+
# Rewind Command/Rewinding State
|
|
16
|
+
# @!constant FASTFORWARD
|
|
17
|
+
# Fast Forward Command/Fast Forwarding State
|
|
18
|
+
|
|
19
|
+
# @!method rewinding?
|
|
20
|
+
# Check if `self == REWIND`
|
|
21
|
+
# @return [true,false]
|
|
22
|
+
|
|
23
|
+
# @!parse alias rewind? rewinding?
|
|
24
|
+
|
|
25
|
+
# @!method fast_forwarding?
|
|
26
|
+
# Check if `self == FASTFORWARD`
|
|
27
|
+
# @return [true,false]
|
|
28
|
+
|
|
29
|
+
# @!parse alias fast_forward? fast_forwarding?
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @!parse
|
|
36
|
+
# RewindFastforwardType = OpenHAB::Core::Types::RewindFastforwardType
|
|
37
|
+
# REWIND = OpenHAB::Core::Types::RewindFastforwardType::REWIND
|
|
38
|
+
# FASTFORWARD = OpenHAB::Core::Types::RewindFastforwardType::FASTFORWARD
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "type"
|
|
4
|
+
|
|
5
|
+
module OpenHAB
|
|
6
|
+
module Core
|
|
7
|
+
module Types
|
|
8
|
+
StopMoveType = org.openhab.core.library.types.StopMoveType
|
|
9
|
+
|
|
10
|
+
# Implements the {STOP} and {MOVE} commands.
|
|
11
|
+
class StopMoveType # rubocop:disable Lint/EmptyClass
|
|
12
|
+
# @!parse include Command
|
|
13
|
+
|
|
14
|
+
# @!constant STOP
|
|
15
|
+
# Stop Command
|
|
16
|
+
# @!constant MOVE
|
|
17
|
+
# Move Command
|
|
18
|
+
|
|
19
|
+
# @!method stop?
|
|
20
|
+
# Check if `self == STOP`
|
|
21
|
+
# @return [true,false]
|
|
22
|
+
|
|
23
|
+
# @!method move?
|
|
24
|
+
# Check if `self == MOVE`
|
|
25
|
+
# @return [true,false]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @!parse
|
|
32
|
+
# StopMoveType = OpenHAB::Core::Types::StopMoveType
|
|
33
|
+
# STOP = OpenHAB::Core::Types::StopMoveType::STOP
|
|
34
|
+
# MOVE = OpenHAB::Core::Types::StopMoveType::MOVE
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "forwardable"
|
|
4
|
+
|
|
5
|
+
require_relative "comparable_type"
|
|
6
|
+
require_relative "type"
|
|
7
|
+
|
|
8
|
+
module OpenHAB
|
|
9
|
+
module Core
|
|
10
|
+
module Types
|
|
11
|
+
StringType = org.openhab.core.library.types.StringType
|
|
12
|
+
|
|
13
|
+
# {StringType} represents a String as a {Type} and a {Command}.
|
|
14
|
+
class StringType
|
|
15
|
+
# @!parse include Command, State
|
|
16
|
+
|
|
17
|
+
extend Forwardable
|
|
18
|
+
include Comparable
|
|
19
|
+
include ComparableType
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Check equality without type conversion
|
|
23
|
+
#
|
|
24
|
+
# @return [true,false] if the same value is represented, without type
|
|
25
|
+
# conversion
|
|
26
|
+
def eql?(other)
|
|
27
|
+
return false unless other.instance_of?(self.class)
|
|
28
|
+
|
|
29
|
+
to_s.compare_to(other.to_s).zero?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Comparison
|
|
34
|
+
#
|
|
35
|
+
# @param [StringType, String]
|
|
36
|
+
# other object to compare to
|
|
37
|
+
#
|
|
38
|
+
# @return [Integer, nil] -1, 0, +1 depending on whether `other` is
|
|
39
|
+
# less than, equal to, or greater than self
|
|
40
|
+
#
|
|
41
|
+
# `nil` is returned if the two values are incomparable.
|
|
42
|
+
#
|
|
43
|
+
def <=>(other)
|
|
44
|
+
logger.trace("(#{self.class}) #{self} <=> #{other} (#{other.class})")
|
|
45
|
+
if other.respond_to?(:to_str)
|
|
46
|
+
to_str <=> other.to_str
|
|
47
|
+
elsif other.respond_to?(:coerce)
|
|
48
|
+
return nil unless (lhs, rhs = other.coerce(self))
|
|
49
|
+
|
|
50
|
+
lhs <=> rhs
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# Type Coercion
|
|
56
|
+
#
|
|
57
|
+
# Coerce object to a StringType
|
|
58
|
+
#
|
|
59
|
+
# @param [String] other object to coerce to a
|
|
60
|
+
# DateTimeType
|
|
61
|
+
#
|
|
62
|
+
# @return [[StringType, StringType], nil]
|
|
63
|
+
#
|
|
64
|
+
def coerce(other)
|
|
65
|
+
logger.trace("Coercing #{self} as a request from #{other.class}")
|
|
66
|
+
return [String.new(other.to_str), self] if other.respond_to?(:to_str)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# any method that exists on String gets forwarded to to_s
|
|
70
|
+
delegate (String.instance_methods - instance_methods + %w[=~ inspect]) => :to_s
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# @!parse StringType = OpenHAB::Core::Types::StringType
|