openhab-scripting 4.20.0 → 4.21.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.
- checksums.yaml +4 -4
- data/lib/openhab/core/openhab_setup.rb +3 -3
- data/lib/openhab/core/thread_local.rb +6 -1
- data/lib/openhab/dsl/items/image_item.rb +1 -1
- data/lib/openhab/dsl/items/timed_command.rb +18 -11
- data/lib/openhab/dsl/rules/automation_rule.rb +19 -15
- data/lib/openhab/dsl/rules/cron_trigger_rule.rb +42 -0
- data/lib/openhab/dsl/rules/rule.rb +54 -24
- data/lib/openhab/dsl/rules/rule_config.rb +2 -15
- data/lib/openhab/dsl/rules/triggers/cron.rb +4 -4
- data/lib/openhab/dsl/timers/reentrant_timer.rb +2 -2
- data/lib/openhab/dsl/timers/timer.rb +9 -2
- data/lib/openhab/dsl/timers.rb +7 -4
- data/lib/openhab/log/logger.rb +66 -26
- data/lib/openhab/version.rb +1 -1
- data/lib/openhab.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 330baeb4ed7472cdf6c60ba060d0b4482f988fa72c8ff0dd33b00c3e2df28b4a
|
4
|
+
data.tar.gz: 35cab5382ecb542fcc90f02200c8ac977ccf4c1c880e2b644df2715c11fc36b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8c14ed23a21431328a55326313c06d16fdd0447426e741270d2f26ada96dee1425fb8e30da96b6d515b6c1406392ec56c2d3e598f5822b0a528273bacbbf441
|
7
|
+
data.tar.gz: 265d8939f4c02ccd883c006903d759c8f5208c6c80035a831344055c44c94880e703f76830ecd535464a8cbddd0d4e543cf5af23e35f379b3c532c9525cc9f2f
|
@@ -18,14 +18,14 @@ module OpenHAB
|
|
18
18
|
#
|
19
19
|
#
|
20
20
|
def self.wait_till_openhab_ready
|
21
|
-
logger.
|
21
|
+
logger.trace('Checking readyness of OpenHAB')
|
22
22
|
# rubocop: disable Style/GlobalVars
|
23
23
|
until $scriptExtension.get('automationManager')
|
24
|
-
logger.
|
24
|
+
logger.trace("Automation manager not loaded, checking again in #{CHECK_DELAY} seconds.")
|
25
25
|
sleep CHECK_DELAY
|
26
26
|
end
|
27
27
|
# rubocop: enable Style/GlobalVars
|
28
|
-
logger.
|
28
|
+
logger.trace 'Automation manager instantiated, OpenHAB ready for rule processing.'
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'openhab/log/logger'
|
4
|
+
|
3
5
|
# OpenHAB main module
|
4
6
|
module OpenHAB
|
5
7
|
module Core
|
@@ -7,15 +9,18 @@ module OpenHAB
|
|
7
9
|
# Manages thread local varaibles for access inside of blocks
|
8
10
|
#
|
9
11
|
module ThreadLocal
|
12
|
+
include OpenHAB::Log
|
13
|
+
|
10
14
|
#
|
11
15
|
# Execute the supplied block with the supplied values set for the currently running thread
|
12
16
|
# The previous values for each key are restored after the block is executed
|
13
17
|
#
|
14
|
-
# @param [Hash] Keys and values to set for running thread
|
18
|
+
# @param [Hash] Keys and values to set for running thread, if hash is nil no values are set
|
15
19
|
#
|
16
20
|
def thread_local(**values)
|
17
21
|
old_values = values.map { |key, _value| [key, Thread.current[key]] }.to_h
|
18
22
|
values.each { |key, value| Thread.current[key] = value }
|
23
|
+
logger.trace "Executing block with thread local context: #{values} - old context: #{old_values}"
|
19
24
|
yield
|
20
25
|
ensure
|
21
26
|
old_values.each { |key, value| Thread.current[key] = value }
|
@@ -33,7 +33,7 @@ module OpenHAB
|
|
33
33
|
#
|
34
34
|
#
|
35
35
|
def update_from_url(uri)
|
36
|
-
logger.
|
36
|
+
logger.trace("Downloading image from #{uri}")
|
37
37
|
response = Net::HTTP.get_response(URI(uri))
|
38
38
|
mime_type = response['content-type']
|
39
39
|
bytes = response.body
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'openhab/dsl/timers'
|
4
4
|
require 'openhab/dsl/rules/triggers/trigger'
|
5
|
+
require 'openhab/log/logger'
|
5
6
|
require 'java'
|
6
7
|
|
7
8
|
require_relative 'generic_item'
|
@@ -140,11 +141,15 @@ module OpenHAB
|
|
140
141
|
#
|
141
142
|
class TimedCommandCancelRule < Java::OrgOpenhabCoreAutomationModuleScriptRulesupportSharedSimple::SimpleRule
|
142
143
|
include OpenHAB::Log
|
144
|
+
include OpenHAB::Core::ThreadLocal
|
145
|
+
|
143
146
|
def initialize(timed_command_details, semaphore, &block)
|
144
147
|
super()
|
145
148
|
@semaphore = semaphore
|
146
149
|
@timed_command_details = timed_command_details
|
147
150
|
@block = block
|
151
|
+
# Capture rule name if known
|
152
|
+
@thread_locals = Thread.current[:RULE_NAME] ? { RULE_NAME: Thread.current[:RULE_NAME] } : {}
|
148
153
|
set_name("Cancels implicit timer for #{timed_command_details.item.id}")
|
149
154
|
set_triggers([OpenHAB::DSL::Rules::Triggers::Trigger.trigger(
|
150
155
|
type: OpenHAB::DSL::Rules::Triggers::Trigger::ITEM_STATE_UPDATE,
|
@@ -164,17 +169,19 @@ module OpenHAB
|
|
164
169
|
# There is no feasible way to break this method into smaller components
|
165
170
|
def execute(_mod = nil, inputs = nil)
|
166
171
|
@semaphore.synchronize do
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
172
|
+
thread_local(@thread_locals) do
|
173
|
+
logger.trace "Canceling implicit timer #{@timed_command_details.timer} for "\
|
174
|
+
"#{@timed_command_details.item.id} because received event #{inputs}"
|
175
|
+
@timed_command_details.timer.cancel
|
176
|
+
# rubocop: disable Style/GlobalVars
|
177
|
+
# Disabled due to OpenHAB design
|
178
|
+
$scriptExtension.get('ruleRegistry').remove(@timed_command_details.rule_uid)
|
179
|
+
# rubocop: enable Style/GlobalVars
|
180
|
+
TimedCommand.timed_commands.delete(@timed_command_details.item)
|
181
|
+
if @block
|
182
|
+
logger.trace 'Executing user supplied block on timed command cancelation'
|
183
|
+
@block&.call(@timed_command_details)
|
184
|
+
end
|
178
185
|
end
|
179
186
|
end
|
180
187
|
end
|
@@ -57,17 +57,19 @@ module OpenHAB
|
|
57
57
|
# @param [Map] inputs map provided by OpenHAB rules engine containing event and other information
|
58
58
|
#
|
59
59
|
#
|
60
|
-
def execute(mod = nil, inputs = nil)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
trigger_delay
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
60
|
+
def execute(mod = nil, inputs = nil) # rubocop:disable Metrics/MethodLength
|
61
|
+
thread_local(RULE_NAME: name) do
|
62
|
+
logger.trace { "Execute called with mod (#{mod&.to_string}) and inputs (#{inputs&.pretty_inspect})" }
|
63
|
+
logger.trace { "Event details #{inputs['event'].pretty_inspect}" } if inputs&.key?('event')
|
64
|
+
if trigger_delay inputs
|
65
|
+
trigger_delay = trigger_delay(inputs)
|
66
|
+
process_trigger_delay(trigger_delay, mod, inputs)
|
67
|
+
else
|
68
|
+
# If guards are satisfied execute the run type blocks
|
69
|
+
# If they are not satisfied, execute the Othewise blocks
|
70
|
+
queue = create_queue(inputs)
|
71
|
+
process_queue(queue, mod, inputs)
|
72
|
+
end
|
71
73
|
end
|
72
74
|
end
|
73
75
|
|
@@ -336,10 +338,12 @@ module OpenHAB
|
|
336
338
|
# @param [Task] task task containing otherwise block to execute
|
337
339
|
#
|
338
340
|
def process_task(event, task)
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
341
|
+
thread_local(RULE_NAME: name) do
|
342
|
+
case task
|
343
|
+
when RuleConfig::Run then process_run_task(event, task)
|
344
|
+
when RuleConfig::Trigger then process_trigger_task(event, task)
|
345
|
+
when RuleConfig::Otherwise then process_otherwise_task(event, task)
|
346
|
+
end
|
343
347
|
end
|
344
348
|
end
|
345
349
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'java'
|
4
|
+
require 'openhab/log/logger'
|
5
|
+
|
6
|
+
module OpenHAB
|
7
|
+
module DSL
|
8
|
+
#
|
9
|
+
# Creates and manages OpenHAB Rules
|
10
|
+
#
|
11
|
+
module Rules
|
12
|
+
#
|
13
|
+
# Specialized rule for cron triggers with attachments because OpenHAB does not provide trigger UID for cron rules
|
14
|
+
#
|
15
|
+
class CronTriggerRule < Java::OrgOpenhabCoreAutomationModuleScriptRulesupportSharedSimple::SimpleRule
|
16
|
+
include OpenHAB::Log
|
17
|
+
|
18
|
+
def initialize(rule_config:, rule:, trigger:)
|
19
|
+
super()
|
20
|
+
set_name("#{rule_config.name}-cron-#{trigger.id}")
|
21
|
+
set_triggers([trigger])
|
22
|
+
@rule = rule
|
23
|
+
@trigger = trigger
|
24
|
+
logger.trace("Created Cron Trigger Rule for #{@trigger}")
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Execute the rule
|
29
|
+
#
|
30
|
+
# @param [Map] mod map provided by OpenHAB rules engine
|
31
|
+
# @param [Map] inputs map provided by OpenHAB rules engine containing event and other information
|
32
|
+
#
|
33
|
+
#
|
34
|
+
def execute(mod = nil, _inputs = nil)
|
35
|
+
logger.trace "Trigger #{@trigger} fired for base rule #{@rule.inspect}"
|
36
|
+
inputs = { 'module' => @trigger.id }
|
37
|
+
@rule.execute(mod, inputs)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'openhab/
|
4
|
-
require 'openhab/
|
5
|
-
|
3
|
+
require 'openhab/core/thread_local'
|
4
|
+
require 'openhab/log/logger'
|
5
|
+
require_relative 'rule_config'
|
6
|
+
require_relative 'automation_rule'
|
7
|
+
require_relative 'cron_trigger_rule'
|
8
|
+
require_relative 'guard'
|
6
9
|
|
7
10
|
module OpenHAB
|
8
11
|
#
|
@@ -13,6 +16,9 @@ module OpenHAB
|
|
13
16
|
# Creates and manages OpenHAB Rules
|
14
17
|
#
|
15
18
|
module Rules
|
19
|
+
include OpenHAB::Core::ThreadLocal
|
20
|
+
include OpenHAB::Log
|
21
|
+
|
16
22
|
@script_rules = []
|
17
23
|
|
18
24
|
# rubocop: disable Style/GlobalVars
|
@@ -31,30 +37,22 @@ module OpenHAB
|
|
31
37
|
# @yield [] Block executed in context of a RuleConfig
|
32
38
|
#
|
33
39
|
#
|
40
|
+
# rubocop: disable Metrics/MethodLength
|
34
41
|
def rule(rule_name, &block)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
thread_local(RULE_NAME: rule_name) do
|
43
|
+
@rule_name = rule_name
|
44
|
+
config = RuleConfig.new(rule_name, block.binding)
|
45
|
+
config.instance_exec(config, &block)
|
46
|
+
config.guard = Guard::Guard.new(only_if: config.only_if, not_if: config.not_if)
|
47
|
+
logger.trace { config.inspect }
|
48
|
+
process_rule_config(config)
|
49
|
+
nil # Must return something other than the rule object. See https://github.com/boc-tothefuture/openhab-jruby/issues/438
|
50
|
+
end
|
42
51
|
rescue StandardError => e
|
52
|
+
puts "#{e.class}: #{e.message}"
|
43
53
|
re_raise_with_backtrace(e)
|
44
54
|
end
|
45
|
-
|
46
|
-
#
|
47
|
-
# Create a logger where name includes rule name if name is set
|
48
|
-
#
|
49
|
-
# @return [Log::Logger] Logger with name that appended with rule name if rule name is set
|
50
|
-
#
|
51
|
-
def logger
|
52
|
-
if @rule_name
|
53
|
-
Log.logger_for(@rule_name.chomp.gsub(/\s+/, '_'))
|
54
|
-
else
|
55
|
-
super
|
56
|
-
end
|
57
|
-
end
|
55
|
+
# rubocop: enable Metrics/MethodLength
|
58
56
|
|
59
57
|
#
|
60
58
|
# Cleanup rules in this script file
|
@@ -85,13 +83,44 @@ module OpenHAB
|
|
85
83
|
def process_rule_config(config)
|
86
84
|
return unless create_rule?(config)
|
87
85
|
|
86
|
+
cron_attach_triggers, other_triggers = partition_triggers(config)
|
87
|
+
logger.trace("Cron triggers: #{cron_attach_triggers} - Other triggers: #{other_triggers}")
|
88
|
+
config.triggers = other_triggers
|
89
|
+
|
88
90
|
rule = AutomationRule.new(config: config)
|
89
91
|
Rules.script_rules << rule
|
90
92
|
add_rule(rule)
|
93
|
+
|
94
|
+
process_cron_attach(cron_attach_triggers, config, rule)
|
95
|
+
|
91
96
|
rule.execute(nil, { 'event' => Struct.new(:attachment).new(config.start_attachment) }) if config.on_start?
|
92
97
|
rule
|
93
98
|
end
|
94
99
|
|
100
|
+
#
|
101
|
+
# Add cron triggers with attachments to rules
|
102
|
+
# @param [Array] cron_attach_triggers cron type triggers with attachments
|
103
|
+
#
|
104
|
+
def process_cron_attach(cron_attach_triggers, config, rule)
|
105
|
+
cron_attach_triggers&.map { |trigger| CronTriggerRule.new(rule_config: config, rule: rule, trigger: trigger) }
|
106
|
+
&.each { |trigger| add_rule(trigger) }
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# Partitions triggers in a config, removing cron triggers with a corresponding attachment
|
111
|
+
# so they can be used with CronTriggerRules to support attachments
|
112
|
+
# @return [Array] Two element array the first element is cron triggers with attachments,
|
113
|
+
# second element is other triggers
|
114
|
+
#
|
115
|
+
def partition_triggers(config)
|
116
|
+
config
|
117
|
+
.triggers
|
118
|
+
.partition do |trigger|
|
119
|
+
trigger.typeUID == OpenHAB::DSL::Rules::Triggers::Trigger::CRON &&
|
120
|
+
config.attachments.key?(trigger.id)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
95
124
|
#
|
96
125
|
# Should a rule be created based on rule configuration
|
97
126
|
#
|
@@ -105,7 +134,7 @@ module OpenHAB
|
|
105
134
|
elsif !execution_blocks?(config)
|
106
135
|
logger.warn "Rule '#{config.name}' has no execution blocks, not creating rule"
|
107
136
|
elsif !config.enabled
|
108
|
-
logger.
|
137
|
+
logger.trace "Rule '#{config.name}' marked as disabled, not creating rule."
|
109
138
|
else
|
110
139
|
return true
|
111
140
|
end
|
@@ -141,6 +170,7 @@ module OpenHAB
|
|
141
170
|
#
|
142
171
|
#
|
143
172
|
def add_rule(rule)
|
173
|
+
logger.trace("Adding rule: #{rule.inspect}")
|
144
174
|
Rules.automation_manager.addRule(rule)
|
145
175
|
end
|
146
176
|
end
|
@@ -33,7 +33,7 @@ module OpenHAB
|
|
33
33
|
extend OpenHAB::DSL
|
34
34
|
|
35
35
|
# @return [Array] Of triggers
|
36
|
-
|
36
|
+
attr_accessor :triggers
|
37
37
|
|
38
38
|
# @return [Array] Of trigger delays
|
39
39
|
attr_reader :trigger_delays
|
@@ -88,9 +88,9 @@ module OpenHAB
|
|
88
88
|
@trigger_delays = {}
|
89
89
|
@attachments = {}
|
90
90
|
@caller = caller_binding.eval 'self'
|
91
|
+
name(rule_name)
|
91
92
|
enabled(true)
|
92
93
|
on_start(false)
|
93
|
-
name(rule_name)
|
94
94
|
end
|
95
95
|
|
96
96
|
#
|
@@ -134,19 +134,6 @@ module OpenHAB
|
|
134
134
|
@caller.instance_eval(&block)
|
135
135
|
end
|
136
136
|
|
137
|
-
#
|
138
|
-
# Create a logger where name includes rule name if name is set
|
139
|
-
#
|
140
|
-
# @return [Log::Logger] Logger with name that appended with rule name if rule name is set
|
141
|
-
#
|
142
|
-
def logger
|
143
|
-
if name
|
144
|
-
Log.logger_for(name.chomp.gsub(/\s+/, '_'))
|
145
|
-
else
|
146
|
-
super
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
137
|
#
|
151
138
|
# Inspect the config object
|
152
139
|
#
|
@@ -68,13 +68,13 @@ module OpenHAB
|
|
68
68
|
# @param [Object] at TimeOfDay or String representing TimeOfDay in which to execute rule
|
69
69
|
#
|
70
70
|
#
|
71
|
-
def every(value, at: nil)
|
71
|
+
def every(value, at: nil, attach: nil)
|
72
72
|
cron_expression = case value
|
73
73
|
when Symbol then cron_from_symbol(value, at)
|
74
74
|
when Java::JavaTime::Duration then cron_from_duration(value, at)
|
75
75
|
else raise ArgumentExpression, 'Unknown interval'
|
76
76
|
end
|
77
|
-
cron(cron_expression)
|
77
|
+
cron(cron_expression, attach: attach)
|
78
78
|
end
|
79
79
|
|
80
80
|
#
|
@@ -82,8 +82,8 @@ module OpenHAB
|
|
82
82
|
#
|
83
83
|
# @param [String] expression OpenHAB style cron expression
|
84
84
|
#
|
85
|
-
def cron(expression)
|
86
|
-
|
85
|
+
def cron(expression, attach: nil)
|
86
|
+
append_trigger(Trigger::CRON, { 'cronExpression' => expression }, attach: attach)
|
87
87
|
end
|
88
88
|
|
89
89
|
private
|
@@ -25,12 +25,12 @@ module OpenHAB
|
|
25
25
|
# @param [Duration] duration Duration until timer should fire
|
26
26
|
# @param [Block] block Block to execute when timer fires
|
27
27
|
#
|
28
|
-
def initialize(duration:, id:, &block)
|
28
|
+
def initialize(duration:, id:, thread_locals: {}, &block)
|
29
29
|
raise 'Reentrant timers do not work in dynamically generated code' unless block.source_location
|
30
30
|
|
31
31
|
@id = id
|
32
32
|
@reentrant_id = self.class.reentrant_id(id: id, &block)
|
33
|
-
super(duration: duration, &block)
|
33
|
+
super(duration: duration, thread_locals: thread_locals, &block)
|
34
34
|
logger.trace("Created Reentrant Timer #{self} with reentrant Key #{@reentrant_id}")
|
35
35
|
end
|
36
36
|
|
@@ -4,6 +4,7 @@ require 'java'
|
|
4
4
|
require 'delegate'
|
5
5
|
require 'forwardable'
|
6
6
|
require 'openhab/log/logger'
|
7
|
+
require 'openhab/core/thread_local'
|
7
8
|
|
8
9
|
module OpenHAB
|
9
10
|
module DSL
|
@@ -22,6 +23,7 @@ module OpenHAB
|
|
22
23
|
# @since 2.0.0
|
23
24
|
class Timer < SimpleDelegator
|
24
25
|
include OpenHAB::Log
|
26
|
+
include OpenHAB::Core::ThreadLocal
|
25
27
|
extend Forwardable
|
26
28
|
|
27
29
|
def_delegator :@timer, :has_terminated, :terminated?
|
@@ -32,8 +34,10 @@ module OpenHAB
|
|
32
34
|
# @param [Duration] duration Duration until timer should fire
|
33
35
|
# @param [Block] block Block to execute when timer fires
|
34
36
|
#
|
35
|
-
|
37
|
+
# rubocop: disable Metrics/MethodLength
|
38
|
+
def initialize(duration:, thread_locals: {}, &block)
|
36
39
|
@duration = duration
|
40
|
+
@thread_locals = thread_locals
|
37
41
|
|
38
42
|
# A semaphore is used to prevent a race condition in which calling the block from the timer thread
|
39
43
|
# occurs before the @timer variable can be set resulting in @timer being nil
|
@@ -48,6 +52,7 @@ module OpenHAB
|
|
48
52
|
Timers.timer_manager.add(self)
|
49
53
|
end
|
50
54
|
end
|
55
|
+
# rubocop: enable Metrics/MethodLength
|
51
56
|
|
52
57
|
#
|
53
58
|
# Reschedule timer
|
@@ -86,7 +91,9 @@ module OpenHAB
|
|
86
91
|
proc {
|
87
92
|
semaphore.synchronize do
|
88
93
|
Timers.timer_manager.delete(self)
|
89
|
-
|
94
|
+
thread_local(@thread_locals) do
|
95
|
+
yield(self)
|
96
|
+
end
|
90
97
|
end
|
91
98
|
}
|
92
99
|
end
|
data/lib/openhab/dsl/timers.rb
CHANGED
@@ -29,9 +29,12 @@ module OpenHAB
|
|
29
29
|
# @return [Timer] Timer object
|
30
30
|
#
|
31
31
|
def after(duration, id: nil, &block)
|
32
|
-
|
32
|
+
# Carry rule name to timer thread
|
33
|
+
thread_locals = { RULE_NAME: Thread.current[:RULE_NAME] } if Thread.current[:RULE_NAME]
|
34
|
+
thread_locals ||= {}
|
35
|
+
return Timers.reentrant_timer(duration: duration, thread_locals: thread_locals, id: id, &block) if id
|
33
36
|
|
34
|
-
Timer.new(duration: duration, &block)
|
37
|
+
Timer.new(duration: duration, thread_locals: thread_locals, &block)
|
35
38
|
end
|
36
39
|
|
37
40
|
#
|
@@ -55,7 +58,7 @@ module OpenHAB
|
|
55
58
|
# @param [Object] id to associate with timer
|
56
59
|
# @param [Block] block to execute, block is passed a Timer object
|
57
60
|
# @return [ReentrantTimer] Timer object
|
58
|
-
def self.reentrant_timer(duration:, id:, &block)
|
61
|
+
def self.reentrant_timer(duration:, id:, thread_locals: nil, &block)
|
59
62
|
timer = @timer_manager.reentrant_timer(id: id, &block)
|
60
63
|
if timer
|
61
64
|
logger.trace("Reentrant timer found - #{timer}")
|
@@ -63,7 +66,7 @@ module OpenHAB
|
|
63
66
|
else
|
64
67
|
logger.trace('No reentrant timer found, creating new timer')
|
65
68
|
end
|
66
|
-
ReentrantTimer.new(duration: duration, id: id, &block)
|
69
|
+
ReentrantTimer.new(duration: duration, id: id, thread_locals: thread_locals, &block)
|
67
70
|
end
|
68
71
|
end
|
69
72
|
end
|
data/lib/openhab/log/logger.rb
CHANGED
@@ -127,6 +127,7 @@ module OpenHAB
|
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
|
+
# Logger caches
|
130
131
|
@loggers = {}
|
131
132
|
|
132
133
|
# Return a logger with the configured log prefix plus the calling scripts name
|
@@ -137,7 +138,7 @@ module OpenHAB
|
|
137
138
|
# @return [Logger] for the current class
|
138
139
|
#
|
139
140
|
def logger
|
140
|
-
Log.logger(self
|
141
|
+
Log.logger(self)
|
141
142
|
end
|
142
143
|
|
143
144
|
class << self
|
@@ -148,29 +149,51 @@ module OpenHAB
|
|
148
149
|
#
|
149
150
|
# @return [Logger] for the supplied name
|
150
151
|
#
|
151
|
-
def logger(
|
152
|
+
def logger(object)
|
153
|
+
# Cache logger instances for each object since construction
|
154
|
+
# of logger name requires lots of operations and logger
|
155
|
+
# names for some objects are specific to the class
|
156
|
+
logger_name = logger_name(object)
|
157
|
+
@loggers[logger_name] ||= Logger.new(logger_name)
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
# Construct the logger name from the supplied object
|
163
|
+
# @param [Object] object to construct logger name from
|
164
|
+
# @return name for logger based on object
|
165
|
+
def logger_name(object)
|
166
|
+
name = Configuration.log_prefix
|
167
|
+
name += rules_file || ''
|
168
|
+
name += rule_name || ''
|
169
|
+
name += klass_name(object) || ''
|
170
|
+
name.tr_s(' ', '_').gsub('::', '.')
|
171
|
+
end
|
172
|
+
|
173
|
+
# Get the class name for the supplied object
|
174
|
+
# @param [Object] object to derive class name for
|
175
|
+
# @return [String] name of class for logging
|
176
|
+
def klass_name(object)
|
177
|
+
object.then(&:class)
|
178
|
+
.then { |klass| java_klass(klass) }
|
179
|
+
.then(&:name)
|
180
|
+
.then { |name| filter_base_classes(name) }
|
181
|
+
.then { |name| name&.prepend('.') }
|
182
|
+
end
|
183
|
+
|
184
|
+
# Get the appropriate java class for the supplied klass if the supplied
|
185
|
+
# class is a java class
|
186
|
+
# @param [Class] klass to inspect
|
187
|
+
# @return Class or Java class of supplied class
|
188
|
+
def java_klass(klass)
|
152
189
|
if klass.respond_to?(:java_class) &&
|
153
190
|
klass.java_class &&
|
154
191
|
!klass.java_class.name.start_with?('org.jruby.Ruby')
|
155
192
|
klass = klass.java_class
|
156
193
|
end
|
157
|
-
|
158
|
-
@loggers[name] ||= Log.logger_for(name)
|
159
|
-
end
|
160
|
-
|
161
|
-
#
|
162
|
-
# Configure a logger for the supplied class name
|
163
|
-
#
|
164
|
-
# @param [String] name to configure logger for
|
165
|
-
#
|
166
|
-
# @return [Logger] for the supplied classname
|
167
|
-
#
|
168
|
-
def logger_for(name)
|
169
|
-
configure_logger_for(name)
|
194
|
+
klass
|
170
195
|
end
|
171
196
|
|
172
|
-
private
|
173
|
-
|
174
197
|
#
|
175
198
|
# Configure a logger for the supplied classname
|
176
199
|
#
|
@@ -178,16 +201,33 @@ module OpenHAB
|
|
178
201
|
#
|
179
202
|
# @return [Logger] Logger for the supplied classname
|
180
203
|
#
|
181
|
-
def
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
end
|
188
|
-
Logger.new(log_prefix)
|
204
|
+
def rules_file
|
205
|
+
# Each rules file gets its own context
|
206
|
+
# Set it once as a class value so that threads not
|
207
|
+
# tied to a rules file pick up the rules file they
|
208
|
+
# were spawned from
|
209
|
+
@rules_file ||= log_caller&.downcase&.prepend('.')
|
189
210
|
end
|
190
211
|
|
212
|
+
# Get the name of the rule from the thread context
|
213
|
+
def rule_name
|
214
|
+
Thread.current[:RULE_NAME]&.downcase&.prepend('.')
|
215
|
+
end
|
216
|
+
|
217
|
+
# Filter out the base classes of Object and Module from the log name
|
218
|
+
def filter_base_classes(klass_name)
|
219
|
+
return nil if %w[Object Module].include?(klass_name)
|
220
|
+
|
221
|
+
klass_name
|
222
|
+
end
|
223
|
+
|
224
|
+
# "#{rule_name.downcase}.#{klass_name}"
|
225
|
+
# if klass_name == 'Object'
|
226
|
+
# "rules.#{rules_file_name.downcase}"
|
227
|
+
# else
|
228
|
+
# "rules.#{rules_file_name.downcase}.#{klass_name}"
|
229
|
+
# end
|
230
|
+
|
191
231
|
#
|
192
232
|
# Figure out the log prefix
|
193
233
|
#
|
@@ -199,7 +239,7 @@ module OpenHAB
|
|
199
239
|
.grep_v(/rubygems/)
|
200
240
|
.grep_v(%r{lib/ruby})
|
201
241
|
.first
|
202
|
-
.
|
242
|
+
.then { |caller| File.basename(caller, '.*') if caller }
|
203
243
|
end
|
204
244
|
end
|
205
245
|
|
data/lib/openhab/version.rb
CHANGED
data/lib/openhab.rb
CHANGED
@@ -28,7 +28,7 @@ module OpenHAB
|
|
28
28
|
base.extend OpenHAB::DSL
|
29
29
|
|
30
30
|
base.send :include, OpenHAB::Core::ScriptHandlingCallbacks
|
31
|
-
logger.
|
31
|
+
logger.debug "OpenHAB JRuby Scripting Library Version #{OpenHAB::VERSION} Loaded"
|
32
32
|
|
33
33
|
OpenHAB::Core.add_rubylib_to_load_path
|
34
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openhab-scripting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian O'Connell
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,6 +94,7 @@ files:
|
|
94
94
|
- lib/openhab/dsl/monkey_patch/ruby/string.rb
|
95
95
|
- lib/openhab/dsl/persistence.rb
|
96
96
|
- lib/openhab/dsl/rules/automation_rule.rb
|
97
|
+
- lib/openhab/dsl/rules/cron_trigger_rule.rb
|
97
98
|
- lib/openhab/dsl/rules/guard.rb
|
98
99
|
- lib/openhab/dsl/rules/item_event.rb
|
99
100
|
- lib/openhab/dsl/rules/property.rb
|