openhab-scripting 5.5.0 → 5.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/openhab/core/actions/audio.rb +5 -2
  3. data/lib/openhab/core/configuration.rb +70 -0
  4. data/lib/openhab/core/emulate_hash.rb +241 -0
  5. data/lib/openhab/core/events/abstract_event.rb +11 -0
  6. data/lib/openhab/core/events/timer_event.rb +48 -0
  7. data/lib/openhab/core/items/group_function.rb +37 -0
  8. data/lib/openhab/core/items/group_item.rb +10 -4
  9. data/lib/openhab/core/items/item.rb +31 -0
  10. data/lib/openhab/core/items/metadata/hash.rb +9 -179
  11. data/lib/openhab/core/items/metadata/namespace_hash.rb +38 -141
  12. data/lib/openhab/core/items/semantics/semantic_tag.rb +5 -0
  13. data/lib/openhab/core/items/semantics/tag_class_methods.rb +9 -0
  14. data/lib/openhab/core/items/semantics.rb +7 -3
  15. data/lib/openhab/core/rules/rule.rb +17 -4
  16. data/lib/openhab/core/things/links/provider.rb +1 -1
  17. data/lib/openhab/core/things/proxy.rb +2 -1
  18. data/lib/openhab/core/things/thing.rb +23 -0
  19. data/lib/openhab/core/types/date_time_type.rb +2 -1
  20. data/lib/openhab/core/types/open_closed_type.rb +2 -1
  21. data/lib/openhab/core/types/string_type.rb +1 -1
  22. data/lib/openhab/core/types/up_down_type.rb +2 -1
  23. data/lib/openhab/core/value_cache.rb +6 -5
  24. data/lib/openhab/core_ext/java/duration.rb +2 -1
  25. data/lib/openhab/core_ext/java/local_time.rb +8 -6
  26. data/lib/openhab/core_ext/java/month_day.rb +2 -1
  27. data/lib/openhab/core_ext/java/period.rb +1 -1
  28. data/lib/openhab/core_ext/ruby/numeric.rb +1 -0
  29. data/lib/openhab/dsl/items/builder.rb +13 -6
  30. data/lib/openhab/dsl/rules/automation_rule.rb +29 -5
  31. data/lib/openhab/dsl/rules/builder.rb +47 -22
  32. data/lib/openhab/dsl/rules/rule_triggers.rb +1 -1
  33. data/lib/openhab/dsl/rules/triggers/conditions/generic.rb +1 -1
  34. data/lib/openhab/dsl/rules/triggers/cron/cron.rb +43 -16
  35. data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +101 -96
  36. data/lib/openhab/dsl/things/builder.rb +8 -6
  37. data/lib/openhab/dsl/thread_local.rb +1 -0
  38. data/lib/openhab/dsl/timer_manager.rb +4 -4
  39. data/lib/openhab/dsl/version.rb +1 -1
  40. data/lib/openhab/dsl.rb +23 -4
  41. data/lib/openhab/osgi.rb +1 -1
  42. data/lib/openhab/rspec/karaf.rb +7 -4
  43. data/lib/openhab/rspec/openhab/core/actions.rb +0 -3
  44. metadata +13 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b21bcd2b958405fb4b4843435e3a6ffa14690af1b6f58139897982a7d55323f
4
- data.tar.gz: a1c258192db348813c49b94e21492771d9b2e7d6515e6aff0e04b5bba7786711
3
+ metadata.gz: 9d58174285c7861dfffd3bdb108f6d9c01af149a4f53aab9b9dd331be7f0f022
4
+ data.tar.gz: 6bdb6e115927aea3396ca05be97ecb1ee9d8afc9bc493689c32f7fcd19a7e71a
5
5
  SHA512:
6
- metadata.gz: 81fd4bfaa0f3cb1907622938750dc0eabcc51b0d46d8ad39fd63282ad6118771f79b38a72fc10ffaa19f0037564d1adb710c7da0b981dad37f9cdf9b6f665cfd
7
- data.tar.gz: 1b30d461514d2f952e71e3ce7325dd5582fa386ca21723458b725378f6f78880f96bf5693a03aeb64d8a70775830979fe6d8f732c67076abaf9fd687e0ff4948
6
+ metadata.gz: 454fb750a412b8e153ce7df0320738b1f9729e1313d6d8e9aaaaa7c720c8c0cda7f704a35d78952705e7f21718551daae2c01e0dcf0b7e26c1fbfa2481d5ab6b
7
+ data.tar.gz: 0a1e62ecb2bcce48a207bed5899bd0e7913492836a5c953a4b22756fa149b353ee8db229e3b5b71f48d503db1d7bfaa4f8baa94abe92469047b386ab3d438da6
@@ -23,8 +23,11 @@ module OpenHAB
23
23
  #
24
24
  def play_sound(filename, sink: nil, volume: nil)
25
25
  volume = PercentType.new(volume) unless volume.is_a?(PercentType) || volume.nil?
26
- java_send :playSound, [java.lang.String, java.lang.String, PercentType.java_class],
27
- sink, filename.to_s, volume
26
+ java_send :playSound,
27
+ [java.lang.String, java.lang.String, PercentType.java_class],
28
+ sink,
29
+ filename.to_s,
30
+ volume
28
31
  end
29
32
 
30
33
  #
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+ require_relative "emulate_hash"
5
+
6
+ module OpenHAB
7
+ module Core
8
+ java_import org.openhab.core.config.core.Configuration
9
+
10
+ #
11
+ # {Configuration} represents openHAB's {org.openhab.core.config.core.Configuration} data
12
+ # with the full interface of {::Hash}.
13
+ #
14
+ # All keys are converted to strings.
15
+ #
16
+ class Configuration
17
+ include EmulateHash
18
+ extend Forwardable
19
+
20
+ alias_method :to_map, :properties
21
+ private :to_map
22
+
23
+ # @!visibility private
24
+ def [](key)
25
+ get(key.to_s)
26
+ end
27
+
28
+ # @!visibility private
29
+ def store(key, value)
30
+ put(key.to_s, value)
31
+ end
32
+
33
+ # @!visibility private
34
+ def delete(key)
35
+ key = key.to_s
36
+ return yield(key) if block_given? && !key?(key)
37
+
38
+ remove(key)
39
+ end
40
+
41
+ # @!visibility private
42
+ def key?(key)
43
+ contains_key(key.to_s)
44
+ end
45
+
46
+ # @!visibility private
47
+ def replace(new_pairs)
48
+ set_properties(new_pairs.to_h.transform_keys(&:to_s))
49
+ self
50
+ end
51
+
52
+ # @!visibility private
53
+ alias_method :keys, :key_set
54
+
55
+ # @!visibility private
56
+ def dup
57
+ self.class.new(self)
58
+ end
59
+
60
+ # @!visibility private
61
+ def ==(other)
62
+ if !other.is_a?(self.class) && other.respond_to?(:to_hash)
63
+ return to_hash == other.to_hash.transform_keys(&:to_s)
64
+ end
65
+
66
+ equals(other)
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,241 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ #
8
+ # Make a class acts like a Ruby Hash that supports indifferent keys.
9
+ #
10
+ # Methods that accepts keys will convert symbolic keys to string keys, but only shallowly.
11
+ # This key indifference does not extend to Hash return values, however.
12
+ # Hash return values will behave like a normal Hash
13
+ # which treats symbolic and string keys differently.
14
+ #
15
+ # The including class must implement at least:
16
+ # - `#to_map` to provide the hash-like data
17
+ # - `#replace`
18
+ # - `#store`
19
+ # - Other methods and mutators as applicable to the underlying storage.
20
+ #
21
+ module EmulateHash
22
+ include Enumerable
23
+ extend Forwardable
24
+
25
+ # Methods delegated to to_map
26
+ DELEGATED_METHODS = %i[>
27
+ >=
28
+ <
29
+ <=
30
+ ==
31
+ any?
32
+ compact
33
+ deconstruct_keys
34
+ transform_keys
35
+ to_hash
36
+ length
37
+ size
38
+ compare_by_identity?
39
+ each
40
+ each_key
41
+ each_pair
42
+ each_value
43
+ equals
44
+ empty?
45
+ filter
46
+ flatten
47
+ has_value?
48
+ invert
49
+ key
50
+ keys
51
+ rassoc
52
+ reject
53
+ select
54
+ shift
55
+ to_a
56
+ to_h
57
+ to_hash
58
+ transform_keys
59
+ transform_values
60
+ value?
61
+ values].freeze
62
+ private_constant :DELEGATED_METHODS
63
+
64
+ def_delegators :to_map, *DELEGATED_METHODS
65
+
66
+ def_delegator :to_h, :inspect
67
+
68
+ # @!visibility private
69
+ alias_method :to_s, :inspect
70
+
71
+ # @!visibility private
72
+ def except(*keys)
73
+ to_map.except(*keys.map(&:to_s))
74
+ end
75
+
76
+ # @!visibility private
77
+ def key?(key)
78
+ to_map.key?(key.to_s)
79
+ end
80
+ alias_method :has_key?, :key?
81
+ alias_method :include?, :key?
82
+
83
+ #
84
+ # @see https://ruby-doc.org/core/Hash.html#method-i-merge
85
+ #
86
+ # java.util.Map#merge is incompatible to Ruby's, but JRuby provides #ruby_merge for it
87
+ #
88
+ # @!visibility private
89
+ def merge(*others, &block)
90
+ return self if others.empty?
91
+
92
+ others.map! { |hash| hash.transform_keys(&:to_s) }
93
+ map = to_map
94
+ if map.respond_to?(:ruby_merge)
95
+ map.ruby_merge(*others, &block)
96
+ else
97
+ # fall back to #merge in case #to_map returns a Ruby Hash
98
+ map.merge(*others, &block)
99
+ end
100
+ end
101
+
102
+ # @!visibility private
103
+ def merge!(*others, &block)
104
+ return self if others.empty?
105
+
106
+ replace(merge(*others, &block))
107
+ end
108
+ alias_method :update, :merge!
109
+
110
+ # @!visibility private
111
+ def replace
112
+ raise NotImplementedError
113
+ end
114
+
115
+ # @!visibility private
116
+ def slice(*keys)
117
+ to_map.slice(*keys.map(&:to_s))
118
+ end
119
+
120
+ # @!visibility private
121
+ def fetch(key, *default, &block)
122
+ to_map.fetch(key.to_s, *default, &block)
123
+ end
124
+
125
+ # @!visibility private
126
+ def [](key)
127
+ fetch(key, nil)
128
+ end
129
+
130
+ # @!visibility private
131
+ def store(key, value)
132
+ raise NotImplementedError
133
+ end
134
+
135
+ # @!visibility private
136
+ def []=(key, value)
137
+ store(key, value)
138
+ end
139
+
140
+ # @!visibility private
141
+ def assoc(key)
142
+ to_map.assoc(key.to_s)
143
+ end
144
+
145
+ # @!visibility private
146
+ def clear
147
+ replace({})
148
+ end
149
+
150
+ # @!visibility private
151
+ def dig(key, *keys)
152
+ to_map.dig(key.to_s, *keys)
153
+ end
154
+
155
+ # @!visibility private
156
+ def compact!
157
+ to_h.compact!&.then { |r| replace(r) }
158
+ end
159
+
160
+ # @!visibility private
161
+ def delete_if(&block)
162
+ raise NotImplementedError unless block
163
+
164
+ replace(to_h.delete_if(&block))
165
+ end
166
+
167
+ # @!visibility private
168
+ def keep_if(&block)
169
+ select!(&block)
170
+ self
171
+ end
172
+
173
+ # @!visibility private
174
+ def select!(&block)
175
+ raise NotImplementedError unless block
176
+
177
+ to_h.select!(&block)&.then { |r| replace(r) }
178
+ end
179
+ alias_method :filter!, :select!
180
+
181
+ # @!visibility private
182
+ def reject!(&block)
183
+ raise NotImplementedError unless block
184
+
185
+ to_h.reject!(&block)&.then { |r| replace(r) }
186
+ end
187
+
188
+ # @!visibility private
189
+ def fetch_values(*keys, &block)
190
+ to_map.fetch_values(*keys.map(&:to_s), &block)
191
+ end
192
+
193
+ # @!visibility private
194
+ def transform_keys!(*args, &block)
195
+ replace(transform_keys(*args, &block))
196
+ end
197
+
198
+ # @!visibility private
199
+ def transform_values!(&block)
200
+ raise NotImplementedError unless block
201
+
202
+ replace(transform_values(&block))
203
+ end
204
+
205
+ # @!visibility private
206
+ def values_at(*keys)
207
+ to_map.values_at(*keys.map(&:to_s))
208
+ end
209
+
210
+ # @!visibility private
211
+ def compare_by_identity
212
+ raise NotImplementedError
213
+ end
214
+
215
+ # @!visibility private
216
+ def default=(*)
217
+ raise NotImplementedError
218
+ end
219
+
220
+ # @!visibility private
221
+ def default_proc=(*)
222
+ raise NotImplementedError
223
+ end
224
+
225
+ # @!visibility private
226
+ def default(*)
227
+ nil
228
+ end
229
+
230
+ # @!visibility private
231
+ def default_proc
232
+ nil
233
+ end
234
+
235
+ # @!visibility private
236
+ def to_proc
237
+ ->(k) { self[k] }
238
+ end
239
+ end
240
+ end
241
+ end
@@ -12,6 +12,17 @@ module OpenHAB
12
12
 
13
13
  # @return [String]
14
14
  alias_method :inspect, :to_s
15
+
16
+ #
17
+ # Returns the event payload as a Hash.
18
+ #
19
+ # @return [Hash, nil] The payload object parsed by JSON. The keys are symbolized.
20
+ # `nil` when the payload is empty.
21
+ #
22
+ def payload
23
+ require "json"
24
+ @payload ||= JSON.parse(get_payload, symbolize_names: true) unless get_payload.empty?
25
+ end
15
26
  end
16
27
  end
17
28
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ module Events
6
+ # @deprecated OH3.4 this guard is not needed on OH4
7
+ if Gem::Version.new(OpenHAB::Core::VERSION) >= Gem::Version.new("4.0.0")
8
+ java_import org.openhab.core.automation.events.TimerEvent
9
+
10
+ #
11
+ # Adds methods to core openHAB TimerEvent to make it more natural in Ruby
12
+ #
13
+ # This event can be triggered by a `DateTimeTrigger`, `cron`, or `TimeOfDay` trigger.
14
+ #
15
+ # @since openHAB 4.0
16
+ #
17
+ class TimerEvent < AbstractEvent
18
+ #
19
+ # @!attribute [r] cron_expression
20
+ # @return [String, nil] The cron expression that triggered this event.
21
+ # `nil` when this event wasn't triggered by a cron trigger.
22
+ #
23
+ def cron_expression
24
+ payload&.[](:cronExpression)
25
+ end
26
+
27
+ #
28
+ # @!attribute [r] item
29
+ # @return [Item, nil] The DateTime item that triggered this event.
30
+ # `nil` when this event wasn't triggered by a DateTimeItem trigger.
31
+ #
32
+ def item
33
+ payload&.[](:itemName)&.then { |item_name| EntityLookup.lookup_item(item_name) }
34
+ end
35
+
36
+ #
37
+ # @!attribute [r] time
38
+ # @return [LocalTime, nil] The configured time for this TimeOfDay trigger event.
39
+ # `nil` when this event wasn't triggered by a TimeOfDay trigger.
40
+ #
41
+ def time
42
+ payload&.[](:time)&.then { |time| LocalTime.parse(time) }
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ module Items
6
+ java_import org.openhab.core.items.GroupFunction
7
+
8
+ #
9
+ # Adds `#to_s` and `#inspect` to group function.
10
+ #
11
+ # @example
12
+ # # Group:SWITCH:OR(ON,OFF) Switches
13
+ # logger.info "The Switches group function is: #{Switches.function}" # => "OR"
14
+ # logger.info "The Switches group function: #{Switches.function.inspect}" # => "OR(ON,OFF)"
15
+ #
16
+ module GroupFunction
17
+ #
18
+ # Returns the group function as an uppercase string
19
+ # @return [String]
20
+ #
21
+ def to_s
22
+ self.class.simple_name.upcase
23
+ end
24
+
25
+ #
26
+ # Returns the group function and its parameters as a string
27
+ # @return [String]
28
+ #
29
+ def inspect
30
+ params = parameters.map(&:inspect).join(",")
31
+ params = "(#{params})" unless params.empty?
32
+ "#{self}#{params}"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -143,16 +143,22 @@ module OpenHAB
143
143
  base_item.format_type(command)
144
144
  end
145
145
 
146
+ %w[color contact date_time dimmer image location number player rollershutter string switch].each do |type|
147
+ type_class = type.gsub(/(^[a-z]|_[a-z])/) { |letter| letter[-1].upcase }
148
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
149
+ def #{type}_item? # def date_time_item?
150
+ base_item&.is_a?(#{type_class}Item) # base_item&.is_a?(DateTimeItem)
151
+ end # end
152
+ RUBY
153
+ end
154
+
146
155
  private
147
156
 
148
157
  # Add base type and function details
149
158
  def type_details
150
159
  r = ""
151
160
  r += ":#{base_item.type}#{base_item.__send__(:type_details)}" if base_item
152
- if function && (fn = function.class.java_class.simple_name.upcase) != "EQUALITY"
153
- r += ":#{fn}"
154
- r += "(#{function.parameters.map(&:inspect).join(",")})" unless function.parameters.empty?
155
- end
161
+ r += ":#{function.inspect}" if function && function.to_s != "EQUALITY"
156
162
  r
157
163
  end
158
164
 
@@ -18,6 +18,22 @@ module OpenHAB
18
18
  def ===(other)
19
19
  other.is_a?(self)
20
20
  end
21
+
22
+ private
23
+
24
+ # @!macro def_type_predicate
25
+ # @!method $1_item?
26
+ # Check if the item is a $1 item.
27
+ # @note If the item is a group item, it will also return true if the base item is a $1 item.
28
+ # @return [true,false]
29
+ def def_type_predicate(type)
30
+ type_class = type.to_s.gsub(/(^[a-z]|_[a-z])/) { |letter| letter[-1].upcase }
31
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
32
+ def #{type}_item? # def date_time_item?
33
+ is_a?(#{type_class}Item) # is_a?(DateTimeItem)
34
+ end # end
35
+ RUBY
36
+ end
21
37
  end
22
38
 
23
39
  # @!attribute [r] name
@@ -270,6 +286,21 @@ module OpenHAB
270
286
  Provider.registry.provider_for(self)
271
287
  end
272
288
 
289
+ def_type_predicate(:color)
290
+ def_type_predicate(:contact)
291
+ def_type_predicate(:date_time)
292
+ # @note Color items are also considered dimmer items.
293
+ def_type_predicate(:dimmer)
294
+ def_type_predicate(:group)
295
+ def_type_predicate(:image)
296
+ def_type_predicate(:location)
297
+ def_type_predicate(:number)
298
+ def_type_predicate(:player)
299
+ def_type_predicate(:rollershutter)
300
+ def_type_predicate(:string)
301
+ # @note Color and dimmer items are also considered switch items.
302
+ def_type_predicate(:switch)
303
+
273
304
  private
274
305
 
275
306
  # Allows sub-classes to append additional details to the type in an inspect string