openhab-scripting 2.9.1

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.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/workflow.yml +327 -0
  3. data/.gitignore +17 -0
  4. data/.java-version +1 -0
  5. data/.rspec +1 -0
  6. data/.yardopts +1 -0
  7. data/CHANGELOG.md +113 -0
  8. data/Gemfile +28 -0
  9. data/Gemfile.lock +245 -0
  10. data/Guardfile +35 -0
  11. data/LICENSE +277 -0
  12. data/README.md +23 -0
  13. data/Rakefile +406 -0
  14. data/bin/console +15 -0
  15. data/bin/setup +8 -0
  16. data/config/userdata/config/org/openhab/restauth.config +3 -0
  17. data/cucumber.yml +1 -0
  18. data/docs/_config.yml +135 -0
  19. data/docs/contributing/index.md +47 -0
  20. data/docs/examples/conversions.md +123 -0
  21. data/docs/examples/index.md +61 -0
  22. data/docs/index.md +19 -0
  23. data/docs/installation/index.md +26 -0
  24. data/docs/motivation/index.md +27 -0
  25. data/docs/usage/execution.md +9 -0
  26. data/docs/usage/execution/delay.md +48 -0
  27. data/docs/usage/execution/otherwise.md +30 -0
  28. data/docs/usage/execution/run.md +70 -0
  29. data/docs/usage/execution/triggered.md +48 -0
  30. data/docs/usage/guards.md +51 -0
  31. data/docs/usage/guards/between.md +30 -0
  32. data/docs/usage/guards/not_if.md +41 -0
  33. data/docs/usage/guards/only_if.md +40 -0
  34. data/docs/usage/index.md +11 -0
  35. data/docs/usage/items.md +66 -0
  36. data/docs/usage/items/contact.md +84 -0
  37. data/docs/usage/items/dimmer.md +147 -0
  38. data/docs/usage/items/groups.md +76 -0
  39. data/docs/usage/items/number.md +225 -0
  40. data/docs/usage/items/string.md +49 -0
  41. data/docs/usage/items/switch.md +85 -0
  42. data/docs/usage/misc.md +7 -0
  43. data/docs/usage/misc/actions.md +108 -0
  44. data/docs/usage/misc/duration.md +21 -0
  45. data/docs/usage/misc/gems.md +25 -0
  46. data/docs/usage/misc/logging.md +21 -0
  47. data/docs/usage/misc/metadata.md +128 -0
  48. data/docs/usage/misc/store_states.md +42 -0
  49. data/docs/usage/misc/time_of_day.md +69 -0
  50. data/docs/usage/misc/timers.md +67 -0
  51. data/docs/usage/rule.md +43 -0
  52. data/docs/usage/things.md +29 -0
  53. data/docs/usage/triggers.md +8 -0
  54. data/docs/usage/triggers/changed.md +57 -0
  55. data/docs/usage/triggers/channel.md +54 -0
  56. data/docs/usage/triggers/command.md +69 -0
  57. data/docs/usage/triggers/cron.md +19 -0
  58. data/docs/usage/triggers/every.md +76 -0
  59. data/docs/usage/triggers/updated.md +78 -0
  60. data/lib/openhab.rb +39 -0
  61. data/lib/openhab/configuration.rb +16 -0
  62. data/lib/openhab/core/cron.rb +27 -0
  63. data/lib/openhab/core/debug.rb +34 -0
  64. data/lib/openhab/core/dsl.rb +47 -0
  65. data/lib/openhab/core/dsl/actions.rb +107 -0
  66. data/lib/openhab/core/dsl/entities.rb +103 -0
  67. data/lib/openhab/core/dsl/gems.rb +29 -0
  68. data/lib/openhab/core/dsl/group.rb +91 -0
  69. data/lib/openhab/core/dsl/items/items.rb +39 -0
  70. data/lib/openhab/core/dsl/items/number_item.rb +217 -0
  71. data/lib/openhab/core/dsl/items/string_item.rb +102 -0
  72. data/lib/openhab/core/dsl/monkey_patch/actions/actions.rb +4 -0
  73. data/lib/openhab/core/dsl/monkey_patch/actions/script_thing_actions.rb +22 -0
  74. data/lib/openhab/core/dsl/monkey_patch/events.rb +5 -0
  75. data/lib/openhab/core/dsl/monkey_patch/events/item_command.rb +13 -0
  76. data/lib/openhab/core/dsl/monkey_patch/events/item_state_changed.rb +25 -0
  77. data/lib/openhab/core/dsl/monkey_patch/events/thing_status_info.rb +26 -0
  78. data/lib/openhab/core/dsl/monkey_patch/items/contact_item.rb +54 -0
  79. data/lib/openhab/core/dsl/monkey_patch/items/dimmer_item.rb +125 -0
  80. data/lib/openhab/core/dsl/monkey_patch/items/group_item.rb +27 -0
  81. data/lib/openhab/core/dsl/monkey_patch/items/items.rb +130 -0
  82. data/lib/openhab/core/dsl/monkey_patch/items/metadata.rb +259 -0
  83. data/lib/openhab/core/dsl/monkey_patch/items/switch_item.rb +86 -0
  84. data/lib/openhab/core/dsl/monkey_patch/ruby/number.rb +69 -0
  85. data/lib/openhab/core/dsl/monkey_patch/ruby/range.rb +46 -0
  86. data/lib/openhab/core/dsl/monkey_patch/ruby/ruby.rb +5 -0
  87. data/lib/openhab/core/dsl/monkey_patch/types/decimal_type.rb +24 -0
  88. data/lib/openhab/core/dsl/monkey_patch/types/on_off_type.rb +41 -0
  89. data/lib/openhab/core/dsl/monkey_patch/types/open_closed_type.rb +25 -0
  90. data/lib/openhab/core/dsl/monkey_patch/types/percent_type.rb +23 -0
  91. data/lib/openhab/core/dsl/monkey_patch/types/types.rb +7 -0
  92. data/lib/openhab/core/dsl/property.rb +85 -0
  93. data/lib/openhab/core/dsl/rule/channel.rb +41 -0
  94. data/lib/openhab/core/dsl/rule/cron.rb +115 -0
  95. data/lib/openhab/core/dsl/rule/guard.rb +99 -0
  96. data/lib/openhab/core/dsl/rule/item.rb +207 -0
  97. data/lib/openhab/core/dsl/rule/rule.rb +374 -0
  98. data/lib/openhab/core/dsl/rule/triggers.rb +77 -0
  99. data/lib/openhab/core/dsl/states.rb +63 -0
  100. data/lib/openhab/core/dsl/things.rb +93 -0
  101. data/lib/openhab/core/dsl/time_of_day.rb +203 -0
  102. data/lib/openhab/core/dsl/timers.rb +85 -0
  103. data/lib/openhab/core/dsl/types/quantity.rb +255 -0
  104. data/lib/openhab/core/dsl/units.rb +41 -0
  105. data/lib/openhab/core/duration.rb +69 -0
  106. data/lib/openhab/core/log.rb +175 -0
  107. data/lib/openhab/core/patch_load_path.rb +7 -0
  108. data/lib/openhab/core/startup_delay.rb +22 -0
  109. data/lib/openhab/osgi.rb +52 -0
  110. data/lib/openhab/version.rb +9 -0
  111. data/openhab-scripting.gemspec +30 -0
  112. data/openhab_rules/warmup.rb +5 -0
  113. metadata +157 -0
@@ -0,0 +1,19 @@
1
+ ---
2
+ layout: default
3
+ title: Cron
4
+ nav_order: 2
5
+ has_children: false
6
+ parent: Triggers
7
+ grand_parent: Usage
8
+ ---
9
+
10
+
11
+ # Cron
12
+ Utilizes [OpenHAB style cron expressions](https://www.openhab.org/docs/configuration/rules-dsl.html#time-based-triggers) to trigger rules. This property can be utilized when you need to represent complex expressions not possible with the simpler [every](#Every) syntax.
13
+
14
+ ```ruby
15
+ rule 'Using Cron Syntax' do
16
+ cron '43 46 13 ? * ?'
17
+ run { logger.info "Cron rule executed" }
18
+ end
19
+ ```
@@ -0,0 +1,76 @@
1
+ ---
2
+ layout: default
3
+ title: Every
4
+ nav_order: 1
5
+ has_children: false
6
+ parent: Triggers
7
+ grand_parent: Usage
8
+ ---
9
+
10
+ # Every
11
+
12
+ | Value | Description | Example |
13
+ | ----------------- | ---------------------------------------- | ---------- |
14
+ | :second | Execute rule every second | :second |
15
+ | :minute | Execute rule very minute | :minute |
16
+ | :hour | Execute rule every hour | :hour |
17
+ | :day | Execute rule every day | :day |
18
+ | :week | Execute rule every week | :week |
19
+ | :month | Execute rule every month | :month |
20
+ | :year | Execute rule one a year | :year |
21
+ | :monday | Execute rule every Monday at midnight | :monday |
22
+ | :tuesday | Execute rule every Tuesday at midnight | :tuesday |
23
+ | :wednesday | Execute rule every Wednesday at midnight | :wednesday |
24
+ | :thursday | Execute rule every Thursday at midnight | :thursday |
25
+ | :friday | Execute rule every Friday at midnight | :friday |
26
+ | :saturday | Execute rule every Saturday at midnight | :saturday |
27
+ | :sunday | Execute rule every Sunday at midnight | :sunday |
28
+ | [Integer].seconds | Execute a rule every X seconds | 5.seconds |
29
+ | [Integer].minutes | Execute rule every X minutes | 3.minutes |
30
+ | [Integer].hours | Execute rule every X minutes | 10.hours |
31
+
32
+ | Option | Description | Example |
33
+ | ------ | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
34
+ | :at | Limit the execution to specific times of day. The value can either be a String or a TimeOfDay object | at: '16:45' or at: TimeOfDay.new(h: 16, m: 45) |
35
+
36
+
37
+ # Examples
38
+
39
+ ```ruby
40
+ rule 'Log the rule name every minute' do
41
+ description 'This rule will create a log every minute'
42
+ every :minute
43
+ run { logger.info "Rule '#{name}' executed" }
44
+ end
45
+ ```
46
+
47
+
48
+ ```ruby
49
+ rule 'Log an entry at 11:21' do
50
+ every :day, at: '11:21'
51
+ run { logger.info("Rule #{name} run at #{TimeOfDay.now}") }
52
+ end
53
+
54
+ # The above rule could also be expressed using TimeOfDay class as below
55
+
56
+ rule 'Log an entry at 11:21' do
57
+ every :day, at: TimeOfDay.new(h: 11, m: 21)
58
+ run { logger.info("Rule #{name} run at #{TimeOfDay.now}") }
59
+ end
60
+ ```
61
+
62
+
63
+ ```ruby
64
+ rule 'Log an entry Wednesdays at 11:21' do
65
+ every :wednesday, at: '11:21'
66
+ run { logger.info("Rule #{name} run at #{TimeOfDay.now}") }
67
+ end
68
+ ```
69
+
70
+
71
+ ```ruby
72
+ rule 'Every 5 seconds' do
73
+ every 5.seconds
74
+ run { logger.info "Rule #{name} executed" }
75
+ end
76
+ ```
@@ -0,0 +1,78 @@
1
+ ---
2
+ layout: default
3
+ title: Updated
4
+ nav_order: 4
5
+ has_children: false
6
+ parent: Triggers
7
+ grand_parent: Usage
8
+ ---
9
+
10
+ # Updated
11
+
12
+
13
+
14
+ | Options | Description | Example |
15
+ | ------- | -------------------------------------------------- | ----------------------- |
16
+ | to | Only execute rule if update state matches to state | `to: 7` or `to: [7,14]` |
17
+
18
+ Changed accepts Items, Things or Groups.
19
+
20
+ The to value restricts the rule from running to only if the updated state matches. If the updated element being used as a trigger is a thing than the to and from values will accept symbols and strings, where the symbol matches the [supported status](https://www.openhab.org/docs/concepts/things.html).
21
+
22
+ The examples below assume the following background:
23
+
24
+ | type | name | group | state |
25
+ | ------ | ---------------- | ---------- | ----- |
26
+ | Number | Alarm_Mode | AlarmModes | 7 |
27
+ | Number | Alarm_Mode_Other | AlarmModes | 7 |
28
+
29
+
30
+ ```ruby
31
+ rule 'Execute rule when item is updated to any value' do
32
+ updated Alarm_Mode
33
+ run { logger.info("Alarm Mode Updated") }
34
+ end
35
+ ```
36
+
37
+ ```ruby
38
+ rule 'Execute rule when item is updated to specific number' do
39
+ updated Alarm_Mode, to: 7
40
+ run { logger.info("Alarm Mode Updated") }
41
+ end
42
+ ```
43
+
44
+ ```ruby
45
+ rule 'Execute rule when item is updated to one of many specific states' do
46
+ updated Alarm_Mode, to: [7,14]
47
+ run { logger.info("Alarm Mode Updated")}
48
+ end
49
+ ```
50
+
51
+ ```ruby
52
+ rule 'Execute rule when group is updated to any state' do
53
+ updated AlarmModes
54
+ triggered { |item| logger.info("Group #{item.id} updated")}
55
+ end
56
+ ```
57
+
58
+ ```ruby
59
+ rule 'Execute rule when member of group is changed to any state' do
60
+ updated AlarmModes.items
61
+ triggered { |item| logger.info("Group item #{item.id} updated")}
62
+ end
63
+ ```
64
+
65
+ ```ruby
66
+ rule 'Execute rule when member of group is changed to one of many states' do
67
+ updated AlarmModes.items, to: [7,14]
68
+ triggered { |item| logger.info("Group item #{item.id} updated")}
69
+ end
70
+ ```
71
+
72
+ Works with things as well:
73
+ ```ruby
74
+ rule 'Execute rule when thing is updated' do
75
+ updated things['astro:sun:home'], :to => :uninitialized
76
+ run { |event| logger.info("Thing #{event.uid} status <trigger> to #{event.status}") }
77
+ end
78
+ ```
data/lib/openhab.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # First patch the $LOAD_PATH to include lib dir
4
+ require 'openhab/core/patch_load_path'
5
+
6
+ require 'openhab/core/startup_delay'
7
+ require 'openhab/core/log'
8
+ require 'openhab/core/debug'
9
+ require 'openhab/core/dsl'
10
+
11
+ require 'openhab/version'
12
+
13
+ #
14
+ # Module used to extend base object with OpenHAB Library functionality
15
+ #
16
+ module OpenHAB
17
+ include Logging
18
+ #
19
+ # Extends calling object with DSL and helper methods
20
+ #
21
+ # @param [Object] base Object to decorate with DSL and helper methods
22
+ #
23
+ #
24
+ def self.extended(base)
25
+ base.extend Logging
26
+ base.extend Debug
27
+ base.extend EntityLookup
28
+ base.extend OpenHAB::Core::DSL
29
+ base.extend OpenHAB::Core::DSL::Tod
30
+
31
+ base.send :include, OpenHAB::Core::DSL::Tod
32
+ base.send :include, OpenHAB::Core::DSL::Items
33
+ base.send :include, OpenHAB::Core::DSL::Types
34
+ logger.info "OpenHAB JRuby Scripting Library Version #{OpenHAB::VERSION} Loaded"
35
+ end
36
+ end
37
+
38
+ # Extend caller with OpenHAB methods
39
+ extend OpenHAB
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This module holds global configuration values
4
+ module Configuration
5
+ # -*- coding: utf-8 -*-
6
+ LOG_PREFIX = 'jsr223.jruby'
7
+
8
+ #
9
+ # Gets the log prefix
10
+ #
11
+ # @return [String] Prefix for all log entries
12
+ #
13
+ def self.log_prefix
14
+ LOG_PREFIX
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module Core
5
+ #
6
+ # Module for Cron related methods
7
+ #
8
+ module Cron
9
+ #
10
+ # Retruns a default map for cron expressions that fires every second
11
+ # This map is usually updated via merge by other methods to refine cron type triggers.
12
+ #
13
+ # @return [Map] Map with symbols for :seconds, :minute, :hour, :dom, :month, :dow configured to fire every second
14
+ #
15
+ def cron_expression_map
16
+ {
17
+ second: '*',
18
+ minute: '*',
19
+ hour: '*',
20
+ dom: '?',
21
+ month: '*',
22
+ dow: '?'
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pp'
4
+ require 'core/log'
5
+ require 'core/dsl/things'
6
+
7
+ #
8
+ # Module to support debugging information about the Ruby or OpenHAB environment
9
+ #
10
+ module Debug
11
+ include Logging
12
+ include OpenHAB::Core::DSL::Things
13
+
14
+ #
15
+ # Print the loadpath, instance and global variables
16
+ #
17
+ def debug_variables
18
+ pp "Instance #{instance_variables}"
19
+ pp "Global #{global_variables}"
20
+ pp "Load Path #{$LOAD_PATH}"
21
+ # pp "Constants #{Module.constants}"
22
+ end
23
+
24
+ #
25
+ # Print information about the OpenHAB instance
26
+ #
27
+ def debug_openhab
28
+ logger.debug { "Things - Count #{things.size}" }
29
+ things.each do |thing|
30
+ logger.debug { "Thing:(#{thing.label}) UID:(#{thing.uid}) Channels(#{thing.channels.map(&:uid).join(', ')})" }
31
+ end
32
+ # logger.debug { $things.getAll.join(", ") }
33
+ end
34
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+ require 'core/log'
5
+ require 'core/dsl/monkey_patch/events'
6
+ require 'core/dsl/monkey_patch/ruby/ruby'
7
+ require 'core/dsl/monkey_patch/items/items'
8
+ require 'core/dsl/monkey_patch/types/types'
9
+ require 'core/dsl/monkey_patch/actions/actions'
10
+ require 'core/dsl/rule/rule'
11
+ require 'core/dsl/actions'
12
+ require 'core/dsl/timers'
13
+ require 'core/dsl/group'
14
+ require 'core/dsl/things'
15
+ require 'core/dsl/items/items'
16
+ require 'core/dsl/items/number_item'
17
+ require 'core/dsl/time_of_day'
18
+ require 'core/dsl/gems'
19
+ require 'core/dsl/units'
20
+ require 'core/dsl/types/quantity'
21
+ require 'core/dsl/states'
22
+
23
+ module OpenHAB
24
+ #
25
+ # Holds core functions for OpenHAB Helper Library
26
+ #
27
+ module Core
28
+ #
29
+ # Module to be extended to access the OpenHAB Ruby DSL
30
+ #
31
+ module DSL
32
+ # Extend the calling module/class with the DSL
33
+ def self.extended(base)
34
+ base.send :include, OpenHAB::Core::DSL::Rule
35
+ base.send :include, OpenHAB::Core::DSL::Items
36
+ base.send :include, OpenHAB::Core::DSL::Types
37
+ base.send :include, OpenHAB::Core::DSL::Groups
38
+ base.send :include, OpenHAB::Core::DSL::Units
39
+ base.send :include, OpenHAB::Core::DSL::Actions
40
+ base.send :include, OpenHAB::Core::DSL::Timers
41
+ base.send :include, OpenHAB::Core::DSL::States
42
+ base.send :include, OpenHAB::Core::DSL::Tod
43
+ base.send :include, Things
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+ require 'openhab/osgi'
5
+
6
+ module OpenHAB
7
+ module Core
8
+ module DSL
9
+ #
10
+ # Module to import and steramlime access to OpenHAB actions
11
+ #
12
+ module Actions
13
+ java_import org.openhab.core.library.types.PercentType
14
+ include Logging
15
+
16
+ OpenHAB::OSGI.services('org.openhab.core.model.script.engine.action.ActionService')&.each do |service|
17
+ java_import service.actionClass.to_s
18
+ logger.trace("Loaded ACTION: #{service.actionClass}")
19
+ end
20
+ # Import common actions
21
+ %w[Exec HTTP Ping].each { |action| java_import "org.openhab.core.model.script.actions.#{action}" }
22
+
23
+ #
24
+ # Return an OpenHAB Action object for the given scope and thing
25
+ #
26
+ # @param scope [String] The action scope
27
+ # @param thing_uid [String] Thing UID
28
+ #
29
+ # @return [Object] OpenHAB action
30
+ #
31
+ def actions(scope, thing_uid)
32
+ # rubocop: disable Style/GlobalVars
33
+ $actions.get(scope, thing_uid)
34
+ # rubocop: enable Style/GlobalVars
35
+ end
36
+
37
+ #
38
+ # Gets the list of action objects associated with a specific ThingUID
39
+ #
40
+ # @param [Java::org::openhab::core::thing::ThingUID] thing_uid to get associated actions for
41
+ #
42
+ # @return [Array] of action objects associated with thing_uid, may be empty
43
+ #
44
+ def actions_for_thing(thing_uid)
45
+ thing_uid = thing_uid.to_s
46
+ # rubocop: disable Style/GlobalVars
47
+ action_keys = $actions.action_keys
48
+ # rubocop: enable Style/GlobalVars
49
+ logger.trace( "Registered actions: '#{action_keys}' for thing '#{thing_uid}'")
50
+ action_keys.map { |action_key| action_key.split('-', 2) }
51
+ .select { |action_pair| action_pair.last == thing_uid }
52
+ .map(&:first)
53
+ .map { |scope| actions(scope, thing_uid) }
54
+ end
55
+
56
+ #
57
+ # Send notification to an email or broadcast
58
+ #
59
+ # @param msg [String] The notification message to send
60
+ # @param email [String] The email address to send to. If nil, the message will be broadcasted
61
+ #
62
+ # @return [void]
63
+ #
64
+ def notify(msg, email: nil)
65
+ unless defined? NotificationAction
66
+ raise NoMethodError, 'NotificationAction is not available. Please install the OpenHAB cloud addon'
67
+ end
68
+
69
+ if email
70
+ NotificationAction.sendNotification email, msg
71
+ else
72
+ NotificationAction.sendBroadcastNotification msg
73
+ end
74
+ end
75
+
76
+ #
77
+ # Say text via OpenHAB Text-To-Speech service, Voice.say()
78
+ #
79
+ # @param text [String] The text to say
80
+ # @param voice [String] Specify a particular voice to use
81
+ # @param sink [String] Specify a particular sink to output the speech
82
+ # @param volume [PercentType] Specify the volume for the speech
83
+ #
84
+ # @return [void]
85
+ #
86
+ def say(text, voice: nil, sink: nil, volume: nil)
87
+ volume = PercentType.new(volume&.to_i) unless volume.is_a?(PercentType) || volume.nil?
88
+ Voice.say text, voice, sink, volume
89
+ end
90
+
91
+ #
92
+ # Play an audio file via OpenHAB sound service, Audio.playSound()
93
+ #
94
+ # @param filename [String] The sound file to play
95
+ # @param sink [String] Specify a particular sink to output the speech
96
+ # @param volume [PercentType] Specify the volume for the speech
97
+ #
98
+ # @return [void]
99
+ #
100
+ def play_sound(filename, sink: nil, volume: nil)
101
+ volume = PercentType.new(volume&.to_i) unless volume.is_a?(PercentType) || volume.nil?
102
+ Audio.playSound sink, filename, volume
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end