openhab-scripting 5.0.0 → 5.1.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: 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