openhab-scripting 2.25.0 → 2.27.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c6a3905160edfd4bf027cb1afbac0af180f0e79641b4558a875d0f89cc275f8
4
- data.tar.gz: 97bc0f35a27b2ccd0fdcac64bfa0e5228b89a68085d5bf8213514e38f33a2add
3
+ metadata.gz: 2076584e55cc649fda227034943f6a412fb7a43a52479aec0ff3f33452266cc4
4
+ data.tar.gz: a7eb3154b9f436987883106bd39ab2a6574190abd2236d7c4898420624cbea87
5
5
  SHA512:
6
- metadata.gz: 39c074134bcd470a537c57256c57203ad1b750daa7137feea17a18dbc457c990dea3b2a985d271a9d6f5d4f7ae9c215c2444cdd4745ca6ae51aee4eebba8ae0f
7
- data.tar.gz: a8d60e555d4dc743bfdcda7e222281cb40e5fcd4bbea970e0d5473791e1f5e4d2cc590fa8256ba7d60a88a0c661ec7fb13ddc458d923e91166f3228333669926
6
+ metadata.gz: 5e1923dd15436484c0bd72c9aa83ab4a72d554e7cc17c7d9c06e4eda0b335a13b283405acdf8282e75bb1488c245c890b9b7151c0de03f8316d6367ad7e5be6f
7
+ data.tar.gz: f7e218fbf8b28b27ef154bcfa42dc167f0cf4bede89fe4772489a4aa8cec77d9827be83d32e748b663876a5286649217322d840b638ea73a37200ef82cfe34a9
@@ -87,25 +87,25 @@ module OpenHAB
87
87
  # @return [Object] the ruby wrapper for the item
88
88
  #
89
89
  # rubocop: disable Metrics/MethodLength
90
- # rubocop: disable Metrics/AbcSize
91
90
  # Disabled line length and branch size - case dispatch pattern
92
91
  private_class_method def self.decorate_item(item)
93
92
  case item
94
93
  when GroupItem
95
94
  decorate_group(item)
96
- when Java::Org.openhab.core.library.items::NumberItem
95
+ when Java::OrgOpenhabCoreLibraryItems::NumberItem
97
96
  OpenHAB::DSL::Items::NumberItem.new(item)
98
- when Java::Org.openhab.core.library.items::StringItem
97
+ when Java::OrgOpenhabCoreLibraryItems::StringItem
99
98
  OpenHAB::DSL::Items::StringItem.new(item)
100
- when Java::Org.openhab.core.library.items::DateTimeItem
99
+ when Java::OrgOpenhabCoreLibraryItems::DateTimeItem
101
100
  OpenHAB::DSL::Items::DateTimeItem.new(item)
102
- when Java::Org.openhab.core.library.items::RollershutterItem
101
+ when Java::OrgOpenhabCoreLibraryItems::RollershutterItem
103
102
  OpenHAB::DSL::Items::RollershutterItem.new(item)
103
+ when Java::OrgOpenhabCoreLibraryItems::PlayerItem
104
+ OpenHAB::DSL::Items::PlayerItem.new(item)
104
105
  else
105
106
  item
106
107
  end
107
108
  end
108
- # rubocop: enable Metrics/AbcSize
109
109
  # rubocop: enable Metrics/MethodLength
110
110
 
111
111
  #
@@ -15,6 +15,7 @@ require 'openhab/dsl/things'
15
15
  require 'openhab/dsl/items/items'
16
16
  require 'openhab/dsl/items/datetime_item'
17
17
  require 'openhab/dsl/items/number_item'
18
+ require 'openhab/dsl/items/player_item'
18
19
  require 'openhab/dsl/time_of_day'
19
20
  require 'openhab/dsl/gems'
20
21
  require 'openhab/dsl/persistence'
@@ -17,11 +17,13 @@ module OpenHAB
17
17
  class DateTimeItem
18
18
  extend Forwardable
19
19
  extend OpenHAB::DSL::Items::ItemDelegate
20
-
20
+ extend OpenHAB::DSL::Items::ItemCommand
21
21
  include Comparable
22
22
 
23
23
  def_item_delegator :@datetime_item
24
24
 
25
+ item_type Java::OrgOpenhabCoreLibraryItems::DateTimeItem
26
+
25
27
  #
26
28
  # Create a new DateTimeItem
27
29
  #
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'java'
4
+ require 'openhab/log/logger'
4
5
 
5
6
  module OpenHAB
6
7
  module DSL
@@ -9,19 +10,25 @@ module OpenHAB
9
10
  # Holds methods to automatically generate commands and
10
11
  # accessors for items
11
12
  module ItemCommand
13
+ include OpenHAB::Log
14
+
12
15
  #
13
16
  # For every value in the supplied enumeration create a corresponding method mapped to the lowercase
14
17
  # string representation of the enum value For example, an enum with values of STOP and START
15
18
  # would create methods stop() and start() that send the corresponding STOP and START commands to the item
16
19
  #
17
20
  # @param [Java::JavaLang::Enum] command_enum Enumeration to create commands for
21
+ # @param [Hash] optional hash in which if a generated method name mactches a key, the value of that key
22
+ # will be used as the method name instead, for example `:play? => :playing?`
18
23
  #
19
24
  #
20
- def item_command(command_enum)
25
+ def item_command(command_enum, methods = {})
21
26
  # rubocop:disable Style/HashEachMethods
22
27
  # Disable rule because Java enum does not support each_value
23
28
  command_enum.values.each do |command|
24
29
  command_method = command.to_s.downcase
30
+ command_method = methods.transform_keys(&:to_sym).fetch(command_method.to_sym, command_method)
31
+ logger.trace("Creating command method (#{command_method}) for #{self.class}")
25
32
  define_method(command_method) do
26
33
  self.command(command)
27
34
  end
@@ -37,20 +44,42 @@ module OpenHAB
37
44
  #
38
45
  # @param [Java::JavaLang::Enum] command_enum Enumeration to create methods for each value
39
46
  # to check if current state matches that enum
40
- # @yield [state] Optional block that can be used to transform state prior to comparison
47
+ # @param [Hash] optional hash in which if a generated method name mactches a key, the value of that key
48
+ # will be used as the method name instead, for example `:play? => :playing?`
41
49
  #
42
50
  #
43
- def item_state(command_enum)
51
+ def item_state(command_enum, methods = {})
44
52
  # rubocop:disable Style/HashEachMethods
45
53
  # Disable rule because Java enum does not support each_value
46
54
  command_enum.values.each do |command|
47
55
  status_method = "#{command.to_s.downcase}?"
56
+ status_method = methods.transform_keys(&:to_sym).fetch(status_method.to_sym, status_method)
57
+ logger.trace("Creating status method (#{status_method}) for #{self.class}")
48
58
  define_method(status_method) do
49
59
  state? && state.as(command_enum) == command
50
60
  end
51
61
  end
52
62
  # rubocop:enable Style/HashEachMethods
53
63
  end
64
+
65
+ #
66
+ # Extract the accepted state and command types from the specified OpenHAB
67
+ # Item class and pass them to item_state/item_command
68
+ #
69
+ # @param [Java::JavaLang::Class] item_class a Class that implements Java::OrgOpenhabCoreItems::Item
70
+ # @param [Hash] optional hash in which if a generated method name mactches a key, the value of that key
71
+ # will be used as the method name instead, for example `:play? => :playing?`
72
+ #
73
+ def item_type(item_class, methods = {})
74
+ item_class.field_reader(:ACCEPTED_DATA_TYPES)
75
+ item_class.field_reader(:ACCEPTED_COMMAND_TYPES)
76
+ item_class.ACCEPTED_DATA_TYPES.select(&:is_enum)
77
+ .grep_v(UnDefType)
78
+ .each { |type| item_state(type.ruby_class, methods) }
79
+ item_class.ACCEPTED_COMMAND_TYPES.select(&:is_enum)
80
+ .grep_v(UnDefType)
81
+ .each { |type| item_command(type.ruby_class, methods) }
82
+ end
54
83
  end
55
84
  end
56
85
  end
@@ -33,7 +33,7 @@ module OpenHAB
33
33
  alias key? include?
34
34
  end
35
35
 
36
- java_import org.openhab.core.items.GroupItem
36
+ java_import Java::OrgOpenhabCoreItems::GroupItem
37
37
  # Fetches all non-group items from the item registry
38
38
  # @return [OpenHAB::DSL::Items::Items]
39
39
  def items
@@ -17,6 +17,7 @@ module OpenHAB
17
17
  # way of breaking it up into multiple classes
18
18
  class NumberItem < Numeric
19
19
  extend OpenHAB::DSL::Items::ItemDelegate
20
+ extend OpenHAB::DSL::Items::ItemCommand
20
21
 
21
22
  def_item_delegator :@number_item
22
23
 
@@ -25,6 +26,8 @@ module OpenHAB
25
26
  java_import 'tec.uom.se.format.SimpleUnitFormat'
26
27
  java_import 'tec.uom.se.AbstractUnit'
27
28
 
29
+ item_type Java::OrgOpenhabCoreLibraryItems::NumberItem
30
+
28
31
  #
29
32
  # Create a new NumberItem
30
33
  #
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'java'
5
+ require 'openhab/dsl/items/item_command'
6
+ require 'openhab/dsl/items/item_delegate'
7
+
8
+ module OpenHAB
9
+ module DSL
10
+ module Items
11
+ #
12
+ # Delegator to OpenHAB Player Item
13
+ #
14
+ class PlayerItem
15
+ extend OpenHAB::DSL::Items::ItemCommand
16
+ extend OpenHAB::DSL::Items::ItemDelegate
17
+ extend Forwardable
18
+
19
+ def_item_delegator :@player_item
20
+
21
+ item_type Java::OrgOpenhabCoreLibraryItems::PlayerItem, play?: :playing?, pause?: :paused?,
22
+ rewind?: :rewinding?, fastforward?: :fastforwarding?
23
+
24
+ # rubocop: disable Style/Alias
25
+ # Disabled because 'alias' does not work with the dynamically defined methods
26
+ alias_method :fast_forward, :fastforward
27
+ alias_method :fast_forwarding?, :fastforwarding?
28
+ # rubocop: enable Style/Alias
29
+
30
+ #
31
+ # Creates a new PlayerItem
32
+ #
33
+ # @param [Java::OrgOpenhabCoreLibraryItems::PlayerItem] player_item
34
+ # The OpenHAB PlayerItem to delegate to
35
+ #
36
+ def initialize(player_item)
37
+ logger.trace("Wrapping #{player_item}")
38
+ @player_item = player_item
39
+
40
+ item_missing_delegate { @player_item }
41
+
42
+ super()
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -19,13 +19,7 @@ module OpenHAB
19
19
 
20
20
  def_item_delegator :@rollershutter_item
21
21
 
22
- java_import Java::OrgOpenhabCoreLibraryTypes::PercentType
23
- java_import Java::OrgOpenhabCoreLibraryTypes::UpDownType
24
- java_import Java::OrgOpenhabCoreLibraryTypes::StopMoveType
25
-
26
- item_command Java::OrgOpenhabCoreLibraryTypes::StopMoveType
27
- item_command Java::OrgOpenhabCoreLibraryTypes::UpDownType
28
- item_state Java::OrgOpenhabCoreLibraryTypes::UpDownType
22
+ item_type Java::OrgOpenhabCoreLibraryItems::RollershutterItem
29
23
 
30
24
  #
31
25
  # Creates a new RollershutterItem
@@ -13,7 +13,7 @@ module OpenHAB
13
13
  #
14
14
  class StringItem
15
15
  extend Forwardable
16
-
16
+ extend OpenHAB::DSL::Items::ItemCommand
17
17
  include Comparable
18
18
  extend OpenHAB::DSL::Items::ItemDelegate
19
19
 
@@ -23,6 +23,8 @@ module OpenHAB
23
23
 
24
24
  def_item_delegator :@string_item
25
25
 
26
+ item_type Java::OrgOpenhabCoreLibraryItems::StringItem
27
+
26
28
  #
27
29
  # Create a new StringItem
28
30
  #
@@ -25,7 +25,7 @@ module OpenHAB
25
25
 
26
26
  java_import Java::OrgOpenhabCoreLibraryTypes::OpenClosedType
27
27
 
28
- item_state Java::OrgOpenhabCoreLibraryTypes::OpenClosedType
28
+ item_type Java::OrgOpenhabCoreLibraryItems::ContactItem
29
29
 
30
30
  #
31
31
  # Compares contacts to OpenClosedTypes
@@ -30,8 +30,7 @@ module OpenHAB
30
30
  extend Forwardable
31
31
  extend OpenHAB::DSL::Items::ItemCommand
32
32
 
33
- item_state Java::OrgOpenhabCoreLibraryTypes::OnOffType
34
- item_command Java::OrgOpenhabCoreLibraryTypes::IncreaseDecreaseType
33
+ item_type Java::OrgOpenhabCoreLibraryItems::DimmerItem
35
34
 
36
35
  def_delegator :state, :to_s
37
36
 
@@ -103,8 +103,7 @@ module OpenHAB
103
103
  # @return [OpenHAB::DSL::MonkeyPatch::Items::MetadataItem], or nil if the namespace doesn't exist
104
104
  #
105
105
  def [](namespace)
106
- logger.trace("Namespaces (#{NamespaceAccessor.registry.getAll})")
107
- logger.trace("Namespace (#{NamespaceAccessor.registry.get(MetadataKey.new(namespace, @item_name))})")
106
+ logger.trace("Getting metadata for item: #{@item_name}, namespace '#{namespace}'")
108
107
  metadata = NamespaceAccessor.registry.get(MetadataKey.new(namespace, @item_name))
109
108
  MetadataItem.new(metadata: metadata) if metadata
110
109
  end
@@ -23,8 +23,7 @@ module OpenHAB
23
23
 
24
24
  java_import Java::OrgOpenhabCoreLibraryTypes::OnOffType
25
25
 
26
- item_command Java::OrgOpenhabCoreLibraryTypes::OnOffType
27
- item_state Java::OrgOpenhabCoreLibraryTypes::OnOffType
26
+ item_type Java::OrgOpenhabCoreLibraryItems::SwitchItem
28
27
 
29
28
  alias truthy? on?
30
29
 
@@ -255,13 +255,28 @@ module OpenHAB
255
255
  event = inputs&.dig('event')
256
256
 
257
257
  while (task = run_queue.shift)
258
- case task
259
- when RuleConfig::Run then process_run_task(event, task)
260
- when RuleConfig::Trigger then process_trigger_task(event, task)
261
- when RuleConfig::Delay then process_delay_task(inputs, mod, run_queue, task)
262
- when RuleConfig::Otherwise then process_otherwise_task(event, task)
258
+ if task.is_a? RuleConfig::Delay
259
+ process_delay_task(inputs, mod, run_queue, task)
260
+ else
261
+ process_task(event, task)
263
262
  end
264
263
  end
264
+ rescue StandardError => e
265
+ print_backtrace(e)
266
+ end
267
+
268
+ #
269
+ # Dispatch execution block tasks to different methods
270
+ #
271
+ # @param [OpenHab Event] event that triggered the rule
272
+ # @param [Task] task task containing otherwise block to execute
273
+ #
274
+ def process_task(event, task)
275
+ case task
276
+ when RuleConfig::Run then process_run_task(event, task)
277
+ when RuleConfig::Trigger then process_trigger_task(event, task)
278
+ when RuleConfig::Otherwise then process_otherwise_task(event, task)
279
+ end
265
280
  end
266
281
 
267
282
  #
@@ -316,6 +331,16 @@ module OpenHAB
316
331
  task.block.call(event)
317
332
  end
318
333
 
334
+ #
335
+ # Print error and stack trace without calls to internal classes
336
+ #
337
+ # @param [Exception] error A rescued error
338
+ #
339
+ def print_backtrace(error)
340
+ error = logger.clean_backtrace(error)
341
+ logger.error { "#{error.message} (#{error.class})\nIn rule: #{name}\n#{error.backtrace&.join("\n")}" }
342
+ end
343
+
319
344
  #
320
345
  # Create a new hash in which all elements are converted to strings
321
346
  #
@@ -79,7 +79,7 @@ module OpenHAB
79
79
  procs, items = conditions.flatten.partition { |condition| condition.is_a? Proc }
80
80
  logger.trace("Procs: #{procs} Items: #{items}")
81
81
 
82
- items.each { |item| logger.trace("#{item} truthy? #{item.truthy?}") }
82
+ items.each { |item| logger.trace { "#{item} truthy? #{item.truthy?}" } }
83
83
 
84
84
  process_check(check_type: check_type, event: event, items: items, procs: procs)
85
85
  end
@@ -27,6 +27,8 @@ module OpenHAB
27
27
  config.guard = Guard::Guard.new(only_if: config.only_if, not_if: config.not_if)
28
28
  logger.trace { config.inspect }
29
29
  process_rule_config(config)
30
+ rescue StandardError => e
31
+ re_raise_with_backtrace(e)
30
32
  end
31
33
 
32
34
  #
@@ -44,6 +46,16 @@ module OpenHAB
44
46
 
45
47
  private
46
48
 
49
+ #
50
+ # Re-raises a rescued error to OpenHAB with added rule name and stack trace
51
+ #
52
+ # @param [Exception] error A rescued error
53
+ #
54
+ def re_raise_with_backtrace(error)
55
+ error = logger.clean_backtrace(error)
56
+ raise error, "#{error.message}\nIn rule: #{@rule_name}\n#{error.backtrace.join("\n")}"
57
+ end
58
+
47
59
  #
48
60
  # Process a rule based on the supplied configuration
49
61
  #
@@ -22,11 +22,14 @@ module OpenHAB
22
22
 
23
23
  def_delegator :datetime, :to_s
24
24
  def_delegator :zoned_date_time, :month_value, :month
25
+ def_delegator :zoned_date_time, :day_of_month, :mday
26
+ def_delegator :zoned_date_time, :day_of_year, :yday
25
27
  def_delegator :zoned_date_time, :minute, :min
26
28
  def_delegator :zoned_date_time, :second, :sec
27
29
  def_delegator :zoned_date_time, :nano, :nsec
28
30
  def_delegator :zoned_date_time, :to_epoch_second, :to_i
29
31
  alias inspect to_s
32
+ alias day mday
30
33
 
31
34
  java_import Java::OrgOpenhabCoreLibraryTypes::DateTimeType
32
35
  java_import java.time.ZonedDateTime
@@ -181,6 +184,15 @@ module OpenHAB
181
184
  utc_offset.zero?
182
185
  end
183
186
 
187
+ #
188
+ # Returns an integer representing the day of the week, 0..6, with Sunday == 0.
189
+ #
190
+ # @return [Integer] The day of week
191
+ #
192
+ def wday
193
+ zoned_date_time.day_of_week.value % 7
194
+ end
195
+
184
196
  #
185
197
  # The timezone
186
198
  #
@@ -144,8 +144,10 @@ module OpenHAB
144
144
 
145
145
  OPERATIONS.each do |operation, method|
146
146
  define_method(operation) do |other|
147
- logger.trace("Executing math operation '#{operation}' on quantity #{inspect} "\
148
- "with other type #{other.class} and value #{other.inspect}")
147
+ logger.trace do
148
+ "Executing math operation '#{operation}' on quantity #{inspect} "\
149
+ "with other type #{other.class} and value #{other.inspect}"
150
+ end
149
151
 
150
152
  a, b = to_qt(coerce(other).reverse)
151
153
  logger.trace("Coerced a='#{a}' with b='#{b}'")
@@ -16,7 +16,14 @@ module OpenHAB
16
16
  java_import org.slf4j.LoggerFactory
17
17
 
18
18
  # @return [Array] Supported logging levels
19
- LEVELS = %i[TRACE DEBUG WARN INFO ERROR].freeze
19
+ LEVELS = %i[trace debug warn info error].freeze
20
+ private_constant :LEVELS
21
+
22
+ #
23
+ # Regex for matching internal calls in a stack trace
24
+ #
25
+ INTERNAL_CALL_REGEX = %r{(openhab-scripting-.*/lib)|(org/jruby/)}.freeze
26
+ private_constant :INTERNAL_CALL_REGEX
20
27
 
21
28
  #
22
29
  # Create a new logger
@@ -32,11 +39,30 @@ module OpenHAB
32
39
  # def <level>(msg=nil, &block)
33
40
  # log(severity: <level>, msg: msg, &block)
34
41
  # end
42
+ #
43
+ # Also creates methods to check if the different logging levels are enabled
44
+ #
35
45
  LEVELS.each do |level|
36
- method = level.to_s.downcase
37
- define_method(method.to_s) do |msg = nil, &block|
46
+ define_method(level) do |msg = nil, &block|
38
47
  log(severity: level, msg: msg, &block)
39
48
  end
49
+ define_method("#{level}_enabled?") { @sl4fj_logger.send("is_#{level}_enabled") }
50
+ end
51
+
52
+ #
53
+ # Cleans the backtrace of an error to remove internal calls. If logging is set
54
+ # to debug or lower, the full backtrace is kept
55
+ #
56
+ # @param [Exception] error An exception to be cleaned
57
+ #
58
+ # @return [Exception] the exception, potentially with a cleaned backtrace.
59
+ #
60
+ def clean_backtrace(error)
61
+ return error if debug_enabled?
62
+
63
+ backtrace = error.backtrace_locations.reject { |line| INTERNAL_CALL_REGEX.match? line.to_s }
64
+ error.set_backtrace(backtrace.map(&:to_s))
65
+ error
40
66
  end
41
67
 
42
68
  private
@@ -54,7 +80,7 @@ module OpenHAB
54
80
  raise ArgumentError, "Unknown Severity #{severity}" unless LEVELS.include? severity
55
81
 
56
82
  # Dynamically check enablement of underlying logger, this expands to "is_<level>_enabled"
57
- return unless @sl4fj_logger.send("is_#{severity.to_s.downcase}_enabled")
83
+ return unless send("#{severity}_enabled?")
58
84
 
59
85
  # Process block if no message provided
60
86
  msg = yield if msg.nil? && block_given?
@@ -62,7 +88,7 @@ module OpenHAB
62
88
  msg = message_to_string(msg: msg)
63
89
 
64
90
  # Dynamically invoke underlying logger, this expands to "<level>(message)"
65
- @sl4fj_logger.send(severity.to_s.downcase, msg)
91
+ @sl4fj_logger.send(severity, msg)
66
92
  end
67
93
 
68
94
  #
@@ -121,7 +147,7 @@ module OpenHAB
121
147
  configure_logger_for(classname)
122
148
  end
123
149
 
124
- private
150
+ private
125
151
 
126
152
  #
127
153
  # Configure a logger for the supplied classname
@@ -153,7 +179,7 @@ module OpenHAB
153
179
  .first
154
180
  .yield_self { |caller| File.basename(caller, '.*') }
155
181
  end
156
- end
182
+ end
157
183
 
158
184
  #
159
185
  # Add logger method to the object that includes this module
@@ -5,5 +5,5 @@
5
5
  #
6
6
  module OpenHAB
7
7
  # @return [String] Version of OpenHAB helper libraries
8
- VERSION = '2.25.0'
8
+ VERSION = '2.27.0'
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openhab-scripting
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.25.0
4
+ version: 2.27.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian O'Connell
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-24 00:00:00.000000000 Z
11
+ date: 2021-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,6 +44,7 @@ files:
44
44
  - lib/openhab/dsl/items/item_delegate.rb
45
45
  - lib/openhab/dsl/items/items.rb
46
46
  - lib/openhab/dsl/items/number_item.rb
47
+ - lib/openhab/dsl/items/player_item.rb
47
48
  - lib/openhab/dsl/items/rollershutter_item.rb
48
49
  - lib/openhab/dsl/items/string_item.rb
49
50
  - lib/openhab/dsl/monkey_patch/actions/actions.rb