openhab-jrubyscripting 5.0.0.rc2 → 5.0.0.rc4
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.
- checksums.yaml +4 -4
- data/lib/openhab/core/actions.rb +6 -2
- data/lib/openhab/core/items/generic_item.rb +13 -5
- data/lib/openhab/core/items/metadata/hash.rb +19 -35
- data/lib/openhab/core/items/persistence.rb +3 -1
- data/lib/openhab/core/items/semantics/enumerable.rb +6 -4
- data/lib/openhab/core/items/semantics.rb +18 -22
- data/lib/openhab/core/profile_factory.rb +15 -3
- data/lib/openhab/core/provider.rb +11 -4
- data/lib/openhab/core/rules/module.rb +26 -0
- data/lib/openhab/core/rules/provider.rb +40 -0
- data/lib/openhab/core/rules/registry.rb +76 -0
- data/lib/openhab/core/rules/rule.rb +150 -0
- data/lib/openhab/core/rules.rb +25 -0
- data/lib/openhab/core/script_handling.rb +32 -3
- data/lib/openhab/core/timer.rb +5 -7
- data/lib/openhab/core/types.rb +1 -1
- data/lib/openhab/core.rb +0 -16
- data/lib/openhab/core_ext/java/list.rb +436 -0
- data/lib/openhab/core_ext/java/map.rb +66 -0
- data/lib/openhab/core_ext/java/month.rb +1 -1
- data/lib/openhab/core_ext/java/zoned_date_time.rb +1 -2
- data/lib/openhab/core_ext/ruby/date.rb +3 -0
- data/lib/openhab/core_ext/ruby/date_time.rb +53 -0
- data/lib/openhab/core_ext/ruby/time.rb +88 -86
- data/lib/openhab/dsl/events/watch_event.rb +1 -1
- data/lib/openhab/dsl/items/builder.rb +8 -3
- data/lib/openhab/dsl/items/ensure.rb +6 -2
- data/lib/openhab/dsl/items/timed_command.rb +10 -11
- data/lib/openhab/dsl/rules/automation_rule.rb +36 -13
- data/lib/openhab/dsl/rules/builder.rb +100 -9
- data/lib/openhab/dsl/rules/name_inference.rb +0 -5
- data/lib/openhab/dsl/rules/rule_triggers.rb +1 -1
- data/lib/openhab/dsl/rules/terse.rb +1 -2
- data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +18 -54
- data/lib/openhab/dsl/rules/triggers/conditions/proc.rb +0 -3
- data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +1 -1
- data/lib/openhab/dsl/rules.rb +0 -21
- data/lib/openhab/dsl/thread_local.rb +2 -2
- data/lib/openhab/dsl/timer_manager.rb +3 -1
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/dsl.rb +12 -105
- data/lib/openhab/log.rb +9 -2
- data/lib/openhab/rspec/example_group.rb +42 -0
- data/lib/openhab/rspec/helpers.rb +31 -8
- data/lib/openhab/rspec/hooks.rb +6 -10
- data/lib/openhab/rspec/karaf.rb +50 -27
- data/lib/openhab/rspec/mocks/synchronous_executor.rb +11 -4
- data/lib/openhab/rspec/mocks/timer.rb +2 -1
- data/lib/openhab/rspec/suspend_rules.rb +4 -2
- metadata +24 -3
- data/lib/openhab/dsl/script_handling.rb +0 -6
@@ -0,0 +1,150 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module Core
|
5
|
+
module Rules
|
6
|
+
# @interface
|
7
|
+
java_import org.openhab.core.automation.Rule
|
8
|
+
|
9
|
+
#
|
10
|
+
# A {Rule} is a chunk of code that can execute when certain conditions are
|
11
|
+
# met, enabling the core dynamic functionality of openHAB.
|
12
|
+
#
|
13
|
+
module Rule
|
14
|
+
#
|
15
|
+
# @!method visible?
|
16
|
+
# Check if visibility == `VISIBLE`
|
17
|
+
# @return [true,false]
|
18
|
+
#
|
19
|
+
|
20
|
+
#
|
21
|
+
# @!method hidden?
|
22
|
+
# Check if visibility == `HIDDEN`
|
23
|
+
# @return [true,false]
|
24
|
+
#
|
25
|
+
|
26
|
+
#
|
27
|
+
# @!method expert?
|
28
|
+
# Check if visibility == `EXPERT`
|
29
|
+
# @return [true,false]
|
30
|
+
#
|
31
|
+
|
32
|
+
#
|
33
|
+
# @!method initializing?
|
34
|
+
# Check if rule status == `INITIALIZING`
|
35
|
+
# @return [true,false]
|
36
|
+
#
|
37
|
+
#
|
38
|
+
# @!method idle?
|
39
|
+
# Check if rule status == `IDLE`
|
40
|
+
# @return [true,false]
|
41
|
+
#
|
42
|
+
#
|
43
|
+
# @!method running?
|
44
|
+
# Check if rule status == `RUNNING`
|
45
|
+
# @return [true,false]
|
46
|
+
#
|
47
|
+
|
48
|
+
Visibility.constants.each do |visibility|
|
49
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
50
|
+
def #{visibility.to_s.downcase}? # def visibile?
|
51
|
+
visibility == Visibility::#{visibility} # visibility == Visibility::VISIBLE
|
52
|
+
end # end
|
53
|
+
RUBY
|
54
|
+
end
|
55
|
+
|
56
|
+
RuleStatus.constants.each do |status|
|
57
|
+
next if status == :UNINITIALIZED
|
58
|
+
|
59
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
60
|
+
def #{status.to_s.downcase}? # def initializing?
|
61
|
+
status == RuleStatus::#{status} # status == RuleStatus::INITIALIZING
|
62
|
+
end # end
|
63
|
+
RUBY
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Check if rule status == `UNINITIALIZED`
|
68
|
+
#
|
69
|
+
# @return [true,false]
|
70
|
+
#
|
71
|
+
def uninitialized?
|
72
|
+
s = status
|
73
|
+
s.nil? || s == RuleStatus::UNINITIALIZED
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Enable the Rule
|
78
|
+
#
|
79
|
+
# @param [true, false] enabled
|
80
|
+
# @return [void]
|
81
|
+
#
|
82
|
+
def enable(enabled: true)
|
83
|
+
Rules.manager.set_enabled(uid, enabled)
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# Disable the Rule
|
88
|
+
#
|
89
|
+
# @return [void]
|
90
|
+
#
|
91
|
+
def disable
|
92
|
+
enable(enabled: false)
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Check if the rule's status detail == `DISABLED`
|
97
|
+
#
|
98
|
+
# @return [true, false]
|
99
|
+
#
|
100
|
+
def disabled?
|
101
|
+
info = status_info
|
102
|
+
info.nil? || info.status_detail == RuleStatusDetail::DISABLED
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# @!attribute [r] status
|
107
|
+
# @return [RuleStatus nil]
|
108
|
+
#
|
109
|
+
def status
|
110
|
+
Rules.manager.get_status(uid)
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# @!attribute [r] status_info
|
115
|
+
# @return [RuleStatusInfo, nil]
|
116
|
+
#
|
117
|
+
def status_info
|
118
|
+
Rules.manager.get_status_info(uid)
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [String]
|
122
|
+
def inspect
|
123
|
+
r = "#<OpenHAB::Core::Rules::Rule #{uid}"
|
124
|
+
r += " #{name.inspect}" if name
|
125
|
+
r += " #{visibility}" unless visible?
|
126
|
+
r += " #{status || "<detached>"}"
|
127
|
+
r += " (#{status_info.status_detail})" if status_info && status_info.status_detail != RuleStatusDetail::NONE
|
128
|
+
r += " tags=#{tags.to_a.inspect}" unless tags.empty?
|
129
|
+
r += " configuration=#{configuration.properties.to_h}" if configuration && !configuration.properties.empty?
|
130
|
+
"#{r}>"
|
131
|
+
end
|
132
|
+
|
133
|
+
# @return [String]
|
134
|
+
def to_s
|
135
|
+
uid
|
136
|
+
end
|
137
|
+
|
138
|
+
#
|
139
|
+
# Manually trigger the rule
|
140
|
+
#
|
141
|
+
# @param [Object, nil] event The event to pass to the rule's execution blocks.
|
142
|
+
# @return [void]
|
143
|
+
#
|
144
|
+
def trigger(event = nil)
|
145
|
+
Rules.manager.run_now(uid, false, { "event" => event })
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module Core
|
5
|
+
#
|
6
|
+
# Contains the core {Rule} as well as related infrastructure.
|
7
|
+
#
|
8
|
+
module Rules
|
9
|
+
java_import org.openhab.core.automation.RuleStatus,
|
10
|
+
org.openhab.core.automation.RuleStatusInfo,
|
11
|
+
org.openhab.core.automation.RuleStatusDetail,
|
12
|
+
org.openhab.core.automation.Visibility
|
13
|
+
|
14
|
+
class << self
|
15
|
+
#
|
16
|
+
# @!attribute [r] rule_manager
|
17
|
+
# @return [org.openhab.core.automation.RuleManager] The OpenHAB rule manager/engine
|
18
|
+
#
|
19
|
+
def manager
|
20
|
+
@manager ||= OSGi.service("org.openhab.core.automation.RuleManager")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -29,9 +29,11 @@ module OpenHAB
|
|
29
29
|
# end
|
30
30
|
#
|
31
31
|
def script_loaded(&block)
|
32
|
-
|
32
|
+
ScriptHandlingCallbacks.script_loaded_hooks << block
|
33
33
|
end
|
34
34
|
|
35
|
+
#
|
36
|
+
# @!method script_unloaded(&block)
|
35
37
|
#
|
36
38
|
# Add a block of code to be executed when the script is unloaded.
|
37
39
|
#
|
@@ -47,8 +49,10 @@ module OpenHAB
|
|
47
49
|
# logger.info 'Hi, this script has been unloaded'
|
48
50
|
# end
|
49
51
|
#
|
50
|
-
def script_unloaded(&block)
|
51
|
-
|
52
|
+
def script_unloaded(before: nil, &block)
|
53
|
+
# `before` is as yet undocumented, because I'm not set on its interface
|
54
|
+
index = before.call(ScriptHandlingCallbacks.script_unloaded_hooks) if before
|
55
|
+
ScriptHandlingCallbacks.script_unloaded_hooks.insert(index || -1, block)
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
@@ -58,6 +62,13 @@ module OpenHAB
|
|
58
62
|
# @!visibility private
|
59
63
|
module ScriptHandlingCallbacks
|
60
64
|
class << self
|
65
|
+
#
|
66
|
+
# Has the script completed loading?
|
67
|
+
#
|
68
|
+
# @!visibility private
|
69
|
+
# @return [true, false]
|
70
|
+
attr_accessor :script_loaded
|
71
|
+
|
61
72
|
#
|
62
73
|
# Return script_loaded_hooks
|
63
74
|
#
|
@@ -74,6 +85,7 @@ module OpenHAB
|
|
74
85
|
@script_unloaded_hooks ||= []
|
75
86
|
end
|
76
87
|
end
|
88
|
+
self.script_loaded = false
|
77
89
|
|
78
90
|
#
|
79
91
|
# Executed when OpenHAB unloads a script file
|
@@ -85,6 +97,22 @@ module OpenHAB
|
|
85
97
|
rescue => e
|
86
98
|
logger.error("Failed to call script_unloaded hook #{hook}: #{e}")
|
87
99
|
end
|
100
|
+
|
101
|
+
return if ScriptHandlingCallbacks.script_loaded
|
102
|
+
|
103
|
+
# Make sure we terminate the main thread if it's still set up, in case
|
104
|
+
# it's timing out and that's why we're unloading.
|
105
|
+
#
|
106
|
+
# It would seem simpler to just record Thread.current when this file
|
107
|
+
# loads, but if the user is using the autorequire feature of the
|
108
|
+
# jrubyscripting addon, this file will load before the main script.
|
109
|
+
#
|
110
|
+
# Note that Thread.list only includes threads that have had Ruby
|
111
|
+
# execute in them, so we don't need to worry about accidentally killing
|
112
|
+
# a random Java thread.
|
113
|
+
#
|
114
|
+
main_thread = Thread.list.find { |t| t != Thread.current && t.name.include?("-safeCall-") }
|
115
|
+
main_thread&.raise(Interrupt.new)
|
88
116
|
end
|
89
117
|
|
90
118
|
#
|
@@ -97,6 +125,7 @@ module OpenHAB
|
|
97
125
|
rescue => e
|
98
126
|
logger.error("Failed to call script_loaded hook #{hook}: #{e}")
|
99
127
|
end
|
128
|
+
ScriptHandlingCallbacks.script_loaded = true
|
100
129
|
end
|
101
130
|
end
|
102
131
|
end
|
data/lib/openhab/core/timer.rb
CHANGED
@@ -35,7 +35,6 @@ module OpenHAB
|
|
35
35
|
# @return [Object, nil]
|
36
36
|
attr_accessor :id
|
37
37
|
|
38
|
-
# @!visibility private
|
39
38
|
# @!visibility private
|
40
39
|
attr_reader :block
|
41
40
|
|
@@ -84,6 +83,7 @@ module OpenHAB
|
|
84
83
|
# @return [self]
|
85
84
|
#
|
86
85
|
def reschedule(time = nil)
|
86
|
+
Thread.current[:openhab_rescheduled_timer] = true if Thread.current[:openhab_rescheduled_timer] == self
|
87
87
|
DSL.timers.add(self)
|
88
88
|
@timer.reschedule(new_execution_time(time || @time))
|
89
89
|
self
|
@@ -119,12 +119,10 @@ module OpenHAB
|
|
119
119
|
# @return [void]
|
120
120
|
#
|
121
121
|
def execute
|
122
|
-
|
123
|
-
DSL::ThreadLocal.thread_local(**@thread_locals)
|
124
|
-
|
125
|
-
|
126
|
-
# don't remove ourselves if we were rescheduled in the block
|
127
|
-
DSL.timers.delete(self) if execution_time == last_execution_time
|
122
|
+
Thread.current[:openhab_rescheduled_timer] = self
|
123
|
+
DSL::ThreadLocal.thread_local(**@thread_locals) { @block.call(self) }
|
124
|
+
DSL.timers.delete(self) unless Thread.current[:openhab_rescheduled_timer] == true
|
125
|
+
Thread.current[:openhab_rescheduled_timer] = nil
|
128
126
|
end
|
129
127
|
|
130
128
|
#
|
data/lib/openhab/core/types.rb
CHANGED
@@ -13,7 +13,7 @@ module OpenHAB
|
|
13
13
|
# Types are the specific data types that commands and states are. They can be
|
14
14
|
# sent to items, be the current state of an item, or be the `command`, `state`,
|
15
15
|
# and `was` field of various
|
16
|
-
# {group::OpenHAB::DSL::Rules::
|
16
|
+
# {group::OpenHAB::DSL::Rules::BuilderDSL::Triggers triggers}.
|
17
17
|
# Some types have additional useful methods.
|
18
18
|
#
|
19
19
|
module Types
|
data/lib/openhab/core.rb
CHANGED
@@ -53,22 +53,6 @@ module OpenHAB
|
|
53
53
|
def automation_manager
|
54
54
|
$scriptExtension.get("automationManager")
|
55
55
|
end
|
56
|
-
|
57
|
-
#
|
58
|
-
# @!attribute [r] rule_registry
|
59
|
-
# @return [org.openhab.core.automation.RuleRegistry] The OpenHAB rule registry
|
60
|
-
#
|
61
|
-
def rule_registry
|
62
|
-
$scriptExtension.get("ruleRegistry")
|
63
|
-
end
|
64
|
-
|
65
|
-
#
|
66
|
-
# @!attribute [r] rule_manager
|
67
|
-
# @return [org.openhab.core.automation.RuleManager] The OpenHAB rule manager/engine
|
68
|
-
#
|
69
|
-
def rule_manager
|
70
|
-
@rule_manager ||= OSGi.service("org.openhab.core.automation.RuleManager")
|
71
|
-
end
|
72
56
|
end
|
73
57
|
end
|
74
58
|
end
|