openhab-jrubyscripting 5.0.0.rc5 → 5.0.0.rc6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/lib/openhab/core/actions.rb +6 -6
  3. data/lib/openhab/core/dependency_tracking.rb +34 -0
  4. data/lib/openhab/core/entity_lookup.rb +132 -78
  5. data/lib/openhab/core/events/item_channel_link.rb +2 -2
  6. data/lib/openhab/core/events/item_command_event.rb +1 -1
  7. data/lib/openhab/core/events/item_event.rb +2 -2
  8. data/lib/openhab/core/events/item_state_changed_event.rb +1 -1
  9. data/lib/openhab/core/events/thing.rb +1 -1
  10. data/lib/openhab/core/items/accepted_data_types.rb +2 -2
  11. data/lib/openhab/core/items/contact_item.rb +1 -1
  12. data/lib/openhab/core/items/dimmer_item.rb +2 -2
  13. data/lib/openhab/core/items/generic_item.rb +45 -224
  14. data/lib/openhab/core/items/group_item.rb +5 -3
  15. data/lib/openhab/core/items/image_item.rb +2 -2
  16. data/lib/openhab/core/items/item.rb +219 -0
  17. data/lib/openhab/core/items/metadata/hash.rb +1 -1
  18. data/lib/openhab/core/items/persistence.rb +4 -5
  19. data/lib/openhab/core/items/provider.rb +2 -2
  20. data/lib/openhab/core/items/proxy.rb +68 -7
  21. data/lib/openhab/core/items/registry.rb +6 -6
  22. data/lib/openhab/core/items/semantics/enumerable.rb +6 -6
  23. data/lib/openhab/core/items/semantics.rb +8 -7
  24. data/lib/openhab/core/items.rb +2 -1
  25. data/lib/openhab/core/provider.rb +14 -7
  26. data/lib/openhab/core/rules/registry.rb +2 -2
  27. data/lib/openhab/core/rules.rb +1 -1
  28. data/lib/openhab/core/script_handling.rb +6 -6
  29. data/lib/openhab/core/things/channel.rb +1 -1
  30. data/lib/openhab/core/things/channel_uid.rb +2 -2
  31. data/lib/openhab/core/things/item_channel_link.rb +2 -2
  32. data/lib/openhab/core/things/links/provider.rb +2 -2
  33. data/lib/openhab/core/things/registry.rb +1 -1
  34. data/lib/openhab/core/things/thing.rb +1 -1
  35. data/lib/openhab/core/types/date_time_type.rb +4 -4
  36. data/lib/openhab/core/types/hsb_type.rb +2 -2
  37. data/lib/openhab/core/types/quantity_type.rb +1 -1
  38. data/lib/openhab/core/types.rb +1 -1
  39. data/lib/openhab/core/uid.rb +1 -1
  40. data/lib/openhab/core/value_cache.rb +188 -0
  41. data/lib/openhab/core.rb +57 -15
  42. data/lib/openhab/core_ext/ruby/symbol.rb +7 -0
  43. data/lib/openhab/dsl/items/builder.rb +17 -10
  44. data/lib/openhab/dsl/items/ensure.rb +5 -5
  45. data/lib/openhab/dsl/items/timed_command.rb +4 -4
  46. data/lib/openhab/dsl/rules/automation_rule.rb +53 -39
  47. data/lib/openhab/dsl/rules/builder.rb +128 -79
  48. data/lib/openhab/dsl/rules/guard.rb +5 -5
  49. data/lib/openhab/dsl/rules/name_inference.rb +20 -1
  50. data/lib/openhab/dsl/rules/rule_triggers.rb +3 -3
  51. data/lib/openhab/dsl/rules/terse.rb +1 -0
  52. data/lib/openhab/dsl/rules/triggers/changed.rb +26 -23
  53. data/lib/openhab/dsl/rules/triggers/command.rb +6 -5
  54. data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +2 -2
  55. data/lib/openhab/dsl/rules/triggers/cron/cron.rb +2 -2
  56. data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +6 -6
  57. data/lib/openhab/dsl/rules/triggers/updated.rb +5 -5
  58. data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +11 -12
  59. data/lib/openhab/dsl/things/builder.rb +73 -14
  60. data/lib/openhab/dsl/version.rb +2 -2
  61. data/lib/openhab/dsl.rb +43 -17
  62. data/lib/openhab/log.rb +5 -5
  63. data/lib/openhab/rspec/configuration.rb +5 -5
  64. data/lib/openhab/rspec/example_group.rb +1 -1
  65. data/lib/openhab/rspec/helpers.rb +4 -4
  66. data/lib/openhab/rspec/hooks.rb +19 -1
  67. data/lib/openhab/rspec/karaf.rb +12 -19
  68. data/lib/openhab/rspec/suspend_rules.rb +2 -1
  69. data/lib/openhab/yard/base_helper.rb +46 -0
  70. data/lib/openhab/yard/markdown_directive.rb +125 -0
  71. data/lib/openhab/yard/markdown_helper.rb +99 -0
  72. metadata +10 -3
@@ -14,15 +14,18 @@ end
14
14
  module OpenHAB
15
15
  module DSL
16
16
  #
17
- # Creates and manages OpenHAB Rules
17
+ # Creates and manages openHAB Rules
18
18
  #
19
19
  module Rules
20
- # A rules builder allows you to create OpenHAB rules.
20
+ # A rules builder allows you to create openHAB rules.
21
21
  #
22
22
  # Note that all methods on this module are also availabe directly on {OpenHAB::DSL}.
23
23
  #
24
24
  class Builder
25
25
  include Terse
26
+ include Core::EntityLookup
27
+
28
+ self.create_dummy_items = true
26
29
 
27
30
  # @return [org.openhab.core.automation.RuleProvider]
28
31
  attr_reader :provider
@@ -34,21 +37,24 @@ module OpenHAB
34
37
  #
35
38
  # Create a new rule
36
39
  #
40
+ # The rule must have at least one trigger and one execution block.
41
+ # To create a "script" without any triggers, use {#script}.
42
+ #
37
43
  # @param [String] name The rule name
38
- # @yield Block executed in the context of a {Rules::Builder}
39
- # @yieldparam [Rules::Builder] rule
44
+ # @yield Block executed in the context of a {Rules::BuilderDSL}
45
+ # @yieldparam [Rules::BuilderDSL] rule
40
46
  # Optional parameter to access the rule configuration from within execution blocks and guards.
41
- # @return [Rule]
47
+ # @return [Core::Rules::Rule, nil] The rule object, or nil if no rule was created.
42
48
  #
43
- # @see OpenHAB::DSL::Rules::Builder Rule builder for details on rule triggers, guards and execution blocks
49
+ # @see OpenHAB::DSL::Rules::BuilderDSL Rule BuilderDSL for details on rule triggers, guards and execution blocks
44
50
  # @see Rules::Terse Terse Rules
45
51
  #
46
52
  # @example
47
53
  # require "openhab/dsl"
48
54
  #
49
55
  # rule "name" do
50
- # <zero or more triggers>
51
- # <zero or more execution blocks>
56
+ # <one or more triggers>
57
+ # <one or more execution blocks>
52
58
  # <zero or more guards>
53
59
  # end
54
60
  #
@@ -85,7 +91,7 @@ module OpenHAB
85
91
  # @param [String] name A descriptive name
86
92
  # @param [String] id The script's ID
87
93
  # @yield [] Block executed when the script is executed.
88
- # @return [Rule]
94
+ # @return [Core::Rules::Rule]
89
95
  #
90
96
  def script(name = nil, id: nil, script: nil, &block)
91
97
  raise ArgumentError, "Block is required" unless block
@@ -108,7 +114,7 @@ module OpenHAB
108
114
  end
109
115
 
110
116
  #
111
- # Rule configuration for OpenHAB Rules engine
117
+ # Rule configuration for openHAB Rules engine
112
118
  #
113
119
  class BuilderDSL
114
120
  include Core::EntityLookup
@@ -117,6 +123,8 @@ module OpenHAB
117
123
  extend Property
118
124
  extend Forwardable
119
125
 
126
+ self.create_dummy_items = true
127
+
120
128
  delegate %i[triggers trigger_conditions attachments] => :@rule_triggers
121
129
 
122
130
  # @!visibility private
@@ -259,7 +267,7 @@ module OpenHAB
259
267
  #
260
268
  # @example
261
269
  # rule 'Delay sleeps between execution elements' do
262
- # on_start
270
+ # on_load
263
271
  # run { logger.info("Sleeping") }
264
272
  # delay 5.seconds
265
273
  # run { logger.info("Awake") }
@@ -267,7 +275,7 @@ module OpenHAB
267
275
  #
268
276
  # @example Like other execution blocks, multiple can exist in a single rule.
269
277
  # rule 'Multiple delays can exist in a rule' do
270
- # on_start
278
+ # on_load
271
279
  # run { logger.info("Sleeping") }
272
280
  # delay 5.seconds
273
281
  # run { logger.info("Sleeping Again") }
@@ -277,7 +285,7 @@ module OpenHAB
277
285
  #
278
286
  # @example You can use Ruby code in your rule across multiple execution blocks like a run and a delay.
279
287
  # rule 'Dim a switch on system startup over 100 seconds' do
280
- # on_start
288
+ # on_load
281
289
  # 100.times do
282
290
  # run { DimmerSwitch.dim }
283
291
  # delay 1.second
@@ -302,7 +310,7 @@ module OpenHAB
302
310
  #
303
311
  # @example
304
312
  # rule 'Turn switch ON or OFF based on value of another switch' do
305
- # on_start
313
+ # on_load
306
314
  # run { TestSwitch << ON }
307
315
  # otherwise { TestSwitch << OFF }
308
316
  # only_if { OtherSwitch.on? }
@@ -425,28 +433,28 @@ module OpenHAB
425
433
  #
426
434
  # @example String of {LocalTime}
427
435
  # rule 'Log an entry if started between 3:30:04 and midnight using strings' do
428
- # on_start
436
+ # on_load
429
437
  # run { logger.info ("Started at #{LocalTime.now}")}
430
438
  # between '3:30:04'..LocalTime::MIDNIGHT
431
439
  # end
432
440
  #
433
441
  # @example {LocalTime}
434
442
  # rule 'Log an entry if started between 3:30:04 and midnight using LocalTime objects' do
435
- # on_start
443
+ # on_load
436
444
  # run { logger.info ("Started at #{LocalTime.now}")}
437
445
  # between LocalTime.of(3, 30, 4)..LocalTime::MIDNIGHT
438
446
  # end
439
447
  #
440
448
  # @example String of {MonthDay}
441
449
  # rule 'Log an entry if started between March 9th and April 10ths' do
442
- # on_start
450
+ # on_load
443
451
  # run { logger.info ("Started at #{Time.now}")}
444
452
  # between '03-09'..'04-10'
445
453
  # end
446
454
  #
447
455
  # @example {MonthDay}
448
456
  # rule 'Log an entry if started between March 9th and April 10ths' do
449
- # on_start
457
+ # on_load
450
458
  # run { logger.info ("Started at #{Time.now}")}
451
459
  # between MonthDay.of(03,09)..'04-06'
452
460
  # end
@@ -533,8 +541,8 @@ module OpenHAB
533
541
  @rule_triggers = RuleTriggers.new
534
542
  @caller = caller_binding.eval "self"
535
543
  @ruby_triggers = []
544
+ @on_load_id = nil
536
545
  enabled(true)
537
- on_start(false)
538
546
  tags([])
539
547
  end
540
548
 
@@ -789,19 +797,19 @@ module OpenHAB
789
797
  # for is a reserved word in ruby, so use local_variable_get :for
790
798
  duration = binding.local_variable_get(:for)
791
799
 
800
+ @ruby_triggers << [:changed, items, { to: to, from: from, duration: duration }]
801
+
792
802
  from = [nil] if from.nil?
793
803
  to = [nil] if to.nil?
794
-
795
- @ruby_triggers << [:changed, items, { to: to, from: from, duration: duration }]
796
804
  items.each do |item|
797
805
  case item
798
806
  when Core::Things::Thing,
799
807
  Core::Things::ThingUID,
800
- Core::Items::GenericItem,
808
+ Core::Items::Item,
801
809
  Core::Items::GroupItem::Members
802
810
  nil
803
811
  else
804
- raise ArgumentError, "items must be a GenericItem, GroupItem::Members, Thing, or ThingUID"
812
+ raise ArgumentError, "items must be an Item, GroupItem::Members, Thing, or ThingUID"
805
813
  end
806
814
 
807
815
  logger.trace("Creating changed trigger for entity(#{item}), to(#{to.inspect}), from(#{from.inspect})")
@@ -818,7 +826,7 @@ module OpenHAB
818
826
  # Create a cron trigger
819
827
  #
820
828
  # @overload cron(expression, attach: nil)
821
- # @param [String, nil] expression [OpenHAB style cron expression](https://www.openhab.org/docs/configuration/rules-dsl.html#time-based-triggers)
829
+ # @param [String, nil] expression [openHAB style cron expression](https://www.openhab.org/docs/configuration/rules-dsl.html#time-based-triggers)
822
830
  # @param [Object] attach object to be attached to the trigger
823
831
  #
824
832
  # @example Using a cron expression
@@ -962,45 +970,116 @@ module OpenHAB
962
970
  end
963
971
 
964
972
  #
965
- # Run this rule when the script is loaded.
973
+ # Creates a trigger that executes when the script is loaded
966
974
  #
967
- # Execute the rule on OpenHAB start up and whenever the script is
968
- # reloaded. This is useful to perform initialization routines,
969
- # especially when combined with other triggers.
975
+ # Execute the rule whenever the script is first loaded, including on openHAB start up,
976
+ # and on subsequent reloads on file modifications.
977
+ # This is useful to perform initialization routines, especially when combined with other triggers.
970
978
  #
971
- # @param [true, false] run_on_start Run this rule on start, defaults to True
972
- # @param [Object] attach object to be attached to the trigger
979
+ # @param [Object] attach Object to be attached to the trigger
973
980
  # @return [void]
974
981
  #
975
982
  # @example
976
- # rule "startup rule" do
977
- # on_start
983
+ # rule "script startup rule" do
984
+ # on_load
978
985
  # run do
979
986
  # <calculate some item state>
980
987
  # end
981
988
  # end
982
989
  #
983
990
  # @example
984
- # rule 'Ensure all security lights are on' do
985
- # on_start
991
+ # rule "Ensure all security lights are on" do
992
+ # on_load
986
993
  # run { Security_Lights.on }
987
994
  # end
988
995
  #
989
- # rubocop:disable Style/OptionalBooleanParameter
990
- def on_start(run_on_start = true, attach: nil)
991
- @on_start = Struct.new(:enabled, :attach).new(run_on_start, attach)
996
+ def on_load(attach: nil)
997
+ # prevent overwriting @on_load_id
998
+ raise ArgumentError, "on_load can only be used once within a rule" if @on_load_id
999
+
1000
+ @on_load_id = SecureRandom.uuid
1001
+ attachments[@on_load_id] = attach
1002
+ end
1003
+
1004
+ #
1005
+ # Creates a trigger that executes when openHAB reaches a certain start level
1006
+ #
1007
+ # This will only trigger once during openHAB start up. It won't trigger on script reloads.
1008
+ #
1009
+ # @param [Integer,:rules,:ruleengine,:ui,:things,:complete] at_level
1010
+ # Zero or more start levels. Note that Startlevels less than 40 are not available as triggers
1011
+ # because the rule engine needs to start up first before it can execute any rules
1012
+ #
1013
+ # | Symbol | Start Level |
1014
+ # | ------------- | ----------- |
1015
+ # | `:osgi` | 10 |
1016
+ # | `:model` | 20 |
1017
+ # | `:state` | 30 |
1018
+ # | `:rules` | 40 |
1019
+ # | `:ruleengine` | 50 |
1020
+ # | `:ui` | 70 |
1021
+ # | `:things` | 80 |
1022
+ # | `:complete` | 100 |
1023
+ # @param [Array<Integer,:rules,:ruleengine,:ui,:things,:complete>] at_levels Fluent alias for `at_level`
1024
+ # @param [Object] attach Object to be attached to the trigger
1025
+ # @return [void]
1026
+ #
1027
+ # @example
1028
+ # rule "Trigger at openHAB system start" do
1029
+ # on_start # trigger at the default startlevel 100
1030
+ # run { logger.info "openHAB start up complete." }
1031
+ # end
1032
+ #
1033
+ # @example Trigger at a specific start level
1034
+ # rule "Trigger after things are loaded" do
1035
+ # on_start at_level: :things
1036
+ # run { logger.info "Things are ready!" }
1037
+ # end
1038
+ #
1039
+ # @example Trigger at multiple levels
1040
+ # rule "Multiple start up triggers" do
1041
+ # on_start at_levels: %i[ui things complete]
1042
+ # run do |event|
1043
+ # logger.info "openHAB startlevel has reached level #{event.startlevel}"
1044
+ # end
1045
+ # end
1046
+ #
1047
+ # @see https://www.openhab.org/docs/configuration/rules-dsl.html#system-based-triggers System based triggers
1048
+ #
1049
+ def on_start(at_level: nil, at_levels: nil, attach: nil)
1050
+ levels = Array.wrap(at_level) | Array.wrap(at_levels)
1051
+ levels = [100] if levels.empty?
1052
+
1053
+ levels.map! do |level|
1054
+ next level unless level.is_a?(Symbol)
1055
+
1056
+ begin
1057
+ klass = org.openhab.core.service.StartLevelService.java_class
1058
+ klass.declared_field("STARTLEVEL_#{level.upcase}").get_int(klass)
1059
+ rescue java.lang.NoSuchFieldException
1060
+ raise ArgumentError, "Invalid symbol for at_level: :#{level}"
1061
+ end
1062
+ end
1063
+
1064
+ @ruby_triggers << [:on_start, levels]
1065
+ levels.each do |level|
1066
+ logger.warn "Rule engine doesn't start until start level 40" if level < 40
1067
+ config = { startlevel: level }
1068
+ logger.trace("Creating a SystemStartlevelTrigger with startlevel=#{level}")
1069
+ Triggers::Trigger.new(rule_triggers: @rule_triggers)
1070
+ .append_trigger(type: "core.SystemStartlevelTrigger", config: config, attach: attach)
1071
+ end
992
1072
  end
993
- # rubocop:enable Style/OptionalBooleanParameter
994
1073
 
995
1074
  #
996
- # Create a trigger for when an item or group receives a command
1075
+ # Creates a trigger for when an item or group receives a command.
997
1076
  #
998
1077
  # The command/commands parameters are replicated for DSL fluency.
999
1078
  #
1000
1079
  # The `event` passed to run blocks will be an
1001
1080
  # {Core::Events::ItemCommandEvent}.
1002
1081
  #
1003
- # @param [GenericItem, GroupItem::Members] items Items to create trigger for
1082
+ # @param [Item, GroupItem::Members] items Items to create trigger for
1004
1083
  # @param [Core::TypesCommand, Array<Command>, Range, Proc] command commands to match for trigger
1005
1084
  # @param [Array<Command>, Range, Proc] commands Fluent alias for `command`
1006
1085
  # @param [Object] attach object to be attached to the trigger
@@ -1072,11 +1151,11 @@ module OpenHAB
1072
1151
 
1073
1152
  items.each do |item|
1074
1153
  case item
1075
- when Core::Items::GenericItem,
1154
+ when Core::Items::Item,
1076
1155
  Core::Items::GroupItem::Members
1077
1156
  nil
1078
1157
  else
1079
- raise ArgumentError, "items must be a GenericItem or GroupItem::Members"
1158
+ raise ArgumentError, "items must be an Item or GroupItem::Members"
1080
1159
  end
1081
1160
  commands.each do |cmd|
1082
1161
  logger.trace "Creating received command trigger for items #{item.inspect} and commands #{cmd.inspect}"
@@ -1194,7 +1273,7 @@ module OpenHAB
1194
1273
  # {Core::Events::ThingStatusInfoEvent} depending on if the triggering
1195
1274
  # element was an item or a thing.
1196
1275
  #
1197
- # @param [GenericItem, GroupItem::Members, Thing] items
1276
+ # @param [Item, GroupItem::Members, Thing] items
1198
1277
  # Objects to create trigger for.
1199
1278
  # @param [State, Array<State>, Range, Proc, Symbol, String] to
1200
1279
  # Only execute rule if the state matches `to` state(s). If the
@@ -1271,11 +1350,11 @@ module OpenHAB
1271
1350
  case item
1272
1351
  when Core::Things::Thing,
1273
1352
  Core::Things::ThingUID,
1274
- Core::Items::GenericItem,
1353
+ Core::Items::Item,
1275
1354
  Core::Items::GroupItem::Members
1276
1355
  nil
1277
1356
  else
1278
- raise ArgumentError, "items must be a GenericItem, GroupItem::Members, Thing, or ThingUID"
1357
+ raise ArgumentError, "items must be an Item, GroupItem::Members, Thing, or ThingUID"
1279
1358
  end
1280
1359
 
1281
1360
  logger.trace("Creating updated trigger for item(#{item}) to(#{to})")
@@ -1317,7 +1396,7 @@ module OpenHAB
1317
1396
  # @param [Object] attach object to be attached to the trigger
1318
1397
  # @return [void]
1319
1398
  #
1320
- # @example Watch `items` directory inside of the OpenHAB configuration path and log any changes.
1399
+ # @example Watch `items` directory inside of the openHAB configuration path and log any changes.
1321
1400
  # rule 'watch directory' do
1322
1401
  # watch OpenHAB::Core.config_folder / 'items'
1323
1402
  # run { |event| logger.info("#{event.path.basename} - #{event.type}") }
@@ -1358,36 +1437,6 @@ module OpenHAB
1358
1437
 
1359
1438
  # @!endgroup
1360
1439
 
1361
- #
1362
- # Checks if this rule should run on start
1363
- #
1364
- # @return [true, false] True if rule should run on start, false otherwise.
1365
- #
1366
- def on_start?
1367
- @on_start.enabled
1368
- end
1369
-
1370
- #
1371
- # Get the optional start attachment
1372
- #
1373
- # @return [Object] optional user provided attachment to the on_start method
1374
- #
1375
- # @!visibility private
1376
- def start_attachment
1377
- @on_start.attach
1378
- end
1379
-
1380
- # @!visibility private
1381
- #
1382
- # Run the supplied block inside the object instance of the object that created the rule
1383
- #
1384
- # @yield [] Block executed in context of the object creating the rule
1385
- #
1386
- #
1387
- def my(&block)
1388
- @caller.instance_eval(&block)
1389
- end
1390
-
1391
1440
  #
1392
1441
  # @return [String]
1393
1442
  #
@@ -1396,7 +1445,7 @@ module OpenHAB
1396
1445
  #<OpenHAB::DSL::Rules::Builder: #{uid}
1397
1446
  triggers=#{triggers.inspect},
1398
1447
  run blocks=#{run.inspect},
1399
- on_start=#{on_start?},
1448
+ on_load=#{!@on_load_id.nil?},
1400
1449
  Trigger Conditions=#{trigger_conditions.inspect},
1401
1450
  Trigger UIDs=#{triggers.map(&:id).inspect},
1402
1451
  Attachments=#{attachments.inspect}
@@ -1419,7 +1468,7 @@ module OpenHAB
1419
1468
  added_rule.actions.first.configuration.put("type", "application/x-ruby")
1420
1469
  added_rule.actions.first.configuration.put("script", script) if script
1421
1470
 
1422
- rule.execute(nil, { "event" => Struct.new(:attachment).new(start_attachment) }) if on_start?
1471
+ rule.execute(nil, { "module" => @on_load_id }) if @on_load_id
1423
1472
  added_rule
1424
1473
  end
1425
1474
 
@@ -1456,7 +1505,7 @@ module OpenHAB
1456
1505
  # @return [true,false] True if rule has triggers, false otherwise
1457
1506
  #
1458
1507
  def triggers?
1459
- on_start? || !triggers.empty?
1508
+ @on_load_id || !triggers.empty?
1460
1509
  end
1461
1510
 
1462
1511
  #
@@ -34,7 +34,7 @@ module OpenHAB
34
34
  #
35
35
  # Checks if a guard should run
36
36
  #
37
- # @param [OpenHAB Trigger Event] event OpenHAB Trigger Event
37
+ # @param [Object] event openHAB Trigger Event
38
38
  #
39
39
  # @return [true,false] True if guard is satisfied, false otherwise
40
40
  #
@@ -51,7 +51,7 @@ module OpenHAB
51
51
  #
52
52
  # @param [Array] conditions to check
53
53
  # @param [Symbol] check_type type of check to perform (:only_if or :not_if)
54
- # @param [Event] event OpenHAB event to see if it satisfies the guard
54
+ # @param [Event] event openHAB event to see if it satisfies the guard
55
55
  #
56
56
  # @return [true,false] True if guard is satisfied, false otherwise
57
57
  #
@@ -70,7 +70,7 @@ module OpenHAB
70
70
  # Execute the guard check
71
71
  #
72
72
  # @param [Symbol] check_type :only_if or :not_if to check
73
- # @param [OpenHAB Event] event event to check if meets guard
73
+ # @param [Object] event event to check if meets guard
74
74
  # @param [Array<Item>] items to check if satisfy criteria
75
75
  # @param [Array] procs to check if satisfy criteria
76
76
  #
@@ -87,7 +87,7 @@ module OpenHAB
87
87
  #
88
88
  # Check not_if guard
89
89
  #
90
- # @param [OpenHAB Event] event to check if meets guard
90
+ # @param [Object] event to check if meets guard
91
91
  # @param [Array<Item>] items to check if satisfy criteria
92
92
  # @param [Array] procs to check if satisfy criteria
93
93
  #
@@ -100,7 +100,7 @@ module OpenHAB
100
100
  #
101
101
  # Check only_if guard
102
102
  #
103
- # @param [OpenHAB Event] event to check if meets guard
103
+ # @param [Object] event to check if meets guard
104
104
  # @param [Array<Item>] items to check if satisfy criteria
105
105
  # @param [Array] procs to check if satisfy criteria
106
106
  #
@@ -18,6 +18,7 @@ module OpenHAB
18
18
  "core.ItemCommandTrigger",
19
19
  "core.ItemStateChangeTrigger",
20
20
  "core.ItemStateUpdateTrigger",
21
+ "core.SystemStartlevelTrigger",
21
22
  Triggers::Cron::CRON_TRIGGER_MODULE_ID
22
23
  ].freeze
23
24
  private_constant :KNOWN_TRIGGER_TYPES
@@ -61,6 +62,8 @@ module OpenHAB
61
62
  infer_rule_name_from_channel_link_trigger(trigger)
62
63
  when :thing_added, :thing_removed, :thing_updated
63
64
  infer_rule_name_from_thing_trigger(trigger)
65
+ when :on_start
66
+ infer_rule_name_from_on_start_trigger(items)
64
67
  end
65
68
  end
66
69
 
@@ -122,6 +125,22 @@ module OpenHAB
122
125
  }[trigger]
123
126
  end
124
127
 
128
+ # formulate a readable rule name from an on_start trigger
129
+ def infer_rule_name_from_on_start_trigger(levels)
130
+ levels = levels.map { |level| "#{level} (#{start_level_description(level)})" }
131
+ levels = format_array(levels)
132
+ "System Start Level reached #{levels}"
133
+ end
134
+
135
+ def start_level_description(level)
136
+ klass = org.openhab.core.service.StartLevelService.java_class
137
+ start_level_type = klass.declared_field("STARTLEVEL_OSGI").type
138
+ klass.declared_fields
139
+ .select { |field| field.type == start_level_type && field.name.start_with?("STARTLEVEL_") }
140
+ .find { |field| field.get_int(klass) == level }
141
+ .name.split("_", 2).last.downcase
142
+ end
143
+
125
144
  # format an array of words that will be the beginning of a sentence
126
145
  def format_beginning_of_sentence_array(array)
127
146
  result = format_array(array)
@@ -146,7 +165,7 @@ module OpenHAB
146
165
  return array[0] if array.length == 1
147
166
  return "#{array[0]} or #{array[1]}" if array.length == 2
148
167
 
149
- "any of #{array.join(", ")}"
168
+ "#{array[0..-2].join(", ")}, or #{array[-1]}"
150
169
  end
151
170
  end
152
171
  end
@@ -10,7 +10,7 @@ module OpenHAB
10
10
  module DSL
11
11
  module Rules
12
12
  #
13
- # Rule configuration for OpenHAB Rules engine
13
+ # Rule configuration for openHAB Rules engine
14
14
  #
15
15
  # @!visibility private
16
16
  class RuleTriggers
@@ -39,7 +39,7 @@ module OpenHAB
39
39
  # @param [Map] config map describing trigger configuration
40
40
  # @param [Object] attach object to be attached to the trigger
41
41
  #
42
- # @return [Trigger] OpenHAB trigger
42
+ # @return [org.openhab.core.automation.Trigger] openHAB trigger
43
43
  #
44
44
  def append_trigger(type:, config:, attach: nil, conditions: nil)
45
45
  config.transform_keys!(&:to_s)
@@ -57,7 +57,7 @@ module OpenHAB
57
57
  # @param [String] type of trigger
58
58
  # @param [Map] config map
59
59
  #
60
- # @return [OpenHAB Trigger] configured by type and supplied config
60
+ # @return [org.openhab.core.automation.Trigger] configured by type and supplied config
61
61
  #
62
62
  def self.trigger(type:, config:)
63
63
  logger.trace("Creating trigger of type '#{type}' config: #{config}")
@@ -56,6 +56,7 @@ module OpenHAB
56
56
  def_terse_rule(:thing_updated)
57
57
  def_terse_rule(:thing_removed)
58
58
  def_terse_rule(:updated)
59
+ def_terse_rule(:on_start)
59
60
  end
60
61
  end
61
62
  end
@@ -16,13 +16,13 @@ module OpenHAB
16
16
  #
17
17
  # Create the trigger
18
18
  #
19
- # @param [Object] item item to create trigger for
20
- # @param [Item State] from state to restrict trigger to
21
- # @param [Item State] to state to restrict trigger to
22
- # @param [Duration, nil] duration ruration to delay trigger until to state is met
19
+ # @param [Core::Items::Item, Core::Items::GroupItem::Members] item item to create trigger for
20
+ # @param [Core::Types::State, Array<Core::Types::State>, Range, Proc] from state to restrict trigger to
21
+ # @param [Core::Types::State, Array<Core::Types::State>, Range, Proc] to state to restrict trigger to
22
+ # @param [Duration, nil] duration duration to delay trigger until to state is met
23
23
  # @param [Object] attach object to be attached to the trigger
24
24
  #
25
- # @return [Trigger] OpenHAB triggers
25
+ # @return [org.openhab.core.automation.Trigger] openHAB triggers
26
26
  #
27
27
  def trigger(item:, from:, to:, duration:, attach:)
28
28
  if duration
@@ -50,13 +50,15 @@ module OpenHAB
50
50
  #
51
51
  # Create a TriggerDelay for for an item or group that is changed for a specific duration
52
52
  #
53
- # @param [Object] item to create trigger delay for
53
+ # @param [Core::Items::Item, Core::Items::GroupItem::Members] item to create trigger delay for
54
54
  # @param [Duration] duration to delay trigger for until condition is met
55
- # @param [Item State] to OpenHAB Item State item or group needs to change to
56
- # @param [Item State] from OpenHAB Item State item or group needs to be coming from
55
+ # @param [Core::Types::State, Array<Core::Types::State>, Range, Proc] to
56
+ # State item or group needs to change to
57
+ # @param [Core::Types::State, Array<Core::Types::State>, Range, Proc] from
58
+ # State item or group needs to be coming from
57
59
  # @param [Object] attach object to be attached to the trigger
58
60
  #
59
- # @return [Trigger] OpenHAB trigger
61
+ # @return [org.openhab.core.automation.Trigger]
60
62
  #
61
63
  def wait_trigger(item:, duration:, to: nil, from: nil, attach: nil)
62
64
  item_name = item.respond_to?(:name) ? item.name : item.to_s
@@ -68,11 +70,11 @@ module OpenHAB
68
70
 
69
71
  #
70
72
  # Creates a trigger with a range condition on either 'from' or 'to' field
71
- # @param [Object] item to create changed trigger on
72
- # @param [Object] from state to restrict trigger to
73
- # @param [Object] to state restrict trigger to
73
+ # @param [Core::Items::Item, Core::Items::GroupItem::Members] item to create changed trigger on
74
+ # @param [Range] from state to restrict trigger to
75
+ # @param [Range] to state restrict trigger to
74
76
  # @param [Object] attach object to be attached to the trigger
75
- # @return [Trigger] OpenHAB trigger
77
+ # @return [org.openhab.core.automation.Trigger]
76
78
  #
77
79
  def range_trigger(item:, from:, to:, attach:)
78
80
  from, to = Conditions::Proc.range_procs(from, to)
@@ -81,11 +83,11 @@ module OpenHAB
81
83
 
82
84
  #
83
85
  # Creates a trigger with a proc condition on either 'from' or 'to' field
84
- # @param [Object] item to create changed trigger on
85
- # @param [Object] from state to restrict trigger to
86
- # @param [Object] to state restrict trigger to
86
+ # @param [Core::Items::Item, Core::Items::GroupItem::Members] item to create changed trigger on
87
+ # @param [Proc] from state to restrict trigger to
88
+ # @param [Proc] to state restrict trigger to
87
89
  # @param [Object] attach object to be attached to the trigger
88
- # @return [Trigger] OpenHAB trigger
90
+ # @return [org.openhab.core.automation.Trigger]
89
91
  #
90
92
  def proc_trigger(item:, from:, to:, attach:)
91
93
  # swap from/to w/ nil if from/to is a proc
@@ -100,10 +102,11 @@ module OpenHAB
100
102
  #
101
103
  # Create a changed trigger
102
104
  #
103
- # @param [Object] item to create changed trigger on
104
- # @param [Object] from state to restrict trigger to
105
- # @param [Object] to state restrict trigger to
105
+ # @param [Core::Items::Item, Core::Items::GroupItem::Members] item to create changed trigger on
106
+ # @param [Core::Items::State, Array<Core::Items::State>] from state to restrict trigger to
107
+ # @param [Core::Items::State, Array<Core::Items::State>] to state restrict trigger to
106
108
  # @param [Object] attach object to be attached to the trigger
109
+ # @return [org.openhab.core.automation.Trigger]
107
110
  #
108
111
  def changed_trigger(item:, from:, to:, attach: nil, conditions: nil)
109
112
  type, config = case item
@@ -121,7 +124,7 @@ module OpenHAB
121
124
  #
122
125
  # Create a changed trigger for a thing
123
126
  #
124
- # @param [Thing] thing to detected changed states on
127
+ # @param [Core::Things::Thing] thing to detected changed states on
125
128
  # @param [String] from state to restrict trigger to
126
129
  # @param [String] to state to restrict trigger to
127
130
  #
@@ -152,7 +155,7 @@ module OpenHAB
152
155
  #
153
156
  # Create a changed trigger for group items
154
157
  #
155
- # @param [Group] group to detected changed states on
158
+ # @param [GroupItem] group to detected changed states on
156
159
  # @param [String] from state to restrict trigger to
157
160
  # @param [String] to to restrict trigger to
158
161
  #
@@ -160,7 +163,7 @@ module OpenHAB
160
163
  # second element is a Hash configuring trigger
161
164
  #
162
165
  def group(group:, from:, to:)
163
- config = { "groupName" => group.group.name }
166
+ config = { "groupName" => group.name }
164
167
  config["state"] = to.to_s if to
165
168
  config["previousState"] = from.to_s if from
166
169
  [GROUP_STATE_CHANGE, config]