rsmp 0.6.0 → 0.6.4
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 +2 -2
- data/README.md +2 -2
- data/config/supervisor.yaml +1 -8
- data/config/tlc.yaml +17 -12
- data/lib/rsmp/archive.rb +2 -2
- data/lib/rsmp/cli.rb +1 -1
- data/lib/rsmp/component.rb +2 -2
- data/lib/rsmp/components.rb +6 -3
- data/lib/rsmp/logger.rb +11 -10
- data/lib/rsmp/logging.rb +1 -1
- data/lib/rsmp/proxy.rb +8 -5
- data/lib/rsmp/supervisor.rb +1 -0
- data/lib/rsmp/supervisor_proxy.rb +11 -4
- data/lib/rsmp/tlc/detector_logic.rb +101 -0
- data/lib/rsmp/tlc/signal_group.rb +85 -0
- data/lib/rsmp/tlc/signal_plan.rb +29 -0
- data/lib/rsmp/tlc/traffic_controller.rb +652 -0
- data/lib/rsmp/tlc/traffic_controller_site.rb +136 -0
- data/lib/rsmp/version.rb +1 -1
- data/lib/rsmp.rb +5 -1
- metadata +8 -4
- data/lib/rsmp/tlc.rb +0 -920
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 33b8c859b9c8450af6a45d52a9d42d982c5becdaf1d4424f398b417bc1c387d8
|
|
4
|
+
data.tar.gz: 7f194bb392a69555f7ba30364466dfed9eeb1b04996505fa13af13d9045bb071
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2d9da45e5f1a96756cd50f58ea3ce16dc0de51138daa45aa114f432e0531595883c5cf3dba86ad63dd0a33aed7ba02d706f058378c257129a8b877eb45e2246b
|
|
7
|
+
data.tar.gz: 59965992a0e7bcdd6e401fac5baa2e8839c392713812da579865020d6cf5d9cf73d51b250f9be72cab3264fd5a9edd287e85619e2ebab0259fb303da9cfe25ff
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
rsmp (0.6.
|
|
4
|
+
rsmp (0.6.4)
|
|
5
5
|
async (~> 1.29.1)
|
|
6
6
|
async-io (~> 1.32.1)
|
|
7
7
|
colorize (~> 0.8.1)
|
|
@@ -96,7 +96,7 @@ GEM
|
|
|
96
96
|
thread_safe
|
|
97
97
|
rake (13.0.3)
|
|
98
98
|
regexp_parser (2.1.1)
|
|
99
|
-
rsmp_schemer (0.3.
|
|
99
|
+
rsmp_schemer (0.3.2)
|
|
100
100
|
json_schemer (~> 0.2.18)
|
|
101
101
|
rspec (3.10.0)
|
|
102
102
|
rspec-core (~> 3.10.0)
|
data/README.md
CHANGED
|
@@ -125,7 +125,7 @@ This will output messages form both the site and the supervisor, ordered chronol
|
|
|
125
125
|
```console
|
|
126
126
|
RN+SU0001 Starting supervisor RN+SU0001 on port 12111
|
|
127
127
|
RN+SI0001 Starting site RN+SI0001
|
|
128
|
-
RN+SI0001 Connecting to
|
|
128
|
+
RN+SI0001 Connecting to supervisor at 127.0.0.1:12111
|
|
129
129
|
RN+SI0001 <-- f8c7 Sent Version
|
|
130
130
|
RN+SU0001 Site connected from 127.0.0.1:53500
|
|
131
131
|
RN+SU0001 RN+SI0001 --> f8c7 Received Version message for sites [RN+SI0001] using RSMP 3.1.4
|
|
@@ -156,7 +156,7 @@ The ```site``` command will start an RSMP site, which will try to connect to one
|
|
|
156
156
|
```console
|
|
157
157
|
% rsmp site
|
|
158
158
|
2019-11-11 12:22:00 UTC Starting site RN+SI0001
|
|
159
|
-
2019-11-11 12:22:00 UTC Connecting to
|
|
159
|
+
2019-11-11 12:22:00 UTC Connecting to supervisor at 127.0.0.1:12111
|
|
160
160
|
2019-11-11 12:22:00 UTC <-- 792f Sent Version
|
|
161
161
|
2019-11-11 12:22:00 UTC RN+SU0001 --> e70e Received Version message, using RSMP 3.1.4
|
|
162
162
|
2019-11-11 12:22:00 UTC RN+SU0001 Connection to supervisor established
|
data/config/supervisor.yaml
CHANGED
|
@@ -8,16 +8,9 @@ guest:
|
|
|
8
8
|
watchdog: 0.2
|
|
9
9
|
acknowledgement: 0.2
|
|
10
10
|
log:
|
|
11
|
-
active: true
|
|
12
|
-
color: true
|
|
13
|
-
timestamp: true
|
|
14
|
-
id: true
|
|
15
|
-
component: true
|
|
16
|
-
ip: false
|
|
17
11
|
port: true
|
|
18
12
|
site_id: 9
|
|
19
|
-
|
|
20
|
-
text: true
|
|
13
|
+
component: 2
|
|
21
14
|
direction: false
|
|
22
15
|
level: false
|
|
23
16
|
debug: true
|
data/config/tlc.yaml
CHANGED
|
@@ -10,15 +10,27 @@ components:
|
|
|
10
10
|
cycle_time: 6
|
|
11
11
|
signal_group:
|
|
12
12
|
A1:
|
|
13
|
-
plan: '11NBBB'
|
|
14
13
|
A2:
|
|
15
|
-
plan: '1NBBBB'
|
|
16
14
|
B1:
|
|
17
|
-
plan: 'BBB11N'
|
|
18
15
|
B2:
|
|
19
|
-
plan: 'BBB1NB'
|
|
20
16
|
detector_logic:
|
|
21
17
|
DL1:
|
|
18
|
+
signal_plans:
|
|
19
|
+
1:
|
|
20
|
+
dynamic_bands:
|
|
21
|
+
1: 0
|
|
22
|
+
2: 5
|
|
23
|
+
states:
|
|
24
|
+
A1: '11NBBB'
|
|
25
|
+
A2: '1NBBBB'
|
|
26
|
+
B1: 'BBB11N'
|
|
27
|
+
B2: 'BBB1NB'
|
|
28
|
+
2:
|
|
29
|
+
states:
|
|
30
|
+
A1: '111NBB'
|
|
31
|
+
A2: '11NBBB'
|
|
32
|
+
B1: 'BBB11N'
|
|
33
|
+
B2: 'BBB1NB'
|
|
22
34
|
intervals:
|
|
23
35
|
timer: 0.1
|
|
24
36
|
watchdog: 0.1
|
|
@@ -30,18 +42,11 @@ security_codes:
|
|
|
30
42
|
1: '1111'
|
|
31
43
|
2: '2222'
|
|
32
44
|
log:
|
|
33
|
-
active: true
|
|
34
|
-
color: true
|
|
35
|
-
timestamp: true
|
|
36
|
-
id: true
|
|
37
|
-
component_id: true
|
|
38
45
|
ip: false
|
|
39
46
|
site_id: 9
|
|
40
|
-
|
|
47
|
+
component: 2
|
|
41
48
|
level: false
|
|
42
49
|
debug: true
|
|
43
|
-
text: true
|
|
44
|
-
direction: false
|
|
45
50
|
json: true
|
|
46
51
|
acknowledgements: false
|
|
47
52
|
watchdogs: false
|
data/lib/rsmp/archive.rb
CHANGED
|
@@ -21,11 +21,11 @@ module RSMP
|
|
|
21
21
|
def self.prepare_item item
|
|
22
22
|
raise ArgumentError unless item.is_a? Hash
|
|
23
23
|
|
|
24
|
-
cleaned = item.select { |k,v| [:author,:level,:ip,:port,:site_id,:
|
|
24
|
+
cleaned = item.select { |k,v| [:author,:level,:ip,:port,:site_id,:component,:text,:message,:exception].include? k }
|
|
25
25
|
cleaned[:timestamp] = Clock.now
|
|
26
26
|
if item[:message]
|
|
27
27
|
cleaned[:direction] = item[:message].direction
|
|
28
|
-
cleaned[:
|
|
28
|
+
cleaned[:component] = item[:message].attributes['cId']
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
cleaned
|
data/lib/rsmp/cli.rb
CHANGED
data/lib/rsmp/component.rb
CHANGED
|
@@ -65,7 +65,8 @@ module RSMP
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def log str, options
|
|
68
|
-
|
|
68
|
+
default = { component: c_id}
|
|
69
|
+
@node.log str, default.merge(options)
|
|
69
70
|
end
|
|
70
71
|
|
|
71
72
|
def handle_command command_code, arg
|
|
@@ -118,7 +119,6 @@ module RSMP
|
|
|
118
119
|
@statuses[sCI][n] ||= {}
|
|
119
120
|
@statuses[sCI][n][:initial] = true
|
|
120
121
|
end
|
|
121
|
-
#pp @subscribes
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
# Our proxy unsubscribed to status updates.
|
data/lib/rsmp/components.rb
CHANGED
|
@@ -15,8 +15,10 @@ module RSMP
|
|
|
15
15
|
return unless settings
|
|
16
16
|
check_main_component settings
|
|
17
17
|
settings.each_pair do |type,components_by_type|
|
|
18
|
-
components_by_type
|
|
19
|
-
|
|
18
|
+
if components_by_type
|
|
19
|
+
components_by_type.each_pair do |id,settings|
|
|
20
|
+
@components[id] = build_component(id:id, type:type, settings:settings)
|
|
21
|
+
end
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
end
|
|
@@ -50,7 +52,8 @@ module RSMP
|
|
|
50
52
|
component = inferred.new node: self, id: component_id
|
|
51
53
|
@components[ component_id] = component
|
|
52
54
|
class_name = component.class.name.split('::').last
|
|
53
|
-
|
|
55
|
+
class_name << " compoent" unless class_name == 'Component'
|
|
56
|
+
log "Inferred #{class_name} #{component_id}", level: :debug
|
|
54
57
|
component
|
|
55
58
|
else
|
|
56
59
|
raise UnknownComponent.new("Component #{component_id} not found") unless component
|
data/lib/rsmp/logger.rb
CHANGED
|
@@ -5,7 +5,7 @@ module RSMP
|
|
|
5
5
|
|
|
6
6
|
def initialize settings={}
|
|
7
7
|
defaults = {
|
|
8
|
-
'active'=>
|
|
8
|
+
'active'=>true,
|
|
9
9
|
'path'=>nil,
|
|
10
10
|
'stream'=>nil,
|
|
11
11
|
'color'=>true,
|
|
@@ -13,6 +13,7 @@ module RSMP
|
|
|
13
13
|
'statistics'=>false,
|
|
14
14
|
'hide_ip_and_port' => false,
|
|
15
15
|
'acknowledgements' => false,
|
|
16
|
+
'watchdogs' => false,
|
|
16
17
|
'json'=>false,
|
|
17
18
|
'tabs'=>'-',
|
|
18
19
|
|
|
@@ -23,11 +24,11 @@ module RSMP
|
|
|
23
24
|
'ip'=>false,
|
|
24
25
|
'port'=>false,
|
|
25
26
|
'site_id'=>true,
|
|
26
|
-
'
|
|
27
|
+
'component'=>true,
|
|
27
28
|
'direction'=>false,
|
|
28
29
|
'level'=>false,
|
|
29
|
-
'id'=>
|
|
30
|
-
'
|
|
30
|
+
'id'=>true,
|
|
31
|
+
'text'=>true,
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
default_lengths = {
|
|
@@ -37,8 +38,8 @@ module RSMP
|
|
|
37
38
|
'ip'=>22,
|
|
38
39
|
'port'=>5,
|
|
39
40
|
'site_id'=>19,
|
|
40
|
-
'
|
|
41
|
-
'direction'=>
|
|
41
|
+
'component'=>19,
|
|
42
|
+
'direction'=>3,
|
|
42
43
|
'level'=>7,
|
|
43
44
|
'id'=>4,
|
|
44
45
|
}
|
|
@@ -189,15 +190,15 @@ module RSMP
|
|
|
189
190
|
build_part( parts, item, :ip )
|
|
190
191
|
build_part( parts, item, :port )
|
|
191
192
|
build_part( parts, item, :site_id )
|
|
192
|
-
build_part( parts, item, :
|
|
193
|
-
build_part( parts, item, :direction ) { |part| {in:"
|
|
193
|
+
build_part( parts, item, :component )
|
|
194
|
+
build_part( parts, item, :direction ) { |part| {in:"In",out:"Out"}[part] }
|
|
194
195
|
build_part( parts, item, :level ) { |part| part.capitalize }
|
|
195
196
|
build_part( parts, item, :id ) { Logger.shorten_message_id(item[:message].m_id,4) if item[:message] }
|
|
196
|
-
build_part( parts, item, :
|
|
197
|
+
build_part( parts, item, :text )
|
|
197
198
|
build_part( parts, item, :json ) { item[:message].json if item[:message] }
|
|
198
199
|
build_part( parts, item, :exception ) { |e| [e.class,e.backtrace].flatten.join("\n") }
|
|
199
200
|
|
|
200
|
-
parts.join(' ').chomp(@settings['tabs']).rstrip
|
|
201
|
+
parts.join(' ').chomp(@settings['tabs'].to_s).rstrip
|
|
201
202
|
end
|
|
202
203
|
end
|
|
203
204
|
end
|
data/lib/rsmp/logging.rb
CHANGED
|
@@ -15,7 +15,7 @@ module RSMP
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def log str, options={}
|
|
18
|
-
default = {
|
|
18
|
+
default = { text:str, level: :log, author: author, ip: @ip, port: @port }
|
|
19
19
|
prepared = RSMP::Archive.prepare_item default.merge(options)
|
|
20
20
|
@archive.add prepared
|
|
21
21
|
@logger.log prepared
|
data/lib/rsmp/proxy.rb
CHANGED
|
@@ -348,20 +348,23 @@ module RSMP
|
|
|
348
348
|
# cannot send NotAcknowledged for a malformed message since we can't read it, just ignore it
|
|
349
349
|
nil
|
|
350
350
|
rescue SchemaError, RSMP::Schemer::Error => e
|
|
351
|
-
|
|
351
|
+
reason = "schema errors: #{e.message}"
|
|
352
|
+
str = "Received invalid #{message.type}, #{reason}"
|
|
352
353
|
log str, message: message, level: :warning
|
|
353
354
|
notify_error e.exception(str), message: message
|
|
354
|
-
dont_acknowledge message, str
|
|
355
|
+
dont_acknowledge message, str, reason
|
|
355
356
|
message
|
|
356
357
|
rescue InvalidMessage => e
|
|
357
|
-
|
|
358
|
+
reason = "#{e.message}"
|
|
359
|
+
str = "Received invalid #{message.type},"
|
|
358
360
|
notify_error e.exception("#{str} #{message.json}"), message: message
|
|
359
|
-
dont_acknowledge message, str
|
|
361
|
+
dont_acknowledge message, str, reason
|
|
360
362
|
message
|
|
361
363
|
rescue FatalError => e
|
|
364
|
+
reason = e.message
|
|
362
365
|
str = "Rejected #{message.type},"
|
|
363
366
|
notify_error e.exception(str), message: message
|
|
364
|
-
dont_acknowledge message, str,
|
|
367
|
+
dont_acknowledge message, str, reason
|
|
365
368
|
stop
|
|
366
369
|
message
|
|
367
370
|
ensure
|
data/lib/rsmp/supervisor.rb
CHANGED
|
@@ -23,15 +23,22 @@ module RSMP
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def start
|
|
26
|
-
log "Connecting to
|
|
26
|
+
log "Connecting to supervisor at #{@ip}:#{@port}", level: :info
|
|
27
27
|
super
|
|
28
28
|
connect
|
|
29
29
|
@logger.unmute @ip, @port
|
|
30
|
-
log "Connected to
|
|
30
|
+
log "Connected to supervisor at #{@ip}:#{@port}", level: :info
|
|
31
31
|
start_reader
|
|
32
32
|
send_version @site_settings['site_id'], @site_settings["rsmp_versions"]
|
|
33
|
-
rescue
|
|
34
|
-
log "
|
|
33
|
+
rescue SystemCallError => e
|
|
34
|
+
log "Could not connect to supervisor at #{@ip}:#{@port}: Errno #{e.errno} #{e}", level: :error
|
|
35
|
+
retry_notice
|
|
36
|
+
rescue StandardError => e
|
|
37
|
+
log "Error while connecting to supervisor at #{@ip}:#{@port}: #{e}", level: :error
|
|
38
|
+
retry_notice
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def retry_notice
|
|
35
42
|
unless @site.site_settings['intervals']['reconnect'] == :no
|
|
36
43
|
log "Will try to reconnect again every #{@site.site_settings['intervals']['reconnect']} seconds..", level: :info
|
|
37
44
|
@logger.mute @ip, @port
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
module RSMP
|
|
2
|
+
module TLC
|
|
3
|
+
class DetectorLogic < Component
|
|
4
|
+
attr_reader :forced, :value
|
|
5
|
+
|
|
6
|
+
def initialize node:, id:
|
|
7
|
+
super node: node, id: id, grouped: false
|
|
8
|
+
@forced = 0
|
|
9
|
+
@value = 0
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get_status code, name=nil
|
|
13
|
+
case code
|
|
14
|
+
when 'S0201', 'S0202', 'S0203', 'S0204'
|
|
15
|
+
return send("handle_#{code.downcase}", code, name)
|
|
16
|
+
else
|
|
17
|
+
raise InvalidMessage.new "unknown status code #{code}"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def handle_s0201 status_code, status_name=nil
|
|
22
|
+
case status_name
|
|
23
|
+
when 'starttime'
|
|
24
|
+
TrafficControllerSite.make_status @node.clock.to_s
|
|
25
|
+
when 'vehicles'
|
|
26
|
+
TrafficControllerSite.make_status 0
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def handle_s0202 status_code, status_name=nil
|
|
31
|
+
case status_name
|
|
32
|
+
when 'starttime'
|
|
33
|
+
TrafficControllerSite.make_status @node.clock.to_s
|
|
34
|
+
when 'speed'
|
|
35
|
+
TrafficControllerSite.make_status 0
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def handle_s0203 status_code, status_name=nil
|
|
40
|
+
case status_name
|
|
41
|
+
when 'starttime'
|
|
42
|
+
TrafficControllerSite.make_status @node.clock.to_s
|
|
43
|
+
when 'occupancy'
|
|
44
|
+
TrafficControllerSite.make_status 0
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def handle_s0204 status_code, status_name=nil
|
|
49
|
+
case status_name
|
|
50
|
+
when 'starttime'
|
|
51
|
+
TrafficControllerSite.make_status @node.clock.to_s
|
|
52
|
+
when 'P'
|
|
53
|
+
TrafficControllerSite.make_status 0
|
|
54
|
+
when 'PS'
|
|
55
|
+
TrafficControllerSite.make_status 0
|
|
56
|
+
when 'L'
|
|
57
|
+
TrafficControllerSite.make_status 0
|
|
58
|
+
when 'LS'
|
|
59
|
+
TrafficControllerSite.make_status 0
|
|
60
|
+
when 'B'
|
|
61
|
+
TrafficControllerSite.make_status 0
|
|
62
|
+
when 'SP'
|
|
63
|
+
TrafficControllerSite.make_status 0
|
|
64
|
+
when 'MC'
|
|
65
|
+
TrafficControllerSite.make_status 0
|
|
66
|
+
when 'C'
|
|
67
|
+
TrafficControllerSite.make_status 0
|
|
68
|
+
when 'F'
|
|
69
|
+
TrafficControllerSite.make_status 0
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def handle_command command_code, arg
|
|
74
|
+
case command_code
|
|
75
|
+
when 'M0008'
|
|
76
|
+
handle_m0008 arg
|
|
77
|
+
else
|
|
78
|
+
raise UnknownCommand.new "Unknown command #{command_code}"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def handle_m0008 arg
|
|
83
|
+
@node.verify_security_code 2, arg['securityCode']
|
|
84
|
+
status = arg['status']=='True'
|
|
85
|
+
mode = arg['mode']=='True'
|
|
86
|
+
force_detector_logic status, mode
|
|
87
|
+
arg
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def force_detector_logic forced, value
|
|
91
|
+
@forced = forced
|
|
92
|
+
@value = value
|
|
93
|
+
if @forced
|
|
94
|
+
log "Forcing to #{value}", level: :info
|
|
95
|
+
else
|
|
96
|
+
log "Releasing", level: :info
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module RSMP
|
|
2
|
+
module TLC
|
|
3
|
+
class SignalGroup < Component
|
|
4
|
+
attr_reader :plan, :state
|
|
5
|
+
|
|
6
|
+
# plan is a string, with each character representing a signal phase at a particular second in the cycle
|
|
7
|
+
def initialize node:, id:
|
|
8
|
+
super node: node, id: id, grouped: false
|
|
9
|
+
move 0
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get_state pos
|
|
13
|
+
default = 'a' # phase a means disabled/dark
|
|
14
|
+
plan = node.main.current_plan
|
|
15
|
+
return default unless plan
|
|
16
|
+
return default unless plan.states
|
|
17
|
+
states = plan.states[c_id]
|
|
18
|
+
return default unless states
|
|
19
|
+
state =states[pos]
|
|
20
|
+
return default unless state =~ /[a-hA-G0-9N-P]/ # valid signal group states
|
|
21
|
+
state
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def move pos
|
|
25
|
+
@state = get_state pos
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def handle_command command_code, arg
|
|
29
|
+
case command_code
|
|
30
|
+
when 'M0010', 'M0011'
|
|
31
|
+
return send("handle_#{command_code.downcase}", arg)
|
|
32
|
+
else
|
|
33
|
+
raise UnknownCommand.new "Unknown command #{command_code}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Start of signal group. Orders a signal group to green
|
|
38
|
+
def handle_m0010 arg
|
|
39
|
+
@node.verify_security_code 2, arg['securityCode']
|
|
40
|
+
if TrafficControllerSite.from_rsmp_bool arg['status']
|
|
41
|
+
log "Start signal group #{c_id}, go to green", level: :info
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Stop of signal group. Orders a signal group to red
|
|
46
|
+
def handle_m0011 arg
|
|
47
|
+
@node.verify_security_code 2, arg['securityCode']
|
|
48
|
+
if TrafficControllerSite.from_rsmp_bool arg['status']
|
|
49
|
+
log "Stop signal group #{c_id}, go to red", level: :info
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def get_status code, name=nil
|
|
54
|
+
case code
|
|
55
|
+
when 'S0025'
|
|
56
|
+
return send("handle_#{code.downcase}", code, name)
|
|
57
|
+
else
|
|
58
|
+
raise InvalidMessage.new "unknown status code #{code}"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def handle_s0025 status_code, status_name=nil
|
|
63
|
+
now = @node.clock.to_s
|
|
64
|
+
case status_name
|
|
65
|
+
when 'minToGEstimate'
|
|
66
|
+
TrafficControllerSite.make_status now
|
|
67
|
+
when 'maxToGEstimate'
|
|
68
|
+
TrafficControllerSite.make_status now
|
|
69
|
+
when 'likelyToGEstimate'
|
|
70
|
+
TrafficControllerSite.make_status now
|
|
71
|
+
when 'ToGConfidence'
|
|
72
|
+
TrafficControllerSite.make_status 0
|
|
73
|
+
when 'minToREstimate'
|
|
74
|
+
TrafficControllerSite.make_status now
|
|
75
|
+
when 'maxToREstimate'
|
|
76
|
+
TrafficControllerSite.make_status now
|
|
77
|
+
when 'likelyToREstimate'
|
|
78
|
+
TrafficControllerSite.make_status now
|
|
79
|
+
when 'ToRConfidence'
|
|
80
|
+
TrafficControllerSite.make_status 0
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module RSMP
|
|
2
|
+
module TLC
|
|
3
|
+
# A Traffic Light Controller Signal Plan.
|
|
4
|
+
# A signal plan is a description of how all signal groups should change
|
|
5
|
+
# state over time.
|
|
6
|
+
class SignalPlan
|
|
7
|
+
attr_reader :nr, :states, :dynamic_bands
|
|
8
|
+
def initialize nr:, states:, dynamic_bands:
|
|
9
|
+
@nr = nr
|
|
10
|
+
@states = states
|
|
11
|
+
@dynamic_bands = dynamic_bands || {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def dynamic_bands_string
|
|
15
|
+
str = @dynamic_bands.map { |band,value| "#{nr}-#{band}-#{value}" }.join(',')
|
|
16
|
+
return nil if str == ''
|
|
17
|
+
str
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def set_band band, value
|
|
21
|
+
@dynamic_bands[ band.to_i ] = value.to_i
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def get_band band
|
|
25
|
+
@dynamic_bands[ band.to_i ]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|