openhab-scripting 5.2.0 → 5.4.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: 3d56223cd6766da527070ec31571d7a22cffa7d69ec754a1a1dbeb06c9354d56
4
- data.tar.gz: c635cf86c119c54c4b665f28cd91b0804a58c868d23f7a99420d4183f60bf195
3
+ metadata.gz: 0522f086fca640c17a05634e13924dd9e39fc0630fba03954d4c0ffcfc1739c7
4
+ data.tar.gz: 9c01b1545d9e999ecc9ff0836691ef858794085ffb09433a3636c7594251e13b
5
5
  SHA512:
6
- metadata.gz: 79e7ac98695e1fb75a6bf100226a555d2d1d8f7a96efa0779b42439e262bfb63777ee99545782885f509c08f21dc77b2b504fd13078a5e5bc1d82ce456e3cca9
7
- data.tar.gz: d735f987f2540cba7b358a4f0550ed723ef807b0a4c5e12ab21177cc844f65a2eec1080778b996e702cd72a5d744b1a7c97fe52ba5679a17a13b4988ccd2bf76
6
+ metadata.gz: c1c7e125bb92764cc330924cacc30b03bf8759633bf34e51000897614af32efa2bcddfd2c48e5514be160d6c2d625eb38449c4d6203c5ca418bf67868d302aa2
7
+ data.tar.gz: 61742a93f67041588c6f6af954f95dd7515d8ee2d913812f5ac32212a8ddc49f979da4712125d1b15ca327b130ec81102308edbe5689f43e386d24b46f185357
@@ -74,19 +74,19 @@ module OpenHAB
74
74
  #
75
75
  # Returns all Scenes (rules tagged with "Scene")
76
76
  #
77
- # @return [Array<Rule>] A list of all the scenes
77
+ # @return [TaggedArray] A list of all the scenes
78
78
  #
79
79
  def scenes
80
- tagged("Scene")
80
+ @scenes ||= TaggedArray.new("Scene")
81
81
  end
82
82
 
83
83
  #
84
84
  # Returns all Scripts (rules tagged with "Script")
85
85
  #
86
- # @return [Array<Rule>] A list of all the scripts
86
+ # @return [TaggedArray] A list of all the scripts
87
87
  #
88
88
  def scripts
89
- tagged("Script")
89
+ @scripts ||= TaggedArray.new("Script")
90
90
  end
91
91
  end
92
92
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "singleton"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Rules
8
+ #
9
+ # Provides access to a set of openHAB {Rule rules}, and acts like an array.
10
+ #
11
+ class TaggedArray
12
+ include LazyArray
13
+
14
+ def initialize(tag)
15
+ @tag = tag
16
+ end
17
+
18
+ #
19
+ # Gets a specific Rule
20
+ #
21
+ # @param [String] uid Rule UID
22
+ # @return [Rule, nil]
23
+ #
24
+ def [](uid)
25
+ rule = $rules.get(uid)
26
+ rule.tagged?(@tag) ? rule : nil
27
+ end
28
+ alias_method :include?, :[]
29
+ alias_method :key?, :[]
30
+ # @deprecated
31
+ alias_method :has_key?, :[]
32
+
33
+ #
34
+ # Explicit conversion to array
35
+ #
36
+ # @return [Array<Rule>]
37
+ #
38
+ def to_a
39
+ $rules.all.to_a.tagged(@tag)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module CoreExt
5
+ module Ruby
6
+ # @!visibility private
7
+ module Object
8
+ class << self
9
+ attr_reader :top_self
10
+ end
11
+
12
+ # @!visibility private
13
+ module ClassMethods
14
+ # capture methods defined at top level (which get added to Object)
15
+ def method_added(method)
16
+ return super unless equal?(::Object)
17
+
18
+ if DSL.private_instance_methods.include?(method)
19
+ # Duplicate methods that conflict with DSL onto `main`'s singleton class,
20
+ # so that they'll take precedence over DSL's method.
21
+ Object.top_self.singleton_class.define_method(method, instance_method(method))
22
+ end
23
+
24
+ super
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -22,6 +22,12 @@ module OpenHAB
22
22
  # group_item Equipment, tags: Semantics::HVAC, thing: "binding:thing"
23
23
  # string_item Mode, tags: Semantics::Control, channel: "mode"
24
24
  # end
25
+ #
26
+ # # dimension Temperature inferred
27
+ # number_item OutdoorTemp, format: "%.1f %unit%", unit: "°F"
28
+ #
29
+ # # unit lx, dimension Illuminance, format "%s %unit%" inferred
30
+ # number_item OutdoorBrightness, state: 10_000 | "lx"
25
31
  # end
26
32
  #
27
33
  module Builder
@@ -156,9 +162,22 @@ module OpenHAB
156
162
  # @return [String, nil]
157
163
  attr_accessor :label
158
164
  # Unit dimension (for number items only)
165
+ #
166
+ # If {unit} is provided, and {dimension} is not, it will be inferred.
167
+ #
159
168
  # @return [String, nil]
160
169
  attr_accessor :dimension
170
+ # Unit (for number items only)
171
+ #
172
+ # Due to {format} inference, setting the unit is cross-compatible with
173
+ # openHAB 3.4 and 4.0.
174
+ #
175
+ # @return [String, nil]
176
+ attr_reader :unit
161
177
  # The formatting pattern for the item's state
178
+ #
179
+ # If {unit} is provided, and {format} is not, it will be inferred.
180
+ #
162
181
  # @return [String, nil]
163
182
  attr_accessor :format
164
183
  # The icon to be associated with the item
@@ -179,13 +198,16 @@ module OpenHAB
179
198
  # @return [Core::Items::Metadata::NamespaceHash]
180
199
  attr_reader :metadata
181
200
  # Initial state
201
+ #
202
+ # If {state} is set to a {QuantityType}, and {unit} is not set, it will be inferred.
203
+ #
182
204
  # @return [Core::Types::State]
183
- attr_accessor :state
205
+ attr_reader :state
184
206
 
185
207
  class << self
186
208
  # @!visibility private
187
209
  def item_factory
188
- @item_factory ||= org.openhab.core.library.CoreItemFactory.new
210
+ @item_factory ||= OpenHAB::OSGi.service("org.openhab.core.items.ItemFactory")
189
211
  end
190
212
 
191
213
  #
@@ -214,6 +236,7 @@ module OpenHAB
214
236
  end
215
237
 
216
238
  # @param dimension [Symbol, nil] The unit dimension for a {NumberItem} (see {ItemBuilder#dimension})
239
+ # @param unit [Symbol, String, nil] The unit for a {NumberItem} (see {ItemBuilder#unit})
217
240
  # @param format [String, nil] The formatting pattern for the item's state (see {ItemBuilder#format})
218
241
  # @param icon [Symbol, nil] The icon to be associated with the item (see {ItemBuilder#icon})
219
242
  # @param group [String,
@@ -246,6 +269,7 @@ module OpenHAB
246
269
  def initialize(type, name = nil, label = nil,
247
270
  provider:,
248
271
  dimension: nil,
272
+ unit: nil,
249
273
  format: nil,
250
274
  icon: nil,
251
275
  group: nil,
@@ -274,6 +298,7 @@ module OpenHAB
274
298
  @label = label
275
299
  @dimension = dimension
276
300
  @format = format
301
+ self.unit = unit
277
302
  @icon = icon
278
303
  @groups = []
279
304
  @tags = []
@@ -291,7 +316,7 @@ module OpenHAB
291
316
  self.alexa(alexa) if alexa
292
317
  self.ga(ga) if ga
293
318
  self.homekit(homekit) if homekit
294
- @state = state
319
+ self.state = state
295
320
 
296
321
  self.group(*group)
297
322
  self.group(*groups)
@@ -434,6 +459,39 @@ module OpenHAB
434
459
  @expire += ",command=#{command}" if command
435
460
  end
436
461
 
462
+ # @!attribute [w] unit
463
+ #
464
+ # Unit (for number items only).
465
+ #
466
+ # If dimension or format are not yet set, they will be inferred.
467
+ #
468
+ # @return [String, nil]
469
+ def unit=(unit)
470
+ @unit = unit
471
+
472
+ self.dimension ||= unit && org.openhab.core.types.util.UnitUtils.parse_unit(unit)&.then do |u|
473
+ org.openhab.core.types.util.UnitUtils.get_dimension_name(u)
474
+ end
475
+ self.format ||= unit && (if Gem::Version.new(Core::VERSION) >= Gem::Version.new("4.0.0.M3")
476
+ "%s %unit%"
477
+ else
478
+ "%s #{unit.gsub("%", "%%")}"
479
+ end)
480
+ end
481
+
482
+ # @!attribute [w] state
483
+ #
484
+ # Initial state
485
+ #
486
+ # If {state} is set to a {QuantityType}, and {unit} is not set, it will be inferred.
487
+ #
488
+ # @return [Core::Types::State]
489
+ def state=(state)
490
+ @state = state
491
+
492
+ self.unit ||= state.unit.to_s if state.is_a?(QuantityType)
493
+ end
494
+
437
495
  # @!visibility private
438
496
  def build
439
497
  item = create_item
@@ -450,6 +508,7 @@ module OpenHAB
450
508
  item.metadata["autoupdate"] = autoupdate.to_s unless autoupdate.nil?
451
509
  item.metadata["expire"] = expire if expire
452
510
  item.metadata["stateDescription"] = { "pattern" => format } if format
511
+ item.metadata["unit"] = unit if unit
453
512
  item.state = item.format_update(state) unless state.nil?
454
513
  item
455
514
  end
@@ -488,6 +547,12 @@ module OpenHAB
488
547
  class GroupItemBuilder < ItemBuilder
489
548
  include Builder
490
549
 
550
+ # This has to be duplicated here, since {Builder} includes DSL, so DSL#unit
551
+ # will be seen first, but we really want ItemBuilder#unit
552
+
553
+ # (see ItemBuilder#unit)
554
+ attr_reader :unit
555
+
491
556
  Builder.public_instance_methods.each do |m|
492
557
  next unless Builder.instance_method(m).owner == Builder
493
558
 
@@ -35,8 +35,7 @@ module OpenHAB
35
35
  super()
36
36
  set_name(config.name)
37
37
  set_description(config.description)
38
- tags = DSL::Items::ItemBuilder.normalize_tags(*config.tags)
39
- set_tags(tags.to_set)
38
+ set_tags(config.tags.to_set)
40
39
  set_triggers(config.triggers)
41
40
  self.uid = config.uid
42
41
  @run_context = config.caller
@@ -104,7 +104,37 @@ module OpenHAB
104
104
  ThreadLocal.thread_local(openhab_rule_type: "script", openhab_rule_uid: id) do
105
105
  builder = BuilderDSL.new(block.binding)
106
106
  builder.uid(id)
107
- builder.tags(["Script"])
107
+ builder.tags("Script")
108
+ builder.name(name)
109
+ builder.script(&block)
110
+ logger.trace { builder.inspect }
111
+ builder.build(provider, script)
112
+ end
113
+ end
114
+
115
+ #
116
+ # Create a new scene
117
+ #
118
+ # A scene is a rule with no triggers. It can be called by various other actions,
119
+ # such as the Run Rules action.
120
+ #
121
+ # @param [String] name A descriptive name
122
+ # @param [String] id The script's ID
123
+ # @yield [] Block executed when the script is executed.
124
+ # @return [Core::Rules::Rule]
125
+ #
126
+ def scene(name = nil, id: nil, script: nil, &block)
127
+ raise ArgumentError, "Block is required" unless block
128
+
129
+ id ||= NameInference.infer_rule_id_from_block(block)
130
+ name ||= id
131
+ script ||= block.source rescue nil # rubocop:disable Style/RescueModifier
132
+
133
+ builder = nil
134
+ ThreadLocal.thread_local(openhab_rule_type: "script", openhab_rule_uid: id) do
135
+ builder = BuilderDSL.new(block.binding)
136
+ builder.uid(id)
137
+ builder.tags("Scene")
108
138
  builder.name(name)
109
139
  builder.script(&block)
110
140
  logger.trace { builder.inspect }
@@ -354,7 +384,7 @@ module OpenHAB
354
384
  prop :description
355
385
 
356
386
  #
357
- # @!method tags(tags)
387
+ # @!method tags(*tags)
358
388
  #
359
389
  # Set the rule's tags.
360
390
  #
@@ -1082,6 +1112,7 @@ module OpenHAB
1082
1112
 
1083
1113
  raise ArgumentError, "Missing cron expression or elements" unless expression
1084
1114
 
1115
+ add_tag("Schedule")
1085
1116
  cron = Cron.new(rule_triggers: @rule_triggers)
1086
1117
  cron.trigger(config: { "cronExpression" => expression }, attach: attach)
1087
1118
  end
@@ -1180,6 +1211,7 @@ module OpenHAB
1180
1211
  if value == :day && at.is_a?(Item)
1181
1212
  raise ArgumentError, "Attachments are not supported with dynamic datetime triggers" unless attach.nil?
1182
1213
 
1214
+ add_tag("Schedule")
1183
1215
  return trigger("timer.DateTimeTrigger", itemName: at.name, timeOnly: true)
1184
1216
  end
1185
1217
 
@@ -1561,6 +1593,7 @@ module OpenHAB
1561
1593
  #
1562
1594
  def at(item)
1563
1595
  item = item.name if item.is_a?(Item)
1596
+ add_tag("Schedule")
1564
1597
  trigger("timer.DateTimeTrigger", itemName: item.to_s)
1565
1598
  end
1566
1599
 
@@ -1847,6 +1880,15 @@ module OpenHAB
1847
1880
 
1848
1881
  private
1849
1882
 
1883
+ # Adds a single tag to this rule
1884
+ # @param [String] tag The tag (it will not be normalized)
1885
+ # @return [void]
1886
+ def add_tag(tag)
1887
+ # have to normalize tags first
1888
+ @tags = DSL::Items::ItemBuilder.normalize_tags(*tags)
1889
+ @tags << tag unless @tags.include?(tag)
1890
+ end
1891
+
1850
1892
  # Calls the on_load block, with a delay if specified
1851
1893
  # @yield block to execute on load time
1852
1894
  # @yieldparam [String] module The module ID that identifies this on_load event
@@ -1871,7 +1913,8 @@ module OpenHAB
1871
1913
  # @return [true,false] true if it should be created, false otherwise
1872
1914
  #
1873
1915
  def create_rule?
1874
- return true if tags.include?("Script")
1916
+ @tags = DSL::Items::ItemBuilder.normalize_tags(*tags)
1917
+ return true unless (tags & %w[Script Scene]).empty?
1875
1918
 
1876
1919
  if !triggers?
1877
1920
  logger.warn "Rule '#{uid}' has no triggers, not creating rule"
@@ -51,7 +51,7 @@ module OpenHAB
51
51
  # @return [CronAdjuster]
52
52
  #
53
53
  def getTemporalAdjuster # rubocop:disable Naming/MethodName
54
- org.openhab.core.scheduler.CronAdjuster.new(expression)
54
+ org.openhab.core.scheduler.CronAdjuster.new(@expression)
55
55
  end
56
56
 
57
57
  #
@@ -4,6 +4,6 @@ module OpenHAB
4
4
  module DSL
5
5
  # Version of openHAB helper libraries
6
6
  # @return [String]
7
- VERSION = "5.2.0"
7
+ VERSION = "5.4.0"
8
8
  end
9
9
  end
data/lib/openhab/dsl.rb CHANGED
@@ -59,6 +59,11 @@ module OpenHAB
59
59
  rules.build { rule(name, **kwargs, &block) }
60
60
  end
61
61
 
62
+ # (see Rules::Builder#scene)
63
+ def scene(name = nil, id: nil, **kwargs, &block)
64
+ rules.build { scene(name, id: id, **kwargs, &block) }
65
+ end
66
+
62
67
  # (see Rules::Builder#script)
63
68
  def script(name = nil, id: nil, **kwargs, &block)
64
69
  rules.build { script(name, id: id, **kwargs, &block) }
@@ -975,5 +980,8 @@ OpenHAB::Core::Items.import_into_global_namespace
975
980
 
976
981
  # Extend `main` with DSL methods
977
982
  singleton_class.include(OpenHAB::DSL)
983
+ # Patch Object to work around https://github.com/openhab/openhab-jruby/issues/4
984
+ Object.extend(OpenHAB::CoreExt::Ruby::Object::ClassMethods)
985
+ OpenHAB::CoreExt::Ruby::Object.instance_variable_set(:@top_self, self)
978
986
 
979
987
  logger.debug "openHAB JRuby Scripting Library Version #{OpenHAB::DSL::VERSION} Loaded"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openhab-scripting
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.0
4
+ version: 5.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian O'Connell
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-05-02 00:00:00.000000000 Z
13
+ date: 2023-06-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -447,6 +447,7 @@ files:
447
447
  - lib/openhab/core/rules/provider.rb
448
448
  - lib/openhab/core/rules/registry.rb
449
449
  - lib/openhab/core/rules/rule.rb
450
+ - lib/openhab/core/rules/tagged_array.rb
450
451
  - lib/openhab/core/script_handling.rb
451
452
  - lib/openhab/core/things.rb
452
453
  - lib/openhab/core/things/channel.rb
@@ -504,6 +505,7 @@ files:
504
505
  - lib/openhab/core_ext/ruby/date_time.rb
505
506
  - lib/openhab/core_ext/ruby/module.rb
506
507
  - lib/openhab/core_ext/ruby/numeric.rb
508
+ - lib/openhab/core_ext/ruby/object.rb
507
509
  - lib/openhab/core_ext/ruby/range.rb
508
510
  - lib/openhab/core_ext/ruby/symbol.rb
509
511
  - lib/openhab/core_ext/ruby/time.rb