openhab-scripting 5.0.0 → 5.1.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: a2826f669c876cc9b59863c2107bc8b1af62327d22c4551ef062f1b7bc97aabb
4
- data.tar.gz: 61bd119ddc94019361d0150ed8bc1e92b5b42de9f610599f1305fbf04055cb14
3
+ metadata.gz: b5064300df1e62e03270a15425080c31ce101bb688c8f91f9f0fa0393f7a1f4c
4
+ data.tar.gz: 8ff582399587b468ac80d525f55648ab997e2d866b7d6b2bf8fc9715171f138e
5
5
  SHA512:
6
- metadata.gz: 0bf813e7b4aba75c75979c05fc317982dfb1ca94b0eae9de656ed342b1861b293ebb8912ed7935ba709b90506a169be6013b92278281ab4dafdb3205e215f927
7
- data.tar.gz: 74a35427271bcae3fd179c3ffd1710f145457e8ae1010481b27310aa28bf710c359f784c6893ed630f2737f1f029c43b7c5f925ceed7cb119239c7cfe77a77e7
6
+ metadata.gz: cd9c5fcfd966a435ac782e3c2cb00e0b7e10e3c3e22fb64c83ce674da9f1476a92c1072df8d44aab536f6ee774ed6ba0960160d09b554b5d9728e669855fdcfb
7
+ data.tar.gz: a88bd0a48d8740d04874fdc2a5ae7de454ed17d363bedb653ebc57cf818e2818d03675cdf47a033ac037400e5a0d3988b6ead3be4c63a816c01f12c3a1103d8c
@@ -23,7 +23,14 @@ 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
- playSound(sink&.to_s, filename.to_s, volume)
26
+ # JRuby calls the wrong overloaded method when volume is given, but sink is nil
27
+ # will call playSound(String, String, float) instead of playSound(String, String, PercentType)
28
+ # and end up with argument type mismatched. So we need to give it a bit of help here.
29
+ if sink
30
+ playSound(sink.to_s, filename.to_s, volume)
31
+ else
32
+ playSound(filename.to_s, volume)
33
+ end
27
34
  end
28
35
 
29
36
  #
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "item_state_event"
4
+
5
+ module OpenHAB
6
+ module Core
7
+ module Events
8
+ begin
9
+ java_import org.openhab.core.items.events.ItemStateUpdatedEvent
10
+
11
+ #
12
+ # {AbstractEvent} sent when an item's state has updated.
13
+ #
14
+ class ItemStateUpdatedEvent < ItemEvent
15
+ include ItemState
16
+ end
17
+ rescue NameError
18
+ # @deprecated OH3.4 OH3 will raise an error ItemStateUpdatedEvent is only in OH4
19
+ end
20
+ end
21
+ end
22
+ end
@@ -77,7 +77,7 @@ module OpenHAB
77
77
  #
78
78
  # This may include running a transformation.
79
79
  #
80
- # @return [String]
80
+ # @return [String] The formatted state
81
81
  #
82
82
  # @example
83
83
  # logger.info(Exterior_WindDirection.formatted_state) # => "NE (36°)"
@@ -92,7 +92,9 @@ module OpenHAB
92
92
  transformed_state_string = org.openhab.core.transform.TransformationHelper.transform(OSGi.bundle_context,
93
93
  pattern,
94
94
  raw_state_string)
95
- return state.format(pattern) if transformed_state_string.nil? || transformed_state_string == raw_state_string
95
+ if transformed_state_string.nil? || transformed_state_string == raw_state_string
96
+ return state&.format(pattern) || raw_state_string
97
+ end
96
98
 
97
99
  transformed_state_string
98
100
  rescue org.openhab.core.transform.TransformationException
@@ -60,6 +60,12 @@ module OpenHAB
60
60
  # and {#property_type}. They can even be used with
61
61
  # {DSL::Items::ItemBuilder#tag}.
62
62
  #
63
+ # The semantic constants in the `Semantics` module are enhanced with {TagClassMethods}
64
+ # to provide easy access to the tags' additional attributes: {TagClassMethods.label label},
65
+ # {TagClassMethods.synonyms synonyms}, and {TagClassMethods.description description}.
66
+ # For example, to get the synonyms for `Semantics::Lightbulb` in German:
67
+ # `Semantics::Lightbulb.synonyms(java.util.Locale::GERMAN)`
68
+ #
63
69
  # @see https://github.com/openhab/openhab-core/blob/main/bundles/org.openhab.core.semantics/model/SemanticTags.csv Semantic Tags Table
64
70
  #
65
71
  # @example Working with tags
@@ -156,6 +162,12 @@ module OpenHAB
156
162
  # # All items tagged "SmartLightControl"
157
163
  # items.tagged("SmartLightControl")
158
164
  #
165
+ # ## Adding Custom Semantic Tags
166
+ #
167
+ # openHAB 4 supports adding custom semantic tags to augment the standard set of tags to better suit
168
+ # your particular requirements.
169
+ #
170
+ # For more information, see {add}
159
171
  #
160
172
  module Semantics
161
173
  GenericItem.include(self)
@@ -188,15 +200,6 @@ module OpenHAB
188
200
  # end
189
201
  #
190
202
 
191
- # import all the semantics constants
192
- [org.openhab.core.semantics.model.point.Points,
193
- org.openhab.core.semantics.model.property.Properties,
194
- org.openhab.core.semantics.model.equipment.Equipments,
195
- org.openhab.core.semantics.model.location.Locations].each do |parent_tag|
196
- parent_tag.stream.for_each do |tag|
197
- const_set(tag.simple_name.to_sym, tag.ruby_class)
198
- end
199
- end
200
203
  # This is a marker interface for all semantic tag classes.
201
204
  # @interface
202
205
  Tag = org.openhab.core.semantics.Tag
@@ -390,6 +393,165 @@ module OpenHAB
390
393
  result.delete(self)
391
394
  result
392
395
  end
396
+
397
+ # @deprecated OH3.4 - this check is only needed for OH3.4
398
+ if org.openhab.core.semantics.SemanticTags.respond_to?(:add)
399
+
400
+ #
401
+ # Adds custom semantic tags.
402
+ #
403
+ # @return [Array<Tag>] An array of tags successfully added.
404
+ #
405
+ # @overload self.add(**tags)
406
+ # Quickly add one or more semantic tags using the default label, empty synonyms and descriptions.
407
+ #
408
+ # @param [kwargs] **tags Exactly one pair of `tag` => `parent` where tag is either a Symbol or a String
409
+ # for the tag to be added, and parent is either a {Tag}, a symbol or a string of an existing tag.
410
+ # @return [Array<Tag>] An array of tags successfully added.
411
+ #
412
+ # @example Add one semantic tag `Balcony` whose parent is `Semantics::Outdoor` (Location)
413
+ # Semantics.add(Balcony: Semantics::Outdoor)
414
+ #
415
+ # @example Add multiple semantic tags
416
+ # Semantics.add(Balcony: Semantics::Outdoor,
417
+ # SecretRoom: Semantics::Room,
418
+ # Motion: Semantics::Property)
419
+ #
420
+ # @overload self.add(label: nil, synonyms: "", description: "", **tags)
421
+ # Add a custom semantic tag with extra details.
422
+ #
423
+ # @example
424
+ # Semantics.add(SecretRoom: Semantics::Room, label: "My Secret Room",
425
+ # synonyms: "HidingPlace", description: "A room that requires a special trick to enter")
426
+ #
427
+ # @param [String,nil] label Optional label. When nil, infer the label from the tag name,
428
+ # converting `CamelCase` to `Camel Case`
429
+ # @param [String,Array<String,Symbol>] synonyms An array of synonyms, or a string containing a
430
+ # comma separated list of synonyms for this tag.
431
+ # @param [String] description A longer description of the tag.
432
+ # @param [kwargs] **tags Exactly one pair of `tag` => `parent` where tag is either a Symbol or a String
433
+ # for the tag to be added, and parent is either a {Tag}, a symbol or a string of an existing tag.
434
+ # @return [Array<Tag>] An array of tags successfully added.
435
+ #
436
+ def self.add(label: nil, synonyms: "", description: "", **tags)
437
+ raise "Tags must be specified" if tags.empty?
438
+ if (tags.length > 1) && !(label.nil? && synonyms.empty? && description.empty?)
439
+ raise "Additional options can only be specified when creating one tag"
440
+ end
441
+
442
+ synonyms = synonyms.map(&:to_s).map(&:strip).join(",") if synonyms.is_a?(Array)
443
+
444
+ tags.map do |name, parent|
445
+ parent_is_tag = parent.respond_to?(:java_class) && parent.java_class < Tag.java_class
446
+ parent = parent_is_tag ? parent.java_class : parent.to_s
447
+ name = name.to_s
448
+ org.openhab.core.semantics.SemanticTags.add(name, parent, label, synonyms, description)
449
+ &.then { const_missing(name) }
450
+ end.compact
451
+ end
452
+ end
453
+
454
+ #
455
+ # Returns all available Semantic tags
456
+ #
457
+ # @return [Array<Tag>] an array containing all the Semantic tags
458
+ #
459
+ def self.tags
460
+ java.util.stream.Stream.of(
461
+ org.openhab.core.semantics.model.point.Points.stream,
462
+ org.openhab.core.semantics.model.property.Properties.stream,
463
+ org.openhab.core.semantics.model.equipment.Equipments.stream,
464
+ org.openhab.core.semantics.model.location.Locations.stream
465
+ ).flat_map(&:itself).map(&:ruby_class).iterator.to_a
466
+ end
467
+
468
+ #
469
+ # Finds the semantic tag using its name, label, or synonyms.
470
+ #
471
+ # @param [String,Symbol] id The tag name, label, or synonym to look up
472
+ # @param [java.util.Locale] locale The locale of the given label or synonym
473
+ #
474
+ # @return [Tag,nil] The semantic tag class if found, or nil if not found.
475
+ #
476
+ def self.lookup(id, locale = nil)
477
+ id = id.to_sym
478
+ return const_get(id) if constants.include?(id) || const_missing(id)
479
+
480
+ locale = java.util.Locale.default if locale.nil?
481
+ org.openhab.core.semantics.SemanticTags.get_by_label_or_synonym(id.to_s, locale).first&.ruby_class
482
+ end
483
+
484
+ #
485
+ # Automatically looks up new semantic classes and adds them as `constants`
486
+ #
487
+ # @return [Tag, nil]
488
+ #
489
+ # @!visibility private
490
+ def self.const_missing(sym)
491
+ logger.trace("const missing, performing Semantics Lookup for: #{sym}")
492
+ # @deprecated OH3.4 - the Property tag had an ID of "MeasurementProperty" in OH3.4. This was corrected in OH4.
493
+ sym = :MeasurementProperty if sym == :Property && Gem::Version.new(Core::VERSION) < Gem::Version.new("4.0.0")
494
+
495
+ org.openhab.core.semantics.SemanticTags.get_by_id(sym.to_s)
496
+ &.then do |tag|
497
+ tag = tag.ruby_class
498
+ tag.singleton_class.include(TagClassMethods)
499
+ const_set(sym, tag)
500
+ end
501
+ end
502
+
503
+ #
504
+ # Adds tag attributes to the semantic tag class
505
+ #
506
+ module TagClassMethods
507
+ # @!visibility private
508
+ java_import org.openhab.core.semantics.SemanticTags
509
+
510
+ #
511
+ # Returns the tag's label
512
+ #
513
+ # @param [java.util.Locale] locale The locale that the label should be in, if available.
514
+ # When nil, the system's default locale is used.
515
+ #
516
+ # @return [String] The tag's label
517
+ #
518
+ def label(locale = nil)
519
+ SemanticTags.get_label(java_class, locale || java.util.Locale.default)
520
+ end
521
+
522
+ #
523
+ # Returns the tag's synonyms
524
+ #
525
+ # @param [java.util.Locale] locale The locale that the label should be in, if available.
526
+ # When nil, the system's default locale is used.
527
+ #
528
+ # @return [Array<String>] The list of synonyms in the requested locale.
529
+ #
530
+ def synonyms(locale = nil)
531
+ unless SemanticTags.respond_to?(:get_synonyms) # @deprecated OH3.4
532
+ return java_class.get_annotation(org.openhab.core.semantics.TagInfo.java_class).synonyms
533
+ .split(",").map(&:strip)
534
+ end
535
+
536
+ SemanticTags.get_synonyms(java_class, locale || java.util.Locale.default).to_a
537
+ end
538
+
539
+ #
540
+ # Returns the tag's description
541
+ #
542
+ # @param [java.util.Locale] locale The locale that the description should be in, if available.
543
+ # When nil, the system's default locale is used.
544
+ #
545
+ # @return [String] The tag's description
546
+ #
547
+ def description(locale = nil)
548
+ unless SemanticTags.respond_to?(:get_description) # @deprecated OH3.4
549
+ return java_class.get_annotation(org.openhab.core.semantics.TagInfo.java_class).description
550
+ end
551
+
552
+ SemanticTags.get_description(java_class, locale || java.util.Locale.default)
553
+ end
554
+ end
393
555
  end
394
556
  end
395
557
  end
@@ -454,7 +616,8 @@ module Enumerable
454
616
  end
455
617
  unless point_or_property_types.all? do |tag|
456
618
  tag.is_a?(Module) &&
457
- (tag < Semantics::Point || tag < Semantics::Property)
619
+ (tag < Semantics::Point ||
620
+ tag < Semantics::Property)
458
621
  end
459
622
  raise ArgumentError, "point_or_property_types must all be a subclass of Point or Property"
460
623
  end
@@ -70,6 +70,24 @@ module OpenHAB
70
70
 
71
71
  provider.remove(rule_uid)
72
72
  end
73
+
74
+ #
75
+ # Returns all Scenes (rules tagged with "Scene")
76
+ #
77
+ # @return [Array<Rule>] A list of all the scenes
78
+ #
79
+ def scenes
80
+ tagged("Scene")
81
+ end
82
+
83
+ #
84
+ # Returns all Scripts (rules tagged with "Script")
85
+ #
86
+ # @return [Array<Rule>] A list of all the scripts
87
+ #
88
+ def scripts
89
+ tagged("Script")
90
+ end
73
91
  end
74
92
  end
75
93
  end
@@ -11,6 +11,15 @@ module OpenHAB
11
11
  # met, enabling the core dynamic functionality of openHAB.
12
12
  #
13
13
  module Rule
14
+ # @!attribute [r] name
15
+ # @return [String,nil] The rule's human-readable name
16
+
17
+ # @!attribute [r] description
18
+ # @return [String,nil] The rule's description
19
+
20
+ # @!attribute [r] tags
21
+ # @return [Array<Tag>] The rule's list of tags
22
+
14
23
  #
15
24
  # @!method visible?
16
25
  # Check if visibility == `VISIBLE`
@@ -102,12 +111,27 @@ module OpenHAB
102
111
  info.nil? || info.status_detail == RuleStatusDetail::DISABLED
103
112
  end
104
113
 
114
+ #
115
+ # Checks if this rule has at least one of the given tags.
116
+ #
117
+ # (see Items::Item#tagged)
118
+ #
119
+ # @example Find rules tagged with "Halloween"
120
+ # rules.tagged?("Halloweed")
121
+ #
122
+ def tagged?(*tags)
123
+ tags.map! do |tag|
124
+ tag.is_a?(::Module) ? tag.simple_name : tag # ::Module to distinguish against Rule::Module!
125
+ end
126
+ !(self.tags.to_a & tags).empty?
127
+ end
128
+
105
129
  #
106
130
  # @!attribute [r] status
107
- # @return [RuleStatus nil]
131
+ # @return [RuleStatus, nil]
108
132
  #
109
133
  def status
110
- Rules.manager.get_status(uid)
134
+ Rules.manager&.get_status(uid)
111
135
  end
112
136
 
113
137
  #
@@ -115,7 +139,7 @@ module OpenHAB
115
139
  # @return [RuleStatusInfo, nil]
116
140
  #
117
141
  def status_info
118
- Rules.manager.get_status_info(uid)
142
+ Rules.manager&.get_status_info(uid)
119
143
  end
120
144
 
121
145
  # @return [String]
@@ -76,8 +76,10 @@ module OpenHAB
76
76
  # This method gets called in rspec's SuspendRules as well
77
77
  def execute!(mod, inputs)
78
78
  ThreadLocal.thread_local(**@thread_locals) do
79
- logger.trace { "Execute called with mod (#{mod&.to_string}) and inputs (#{inputs.inspect})" }
80
- logger.trace { "Event details #{inputs["event"].inspect}" } if inputs&.key?("event")
79
+ if logger.trace?
80
+ logger.trace("Execute called with mod (#{mod&.to_string}) and inputs (#{inputs.inspect})")
81
+ logger.trace("Event details #{inputs["event"].inspect}") if inputs&.key?("event")
82
+ end
81
83
  trigger_conditions(inputs).process(mod: mod, inputs: inputs) do
82
84
  event = extract_event(inputs)
83
85
  @debouncer.call { process_queue(create_queue(event), mod, event) }
@@ -4,6 +4,6 @@ module OpenHAB
4
4
  module DSL
5
5
  # Version of openHAB helper libraries
6
6
  # @return [String]
7
- VERSION = "5.0.0"
7
+ VERSION = "5.1.0"
8
8
  end
9
9
  end
data/lib/openhab/dsl.rb CHANGED
@@ -127,7 +127,7 @@ module OpenHAB
127
127
  # # strip the unit from the command, as the binding likely can't handle it
128
128
  # next true unless command.is_a?(QuantityType)
129
129
  #
130
- # callback.send_command(DecimalType.new(command.to_d))
130
+ # callback.handle_command(DecimalType.new(command.to_d))
131
131
  # false
132
132
  # else
133
133
  # true # pass other events through as normal
@@ -500,7 +500,7 @@ module OpenHAB
500
500
  # @example Prevent door bell from ringing repeatedly
501
501
  # # This can be called from a UI rule.
502
502
  # # For file based rule, use the `only_every` rule guard
503
- # only_every(30.seconds) do { Audio.play_sound("doorbell.mp3") }
503
+ # only_every(30.seconds) { Audio.play_sound("doorbell.mp3") }
504
504
  #
505
505
  # @see Rules::BuilderDSL#debounce_for Rule builder's debounce_for for a detailed description
506
506
  # @see Rules::BuilderDSL#only_every
@@ -777,7 +777,7 @@ module OpenHAB
777
777
  # Sets the implicit provider(s) for operations inside the block.
778
778
  #
779
779
  # @param (see #provider!)
780
- # @yield [] The block will be executed in the context of the specified unit(s).
780
+ # @yield [] The block will be executed using the specified provider(s).
781
781
  # @return [Object] the result of the block
782
782
  #
783
783
  # @example
@@ -793,11 +793,11 @@ module OpenHAB
793
793
  # @see provider!
794
794
  # @see OpenHAB::Core::Provider.current Provider.current for how the current provider is calculated
795
795
  #
796
- def provider(*args, **kwargs)
796
+ def provider(*providers, **providers_by_type)
797
797
  raise ArgumentError, "You must give a block to set the provider for the duration of" unless block_given?
798
798
 
799
799
  begin
800
- old_providers = provider!(*args, **kwargs)
800
+ old_providers = provider!(*providers, **providers_by_type)
801
801
  yield
802
802
  ensure
803
803
  Thread.current[:openhab_providers] = old_providers
@@ -127,7 +127,7 @@ module OpenHAB
127
127
  last_index = item_history.bsearch_index do |i|
128
128
  i.timestamp.compare_to(filter.end_date).positive?
129
129
  end
130
- return if last_index.zero?
130
+ return if last_index&.zero?
131
131
 
132
132
  last_index ||= item_history.length
133
133
  end
@@ -45,7 +45,7 @@ module OpenHAB
45
45
  html.css("h1, h2, h3, h4, h5, h6").each do |header|
46
46
  next if header["id"]
47
47
 
48
- id = header.text.strip.downcase.delete(%(.?"')).tr(" ", "-")
48
+ id = header.text.strip.downcase.delete(%(.?"')).gsub(/[ ,]+/, "-")
49
49
  header["id"] = id
50
50
  header.prepend_child(%(<a href="##{id}" class="header-anchor">#</a>))
51
51
  end
@@ -52,6 +52,9 @@ module OpenHAB
52
52
  end
53
53
  end
54
54
 
55
+ # Remove the "omit from toc" comments
56
+ result.gsub!(" <!-- omit from toc -->", "")
57
+
55
58
  # re-link files in docs/*.md. They're written so they work on github without any
56
59
  # processing
57
60
  result.gsub!(%r{\[([A-Za-z0-9,. ]+)\]\(([A-Za-z0-9./-]+)\)}) do |str|
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.0.0
4
+ version: 5.1.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-03-08 00:00:00.000000000 Z
13
+ date: 2023-04-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -96,6 +96,20 @@ dependencies:
96
96
  - - "~>"
97
97
  - !ruby/object:Gem::Version
98
98
  version: '1.2'
99
+ - !ruby/object:Gem::Dependency
100
+ name: faraday-retry
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: '2.1'
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - "~>"
111
+ - !ruby/object:Gem::Version
112
+ version: '2.1'
99
113
  - !ruby/object:Gem::Dependency
100
114
  name: gem-release
101
115
  requirement: !ruby/object:Gem::Requirement
@@ -110,6 +124,20 @@ dependencies:
110
124
  - - "~>"
111
125
  - !ruby/object:Gem::Version
112
126
  version: '2.2'
127
+ - !ruby/object:Gem::Dependency
128
+ name: github_changelog_generator
129
+ requirement: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - "~>"
132
+ - !ruby/object:Gem::Version
133
+ version: '1.16'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - "~>"
139
+ - !ruby/object:Gem::Version
140
+ version: '1.16'
113
141
  - !ruby/object:Gem::Dependency
114
142
  name: guard-rubocop
115
143
  requirement: !ruby/object:Gem::Requirement
@@ -379,6 +407,7 @@ files:
379
407
  - lib/openhab/core/events/item_event.rb
380
408
  - lib/openhab/core/events/item_state_changed_event.rb
381
409
  - lib/openhab/core/events/item_state_event.rb
410
+ - lib/openhab/core/events/item_state_updated_event.rb
382
411
  - lib/openhab/core/events/thing_status_info_event.rb
383
412
  - lib/openhab/core/items.rb
384
413
  - lib/openhab/core/items/accepted_data_types.rb