openhab-scripting 5.36.2 → 5.38.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.
@@ -1059,7 +1059,11 @@ module OpenHAB
1059
1059
  # {Core::Events::ThingStatusInfoChangedEvent} depending on if the
1060
1060
  # triggering element was an item or a thing.
1061
1061
  #
1062
- # @param [Item, GroupItem::Members, Thing, ThingUID, Things::Registry] items Objects to create trigger for.
1062
+ # @param [Item, GroupItem::Members, Thing, ThingUID, Things::Registry, String] items
1063
+ # Objects to create trigger for.
1064
+ # When a String is provided, it is assumed to be an item or group name, unless when it
1065
+ # contains a colon, in which case it is assumed to be a thing UID.
1066
+ # The String may contain `*` and `?` wildcards since openHAB 5.0.
1063
1067
  # @param [State, Array<State>, #===, nil] from
1064
1068
  # Only execute rule if previous state matches `from` state(s).
1065
1069
  # @param [State, Array<State>, #===, nil] to
@@ -1149,11 +1153,25 @@ module OpenHAB
1149
1153
  # @example Trigger when any Thing changes status
1150
1154
  # rule "Thing status monitoring" do
1151
1155
  # changed things, to: :offline
1156
+ # # Alternatively, you can use the following:
1157
+ # # changed "*:*", to: :offline
1152
1158
  # run do |event|
1153
1159
  # Notification.send("Thing #{event.thing.uid} is offline")
1154
1160
  # end
1155
1161
  # end
1156
1162
  #
1163
+ # @example Use Item wildcards (since openHAB 5.0)
1164
+ # rule "Execute rule when the state of a matching item changed" do
1165
+ # changed "*_Door", to: OPEN
1166
+ # run { |event| logger.info("Item #{event.item.name} changed to #{event.state}") }
1167
+ # end
1168
+ #
1169
+ # @example Use Thing wildcards (since openHAB 5.0)
1170
+ # rule "Execute rule when a matching thing changed status" do
1171
+ # changed "mqtt:topic:*light*", to: :online
1172
+ # run { |event| logger.info("Thing #{event.thing.uid} changed to #{event.status}") }
1173
+ # end
1174
+ #
1157
1175
  # @example Real World Example
1158
1176
  # rule "Log (or notify) when an exterior door is left open for more than 5 minutes" do
1159
1177
  # changed ExteriorDoors.members, to: OPEN, for: 5.minutes
@@ -1175,11 +1193,12 @@ module OpenHAB
1175
1193
  Core::Things::ThingUID,
1176
1194
  Core::Things::Registry,
1177
1195
  Core::Items::Item,
1178
- Core::Items::GroupItem::Members
1196
+ Core::Items::GroupItem::Members,
1197
+ String
1179
1198
  nil
1180
1199
  else
1181
1200
  raise ArgumentError,
1182
- "items must be an Item, GroupItem::Members, Thing, ThingUID, or Things::Registry"
1201
+ "items must be an Item, GroupItem::Members, Thing, ThingUID, Things::Registry, or a String"
1183
1202
  end
1184
1203
 
1185
1204
  logger.trace { "Creating changed trigger for entity(#{item}), to(#{to.inspect}), from(#{from.inspect})" }
@@ -1531,7 +1550,10 @@ module OpenHAB
1531
1550
  # The `event` passed to run blocks will be an
1532
1551
  # {Core::Events::ItemCommandEvent}.
1533
1552
  #
1534
- # @param [Item, GroupItem::Members] items Items to create trigger for
1553
+ # @param [Item, GroupItem::Members, String] items
1554
+ # Items to create trigger for.
1555
+ # When a String is provided, it is assumed to be an item or group name.
1556
+ # The String may contain `*` and `?` wildcards since openHAB 5.0.
1535
1557
  # @param [Core::Types::Command, Array<Core::Types::Command>, #===, nil] command commands to match for trigger
1536
1558
  # @param [Array<Core::Types::Command>, #===, nil] commands Fluent alias for `command`
1537
1559
  # @param [Object] attach object to be attached to the trigger
@@ -1597,6 +1619,12 @@ module OpenHAB
1597
1619
  # run { |event| logger.info("Item received command: #{event.command}" ) }
1598
1620
  # end
1599
1621
  #
1622
+ # @example Use Item wildcards (since openHAB 5.0)
1623
+ # rule 'Execute rule when the matching item received command' do
1624
+ # received_command '*_Light', command: ON
1625
+ # run { |event| logger.info("Item received command: #{event.command}") }
1626
+ # end
1627
+ #
1600
1628
  def received_command(*items, command: nil, commands: nil, attach: nil)
1601
1629
  command_trigger = Command.new(rule_triggers: @rule_triggers)
1602
1630
 
@@ -1610,10 +1638,11 @@ module OpenHAB
1610
1638
  items.each do |item|
1611
1639
  case item
1612
1640
  when Core::Items::Item,
1613
- Core::Items::GroupItem::Members
1641
+ Core::Items::GroupItem::Members,
1642
+ String
1614
1643
  nil
1615
1644
  else
1616
- raise ArgumentError, "items must be an Item or GroupItem::Members"
1645
+ raise ArgumentError, "items must be an Item, GroupItem::Members, or a String"
1617
1646
  end
1618
1647
  commands.each do |cmd|
1619
1648
  logger.trace { "Creating received command trigger for items #{item.inspect} and commands #{cmd.inspect}" }
@@ -1888,8 +1917,11 @@ module OpenHAB
1888
1917
  # {Core::Events::ThingStatusInfoEvent} depending on if the triggering
1889
1918
  # element was an item or a thing.
1890
1919
  #
1891
- # @param [Item, GroupItem::Members, Thing] items
1920
+ # @param [Item, GroupItem::Members, Thing, String] items
1892
1921
  # Objects to create trigger for.
1922
+ # When a String is provided, it is assumed to be an item or group name, unless when it
1923
+ # contains a colon, in which case it is assumed to be a thing UID.
1924
+ # The String may contain `*` and `?` wildcards since openHAB 5.0.
1893
1925
  # @param [State, Array<State>, Symbol, String, #===, nil] to
1894
1926
  # Only execute rule if the state matches `to` state(s). If the
1895
1927
  # updated element is a {Core::Things::Thing}, the `to` accepts
@@ -1964,6 +1996,19 @@ module OpenHAB
1964
1996
  # run { |event| logger.info("Thing #{event.uid} status <trigger> to #{event.status}") }
1965
1997
  # end
1966
1998
  #
1999
+ # @example Use Item wildcards (since openHAB 5.0)
2000
+ # rule 'Execute rule when the state of a matching item is updated' do
2001
+ # updated '*_Door', to: OPEN
2002
+ # run { |event| logger.info("Item #{event.item.name} updated to #{event.state}") }
2003
+ # end
2004
+ #
2005
+ # @example Use Thing wildcards (since openHAB 5.0)
2006
+ # rule 'Execute rule when the status of a matching thing is updated' do
2007
+ # updated 'mqtt:topic:*light*', to: :online
2008
+ # # to match all things, use "*:*" as the pattern
2009
+ # run { |event| logger.info("Thing #{event.thing.uid} updated to #{event.status}") }
2010
+ # end
2011
+ #
1967
2012
  def updated(*items, to: nil, attach: nil)
1968
2013
  updated = Updated.new(rule_triggers: @rule_triggers)
1969
2014
  @ruby_triggers << [:updated, items, { to: }]
@@ -1972,10 +2017,11 @@ module OpenHAB
1972
2017
  when Core::Things::Thing,
1973
2018
  Core::Things::ThingUID,
1974
2019
  Core::Items::Item,
1975
- Core::Items::GroupItem::Members
2020
+ Core::Items::GroupItem::Members,
2021
+ String
1976
2022
  nil
1977
2023
  else
1978
- raise ArgumentError, "items must be an Item, GroupItem::Members, Thing, or ThingUID"
2024
+ raise ArgumentError, "items must be an Item, GroupItem::Members, Thing, ThingUID, or a String"
1979
2025
  end
1980
2026
 
1981
2027
  logger.trace { "Creating updated trigger for item(#{item}) to(#{to})" }
@@ -82,8 +82,16 @@ module OpenHAB
82
82
  thing(thing: item, from:, to:)
83
83
  when Core::Things::Registry
84
84
  thing(thing: "*", from:, to:)
85
- else
85
+ when Core::Items::Item
86
86
  item(item:, from:, to:)
87
+ when Core::Items::Registry
88
+ item(item: "*", from:, to:)
89
+ else
90
+ if item.to_s.include?(":")
91
+ thing(thing: item, from:, to:)
92
+ else
93
+ item(item:, from:, to:)
94
+ end
87
95
  end
88
96
  append_trigger(type:, config:, attach:, conditions:, label:)
89
97
  end
@@ -113,7 +121,7 @@ module OpenHAB
113
121
  # second element is a Hash configuring trigger
114
122
  #
115
123
  def item(item:, from:, to:)
116
- config = { "itemName" => item.name }
124
+ config = { "itemName" => item.is_a?(Item) ? item.name : item.to_s }
117
125
  config["state"] = to.to_s if to
118
126
  config["previousState"] = from.to_s if from
119
127
  [ITEM_STATE_CHANGE, config]
@@ -26,10 +26,13 @@ module OpenHAB
26
26
  command = nil
27
27
  end
28
28
 
29
- type, config = if item.is_a?(GroupItem::Members)
29
+ type, config = case item
30
+ when GroupItem::Members
30
31
  [GROUP_COMMAND, { "groupName" => item.group.name }]
31
- else
32
+ when Item
32
33
  [ITEM_COMMAND, { "itemName" => item.name }]
34
+ else
35
+ [ITEM_COMMAND, { "itemName" => item.to_s }]
33
36
  end
34
37
  config["command"] = command.to_s unless command.nil?
35
38
  append_trigger(type:, config:, attach:, conditions:)
@@ -29,11 +29,16 @@ module OpenHAB
29
29
  type, config = case item
30
30
  when GroupItem::Members
31
31
  group_update(item:, to:)
32
- when Core::Things::Thing,
33
- Core::Things::ThingUID
32
+ when Core::Things::Thing, Core::Things::ThingUID
34
33
  thing_update(thing: item, to:)
35
- else
34
+ when Core::Items::Item
36
35
  item_update(item:, to:)
36
+ else
37
+ if item.to_s.include?(":")
38
+ thing_update(thing: item, to:)
39
+ else
40
+ item_update(item:, to:)
41
+ end
37
42
  end
38
43
  append_trigger(type:, config:, attach:, conditions:)
39
44
  end
@@ -62,7 +67,7 @@ module OpenHAB
62
67
  # second element is a Hash configuring trigger
63
68
  #
64
69
  def item_update(item:, to:)
65
- config = { "itemName" => item.name }
70
+ config = { "itemName" => item.is_a?(Item) ? item.name : item.to_s }
66
71
  config["state"] = to.to_s unless to.nil?
67
72
  [ITEM_STATE_UPDATE, config]
68
73
  end
@@ -4,6 +4,6 @@ module OpenHAB
4
4
  module DSL
5
5
  # Version of openHAB helper libraries
6
6
  # @return [String]
7
- VERSION = "5.36.2"
7
+ VERSION = "5.38.0"
8
8
  end
9
9
  end
data/lib/openhab/dsl.rb CHANGED
@@ -296,6 +296,19 @@ module OpenHAB
296
296
  # own instance of the timers object, so you don't need to worry about collisions among
297
297
  # different files.
298
298
  #
299
+ # ### Sharing Timers with other scripts
300
+ #
301
+ # When a timer is stored in the {shared_cache}, it will automatically be converted into
302
+ # an openHAB Timer object. It can then be used in other scripts or UI rules,
303
+ # written in JRuby or other supported languages.
304
+ #
305
+ # Timers are normally managed by TimerManager, and are normally automatically cancelled
306
+ # when the script unloads/reloads.
307
+ # To disable this automatic timer cancellation at script unload, call {Core::Timer#unmanage}.
308
+ #
309
+ # openHAB will cancel the timer stored in the {OpenHAB::DSL.shared_cache shared_cache}
310
+ # and remove the cache entry when all the scripts that _had accessed_ it have been unloaded.
311
+ #
299
312
  # @see timers
300
313
  # @see Rules::BuilderDSL#changed
301
314
  # @see Items::TimedCommand
@@ -377,6 +390,19 @@ module OpenHAB
377
390
  # end
378
391
  # end
379
392
  #
393
+ # @example Timers can be shared with other scripts
394
+ # # script1.rb:
395
+ # timer = after(10.hours) { logger.warn "Timer created in script1.rb fired" }
396
+ # shared_cache[:script1_timer] = timer
397
+ #
398
+ # # inside a different JRuby UI rule or script:
399
+ # # This is an openHAB timer object, not a JRuby timer object
400
+ # # the reschedule method expects a ZonedDateTime
401
+ # shared_cache[:script1_timer]&.reschedule(10.seconds.from_now)
402
+ #
403
+ # # inside another JS script:
404
+ # cache.shared.get("script1_timer")?.cancel()
405
+ #
380
406
  def after(duration, id: nil, reschedule: true, &block)
381
407
  raise ArgumentError, "Block is required" unless block
382
408
 
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is the default 'require' file in a Gemfile
4
+
5
+ return unless defined?(Java::OrgOpenhabCore::OpenHAB)
6
+
7
+ require_relative "dsl"
@@ -45,6 +45,9 @@ module OpenHAB
45
45
  if match
46
46
  log.warn "In file `#{file}':#{line}: Cannot resolve link to #{name} from text#{match ? ":" : "."}\n" \
47
47
  "\t#{match[1] ? "..." : ""}#{match[2].delete("\n")}#{match[3] ? "..." : ""}"
48
+ # Don't strip the link. This is so literals like {RUBY_ENGINE_VERSION} remain as they are,
49
+ # not stripped to "RUBY_ENGINE_VERSION"
50
+ next str
48
51
  end
49
52
  end
50
53
 
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.36.2
4
+ version: 5.38.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian O'Connell
@@ -9,7 +9,7 @@ authors:
9
9
  - Jimmy Tanagra
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-03-18 00:00:00.000000000 Z
12
+ date: 1980-01-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -433,6 +433,7 @@ files:
433
433
  - lib/openhab/rspec/openhab/core/things/proxy.rb
434
434
  - lib/openhab/rspec/shell.rb
435
435
  - lib/openhab/rspec/suspend_rules.rb
436
+ - lib/openhab/scripting.rb
436
437
  - lib/openhab/yard.rb
437
438
  - lib/openhab/yard/base_helper.rb
438
439
  - lib/openhab/yard/cli/stats.rb
@@ -478,7 +479,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
478
479
  - !ruby/object:Gem::Version
479
480
  version: '0'
480
481
  requirements: []
481
- rubygems_version: 3.6.6
482
+ rubygems_version: 3.6.7
482
483
  specification_version: 4
483
484
  summary: JRuby Helper Libraries for openHAB Scripting
484
485
  test_files: []