openhab-scripting 2.16.1 → 2.18.0

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.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/lib/openhab.rb +12 -16
  3. data/lib/openhab/core/entity_lookup.rb +168 -0
  4. data/lib/openhab/core/openhab_setup.rb +31 -0
  5. data/lib/openhab/core/osgi.rb +61 -0
  6. data/lib/openhab/dsl/actions.rb +105 -0
  7. data/lib/openhab/dsl/dsl.rb +49 -0
  8. data/lib/openhab/{core/dsl → dsl}/gems.rb +0 -1
  9. data/lib/openhab/dsl/group.rb +100 -0
  10. data/lib/openhab/dsl/items/datetime_item.rb +97 -0
  11. data/lib/openhab/dsl/items/items.rb +46 -0
  12. data/lib/openhab/dsl/items/number_item.rb +352 -0
  13. data/lib/openhab/dsl/items/string_item.rb +120 -0
  14. data/lib/openhab/dsl/monkey_patch/actions/actions.rb +4 -0
  15. data/lib/openhab/dsl/monkey_patch/actions/script_thing_actions.rb +32 -0
  16. data/lib/openhab/dsl/monkey_patch/events/events.rb +5 -0
  17. data/lib/openhab/dsl/monkey_patch/events/item_command.rb +23 -0
  18. data/lib/openhab/dsl/monkey_patch/events/item_state_changed.rb +35 -0
  19. data/lib/openhab/dsl/monkey_patch/events/thing_status_info.rb +33 -0
  20. data/lib/openhab/dsl/monkey_patch/items/contact_item.rb +61 -0
  21. data/lib/openhab/dsl/monkey_patch/items/dimmer_item.rb +193 -0
  22. data/lib/openhab/dsl/monkey_patch/items/group_item.rb +37 -0
  23. data/lib/openhab/dsl/monkey_patch/items/items.rb +133 -0
  24. data/lib/openhab/dsl/monkey_patch/items/metadata.rb +281 -0
  25. data/lib/openhab/dsl/monkey_patch/items/persistence.rb +70 -0
  26. data/lib/openhab/dsl/monkey_patch/items/switch_item.rb +95 -0
  27. data/lib/openhab/dsl/monkey_patch/ruby/number.rb +39 -0
  28. data/lib/openhab/dsl/monkey_patch/ruby/range.rb +47 -0
  29. data/lib/openhab/dsl/monkey_patch/ruby/ruby.rb +8 -0
  30. data/lib/openhab/dsl/monkey_patch/ruby/string.rb +41 -0
  31. data/lib/openhab/dsl/monkey_patch/ruby/time.rb +32 -0
  32. data/lib/openhab/dsl/monkey_patch/types/decimal_type.rb +70 -0
  33. data/lib/openhab/dsl/monkey_patch/types/on_off_type.rb +51 -0
  34. data/lib/openhab/dsl/monkey_patch/types/open_closed_type.rb +36 -0
  35. data/lib/openhab/dsl/monkey_patch/types/percent_type.rb +32 -0
  36. data/lib/openhab/dsl/monkey_patch/types/quantity_type.rb +69 -0
  37. data/lib/openhab/dsl/monkey_patch/types/types.rb +8 -0
  38. data/lib/openhab/dsl/persistence.rb +25 -0
  39. data/lib/openhab/dsl/rules/automation_rule.rb +342 -0
  40. data/lib/openhab/dsl/rules/guard.rb +134 -0
  41. data/lib/openhab/dsl/rules/property.rb +102 -0
  42. data/lib/openhab/dsl/rules/rule.rb +116 -0
  43. data/lib/openhab/dsl/rules/rule_config.rb +151 -0
  44. data/lib/openhab/dsl/rules/triggers/changed.rb +143 -0
  45. data/lib/openhab/dsl/rules/triggers/channel.rb +53 -0
  46. data/lib/openhab/dsl/rules/triggers/command.rb +104 -0
  47. data/lib/openhab/dsl/rules/triggers/cron.rb +177 -0
  48. data/lib/openhab/dsl/rules/triggers/trigger.rb +124 -0
  49. data/lib/openhab/dsl/rules/triggers/updated.rb +98 -0
  50. data/lib/openhab/dsl/states.rb +61 -0
  51. data/lib/openhab/dsl/things.rb +91 -0
  52. data/lib/openhab/dsl/time_of_day.rb +232 -0
  53. data/lib/openhab/dsl/timers.rb +77 -0
  54. data/lib/openhab/dsl/types/datetime.rb +326 -0
  55. data/lib/openhab/dsl/types/quantity.rb +290 -0
  56. data/lib/openhab/dsl/units.rb +39 -0
  57. data/lib/openhab/log/configuration.rb +21 -0
  58. data/lib/openhab/log/logger.rb +172 -0
  59. data/lib/openhab/version.rb +1 -1
  60. metadata +58 -58
  61. data/lib/openhab/configuration.rb +0 -16
  62. data/lib/openhab/core/cron.rb +0 -27
  63. data/lib/openhab/core/debug.rb +0 -34
  64. data/lib/openhab/core/dsl.rb +0 -51
  65. data/lib/openhab/core/dsl/actions.rb +0 -107
  66. data/lib/openhab/core/dsl/entities.rb +0 -140
  67. data/lib/openhab/core/dsl/group.rb +0 -93
  68. data/lib/openhab/core/dsl/items/items.rb +0 -51
  69. data/lib/openhab/core/dsl/items/number_item.rb +0 -323
  70. data/lib/openhab/core/dsl/items/string_item.rb +0 -122
  71. data/lib/openhab/core/dsl/monkey_patch/actions/actions.rb +0 -4
  72. data/lib/openhab/core/dsl/monkey_patch/actions/script_thing_actions.rb +0 -22
  73. data/lib/openhab/core/dsl/monkey_patch/events.rb +0 -5
  74. data/lib/openhab/core/dsl/monkey_patch/events/item_command.rb +0 -13
  75. data/lib/openhab/core/dsl/monkey_patch/events/item_state_changed.rb +0 -25
  76. data/lib/openhab/core/dsl/monkey_patch/events/thing_status_info.rb +0 -26
  77. data/lib/openhab/core/dsl/monkey_patch/items/contact_item.rb +0 -54
  78. data/lib/openhab/core/dsl/monkey_patch/items/dimmer_item.rb +0 -182
  79. data/lib/openhab/core/dsl/monkey_patch/items/group_item.rb +0 -27
  80. data/lib/openhab/core/dsl/monkey_patch/items/items.rb +0 -132
  81. data/lib/openhab/core/dsl/monkey_patch/items/metadata.rb +0 -283
  82. data/lib/openhab/core/dsl/monkey_patch/items/persistence.rb +0 -72
  83. data/lib/openhab/core/dsl/monkey_patch/items/switch_item.rb +0 -87
  84. data/lib/openhab/core/dsl/monkey_patch/ruby/number.rb +0 -41
  85. data/lib/openhab/core/dsl/monkey_patch/ruby/range.rb +0 -47
  86. data/lib/openhab/core/dsl/monkey_patch/ruby/ruby.rb +0 -7
  87. data/lib/openhab/core/dsl/monkey_patch/ruby/string.rb +0 -43
  88. data/lib/openhab/core/dsl/monkey_patch/types/decimal_type.rb +0 -60
  89. data/lib/openhab/core/dsl/monkey_patch/types/on_off_type.rb +0 -41
  90. data/lib/openhab/core/dsl/monkey_patch/types/open_closed_type.rb +0 -25
  91. data/lib/openhab/core/dsl/monkey_patch/types/percent_type.rb +0 -23
  92. data/lib/openhab/core/dsl/monkey_patch/types/quantity_type.rb +0 -58
  93. data/lib/openhab/core/dsl/monkey_patch/types/types.rb +0 -8
  94. data/lib/openhab/core/dsl/persistence.rb +0 -27
  95. data/lib/openhab/core/dsl/property.rb +0 -96
  96. data/lib/openhab/core/dsl/rule/automation_rule.rb +0 -348
  97. data/lib/openhab/core/dsl/rule/guard.rb +0 -136
  98. data/lib/openhab/core/dsl/rule/rule.rb +0 -117
  99. data/lib/openhab/core/dsl/rule/rule_config.rb +0 -153
  100. data/lib/openhab/core/dsl/rule/triggers/changed.rb +0 -145
  101. data/lib/openhab/core/dsl/rule/triggers/channel.rb +0 -55
  102. data/lib/openhab/core/dsl/rule/triggers/command.rb +0 -106
  103. data/lib/openhab/core/dsl/rule/triggers/cron.rb +0 -160
  104. data/lib/openhab/core/dsl/rule/triggers/trigger.rb +0 -126
  105. data/lib/openhab/core/dsl/rule/triggers/updated.rb +0 -100
  106. data/lib/openhab/core/dsl/states.rb +0 -63
  107. data/lib/openhab/core/dsl/things.rb +0 -93
  108. data/lib/openhab/core/dsl/time_of_day.rb +0 -231
  109. data/lib/openhab/core/dsl/timers.rb +0 -79
  110. data/lib/openhab/core/dsl/types/quantity.rb +0 -292
  111. data/lib/openhab/core/dsl/units.rb +0 -41
  112. data/lib/openhab/core/log.rb +0 -170
  113. data/lib/openhab/core/patch_load_path.rb +0 -7
  114. data/lib/openhab/core/startup_delay.rb +0 -23
  115. data/lib/openhab/osgi.rb +0 -59
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'java'
4
- require 'core/log'
5
- require 'core/dsl/monkey_patch/events'
6
- require 'core/dsl/monkey_patch/ruby/ruby'
7
- require 'core/dsl/monkey_patch/items/items'
8
- require 'core/dsl/monkey_patch/types/types'
9
- require 'core/dsl/monkey_patch/actions/actions'
10
- require 'core/dsl/rule/rule'
11
- require 'core/dsl/actions'
12
- require 'core/dsl/timers'
13
- require 'core/dsl/group'
14
- require 'core/dsl/things'
15
- require 'core/dsl/items/items'
16
- require 'core/dsl/items/number_item'
17
- require 'core/dsl/time_of_day'
18
- require 'core/dsl/gems'
19
- require 'core/dsl/units'
20
- require 'core/dsl/types/quantity'
21
- require 'core/dsl/states'
22
- require 'core/dsl/persistence'
23
-
24
- module OpenHAB
25
- #
26
- # Holds core functions for OpenHAB Helper Library
27
- #
28
- module Core
29
- #
30
- # Module to be extended to access the OpenHAB Ruby DSL
31
- #
32
- module DSL
33
- # Extend the calling module/class with the DSL
34
- # rubocop: disable Metrics/MethodLength
35
- def self.extended(base)
36
- base.send :include, OpenHAB::Core::DSL::Rule
37
- base.send :include, OpenHAB::Core::DSL::Items
38
- base.send :include, OpenHAB::Core::DSL::Types
39
- base.send :include, OpenHAB::Core::DSL::Groups
40
- base.send :include, OpenHAB::Core::DSL::Units
41
- base.send :include, OpenHAB::Core::DSL::Actions
42
- base.send :include, OpenHAB::Core::DSL::Timers
43
- base.send :include, OpenHAB::Core::DSL::States
44
- base.send :include, OpenHAB::Core::DSL::Tod
45
- base.send :include, OpenHAB::Core::DSL::Persistence
46
- base.send :include, Things
47
- end
48
- # rubocop: enable Metrics/MethodLength
49
- end
50
- end
51
- end
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'java'
4
- require 'openhab/osgi'
5
-
6
- module OpenHAB
7
- module Core
8
- module DSL
9
- #
10
- # Module to import and steramlime access to OpenHAB actions
11
- #
12
- module Actions
13
- java_import org.openhab.core.library.types.PercentType
14
- include Logging
15
-
16
- OpenHAB::OSGI.services('org.openhab.core.model.script.engine.action.ActionService')&.each do |service|
17
- java_import service.actionClass.to_s
18
- logger.trace("Loaded ACTION: #{service.actionClass}")
19
- end
20
- # Import common actions
21
- %w[Exec HTTP Ping].each { |action| java_import "org.openhab.core.model.script.actions.#{action}" }
22
-
23
- #
24
- # Return an OpenHAB Action object for the given scope and thing
25
- #
26
- # @param scope [String] The action scope
27
- # @param thing_uid [String] Thing UID
28
- #
29
- # @return [Object] OpenHAB action
30
- #
31
- def actions(scope, thing_uid)
32
- # rubocop: disable Style/GlobalVars
33
- $actions.get(scope, thing_uid)
34
- # rubocop: enable Style/GlobalVars
35
- end
36
-
37
- #
38
- # Gets the list of action objects associated with a specific ThingUID
39
- #
40
- # @param [Java::org::openhab::core::thing::ThingUID] thing_uid to get associated actions for
41
- #
42
- # @return [Array] of action objects associated with thing_uid, may be empty
43
- #
44
- def actions_for_thing(thing_uid)
45
- thing_uid = thing_uid.to_s
46
- # rubocop: disable Style/GlobalVars
47
- action_keys = $actions.action_keys
48
- # rubocop: enable Style/GlobalVars
49
- logger.trace("Registered actions: '#{action_keys}' for thing '#{thing_uid}'")
50
- action_keys.map { |action_key| action_key.split('-', 2) }
51
- .select { |action_pair| action_pair.last == thing_uid }
52
- .map(&:first)
53
- .map { |scope| actions(scope, thing_uid) }
54
- end
55
-
56
- #
57
- # Send notification to an email or broadcast
58
- #
59
- # @param msg [String] The notification message to send
60
- # @param email [String] The email address to send to. If nil, the message will be broadcasted
61
- #
62
- # @return [void]
63
- #
64
- def notify(msg, email: nil)
65
- unless defined? NotificationAction
66
- raise NoMethodError, 'NotificationAction is not available. Please install the OpenHAB cloud addon'
67
- end
68
-
69
- if email
70
- NotificationAction.sendNotification email, msg
71
- else
72
- NotificationAction.sendBroadcastNotification msg
73
- end
74
- end
75
-
76
- #
77
- # Say text via OpenHAB Text-To-Speech service, Voice.say()
78
- #
79
- # @param text [String] The text to say
80
- # @param voice [String] Specify a particular voice to use
81
- # @param sink [String] Specify a particular sink to output the speech
82
- # @param volume [PercentType] Specify the volume for the speech
83
- #
84
- # @return [void]
85
- #
86
- def say(text, voice: nil, sink: nil, volume: nil)
87
- volume = PercentType.new(volume&.to_i) unless volume.is_a?(PercentType) || volume.nil?
88
- Voice.say text, voice, sink, volume
89
- end
90
-
91
- #
92
- # Play an audio file via OpenHAB sound service, Audio.playSound()
93
- #
94
- # @param filename [String] The sound file to play
95
- # @param sink [String] Specify a particular sink to output the speech
96
- # @param volume [PercentType] Specify the volume for the speech
97
- #
98
- # @return [void]
99
- #
100
- def play_sound(filename, sink: nil, volume: nil)
101
- volume = PercentType.new(volume&.to_i) unless volume.is_a?(PercentType) || volume.nil?
102
- Audio.playSound sink, filename, volume
103
- end
104
- end
105
- end
106
- end
107
- end
@@ -1,140 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'pp'
4
- require 'java'
5
- require 'set'
6
- require 'core/dsl/group'
7
- require 'core/log'
8
- require 'core/dsl/items/number_item'
9
- require 'core/dsl/items/string_item'
10
-
11
- # Automation lookup and injection of OpenHab entities
12
- java_import org.openhab.core.items.GroupItem
13
-
14
- #
15
- # Implements const_missing to return OpenHAB items or things if mapping to missing name if they exist
16
- #
17
- # @param [String] name Capital string that was not set as a constant and to be looked up
18
- #
19
- # @return [Object] OpenHAB Item or Thing if their name exist in OpenHAB item and thing regestries
20
- #
21
- def Object.const_missing(name)
22
- EntityLookup.lookup_item(name) || EntityLookup.lookup_thing(name) || super
23
- end
24
-
25
- #
26
- # Manages access to OpenHAB entities
27
- #
28
- module EntityLookup
29
- include Logging
30
- #
31
- # Decorate items with Ruby wrappers
32
- #
33
- # @param [Array] items Array of items to decorate
34
- #
35
- # @return [Array] Array of decorated items
36
- #
37
- # rubocop: disable Metrics/MethodLength
38
- # Disabled line length - case dispatch pattern
39
- def self.decorate_items(*items)
40
- items.flatten.map do |item|
41
- case item
42
- when GroupItem
43
- decorate_group(item)
44
- when Java::Org.openhab.core.library.items::NumberItem
45
- OpenHAB::Core::DSL::Items::NumberItem.new(item)
46
- when Java::Org.openhab.core.library.items::StringItem
47
- OpenHAB::Core::DSL::Items::StringItem.new(item)
48
- else
49
- item
50
- end
51
- end
52
- end
53
- # rubocop: enable Metrics/MethodLength
54
-
55
- #
56
- # Loops up a Thing in the OpenHAB registry replacing '_' with ':'
57
- #
58
- # @param [String] name of Thing to lookup in Thing registry
59
- #
60
- # @return [Thing] if found, nil otherwise
61
- #
62
- def self.lookup_thing(name)
63
- logger.trace("Looking up thing(#{name})")
64
- # Convert from : syntax to underscore
65
- name = name.to_s if name.is_a? Symbol
66
-
67
- # Thing UIDs have at least 3 segements
68
- return if name.count('_') < 3
69
-
70
- name = name.gsub('_', ':')
71
- # rubocop: disable Style/GlobalVars
72
- $things.get(Java::OrgOpenhabCoreThing::ThingUID.new(name))
73
- # rubocop: enable Style/GlobalVars
74
- end
75
-
76
- #
77
- # Lookup OpenHAB items in item registry
78
- #
79
- # @param [String] name of item to lookup
80
- #
81
- # @return [Item] OpenHAB item if registry contains a matching item, nil othewise
82
- #
83
- def self.lookup_item(name)
84
- logger.trace("Looking up item(#{name})")
85
- name = name.to_s if name.is_a? Symbol
86
- # rubocop: disable Style/GlobalVars
87
- item = $ir.get(name)
88
- # rubocop: enable Style/GlobalVars
89
- EntityLookup.decorate_items(item).first
90
- end
91
-
92
- #
93
- # Automatically looks up OpenHAB items and things in appropriate registries
94
- #
95
- # @param [method] method Name of item to lookup
96
- # @param [<Type>] args method arguments
97
- # @param [<Type>] block supplied to missing method
98
- #
99
- # @return [Object] Item or Thing if found in registry
100
- #
101
- def method_missing(method, *args, &block)
102
- return if method.to_s == 'scriptLoaded'
103
- return if method.to_s == 'scriptUnloaded'
104
-
105
- logger.trace("method missing, performing OpenHab Lookup for: #{method}")
106
- EntityLookup.lookup_item(method) || EntityLookup.lookup_thing(method) || super
107
- end
108
-
109
- #
110
- # Checks if this method responds to the missing method
111
- #
112
- # @param [String] method_name Name of the method to check
113
- # @param [Boolean] _include_private boolean if private methods should be checked
114
- #
115
- # @return [Boolean] true if this object will respond to the supplied method, false otherwise
116
- #
117
- def respond_to_missing?(method_name, _include_private = false)
118
- logger.trace("Checking if OpenHAB entites exist for #{method_name}")
119
- method_name = method_name.to_s if method_name.is_a? Symbol
120
-
121
- method_name == 'scriptLoaded' ||
122
- method_name == 'scriptUnloaded' ||
123
- EntityLookup.lookup_item(method_name) ||
124
- EntityLookup.lookup_thing(method_name) ||
125
- super
126
- end
127
-
128
- #
129
- # Decorate a group from an item base
130
- #
131
- # @param [OpenHAB item] item item to convert to a group item
132
- #
133
- # @return [OpenHAB::Core::DSL::Groups::Group] Group created from supplied item
134
- #
135
- def self.decorate_group(item)
136
- group = OpenHAB::Core::DSL::Groups::Group.new(Set.new(EntityLookup.decorate_items(item.all_members.to_a)))
137
- group.group = item
138
- group
139
- end
140
- end
@@ -1,93 +0,0 @@
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
- # rubocop: disable Style/GlobalVars
42
- Groups.new(EntityLookup.decorate_items($ir.items.select { |item| item.is_a? GroupItem }))
43
- # rubocop: enable Style/GlobalVars
44
- end
45
-
46
- # Group class that provides access to OpenHAB group object and delegates other methods to
47
- # a set of group items
48
- class Group < SimpleDelegator
49
- extend Forwardable
50
-
51
- java_import org.openhab.core.items.GroupItem
52
-
53
- # @return [org.openhab.core.items.GroupItem] OpenHAB Java Group Item
54
- attr_accessor :group
55
-
56
- # @!macro [attach] def_delegators
57
- # @!method $2
58
- # Forwards to org.openhab.core.items.GroupItem
59
- # @see org::openhab::core::items::GroupItem
60
- def_delegator :@group, :name
61
- def_delegator :@group, :label
62
-
63
- #
64
- # Gets members of this group that are themselves a group
65
- #
66
- # @return [Set] Set of members that are of type group
67
- #
68
- def groups
69
- group.members.grep(org.openhab.core.items.GroupItem)
70
- end
71
-
72
- #
73
- # Wraps the group in a struct, this method is intended to be called
74
- # as an indicator to the rule method that the user wishes to trigger
75
- # based on changes to group items
76
- #
77
- # @return [GroupItems] Indicator struct used by rules engine to trigger based on item changes
78
- #
79
- def items
80
- GroupItems.new(group: group)
81
- end
82
-
83
- #
84
- # @return [String] List of groups seperated by commas
85
- #
86
- def to_s
87
- "[#{map(&:to_s).join(',')}]"
88
- end
89
- end
90
- end
91
- end
92
- end
93
- end
@@ -1,51 +0,0 @@
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
- rescue Java::OrgOpenhabCoreItems::ItemNotFoundException
26
- nil
27
- end
28
-
29
- # Returns true if the given item name exists
30
- # @param name [String] Item name to check
31
- # @return [Boolean] true if the item exists, false otherwise
32
- def include?(name)
33
- # rubocop: disable Style/GlobalVars
34
- !$ir.getItems(name).empty?
35
- # rubocop: enable Style/GlobalVars
36
- end
37
- alias key? include?
38
- end
39
-
40
- java_import org.openhab.core.items.GroupItem
41
- # Fetches all non-group items from the item registry
42
- # @return [OpenHAB::Core::DSL::Items::Items]
43
- def items
44
- # rubocop: disable Style/GlobalVars
45
- Items.new(EntityLookup.decorate_items($ir.items.reject { |item| item.is_a? GroupItem }))
46
- # rubocop: enable Style/GlobalVars
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,323 +0,0 @@
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
- # rubocop: disable Metrics/ClassLength
16
- # Disabled because this class has a single responsibility, there does not appear a logical
17
- # way of breaking it up into multiple classes
18
- class NumberItem < Numeric
19
- extend Forwardable
20
-
21
- def_delegator :@number_item, :to_s
22
-
23
- java_import org.openhab.core.library.types.DecimalType
24
- java_import org.openhab.core.library.types.QuantityType
25
- java_import 'tec.uom.se.format.SimpleUnitFormat'
26
- java_import 'tec.uom.se.AbstractUnit'
27
-
28
- #
29
- # Create a new NumberItem
30
- #
31
- # @param [Java::Org::openhab::core::library::items::NumberItem] number_item OpenHAB number item to delegate to
32
- #
33
- def initialize(number_item)
34
- @number_item = number_item
35
- super()
36
- end
37
-
38
- #
39
- # Check if NumberItem is truthy? as per defined by library
40
- #
41
- # @return [Boolean] True if item is not in state UNDEF or NULL and value is not zero.
42
- #
43
- def truthy?
44
- @number_item.state? && @number_item.state != DecimalType::ZERO
45
- end
46
-
47
- #
48
- # Coerce objects into a NumberItem
49
- #
50
- # @param [Object] other object to coerce to a NumberItem if possible
51
- #
52
- # @return [Object] NumberItem, QuantityTypes, BigDecimal or nil depending on NumberItem configuration
53
- # and/or supplied object
54
- #
55
- def coerce(other)
56
- logger.trace("Coercing #{self} as a request from #{other.class}")
57
- case other
58
- when Quantity then coerce_from_quantity(other)
59
- when Numeric then coerce_from_numeric(other)
60
- else
61
- logger.trace("#{self} cannot be coerced to #{other.class}")
62
- nil
63
- end
64
- end
65
-
66
- #
67
- # Compare NumberItem to supplied object
68
- #
69
- # @param [Object] other object to compare to
70
- #
71
- # @return [Integer] -1,0,1 or nil depending on value supplied,
72
- # nil comparison to supplied object is not possible.
73
- #
74
- # rubocop: disable Metrics/AbcSize
75
- def <=>(other)
76
- logger.trace("NumberItem #{self} <=> #{other} (#{other.class})")
77
- case other
78
- when NumberItem then number_item_compare(other)
79
- when Numeric then @number_item.state.to_big_decimal.to_d <=> other.to_d
80
- when String then @number_item.state <=> QuantityType.new(other) if dimension
81
- else
82
- other = other.state if other.respond_to? :state
83
- @number_item.state <=> other
84
- end
85
- end
86
- # rubocop: enable Metrics/AbcSize
87
-
88
- #
89
- # Convert NumberItem to a Quantity
90
- #
91
- # @param [Object] other String or Unit representing an OpenHAB Unit
92
- #
93
- # @return [OpenHAB::Core::DSL::Types::Quantity] NumberItem converted to supplied Unit
94
- #
95
- def |(other)
96
- other = SimpleUnitFormat.instance.unitFor(other) if other.is_a? String
97
-
98
- if dimension
99
- to_qt | other
100
- else
101
- Quantity.new(QuantityType.new(to_d.to_java, other))
102
- end
103
- end
104
-
105
- #
106
- # Convert NumberItem to a Quantity
107
- #
108
- # @return [OpenHAB::Core::DSL::Types::Quantity] NumberItem converted to a QuantityUnit
109
- #
110
- def to_qt
111
- if dimension
112
- Quantity.new(@number_item.get_state_as(QuantityType))
113
- else
114
- Quantity.new(QuantityType.new(to_d.to_java, AbstractUnit::ONE))
115
- end
116
- end
117
-
118
- #
119
- # Converts the NumberItem to an Integer
120
- #
121
- # @return [Integer] NumberItem as an integer
122
- #
123
- def to_i
124
- to_d&.to_i
125
- end
126
-
127
- #
128
- # Converts the NumberItem to a float
129
- #
130
- # @return [Float] NumberItem as a float
131
- #
132
- def to_f
133
- to_d&.to_f
134
- end
135
-
136
- #
137
- # Converts the NumberItem to a BigDecimal
138
- #
139
- # @return [BigDecimal] NumberItem as a BigDecimal
140
- #
141
- def to_d
142
- @number_item.state.to_big_decimal.to_d if @number_item.state.respond_to? :to_big_decimal
143
- end
144
-
145
- #
146
- # Get the Dimension attached to the NumberItem
147
- #
148
- # @return [Java::org::openhab::core::library::types::QuantityType] dimension
149
- #
150
- def dimension
151
- @number_item.dimension
152
- end
153
-
154
- #
155
- # Forward missing methods to Openhab Number Item if they are defined
156
- #
157
- # @param [String] meth method name
158
- # @param [Array] args arguments for method
159
- # @param [Proc] block <description>
160
- #
161
- # @return [Object] Value from delegated method in OpenHAB NumberItem
162
- #
163
- def method_missing(meth, *args, &block)
164
- logger.trace("Method missing, performing dynamic lookup for: #{meth}")
165
- if @number_item.respond_to?(meth)
166
- @number_item.__send__(meth, *args, &block)
167
- elsif ::Kernel.method_defined?(meth) || ::Kernel.private_method_defined?(meth)
168
- ::Kernel.instance_method(meth).bind_call(self, *args, &block)
169
- else
170
- super(meth, *args, &block)
171
- end
172
- end
173
-
174
- #
175
- # Checks if this method responds to the missing method
176
- #
177
- # @param [String] method_name Name of the method to check
178
- # @param [Boolean] _include_private boolean if private methods should be checked
179
- #
180
- # @return [Boolean] true if this object will respond to the supplied method, false otherwise
181
- #
182
- def respond_to_missing?(method_name, _include_private = false)
183
- @number_item.respond_to?(method_name) ||
184
- ::Kernel.method_defined?(method_name) ||
185
- ::Kernel.private_method_defined?(method_name)
186
- end
187
-
188
- %w[+ - * /].each do |operation|
189
- define_method(operation) do |other|
190
- logger.trace("Execution math operation '#{operation}' on #{inspect} with #{other.inspect}")
191
- left_operand, right_operand = operands_for_operation(other)
192
- left_operand.public_send(operation, right_operand)
193
- end
194
- end
195
-
196
- private
197
-
198
- #
199
- # Get the operands for any operation
200
- #
201
- # @param [Object] other object to convert to a compatible operand
202
- #
203
- # @return [Array[Object,Object]] of operands where the first value is the left operand
204
- # and the second value is the right operand
205
- #
206
- def operands_for_operation(other)
207
- case other
208
- when NumberItem then number_item_operands(other)
209
- when Numeric then [to_d, other.to_d]
210
- when String then string_operands(other)
211
- else
212
- return other.coerce(to_d) if other.respond_to? :coerce
213
-
214
- raise ArgumentError, "#{other.class} can't be coerced into a NumberItem"
215
- end
216
- end
217
-
218
- #
219
- # Get operands for an operation when the right operand is provided as a string
220
- #
221
- # @param [String] other right operand
222
- #
223
- # @return [Array[QuantityType,QuantiyType]] of operands where the first value is the left operand
224
- # and the second value is the right operand
225
- #
226
- def string_operands(other)
227
- return [to_qt, Quantity.new(other)] if dimension
228
-
229
- raise ArgumentError, 'Strings are only valid operands if NumberItem is dimensions=ed.'
230
- end
231
-
232
- #
233
- # Get operands for an operation when the right operand is provided is another number item
234
- #
235
- # @param [NumberItem] other right operand
236
- #
237
- # @return [Array<QuantityType,QuantityType>,Array<BigDecimal,BigDecimal>] of operands depending on
238
- # if the left or right operand has a dimensions
239
- #
240
- def number_item_operands(other)
241
- if dimension || other.dimension
242
- dimensioned_operands(other)
243
- else
244
- logger.trace("Both objects lack dimension, self='#{self}' other='#{other}'")
245
- # If nothing has a dimension, just use BigDecimals
246
- [to_d, other.to_d]
247
- end
248
- end
249
-
250
- #
251
- # Get operands for an operation when the left or right operand has a dimension
252
- #
253
- # @param [NumberItem] other right operand
254
- #
255
- # @return [Array<QuantityType,QuantityType>] of operands
256
- #
257
- def dimensioned_operands(other)
258
- logger.trace("Dimensions self='#{dimension}' other='#{other.dimension}'")
259
- if dimension
260
- if other.dimension
261
- # If both numbers have dimensions, do the math on the quantity types.
262
- [to_qt, other.to_qt]
263
- else
264
- # If this number has dimension and the other does not,
265
- # do math with this quantity type and the other as a big decimal
266
- [to_qt, other]
267
- end
268
- else
269
- # If this number has no dimension and the other does, convert this into a dimensionless quantity
270
- [to_qt, other]
271
- end
272
- end
273
-
274
- #
275
- # Compare two number items, taking into account any dimensions
276
- #
277
- # @param [NumberItem] other number item
278
- #
279
- # @return [-1,0,1] depending on if other object is less than, equal to or greater than self
280
- #
281
- def number_item_compare(other)
282
- if other.dimension
283
- logger.trace('Other is dimensioned, converting self and other to QuantityTypes to compare')
284
- to_qt <=> other.to_qt
285
- else
286
- @number_item.state <=> other.state
287
- end
288
- end
289
-
290
- #
291
- # Coerce from a numberic object depnding on dimension and state
292
- #
293
- # @param [Numeric] other numeric object to convert
294
- #
295
- # @return [Array<QuantityType,QuantityType>,Array<BigDecimal,BigDecimal>,nil] depending on
296
- # if this object has a dimension or state
297
- #
298
- def coerce_from_numeric(other)
299
- if dimension
300
- [Quantity.new(other), to_qt]
301
- elsif @number_item.state?
302
- [other.to_d, @number_item.state.to_big_decimal.to_d]
303
- end
304
- end
305
-
306
- #
307
- # Coerce when other is a quantity
308
- #
309
- # @param [QuantityType] other
310
- #
311
- # @return [Array<QuanityType,QuantityType] other and self as a quantity type
312
- #
313
- def coerce_from_quantity(other)
314
- as_qt = to_qt
315
- logger.trace("Converted #{self} to a Quantity #{as_qt}")
316
- [other, as_qt]
317
- end
318
- end
319
- end
320
- end
321
- end
322
- end
323
- # rubocop: enable Metrics/ClassLength