rsmp 0.3.3 → 0.3.7
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 +14 -4
- data/lib/rsmp/components.rb +16 -3
- data/lib/rsmp/error.rb +3 -0
- data/lib/rsmp/message.rb +60 -5
- data/lib/rsmp/proxy.rb +11 -5
- data/lib/rsmp/site.rb +1 -1
- data/lib/rsmp/site_proxy.rb +12 -17
- data/lib/rsmp/supervisor_proxy.rb +0 -10
- data/lib/rsmp/tlc.rb +4 -2
- data/lib/rsmp/version.rb +1 -1
- data/lib/rsmp.rb +0 -1
- metadata +3 -4
- 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: 63163e8e010e001deffd0bba691e343c028ae5edbf3a5c9022529d319c36035e
|
4
|
+
data.tar.gz: 07225c7538b514c3b74dbc307a432f32eb1fe839faaeef4483208206b29e103a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6eed25d057be1a6766b94d1127b41f498b4e3532bf5650d7c888321dfe48bafaf2af69ff2d871cc437fc44ae9286d898da2387bc2e267d451aca332d3695159f
|
7
|
+
data.tar.gz: 011f89ceb76bbfdc521ca0730c2d7f1c48663e4faf35576e4e72bee83831813745bc0ce0c45aab4201c1874f1ee21a5c1f6235dbab0c16feab1e3970acc56d3b
|
data/Gemfile.lock
CHANGED
data/lib/rsmp/component.rb
CHANGED
@@ -13,7 +13,7 @@ module RSMP
|
|
13
13
|
:rest,
|
14
14
|
:not_connected ]
|
15
15
|
|
16
|
-
def initialize node:, id:, grouped:
|
16
|
+
def initialize node:, id:, grouped: false
|
17
17
|
@c_id = id
|
18
18
|
@node = node
|
19
19
|
@grouped = grouped
|
@@ -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
@@ -38,10 +38,23 @@ module RSMP
|
|
38
38
|
Component.new id:id, node: self, grouped: type=='main'
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
41
|
+
def infer_component_type component_id
|
42
|
+
Component
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_component component_id, build: true
|
42
46
|
component = @components[component_id]
|
43
|
-
|
44
|
-
|
47
|
+
return component if component
|
48
|
+
if build
|
49
|
+
inferred = infer_component_type component_id
|
50
|
+
component = inferred.new node: self, id: component_id
|
51
|
+
@components[ component_id] = component
|
52
|
+
class_name = component.class.name.split('::').last
|
53
|
+
log "Inferred #{class_name} component #{component_id}", level: :info
|
54
|
+
component
|
55
|
+
else
|
56
|
+
raise UnknownComponent.new("Component #{component_id} not found") unless component
|
57
|
+
end
|
45
58
|
end
|
46
59
|
|
47
60
|
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
|
@@ -303,10 +308,11 @@ module RSMP
|
|
303
308
|
end
|
304
309
|
|
305
310
|
def should_validate_ingoing_message? message
|
306
|
-
return
|
311
|
+
return true unless @site_settings
|
307
312
|
skip = @site_settings.dig('skip_validation')
|
308
|
-
return true unless skip
|
309
|
-
|
313
|
+
return true unless skip
|
314
|
+
klass = message.class.name.split('::').last
|
315
|
+
!skip.include?(klass)
|
310
316
|
end
|
311
317
|
|
312
318
|
def process_packet json
|
data/lib/rsmp/site.rb
CHANGED
data/lib/rsmp/site_proxy.rb
CHANGED
@@ -125,17 +125,11 @@ module RSMP
|
|
125
125
|
se = message.attribute("se")
|
126
126
|
validate_aggregated_status(message,se) == false
|
127
127
|
c_id = message.attributes["cId"]
|
128
|
-
component =
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
log "Adding component #{c_id} to site #{@site_id}", level: :info
|
134
|
-
else
|
135
|
-
reason = "component #{c_id} not found"
|
136
|
-
dont_acknowledge message, "Ignoring #{message.type}:", reason
|
137
|
-
return
|
138
|
-
end
|
128
|
+
component = find_component c_id
|
129
|
+
unless component
|
130
|
+
reason = "component #{c_id} not found"
|
131
|
+
dont_acknowledge message, "Ignoring #{message.type}:", reason
|
132
|
+
return
|
139
133
|
end
|
140
134
|
|
141
135
|
component.set_aggregated_status_bools se
|
@@ -148,11 +142,17 @@ module RSMP
|
|
148
142
|
end
|
149
143
|
|
150
144
|
def process_alarm message
|
145
|
+
component = find_component message.attribute("cId")
|
146
|
+
status = ["ack","aS","sS"].map { |key| message.attribute(key) }.join(',')
|
147
|
+
component.handle_alarm message
|
151
148
|
alarm_code = message.attribute("aCId")
|
152
149
|
asp = message.attribute("aSp")
|
153
|
-
status = ["ack","aS","sS"].map { |key| message.attribute(key) }.join(',')
|
154
150
|
log "Received #{message.type}, #{alarm_code} #{asp} [#{status}]", message: message, level: :log
|
155
151
|
acknowledge message
|
152
|
+
rescue RSMP::RepeatedAlarmError => e
|
153
|
+
str = "Rejected #{message.type} message, "
|
154
|
+
dont_acknowledge message, str, "#{e}"
|
155
|
+
notify_error e.exception("#{str}#{e.message} #{message.json}")
|
156
156
|
end
|
157
157
|
|
158
158
|
def version_acknowledged
|
@@ -241,13 +241,8 @@ module RSMP
|
|
241
241
|
|
242
242
|
def send_alarm_acknowledgement component, alarm_code, options={}
|
243
243
|
message = RSMP::AlarmAcknowledged.new({
|
244
|
-
"ntsOId" => '',
|
245
|
-
"xNId" => '',
|
246
244
|
"cId" => component,
|
247
245
|
"aCId" => alarm_code,
|
248
|
-
"xACId" => '',
|
249
|
-
"xNACId" => '',
|
250
|
-
"aSp" => 'Acknowledge'
|
251
246
|
})
|
252
247
|
send_message message, validate: options[:validate]
|
253
248
|
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/tlc.rb
CHANGED
@@ -5,7 +5,7 @@ module RSMP
|
|
5
5
|
class TrafficController < Component
|
6
6
|
attr_reader :pos, :cycle_time
|
7
7
|
|
8
|
-
def initialize node:, id:, cycle_time:
|
8
|
+
def initialize node:, id:, cycle_time: 10
|
9
9
|
super node: node, id: id, grouped: true
|
10
10
|
@signal_groups = []
|
11
11
|
@detector_logics = []
|
@@ -625,13 +625,15 @@ module RSMP
|
|
625
625
|
class SignalGroup < Component
|
626
626
|
attr_reader :plan, :state
|
627
627
|
|
628
|
-
|
628
|
+
# plan is a string, with each character representing a signal phase at a particular second in the cycle
|
629
|
+
def initialize node:, id:, plan: nil
|
629
630
|
super node: node, id: id, grouped: false
|
630
631
|
@plan = plan
|
631
632
|
move 0
|
632
633
|
end
|
633
634
|
|
634
635
|
def get_state pos
|
636
|
+
return 'a' unless @plan # if no plan, use phase a, which means disabled/dark
|
635
637
|
if pos > @plan.length
|
636
638
|
'.'
|
637
639
|
else
|
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.7
|
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-25 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
|
@@ -255,7 +254,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
255
254
|
- !ruby/object:Gem::Version
|
256
255
|
version: '0'
|
257
256
|
requirements: []
|
258
|
-
rubygems_version: 3.2.
|
257
|
+
rubygems_version: 3.2.26
|
259
258
|
signing_key:
|
260
259
|
specification_version: 4
|
261
260
|
summary: RoadSide Message Protocol (RSMP) library.
|
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
|