rsmp 0.1.10 → 0.1.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +47 -49
- data/README.md +7 -1
- data/config/site.yaml +3 -4
- data/config/supervisor.yaml +2 -5
- data/config/tlc.yaml +44 -0
- data/documentation/classes.md +62 -0
- data/lib/rsmp.rb +1 -0
- data/lib/rsmp/archive.rb +11 -5
- data/lib/rsmp/cli.rb +15 -5
- data/lib/rsmp/component.rb +12 -2
- data/lib/rsmp/error.rb +10 -1
- data/lib/rsmp/message.rb +25 -2
- data/lib/rsmp/node.rb +33 -6
- data/lib/rsmp/probe.rb +5 -18
- data/lib/rsmp/proxy.rb +43 -43
- data/lib/rsmp/site.rb +7 -3
- data/lib/rsmp/site_base.rb +6 -4
- data/lib/rsmp/site_proxy.rb +103 -59
- data/lib/rsmp/supervisor.rb +6 -5
- data/lib/rsmp/supervisor_proxy.rb +84 -31
- data/lib/rsmp/tlc.rb +869 -0
- data/lib/rsmp/version.rb +1 -1
- data/lib/rsmp/wait.rb +149 -3
- data/rsmp.gemspec +9 -10
- metadata +28 -34
- data/lib/rsmp/supervisor_base.rb +0 -10
data/lib/rsmp/error.rb
CHANGED
@@ -23,7 +23,7 @@ module RSMP
|
|
23
23
|
class MissingWatchdog < Error
|
24
24
|
end
|
25
25
|
|
26
|
-
class
|
26
|
+
class MessageRejected < Error
|
27
27
|
end
|
28
28
|
|
29
29
|
class MissingAttribute < InvalidMessage
|
@@ -43,4 +43,13 @@ module RSMP
|
|
43
43
|
|
44
44
|
class UnknownComponent < Error
|
45
45
|
end
|
46
|
+
|
47
|
+
class UnknownCommand < Error
|
48
|
+
end
|
49
|
+
|
50
|
+
class UnknownStatus < Error
|
51
|
+
end
|
52
|
+
|
53
|
+
class ConfigurationError < Error
|
54
|
+
end
|
46
55
|
end
|
data/lib/rsmp/message.rb
CHANGED
@@ -27,6 +27,9 @@ module RSMP
|
|
27
27
|
|
28
28
|
@@schemas = load_schemas
|
29
29
|
|
30
|
+
def self.make_m_id
|
31
|
+
SecureRandom.uuid()
|
32
|
+
end
|
30
33
|
|
31
34
|
def self.parse_attributes json
|
32
35
|
raise ArgumentError unless json
|
@@ -80,8 +83,12 @@ module RSMP
|
|
80
83
|
@attributes["mId"]
|
81
84
|
end
|
82
85
|
|
86
|
+
def self.shorten_m_id m_id, length=4
|
87
|
+
m_id[0..length-1]
|
88
|
+
end
|
89
|
+
|
83
90
|
def m_id_short
|
84
|
-
@attributes["mId"]
|
91
|
+
Message.shorten_m_id @attributes["mId"]
|
85
92
|
end
|
86
93
|
|
87
94
|
def attribute key
|
@@ -126,7 +133,7 @@ module RSMP
|
|
126
133
|
|
127
134
|
def ensure_message_id
|
128
135
|
# if message id is empty, generate a new one
|
129
|
-
@attributes["mId"] ||=
|
136
|
+
@attributes["mId"] ||= Message.make_m_id
|
130
137
|
end
|
131
138
|
|
132
139
|
def validate sxl=nil
|
@@ -197,6 +204,22 @@ module RSMP
|
|
197
204
|
end
|
198
205
|
end
|
199
206
|
|
207
|
+
class AlarmRequest < Message
|
208
|
+
def initialize attributes = {}
|
209
|
+
super({
|
210
|
+
"type" => "Alarm",
|
211
|
+
}.merge attributes)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
class AlarmAcknowledged < Message
|
216
|
+
def initialize attributes = {}
|
217
|
+
super({
|
218
|
+
"type" => "Alarm",
|
219
|
+
}.merge attributes)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
200
223
|
class Watchdog < Message
|
201
224
|
def initialize attributes = {}
|
202
225
|
super({
|
data/lib/rsmp/node.rb
CHANGED
@@ -5,19 +5,46 @@
|
|
5
5
|
|
6
6
|
module RSMP
|
7
7
|
class Node < Base
|
8
|
-
|
8
|
+
include Wait
|
9
|
+
|
10
|
+
attr_reader :archive, :logger, :task, :deferred
|
9
11
|
|
10
12
|
def initialize options
|
11
13
|
super options
|
14
|
+
@task = options[:task]
|
15
|
+
@deferred = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def defer item
|
19
|
+
@deferred << item
|
20
|
+
end
|
21
|
+
|
22
|
+
def process_deferred
|
23
|
+
cloned = @deferred.clone # clone in case do_deferred restarts the current task
|
24
|
+
@deferred.clear
|
25
|
+
cloned.each do |item|
|
26
|
+
do_deferred item
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def do_deferred item
|
31
|
+
end
|
32
|
+
|
33
|
+
def do_start task
|
34
|
+
task.annotate self.class.to_s
|
35
|
+
@task = task
|
36
|
+
start_action
|
37
|
+
idle
|
12
38
|
end
|
13
39
|
|
14
40
|
def start
|
15
41
|
starting
|
16
|
-
|
17
|
-
task
|
18
|
-
|
19
|
-
|
20
|
-
|
42
|
+
if @task
|
43
|
+
do_start @task
|
44
|
+
else
|
45
|
+
Async do |task|
|
46
|
+
do_start task
|
47
|
+
end
|
21
48
|
end
|
22
49
|
rescue Errno::EADDRINUSE => e
|
23
50
|
log "Cannot start: #{e.to_s}", level: :error
|
data/lib/rsmp/probe.rb
CHANGED
@@ -6,22 +6,6 @@ module RSMP
|
|
6
6
|
class Probe
|
7
7
|
attr_reader :condition, :items, :done
|
8
8
|
|
9
|
-
# block should send a message and return message just sent
|
10
|
-
def self.collect_response proxy, options={}, &block
|
11
|
-
from = proxy.archive.current_index
|
12
|
-
sent = yield
|
13
|
-
raise RuntimeError unless sent && sent[:message].is_a?(RSMP::Message)
|
14
|
-
item = proxy.archive.capture(options.merge(from: from+1, num: 1, with_message: true)) do |item|
|
15
|
-
["CommandResponse","StatusResponse","MessageNotAck"].include?(item[:message].type)
|
16
|
-
end
|
17
|
-
if item
|
18
|
-
item[:message]
|
19
|
-
else
|
20
|
-
nil
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
9
|
def initialize archive
|
26
10
|
raise ArgumentError.new("Archive expected") unless archive.is_a? Archive
|
27
11
|
@archive = archive
|
@@ -30,6 +14,7 @@ module RSMP
|
|
30
14
|
end
|
31
15
|
|
32
16
|
def capture task, options={}, &block
|
17
|
+
raise ArgumentError.new("timeout option is missing") unless options[:timeout]
|
33
18
|
@options = options
|
34
19
|
@block = block
|
35
20
|
@num = options[:num]
|
@@ -37,8 +22,6 @@ module RSMP
|
|
37
22
|
if options[:earliest]
|
38
23
|
from = find_timestamp_index options[:earliest]
|
39
24
|
backscan from
|
40
|
-
elsif options[:from]
|
41
|
-
backscan options[:from]
|
42
25
|
end
|
43
26
|
|
44
27
|
# if backscan didn't find enough items, then
|
@@ -62,6 +45,7 @@ module RSMP
|
|
62
45
|
end
|
63
46
|
|
64
47
|
def find_timestamp_index earliest
|
48
|
+
return 0 if earliest == :start
|
65
49
|
(0..@archive.items.size).bsearch do |i| # use binary search to find item index
|
66
50
|
@archive.items[i][:timestamp] >= earliest
|
67
51
|
end
|
@@ -105,6 +89,9 @@ module RSMP
|
|
105
89
|
end
|
106
90
|
return if @options[:level] && item[:level] != @options[:level]
|
107
91
|
return false if @options[:with_message] && !(item[:direction] && item[:message])
|
92
|
+
if @options[:component]
|
93
|
+
return false if item[:message].attributes['cId'] && item[:message].attributes['cId'] != @options[:component]
|
94
|
+
end
|
108
95
|
if @block
|
109
96
|
return false if @block.call(item) == false
|
110
97
|
end
|
data/lib/rsmp/proxy.rb
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
module RSMP
|
4
4
|
class Proxy < Base
|
5
|
-
|
5
|
+
include Wait
|
6
|
+
|
7
|
+
attr_reader :state, :archive, :connection_info, :sxl, :task
|
6
8
|
|
7
9
|
def initialize options
|
8
10
|
super options
|
@@ -18,7 +20,7 @@ module RSMP
|
|
18
20
|
def run
|
19
21
|
start
|
20
22
|
@reader.wait if @reader
|
21
|
-
stop
|
23
|
+
stop unless [:stopped, :stopping].include? @state
|
22
24
|
end
|
23
25
|
|
24
26
|
def ready?
|
@@ -115,26 +117,42 @@ module RSMP
|
|
115
117
|
interval = @settings["timer_interval"] || 1
|
116
118
|
log "Starting #{name} with interval #{interval} seconds", level: :debug
|
117
119
|
@latest_watchdog_received = RSMP.now_object
|
120
|
+
|
118
121
|
@timer = @task.async do |task|
|
119
122
|
task.annotate "timer"
|
123
|
+
next_time = Time.now.to_f
|
120
124
|
loop do
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
+
begin
|
126
|
+
now = RSMP.now_object
|
127
|
+
timer(now)
|
128
|
+
rescue EOFError => e
|
129
|
+
log "Timer: Connection closed: #{e}", level: :warning
|
130
|
+
rescue IOError => e
|
131
|
+
log "Timer: IOError", level: :warning
|
132
|
+
rescue Errno::ECONNRESET
|
133
|
+
log "Timer: Connection reset by peer", level: :warning
|
134
|
+
rescue Errno::EPIPE => e
|
135
|
+
log "Timer: Broken pipe", level: :warning
|
136
|
+
rescue StandardError => e
|
137
|
+
log "Error: #{e}", level: :debug
|
138
|
+
#rescue StandardError => e
|
139
|
+
# log ["Timer error: #{e}",e.backtrace].flatten.join("\n"), level: :error
|
140
|
+
end
|
125
141
|
ensure
|
126
|
-
|
142
|
+
next_time += interval
|
143
|
+
duration = next_time - Time.now.to_f
|
144
|
+
task.sleep duration
|
127
145
|
end
|
128
146
|
end
|
129
147
|
end
|
130
148
|
|
131
149
|
def timer now
|
132
|
-
|
133
|
-
|
134
|
-
|
150
|
+
watchdog_send_timer now
|
151
|
+
check_ack_timeout now
|
152
|
+
check_watchdog_timeout now
|
135
153
|
end
|
136
154
|
|
137
|
-
def
|
155
|
+
def watchdog_send_timer now
|
138
156
|
return unless @watchdog_started
|
139
157
|
return if @settings["watchdog_interval"] == :never
|
140
158
|
|
@@ -148,8 +166,6 @@ module RSMP
|
|
148
166
|
send_watchdog now
|
149
167
|
end
|
150
168
|
end
|
151
|
-
rescue StandardError => e
|
152
|
-
log ["Watchdog error: #{e}",e.backtrace].flatten.join("\n"), level: :error
|
153
169
|
end
|
154
170
|
|
155
171
|
def send_watchdog now=nil
|
@@ -167,24 +183,18 @@ module RSMP
|
|
167
183
|
if now > latest
|
168
184
|
log "No acknowledgements for #{message.type} #{message.m_id_short} within #{timeout} seconds", level: :error
|
169
185
|
stop
|
170
|
-
return true
|
171
186
|
end
|
172
187
|
end
|
173
|
-
false
|
174
188
|
end
|
175
189
|
|
176
190
|
def check_watchdog_timeout now
|
177
|
-
|
178
191
|
timeout = @settings["watchdog_timeout"]
|
179
192
|
latest = @latest_watchdog_received + timeout
|
180
193
|
left = latest - now
|
181
|
-
log "Check watchdog, time:#{timeout}, last:#{@latest_watchdog_received}, now: #{now}, latest:#{latest}, left #{left}, fail:#{left<0}", level: :debug
|
182
194
|
if left < 0
|
183
|
-
log "No Watchdog within #{timeout} seconds
|
195
|
+
log "No Watchdog within #{timeout} seconds", level: :error
|
184
196
|
stop
|
185
|
-
return true
|
186
197
|
end
|
187
|
-
false
|
188
198
|
end
|
189
199
|
|
190
200
|
def stop_tasks
|
@@ -212,7 +222,7 @@ module RSMP
|
|
212
222
|
|
213
223
|
def buffer_message message
|
214
224
|
# TODO
|
215
|
-
log "Cannot send #{message.type} because the connection is closed.", message: message, level: :error
|
225
|
+
#log "Cannot send #{message.type} because the connection is closed.", message: message, level: :error
|
216
226
|
end
|
217
227
|
|
218
228
|
def log_send message, reason=nil
|
@@ -235,12 +245,13 @@ module RSMP
|
|
235
245
|
message.validate sxl
|
236
246
|
expect_version_message(message) unless @version_determined
|
237
247
|
process_message message
|
248
|
+
process_deferred
|
238
249
|
message
|
239
250
|
rescue InvalidPacket => e
|
240
|
-
|
251
|
+
log "Received invalid package, must be valid JSON but got #{json.size} bytes: #{e.message}", level: :warning
|
241
252
|
nil
|
242
253
|
rescue MalformedMessage => e
|
243
|
-
|
254
|
+
log "Received malformed message, #{e.message}", message: Malformed.new(attributes), level: :warning
|
244
255
|
# cannot send NotAcknowledged for a malformed message since we can't read it, just ignore it
|
245
256
|
nil
|
246
257
|
rescue SchemaError => e
|
@@ -331,7 +342,7 @@ module RSMP
|
|
331
342
|
def wait_for_state state, timeout
|
332
343
|
states = [state].flatten
|
333
344
|
return if states.include?(@state)
|
334
|
-
|
345
|
+
wait_for(@state_condition,timeout) do |s|
|
335
346
|
states.include?(@state)
|
336
347
|
end
|
337
348
|
@state
|
@@ -441,27 +452,16 @@ module RSMP
|
|
441
452
|
def version_acknowledged
|
442
453
|
end
|
443
454
|
|
444
|
-
def wait_for_acknowledgement original, timeout
|
455
|
+
def wait_for_acknowledgement original, timeout
|
445
456
|
raise ArgumentError unless original
|
446
|
-
|
447
|
-
message.is_a?(
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
def wait_for_not_acknowledged original, timeout
|
453
|
-
raise ArgumentError unless original
|
454
|
-
RSMP::Wait.wait_for(@task,@acknowledgement_condition,timeout) do |message|
|
455
|
-
message.is_a?(MessageNotAck) &&
|
456
|
-
message.attributes["oMId"] == original.m_id
|
457
|
-
end
|
458
|
-
end
|
459
|
-
|
460
|
-
def wait_for_acknowledgements timeout
|
461
|
-
return if @awaiting_acknowledgement.empty?
|
462
|
-
RSMP::Wait.wait_for(@task,@acknowledgement_condition,timeout) do |message|
|
463
|
-
@awaiting_acknowledgement.empty?
|
457
|
+
wait_for(@acknowledgement_condition,timeout) do |message|
|
458
|
+
if message.is_a?(MessageNotAck) && message.attributes["oMId"] == original.m_id
|
459
|
+
raise RSMP::MessageRejected.new(message.attributes['rea'])
|
460
|
+
end
|
461
|
+
message.is_a?(MessageAck) && message.attributes["oMId"] == original.m_id
|
464
462
|
end
|
463
|
+
rescue Async::TimeoutError
|
464
|
+
raise RSMP::TimeoutError.new("Acknowledgement for #{original.type} #{original.m_id} not received within #{timeout}s")
|
465
465
|
end
|
466
466
|
|
467
467
|
def node
|
data/lib/rsmp/site.rb
CHANGED
@@ -27,6 +27,7 @@ module RSMP
|
|
27
27
|
{ 'ip' => '127.0.0.1', 'port' => 12111 }
|
28
28
|
],
|
29
29
|
'rsmp_versions' => ['3.1.1','3.1.2','3.1.3','3.1.4'],
|
30
|
+
'sxl' => 'traffic_light_controller',
|
30
31
|
'sxl_version' => '1.0.7',
|
31
32
|
'timer_interval' => 0.1,
|
32
33
|
'watchdog_interval' => 1,
|
@@ -69,7 +70,7 @@ module RSMP
|
|
69
70
|
end
|
70
71
|
end
|
71
72
|
|
72
|
-
def
|
73
|
+
def build_proxy settings
|
73
74
|
SupervisorProxy.new settings
|
74
75
|
end
|
75
76
|
|
@@ -80,7 +81,7 @@ module RSMP
|
|
80
81
|
end
|
81
82
|
|
82
83
|
def connect_to_supervisor task, supervisor_settings
|
83
|
-
proxy =
|
84
|
+
proxy = build_proxy({
|
84
85
|
site: self,
|
85
86
|
task: @task,
|
86
87
|
settings: @site_settings,
|
@@ -109,7 +110,9 @@ module RSMP
|
|
109
110
|
if @site_settings["reconnect_interval"] != :no
|
110
111
|
# sleep until waken by reconnect() or the reconnect interval passed
|
111
112
|
proxy.set_state :wait_for_reconnect
|
112
|
-
task.with_timeout(@site_settings["reconnect_interval"])
|
113
|
+
task.with_timeout(@site_settings["reconnect_interval"]) do
|
114
|
+
@sleep_condition.wait
|
115
|
+
end
|
113
116
|
else
|
114
117
|
proxy.set_state :cannot_connect
|
115
118
|
break
|
@@ -140,5 +143,6 @@ module RSMP
|
|
140
143
|
proxy.stop
|
141
144
|
end
|
142
145
|
end
|
146
|
+
|
143
147
|
end
|
144
148
|
end
|
data/lib/rsmp/site_base.rb
CHANGED
@@ -13,8 +13,10 @@ module RSMP
|
|
13
13
|
|
14
14
|
def setup_components settings
|
15
15
|
return unless settings
|
16
|
-
settings.each_pair do |
|
17
|
-
|
16
|
+
settings.each_pair do |type,components_by_type|
|
17
|
+
components_by_type.each_pair do |id,settings|
|
18
|
+
@components[id] = build_component(id:id, type:type, settings:settings)
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
@@ -22,8 +24,8 @@ module RSMP
|
|
22
24
|
@components[component.c_id] = component
|
23
25
|
end
|
24
26
|
|
25
|
-
def build_component id
|
26
|
-
Component.new id:
|
27
|
+
def build_component id:, type:, settings:{}
|
28
|
+
Component.new id:id, node: self, grouped: true
|
27
29
|
end
|
28
30
|
|
29
31
|
def find_component component_id
|
data/lib/rsmp/site_proxy.rb
CHANGED
@@ -23,6 +23,11 @@ module RSMP
|
|
23
23
|
start_reader
|
24
24
|
end
|
25
25
|
|
26
|
+
def stop
|
27
|
+
log "Closing connection to site", level: :info
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
26
31
|
def connection_complete
|
27
32
|
super
|
28
33
|
log "Connection to site #{@site_id} established", level: :info
|
@@ -50,11 +55,15 @@ module RSMP
|
|
50
55
|
end
|
51
56
|
end
|
52
57
|
|
58
|
+
def process_deferred
|
59
|
+
supervisor.process_deferred
|
60
|
+
end
|
61
|
+
|
53
62
|
def version_accepted message
|
54
63
|
log "Received Version message for site #{@site_id} using RSMP #{@rsmp_version}", message: message, level: :log
|
55
64
|
start_timer
|
56
65
|
acknowledge message
|
57
|
-
send_version @site_id, @
|
66
|
+
send_version @site_id, @settings['rsmp_versions']
|
58
67
|
@version_determined = true
|
59
68
|
|
60
69
|
if @settings['sites']
|
@@ -81,7 +90,7 @@ module RSMP
|
|
81
90
|
component = @components[c_id]
|
82
91
|
if component == nil
|
83
92
|
if @site_settings == nil || @site_settings['components'] == nil
|
84
|
-
component = build_component
|
93
|
+
component = build_component(id:c_id, type:nil)
|
85
94
|
@components[c_id] = component
|
86
95
|
log "Adding component #{c_id} to site #{@site_id}", level: :info
|
87
96
|
else
|
@@ -123,16 +132,38 @@ module RSMP
|
|
123
132
|
@supervisor.site_ids_changed
|
124
133
|
end
|
125
134
|
|
126
|
-
def
|
127
|
-
|
135
|
+
def fetch_status parent_task, options
|
136
|
+
wait_for_status_responses(parent_task,options) do |m_id|
|
137
|
+
request_status options.merge(m_id: m_id)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Convert from a short ruby hash:
|
142
|
+
# {:S0001=>[:signalgroupstatus, :cyclecounter, :basecyclecounter, :stage]}
|
143
|
+
# to an rsmp-style list:
|
144
|
+
# [{"sCI"=>"S0001", "n"=>"signalgroupstatus"}, {"sCI"=>"S0001", "n"=>"cyclecounter"}, {"sCI"=>"S0001", "n"=>"basecyclecounter"}, {"sCI"=>"S0001", "n"=>"stage"}]
|
145
|
+
#
|
146
|
+
# If the input is already an array, just return it
|
147
|
+
def convert_status_list list
|
148
|
+
return list.clone if list.is_a? Array
|
149
|
+
list.map do |status_code_id,names|
|
150
|
+
names.map do |name|
|
151
|
+
{ 'sCI' => status_code_id.to_s, 'n' => name.to_s }
|
152
|
+
end
|
153
|
+
end.flatten
|
154
|
+
end
|
155
|
+
|
156
|
+
def request_status options
|
157
|
+
raise NotReady unless ready?
|
128
158
|
message = RSMP::StatusRequest.new({
|
129
159
|
"ntsOId" => '',
|
130
160
|
"xNId" => '',
|
131
|
-
"cId" => component,
|
132
|
-
"sS" => status_list
|
161
|
+
"cId" => options[:component],
|
162
|
+
"sS" => convert_status_list(options[:status_list]),
|
163
|
+
"mId" => options[:m_id]
|
133
164
|
})
|
134
165
|
send_message message
|
135
|
-
|
166
|
+
message
|
136
167
|
end
|
137
168
|
|
138
169
|
def process_status_response message
|
@@ -140,41 +171,26 @@ module RSMP
|
|
140
171
|
acknowledge message
|
141
172
|
end
|
142
173
|
|
143
|
-
def
|
144
|
-
raise
|
145
|
-
item = @archive.capture(@task, options.merge(
|
146
|
-
type: ['StatusResponse','MessageNotAck'],
|
147
|
-
with_message: true,
|
148
|
-
num: 1
|
149
|
-
)) do |item|
|
150
|
-
if item[:message].type == 'MessageNotAck'
|
151
|
-
next item[:message].attribute('oMId') == options[:message].m_id
|
152
|
-
elsif item[:message].type == 'StatusResponse'
|
153
|
-
next item[:message].attribute('cId') == options[:message].attribute('cId')
|
154
|
-
end
|
155
|
-
end
|
156
|
-
item[:message] if item
|
157
|
-
end
|
158
|
-
|
159
|
-
def subscribe_to_status component, status_list, timeout
|
160
|
-
raise NotReady unless @state == :ready
|
174
|
+
def subscribe_to_status component, status_list, options={}
|
175
|
+
raise NotReady unless ready?
|
161
176
|
message = RSMP::StatusSubscribe.new({
|
162
177
|
"ntsOId" => '',
|
163
178
|
"xNId" => '',
|
164
179
|
"cId" => component,
|
165
|
-
"sS" => status_list
|
180
|
+
"sS" => convert_status_list(status_list),
|
181
|
+
'mId'=>options[:m_id]
|
166
182
|
})
|
167
183
|
send_message message
|
168
|
-
return message
|
184
|
+
return message
|
169
185
|
end
|
170
186
|
|
171
187
|
def unsubscribe_to_status component, status_list
|
172
|
-
raise NotReady unless
|
188
|
+
raise NotReady unless ready?
|
173
189
|
message = RSMP::StatusUnsubscribe.new({
|
174
190
|
"ntsOId" => '',
|
175
191
|
"xNId" => '',
|
176
192
|
"cId" => component,
|
177
|
-
"sS" => status_list
|
193
|
+
"sS" => convert_status_list(status_list)
|
178
194
|
})
|
179
195
|
send_message message
|
180
196
|
message
|
@@ -185,50 +201,79 @@ module RSMP
|
|
185
201
|
acknowledge message
|
186
202
|
end
|
187
203
|
|
188
|
-
def
|
189
|
-
|
190
|
-
|
204
|
+
def status_match? query, item
|
205
|
+
return false if query[:sCI] && query[:sCI] != item['sCI']
|
206
|
+
return false if query[:n] && query[:n] != item['n']
|
207
|
+
return false if query[:q] && query[:q] != item['q']
|
208
|
+
if query[:s].is_a? Regexp
|
209
|
+
return false if query[:s] && item['s'] !~ query[:s]
|
210
|
+
else
|
211
|
+
return false if query[:s] && item['s'] != query[:s]
|
212
|
+
end
|
213
|
+
true
|
214
|
+
end
|
215
|
+
|
216
|
+
def wait_for_alarm options={}
|
217
|
+
raise ArgumentError.new("component argument is missing") unless options[:component]
|
218
|
+
matching_alarm = nil
|
219
|
+
item = @archive.capture(@task,options.merge(type: "Alarm", with_message: true, num: 1)) do |item|
|
191
220
|
# TODO check components
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
found
|
221
|
+
matching_alarm = nil
|
222
|
+
alarm = item[:message]
|
223
|
+
next if options[:aCId] && options[:aCId] != alarm.attribute("aCId")
|
224
|
+
next if options[:aSp] && options[:aSp] != alarm.attribute("aSp")
|
225
|
+
next if options[:aS] && options[:aS] != alarm.attribute("aS")
|
226
|
+
matching_alarm = alarm
|
227
|
+
break
|
228
|
+
end
|
229
|
+
if item
|
230
|
+
{ message: item[:message], status: matching_alarm }
|
203
231
|
end
|
204
|
-
item[:message] if item
|
205
232
|
end
|
206
233
|
|
207
|
-
def
|
208
|
-
|
209
|
-
message = RSMP::CommandRequest.new({
|
234
|
+
def send_alarm_acknowledgement component, alarm_code
|
235
|
+
message = RSMP::AlarmAcknowledged.new({
|
210
236
|
"ntsOId" => '',
|
211
237
|
"xNId" => '',
|
212
238
|
"cId" => component,
|
213
|
-
"
|
239
|
+
"aCId" => alarm_code,
|
240
|
+
"xACId" => '',
|
241
|
+
"xNACId" => '',
|
242
|
+
"aSp" => 'Acknowledge'
|
214
243
|
})
|
215
244
|
send_message message
|
216
245
|
message
|
217
246
|
end
|
218
247
|
|
219
|
-
def
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
248
|
+
def wait_for_alarm_acknowledgement_response options
|
249
|
+
raise ArgumentError.new("component argument is missing") unless options[:component]
|
250
|
+
item = @archive.capture(@task,options.merge(
|
251
|
+
num: 1,
|
252
|
+
type: ['AlarmAcknowledgedResponse','MessageNotAck'],
|
253
|
+
with_message: true
|
254
|
+
)) do |item|
|
255
|
+
if item[:message].type == 'MessageNotAck'
|
256
|
+
next item[:message].attribute('oMId') == options[:message].m_id
|
257
|
+
elsif item[:message].type == 'AlarmAcknowledgedResponse'
|
258
|
+
next item[:message].attribute('cId') == options[:message].attribute('cId')
|
259
|
+
end
|
228
260
|
end
|
229
261
|
item[:message] if item
|
230
262
|
end
|
231
263
|
|
264
|
+
def send_command component, args, options={}
|
265
|
+
raise NotReady unless ready?
|
266
|
+
message = RSMP::CommandRequest.new({
|
267
|
+
"ntsOId" => '',
|
268
|
+
"xNId" => '',
|
269
|
+
"cId" => component,
|
270
|
+
"arg" => args,
|
271
|
+
"mId" => options[:m_id]
|
272
|
+
})
|
273
|
+
send_message message
|
274
|
+
message
|
275
|
+
end
|
276
|
+
|
232
277
|
def set_watchdog_interval interval
|
233
278
|
@settings["watchdog_interval"] = interval
|
234
279
|
end
|
@@ -261,6 +306,5 @@ module RSMP
|
|
261
306
|
site_ids_changed
|
262
307
|
end
|
263
308
|
|
264
|
-
|
265
309
|
end
|
266
|
-
end
|
310
|
+
end
|