rsmp 0.1.19 → 0.1.21
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/Gemfile.lock +10 -10
- data/documentation/{classes.md → classes_and_modules.md} +25 -22
- data/documentation/message_distribution.md +23 -0
- data/lib/rsmp.rb +9 -5
- data/lib/rsmp/archive.rb +5 -13
- data/lib/rsmp/{probe.rb → collector.rb} +31 -42
- data/lib/rsmp/{site_base.rb → components.rb} +2 -2
- data/lib/rsmp/listener.rb +33 -0
- data/lib/rsmp/logger.rb +3 -3
- data/lib/rsmp/{base.rb → logging.rb} +2 -2
- data/lib/rsmp/node.rb +4 -6
- data/lib/rsmp/notifier.rb +24 -0
- data/lib/rsmp/proxy.rb +25 -5
- data/lib/rsmp/site.rb +2 -2
- data/lib/rsmp/site_proxy.rb +66 -84
- data/lib/rsmp/site_proxy_wait.rb +181 -0
- data/lib/rsmp/supervisor.rb +2 -2
- data/lib/rsmp/supervisor_proxy.rb +0 -1
- data/lib/rsmp/tlc.rb +20 -4
- data/lib/rsmp/version.rb +1 -1
- data/lib/rsmp/wait.rb +4 -151
- data/rsmp.gemspec +4 -4
- metadata +22 -19
- data/lib/rsmp/probe_collection.rb +0 -28
data/lib/rsmp/supervisor.rb
CHANGED
@@ -117,17 +117,17 @@ module RSMP
|
|
117
117
|
level: :info,
|
118
118
|
timestamp: RSMP.now_object
|
119
119
|
|
120
|
+
settings = @supervisor_settings['sites'][info[:ip]] || @supervisor_settings['sites'][:any]
|
120
121
|
proxy = build_proxy({
|
121
122
|
supervisor: self,
|
122
123
|
task: @task,
|
123
|
-
settings:
|
124
|
+
settings: settings,
|
124
125
|
socket: socket,
|
125
126
|
info: info,
|
126
127
|
logger: @logger,
|
127
128
|
archive: @archive
|
128
129
|
})
|
129
130
|
@proxies.push proxy
|
130
|
-
|
131
131
|
proxy.run # will run until the site disconnects
|
132
132
|
ensure
|
133
133
|
@proxies.delete proxy
|
data/lib/rsmp/tlc.rb
CHANGED
@@ -125,18 +125,29 @@ module RSMP
|
|
125
125
|
|
126
126
|
def handle_m0005 arg
|
127
127
|
@node.verify_security_code 2, arg['securityCode']
|
128
|
-
@emergency_route = arg['status'] == 'True'
|
128
|
+
@emergency_route = (arg['status'] == 'True')
|
129
129
|
@emergency_route_number = arg['emergencyroute'].to_i
|
130
|
+
|
131
|
+
if @emergency_route
|
132
|
+
log "Switching to emergency route #{@emergency_route_number}", level: :info
|
133
|
+
else
|
134
|
+
log "Switching off emergency route", level: :info
|
135
|
+
end
|
130
136
|
end
|
131
137
|
|
132
138
|
def handle_m0006 arg
|
133
139
|
@node.verify_security_code 2, arg['securityCode']
|
134
140
|
input = arg['input'].to_i
|
135
141
|
idx = input - 1
|
136
|
-
return unless idx>=0 && input<@num_inputs
|
142
|
+
return unless idx>=0 && input<@num_inputs # TODO should NotAck
|
137
143
|
@input_activations[idx] = (arg['status']=='True' ? '1' : '0')
|
138
144
|
result = @input_activations[idx]=='1' || @inputs[idx]=='1'
|
139
145
|
@input_results[idx] = (result ? '1' : '0')
|
146
|
+
if @input_activations[idx]
|
147
|
+
log "Activate input #{idx}", level: :info
|
148
|
+
else
|
149
|
+
log "Deactivate input #{idx}", level: :info
|
150
|
+
end
|
140
151
|
end
|
141
152
|
|
142
153
|
def handle_m0007 arg
|
@@ -203,8 +214,13 @@ module RSMP
|
|
203
214
|
end
|
204
215
|
|
205
216
|
def switch_plan plan
|
206
|
-
|
207
|
-
|
217
|
+
plan_nr = plan.to_i
|
218
|
+
if plan_nr == 0
|
219
|
+
log "Switching to plan selection by time table", level: :info
|
220
|
+
else
|
221
|
+
log "Switching to plan #{plan_nr}", level: :info
|
222
|
+
end
|
223
|
+
@plan = plan_nr
|
208
224
|
end
|
209
225
|
|
210
226
|
def switch_mode mode
|
data/lib/rsmp/version.rb
CHANGED
data/lib/rsmp/wait.rb
CHANGED
@@ -1,163 +1,16 @@
|
|
1
|
-
# Helper for waiting for an Async condition using a block
|
2
|
-
|
3
1
|
module RSMP
|
4
2
|
module Wait
|
5
|
-
|
3
|
+
# wait for an async condition to signal, then yield to block
|
4
|
+
# if block returns true we're done. otherwise, wait again
|
6
5
|
def wait_for condition, timeout, &block
|
7
|
-
raise RuntimeError.new("Can't wait for
|
6
|
+
raise RuntimeError.new("Can't wait for condition because task is not running") unless @task.running?
|
8
7
|
@task.with_timeout(timeout) do
|
9
|
-
while task.running? do
|
8
|
+
while @task.running? do
|
10
9
|
value = condition.wait
|
11
10
|
result = yield value
|
12
11
|
return result if result # return result of check, if not nil
|
13
12
|
end
|
14
13
|
end
|
15
14
|
end
|
16
|
-
|
17
|
-
def capture_status_updates_or_responses task, type, options, m_id
|
18
|
-
task.annotate "wait for status update/response"
|
19
|
-
want = convert_status_list options[:status_list]
|
20
|
-
result = {}
|
21
|
-
# wait for a status update
|
22
|
-
item = @archive.capture(task,options.merge({
|
23
|
-
type: [type,'MessageNotAck'],
|
24
|
-
num: 1
|
25
|
-
})) do |item|
|
26
|
-
message = item[:message]
|
27
|
-
if message.is_a?(MessageNotAck) && message.attribute('oMId') == m_id
|
28
|
-
# set result to an exception, but don't raise it.
|
29
|
-
# this will be returned by the task and stored as the task result
|
30
|
-
# when the parent task call wait() on the task, the exception
|
31
|
-
# will be raised in the parent task, and caught by rspec.
|
32
|
-
# rspec will then show the error and record the test as failed
|
33
|
-
m_id_short = RSMP::Message.shorten_m_id m_id, 8
|
34
|
-
result = RSMP::MessageRejected.new "Status request #{m_id_short} was rejected: #{message.attribute('rea')}"
|
35
|
-
next true # done, no more messages wanted
|
36
|
-
end
|
37
|
-
found = []
|
38
|
-
# look through querues
|
39
|
-
want.each_with_index do |query,i|
|
40
|
-
# look through status items in message
|
41
|
-
item[:message].attributes['sS'].each do |input|
|
42
|
-
ok = status_match? query, input
|
43
|
-
if ok
|
44
|
-
result[query] = input
|
45
|
-
found << i # record which queries where matched succesfully
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
# remove queries that where matched
|
50
|
-
found.sort.reverse.each do |i|
|
51
|
-
want.delete_at i
|
52
|
-
end
|
53
|
-
want.empty? # any queries left to match?
|
54
|
-
end
|
55
|
-
result
|
56
|
-
rescue Async::TimeoutError
|
57
|
-
type_str = {'StatusUpdate'=>'update', 'StatusResponse'=>'response'}[type]
|
58
|
-
raise RSMP::TimeoutError.new "Did not received status #{type_str} in reply to #{m_id} within #{options[:timeout]}s"
|
59
|
-
end
|
60
|
-
|
61
|
-
def wait_for_status_updates_or_responses parent_task, type, options={}, &block
|
62
|
-
raise ArgumentError.new("component argument is missing") unless options[:component]
|
63
|
-
raise ArgumentError.new("status_list argument is missing") unless options[:status_list]
|
64
|
-
m_id = RSMP::Message.make_m_id # make message id so we can start waiting for it
|
65
|
-
|
66
|
-
# wait for command responses in an async task
|
67
|
-
task = parent_task.async do |task|
|
68
|
-
capture_status_updates_or_responses task, type, options, m_id
|
69
|
-
end
|
70
|
-
|
71
|
-
# call block, it should send command request using the given m_id
|
72
|
-
yield m_id
|
73
|
-
|
74
|
-
# wait for the response and return it, raise exception if NotAck received, it it timed out
|
75
|
-
task.wait
|
76
|
-
end
|
77
|
-
|
78
|
-
def wait_for_status_updates parent_task, options={}, &block
|
79
|
-
wait_for_status_updates_or_responses parent_task, 'StatusUpdate', options, &block
|
80
|
-
end
|
81
|
-
|
82
|
-
def wait_for_status_responses parent_task, options={}, &block
|
83
|
-
wait_for_status_updates_or_responses parent_task, 'StatusResponse', options, &block
|
84
|
-
end
|
85
|
-
|
86
|
-
def process_command_response message
|
87
|
-
log "Received #{message.type}", message: message, level: :log
|
88
|
-
acknowledge message
|
89
|
-
end
|
90
|
-
|
91
|
-
def command_match? query, item
|
92
|
-
return false if query[:sCI] && query[:sCI] != item['sCI']
|
93
|
-
return false if query[:n] && query[:n] != item['n']
|
94
|
-
if query[:s].is_a? Regexp
|
95
|
-
return false if query[:v] && item['v'] !~ query[:v]
|
96
|
-
else
|
97
|
-
return false if query[:v] && item['v'] != query[:v]
|
98
|
-
end
|
99
|
-
true
|
100
|
-
end
|
101
|
-
|
102
|
-
def capture_command_responses parent_task, type, options, m_id
|
103
|
-
task.annotate "wait for command response"
|
104
|
-
want = options[:command_list].clone
|
105
|
-
result = {}
|
106
|
-
item = @archive.capture(parent_task,options.merge({
|
107
|
-
type: [type,'MessageNotAck'],
|
108
|
-
num: 1
|
109
|
-
})) do |item|
|
110
|
-
message = item[:message]
|
111
|
-
if message.is_a?(MessageNotAck) && message.attribute('oMId') == m_id
|
112
|
-
# and message.attribute('oMId')==m_id
|
113
|
-
# set result to an exception, but don't raise it.
|
114
|
-
# this will be returned by the task and stored as the task result
|
115
|
-
# when the parent task call wait() on the task, the exception
|
116
|
-
# will be raised in the parent task, and caught by rspec.
|
117
|
-
# rspec will then show the error and record the test as failed
|
118
|
-
m_id_short = RSMP::Message.shorten_m_id m_id, 8
|
119
|
-
result = RSMP::MessageRejected.new "Command request #{m_id_short} was rejected: #{message.attribute('rea')}"
|
120
|
-
next true # done, no more messages wanted
|
121
|
-
end
|
122
|
-
|
123
|
-
found = []
|
124
|
-
# look through querues
|
125
|
-
want.each_with_index do |query,i|
|
126
|
-
# look through items in message
|
127
|
-
item[:message].attributes['rvs'].each do |input|
|
128
|
-
ok = command_match? query, input
|
129
|
-
if ok
|
130
|
-
result[query] = input
|
131
|
-
found << i # record which queries where matched succesfully
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
# remove queries that where matched
|
136
|
-
found.sort.reverse.each do |i|
|
137
|
-
want.delete_at i
|
138
|
-
end
|
139
|
-
want.empty? # any queries left to match?
|
140
|
-
end
|
141
|
-
result
|
142
|
-
rescue Async::TimeoutError
|
143
|
-
raise RSMP::TimeoutError.new "Did not receive command response to #{m_id} within #{options[:timeout]}s"
|
144
|
-
end
|
145
|
-
|
146
|
-
def wait_for_command_responses parent_task, options={}, &block
|
147
|
-
raise ArgumentError.new("component argument is missing") unless options[:component]
|
148
|
-
raise ArgumentError.new("command_list argument is missing") unless options[:command_list]
|
149
|
-
m_id = RSMP::Message.make_m_id # make message id so we can start waiting for it
|
150
|
-
|
151
|
-
# wait for command responses in an async task
|
152
|
-
task = parent_task.async do |task|
|
153
|
-
capture_command_responses task, 'CommandResponse', options, m_id
|
154
|
-
end
|
155
|
-
|
156
|
-
# call block, it should send command request using the given m_id
|
157
|
-
yield m_id
|
158
|
-
|
159
|
-
# wait for the response and return it, raise exception if NotAck received, it it timed out
|
160
|
-
task.wait
|
161
|
-
end
|
162
15
|
end
|
163
16
|
end
|
data/rsmp.gemspec
CHANGED
@@ -41,13 +41,13 @@ Gem::Specification.new do |spec|
|
|
41
41
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
42
42
|
spec.require_paths = ["lib"]
|
43
43
|
|
44
|
-
spec.add_dependency "async", "~> 1.
|
45
|
-
spec.add_dependency "async-io", "~> 1.
|
44
|
+
spec.add_dependency "async", "~> 1.28.3"
|
45
|
+
spec.add_dependency "async-io", "~> 1.30.1"
|
46
46
|
spec.add_dependency "colorize", "~> 0.8.1"
|
47
47
|
spec.add_dependency "thor", "~> 1.0.1"
|
48
|
-
spec.add_dependency "json_schemer", "~> 0.2.
|
48
|
+
spec.add_dependency "json_schemer", "~> 0.2.17"
|
49
49
|
|
50
|
-
spec.add_development_dependency "bundler", "~> 2.
|
50
|
+
spec.add_development_dependency "bundler", "~> 2.2.3"
|
51
51
|
spec.add_development_dependency "rake", "~> 13.0.1"
|
52
52
|
spec.add_development_dependency "rspec", "~> 3.9.0"
|
53
53
|
spec.add_development_dependency "rspec-expectations", "~> 3.9.1"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsmp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emil Tin
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.28.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.28.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: async-io
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.30.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.30.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: colorize
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,28 +72,28 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.2.
|
75
|
+
version: 0.2.17
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.2.
|
82
|
+
version: 0.2.17
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: bundler
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 2.
|
89
|
+
version: 2.2.3
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 2.
|
96
|
+
version: 2.2.3
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rake
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -200,25 +200,28 @@ files:
|
|
200
200
|
- config/site.yaml
|
201
201
|
- config/supervisor.yaml
|
202
202
|
- config/tlc.yaml
|
203
|
-
- documentation/
|
203
|
+
- documentation/classes_and_modules.md
|
204
|
+
- documentation/message_distribution.md
|
204
205
|
- exe/rsmp
|
205
206
|
- lib/rsmp.rb
|
206
207
|
- lib/rsmp/alarm.rb
|
207
208
|
- lib/rsmp/archive.rb
|
208
|
-
- lib/rsmp/base.rb
|
209
209
|
- lib/rsmp/cli.rb
|
210
|
+
- lib/rsmp/collector.rb
|
210
211
|
- lib/rsmp/component.rb
|
212
|
+
- lib/rsmp/components.rb
|
211
213
|
- lib/rsmp/error.rb
|
214
|
+
- lib/rsmp/listener.rb
|
212
215
|
- lib/rsmp/logger.rb
|
216
|
+
- lib/rsmp/logging.rb
|
213
217
|
- lib/rsmp/message.rb
|
214
218
|
- lib/rsmp/node.rb
|
215
|
-
- lib/rsmp/
|
216
|
-
- lib/rsmp/probe_collection.rb
|
219
|
+
- lib/rsmp/notifier.rb
|
217
220
|
- lib/rsmp/proxy.rb
|
218
221
|
- lib/rsmp/rsmp.rb
|
219
222
|
- lib/rsmp/site.rb
|
220
|
-
- lib/rsmp/site_base.rb
|
221
223
|
- lib/rsmp/site_proxy.rb
|
224
|
+
- lib/rsmp/site_proxy_wait.rb
|
222
225
|
- lib/rsmp/supervisor.rb
|
223
226
|
- lib/rsmp/supervisor_proxy.rb
|
224
227
|
- lib/rsmp/tlc.rb
|
@@ -336,7 +339,7 @@ metadata:
|
|
336
339
|
source_code_uri: https://github.com/rsmp-nordic/rsmp
|
337
340
|
changelog_uri: https://github.com/rsmp-nordic/rsmp/blob/master/CHANGELOG.md
|
338
341
|
bug_tracker_uri: https://github.com/rsmp-nordic/rsmp/issues
|
339
|
-
post_install_message:
|
342
|
+
post_install_message:
|
340
343
|
rdoc_options: []
|
341
344
|
require_paths:
|
342
345
|
- lib
|
@@ -351,8 +354,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
351
354
|
- !ruby/object:Gem::Version
|
352
355
|
version: '0'
|
353
356
|
requirements: []
|
354
|
-
rubygems_version: 3.
|
355
|
-
signing_key:
|
357
|
+
rubygems_version: 3.2.3
|
358
|
+
signing_key:
|
356
359
|
specification_version: 4
|
357
360
|
summary: RoadSide Message Protocol (RSMP) library.
|
358
361
|
test_files: []
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# Collection of probes
|
2
|
-
|
3
|
-
module RSMP
|
4
|
-
class ProbeCollection
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
@probes = []
|
8
|
-
end
|
9
|
-
|
10
|
-
def add probe
|
11
|
-
raise ArgumentError unless probe
|
12
|
-
@probes << probe
|
13
|
-
end
|
14
|
-
|
15
|
-
def remove probe
|
16
|
-
raise ArgumentError unless probe
|
17
|
-
@probes.delete probe
|
18
|
-
end
|
19
|
-
|
20
|
-
def process item
|
21
|
-
@probes.each { |probe| probe.process item }
|
22
|
-
end
|
23
|
-
|
24
|
-
def clear
|
25
|
-
@probes.each { |probe| probe.clear }
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|