rsmp 0.37.0 → 0.38.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/.devcontainer/devcontainer.json +22 -0
- data/.github/workflows/rubocop.yaml +17 -0
- data/.gitignore +5 -6
- data/.rubocop.yml +80 -0
- data/Gemfile +13 -1
- data/Gemfile.lock +34 -1
- data/Rakefile +3 -3
- data/lib/rsmp/cli.rb +147 -124
- data/lib/rsmp/collect/ack_collector.rb +8 -7
- data/lib/rsmp/collect/aggregated_status_collector.rb +4 -4
- data/lib/rsmp/collect/alarm_collector.rb +31 -23
- data/lib/rsmp/collect/alarm_matcher.rb +3 -3
- data/lib/rsmp/collect/collector/logging.rb +17 -0
- data/lib/rsmp/collect/collector/reporting.rb +44 -0
- data/lib/rsmp/collect/collector/status.rb +34 -0
- data/lib/rsmp/collect/collector.rb +69 -150
- data/lib/rsmp/collect/command_matcher.rb +19 -6
- data/lib/rsmp/collect/command_response_collector.rb +7 -7
- data/lib/rsmp/collect/distributor.rb +14 -11
- data/lib/rsmp/collect/filter.rb +31 -15
- data/lib/rsmp/collect/matcher.rb +7 -11
- data/lib/rsmp/collect/queue.rb +4 -4
- data/lib/rsmp/collect/receiver.rb +10 -12
- data/lib/rsmp/collect/state_collector.rb +116 -77
- data/lib/rsmp/collect/status_collector.rb +6 -6
- data/lib/rsmp/collect/status_matcher.rb +17 -7
- data/lib/rsmp/{alarm_state.rb → component/alarm_state.rb} +76 -37
- data/lib/rsmp/{component.rb → component/component.rb} +15 -15
- data/lib/rsmp/component/component_base.rb +89 -0
- data/lib/rsmp/component/component_proxy.rb +75 -0
- data/lib/rsmp/component/components.rb +63 -0
- data/lib/rsmp/convert/export/json_schema.rb +116 -110
- data/lib/rsmp/convert/import/yaml.rb +21 -18
- data/lib/rsmp/{rsmp.rb → helpers/clock.rb} +5 -6
- data/lib/rsmp/{deep_merge.rb → helpers/deep_merge.rb} +2 -1
- data/lib/rsmp/helpers/error.rb +71 -0
- data/lib/rsmp/{inspect.rb → helpers/inspect.rb} +6 -10
- data/lib/rsmp/log/archive.rb +98 -0
- data/lib/rsmp/log/colorization.rb +41 -0
- data/lib/rsmp/log/filtering.rb +54 -0
- data/lib/rsmp/log/logger.rb +206 -0
- data/lib/rsmp/{logging.rb → log/logging.rb} +5 -7
- data/lib/rsmp/message.rb +159 -148
- data/lib/rsmp/{node.rb → node/node.rb} +19 -17
- data/lib/rsmp/{protocol.rb → node/protocol.rb} +5 -3
- data/lib/rsmp/node/site/site.rb +195 -0
- data/lib/rsmp/node/supervisor/modules/configuration.rb +59 -0
- data/lib/rsmp/node/supervisor/modules/connection.rb +140 -0
- data/lib/rsmp/node/supervisor/modules/sites.rb +64 -0
- data/lib/rsmp/node/supervisor/supervisor.rb +72 -0
- data/lib/rsmp/{task.rb → node/task.rb} +12 -14
- data/lib/rsmp/proxy/modules/acknowledgements.rb +144 -0
- data/lib/rsmp/proxy/modules/receive.rb +119 -0
- data/lib/rsmp/proxy/modules/send.rb +76 -0
- data/lib/rsmp/proxy/modules/state.rb +25 -0
- data/lib/rsmp/proxy/modules/tasks.rb +105 -0
- data/lib/rsmp/proxy/modules/versions.rb +69 -0
- data/lib/rsmp/proxy/modules/watchdogs.rb +66 -0
- data/lib/rsmp/proxy/proxy.rb +199 -0
- data/lib/rsmp/proxy/site/modules/aggregated_status.rb +52 -0
- data/lib/rsmp/proxy/site/modules/alarms.rb +27 -0
- data/lib/rsmp/proxy/site/modules/commands.rb +31 -0
- data/lib/rsmp/proxy/site/modules/status.rb +110 -0
- data/lib/rsmp/proxy/site/site_proxy.rb +205 -0
- data/lib/rsmp/proxy/supervisor/modules/aggregated_status.rb +47 -0
- data/lib/rsmp/proxy/supervisor/modules/alarms.rb +73 -0
- data/lib/rsmp/proxy/supervisor/modules/commands.rb +53 -0
- data/lib/rsmp/proxy/supervisor/modules/status.rb +204 -0
- data/lib/rsmp/proxy/supervisor/supervisor_proxy.rb +178 -0
- data/lib/rsmp/tlc/detector_logic.rb +18 -34
- data/lib/rsmp/tlc/input_states.rb +126 -0
- data/lib/rsmp/tlc/modules/detector_logics.rb +50 -0
- data/lib/rsmp/tlc/modules/display.rb +78 -0
- data/lib/rsmp/tlc/modules/helpers.rb +41 -0
- data/lib/rsmp/tlc/modules/inputs.rb +173 -0
- data/lib/rsmp/tlc/modules/modes.rb +253 -0
- data/lib/rsmp/tlc/modules/outputs.rb +30 -0
- data/lib/rsmp/tlc/modules/plans.rb +218 -0
- data/lib/rsmp/tlc/modules/signal_groups.rb +109 -0
- data/lib/rsmp/tlc/modules/startup_sequence.rb +22 -0
- data/lib/rsmp/tlc/modules/system.rb +140 -0
- data/lib/rsmp/tlc/modules/traffic_data.rb +49 -0
- data/lib/rsmp/tlc/signal_group.rb +37 -41
- data/lib/rsmp/tlc/signal_plan.rb +14 -11
- data/lib/rsmp/tlc/signal_priority.rb +39 -35
- data/lib/rsmp/tlc/startup_sequence.rb +59 -0
- data/lib/rsmp/tlc/traffic_controller.rb +38 -1010
- data/lib/rsmp/tlc/traffic_controller_site.rb +58 -57
- data/lib/rsmp/version.rb +1 -1
- data/lib/rsmp.rb +82 -48
- data/rsmp.gemspec +24 -31
- metadata +79 -139
- data/lib/rsmp/archive.rb +0 -76
- data/lib/rsmp/collect/message_matchers.rb +0 -0
- data/lib/rsmp/component_base.rb +0 -87
- data/lib/rsmp/component_proxy.rb +0 -57
- data/lib/rsmp/components.rb +0 -65
- data/lib/rsmp/error.rb +0 -71
- data/lib/rsmp/logger.rb +0 -216
- data/lib/rsmp/proxy.rb +0 -693
- data/lib/rsmp/site.rb +0 -188
- data/lib/rsmp/site_proxy.rb +0 -389
- data/lib/rsmp/supervisor.rb +0 -302
- data/lib/rsmp/supervisor_proxy.rb +0 -510
- data/lib/rsmp/tlc/inputs.rb +0 -134
data/lib/rsmp/collect/filter.rb
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
module RSMP
|
|
2
|
-
|
|
3
2
|
# Filter messages based on type, direction and component id.
|
|
4
3
|
# Used by Collectors.
|
|
5
4
|
class Filter
|
|
6
|
-
|
|
7
5
|
attr_reader :ingoing, :outgoing, :type, :component
|
|
8
6
|
|
|
9
|
-
def initialize
|
|
7
|
+
def initialize(ingoing: true, outgoing: true, type: nil, component: nil)
|
|
10
8
|
@ingoing = ingoing
|
|
11
9
|
@outgoing = outgoing
|
|
12
10
|
@type = type ? [type].flatten : nil
|
|
@@ -14,23 +12,41 @@ module RSMP
|
|
|
14
12
|
end
|
|
15
13
|
|
|
16
14
|
# Check a message against our match criteria
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
def accept?(message)
|
|
16
|
+
return false unless direction_matches?(message)
|
|
17
|
+
return false unless type_matches?(message)
|
|
18
|
+
return false unless component_matches?(message)
|
|
19
|
+
|
|
20
|
+
true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def direction_matches?(message)
|
|
19
26
|
return false if message.direction == :in && @ingoing == false
|
|
20
27
|
return false if message.direction == :out && @outgoing == false
|
|
21
|
-
|
|
22
|
-
unless message.is_a?(MessageNotAck)
|
|
23
|
-
return false unless @type.include? message.type
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
if @component
|
|
27
|
-
return false if message.attributes['cId'] && message.attributes['cId'] != @component
|
|
28
|
-
end
|
|
28
|
+
|
|
29
29
|
true
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
def
|
|
32
|
+
def type_matches?(message)
|
|
33
|
+
return true unless @type
|
|
34
|
+
return true if message.is_a?(MessageNotAck)
|
|
35
|
+
|
|
36
|
+
@type.include?(message.type)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def component_matches?(message)
|
|
40
|
+
return true unless @component
|
|
41
|
+
return true unless message.attributes['cId']
|
|
42
|
+
|
|
43
|
+
message.attributes['cId'] == @component
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
public
|
|
47
|
+
|
|
48
|
+
def reject?(message)
|
|
33
49
|
!accept?(message)
|
|
34
50
|
end
|
|
35
51
|
end
|
|
36
|
-
end
|
|
52
|
+
end
|
data/lib/rsmp/collect/matcher.rb
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
module RSMP
|
|
2
|
-
|
|
3
2
|
# Class that matches a single status or command item
|
|
4
3
|
class Matcher
|
|
5
4
|
attr_reader :want, :got, :message
|
|
6
5
|
|
|
7
|
-
def initialize
|
|
6
|
+
def initialize(want)
|
|
8
7
|
@want = want
|
|
9
8
|
@got = nil
|
|
10
9
|
@message = nil
|
|
@@ -17,18 +16,16 @@ module RSMP
|
|
|
17
16
|
|
|
18
17
|
# Check an item and set @done to true if it matches
|
|
19
18
|
# Store the item and corresponding message if there's a positive or negative match
|
|
20
|
-
def perform_match
|
|
19
|
+
def perform_match(item, _message, block)
|
|
21
20
|
matched = match? item
|
|
22
|
-
if matched
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
matched = status if status == true || status == false
|
|
26
|
-
end
|
|
21
|
+
if !matched.nil? && block
|
|
22
|
+
status = block.call(nil, item)
|
|
23
|
+
matched = status if [true, false].include?(status)
|
|
27
24
|
end
|
|
28
25
|
matched
|
|
29
26
|
end
|
|
30
27
|
|
|
31
|
-
def keep
|
|
28
|
+
def keep(message, item)
|
|
32
29
|
@message = message
|
|
33
30
|
@got = item
|
|
34
31
|
end
|
|
@@ -38,7 +35,6 @@ module RSMP
|
|
|
38
35
|
@got = nil
|
|
39
36
|
end
|
|
40
37
|
|
|
41
|
-
def match?
|
|
42
|
-
end
|
|
38
|
+
def match?(item); end
|
|
43
39
|
end
|
|
44
40
|
end
|
data/lib/rsmp/collect/queue.rb
CHANGED
|
@@ -7,7 +7,7 @@ module RSMP
|
|
|
7
7
|
|
|
8
8
|
attr_reader :messages
|
|
9
9
|
|
|
10
|
-
def initialize
|
|
10
|
+
def initialize(distributor, task:, filter: nil)
|
|
11
11
|
initialize_receiver distributor, filter: filter
|
|
12
12
|
@condition = Async::Notification.new
|
|
13
13
|
@task = task
|
|
@@ -18,7 +18,7 @@ module RSMP
|
|
|
18
18
|
@messages = []
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def wait_for_message
|
|
21
|
+
def wait_for_message(timeout: nil)
|
|
22
22
|
if @messages.empty?
|
|
23
23
|
if timeout
|
|
24
24
|
@task.with_timeout(timeout) { @condition.wait }
|
|
@@ -31,9 +31,9 @@ module RSMP
|
|
|
31
31
|
raise RSMP::TimeoutError
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
def handle_message
|
|
34
|
+
def handle_message(message)
|
|
35
35
|
@messages << message
|
|
36
36
|
@condition.signal
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
|
-
end
|
|
39
|
+
end
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Receives items from a Distributor, as long as it's
|
|
2
2
|
# installed as a receiver.
|
|
3
|
-
# Optionally
|
|
3
|
+
# Optionally filter mesage using a Filter.
|
|
4
4
|
|
|
5
5
|
module RSMP
|
|
6
6
|
module Receiver
|
|
7
7
|
include Inspect
|
|
8
8
|
|
|
9
|
-
def initialize_receiver
|
|
9
|
+
def initialize_receiver(distributor, filter: nil)
|
|
10
10
|
@distributor = distributor
|
|
11
11
|
@filter = filter
|
|
12
12
|
end
|
|
@@ -19,22 +19,20 @@ module RSMP
|
|
|
19
19
|
@distributor.remove_receiver(self)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def receive
|
|
23
|
-
handle_message(message) if accept_message?(message)
|
|
22
|
+
def receive(message)
|
|
23
|
+
handle_message(message) if accept_message?(message)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def receive_error
|
|
27
|
-
end
|
|
26
|
+
def receive_error(error, options = {}); end
|
|
28
27
|
|
|
29
|
-
def accept_message?
|
|
30
|
-
@filter
|
|
28
|
+
def accept_message?(message)
|
|
29
|
+
@filter.nil? || @filter.accept?(message)
|
|
31
30
|
end
|
|
32
31
|
|
|
33
|
-
def reject_message?
|
|
32
|
+
def reject_message?(message)
|
|
34
33
|
!accept_message?(message)
|
|
35
34
|
end
|
|
36
35
|
|
|
37
|
-
def handle_message
|
|
38
|
-
end
|
|
36
|
+
def handle_message(message); end
|
|
39
37
|
end
|
|
40
|
-
end
|
|
38
|
+
end
|
|
@@ -35,91 +35,103 @@ module RSMP
|
|
|
35
35
|
attr_reader :matchers
|
|
36
36
|
|
|
37
37
|
# Initialize with a list of wanted statuses
|
|
38
|
-
def initialize
|
|
39
|
-
raise ArgumentError
|
|
40
|
-
|
|
38
|
+
def initialize(proxy, want, options = {})
|
|
39
|
+
raise ArgumentError, 'num option cannot be used' if options[:num]
|
|
40
|
+
|
|
41
|
+
super(proxy, options)
|
|
41
42
|
@matchers = want.map { |item| build_matcher item }
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
# Build a matcher object.
|
|
45
46
|
# Sub-classes should override to use their own matcher classes.
|
|
46
|
-
def build_matcher
|
|
47
|
+
def build_matcher(want)
|
|
47
48
|
Matcher.new want
|
|
48
49
|
end
|
|
49
50
|
|
|
50
51
|
# Get a results
|
|
51
|
-
def matcher_result
|
|
52
|
-
matcher = @matchers.find { |q| q.want == want}
|
|
52
|
+
def matcher_result(want)
|
|
53
|
+
matcher = @matchers.find { |q| q.want == want }
|
|
53
54
|
raise unless matcher
|
|
55
|
+
|
|
54
56
|
matcher.got
|
|
55
57
|
end
|
|
56
58
|
|
|
57
59
|
# Get an array of the last item received for each matcher
|
|
58
60
|
def reached
|
|
59
|
-
@matchers.map
|
|
61
|
+
@matchers.map(&:got).compact
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
# Get messages from results
|
|
63
65
|
def messages
|
|
64
|
-
@matchers.map
|
|
66
|
+
@matchers.map(&:message).uniq.compact
|
|
65
67
|
end
|
|
66
68
|
|
|
67
69
|
# Return progress as completes matchers vs. total number of matchers
|
|
68
70
|
def progress
|
|
69
71
|
need = @matchers.size
|
|
70
|
-
reached =
|
|
72
|
+
reached = @matchers.count(&:done?)
|
|
71
73
|
{ need: need, reached: reached }
|
|
72
74
|
end
|
|
73
75
|
|
|
74
76
|
# Are there matchers left to type_match?
|
|
75
77
|
def done?
|
|
76
|
-
@matchers.all?
|
|
78
|
+
@matchers.all?(&:done?)
|
|
77
79
|
end
|
|
78
80
|
|
|
79
81
|
# Get a simplified hash of matchers, with values set to either true or false,
|
|
80
82
|
# indicating which matchers have been matched.
|
|
81
83
|
def matcher_status
|
|
82
|
-
@matchers.
|
|
84
|
+
@matchers.to_h { |matcher| [matcher.want, matcher.done?] }
|
|
83
85
|
end
|
|
84
86
|
|
|
85
87
|
# Get a simply array of bools, showing which matchers have been matched.
|
|
86
88
|
def summary
|
|
87
|
-
@matchers.map
|
|
89
|
+
@matchers.map(&:done?)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def log_match_result(message, matched, matcher, item)
|
|
93
|
+
type = { true => 'match', false => 'mismatch' }[matched]
|
|
94
|
+
@distributor.log "#{@title.capitalize} #{message.m_id_short} collect #{type} #{matcher.want}, item #{item}",
|
|
95
|
+
level: :debug
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def handle_match_result(matched, matcher, message, item)
|
|
99
|
+
return if matched.nil?
|
|
100
|
+
|
|
101
|
+
log_match_result(message, matched, matcher, item)
|
|
102
|
+
if matched == true
|
|
103
|
+
matcher.keep message, item
|
|
104
|
+
elsif matched == false
|
|
105
|
+
matcher.forget
|
|
106
|
+
end
|
|
88
107
|
end
|
|
89
108
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
def perform_match message
|
|
93
|
-
return false if super(message) == false
|
|
109
|
+
def perform_match(message)
|
|
110
|
+
return false if super == false
|
|
94
111
|
return unless collecting?
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
elsif matched == false
|
|
105
|
-
matcher.forget
|
|
106
|
-
end
|
|
107
|
-
end
|
|
112
|
+
|
|
113
|
+
@matchers.each do |matcher|
|
|
114
|
+
break unless collecting?
|
|
115
|
+
|
|
116
|
+
get_items(message).each do |item|
|
|
117
|
+
matched = matcher.perform_match(item, message, @block)
|
|
118
|
+
break unless collecting?
|
|
119
|
+
|
|
120
|
+
handle_match_result(matched, matcher, message, item)
|
|
108
121
|
end
|
|
109
122
|
end
|
|
110
123
|
end
|
|
111
124
|
|
|
112
125
|
# don't collect anything. Matcher will collect them instead
|
|
113
|
-
def keep
|
|
114
|
-
end
|
|
126
|
+
def keep(message); end
|
|
115
127
|
|
|
116
128
|
def describe
|
|
117
|
-
@matchers.map {|q| q.want.to_s }
|
|
129
|
+
@matchers.map { |q| q.want.to_s }
|
|
118
130
|
end
|
|
119
131
|
|
|
120
132
|
# return a string that describes the attributes that we're looking for
|
|
121
133
|
def describe_matcher
|
|
122
|
-
"#{super} matching #{matcher_want_hash
|
|
134
|
+
"#{super} matching #{matcher_want_hash}"
|
|
123
135
|
end
|
|
124
136
|
|
|
125
137
|
# return a hash that describe the status of all matchers
|
|
@@ -128,33 +140,45 @@ module RSMP
|
|
|
128
140
|
@matchers.each do |matcher|
|
|
129
141
|
want = matcher.want
|
|
130
142
|
if want['cCI']
|
|
131
|
-
|
|
132
|
-
h[cCI] ||= {}
|
|
133
|
-
cO = h['cO']
|
|
134
|
-
n = h['n']
|
|
135
|
-
v = h['v']
|
|
136
|
-
h[cCI][cO] ||= {}
|
|
137
|
-
h[cCI][cO][n] = v
|
|
143
|
+
process_command_matcher(h, matcher, want)
|
|
138
144
|
elsif want['sCI']
|
|
139
|
-
|
|
140
|
-
h[sCI] ||= {}
|
|
141
|
-
n = want['n']
|
|
142
|
-
s = want['s']
|
|
143
|
-
if matcher.got && matcher.got['s']
|
|
144
|
-
h[sCI][n] = { {s=>matcher.got['s']} => matcher.done? }
|
|
145
|
-
else
|
|
146
|
-
h[sCI][n] = { s=>nil }
|
|
147
|
-
end
|
|
145
|
+
process_status_matcher(h, matcher, want)
|
|
148
146
|
end
|
|
149
147
|
end
|
|
150
148
|
h
|
|
151
149
|
end
|
|
152
150
|
|
|
151
|
+
private
|
|
152
|
+
|
|
153
|
+
def process_command_matcher(hash, _matcher, want)
|
|
154
|
+
cci = want['cCI']
|
|
155
|
+
hash[cci] ||= {}
|
|
156
|
+
co = want['cO']
|
|
157
|
+
n = want['n']
|
|
158
|
+
v = want['v']
|
|
159
|
+
hash[cci][co] ||= {}
|
|
160
|
+
hash[cci][co][n] = v
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def process_status_matcher(hash, matcher, want)
|
|
164
|
+
sci = want['sCI']
|
|
165
|
+
hash[sci] ||= {}
|
|
166
|
+
n = want['n']
|
|
167
|
+
s = want['s']
|
|
168
|
+
hash[sci][n] = if matcher.got && matcher.got['s']
|
|
169
|
+
{ { s => matcher.got['s'] } => matcher.done? }
|
|
170
|
+
else
|
|
171
|
+
{ s => nil }
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
public
|
|
176
|
+
|
|
153
177
|
# return a string that describe how many many messages have been collected
|
|
154
178
|
def describe_progress
|
|
155
179
|
num_matchers = @matchers.size
|
|
156
|
-
num_matched = @matchers.count
|
|
157
|
-
".. Matched #{num_matched}/#{num_matchers} with #{progress_hash
|
|
180
|
+
num_matched = @matchers.count(&:done?)
|
|
181
|
+
".. Matched #{num_matched}/#{num_matchers} with #{progress_hash}"
|
|
158
182
|
end
|
|
159
183
|
|
|
160
184
|
def matcher_want_hash
|
|
@@ -162,44 +186,59 @@ module RSMP
|
|
|
162
186
|
@matchers.each do |matcher|
|
|
163
187
|
item = matcher.want
|
|
164
188
|
if item['cCI']
|
|
165
|
-
|
|
166
|
-
h[cCI] ||= {}
|
|
167
|
-
cO = item['cO']
|
|
168
|
-
h[cCI][cO] ||= {}
|
|
169
|
-
n = item['n']
|
|
170
|
-
v = item['v']
|
|
171
|
-
h[cCI][cO][n] = v || :any
|
|
189
|
+
add_command_want_to_hash(h, item)
|
|
172
190
|
elsif item['sCI']
|
|
173
|
-
|
|
174
|
-
h[sCI] ||= {}
|
|
175
|
-
n = item['n']
|
|
176
|
-
s = item['s']
|
|
177
|
-
h[sCI][n] = s || :any
|
|
191
|
+
add_status_want_to_hash(h, item)
|
|
178
192
|
end
|
|
179
193
|
end
|
|
180
194
|
h
|
|
181
195
|
end
|
|
182
196
|
|
|
183
|
-
|
|
197
|
+
def add_command_want_to_hash(hash, item)
|
|
198
|
+
cci = item['cCI']
|
|
199
|
+
hash[cci] ||= {}
|
|
200
|
+
co = item['cO']
|
|
201
|
+
hash[cci][co] ||= {}
|
|
202
|
+
n = item['n']
|
|
203
|
+
v = item['v']
|
|
204
|
+
hash[cci][co][n] = v || :any
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def add_status_want_to_hash(hash, item)
|
|
208
|
+
sci = item['sCI']
|
|
209
|
+
hash[sci] ||= {}
|
|
210
|
+
n = item['n']
|
|
211
|
+
s = item['s']
|
|
212
|
+
hash[sci][n] = s || :any
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def add_command_result(hash, want, got)
|
|
216
|
+
cci = want['cCI']
|
|
217
|
+
hash[cci] ||= {}
|
|
218
|
+
co = want['cO']
|
|
219
|
+
hash[cci][co] ||= {}
|
|
220
|
+
n = want['n']
|
|
221
|
+
v = got ? got['v'] : nil
|
|
222
|
+
hash[cci][co][n] = v
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def add_status_result(hash, want, got)
|
|
226
|
+
sci = want['sCI']
|
|
227
|
+
hash[sci] ||= {}
|
|
228
|
+
n = want['n']
|
|
229
|
+
s = got ? got['s'] : nil
|
|
230
|
+
hash[sci][n] = s
|
|
231
|
+
end
|
|
232
|
+
|
|
184
233
|
def matcher_got_hash
|
|
185
234
|
h = {}
|
|
186
235
|
@matchers.each do |matcher|
|
|
187
236
|
want = matcher.want
|
|
188
237
|
got = matcher.got
|
|
189
238
|
if want['cCI']
|
|
190
|
-
|
|
191
|
-
h[cCI] ||= {}
|
|
192
|
-
cO = want['cO']
|
|
193
|
-
h[cCI][cO] ||= {}
|
|
194
|
-
n = want['n']
|
|
195
|
-
v = got ? got['v'] : nil
|
|
196
|
-
h[cCI][cO][n] = v
|
|
239
|
+
add_command_result(h, want, got)
|
|
197
240
|
elsif want['sCI']
|
|
198
|
-
|
|
199
|
-
h[sCI] ||= {}
|
|
200
|
-
n = want['n']
|
|
201
|
-
s = got ? got['s'] : nil
|
|
202
|
-
h[sCI][n] = s
|
|
241
|
+
add_status_result(h, want, got)
|
|
203
242
|
end
|
|
204
243
|
end
|
|
205
244
|
h
|
|
@@ -207,7 +246,7 @@ module RSMP
|
|
|
207
246
|
|
|
208
247
|
# log when we end collecting
|
|
209
248
|
def log_complete
|
|
210
|
-
@distributor.log "#{identifier}: Completed with #{matcher_got_hash
|
|
249
|
+
@distributor.log "#{identifier}: Completed with #{matcher_got_hash}", level: :collect
|
|
211
250
|
end
|
|
212
251
|
end
|
|
213
252
|
end
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
module RSMP
|
|
2
2
|
# Base class for waiting for status updates or responses
|
|
3
3
|
class StatusCollector < StateCollector
|
|
4
|
-
def initialize
|
|
4
|
+
def initialize(proxy, want, options = {})
|
|
5
5
|
type = []
|
|
6
6
|
type << 'StatusUpdate' unless options[:updates] == false
|
|
7
7
|
type << 'StatusResponse' unless options[:reponses] == false
|
|
8
8
|
|
|
9
|
-
super
|
|
9
|
+
super(proxy, want, options.merge(
|
|
10
10
|
title: 'status response',
|
|
11
11
|
filter: RSMP::Filter.new(ingoing: true, outgoing: false, type: type)
|
|
12
|
-
)
|
|
12
|
+
))
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def build_matcher
|
|
15
|
+
def build_matcher(want)
|
|
16
16
|
RSMP::StatusMatcher.new want
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
# Get items, in our case status values
|
|
20
|
-
def get_items
|
|
20
|
+
def get_items(message)
|
|
21
21
|
message.attributes['sS'] || []
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
|
-
end
|
|
24
|
+
end
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
module RSMP
|
|
2
|
-
# Match a specific status response or update
|
|
3
2
|
class StatusMatcher < Matcher
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return
|
|
7
|
-
return
|
|
8
|
-
|
|
3
|
+
def match_code?(item)
|
|
4
|
+
return false if @want['sCI'] && @want['sCI'] != item['sCI']
|
|
5
|
+
return false if @want['cO'] && @want['cO'] != item['cO']
|
|
6
|
+
return false if @want['n'] && @want['n'] != item['n']
|
|
7
|
+
|
|
8
|
+
true
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def match_value?(item)
|
|
9
12
|
return false if @want['q'] && @want['q'] != item['q']
|
|
13
|
+
|
|
10
14
|
if @want['s'].is_a? Regexp
|
|
11
15
|
return false if item['s'] !~ @want['s']
|
|
12
16
|
elsif @want['s']
|
|
@@ -14,5 +18,11 @@ module RSMP
|
|
|
14
18
|
end
|
|
15
19
|
true
|
|
16
20
|
end
|
|
21
|
+
|
|
22
|
+
def match?(item)
|
|
23
|
+
return nil unless match_code?(item)
|
|
24
|
+
|
|
25
|
+
match_value?(item)
|
|
26
|
+
end
|
|
17
27
|
end
|
|
18
|
-
end
|
|
28
|
+
end
|