rsmp 0.3.1 → 0.3.5
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 +1 -1
- data/lib/rsmp/component.rb +13 -3
- data/lib/rsmp/components.rb +10 -0
- data/lib/rsmp/error.rb +3 -0
- data/lib/rsmp/message.rb +60 -5
- data/lib/rsmp/proxy.rb +16 -3
- data/lib/rsmp/site.rb +6 -2
- data/lib/rsmp/site_proxy.rb +7 -6
- data/lib/rsmp/supervisor_proxy.rb +0 -10
- data/lib/rsmp/version.rb +1 -1
- data/lib/rsmp.rb +0 -1
- metadata +2 -3
- data/lib/rsmp/alarm.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d22d8796a378484c9c7a9d50b3bc48386db2e12893c5af07a1ef83825d2f1b0e
|
4
|
+
data.tar.gz: ee6a4ebb4fcf094cb45e1f541e6f228e6ea9c3364fca6e1526e4fe46026751f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1a495ba2c110ebb42db60596516de255b9c9a9cb903fdd66bf77bd27a3f5d5b786b273436b522af3dbf57e983651676b9a9e67aee7387ba134ef89812261618
|
7
|
+
data.tar.gz: 21f2e48b596dcca6296da89f687ec46d3845eaafb6cad497a16ac4fabca1cb5574da6df324256f4929b7207eeccd17697bd5021b328b4d265ff7d836d2a5e2c3
|
data/Gemfile.lock
CHANGED
data/lib/rsmp/component.rb
CHANGED
@@ -57,9 +57,6 @@ module RSMP
|
|
57
57
|
def aggregated_status_changed options={}
|
58
58
|
@node.aggregated_status_changed self, options
|
59
59
|
end
|
60
|
-
|
61
|
-
def alarm code:, status:
|
62
|
-
end
|
63
60
|
|
64
61
|
def log str, options
|
65
62
|
@node.log str, options
|
@@ -73,5 +70,18 @@ module RSMP
|
|
73
70
|
raise UnknownStatus.new "Status #{status_code}/#{status_name} not implemented by #{self.class}"
|
74
71
|
end
|
75
72
|
|
73
|
+
def handle_alarm message
|
74
|
+
code = message.attribute('aCId')
|
75
|
+
alarm = @alarms[code]
|
76
|
+
if alarm
|
77
|
+
if alarm.differ? message
|
78
|
+
@alarms[code] = alarm
|
79
|
+
else
|
80
|
+
raise RepeatedAlarmError.new("no changes from previous alarm #{alarm.m_id_short}")
|
81
|
+
end
|
82
|
+
else
|
83
|
+
@alarms[code] = message
|
84
|
+
end
|
85
|
+
end
|
76
86
|
end
|
77
87
|
end
|
data/lib/rsmp/components.rb
CHANGED
@@ -13,6 +13,7 @@ module RSMP
|
|
13
13
|
|
14
14
|
def setup_components settings
|
15
15
|
return unless settings
|
16
|
+
check_main_component settings
|
16
17
|
settings.each_pair do |type,components_by_type|
|
17
18
|
components_by_type.each_pair do |id,settings|
|
18
19
|
@components[id] = build_component(id:id, type:type, settings:settings)
|
@@ -20,6 +21,15 @@ module RSMP
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
24
|
+
def check_main_component settings
|
25
|
+
unless settings['main'] && settings['main'].size >= 1
|
26
|
+
raise ConfigurationError.new("main component must be defined")
|
27
|
+
end
|
28
|
+
if settings['main'].size > 1
|
29
|
+
raise ConfigurationError.new("only one main component can be defined, found #{settings['main'].keys.join(', ')}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
23
33
|
def add_component component
|
24
34
|
@components[component.c_id] = component
|
25
35
|
end
|
data/lib/rsmp/error.rb
CHANGED
data/lib/rsmp/message.rb
CHANGED
@@ -36,7 +36,7 @@ module RSMP
|
|
36
36
|
when "Watchdog"
|
37
37
|
message = Watchdog.new attributes
|
38
38
|
when "Alarm"
|
39
|
-
message =
|
39
|
+
message = self.build_alarm attributes
|
40
40
|
when "CommandRequest"
|
41
41
|
message = CommandRequest.new attributes
|
42
42
|
when "CommandResponse"
|
@@ -59,6 +59,23 @@ module RSMP
|
|
59
59
|
message
|
60
60
|
end
|
61
61
|
|
62
|
+
def self.build_alarm attributes
|
63
|
+
case attributes["aSp"]
|
64
|
+
when 'Issue'
|
65
|
+
AlarmIssue.new attributes
|
66
|
+
when 'Request'
|
67
|
+
AlarmRequest.new attributes
|
68
|
+
when 'Acknowledge'
|
69
|
+
AlarmAcknowledged.new attributes
|
70
|
+
when 'Suspend'
|
71
|
+
AlarmSuspend.new attributes
|
72
|
+
when 'Resume'
|
73
|
+
AlarmResume.new attributes
|
74
|
+
else
|
75
|
+
Alarm.new attributes
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
62
79
|
def type
|
63
80
|
@attributes["type"]
|
64
81
|
end
|
@@ -191,26 +208,64 @@ module RSMP
|
|
191
208
|
def initialize attributes = {}
|
192
209
|
super({
|
193
210
|
"type" => "Alarm",
|
211
|
+
"ntsOId" => '',
|
212
|
+
"xNId" => '',
|
213
|
+
"xACId" => '',
|
214
|
+
"xNACId" => ''
|
194
215
|
}.merge attributes)
|
195
216
|
end
|
217
|
+
|
218
|
+
def differ? from
|
219
|
+
%w{aSp aCId ack aS sS aTs cat pri}.each do |key|
|
220
|
+
return true if attribute(key).downcase != from.attribute(key).downcase
|
221
|
+
end
|
222
|
+
return true if attribute('rvs') != from.attribute('rvs')
|
223
|
+
false
|
224
|
+
end
|
196
225
|
end
|
197
226
|
|
198
|
-
class
|
227
|
+
class AlarmIssue < Alarm
|
199
228
|
def initialize attributes = {}
|
200
229
|
super({
|
201
|
-
"
|
230
|
+
"aSp" => "Issue",
|
202
231
|
}.merge attributes)
|
203
232
|
end
|
204
233
|
end
|
205
234
|
|
206
|
-
class
|
235
|
+
class AlarmRequest < Alarm
|
207
236
|
def initialize attributes = {}
|
208
237
|
super({
|
209
|
-
"
|
238
|
+
"aSp" => "Request",
|
239
|
+
}.merge attributes)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
class AlarmAcknowledged < Alarm
|
244
|
+
def initialize attributes = {}
|
245
|
+
super({
|
246
|
+
"aSp" => "Acknowledge",
|
210
247
|
}.merge attributes)
|
211
248
|
end
|
212
249
|
end
|
213
250
|
|
251
|
+
class AlarmSuspend < Alarm
|
252
|
+
def initialize attributes = {}
|
253
|
+
super({
|
254
|
+
"aSp" => "Suspend",
|
255
|
+
}.merge attributes)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
class AlarmResume < Alarm
|
260
|
+
def initialize attributes = {}
|
261
|
+
super({
|
262
|
+
"aSp" => "Resume",
|
263
|
+
}.merge attributes)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
|
268
|
+
|
214
269
|
class Watchdog < Message
|
215
270
|
def initialize attributes = {}
|
216
271
|
super({
|
data/lib/rsmp/proxy.rb
CHANGED
@@ -73,6 +73,11 @@ module RSMP
|
|
73
73
|
@state == :ready
|
74
74
|
end
|
75
75
|
|
76
|
+
def connected?
|
77
|
+
@state == :starting || @state == :ready
|
78
|
+
end
|
79
|
+
|
80
|
+
|
76
81
|
def start
|
77
82
|
set_state :starting
|
78
83
|
end
|
@@ -118,7 +123,6 @@ module RSMP
|
|
118
123
|
task.annotate "reader"
|
119
124
|
@stream ||= Async::IO::Stream.new(@socket)
|
120
125
|
@protocol ||= Async::IO::Protocol::Line.new(@stream,WRAPPING_DELIMITER) # rsmp messages are json terminated with a form-feed
|
121
|
-
|
122
126
|
while json = @protocol.read_line
|
123
127
|
beginning = Time.now
|
124
128
|
message = process_packet json
|
@@ -267,12 +271,13 @@ module RSMP
|
|
267
271
|
end
|
268
272
|
|
269
273
|
def send_message message, reason=nil, validate: true
|
274
|
+
raise NotReady unless connected?
|
270
275
|
raise IOError unless @protocol
|
271
276
|
message.direction = :out
|
272
277
|
message.generate_json
|
273
278
|
message.validate get_schemas unless validate==false
|
274
|
-
expect_acknowledgement message
|
275
279
|
@protocol.write_lines message.json
|
280
|
+
expect_acknowledgement message
|
276
281
|
notify message
|
277
282
|
log_send message, reason
|
278
283
|
rescue EOFError, IOError
|
@@ -302,10 +307,18 @@ module RSMP
|
|
302
307
|
end
|
303
308
|
end
|
304
309
|
|
310
|
+
def should_validate_ingoing_message? message
|
311
|
+
return true unless @site_settings
|
312
|
+
skip = @site_settings.dig('skip_validation')
|
313
|
+
return true unless skip
|
314
|
+
klass = message.class.name.split('::').last
|
315
|
+
!skip.include?(klass)
|
316
|
+
end
|
317
|
+
|
305
318
|
def process_packet json
|
306
319
|
attributes = Message.parse_attributes json
|
307
320
|
message = Message.build attributes, json
|
308
|
-
message.validate
|
321
|
+
message.validate(get_schemas) if should_validate_ingoing_message?(message)
|
309
322
|
notify message
|
310
323
|
expect_version_message(message) unless @version_determined
|
311
324
|
process_message message
|
data/lib/rsmp/site.rb
CHANGED
@@ -46,7 +46,11 @@ module RSMP
|
|
46
46
|
}
|
47
47
|
}
|
48
48
|
}
|
49
|
-
|
49
|
+
# only one main component can be defined, so replace the default if options define one
|
50
|
+
if options.dig(:site_settings,'components','main')
|
51
|
+
defaults['components']['main'] = options[:site_settings]['components']['main']
|
52
|
+
end
|
53
|
+
|
50
54
|
@site_settings = defaults.deep_merge options[:site_settings]
|
51
55
|
check_sxl_version
|
52
56
|
setup_components @site_settings['components']
|
@@ -79,7 +83,7 @@ module RSMP
|
|
79
83
|
|
80
84
|
def aggregated_status_changed component, options={}
|
81
85
|
@proxies.each do |proxy|
|
82
|
-
proxy.send_aggregated_status component, options
|
86
|
+
proxy.send_aggregated_status component, options if proxy.ready?
|
83
87
|
end
|
84
88
|
end
|
85
89
|
|
data/lib/rsmp/site_proxy.rb
CHANGED
@@ -148,11 +148,17 @@ module RSMP
|
|
148
148
|
end
|
149
149
|
|
150
150
|
def process_alarm message
|
151
|
+
component = find_component message.attribute("cId")
|
152
|
+
status = ["ack","aS","sS"].map { |key| message.attribute(key) }.join(',')
|
153
|
+
component.handle_alarm message
|
151
154
|
alarm_code = message.attribute("aCId")
|
152
155
|
asp = message.attribute("aSp")
|
153
|
-
status = ["ack","aS","sS"].map { |key| message.attribute(key) }.join(',')
|
154
156
|
log "Received #{message.type}, #{alarm_code} #{asp} [#{status}]", message: message, level: :log
|
155
157
|
acknowledge message
|
158
|
+
rescue RSMP::RepeatedAlarmError => e
|
159
|
+
str = "Rejected #{message.type} message, "
|
160
|
+
dont_acknowledge message, str, "#{e}"
|
161
|
+
notify_error e.exception("#{str}#{e.message} #{message.json}")
|
156
162
|
end
|
157
163
|
|
158
164
|
def version_acknowledged
|
@@ -241,13 +247,8 @@ module RSMP
|
|
241
247
|
|
242
248
|
def send_alarm_acknowledgement component, alarm_code, options={}
|
243
249
|
message = RSMP::AlarmAcknowledged.new({
|
244
|
-
"ntsOId" => '',
|
245
|
-
"xNId" => '',
|
246
250
|
"cId" => component,
|
247
251
|
"aCId" => alarm_code,
|
248
|
-
"xACId" => '',
|
249
|
-
"xNACId" => '',
|
250
|
-
"aSp" => 'Acknowledge'
|
251
252
|
})
|
252
253
|
send_message message, validate: options[:validate]
|
253
254
|
message
|
@@ -363,16 +363,6 @@ module RSMP
|
|
363
363
|
end
|
364
364
|
end
|
365
365
|
|
366
|
-
def send_alarm
|
367
|
-
message = Alarm.new({
|
368
|
-
"aSTS"=>clock.to_s,
|
369
|
-
"fP"=>nil,
|
370
|
-
"fS"=>nil,
|
371
|
-
"se"=>@site.aggregated_status_bools
|
372
|
-
})
|
373
|
-
send_message message
|
374
|
-
end
|
375
|
-
|
376
366
|
def sxl_version
|
377
367
|
@site_settings['sxl_version']
|
378
368
|
end
|
data/lib/rsmp/version.rb
CHANGED
data/lib/rsmp.rb
CHANGED
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.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emil Tin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|
@@ -203,7 +203,6 @@ files:
|
|
203
203
|
- documentation/message_distribution.md
|
204
204
|
- exe/rsmp
|
205
205
|
- lib/rsmp.rb
|
206
|
-
- lib/rsmp/alarm.rb
|
207
206
|
- lib/rsmp/archive.rb
|
208
207
|
- lib/rsmp/cli.rb
|
209
208
|
- lib/rsmp/collector.rb
|
data/lib/rsmp/alarm.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# RSMP Alarm. Manages the various states an alarm can be in.
|
2
|
-
|
3
|
-
module RSMP
|
4
|
-
class Alarm
|
5
|
-
|
6
|
-
def initialize code: code, blocked: blocked=false, suspended: suspended=false, acknowledged: acknowledged=false
|
7
|
-
@code = code
|
8
|
-
@code = code
|
9
|
-
@blocked = blocked
|
10
|
-
@suspended = suspended
|
11
|
-
@acknowledged = acknowledged
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
end
|