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,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bigdecimal'
4
+ require 'forwardable'
5
+ require 'java'
6
+
7
+ module OpenHAB
8
+ module Core
9
+ module DSL
10
+ module Items
11
+ #
12
+ # Delegator to OpenHAB String Item
13
+ #
14
+ class StringItem
15
+ extend Forwardable
16
+ include Comparable
17
+
18
+ BLANK_RE = /\A[[:space:]]*\z/.freeze
19
+ private_constant :BLANK_RE
20
+
21
+ def_delegator :@string_item, :to_s
22
+
23
+ #
24
+ # Create a new StringItem
25
+ #
26
+ # @param [Java::Org::openhab::core::library::items::StringItem] string_item OpenHAB string item to delegate to
27
+ #
28
+ def initialize(string_item)
29
+ @string_item = string_item
30
+ super()
31
+ end
32
+
33
+ #
34
+ # Convert the StringItem into a String
35
+ #
36
+ # @return [String] String representation of the StringItem or nil if underlying OpenHAB StringItem does not have a state
37
+ #
38
+ def to_str
39
+ @string_item.state&.to_full_string&.to_s
40
+ end
41
+
42
+ #
43
+ # Detect if the string is blank (not set or only whitespace)
44
+ #
45
+ # @return [Boolean] True if string item is not set or contains only whitespace, false otherwise
46
+ #
47
+ def blank?
48
+ return true unless @string_item.state?
49
+
50
+ @string_item.state.to_full_string.to_s.empty? || BLANK_RE.match?(self)
51
+ end
52
+
53
+ #
54
+ # Check if StringItem is truthy? as per defined by library
55
+ #
56
+ # @return [Boolean] True if item is not in state UNDEF or NULL and value is not blank
57
+ #
58
+ def truthy?
59
+ @string_item.state? && blank? == false
60
+ end
61
+
62
+ #
63
+ # Compare StringItem to supplied object
64
+ #
65
+ # @param [Object] other object to compare to
66
+ #
67
+ # @return [Integer] -1,0,1 or nil depending on value supplied, nil comparison to supplied object is not possible.
68
+ #
69
+ def <=>(other)
70
+ case other
71
+ when StringItem
72
+ @string_item.state <=> other.state
73
+ when String
74
+ @string_item.state.to_s <=> other
75
+ end
76
+ end
77
+
78
+ #
79
+ # Forward missing methods to Openhab String Item or String representation of the item if they are defined
80
+ #
81
+ # @param [String] meth method name
82
+ # @param [Array] args arguments for method
83
+ # @param [Proc] block <description>
84
+ #
85
+ # @return [Object] Value from delegated method in OpenHAB StringItem or Ruby String
86
+ #
87
+ def method_missing(meth, *args, &block)
88
+ if @string_item.respond_to?(meth)
89
+ @string_item.__send__(meth, *args, &block)
90
+ elsif @string_item.state? && @string_item.state.to_full_string.to_s.respond_to?(meth)
91
+ @string_item.state.to_full_string.to_s.__send__(meth, *args, &block)
92
+ elsif ::Kernel.method_defined?(meth) || ::Kernel.private_method_defined?(meth)
93
+ ::Kernel.instance_method(meth).bind_call(self, *args, &block)
94
+ else
95
+ super(meth, *args, &block)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Monkey patch actions
4
+ require 'openhab/core/dsl/monkey_patch/actions/script_thing_actions'
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+
5
+ #
6
+ # MonkeyPatching ScriptThingActions
7
+ #
8
+ # rubocop:disable Style/ClassAndModuleChildren
9
+ class Java::OrgOpenhabCoreAutomationModuleScriptInternalDefaultscope::ScriptThingActions
10
+ # rubocop:enable Style/ClassAndModuleChildren
11
+
12
+ field_reader :THING_ACTIONS_MAP
13
+
14
+ #
15
+ # Fetch keys for all actions defined in OpenHAB
16
+ #
17
+ # @return [Set] of keys for defined actions in the form of 'scope-thing_uid'
18
+ #
19
+ def action_keys
20
+ Java::OrgOpenhabCoreAutomationModuleScriptInternalDefaultscope::ScriptThingActions.THING_ACTIONS_MAP.keys
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'core/dsl/monkey_patch/events/item_state_changed'
4
+ require 'core/dsl/monkey_patch/events/thing_status_info'
5
+ require 'core/dsl/monkey_patch/events/item_command'
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+
5
+ #
6
+ # Monkey patch with ruby style accesors
7
+ #
8
+ # rubocop:disable Style/ClassAndModuleChildren
9
+ class Java::OrgOpenhabCoreItemsEvents::ItemCommandEvent
10
+ # rubocop:enable Style/ClassAndModuleChildren
11
+
12
+ alias command item_command
13
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+
5
+ #
6
+ # MonkeyPatch with ruby style accessors
7
+ #
8
+ # rubocop:disable Style/ClassAndModuleChildren
9
+ class Java::OrgOpenhabCoreItemsEvents::ItemStateChangedEvent
10
+ # rubocop:enable Style/ClassAndModuleChildren
11
+
12
+ #
13
+ # Get the item that caused the state change
14
+ #
15
+ # @return [Item] Item that caused state change
16
+ #
17
+ def item
18
+ # rubocop:disable Style/GlobalVars
19
+ $ir.get(item_name)
20
+ # rubocop:enable Style/GlobalVars
21
+ end
22
+
23
+ alias state item_state
24
+ alias last old_item_state
25
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+
5
+ #
6
+ # Monkey patch with ruby style accessors
7
+ #
8
+ # rubocop:disable Style/ClassAndModuleChildren
9
+ class Java::OrgOpenhabCoreThingEvents::ThingStatusInfoChangedEvent
10
+ # rubocop:enable Style/ClassAndModuleChildren
11
+
12
+ alias uid get_thing_uid
13
+ alias last get_old_status_info
14
+ alias status status_info
15
+ end
16
+
17
+ #
18
+ # Monkey patch with ruby style accessors
19
+ #
20
+ # rubocop:disable Style/ClassAndModuleChildren
21
+ class Java::OrgOpenhabCoreThingEvents::ThingStatusInfoEvent
22
+ # rubocop:enable Style/ClassAndModuleChildren
23
+
24
+ alias uid get_thing_uid
25
+ alias status status_info
26
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+
5
+ # Alias for is_a? testing
6
+ java_import org.openhab.core.library.items.ContactItem
7
+
8
+ #
9
+ # Alias class for ContactItem
10
+ #
11
+ Contact = ContactItem
12
+
13
+ #
14
+ # Monkey patch Contact Item with Ruby methods
15
+ #
16
+ # rubocop:disable Style/ClassAndModuleChildren
17
+ class Java::OrgOpenhabCoreLibraryItems::ContactItem
18
+ java_import org.openhab.core.library.types.OpenClosedType
19
+ # rubocop:enable Style/ClassAndModuleChildren
20
+
21
+ #
22
+ # Check if the contact is open
23
+ #
24
+ # @return [Boolean] True if contact has state and is open, false otherwise
25
+ #
26
+ def open?
27
+ state? && state == OpenClosedType::OPEN
28
+ end
29
+
30
+ #
31
+ # Check if the contact is closed
32
+ #
33
+ # @return [Boolean] True if contact has state and is closed, false otherwise
34
+ #
35
+ def closed?
36
+ state? && state == OpenClosedType::CLOSED
37
+ end
38
+
39
+ #
40
+ # Compares contacts to OpenClosedTypes
41
+ #
42
+ # @param [Object] other object to compare to
43
+ #
44
+ # @return [Boolean] True if contact has a state and state equals other, nil if no state,
45
+ # result from super if not supplied an OpenClosedType
46
+ #
47
+ def ==(other)
48
+ if other.is_a? OpenClosedType
49
+ state? && state == other
50
+ else
51
+ super
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+
5
+ java_import org.openhab.core.library.items.DimmerItem
6
+
7
+ #
8
+ # Alias class for is_a? testing
9
+ #
10
+ Dimmer = DimmerItem
11
+
12
+ #
13
+ # Monkey Patch DimmerItem
14
+ #
15
+ # rubocop:disable Style/ClassAndModuleChildren
16
+ class Java::OrgOpenhabCoreLibraryItems::DimmerItem
17
+ # rubocop:enable Style/ClassAndModuleChildren
18
+ java_import org.openhab.core.library.types.DecimalType
19
+ java_import org.openhab.core.library.types.IncreaseDecreaseType
20
+
21
+ #
22
+ # Add the current dimmer value to the supplied object
23
+ #
24
+ # @param [Object] other object to add the dimmer value to
25
+ #
26
+ # @return [Integer] Current dimmer value plus value of supplied object
27
+ #
28
+ def +(other)
29
+ return unless state?
30
+
31
+ state.to_big_decimal.intValue + other
32
+ end
33
+
34
+ #
35
+ # Subtract the supplied object from the current value of the dimmer
36
+ #
37
+ # @param [Object] other object to subtract from the dimmer value
38
+ #
39
+ # @return [Integer] Current dimmer value minus value of supplied object
40
+ #
41
+ def -(other)
42
+ return unless state?
43
+
44
+ state.to_big_decimal.intValue - other
45
+ end
46
+
47
+ #
48
+ # Dim the dimmer
49
+ #
50
+ # @param [Integer] amount to dim by
51
+ #
52
+ # @return [Integer] level target for dimmer
53
+ #
54
+ def dim(amount = 1)
55
+ return unless state?
56
+
57
+ target = [state.to_big_decimal.intValue - amount, 0].max
58
+
59
+ if amount == 1
60
+ command(IncreaseDecreaseType::DECREASE)
61
+ else
62
+ command(target)
63
+ end
64
+
65
+ target
66
+ end
67
+
68
+ #
69
+ # Brighten the dimmer
70
+ #
71
+ # @param [Integer] amount to brighten by
72
+ #
73
+ # @return [Integer] level target for dimmer
74
+ #
75
+ def brighten(amount = 1)
76
+ return unless state?
77
+
78
+ target = state.to_big_decimal.intValue + amount
79
+
80
+ if amount == 1
81
+ command(IncreaseDecreaseType::INCREASE)
82
+ else
83
+ command(target)
84
+ end
85
+ target
86
+ end
87
+
88
+ #
89
+ # Check if dimmer has a state and state is not zero
90
+ #
91
+ # @return [Boolean] True if dimmer is not NULL or UNDEF and value is not 0
92
+ #
93
+ def truthy?
94
+ state? && state != DecimalType::ZERO
95
+ end
96
+
97
+ #
98
+ # Value of dimmer
99
+ #
100
+ # @return [Integer] Value of dimmer or nil if state is UNDEF or NULL
101
+ #
102
+ def to_i
103
+ state&.to_big_decimal&.intValue
104
+ end
105
+
106
+ alias to_int to_i
107
+
108
+ #
109
+ # Check if dimmer is on
110
+ #
111
+ # @return [Boolean] True if item is not UNDEF or NULL and has a value greater than 0
112
+ #
113
+ def on?
114
+ state&.to_big_decimal&.intValue&.positive?
115
+ end
116
+
117
+ #
118
+ # Check if dimmer is off
119
+ #
120
+ # @return [Boolean] True if item is not UNDEF or NULL and has a state of 0
121
+ #
122
+ def off?
123
+ state&.to_big_decimal&.intValue&.zero?
124
+ end
125
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Monkey patch Group Item
5
+ #
6
+ # rubocop:disable Style/ClassAndModuleChildren
7
+ class Java::OrgOpenhabCoreItems::GroupItem
8
+ # rubocop:enable Style/ClassAndModuleChildren
9
+
10
+ #
11
+ # Get all items in a group
12
+ #
13
+ # @return [Array] Array of items in the group
14
+ #
15
+ def items
16
+ to_a
17
+ end
18
+
19
+ #
20
+ # Get all items in the group as an Array
21
+ #
22
+ # @return [Array] All items in the group
23
+ #
24
+ def to_a
25
+ all_members.each_with_object([]) { |item, arr| arr << item }
26
+ end
27
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'java'
4
+ require 'openhab/core/log'
5
+ require 'bigdecimal'
6
+
7
+ # Monkey patch items
8
+ require 'openhab/core/dsl/monkey_patch/items/metadata'
9
+ require 'openhab/core/dsl/monkey_patch/items/contact_item'
10
+ require 'openhab/core/dsl/monkey_patch/items/dimmer_item'
11
+ require 'openhab/core/dsl/monkey_patch/items/switch_item'
12
+ require 'openhab/core/dsl/monkey_patch/items/group_item'
13
+
14
+ module OpenHAB
15
+ module Core
16
+ module DSL
17
+ module MonkeyPatch
18
+ #
19
+ # Monkeypatches Items
20
+ #
21
+ module Items
22
+ #
23
+ # Extensions for Items
24
+ #
25
+ module ItemExtensions
26
+ include Logging
27
+ java_import org.openhab.core.model.script.actions.BusEvent
28
+ java_import org.openhab.core.types.UnDefType
29
+
30
+ #
31
+ # Send a command to this item
32
+ #
33
+ # @param [Object] command to send to object
34
+ #
35
+ #
36
+ def command(command)
37
+ command = command.to_java.strip_trailing_zeros if command.is_a? BigDecimal
38
+ logger.trace "Sending Command #{command} to #{id}"
39
+ BusEvent.sendCommand(self, command.to_s)
40
+ end
41
+
42
+ alias << command
43
+
44
+ #
45
+ # Send an update to this item
46
+ #
47
+ # @param [Object] update the item
48
+ #
49
+ #
50
+ def update(update)
51
+ logger.trace "Sending Update #{update} to #{id}"
52
+ BusEvent.postUpdate(self, update.to_s)
53
+ end
54
+
55
+ #
56
+ # Check if the item state == UNDEF
57
+ #
58
+ # @return [Boolean] True if the state is UNDEF, false otherwise
59
+ #
60
+ def undef?
61
+ # Need to explicitly call the super method version because this state will never return UNDEF
62
+ method(:state).super_method.call == UnDefType::UNDEF
63
+ end
64
+
65
+ #
66
+ # Check if the item state == NULL
67
+ #
68
+ # @return [Boolean] True if the state is NULL, false otherwise
69
+ def null?
70
+ # Need to explicitly call the super method version because this state will never return NULL
71
+ method(:state).super_method.call == UnDefType::NULL
72
+ end
73
+
74
+ #
75
+ # Check if the item has a state (not UNDEF or NULL)
76
+ #
77
+ # @return [Boolean] True if state is not UNDEF or NULL
78
+ #
79
+ def state?
80
+ undef? == false && null? == false
81
+ end
82
+
83
+ #
84
+ # Get the item state
85
+ #
86
+ # @return [State] OpenHAB item state if state is not UNDEF or NULL, nil otherwise
87
+ #
88
+ def state
89
+ super if state?
90
+ end
91
+
92
+ #
93
+ # Get an ID for the item, using the item label if set, otherwise item name
94
+ #
95
+ # @return [String] label if set otherwise name
96
+ #
97
+ def id
98
+ label || name
99
+ end
100
+
101
+ #
102
+ # Get the string representation of the state of the item
103
+ #
104
+ # @return [String] State of the item as a string if not UNDEF or NULL, nil otherwise
105
+ #
106
+ def to_s
107
+ state&.to_s
108
+ end
109
+
110
+ #
111
+ # Inspect the item
112
+ #
113
+ # @return [String] details of the item
114
+ #
115
+ def inspect
116
+ toString
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ # rubocop:disable Style/ClassAndModuleChildren
126
+ class Java::OrgOpenhabCoreItems::GenericItem
127
+ # rubocop:enable Style/ClassAndModuleChildren
128
+ prepend OpenHAB::Core::DSL::MonkeyPatch::Items::ItemExtensions
129
+ prepend OpenHAB::Core::DSL::MonkeyPatch::Items::Metadata
130
+ end