openhab-scripting 2.9.1
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/.github/workflows/workflow.yml +327 -0
- data/.gitignore +17 -0
- data/.java-version +1 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +113 -0
- data/Gemfile +28 -0
- data/Gemfile.lock +245 -0
- data/Guardfile +35 -0
- data/LICENSE +277 -0
- data/README.md +23 -0
- data/Rakefile +406 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/config/userdata/config/org/openhab/restauth.config +3 -0
- data/cucumber.yml +1 -0
- data/docs/_config.yml +135 -0
- data/docs/contributing/index.md +47 -0
- data/docs/examples/conversions.md +123 -0
- data/docs/examples/index.md +61 -0
- data/docs/index.md +19 -0
- data/docs/installation/index.md +26 -0
- data/docs/motivation/index.md +27 -0
- data/docs/usage/execution.md +9 -0
- data/docs/usage/execution/delay.md +48 -0
- data/docs/usage/execution/otherwise.md +30 -0
- data/docs/usage/execution/run.md +70 -0
- data/docs/usage/execution/triggered.md +48 -0
- data/docs/usage/guards.md +51 -0
- data/docs/usage/guards/between.md +30 -0
- data/docs/usage/guards/not_if.md +41 -0
- data/docs/usage/guards/only_if.md +40 -0
- data/docs/usage/index.md +11 -0
- data/docs/usage/items.md +66 -0
- data/docs/usage/items/contact.md +84 -0
- data/docs/usage/items/dimmer.md +147 -0
- data/docs/usage/items/groups.md +76 -0
- data/docs/usage/items/number.md +225 -0
- data/docs/usage/items/string.md +49 -0
- data/docs/usage/items/switch.md +85 -0
- data/docs/usage/misc.md +7 -0
- data/docs/usage/misc/actions.md +108 -0
- data/docs/usage/misc/duration.md +21 -0
- data/docs/usage/misc/gems.md +25 -0
- data/docs/usage/misc/logging.md +21 -0
- data/docs/usage/misc/metadata.md +128 -0
- data/docs/usage/misc/store_states.md +42 -0
- data/docs/usage/misc/time_of_day.md +69 -0
- data/docs/usage/misc/timers.md +67 -0
- data/docs/usage/rule.md +43 -0
- data/docs/usage/things.md +29 -0
- data/docs/usage/triggers.md +8 -0
- data/docs/usage/triggers/changed.md +57 -0
- data/docs/usage/triggers/channel.md +54 -0
- data/docs/usage/triggers/command.md +69 -0
- data/docs/usage/triggers/cron.md +19 -0
- data/docs/usage/triggers/every.md +76 -0
- data/docs/usage/triggers/updated.md +78 -0
- data/lib/openhab.rb +39 -0
- data/lib/openhab/configuration.rb +16 -0
- data/lib/openhab/core/cron.rb +27 -0
- data/lib/openhab/core/debug.rb +34 -0
- data/lib/openhab/core/dsl.rb +47 -0
- data/lib/openhab/core/dsl/actions.rb +107 -0
- data/lib/openhab/core/dsl/entities.rb +103 -0
- data/lib/openhab/core/dsl/gems.rb +29 -0
- data/lib/openhab/core/dsl/group.rb +91 -0
- data/lib/openhab/core/dsl/items/items.rb +39 -0
- data/lib/openhab/core/dsl/items/number_item.rb +217 -0
- data/lib/openhab/core/dsl/items/string_item.rb +102 -0
- data/lib/openhab/core/dsl/monkey_patch/actions/actions.rb +4 -0
- data/lib/openhab/core/dsl/monkey_patch/actions/script_thing_actions.rb +22 -0
- data/lib/openhab/core/dsl/monkey_patch/events.rb +5 -0
- data/lib/openhab/core/dsl/monkey_patch/events/item_command.rb +13 -0
- data/lib/openhab/core/dsl/monkey_patch/events/item_state_changed.rb +25 -0
- data/lib/openhab/core/dsl/monkey_patch/events/thing_status_info.rb +26 -0
- data/lib/openhab/core/dsl/monkey_patch/items/contact_item.rb +54 -0
- data/lib/openhab/core/dsl/monkey_patch/items/dimmer_item.rb +125 -0
- data/lib/openhab/core/dsl/monkey_patch/items/group_item.rb +27 -0
- data/lib/openhab/core/dsl/monkey_patch/items/items.rb +130 -0
- data/lib/openhab/core/dsl/monkey_patch/items/metadata.rb +259 -0
- data/lib/openhab/core/dsl/monkey_patch/items/switch_item.rb +86 -0
- data/lib/openhab/core/dsl/monkey_patch/ruby/number.rb +69 -0
- data/lib/openhab/core/dsl/monkey_patch/ruby/range.rb +46 -0
- data/lib/openhab/core/dsl/monkey_patch/ruby/ruby.rb +5 -0
- data/lib/openhab/core/dsl/monkey_patch/types/decimal_type.rb +24 -0
- data/lib/openhab/core/dsl/monkey_patch/types/on_off_type.rb +41 -0
- data/lib/openhab/core/dsl/monkey_patch/types/open_closed_type.rb +25 -0
- data/lib/openhab/core/dsl/monkey_patch/types/percent_type.rb +23 -0
- data/lib/openhab/core/dsl/monkey_patch/types/types.rb +7 -0
- data/lib/openhab/core/dsl/property.rb +85 -0
- data/lib/openhab/core/dsl/rule/channel.rb +41 -0
- data/lib/openhab/core/dsl/rule/cron.rb +115 -0
- data/lib/openhab/core/dsl/rule/guard.rb +99 -0
- data/lib/openhab/core/dsl/rule/item.rb +207 -0
- data/lib/openhab/core/dsl/rule/rule.rb +374 -0
- data/lib/openhab/core/dsl/rule/triggers.rb +77 -0
- data/lib/openhab/core/dsl/states.rb +63 -0
- data/lib/openhab/core/dsl/things.rb +93 -0
- data/lib/openhab/core/dsl/time_of_day.rb +203 -0
- data/lib/openhab/core/dsl/timers.rb +85 -0
- data/lib/openhab/core/dsl/types/quantity.rb +255 -0
- data/lib/openhab/core/dsl/units.rb +41 -0
- data/lib/openhab/core/duration.rb +69 -0
- data/lib/openhab/core/log.rb +175 -0
- data/lib/openhab/core/patch_load_path.rb +7 -0
- data/lib/openhab/core/startup_delay.rb +22 -0
- data/lib/openhab/osgi.rb +52 -0
- data/lib/openhab/version.rb +9 -0
- data/openhab-scripting.gemspec +30 -0
- data/openhab_rules/warmup.rb +5 -0
- metadata +157 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'pp'
|
|
4
|
+
require 'java'
|
|
5
|
+
require 'set'
|
|
6
|
+
require 'core/dsl/group'
|
|
7
|
+
require 'core/dsl/items/number_item'
|
|
8
|
+
require 'core/dsl/items/string_item'
|
|
9
|
+
|
|
10
|
+
# Automation lookup and injection of OpenHab entities
|
|
11
|
+
java_import org.openhab.core.items.GroupItem
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# Implements const_missing to return OpenHAB items or things if mapping to missing name if they exist
|
|
15
|
+
#
|
|
16
|
+
# @param [String] name Capital string that was not set as a constant and to be looked up
|
|
17
|
+
#
|
|
18
|
+
# @return [Object] OpenHAB Item or Thing if their name exist in OpenHAB item and thing regestries
|
|
19
|
+
#
|
|
20
|
+
def Object.const_missing(name)
|
|
21
|
+
EntityLookup.lookup_item(name) || EntityLookup.lookup_thing(name) || super
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Manages access to OpenHAB entities
|
|
26
|
+
#
|
|
27
|
+
module EntityLookup
|
|
28
|
+
#
|
|
29
|
+
# Decorate items with Ruby wrappers
|
|
30
|
+
#
|
|
31
|
+
# @param [Array] items Array of items to decorate
|
|
32
|
+
#
|
|
33
|
+
# @return [Array] Array of decorated items
|
|
34
|
+
#
|
|
35
|
+
def self.decorate_items(*items)
|
|
36
|
+
items.flatten.map do |item|
|
|
37
|
+
case item
|
|
38
|
+
when GroupItem
|
|
39
|
+
group = item
|
|
40
|
+
item = OpenHAB::Core::DSL::Groups::Group.new(Set.new(EntityLookup.decorate_items(item.all_members.to_a)))
|
|
41
|
+
item.group = group
|
|
42
|
+
item
|
|
43
|
+
when Java::Org.openhab.core.library.items::NumberItem
|
|
44
|
+
OpenHAB::Core::DSL::Items::NumberItem.new(item)
|
|
45
|
+
when Java::Org.openhab.core.library.items::StringItem
|
|
46
|
+
OpenHAB::Core::DSL::Items::StringItem.new(item)
|
|
47
|
+
else
|
|
48
|
+
item
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# Loops up a Thing in the OpenHAB registry replacing '_' with ':'
|
|
55
|
+
#
|
|
56
|
+
# @param [String] name of Thing to lookup in Thing registry
|
|
57
|
+
#
|
|
58
|
+
# @return [Thing] if found, nil otherwise
|
|
59
|
+
#
|
|
60
|
+
def self.lookup_thing(name)
|
|
61
|
+
# Convert from : syntax to underscore
|
|
62
|
+
name = name.to_s if name.is_a? Symbol
|
|
63
|
+
|
|
64
|
+
# Thing UIDs have at least 3 segements
|
|
65
|
+
return if name.count('_') < 3
|
|
66
|
+
|
|
67
|
+
name = name.gsub('_', ':')
|
|
68
|
+
# rubocop: disable Style/GlobalVars
|
|
69
|
+
$things.get(Java::OrgOpenhabCoreThing::ThingUID.new(name))
|
|
70
|
+
# rubocop: enable Style/GlobalVars
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#
|
|
74
|
+
# Lookup OpenHAB items in item registry
|
|
75
|
+
#
|
|
76
|
+
# @param [String] name of item to lookup
|
|
77
|
+
#
|
|
78
|
+
# @return [Item] OpenHAB item if registry contains a matching item, nil othewise
|
|
79
|
+
#
|
|
80
|
+
def self.lookup_item(name)
|
|
81
|
+
name = name.to_s if name.is_a? Symbol
|
|
82
|
+
# rubocop: disable Style/GlobalVars
|
|
83
|
+
item = $ir.get(name)
|
|
84
|
+
# rubocop: enable Style/GlobalVars
|
|
85
|
+
EntityLookup.decorate_items(item).first
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
#
|
|
89
|
+
# Automatically looks up OpenHAB items and things in appropriate registries
|
|
90
|
+
#
|
|
91
|
+
# @param [method] method Name of item to lookup
|
|
92
|
+
# @param [<Type>] args method arguments
|
|
93
|
+
# @param [<Type>] block supplied to missing method
|
|
94
|
+
#
|
|
95
|
+
# @return [Object] Item or Thing if found in registry
|
|
96
|
+
#
|
|
97
|
+
def method_missing(method, *args, &block)
|
|
98
|
+
return if method.to_s == 'scriptLoaded'
|
|
99
|
+
return if method.to_s == 'scriptUnloaded'
|
|
100
|
+
|
|
101
|
+
EntityLookup.lookup_item(method) || EntityLookup.lookup_thing(method) || super
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'core/log'
|
|
4
|
+
|
|
5
|
+
begin
|
|
6
|
+
require 'bundler/inline'
|
|
7
|
+
|
|
8
|
+
include Logging
|
|
9
|
+
logger.debug('Bundler required')
|
|
10
|
+
rescue LoadError
|
|
11
|
+
include Logging
|
|
12
|
+
logger.debug('Bundler not found installing')
|
|
13
|
+
|
|
14
|
+
begin
|
|
15
|
+
require 'rubygems/commands/install_command'
|
|
16
|
+
cmd = Gem::Commands::InstallCommand.new
|
|
17
|
+
cmd.handle_options ['--no-document', 'bundler', '-v', '2.1.4']
|
|
18
|
+
cmd.execute
|
|
19
|
+
logger.debug('Bundler is installed')
|
|
20
|
+
require 'bundler/inline'
|
|
21
|
+
rescue Gem::SystemExitException => e
|
|
22
|
+
if e.exit_code.zero?
|
|
23
|
+
logger.debug('Bundler is installed')
|
|
24
|
+
require 'bundler/inline'
|
|
25
|
+
else
|
|
26
|
+
logger.error("Error installing bundler, exit code: #{e}")
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'delegate'
|
|
4
|
+
require 'forwardable'
|
|
5
|
+
require 'openhab/core/dsl/entities'
|
|
6
|
+
|
|
7
|
+
module OpenHAB
|
|
8
|
+
module Core
|
|
9
|
+
module DSL
|
|
10
|
+
#
|
|
11
|
+
# Provides access to OpenHAB Groups
|
|
12
|
+
#
|
|
13
|
+
module Groups
|
|
14
|
+
#
|
|
15
|
+
# Indicator struct interpreted by rules to trigger based on items contained in a group
|
|
16
|
+
#
|
|
17
|
+
GroupItems = Struct.new(:group, keyword_init: true)
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# Provide access to groups as a set
|
|
21
|
+
#
|
|
22
|
+
class Groups < SimpleDelegator
|
|
23
|
+
#
|
|
24
|
+
# Get a OpenHAB Group by name
|
|
25
|
+
# @param [String] name of the group to retrieve
|
|
26
|
+
#
|
|
27
|
+
# @return [Set] of OpenHAB Groups
|
|
28
|
+
#
|
|
29
|
+
def[](name)
|
|
30
|
+
group = EntityLookup.lookup_item(name)
|
|
31
|
+
(group.is_a? Group) ? group : nil
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Retreive all OpenHAB groups
|
|
37
|
+
#
|
|
38
|
+
# @return [Set] of OpenHAB Groups
|
|
39
|
+
#
|
|
40
|
+
def groups
|
|
41
|
+
Groups.new(EntityLookup.decorate_items($ir.items.select { |item| item.is_a? GroupItem }))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Group class that provides access to OpenHAB group object and delegates other methods to
|
|
45
|
+
# a set of group items
|
|
46
|
+
class Group < SimpleDelegator
|
|
47
|
+
extend Forwardable
|
|
48
|
+
|
|
49
|
+
java_import org.openhab.core.items.GroupItem
|
|
50
|
+
|
|
51
|
+
# @return [org.openhab.core.items.GroupItem] OpenHAB Java Group Item
|
|
52
|
+
attr_accessor :group
|
|
53
|
+
|
|
54
|
+
# @!macro [attach] def_delegators
|
|
55
|
+
# @!method $2
|
|
56
|
+
# Forwards to org.openhab.core.items.GroupItem
|
|
57
|
+
# @see org::openhab::core::items::GroupItem
|
|
58
|
+
def_delegator :@group, :name
|
|
59
|
+
def_delegator :@group, :label
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# Gets members of this group that are themselves a group
|
|
63
|
+
#
|
|
64
|
+
# @return [Set] Set of members that are of type group
|
|
65
|
+
#
|
|
66
|
+
def groups
|
|
67
|
+
group.members.grep(org.openhab.core.items.GroupItem)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# Wraps the group in a struct, this method is intended to be called
|
|
72
|
+
# as an indicator to the rule method that the user wishes to trigger
|
|
73
|
+
# based on changes to group items
|
|
74
|
+
#
|
|
75
|
+
# @return [GroupItems] Indicator struct used by rules engine to trigger based on item changes
|
|
76
|
+
#
|
|
77
|
+
def items
|
|
78
|
+
GroupItems.new(group: group)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# @return [String] List of groups seperated by commas
|
|
83
|
+
#
|
|
84
|
+
def to_s
|
|
85
|
+
"[#{map(&:to_s).join(',')}]"
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'java'
|
|
4
|
+
require 'openhab/core/dsl/entities'
|
|
5
|
+
|
|
6
|
+
module OpenHAB
|
|
7
|
+
module Core
|
|
8
|
+
module DSL
|
|
9
|
+
#
|
|
10
|
+
# Manages OpenHAB items
|
|
11
|
+
#
|
|
12
|
+
module Items
|
|
13
|
+
#
|
|
14
|
+
# Delegates to underlying set of all OpenHAB Items, provides convenience methods
|
|
15
|
+
#
|
|
16
|
+
class Items < SimpleDelegator
|
|
17
|
+
# Fetches the named item from the the ItemRegistry
|
|
18
|
+
# @param [String] name
|
|
19
|
+
# @return Item from registry, nil if item missing or requested item is a Group Type
|
|
20
|
+
def[](name)
|
|
21
|
+
# rubocop: disable Style/GlobalVars
|
|
22
|
+
item = $ir.getItem(name)
|
|
23
|
+
# rubocop: enable Style/GlobalVars
|
|
24
|
+
(item.is_a? GroupItem) ? nil : item
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
java_import org.openhab.core.items.GroupItem
|
|
29
|
+
# Fetches all non-group items from the item registry
|
|
30
|
+
# @return [OpenHAB::Core::DSL::Items::Items]
|
|
31
|
+
def items
|
|
32
|
+
# rubocop: disable Style/GlobalVars
|
|
33
|
+
Items.new(EntityLookup.decorate_items($ir.items.reject { |item| item.is_a? GroupItem }))
|
|
34
|
+
# rubocop: enable Style/GlobalVars
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bigdecimal'
|
|
4
|
+
require 'forwardable'
|
|
5
|
+
require 'java'
|
|
6
|
+
require 'openhab/core/dsl/types/quantity'
|
|
7
|
+
|
|
8
|
+
module OpenHAB
|
|
9
|
+
module Core
|
|
10
|
+
module DSL
|
|
11
|
+
module Items
|
|
12
|
+
#
|
|
13
|
+
# Delegation to OpenHAB Number Item
|
|
14
|
+
#
|
|
15
|
+
class NumberItem < Numeric
|
|
16
|
+
extend Forwardable
|
|
17
|
+
|
|
18
|
+
def_delegator :@number_item, :to_s
|
|
19
|
+
|
|
20
|
+
java_import org.openhab.core.library.types.DecimalType
|
|
21
|
+
java_import org.openhab.core.library.types.QuantityType
|
|
22
|
+
java_import 'tec.uom.se.format.SimpleUnitFormat'
|
|
23
|
+
java_import 'tec.uom.se.AbstractUnit'
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Create a new NumberItem
|
|
27
|
+
#
|
|
28
|
+
# @param [Java::Org::openhab::core::library::items::NumberItem] number_item OpenHAB number item to delegate to
|
|
29
|
+
#
|
|
30
|
+
def initialize(number_item)
|
|
31
|
+
@number_item = number_item
|
|
32
|
+
super()
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Check if NumberItem is truthy? as per defined by library
|
|
37
|
+
#
|
|
38
|
+
# @return [Boolean] True if item is not in state UNDEF or NULL and value is not zero.
|
|
39
|
+
#
|
|
40
|
+
def truthy?
|
|
41
|
+
@number_item.state? && @number_item.state != DecimalType::ZERO
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
# Coerce objects into a NumberItem
|
|
46
|
+
#
|
|
47
|
+
# @param [Object] other object to coerce to a NumberItem if possible
|
|
48
|
+
#
|
|
49
|
+
# @return [Object] NumberItem, QuantityTypes, BigDecimal or nil depending on NumberItem configuration and/or supplied object
|
|
50
|
+
#
|
|
51
|
+
def coerce(other)
|
|
52
|
+
logger.trace("Coercing #{self} as a request from #{other.class}")
|
|
53
|
+
case other
|
|
54
|
+
when Quantity
|
|
55
|
+
as_qt = to_qt
|
|
56
|
+
logger.trace("Converted #{self} to a Quantity #{as_qt}")
|
|
57
|
+
[other, as_qt]
|
|
58
|
+
when Numeric
|
|
59
|
+
if dimension
|
|
60
|
+
[Quantity.new(other), to_qt]
|
|
61
|
+
elsif @number_item.state?
|
|
62
|
+
[BigDecimal(other), @number_item.state.to_big_decimal.to_d]
|
|
63
|
+
end
|
|
64
|
+
else
|
|
65
|
+
logger.trace("#{self} cannot be coereced to #{other.class}")
|
|
66
|
+
nil
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# Compare NumberItem to supplied object
|
|
72
|
+
#
|
|
73
|
+
# @param [Object] other object to compare to
|
|
74
|
+
#
|
|
75
|
+
# @return [Integer] -1,0,1 or nil depending on value supplied, nil comparison to supplied object is not possible.
|
|
76
|
+
#
|
|
77
|
+
def <=>(other)
|
|
78
|
+
logger.trace("Comparing #{self} to #{other}")
|
|
79
|
+
case other
|
|
80
|
+
when NumberItem
|
|
81
|
+
if other.dimension
|
|
82
|
+
logger.trace('Other is dimensioned, converting self and other to QuantityTypes to compare')
|
|
83
|
+
to_qt <=> other.to_qt
|
|
84
|
+
else
|
|
85
|
+
@number_item.state <=> other.state
|
|
86
|
+
end
|
|
87
|
+
when Numeric
|
|
88
|
+
@number_item.state.to_big_decimal.to_d <=> BigDecimal(other)
|
|
89
|
+
when String
|
|
90
|
+
@number_item.state <=> QuantityType.new(other) if dimension
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
#
|
|
95
|
+
# Convert NumberItem to a Quantity
|
|
96
|
+
#
|
|
97
|
+
# @param [Object] other String or Unit representing an OpenHAB Unit
|
|
98
|
+
#
|
|
99
|
+
# @return [OpenHAB::Core::DSL::Types::Quantity] NumberItem converted to supplied Unit
|
|
100
|
+
#
|
|
101
|
+
def |(other)
|
|
102
|
+
other = SimpleUnitFormat.instance.unitFor(other) if other.is_a? String
|
|
103
|
+
|
|
104
|
+
if dimension
|
|
105
|
+
to_qt | other
|
|
106
|
+
else
|
|
107
|
+
Quantity.new(QuantityType.new(to_d.to_java, other))
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
#
|
|
112
|
+
# Convert NumberItem to a Quantity
|
|
113
|
+
#
|
|
114
|
+
# @return [OpenHAB::Core::DSL::Types::Quantity] NumberItem converted to a QuantityUnit
|
|
115
|
+
#
|
|
116
|
+
def to_qt
|
|
117
|
+
if dimension
|
|
118
|
+
Quantity.new(@number_item.get_state_as(QuantityType))
|
|
119
|
+
else
|
|
120
|
+
Quantity.new(QuantityType.new(to_d.to_java, AbstractUnit::ONE))
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
#
|
|
125
|
+
# Converts the NumberItem to an Integer
|
|
126
|
+
#
|
|
127
|
+
# @return [Integer] NumberItem as an integer
|
|
128
|
+
#
|
|
129
|
+
def to_i
|
|
130
|
+
to_d&.to_i
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
#
|
|
134
|
+
# Converts the NumberItem to a float
|
|
135
|
+
#
|
|
136
|
+
# @return [Float] NumberItem as a float
|
|
137
|
+
#
|
|
138
|
+
def to_f
|
|
139
|
+
to_d&.to_f
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
#
|
|
143
|
+
# Converts the NumberItem to a BigDecimal
|
|
144
|
+
#
|
|
145
|
+
# @return [BigDecimal] NumberItem as a BigDecimal
|
|
146
|
+
#
|
|
147
|
+
def to_d
|
|
148
|
+
@number_item.state.to_big_decimal.to_d if @number_item.state.respond_to? :to_big_decimal
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
#
|
|
152
|
+
# Get the Dimension attached to the NumberItem
|
|
153
|
+
#
|
|
154
|
+
# @return [Java::org::openhab::core::library::types::QuantityType] dimension
|
|
155
|
+
#
|
|
156
|
+
def dimension
|
|
157
|
+
@number_item.dimension
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
#
|
|
161
|
+
# Forward missing methods to Openhab Number Item if they are defined
|
|
162
|
+
#
|
|
163
|
+
# @param [String] meth method name
|
|
164
|
+
# @param [Array] args arguments for method
|
|
165
|
+
# @param [Proc] block <description>
|
|
166
|
+
#
|
|
167
|
+
# @return [Object] Value from delegated method in OpenHAB NumberItem
|
|
168
|
+
#
|
|
169
|
+
def method_missing(meth, *args, &block)
|
|
170
|
+
if @number_item.respond_to?(meth)
|
|
171
|
+
@number_item.__send__(meth, *args, &block)
|
|
172
|
+
elsif ::Kernel.method_defined?(meth) || ::Kernel.private_method_defined?(meth)
|
|
173
|
+
::Kernel.instance_method(meth).bind_call(self, *args, &block)
|
|
174
|
+
else
|
|
175
|
+
super(meth, *args, &block)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
%w[+ - * /].each do |operation|
|
|
180
|
+
define_method(operation) do |other|
|
|
181
|
+
logger.trace("Execution math operation '#{operation}' on #{inspect} with #{other.inspect}")
|
|
182
|
+
if other.is_a? NumberItem
|
|
183
|
+
logger.trace('Math operations is between two NumberItems.')
|
|
184
|
+
if dimension && other.dimension
|
|
185
|
+
# If both numbers have dimensions, do the math on the quantity types.
|
|
186
|
+
logger.trace("Both objects have dimensions self='#{dimension}' other='#{other.dimension}'")
|
|
187
|
+
to_qt.public_send(operation, other.to_qt)
|
|
188
|
+
elsif dimension && !other.dimension
|
|
189
|
+
# If this number has dimension and the other does not, do math with this quantity type and the other as a big decimal
|
|
190
|
+
logger.trace("Self has dimension self='#{dimension}' other lacks dimension='#{other}'")
|
|
191
|
+
to_qt.public_send(operation, other)
|
|
192
|
+
elsif other.dimension
|
|
193
|
+
# If this number has no dimension and the other does, convert this into a dimensionless quantity
|
|
194
|
+
logger.trace("Self has no dimension self='#{self}' other has dimension='#{other.dimension}'")
|
|
195
|
+
to_qt.public_send(operation, other)
|
|
196
|
+
else
|
|
197
|
+
logger.trace("Both objects lack dimension, self='#{self}' other='#{other}'")
|
|
198
|
+
# If nothing has a dimension, just use BigDecimals
|
|
199
|
+
to_d.public_send(operation, other.to_d)
|
|
200
|
+
end
|
|
201
|
+
elsif other.is_a? Numeric
|
|
202
|
+
to_d.public_send(operation, BigDecimal(other))
|
|
203
|
+
elsif dimension && other.is_a?(String)
|
|
204
|
+
to_qt.public_send(operation, Quantity.new(other))
|
|
205
|
+
elsif other.respond_to? :coerce
|
|
206
|
+
a, b = other.coerce(to_d)
|
|
207
|
+
a.public_send(operation, b)
|
|
208
|
+
else
|
|
209
|
+
raise TypeError, "#{other.class} can't be coerced into a NumberItem"
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|