rsmp 0.12.2 → 0.13.1
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 +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
|