rsmp 0.1.10 → 0.1.19
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/.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
|