openhab-scripting 2.25.1 → 2.27.1

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: 7226c1329289ce5ce0f85f552c091a6c5f89cb27427b9e6419d528c77a792239
4
- data.tar.gz: e92ad134d92584fed6ddeeef98984cabc56355cd94f4d205a5228263ac2677d1
3
+ metadata.gz: f73567aa2e4ca6070bbcb6963c46babc966e069f62d60f4def67fbca8aa0b70e
4
+ data.tar.gz: d01862005948c69fb130ba93a14732f6fa565528b40d13ce13252c6da7523359
5
5
  SHA512:
6
- metadata.gz: '0519c68cec3b2316751c36ba27c208267ee86f76230a1722dcd3369d61e19da73a96b6616ed2a71838daf68beb3f64b88e1553f82f8cb00daec4de5c859ecb87'
7
- data.tar.gz: f688f894e8a4bde1c3ee12facc846836a922cc7a1120ffd5d89ff41a6d6be1692608467265179543aaed1262394ea37aaa92d4bd5b03ad9eb33bcdd13b06c8dc
6
+ metadata.gz: bbdae9215b3347eabc65ea92eb70ac44834b374233ce7f31b15bfa8f99dcc05c9b85d2c1b7fad3c29d63be62100966648bac9e4255ab614edf40a2dd231b24a8
7
+ data.tar.gz: 5d8b30987d208674337ffddd43caaeee1c72596ae82e9a3792b74adbb0d7c82879040333173230c6016fb0552be191de877ec664566cbd61f9b14fc150ed4d9e
@@ -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'
@@ -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,14 +44,17 @@ 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
@@ -57,14 +67,18 @@ module OpenHAB
57
67
  # Item class and pass them to item_state/item_command
58
68
  #
59
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?`
60
72
  #
61
- def item_type(item_class)
73
+ def item_type(item_class, methods = {})
62
74
  item_class.field_reader(:ACCEPTED_DATA_TYPES)
63
75
  item_class.field_reader(:ACCEPTED_COMMAND_TYPES)
64
- item_class.ACCEPTED_DATA_TYPES.select(&:is_enum).grep_v(UnDefType).each { |type| item_state(type.ruby_class) }
65
- item_class.ACCEPTED_COMMAND_TYPES.select(&:is_enum).grep_v(UnDefType).each do |type|
66
- item_command(type.ruby_class)
67
- end
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) }
68
82
  end
69
83
  end
70
84
  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
@@ -0,0 +1,49 @@
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?,
22
+ :pause? => :paused?,
23
+ :rewind? => :rewinding?,
24
+ :fastforward? => :fastforwarding?
25
+
26
+ # rubocop: disable Style/Alias
27
+ # Disabled because 'alias' does not work with the dynamically defined methods
28
+ alias_method :fast_forward, :fastforward
29
+ alias_method :fast_forwarding?, :fastforwarding?
30
+ # rubocop: enable Style/Alias
31
+
32
+ #
33
+ # Creates a new PlayerItem
34
+ #
35
+ # @param [Java::OrgOpenhabCoreLibraryItems::PlayerItem] player_item
36
+ # The OpenHAB PlayerItem to delegate to
37
+ #
38
+ def initialize(player_item)
39
+ logger.trace("Wrapping #{player_item}")
40
+ @player_item = player_item
41
+
42
+ item_missing_delegate { @player_item }
43
+
44
+ super()
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -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
@@ -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
  #
@@ -59,7 +59,8 @@ module OpenHAB
59
59
  #
60
60
  def should_run?(event)
61
61
  logger.trace("Checking guards #{self}")
62
- check(@only_if, check_type: :only_if, event: event) && check(@not_if, check_type: :not_if, event: event)
62
+ check(@only_if, :check_type => :only_if,
63
+ :event => event) && check(@not_if, :check_type => :not_if, :event => event)
63
64
  end
64
65
 
65
66
  private
@@ -79,7 +80,7 @@ module OpenHAB
79
80
  procs, items = conditions.flatten.partition { |condition| condition.is_a? Proc }
80
81
  logger.trace("Procs: #{procs} Items: #{items}")
81
82
 
82
- items.each { |item| logger.trace("#{item} truthy? #{item.truthy?}") }
83
+ items.each { |item| logger.trace { "#{item} truthy? #{item.truthy?}" } }
83
84
 
84
85
  process_check(check_type: check_type, event: event, items: items, procs: procs)
85
86
  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
  #
@@ -62,10 +62,10 @@ module OpenHAB
62
62
  #
63
63
  Delay = Struct.new(:duration)
64
64
 
65
- prop_array :run, array_name: :run_queue, wrapper: Run
66
- prop_array :triggered, array_name: :run_queue, wrapper: Trigger
67
- prop_array :delay, array_name: :run_queue, wrapper: Delay
68
- prop_array :otherwise, array_name: :run_queue, wrapper: Otherwise
65
+ prop_array :run, :array_name => :run_queue, :wrapper => Run
66
+ prop_array :triggered, :array_name => :run_queue, :wrapper => Trigger
67
+ prop_array :delay, :array_name => :run_queue, :wrapper => Delay
68
+ prop_array :otherwise, :array_name => :run_queue, :wrapper => Otherwise
69
69
 
70
70
  prop :name
71
71
  prop :description
@@ -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.1'
8
+ VERSION = '2.27.1'
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.1
4
+ version: 2.27.1
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-28 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