rsmp 0.12.2 → 0.13.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -4
- data/lib/rsmp/alarm_state.rb +70 -9
- data/lib/rsmp/component.rb +16 -20
- data/lib/rsmp/component_base.rb +5 -1
- data/lib/rsmp/component_proxy.rb +6 -18
- data/lib/rsmp/message.rb +23 -1
- data/lib/rsmp/site.rb +18 -10
- data/lib/rsmp/site_proxy.rb +13 -11
- data/lib/rsmp/supervisor_proxy.rb +5 -1
- data/lib/rsmp/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1840c079564613302ef539e2c0a502c2cafdabe8c875ab2dfb3b389470becf8
|
4
|
+
data.tar.gz: 35eda6efcfabe4624ba58d5150b3c1263a34a2a0b1f363b1a704566acc65cfed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32c6bb82731643e24000e2056a19896fa591755b1336ccad74df28b82ee9800cdb16ee96e6d6e1996e09137fa22cfed5c64801d8b131953a4abc94d32ba9ab08
|
7
|
+
data.tar.gz: d588d1e92eb16473ee86e25e0a595d6bd03c4744f113860bbe89be6f3c3df6ab19bb522daea617f28e8b32708a048d4a2895700cda8de34fed6fd986de85c6a4
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rsmp (0.
|
4
|
+
rsmp (0.13.1)
|
5
5
|
async (~> 1.29.1)
|
6
6
|
async-io (~> 1.32.2)
|
7
7
|
colorize (~> 0.8.1)
|
@@ -68,7 +68,7 @@ GEM
|
|
68
68
|
ffi (1.15.5-x64-mingw32)
|
69
69
|
fiber-local (1.0.0)
|
70
70
|
hana (1.3.7)
|
71
|
-
json_schemer (0.2.
|
71
|
+
json_schemer (0.2.20)
|
72
72
|
ecma-re-validator (~> 0.3)
|
73
73
|
hana (~> 1.3)
|
74
74
|
regexp_parser (~> 2.0)
|
@@ -79,8 +79,8 @@ GEM
|
|
79
79
|
multi_test (0.1.2)
|
80
80
|
nio4r (2.5.8)
|
81
81
|
rake (13.0.6)
|
82
|
-
regexp_parser (2.
|
83
|
-
rsmp_schemer (0.
|
82
|
+
regexp_parser (2.3.1)
|
83
|
+
rsmp_schemer (0.4.0)
|
84
84
|
json_schemer (~> 0.2.18)
|
85
85
|
rspec (3.10.0)
|
86
86
|
rspec-core (~> 3.10.0)
|
data/lib/rsmp/alarm_state.rb
CHANGED
@@ -1,33 +1,94 @@
|
|
1
1
|
module RSMP
|
2
2
|
# class that tracks the state of an alarm
|
3
3
|
class AlarmState
|
4
|
-
attr_reader :component_id, :code, :acknowledged, :suspended, :active, :timestamp, :category, :priority
|
4
|
+
attr_reader :component_id, :code, :acknowledged, :suspended, :active, :timestamp, :category, :priority, :rvs
|
5
5
|
|
6
|
-
def initialize
|
7
|
-
@
|
6
|
+
def initialize component:, code:
|
7
|
+
@component = component
|
8
|
+
@component_id = component.c_id
|
8
9
|
@code = code
|
10
|
+
@suspended = false
|
9
11
|
@acknowledged = false
|
10
12
|
@suspended = false
|
11
13
|
@active = false
|
12
14
|
@timestamp = nil
|
13
|
-
@category =
|
14
|
-
@priority =
|
15
|
+
@category = 'D'
|
16
|
+
@priority = 2
|
17
|
+
@rvs = []
|
15
18
|
end
|
16
19
|
|
17
20
|
def suspend
|
18
|
-
@suspended = true
|
21
|
+
change, @suspended = !@suspended, true
|
22
|
+
update_timestamp if change
|
23
|
+
change
|
19
24
|
end
|
20
25
|
|
21
26
|
def resume
|
22
|
-
@suspended = false
|
27
|
+
change, @suspended = @suspended, false
|
28
|
+
update_timestamp if change
|
29
|
+
change
|
23
30
|
end
|
24
31
|
|
25
32
|
def activate
|
26
|
-
@active = true
|
33
|
+
change, @active = !@active, true
|
34
|
+
update_timestamp if change
|
35
|
+
change
|
27
36
|
end
|
28
37
|
|
29
38
|
def deactivate
|
30
|
-
@active = false
|
39
|
+
change, @active = @active, false
|
40
|
+
update_timestamp if change
|
41
|
+
change
|
42
|
+
end
|
43
|
+
|
44
|
+
def update_timestamp
|
45
|
+
@timestamp = @component.node.clock.now
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_message specialization:
|
49
|
+
Alarm.new(
|
50
|
+
'cId' => @component_id,
|
51
|
+
'aSp' => specialization,
|
52
|
+
'aCId' => @code,
|
53
|
+
'aTs' => Clock.to_s(@timestamp),
|
54
|
+
'ack' => (@acknowledged ? 'Acknowledged' : 'notAcknowledged'),
|
55
|
+
'sS' => (@suspended ? 'suspended' : 'notSuspended'),
|
56
|
+
'aS' => (@active ? 'Active' : 'inActive'),
|
57
|
+
'cat' => @category,
|
58
|
+
'pri' => @priority.to_s,
|
59
|
+
'rvs' => @rvs
|
60
|
+
)
|
31
61
|
end
|
62
|
+
|
63
|
+
def differ_from_message? message
|
64
|
+
return true if @timestamp != message.attribute('aTs')
|
65
|
+
return true if message.attribute('ack') && @acknowledged != (message.attribute('ack') == 'True')
|
66
|
+
return true if message.attribute('sS') && @suspended != (message.attribute('sS') == 'True')
|
67
|
+
return true if message.attribute('aS') && @active != (message.attribute('aS') == 'True')
|
68
|
+
return true if message.attribute('cat') && @category != message.attribute('cat')
|
69
|
+
return true if message.attribute('pri') && @priority != message.attribute('pri').to_i
|
70
|
+
#return true @rvs = message.attribute('rvs')
|
71
|
+
false
|
72
|
+
end
|
73
|
+
|
74
|
+
# update from rsmp message
|
75
|
+
# component id, alarm code and specialization are not updated
|
76
|
+
def update_from_message message
|
77
|
+
unless differ_from_message? message
|
78
|
+
raise RepeatedAlarmError.new("no changes from previous alarm #{message.m_id_short}")
|
79
|
+
end
|
80
|
+
if Time.parse(message.attribute('aTs')) < Time.parse(message.attribute('aTs'))
|
81
|
+
raise TimestampError.new("timestamp is earlier than previous alarm #{message.m_id_short}")
|
82
|
+
end
|
83
|
+
ensure
|
84
|
+
@timestamp = message.attribute('aTs')
|
85
|
+
@acknowledged = message.attribute('ack') == 'True'
|
86
|
+
@suspended = message.attribute('sS') == 'True'
|
87
|
+
@active = message.attribute('aS') == 'True'
|
88
|
+
@category = message.attribute('cat')
|
89
|
+
@priority = message.attribute('pri').to_i
|
90
|
+
@rvs = message.attribute('rvs')
|
91
|
+
end
|
92
|
+
|
32
93
|
end
|
33
94
|
end
|
data/lib/rsmp/component.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module RSMP
|
2
|
-
|
3
2
|
# RSMP component
|
4
|
-
|
5
3
|
class Component < ComponentBase
|
6
4
|
def initialize node:, id:, grouped: false
|
7
5
|
super
|
@@ -15,40 +13,38 @@ module RSMP
|
|
15
13
|
raise UnknownStatus.new "Status #{status_code}/#{status_name} not implemented by #{self.class}"
|
16
14
|
end
|
17
15
|
|
18
|
-
def get_alarm_state alarm_code
|
19
|
-
alarm = @alarms[alarm_code] ||= RSMP::AlarmState.new component_id: c_id, code: alarm_code
|
20
|
-
end
|
21
|
-
|
22
16
|
def suspend_alarm alarm_code
|
23
17
|
alarm = get_alarm_state alarm_code
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
18
|
+
if alarm.suspend
|
19
|
+
log "Suspending alarm #{alarm_code}", level: :info
|
20
|
+
@node.alarm_suspended_or_resumed alarm
|
21
|
+
else
|
22
|
+
log "Alarm #{alarm_code} already suspended", level: :info
|
23
|
+
end
|
28
24
|
end
|
29
25
|
|
30
26
|
def resume_alarm alarm_code
|
31
27
|
alarm = get_alarm_state alarm_code
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
28
|
+
if alarm.resume
|
29
|
+
log "Resuming alarm #{alarm_code}", level: :info
|
30
|
+
@node.alarm_suspended_or_resumed alarm
|
31
|
+
else
|
32
|
+
log "Alarm #{alarm_code} already resumed", level: :info
|
33
|
+
end
|
36
34
|
end
|
37
35
|
|
38
36
|
def activate_alarm alarm_code
|
39
37
|
alarm = get_alarm_state alarm_code
|
40
|
-
return
|
38
|
+
return unless alarm.activate
|
41
39
|
log "Activating alarm #{alarm_code}", level: :info
|
42
|
-
alarm
|
43
|
-
@node.alarm_changed alarm
|
40
|
+
@node.alarm_activated_or_deactivated alarm
|
44
41
|
end
|
45
42
|
|
46
43
|
def deactivate_alarm alarm_code
|
47
44
|
alarm = get_alarm_state alarm_code
|
48
|
-
return unless alarm.
|
45
|
+
return unless alarm.deactivate
|
49
46
|
log "Deactivating alarm #{alarm_code}", level: :info
|
50
|
-
alarm
|
51
|
-
@node.alarm_changed alarm
|
47
|
+
@node.alarm_activated_or_deactivated alarm
|
52
48
|
end
|
53
49
|
end
|
54
50
|
end
|
data/lib/rsmp/component_base.rb
CHANGED
@@ -20,8 +20,12 @@ module RSMP
|
|
20
20
|
@c_id = id
|
21
21
|
@node = node
|
22
22
|
@grouped = grouped
|
23
|
-
@alarms = {}
|
24
23
|
clear_aggregated_status
|
24
|
+
@alarms = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_alarm_state alarm_code
|
28
|
+
alarm = @alarms[alarm_code] ||= RSMP::AlarmState.new component: self, code: alarm_code
|
25
29
|
end
|
26
30
|
|
27
31
|
def clear_aggregated_status
|
data/lib/rsmp/component_proxy.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
module RSMP
|
2
|
-
|
3
2
|
# A proxy to a remote RSMP component.
|
4
|
-
|
5
3
|
class ComponentProxy < ComponentBase
|
6
4
|
def initialize node:, id:, grouped: false
|
7
5
|
super
|
6
|
+
@alarms = {}
|
8
7
|
@statuses = {}
|
9
8
|
@allow_repeat_updates = {}
|
10
9
|
end
|
@@ -45,23 +44,12 @@ module RSMP
|
|
45
44
|
@allow_repeat_updates[sCI].delete(n) if @allow_repeat_updates[sCI]
|
46
45
|
end
|
47
46
|
end
|
48
|
-
|
47
|
+
|
49
48
|
# handle incoming alarm
|
50
49
|
def handle_alarm message
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
# unless message.differ?(previous)
|
55
|
-
# raise RepeatedAlarmError.new("no changes from previous alarm #{previous.m_id_short}")
|
56
|
-
# end
|
57
|
-
# if Time.parse(message.attribute('aTs')) < Time.parse(previous.attribute('aTs'))
|
58
|
-
# raise TimestampError.new("timestamp is earlier than previous alarm #{previous.m_id_short}")
|
59
|
-
# end
|
60
|
-
# end
|
61
|
-
# p message
|
62
|
-
# ensure
|
63
|
-
# @alarms[code] = message
|
50
|
+
code = message.attribute('aCId')
|
51
|
+
alarm = get_alarm_state code
|
52
|
+
alarm.update_from_message message
|
64
53
|
end
|
65
|
-
|
66
|
-
end
|
54
|
+
end
|
67
55
|
end
|
data/lib/rsmp/message.rb
CHANGED
@@ -68,7 +68,13 @@ module RSMP
|
|
68
68
|
when /Acknowledge/i
|
69
69
|
AlarmAcknowledged.new attributes
|
70
70
|
when /Suspend/i
|
71
|
-
|
71
|
+
if attributes['sS'] =~ /suspended/i
|
72
|
+
AlarmSuspended.new attributes
|
73
|
+
elsif attributes['sS'] =~ /notSuspended/i
|
74
|
+
AlarmResumed.new attributes
|
75
|
+
else
|
76
|
+
AlarmSuspend.new attributes
|
77
|
+
end
|
72
78
|
when /Resume/i
|
73
79
|
AlarmResume.new attributes
|
74
80
|
else
|
@@ -264,7 +270,23 @@ module RSMP
|
|
264
270
|
end
|
265
271
|
end
|
266
272
|
|
273
|
+
class AlarmSuspended < Alarm
|
274
|
+
def initialize attributes = {}
|
275
|
+
super({
|
276
|
+
"aSp" => "Suspend",
|
277
|
+
"sS" => "suspended"
|
278
|
+
}.merge attributes)
|
279
|
+
end
|
280
|
+
end
|
267
281
|
|
282
|
+
class AlarmResumed < Alarm
|
283
|
+
def initialize attributes = {}
|
284
|
+
super({
|
285
|
+
"aSp" => "Suspend",
|
286
|
+
"sS" => "notSuspended"
|
287
|
+
}.merge attributes)
|
288
|
+
end
|
289
|
+
end
|
268
290
|
|
269
291
|
class Watchdog < Message
|
270
292
|
def initialize attributes = {}
|
data/lib/rsmp/site.rb
CHANGED
@@ -93,23 +93,31 @@ module RSMP
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
def
|
97
|
-
|
96
|
+
def alarm_state_to_hash alarm_state
|
97
|
+
{
|
98
98
|
'cId' => alarm_state.component_id,
|
99
|
-
'aTs' => clock.to_s,
|
100
99
|
'aCId' => alarm_state.code,
|
101
|
-
'
|
100
|
+
'aTs' => Clock.to_s(alarm_state.timestamp),
|
102
101
|
'ack' => (alarm_state.acknowledged ? 'Acknowledged' : 'notAcknowledged'),
|
103
102
|
'sS' => (alarm_state.suspended ? 'suspended' : 'notSuspended'),
|
104
103
|
'aS' => (alarm_state.active ? 'Active' : 'inActive'),
|
105
|
-
'cat' =>
|
106
|
-
'pri' =>
|
107
|
-
'rvs' =>
|
108
|
-
|
104
|
+
'cat' => alarm_state.category,
|
105
|
+
'pri' => alarm_state.priority.to_s,
|
106
|
+
'rvs' => alarm_state.rvs
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
def alarm_suspended_or_resumed alarm_state
|
111
|
+
alarm = AlarmIssue.new( alarm_state_to_hash(alarm_state).merge('aSp' => 'Suspend') )
|
112
|
+
send_alarm alarm
|
113
|
+
end
|
114
|
+
|
115
|
+
def alarm_activated_or_deactivated alarm_state
|
116
|
+
alarm = AlarmIssue.new( alarm_state_to_hash(alarm_state).merge('aSp' => 'Issue') )
|
117
|
+
send_alarm alarm
|
109
118
|
end
|
110
119
|
|
111
|
-
def
|
112
|
-
alarm = alarm_state_to_message alarm_state
|
120
|
+
def send_alarm alarm
|
113
121
|
@proxies.each do |proxy|
|
114
122
|
proxy.send_message alarm if proxy.ready?
|
115
123
|
end
|
data/lib/rsmp/site_proxy.rb
CHANGED
@@ -63,7 +63,7 @@ module RSMP
|
|
63
63
|
process_aggregated_status message
|
64
64
|
when AggregatedStatusRequest
|
65
65
|
will_not_handle message
|
66
|
-
when
|
66
|
+
when AlarmIssue, AlarmSuspended, AlarmResumed
|
67
67
|
process_alarm message
|
68
68
|
when CommandResponse
|
69
69
|
process_command_response message
|
@@ -116,8 +116,8 @@ module RSMP
|
|
116
116
|
m_id = options[:m_id] || RSMP::Message.make_m_id
|
117
117
|
|
118
118
|
message = RSMP::AggregatedStatusRequest.new({
|
119
|
-
"ntsOId" =>
|
120
|
-
"xNId" =>
|
119
|
+
"ntsOId" => @ntsOId,
|
120
|
+
"xNId" => @xNId,
|
121
121
|
"cId" => component,
|
122
122
|
"mId" => m_id
|
123
123
|
})
|
@@ -187,8 +187,8 @@ module RSMP
|
|
187
187
|
request_list = status_list.map { |item| item.slice('sCI','n') }
|
188
188
|
|
189
189
|
message = RSMP::StatusRequest.new({
|
190
|
-
"ntsOId" =>
|
191
|
-
"xNId" =>
|
190
|
+
"ntsOId" => @ntsOId,
|
191
|
+
"xNId" => @xNId,
|
192
192
|
"cId" => component,
|
193
193
|
"sS" => request_list,
|
194
194
|
"mId" => m_id
|
@@ -232,8 +232,8 @@ module RSMP
|
|
232
232
|
component.allow_repeat_updates subscribe_list
|
233
233
|
|
234
234
|
message = RSMP::StatusSubscribe.new({
|
235
|
-
"ntsOId" =>
|
236
|
-
"xNId" =>
|
235
|
+
"ntsOId" => @ntsOId,
|
236
|
+
"xNId" => @xNId,
|
237
237
|
"cId" => component_id,
|
238
238
|
"sS" => subscribe_list,
|
239
239
|
'mId' => m_id
|
@@ -262,8 +262,8 @@ module RSMP
|
|
262
262
|
end
|
263
263
|
|
264
264
|
message = RSMP::StatusUnsubscribe.new({
|
265
|
-
"ntsOId" =>
|
266
|
-
"xNId" =>
|
265
|
+
"ntsOId" => @ntsOId,
|
266
|
+
"xNId" => @xNId,
|
267
267
|
"cId" => component_id,
|
268
268
|
"sS" => status_list
|
269
269
|
})
|
@@ -292,8 +292,8 @@ module RSMP
|
|
292
292
|
validate_ready 'send command'
|
293
293
|
m_id = options[:m_id] || RSMP::Message.make_m_id
|
294
294
|
message = RSMP::CommandRequest.new({
|
295
|
-
"ntsOId" =>
|
296
|
-
"xNId" =>
|
295
|
+
"ntsOId" => @ntsOId,
|
296
|
+
"xNId" => @xNId,
|
297
297
|
"cId" => component,
|
298
298
|
"arg" => command_list,
|
299
299
|
"mId" => m_id
|
@@ -369,6 +369,8 @@ module RSMP
|
|
369
369
|
@site_settings = find_site_settings @site_id
|
370
370
|
if @site_settings
|
371
371
|
@sxl = @site_settings['sxl']
|
372
|
+
@ntsOId = @site_settings['ntsOId']
|
373
|
+
@xNId = @site_settings['xNId']
|
372
374
|
setup_components @site_settings['components']
|
373
375
|
else
|
374
376
|
dont_acknowledge message, 'Rejected', "No config found for site #{@site_id}"
|
@@ -15,6 +15,8 @@ module RSMP
|
|
15
15
|
@port = options[:port]
|
16
16
|
@status_subscriptions = {}
|
17
17
|
@sxl = @site_settings['sxl']
|
18
|
+
@ntsOId = @site_settings['ntsOId']
|
19
|
+
@xNId = @site_settings['xNId']
|
18
20
|
@synthetic_id = Supervisor.build_id_from_ip_port @ip, @port
|
19
21
|
end
|
20
22
|
|
@@ -105,7 +107,7 @@ module RSMP
|
|
105
107
|
process_status_subcribe message
|
106
108
|
when StatusUnsubscribe
|
107
109
|
process_status_unsubcribe message
|
108
|
-
when AlarmAcknowledged, AlarmSuspend, AlarmResume, AlarmRequest
|
110
|
+
when Alarm, AlarmAcknowledged, AlarmSuspend, AlarmResume, AlarmRequest
|
109
111
|
process_alarm message
|
110
112
|
else
|
111
113
|
super message
|
@@ -160,6 +162,8 @@ module RSMP
|
|
160
162
|
"se" => component.aggregated_status_bools,
|
161
163
|
"mId" => m_id,
|
162
164
|
})
|
165
|
+
message.attributes['ntsOId'] = @site_settings['ntsOId'] if @site_settings['ntsOId']
|
166
|
+
message.attributes['xNId'] = @site_settings['xNId'] if @site_settings['xNId']
|
163
167
|
|
164
168
|
send_and_optionally_collect message, options do |collect_options|
|
165
169
|
Collector.new self, collect_options.merge(task:@task, type: 'MessageAck')
|
data/lib/rsmp/version.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.
|
4
|
+
version: 0.13.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emil Tin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-04-
|
11
|
+
date: 2022-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|