openhab-scripting 3.0.0 → 3.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7eb19f2aa4bac30a6fb3b4f07953a9b78a54419795d4845c073432d803fa8629
4
- data.tar.gz: 7528671d2c2db7a58ecdc46b33f9b94656ff2cfc878ab76bc2703fcff4c49a7b
3
+ metadata.gz: 0be2b09569b3f3e96c5a79dbec4c6b0be6616a46d013831650c1e5d60cee374f
4
+ data.tar.gz: f71890c321e188f6322191e0c40099a6de22bc086d89085743b0c20f6b211649
5
5
  SHA512:
6
- metadata.gz: 6ef8331db3b6985bcc1ebb3b3b16fb251b61a482e10fc586e1d6bb2f7460ca197ecf8e38492613effd7fe6ff3f62f3975b443879f698373083c0b6ec192542d5
7
- data.tar.gz: 20451cc85edb7a50ad3d5f7d80415b6b769129d5ce5b9cd246f98d51f1c588036340a7c1c9211184c396b1919a44c8d49fa303b3637d6182964b28cf76ca6edb
6
+ metadata.gz: ff1e955329247a70b39158dff4a3694f51e2974fb11ce18260ff7048b686ac1181a99c7e941299def6f77697cacdaabf8f67e72d5c8bc0193f3b4334df761f94
7
+ data.tar.gz: db0fb2c35af26aaa963107b7971e83bfbfdd43c42d951cc470dec1192e8f743978ed91e04859953b5970e076516c275f7133784d12545a842e856181e76ef5af
@@ -87,8 +87,10 @@ module OpenHAB
87
87
  # @return [Object] the ruby wrapper for the item
88
88
  #
89
89
  # rubocop: disable Metrics/MethodLength
90
+ # rubocop: disable Metrics/CyclomaticComplexity
90
91
  # Disabled line length and branch size - case dispatch pattern
91
92
  def self.decorate_item(item)
93
+ logger.trace("Decorating #{item.class}")
92
94
  case item
93
95
  when Java::OrgOpenhabCoreItems::GroupItem
94
96
  OpenHAB::DSL::Items::GroupItem.new(item)
@@ -102,11 +104,15 @@ module OpenHAB
102
104
  OpenHAB::DSL::Items::RollershutterItem.new(item)
103
105
  when Java::OrgOpenhabCoreLibraryItems::PlayerItem
104
106
  OpenHAB::DSL::Items::PlayerItem.new(item)
107
+ when Java::OrgOpenhabCoreLibraryItems::ImageItem
108
+ OpenHAB::DSL::Items::ImageItem.new(item)
105
109
  else
110
+ logger.trace("Returning undecorated item #{item.class}")
106
111
  item
107
112
  end
108
113
  end
109
114
  # rubocop: enable Metrics/MethodLength
115
+ # rubocop: enable Metrics/CyclomaticComplexity
110
116
 
111
117
  #
112
118
  # Looks up a Thing in the OpenHAB registry replacing '_' with ':'
@@ -14,6 +14,7 @@ require 'openhab/dsl/group'
14
14
  require 'openhab/dsl/things'
15
15
  require 'openhab/dsl/items/items'
16
16
  require 'openhab/dsl/items/datetime_item'
17
+ require 'openhab/dsl/items/image_item'
17
18
  require 'openhab/dsl/items/number_item'
18
19
  require 'openhab/dsl/items/player_item'
19
20
  require 'openhab/dsl/items/group_item'
@@ -5,6 +5,7 @@ require 'java'
5
5
  require 'time'
6
6
  require 'openhab/dsl/types/datetime'
7
7
  require 'openhab/dsl/items/item_delegate'
8
+ require 'openhab/dsl/items/item_command'
8
9
 
9
10
  module OpenHAB
10
11
  module DSL
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+ require 'net/http'
5
+ require 'java'
6
+ require 'mimemagic'
7
+ require 'openhab/dsl/items/item_command'
8
+ require 'openhab/dsl/items/item_delegate'
9
+
10
+ module OpenHAB
11
+ module DSL
12
+ module Items
13
+ #
14
+ # Delegator to OpenHAB Player Item
15
+ #
16
+ class ImageItem
17
+ extend OpenHAB::DSL::Items::ItemCommand
18
+ extend OpenHAB::DSL::Items::ItemDelegate
19
+
20
+ def_item_delegator :@image_item
21
+
22
+ item_type Java::OrgOpenhabCoreLibraryItems::ImageItem
23
+
24
+ #
25
+ # Creates a new ImageItem
26
+ #
27
+ # @param [Java::OrgOpenhabCoreLibraryItems::ImageItem] image_item
28
+ # The OpenHAB ImageItem to delegate to
29
+ #
30
+ def initialize(image_item)
31
+ logger.trace("Wrapping #{image_item}")
32
+ @image_item = image_item
33
+
34
+ item_missing_delegate { @image_item }
35
+
36
+ super()
37
+ end
38
+
39
+ #
40
+ #
41
+ # Update image with base64 encoded OpenHAB compatable image
42
+ #
43
+ # @param [String] base_64 base_64 encoding of an image
44
+ #
45
+ #
46
+ def update(base_64_encoded_image)
47
+ logger.trace { "Updating #{self} with Base64 image #{base_64_encoded_image}" }
48
+ @image_item.update base_64_encoded_image
49
+ end
50
+
51
+ #
52
+ # Update image from file
53
+ #
54
+ # @param [String] file location
55
+ # @param [String] mime_type of image
56
+ #
57
+ #
58
+ def update_from_file(file, mime_type: nil)
59
+ file_data = IO.binread(file)
60
+ mime_type ||= (MimeMagic.by_path(file) || MimeMagic.by_magic(file_data))&.type
61
+ update_from_bytes(file_data, mime_type: mime_type)
62
+ end
63
+
64
+ #
65
+ # Update image from image at URL
66
+ #
67
+ # @param [String] uri location of image
68
+ #
69
+ #
70
+ def update_from_url(uri)
71
+ logger.debug("Downloading image from #{uri}")
72
+ response = Net::HTTP.get_response(URI(uri))
73
+ mime_type = response['content-type']
74
+ bytes = response.body
75
+ mime_type ||= detect_mime_from_bytes(bytes: bytes)
76
+ update_from_bytes(bytes, mime_type: mime_type)
77
+ end
78
+
79
+ #
80
+ # Update image from image bytes
81
+ #
82
+ # @param [String] mime_type of image
83
+ # @param [Object] bytes image data
84
+ #
85
+ #
86
+ def update_from_bytes(bytes, mime_type: nil)
87
+ mime_type ||= detect_mime_from_bytes(bytes: bytes)
88
+ base_64_image = encode_image(mime_type: mime_type, bytes: bytes)
89
+ update base_64_image
90
+ end
91
+
92
+ #
93
+ # Get the mime type for the image item
94
+ #
95
+ # @return [String] mime type for image, e.g. image/png
96
+ #
97
+ def mime_type
98
+ state&.mime_type
99
+ end
100
+
101
+ #
102
+ # Get the bytes of the image
103
+ #
104
+ # @return [Array] Bytes that comprise the image
105
+ #
106
+ def bytes
107
+ state&.get_bytes
108
+ end
109
+
110
+ private
111
+
112
+ #
113
+ # Encode image information in the format required by OpenHAB
114
+ #
115
+ # @param [String] mime_type for image
116
+ # @param [Object] bytes image data
117
+ #
118
+ # @return [String] OpenHAB image format with image data Base64 encoded
119
+ #
120
+ def encode_image(mime_type:, bytes:)
121
+ "data:#{mime_type};base64,#{Base64.strict_encode64(bytes)}"
122
+ end
123
+
124
+ #
125
+ # Detect the mime type based on bytes
126
+ #
127
+ # @param [Array] bytes representing image data
128
+ #
129
+ # @return [String] mime type if it can be detected, nil otherwise
130
+ #
131
+ def detect_mime_from_bytes(bytes:)
132
+ logger.trace('Detecting mime type from file image contents')
133
+ MimeMagic.by_magic(bytes)&.type
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -43,7 +43,7 @@ module OpenHAB
43
43
  # @return [Java::OrgOpenhabCoreLibraryTypes::PercentType] the position of the rollershutter
44
44
  #
45
45
  def position
46
- state.as(PercentType)
46
+ state&.as(PercentType)
47
47
  end
48
48
 
49
49
  #
@@ -54,6 +54,8 @@ module OpenHAB
54
54
  # @return [Integer] -1, 0 or 1 depending on the result of the comparison
55
55
  #
56
56
  def <=>(other)
57
+ return nil unless state?
58
+
57
59
  case other
58
60
  when PercentType, Java::OrgOpenhabCoreLibraryTypes::DecimalType then position.compare_to(other)
59
61
  when Numeric then position.int_value <=> other
@@ -73,8 +75,8 @@ module OpenHAB
73
75
  raise ArgumentError, "Cannot coerce to #{other.class}" unless other.is_a? Numeric
74
76
 
75
77
  case other
76
- when Integer then [other, position.int_value]
77
- when Float then [other, position.float_value]
78
+ when Integer then [other, position&.int_value]
79
+ when Float then [other, position&.float_value]
78
80
  end
79
81
  end
80
82
 
@@ -84,7 +86,7 @@ module OpenHAB
84
86
  %i[+ - * / %].each do |operator|
85
87
  define_method(operator) do |other|
86
88
  right, left = coerce(other)
87
- left.send(operator, right)
89
+ left&.send(operator, right)
88
90
  end
89
91
  end
90
92
  end
@@ -36,6 +36,8 @@ module OpenHAB
36
36
  # result from super if not supplied an OpenClosedType
37
37
  #
38
38
  def ==(other)
39
+ other = other.get_state_as(OpenClosedType) if other.respond_to?(:get_state_as)
40
+
39
41
  if other.is_a? OpenClosedType
40
42
  state? && state == other
41
43
  else
@@ -56,6 +56,8 @@ module OpenHAB
56
56
  # otherwise result from super
57
57
  #
58
58
  def ==(other)
59
+ other = other.get_state_as(OnOffType) if other.respond_to?(:get_state_as)
60
+
59
61
  if other.is_a? OnOffType
60
62
  state? && state == other
61
63
  else
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'openhab/dsl/types/quantity'
4
+ require 'openhab/dsl/types/datetime'
5
+ require 'openhab/dsl/items/datetime_item'
4
6
 
5
7
  module OpenHAB
6
8
  module DSL
@@ -21,7 +23,8 @@ module OpenHAB
21
23
  #
22
24
  def ==(other)
23
25
  case other
24
- when OpenHAB::DSL::Types::Quantity, QuantityType, Java::OrgOpenhabCoreLibraryTypes::StringType
26
+ when OpenHAB::DSL::Types::Quantity, QuantityType, Java::OrgOpenhabCoreLibraryTypes::StringType,
27
+ OpenHAB::DSL::Types::DateTime, OpenHAB::DSL::Items::DateTimeItem
25
28
  other == self
26
29
  else
27
30
  super
@@ -44,6 +44,21 @@ module OpenHAB
44
44
  end
45
45
  # rubocop:enable Style/CaseLikeIf
46
46
  end
47
+
48
+ #
49
+ # Test for equality
50
+ #
51
+ # @param [Object] other Other object to compare against
52
+ #
53
+ # @return [Boolean] true if self and other can be considered equal, false otherwise
54
+ #
55
+ def ==(other)
56
+ if other.respond_to?(:get_state_as)
57
+ self == other.get_state_as(OnOffType)
58
+ else
59
+ super
60
+ end
61
+ end
47
62
  end
48
63
  end
49
64
  end
@@ -33,6 +33,21 @@ module OpenHAB
33
33
  super
34
34
  end
35
35
  end
36
+
37
+ #
38
+ # Test for equality
39
+ #
40
+ # @param [Object] other Other object to compare against
41
+ #
42
+ # @return [Boolean] true if self and other can be considered equal, false otherwise
43
+ #
44
+ def ==(other)
45
+ if other.respond_to?(:get_state_as)
46
+ self == other.get_state_as(OpenClosedType)
47
+ else
48
+ super
49
+ end
50
+ end
36
51
  end
37
52
  end
38
53
  end
@@ -30,6 +30,21 @@ module OpenHAB
30
30
  super
31
31
  end
32
32
  end
33
+
34
+ #
35
+ # Test for equality
36
+ #
37
+ # @param [Object] other Other object to compare against
38
+ #
39
+ # @return [Boolean] true if self and other can be considered equal, false otherwise
40
+ #
41
+ def ==(other)
42
+ if other.respond_to?(:get_state_as)
43
+ self == other.get_state_as(UpDownType)
44
+ else
45
+ super
46
+ end
47
+ end
33
48
  end
34
49
  end
35
50
  end
@@ -29,6 +29,7 @@ module OpenHAB
29
29
  set_name(config.name)
30
30
  set_description(config.description)
31
31
  set_triggers(config.triggers)
32
+ @run_context = config.caller
32
33
  @run_queue = config.run
33
34
  @guard = config.guard
34
35
  between = config.between&.yield_self { between(config.between) }
@@ -288,7 +289,7 @@ module OpenHAB
288
289
  #
289
290
  def process_otherwise_task(event, task)
290
291
  logger.trace { "Executing rule '#{name}' otherwise block with event(#{event})" }
291
- task.block.call(event)
292
+ @run_context.instance_exec(event, &task.block)
292
293
  end
293
294
 
294
295
  #
@@ -316,7 +317,7 @@ module OpenHAB
316
317
  return unless event&.item
317
318
 
318
319
  logger.trace { "Executing rule '#{name}' trigger block with item (#{event.item})" }
319
- task.block.call(event.item)
320
+ @run_context.instance_exec(event.item, &task.block)
320
321
  end
321
322
 
322
323
  #
@@ -328,7 +329,7 @@ module OpenHAB
328
329
  #
329
330
  def process_run_task(event, task)
330
331
  logger.trace { "Executing rule '#{name}' run block with event(#{event})" }
331
- task.block.call(event)
332
+ @run_context.instance_exec(event, &task.block)
332
333
  end
333
334
 
334
335
  #
@@ -23,10 +23,11 @@ module OpenHAB
23
23
  def rule(rule_name, &block)
24
24
  @rule_name = rule_name
25
25
  config = RuleConfig.new(rule_name, block.binding)
26
- config.instance_eval(&block)
26
+ config.instance_exec(config, &block)
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
+ config
30
31
  rescue StandardError => e
31
32
  re_raise_with_backtrace(e)
32
33
  end
@@ -40,6 +40,9 @@ module OpenHAB
40
40
  # @return [Array] Of trigger guards
41
41
  attr_accessor :guard
42
42
 
43
+ # @return [Object] object that invoked rule method
44
+ attr_accessor :caller
45
+
43
46
  #
44
47
  # Struct holding a run block
45
48
  #
@@ -61,7 +61,7 @@ module OpenHAB
61
61
  # @return [Array] A new flat array with any GroupMembers object left intact
62
62
  #
63
63
  def separate_groups(item_array)
64
- return item_array if item_array.length <= 1 && item_array.grep(Array).length.zero?
64
+ return item_array if item_array.grep(Array).length.zero?
65
65
 
66
66
  groups, items = item_array.partition { |item| item.is_a? OpenHAB::DSL::Items::GroupItem::GroupMembers }
67
67
  groups + separate_groups(items.flatten(1))
@@ -75,13 +75,13 @@ module OpenHAB
75
75
  # @return [Integer] -1, 0 or 1 depending on the outcome
76
76
  #
77
77
  def <=>(other)
78
+ if other.respond_to?(:zoned_date_time)
79
+ return zoned_date_time.to_instant.compare_to(other.zoned_date_time.to_instant)
80
+ end
81
+
78
82
  case other
79
- when DateTime, DateTimeType, DateTimeItem
80
- zoned_date_time.to_instant.compare_to(other.zoned_date_time.to_instant)
81
- when TimeOfDay::TimeOfDay, TimeOfDay::TimeOfDayRangeElement
82
- to_tod <=> other
83
- when String
84
- self <=> DateTime.parse(DATE_ONLY_REGEX =~ other ? "#{other}'T'00:00:00#{zone}" : other)
83
+ when TimeOfDay::TimeOfDay, TimeOfDay::TimeOfDayRangeElement then to_tod <=> other
84
+ when String then self <=> DateTime.parse(DATE_ONLY_REGEX =~ other ? "#{other}'T'00:00:00#{zone}" : other)
85
85
  else
86
86
  self <=> DateTime.from(other)
87
87
  end
@@ -5,5 +5,5 @@
5
5
  #
6
6
  module OpenHAB
7
7
  # @return [String] Version of OpenHAB helper libraries
8
- VERSION = '3.0.0'
8
+ VERSION = '3.2.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: 3.0.0
4
+ version: 3.2.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-03-02 00:00:00.000000000 Z
11
+ date: 2021-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mimemagic
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.3'
27
41
  description: JRuby Helper Libraries for OpenHAB Scripting
28
42
  email:
29
43
  - broconne@gmail.com
@@ -41,6 +55,7 @@ files:
41
55
  - lib/openhab/dsl/group.rb
42
56
  - lib/openhab/dsl/items/datetime_item.rb
43
57
  - lib/openhab/dsl/items/group_item.rb
58
+ - lib/openhab/dsl/items/image_item.rb
44
59
  - lib/openhab/dsl/items/item_command.rb
45
60
  - lib/openhab/dsl/items/item_delegate.rb
46
61
  - lib/openhab/dsl/items/items.rb