rsmp 0.37.0 → 0.38.0
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/.devcontainer/devcontainer.json +22 -0
- data/.github/workflows/rubocop.yaml +17 -0
- data/.gitignore +5 -6
- data/.rubocop.yml +80 -0
- data/Gemfile +13 -1
- data/Gemfile.lock +34 -1
- data/Rakefile +3 -3
- data/lib/rsmp/cli.rb +147 -124
- data/lib/rsmp/collect/ack_collector.rb +8 -7
- data/lib/rsmp/collect/aggregated_status_collector.rb +4 -4
- data/lib/rsmp/collect/alarm_collector.rb +31 -23
- data/lib/rsmp/collect/alarm_matcher.rb +3 -3
- data/lib/rsmp/collect/collector/logging.rb +17 -0
- data/lib/rsmp/collect/collector/reporting.rb +44 -0
- data/lib/rsmp/collect/collector/status.rb +34 -0
- data/lib/rsmp/collect/collector.rb +69 -150
- data/lib/rsmp/collect/command_matcher.rb +19 -6
- data/lib/rsmp/collect/command_response_collector.rb +7 -7
- data/lib/rsmp/collect/distributor.rb +14 -11
- data/lib/rsmp/collect/filter.rb +31 -15
- data/lib/rsmp/collect/matcher.rb +7 -11
- data/lib/rsmp/collect/queue.rb +4 -4
- data/lib/rsmp/collect/receiver.rb +10 -12
- data/lib/rsmp/collect/state_collector.rb +116 -77
- data/lib/rsmp/collect/status_collector.rb +6 -6
- data/lib/rsmp/collect/status_matcher.rb +17 -7
- data/lib/rsmp/{alarm_state.rb → component/alarm_state.rb} +76 -37
- data/lib/rsmp/{component.rb → component/component.rb} +15 -15
- data/lib/rsmp/component/component_base.rb +89 -0
- data/lib/rsmp/component/component_proxy.rb +75 -0
- data/lib/rsmp/component/components.rb +63 -0
- data/lib/rsmp/convert/export/json_schema.rb +116 -110
- data/lib/rsmp/convert/import/yaml.rb +21 -18
- data/lib/rsmp/{rsmp.rb → helpers/clock.rb} +5 -6
- data/lib/rsmp/{deep_merge.rb → helpers/deep_merge.rb} +2 -1
- data/lib/rsmp/helpers/error.rb +71 -0
- data/lib/rsmp/{inspect.rb → helpers/inspect.rb} +6 -10
- data/lib/rsmp/log/archive.rb +98 -0
- data/lib/rsmp/log/colorization.rb +41 -0
- data/lib/rsmp/log/filtering.rb +54 -0
- data/lib/rsmp/log/logger.rb +206 -0
- data/lib/rsmp/{logging.rb → log/logging.rb} +5 -7
- data/lib/rsmp/message.rb +159 -148
- data/lib/rsmp/{node.rb → node/node.rb} +19 -17
- data/lib/rsmp/{protocol.rb → node/protocol.rb} +5 -3
- data/lib/rsmp/node/site/site.rb +195 -0
- data/lib/rsmp/node/supervisor/modules/configuration.rb +59 -0
- data/lib/rsmp/node/supervisor/modules/connection.rb +140 -0
- data/lib/rsmp/node/supervisor/modules/sites.rb +64 -0
- data/lib/rsmp/node/supervisor/supervisor.rb +72 -0
- data/lib/rsmp/{task.rb → node/task.rb} +12 -14
- data/lib/rsmp/proxy/modules/acknowledgements.rb +144 -0
- data/lib/rsmp/proxy/modules/receive.rb +119 -0
- data/lib/rsmp/proxy/modules/send.rb +76 -0
- data/lib/rsmp/proxy/modules/state.rb +25 -0
- data/lib/rsmp/proxy/modules/tasks.rb +105 -0
- data/lib/rsmp/proxy/modules/versions.rb +69 -0
- data/lib/rsmp/proxy/modules/watchdogs.rb +66 -0
- data/lib/rsmp/proxy/proxy.rb +199 -0
- data/lib/rsmp/proxy/site/modules/aggregated_status.rb +52 -0
- data/lib/rsmp/proxy/site/modules/alarms.rb +27 -0
- data/lib/rsmp/proxy/site/modules/commands.rb +31 -0
- data/lib/rsmp/proxy/site/modules/status.rb +110 -0
- data/lib/rsmp/proxy/site/site_proxy.rb +205 -0
- data/lib/rsmp/proxy/supervisor/modules/aggregated_status.rb +47 -0
- data/lib/rsmp/proxy/supervisor/modules/alarms.rb +73 -0
- data/lib/rsmp/proxy/supervisor/modules/commands.rb +53 -0
- data/lib/rsmp/proxy/supervisor/modules/status.rb +204 -0
- data/lib/rsmp/proxy/supervisor/supervisor_proxy.rb +178 -0
- data/lib/rsmp/tlc/detector_logic.rb +18 -34
- data/lib/rsmp/tlc/input_states.rb +126 -0
- data/lib/rsmp/tlc/modules/detector_logics.rb +50 -0
- data/lib/rsmp/tlc/modules/display.rb +78 -0
- data/lib/rsmp/tlc/modules/helpers.rb +41 -0
- data/lib/rsmp/tlc/modules/inputs.rb +173 -0
- data/lib/rsmp/tlc/modules/modes.rb +253 -0
- data/lib/rsmp/tlc/modules/outputs.rb +30 -0
- data/lib/rsmp/tlc/modules/plans.rb +218 -0
- data/lib/rsmp/tlc/modules/signal_groups.rb +109 -0
- data/lib/rsmp/tlc/modules/startup_sequence.rb +22 -0
- data/lib/rsmp/tlc/modules/system.rb +140 -0
- data/lib/rsmp/tlc/modules/traffic_data.rb +49 -0
- data/lib/rsmp/tlc/signal_group.rb +37 -41
- data/lib/rsmp/tlc/signal_plan.rb +14 -11
- data/lib/rsmp/tlc/signal_priority.rb +39 -35
- data/lib/rsmp/tlc/startup_sequence.rb +59 -0
- data/lib/rsmp/tlc/traffic_controller.rb +38 -1010
- data/lib/rsmp/tlc/traffic_controller_site.rb +58 -57
- data/lib/rsmp/version.rb +1 -1
- data/lib/rsmp.rb +82 -48
- data/rsmp.gemspec +24 -31
- metadata +79 -139
- data/lib/rsmp/archive.rb +0 -76
- data/lib/rsmp/collect/message_matchers.rb +0 -0
- data/lib/rsmp/component_base.rb +0 -87
- data/lib/rsmp/component_proxy.rb +0 -57
- data/lib/rsmp/components.rb +0 -65
- data/lib/rsmp/error.rb +0 -71
- data/lib/rsmp/logger.rb +0 -216
- data/lib/rsmp/proxy.rb +0 -693
- data/lib/rsmp/site.rb +0 -188
- data/lib/rsmp/site_proxy.rb +0 -389
- data/lib/rsmp/supervisor.rb +0 -302
- data/lib/rsmp/supervisor_proxy.rb +0 -510
- data/lib/rsmp/tlc/inputs.rb +0 -134
|
@@ -5,51 +5,33 @@ module RSMP
|
|
|
5
5
|
# and keeps track of signal plans, detector logics, inputs, etc. which do
|
|
6
6
|
# not have dedicated components.
|
|
7
7
|
class TrafficController < Component
|
|
8
|
+
include TLC::Modules::System
|
|
9
|
+
include TLC::Modules::Modes
|
|
10
|
+
include TLC::Modules::Plans
|
|
11
|
+
include TLC::Modules::SignalGroups
|
|
12
|
+
include TLC::Modules::Inputs
|
|
13
|
+
include TLC::Modules::Outputs
|
|
14
|
+
include TLC::Modules::DetectorLogics
|
|
15
|
+
include TLC::Modules::TrafficData
|
|
16
|
+
include TLC::Modules::StartupSequence
|
|
17
|
+
include TLC::Modules::Display
|
|
18
|
+
include TLC::Modules::Helpers
|
|
19
|
+
|
|
8
20
|
attr_reader :pos, :cycle_time, :plan, :cycle_counter,
|
|
9
|
-
|
|
10
|
-
:startup_sequence_active, :startup_sequence, :startup_sequence_pos
|
|
21
|
+
:functional_position, :startup_sequence
|
|
11
22
|
|
|
12
|
-
def initialize
|
|
13
|
-
|
|
14
|
-
super node: node, id: id, ntsOId: ntsOId, xNId: xNId, grouped: true
|
|
23
|
+
def initialize(node:, id:, ntsoid: nil, xnid: nil, **options)
|
|
24
|
+
super(node: node, id: id, ntsoid: ntsoid, xnid: xnid, grouped: true)
|
|
15
25
|
@signal_groups = []
|
|
16
26
|
@detector_logics = []
|
|
17
|
-
@plans = signal_plans
|
|
27
|
+
@plans = options[:signal_plans]
|
|
18
28
|
@num_traffic_situations = 1
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@input_programming = inputs['programming']
|
|
23
|
-
else
|
|
24
|
-
@input_programming = nil
|
|
25
|
-
end
|
|
26
|
-
@inputs = TLC::Inputs.new num_inputs || 8
|
|
27
|
-
|
|
28
|
-
@startup_sequence = startup_sequence
|
|
29
|
-
@live_output = live_output
|
|
29
|
+
setup_inputs(options[:inputs])
|
|
30
|
+
@startup_sequence = StartupSequence.new(options[:startup_sequence])
|
|
31
|
+
@live_output = options[:live_output]
|
|
30
32
|
reset
|
|
31
33
|
end
|
|
32
34
|
|
|
33
|
-
def reset_modes
|
|
34
|
-
@function_position = 'NormalControl'
|
|
35
|
-
@function_position_source = 'startup'
|
|
36
|
-
@previous_functional_position = nil
|
|
37
|
-
@functional_position_timeout = nil
|
|
38
|
-
|
|
39
|
-
@booting = false
|
|
40
|
-
@is_starting = false
|
|
41
|
-
@control_mode = 'control'
|
|
42
|
-
@manual_control = false
|
|
43
|
-
@manual_control_source = 'startup'
|
|
44
|
-
@fixed_time_control = false
|
|
45
|
-
@fixed_time_control_source = 'startup'
|
|
46
|
-
@isolated_control = false
|
|
47
|
-
@isolated_control_source = 'startup'
|
|
48
|
-
@all_red = false
|
|
49
|
-
@all_red_source = 'startup'
|
|
50
|
-
@police_key = 0
|
|
51
|
-
end
|
|
52
|
-
|
|
53
35
|
def reset
|
|
54
36
|
reset_modes
|
|
55
37
|
@cycle_counter = 0
|
|
@@ -62,577 +44,57 @@ module RSMP
|
|
|
62
44
|
@traffic_situation = 0
|
|
63
45
|
@traffic_situation_source = 'startup'
|
|
64
46
|
@day_time_table = {}
|
|
65
|
-
@startup_sequence_active = false
|
|
66
|
-
@startup_sequence_initiated_at = nil
|
|
67
|
-
@startup_sequence_pos = 0
|
|
68
47
|
@time_int = nil
|
|
69
48
|
@inputs.reset
|
|
70
49
|
@signal_priorities = []
|
|
71
50
|
@dynamic_bands_timeout = 0
|
|
72
51
|
end
|
|
73
52
|
|
|
74
|
-
def
|
|
75
|
-
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def yellow_flash?
|
|
79
|
-
@function_position == 'YellowFlash'
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def normal_control?
|
|
83
|
-
@function_position == 'NormalControl'
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def clock
|
|
87
|
-
node.clock
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def current_plan
|
|
91
|
-
# TODO plan 0 should means use time table
|
|
92
|
-
if @plans
|
|
93
|
-
@plans[ plan ] || @plans.values.first
|
|
94
|
-
else
|
|
95
|
-
nil
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def add_signal_group group
|
|
100
|
-
@signal_groups << group
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def add_detector_logic logic
|
|
104
|
-
@detector_logics << logic
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def timer now
|
|
108
|
-
# TODO use monotone timer, to avoid jumps in case the user sets the system time
|
|
53
|
+
def timer(_now)
|
|
54
|
+
# TODO: use monotone timer, to avoid jumps in case the user sets the system time
|
|
109
55
|
return unless move_cycle_counter
|
|
56
|
+
|
|
110
57
|
check_functional_position_timeout
|
|
111
|
-
|
|
58
|
+
@startup_sequence.advance if @startup_sequence.active?
|
|
112
59
|
|
|
113
|
-
@signal_groups.each
|
|
114
|
-
@signal_priorities.each
|
|
60
|
+
@signal_groups.each(&:timer)
|
|
61
|
+
@signal_priorities.each(&:timer)
|
|
115
62
|
|
|
116
63
|
output_states
|
|
117
64
|
end
|
|
118
65
|
|
|
119
|
-
def signal_priority_changed priority, state
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
# remove all stale priority requests
|
|
123
|
-
def prune_priorities
|
|
124
|
-
@signal_priorities.delete_if {|priority| priority.prune? }
|
|
125
|
-
end
|
|
126
|
-
|
|
127
66
|
# this method is called by the supervisor proxy each time status updates have been send
|
|
128
|
-
# we can then prune our priority request list
|
|
67
|
+
# we can then prune our priority request list
|
|
129
68
|
def status_updates_sent
|
|
130
69
|
prune_priorities
|
|
131
70
|
end
|
|
132
71
|
|
|
133
|
-
def get_priority_list
|
|
134
|
-
@signal_priorities.map do |priority|
|
|
135
|
-
{
|
|
136
|
-
"r" => priority.id,
|
|
137
|
-
"t" => RSMP::Clock.to_s(priority.updated),
|
|
138
|
-
"s" => priority.state
|
|
139
|
-
}
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
72
|
def move_cycle_counter
|
|
144
73
|
plan = current_plan
|
|
145
|
-
if plan
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
74
|
+
counter = if plan
|
|
75
|
+
Time.now.to_i % plan.cycle_time
|
|
76
|
+
else
|
|
77
|
+
0
|
|
78
|
+
end
|
|
150
79
|
changed = counter != @cycle_counter
|
|
151
80
|
@cycle_counter = counter
|
|
152
81
|
changed
|
|
153
82
|
end
|
|
154
83
|
|
|
155
|
-
def
|
|
156
|
-
return unless @functional_position_timeout
|
|
157
|
-
if clock.now >= @functional_position_timeout
|
|
158
|
-
switch_functional_position @previous_functional_position, reverting: true, source: 'calendar_clock'
|
|
159
|
-
@functional_position_timeout = nil
|
|
160
|
-
@previous_functional_position = nil
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def startup_state
|
|
165
|
-
return unless @startup_sequence_active
|
|
166
|
-
return unless @startup_sequence_pos
|
|
167
|
-
@startup_sequence[ @startup_sequence_pos ]
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def initiate_startup_sequence
|
|
171
|
-
log "Initiating startup sequence", level: :info
|
|
172
|
-
reset_modes
|
|
173
|
-
@startup_sequence_active = true
|
|
174
|
-
@startup_sequence_initiated_at = nil
|
|
175
|
-
@startup_sequence_pos = nil
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
def end_startup_sequence
|
|
179
|
-
@startup_sequence_active = false
|
|
180
|
-
@startup_sequence_initiated_at = nil
|
|
181
|
-
@startup_sequence_pos = nil
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
def move_startup_sequence
|
|
185
|
-
was = @startup_sequence_pos
|
|
186
|
-
if @startup_sequence_initiated_at == nil
|
|
187
|
-
@startup_sequence_initiated_at = Time.now.to_i + 1
|
|
188
|
-
@startup_sequence_pos = 0
|
|
189
|
-
else
|
|
190
|
-
@startup_sequence_pos = Time.now.to_i - @startup_sequence_initiated_at
|
|
191
|
-
end
|
|
192
|
-
if @startup_sequence_pos >= @startup_sequence.size
|
|
193
|
-
end_startup_sequence
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
def output_states
|
|
198
|
-
return unless @live_output
|
|
199
|
-
|
|
200
|
-
str = @signal_groups.map do |group|
|
|
201
|
-
state = group.state
|
|
202
|
-
s = "#{group.c_id}:#{state}"
|
|
203
|
-
if state =~ /^[1-9]$/
|
|
204
|
-
s.colorize(:green)
|
|
205
|
-
elsif state =~ /^[NOP]$/
|
|
206
|
-
s.colorize(:yellow)
|
|
207
|
-
elsif state =~ /^[ae]$/
|
|
208
|
-
s.colorize(:light_black)
|
|
209
|
-
elsif state =~ /^[f]$/
|
|
210
|
-
s.colorize(:yellow)
|
|
211
|
-
elsif state =~ /^[g]$/
|
|
212
|
-
s.colorize(:red)
|
|
213
|
-
else
|
|
214
|
-
s.colorize(:red)
|
|
215
|
-
end
|
|
216
|
-
end.join ' '
|
|
217
|
-
|
|
218
|
-
modes = '.'*9
|
|
219
|
-
modes[0] = 'N' if @function_position == 'NormalControl'
|
|
220
|
-
modes[1] = 'Y' if @function_position == 'YellowFlash'
|
|
221
|
-
modes[2] = 'D' if @function_position == 'Dark'
|
|
222
|
-
modes[3] = 'B' if @booting
|
|
223
|
-
modes[4] = 'S' if @startup_sequence_active
|
|
224
|
-
modes[5] = 'M' if @manual_control
|
|
225
|
-
modes[6] = 'F' if @fixed_time_control
|
|
226
|
-
modes[7] = 'R' if @all_red
|
|
227
|
-
modes[8] = 'I' if @isolated_control
|
|
228
|
-
modes[9] = 'P' if @police_key != 0
|
|
229
|
-
|
|
230
|
-
plan = "P#{@plan}"
|
|
231
|
-
|
|
232
|
-
# create folders if needed
|
|
233
|
-
FileUtils.mkdir_p File.dirname(@live_output)
|
|
234
|
-
|
|
235
|
-
# append a line with the current state to the file
|
|
236
|
-
File.open @live_output, 'w' do |file|
|
|
237
|
-
file.puts "#{modes} #{plan.rjust(2)} #{@cycle_counter.to_s.rjust(3)} #{str}\r"
|
|
238
|
-
end
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
def format_signal_group_status
|
|
242
|
-
@signal_groups.map { |group| group.state }.join
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
def handle_command command_code, arg, options={}
|
|
84
|
+
def handle_command(command_code, arg, options = {})
|
|
246
85
|
case command_code
|
|
247
86
|
when 'M0001', 'M0002', 'M0003', 'M0004', 'M0005', 'M0006', 'M0007',
|
|
248
87
|
'M0012', 'M0013', 'M0014', 'M0015', 'M0016', 'M0017', 'M0018',
|
|
249
88
|
'M0019', 'M0020', 'M0021', 'M0022', 'M0023',
|
|
250
89
|
'M0103', 'M0104'
|
|
251
90
|
|
|
252
|
-
|
|
253
|
-
else
|
|
254
|
-
raise UnknownCommand.new "Unknown command #{command_code}"
|
|
255
|
-
end
|
|
256
|
-
end
|
|
257
|
-
|
|
258
|
-
def handle_m0001 arg, options={}
|
|
259
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
260
|
-
|
|
261
|
-
# timeout is specified in minutes, but we take 1 to mean 1s
|
|
262
|
-
# this is not according to the curent rsmp spec, but is done
|
|
263
|
-
# to speed up testing
|
|
264
|
-
timeout = arg['timeout'].to_i
|
|
265
|
-
if timeout == 1
|
|
266
|
-
timeout = 1
|
|
267
|
-
else
|
|
268
|
-
timeout *= 60
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
switch_functional_position arg['status'],
|
|
272
|
-
timeout: timeout,
|
|
273
|
-
source: 'forced'
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
def handle_m0002 arg, options={}
|
|
277
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
278
|
-
if TrafficControllerSite.from_rsmp_bool(arg['status'])
|
|
279
|
-
switch_plan arg['timeplan'], source: 'forced'
|
|
280
|
-
else
|
|
281
|
-
switch_plan 0, source: 'startup' # TODO use clock/calender
|
|
282
|
-
end
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
def handle_m0003 arg, options={}
|
|
286
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
287
|
-
switch_traffic_situation arg['traficsituation'], source: 'forced'
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
def switch_traffic_situation situation, source:
|
|
291
|
-
@traffic_situation = situation.to_i
|
|
292
|
-
@traffic_situation_source = 'forced'
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
def handle_m0004 arg, options={}
|
|
296
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
297
|
-
# don't restart immeediately, since we need to first send command response
|
|
298
|
-
# instead, defer an action, which will be handled by the TLC site
|
|
299
|
-
log "Sheduling restart of TLC", level: :info
|
|
300
|
-
@node.defer :restart
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
def handle_m0005 arg, options={}
|
|
304
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
305
|
-
route = arg['emergencyroute'].to_i
|
|
306
|
-
enable = (arg['status'] == 'True')
|
|
307
|
-
@last_emergency_route = route
|
|
308
|
-
|
|
309
|
-
if enable
|
|
310
|
-
if @emergency_routes.add? route
|
|
311
|
-
log "Enabling emergency route #{route}", level: :info
|
|
312
|
-
else
|
|
313
|
-
log "Emergency route #{route} already enabled", level: :info
|
|
314
|
-
end
|
|
315
|
-
else
|
|
316
|
-
if @emergency_routes.delete? route
|
|
317
|
-
log "Disabling emergency route #{route}", level: :info
|
|
318
|
-
else
|
|
319
|
-
log "Emergency route #{route} already disabled", level: :info
|
|
320
|
-
end
|
|
321
|
-
end
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
def input_logic input, change
|
|
325
|
-
return unless @input_programming && change != nil
|
|
326
|
-
action = @input_programming[input]
|
|
327
|
-
return unless action
|
|
328
|
-
if action['raise_alarm']
|
|
329
|
-
if action['component']
|
|
330
|
-
component = node.find_component action['component']
|
|
331
|
-
else
|
|
332
|
-
component = node.main
|
|
333
|
-
end
|
|
334
|
-
alarm_code = action['raise_alarm']
|
|
335
|
-
if change
|
|
336
|
-
log "Activating input #{input} is programmed to raise alarm #{alarm_code} on #{component.c_id}", level: :info
|
|
337
|
-
component.activate_alarm alarm_code
|
|
338
|
-
else
|
|
339
|
-
log "Deactivating input #{input} is programmed to clear alarm #{alarm_code} on #{component.c_id}", level: :info
|
|
340
|
-
component.deactivate_alarm alarm_code
|
|
341
|
-
end
|
|
342
|
-
end
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
def handle_m0006 arg, options={}
|
|
346
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
347
|
-
input = arg['input'].to_i
|
|
348
|
-
status = string_to_bool arg['status']
|
|
349
|
-
unless input>=1 && input<=@inputs.size
|
|
350
|
-
raise MessageRejected.new("Input must be in the range 1-#{@inputs.size}")
|
|
351
|
-
end
|
|
352
|
-
if status
|
|
353
|
-
log "Activating input #{input}", level: :info
|
|
354
|
-
else
|
|
355
|
-
log "Deactivating input #{input}", level: :info
|
|
356
|
-
end
|
|
357
|
-
change = @inputs.set input, status
|
|
358
|
-
input_logic input, change if change != nil
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
def handle_m0007 arg, options={}
|
|
362
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
363
|
-
set_fixed_time_control arg['status'], source: 'forced'
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
def handle_m0012 arg, options={}
|
|
367
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
368
|
-
end
|
|
369
|
-
|
|
370
|
-
def handle_m0013 arg, options={}
|
|
371
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
372
|
-
set, clear = [], []
|
|
373
|
-
arg['status'].split(';').map do |part|
|
|
374
|
-
offset, set_bits, clear_bits = part.split(',').map { |i| i.to_i }
|
|
375
|
-
set_bits.to_s(2).reverse.each_char.with_index do |bit,i|
|
|
376
|
-
set << i + offset if bit == '1'
|
|
377
|
-
end
|
|
378
|
-
clear_bits.to_s(2).reverse.each_char.with_index do |bit,i|
|
|
379
|
-
clear << i + offset if bit == '1'
|
|
380
|
-
end
|
|
381
|
-
end
|
|
382
|
-
|
|
383
|
-
set = set.uniq.sort
|
|
384
|
-
clear = clear.uniq.sort
|
|
385
|
-
|
|
386
|
-
# if input is both activated and deacticvated, there is no need to acticate first
|
|
387
|
-
set -= (set & clear)
|
|
388
|
-
|
|
389
|
-
[set,clear].each do |inputs|
|
|
390
|
-
inputs.each do |input|
|
|
391
|
-
if input<1
|
|
392
|
-
raise MessageRejected.new("Cannot acticate inputs #{set} and deactive inputs #{clear}: input #{input} is invalid (must be 1 or higher)"
|
|
393
|
-
) if input<1
|
|
394
|
-
end
|
|
395
|
-
if input>@inputs.size
|
|
396
|
-
raise MessageRejected.new("Cannot acticate inputs #{set} and deactive inputs #{clear}: input #{input} is invalid (only #{@inputs.size} inputs present)")
|
|
397
|
-
end
|
|
398
|
-
end
|
|
399
|
-
end
|
|
400
|
-
|
|
401
|
-
log "Activating inputs #{set} and deactivating inputs #{clear}", level: :info
|
|
402
|
-
|
|
403
|
-
set.each do |input|
|
|
404
|
-
change = @inputs.set input, true
|
|
405
|
-
input_logic input, change if change != nil
|
|
406
|
-
end
|
|
407
|
-
clear.each do |input|
|
|
408
|
-
change = @inputs.set input, false
|
|
409
|
-
input_logic input, change if change != nil
|
|
410
|
-
end
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
def find_plan plan_nr
|
|
414
|
-
plan = @plans[plan_nr.to_i]
|
|
415
|
-
raise InvalidMessage.new "unknown signal plan #{plan_nr}, known only [#{@plans.keys.join(', ')}]" unless plan
|
|
416
|
-
plan
|
|
417
|
-
end
|
|
418
|
-
|
|
419
|
-
def handle_m0014 arg, options={}
|
|
420
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
421
|
-
plan = find_plan arg['plan']
|
|
422
|
-
arg['status'].split(',').each do |item|
|
|
423
|
-
matched = /(\d+)-(\d+)/.match item
|
|
424
|
-
band = matched[1].to_i
|
|
425
|
-
value = matched[2].to_i
|
|
426
|
-
log "Set plan #{arg['plan']} dynamic band #{band} to #{value}", level: :info
|
|
427
|
-
plan.set_band band, value
|
|
428
|
-
end
|
|
429
|
-
end
|
|
430
|
-
|
|
431
|
-
def handle_m0015 arg, options={}
|
|
432
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
433
|
-
end
|
|
434
|
-
|
|
435
|
-
def handle_m0016 arg, options={}
|
|
436
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
437
|
-
end
|
|
438
|
-
|
|
439
|
-
def handle_m0017 arg, options={}
|
|
440
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
441
|
-
arg['status'].split(',').each do |item|
|
|
442
|
-
elems = item.split('-')
|
|
443
|
-
nr = elems[0].to_i
|
|
444
|
-
plan = elems[1].to_i
|
|
445
|
-
hour = elems[2].to_i
|
|
446
|
-
min = elems[3].to_i
|
|
447
|
-
if nr<0 || nr>12
|
|
448
|
-
raise InvalidMessage.new "time table id must be between 0 and 12, got #{nr}"
|
|
449
|
-
end
|
|
450
|
-
#p "nr: #{nr}, plan #{plan} at #{hour}:#{min}"
|
|
451
|
-
@day_time_table[nr] = {plan: plan, hour: hour, min:min}
|
|
452
|
-
end
|
|
453
|
-
end
|
|
454
|
-
|
|
455
|
-
def handle_m0018 arg, options={}
|
|
456
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
457
|
-
nr = arg['plan'].to_i
|
|
458
|
-
cycle_time = arg['status'].to_i
|
|
459
|
-
plan = @plans[nr]
|
|
460
|
-
raise RSMP::MessageRejected.new "Plan '#{nr}' not found" unless plan
|
|
461
|
-
raise RSMP::MessageRejected.new "Cycle time must be greater or equal to zero" if cycle_time < 0
|
|
462
|
-
log "Set plan #{nr} cycle time to #{cycle_time}", level: :info
|
|
463
|
-
plan.set_cycle_time cycle_time
|
|
464
|
-
end
|
|
465
|
-
|
|
466
|
-
def string_to_bool bool_str
|
|
467
|
-
case bool_str
|
|
468
|
-
when 'True'
|
|
469
|
-
true
|
|
470
|
-
when 'False'
|
|
471
|
-
false
|
|
472
|
-
else
|
|
473
|
-
raise RSMP::MessageRejected.new "Invalid boolean '#{bool}', must be 'True' or 'False'"
|
|
474
|
-
end
|
|
475
|
-
end
|
|
476
|
-
|
|
477
|
-
def bool_string_to_digit bool
|
|
478
|
-
case bool
|
|
479
|
-
when 'True'
|
|
480
|
-
'1'
|
|
481
|
-
when 'False'
|
|
482
|
-
'0'
|
|
483
|
-
else
|
|
484
|
-
raise RSMP::MessageRejected.new "Invalid boolean '#{bool}', must be 'True' or 'False'"
|
|
485
|
-
end
|
|
486
|
-
end
|
|
487
|
-
|
|
488
|
-
def bool_to_digit bool
|
|
489
|
-
bool ? '1' : '0'
|
|
490
|
-
end
|
|
491
|
-
|
|
492
|
-
def handle_m0019 arg, options={}
|
|
493
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
494
|
-
input = arg['input'].to_i
|
|
495
|
-
force = string_to_bool arg['status']
|
|
496
|
-
forced_value = string_to_bool arg['inputValue']
|
|
497
|
-
unless input>=1 && input<=@inputs.size
|
|
498
|
-
raise MessageRejected.new("Input must be in the range 1-#{@inputs.size}")
|
|
499
|
-
end
|
|
500
|
-
if force
|
|
501
|
-
log "Forcing input #{input} to #{forced_value}", level: :info
|
|
502
|
-
else
|
|
503
|
-
log "Releasing input #{input}", level: :info
|
|
504
|
-
end
|
|
505
|
-
change = @inputs.set_forcing input, force, forced_value
|
|
506
|
-
|
|
507
|
-
input_logic input, change if change != nil
|
|
508
|
-
end
|
|
509
|
-
|
|
510
|
-
def handle_m0020 arg, options={}
|
|
511
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
512
|
-
end
|
|
513
|
-
|
|
514
|
-
def handle_m0021 arg, options={}
|
|
515
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
516
|
-
end
|
|
517
|
-
|
|
518
|
-
def handle_m0022 arg, options={}
|
|
519
|
-
id = arg['requestId']
|
|
520
|
-
type = arg['type']
|
|
521
|
-
priority = @signal_priorities.find { |priority| priority.id == id }
|
|
522
|
-
case type
|
|
523
|
-
when 'new'
|
|
524
|
-
if priority
|
|
525
|
-
raise MessageRejected.new("Priority Request #{id} already exists")
|
|
526
|
-
else
|
|
527
|
-
#ref = arg.slice('signalGroupId','inputId','connectionId','approachId','laneInId','laneOutId')
|
|
528
|
-
if arg['signalGroupId']
|
|
529
|
-
signal_group = node.find_component arg['signalGroupId']
|
|
530
|
-
end
|
|
531
|
-
|
|
532
|
-
level = arg['level']
|
|
533
|
-
eta = arg['eta']
|
|
534
|
-
vehicleType = arg['vehicleType']
|
|
535
|
-
@signal_priorities << SignalPriority.new(node:self, id:id, level:level, eta:eta, vehicleType:vehicleType)
|
|
536
|
-
log "Priority request #{id} for signal group #{signal_group.c_id} received.", level: :info
|
|
537
|
-
end
|
|
538
|
-
when 'update'
|
|
539
|
-
if priority
|
|
540
|
-
log "Updating Priority Request #{id}", level: :info
|
|
541
|
-
|
|
542
|
-
else
|
|
543
|
-
raise MessageRejected.new("Cannot update priority request #{id}, not found")
|
|
544
|
-
end
|
|
545
|
-
when 'cancel'
|
|
546
|
-
if priority
|
|
547
|
-
priority.cancel
|
|
548
|
-
log "Priority request with id #{id} cancelled.", level: :info
|
|
549
|
-
else
|
|
550
|
-
raise MessageRejected.new("Cannot cancel priority request #{id}, not found")
|
|
551
|
-
end
|
|
552
|
-
else
|
|
553
|
-
raise MessageRejected.new("Unknown type #{type}")
|
|
554
|
-
end
|
|
555
|
-
end
|
|
556
|
-
|
|
557
|
-
def handle_m0023 arg, options={}
|
|
558
|
-
@node.verify_security_code 2, arg['securityCode']
|
|
559
|
-
timeout = arg['status'].to_i
|
|
560
|
-
unless timeout>=0 and timeout <= 65535
|
|
561
|
-
raise RSMP::MessageRejected.new "Timeout must be in the range 0-65535, got #{timeout}"
|
|
562
|
-
end
|
|
563
|
-
if timeout == 0
|
|
564
|
-
log "Dynamic bands timeout disabled", level: :info
|
|
565
|
-
else
|
|
566
|
-
log "Dynamic bands timeout set to #{timeout}min", level: :info
|
|
567
|
-
end
|
|
568
|
-
@dynamic_bands_timeout = timeout
|
|
569
|
-
end
|
|
570
|
-
|
|
571
|
-
def handle_m0103 arg, options={}
|
|
572
|
-
level = {'Level1'=>1,'Level2'=>2}[arg['status']]
|
|
573
|
-
@node.change_security_code level, arg['oldSecurityCode'], arg['newSecurityCode']
|
|
574
|
-
end
|
|
575
|
-
|
|
576
|
-
def handle_m0104 arg, options={}
|
|
577
|
-
@node.verify_security_code 1, arg['securityCode']
|
|
578
|
-
time = Time.new(
|
|
579
|
-
arg['year'],
|
|
580
|
-
arg['month'],
|
|
581
|
-
arg['day'],
|
|
582
|
-
arg['hour'],
|
|
583
|
-
arg['minute'],
|
|
584
|
-
arg['second'],
|
|
585
|
-
'UTC'
|
|
586
|
-
)
|
|
587
|
-
clock.set time
|
|
588
|
-
log "Clock set to #{time}, (adjustment is #{clock.adjustment}s)", level: :info
|
|
589
|
-
end
|
|
590
|
-
|
|
591
|
-
def set_input i, value
|
|
592
|
-
return unless i>=0 && i<@num_inputs
|
|
593
|
-
@inputs[i] = bool_to_digit arg['value']
|
|
594
|
-
end
|
|
595
|
-
|
|
596
|
-
def set_fixed_time_control status, source:
|
|
597
|
-
@fixed_time_control = status
|
|
598
|
-
@fixed_time_control_source = source
|
|
599
|
-
end
|
|
600
|
-
|
|
601
|
-
def switch_plan plan, source:
|
|
602
|
-
plan_nr = plan.to_i
|
|
603
|
-
if plan_nr == 0
|
|
604
|
-
log "Switching to plan selection by time table", level: :info
|
|
91
|
+
send("handle_#{command_code.downcase}", arg, options)
|
|
605
92
|
else
|
|
606
|
-
|
|
607
|
-
log "Switching to plan #{plan_nr}", level: :info
|
|
93
|
+
raise UnknownCommand, "Unknown command #{command_code}"
|
|
608
94
|
end
|
|
609
|
-
@plan = plan_nr
|
|
610
|
-
@plan_source = source
|
|
611
95
|
end
|
|
612
96
|
|
|
613
|
-
def
|
|
614
|
-
unless ['NormalControl','YellowFlash','Dark'].include? mode
|
|
615
|
-
raise RSMP::MessageRejected.new "Invalid functional position #{mode.inspect}, must be NormalControl, YellowFlash or Dark"
|
|
616
|
-
end
|
|
617
|
-
if reverting
|
|
618
|
-
log "Reverting to functional position #{mode} after timeout", level: :info
|
|
619
|
-
elsif timeout && timeout > 0
|
|
620
|
-
log "Switching to functional position #{mode} with timeout #{(timeout/60).round(1)}min", level: :info
|
|
621
|
-
@previous_functional_position = @function_position
|
|
622
|
-
now = clock.now
|
|
623
|
-
@functional_position_timeout = now + timeout
|
|
624
|
-
else
|
|
625
|
-
log "Switching to functional position #{mode}", level: :info
|
|
626
|
-
end
|
|
627
|
-
if mode == 'NormalControl'
|
|
628
|
-
initiate_startup_sequence if @function_position != 'NormalControl'
|
|
629
|
-
end
|
|
630
|
-
@function_position = mode
|
|
631
|
-
@function_position_source = source
|
|
632
|
-
mode
|
|
633
|
-
end
|
|
634
|
-
|
|
635
|
-
def get_status code, name=nil, options={}
|
|
97
|
+
def get_status(code, name = nil, options = {})
|
|
636
98
|
case code
|
|
637
99
|
when 'S0001', 'S0002', 'S0003', 'S0004', 'S0005', 'S0006', 'S0007',
|
|
638
100
|
'S0008', 'S0009', 'S0010', 'S0011', 'S0012', 'S0013', 'S0014',
|
|
@@ -641,445 +103,11 @@ module RSMP
|
|
|
641
103
|
'S0029', 'S0030', 'S0031', 'S0032', 'S0033', 'S0035',
|
|
642
104
|
'S0091', 'S0092', 'S0095', 'S0096', 'S0097', 'S0098',
|
|
643
105
|
'S0205', 'S0206', 'S0207', 'S0208'
|
|
644
|
-
|
|
106
|
+
send("handle_#{code.downcase}", code, name, options)
|
|
645
107
|
else
|
|
646
|
-
raise InvalidMessage
|
|
647
|
-
end
|
|
648
|
-
end
|
|
649
|
-
|
|
650
|
-
def handle_s0001 status_code, status_name=nil, options={}
|
|
651
|
-
case status_name
|
|
652
|
-
when 'signalgroupstatus'
|
|
653
|
-
TrafficControllerSite.make_status format_signal_group_status
|
|
654
|
-
when 'cyclecounter'
|
|
655
|
-
TrafficControllerSite.make_status @cycle_counter.to_s
|
|
656
|
-
when 'basecyclecounter'
|
|
657
|
-
TrafficControllerSite.make_status @cycle_counter.to_s
|
|
658
|
-
when 'stage'
|
|
659
|
-
TrafficControllerSite.make_status 0.to_s
|
|
660
|
-
end
|
|
661
|
-
end
|
|
662
|
-
|
|
663
|
-
def handle_s0002 status_code, status_name=nil, options={}
|
|
664
|
-
case status_name
|
|
665
|
-
when 'detectorlogicstatus'
|
|
666
|
-
TrafficControllerSite.make_status @detector_logics.map { |dl| bool_to_digit(dl.value) }.join
|
|
667
|
-
end
|
|
668
|
-
end
|
|
669
|
-
|
|
670
|
-
def handle_s0003 status_code, status_name=nil, options={}
|
|
671
|
-
case status_name
|
|
672
|
-
when 'inputstatus'
|
|
673
|
-
TrafficControllerSite.make_status @inputs.actual_string
|
|
674
|
-
when 'extendedinputstatus'
|
|
675
|
-
TrafficControllerSite.make_status 0.to_s
|
|
676
|
-
end
|
|
677
|
-
end
|
|
678
|
-
|
|
679
|
-
def handle_s0004 status_code, status_name=nil, options={}
|
|
680
|
-
case status_name
|
|
681
|
-
when 'outputstatus'
|
|
682
|
-
TrafficControllerSite.make_status 0
|
|
683
|
-
when 'extendedoutputstatus'
|
|
684
|
-
TrafficControllerSite.make_status 0
|
|
685
|
-
end
|
|
686
|
-
end
|
|
687
|
-
|
|
688
|
-
def handle_s0005 status_code, status_name=nil, options={}
|
|
689
|
-
case status_name
|
|
690
|
-
when 'status'
|
|
691
|
-
TrafficControllerSite.make_status @is_starting
|
|
692
|
-
when 'statusByIntersection' # from sxl 1.2.0
|
|
693
|
-
TrafficControllerSite.make_status([
|
|
694
|
-
{
|
|
695
|
-
"intersection"=>"1",
|
|
696
|
-
"startup" => TrafficControllerSite.to_rmsp_bool(@is_starting)
|
|
697
|
-
}
|
|
698
|
-
])
|
|
699
|
-
end
|
|
700
|
-
end
|
|
701
|
-
|
|
702
|
-
def handle_s0006 status_code, status_name=nil, options={}
|
|
703
|
-
if Proxy.version_meets_requirement? options[:sxl_version], '>=1.2.0'
|
|
704
|
-
log "S0006 is depreciated, use S0035 instead.", level: :warning
|
|
705
|
-
end
|
|
706
|
-
status = @emergency_routes.any?
|
|
707
|
-
case status_name
|
|
708
|
-
when 'status'
|
|
709
|
-
TrafficControllerSite.make_status status
|
|
710
|
-
when 'emergencystage'
|
|
711
|
-
TrafficControllerSite.make_status status ? @last_emergency_route : 0
|
|
712
|
-
end
|
|
713
|
-
end
|
|
714
|
-
|
|
715
|
-
def handle_s0035 status_code, status_name=nil, options={}
|
|
716
|
-
case status_name
|
|
717
|
-
when 'emergencyroutes'
|
|
718
|
-
list = @emergency_routes.sort.map {|route| {'id'=>route.to_s}}
|
|
719
|
-
TrafficControllerSite.make_status list
|
|
720
|
-
end
|
|
721
|
-
end
|
|
722
|
-
|
|
723
|
-
def handle_s0007 status_code, status_name=nil, options={}
|
|
724
|
-
case status_name
|
|
725
|
-
when 'intersection'
|
|
726
|
-
TrafficControllerSite.make_status @intersection
|
|
727
|
-
when 'status'
|
|
728
|
-
TrafficControllerSite.make_status @function_position != 'Dark'
|
|
729
|
-
when 'source'
|
|
730
|
-
TrafficControllerSite.make_status @function_position_source
|
|
731
|
-
end
|
|
732
|
-
end
|
|
733
|
-
|
|
734
|
-
def handle_s0008 status_code, status_name=nil, options={}
|
|
735
|
-
case status_name
|
|
736
|
-
when 'intersection'
|
|
737
|
-
TrafficControllerSite.make_status @intersection
|
|
738
|
-
when 'status'
|
|
739
|
-
TrafficControllerSite.make_status @manual_control
|
|
740
|
-
when 'source'
|
|
741
|
-
TrafficControllerSite.make_status @manual_control_source
|
|
742
|
-
end
|
|
743
|
-
end
|
|
744
|
-
|
|
745
|
-
def handle_s0009 status_code, status_name=nil, options={}
|
|
746
|
-
case status_name
|
|
747
|
-
when 'intersection'
|
|
748
|
-
TrafficControllerSite.make_status @intersection
|
|
749
|
-
when 'status'
|
|
750
|
-
TrafficControllerSite.make_status @fixed_time_control
|
|
751
|
-
when 'source'
|
|
752
|
-
TrafficControllerSite.make_status @fixed_time_control_source
|
|
753
|
-
end
|
|
754
|
-
end
|
|
755
|
-
|
|
756
|
-
def handle_s0010 status_code, status_name=nil, options={}
|
|
757
|
-
case status_name
|
|
758
|
-
when 'intersection'
|
|
759
|
-
TrafficControllerSite.make_status @intersection
|
|
760
|
-
when 'status'
|
|
761
|
-
TrafficControllerSite.make_status @isolated_control
|
|
762
|
-
when 'source'
|
|
763
|
-
TrafficControllerSite.make_status @isolated_control_source
|
|
764
|
-
end
|
|
765
|
-
end
|
|
766
|
-
|
|
767
|
-
def handle_s0011 status_code, status_name=nil, options={}
|
|
768
|
-
case status_name
|
|
769
|
-
when 'intersection'
|
|
770
|
-
TrafficControllerSite.make_status @intersection
|
|
771
|
-
when 'status'
|
|
772
|
-
TrafficControllerSite.make_status TrafficControllerSite.to_rmsp_bool( @function_position == 'YellowFlash' )
|
|
773
|
-
when 'source'
|
|
774
|
-
TrafficControllerSite.make_status @function_position_source
|
|
775
|
-
end
|
|
776
|
-
end
|
|
777
|
-
|
|
778
|
-
def handle_s0012 status_code, status_name=nil, options={}
|
|
779
|
-
case status_name
|
|
780
|
-
when 'intersection'
|
|
781
|
-
TrafficControllerSite.make_status @intersection
|
|
782
|
-
when 'status'
|
|
783
|
-
TrafficControllerSite.make_status @all_red
|
|
784
|
-
when 'source'
|
|
785
|
-
TrafficControllerSite.make_status @all_red_source
|
|
786
|
-
end
|
|
787
|
-
end
|
|
788
|
-
|
|
789
|
-
def handle_s0013 status_code, status_name=nil, options={}
|
|
790
|
-
case status_name
|
|
791
|
-
when 'intersection'
|
|
792
|
-
TrafficControllerSite.make_status @intersection
|
|
793
|
-
when 'status'
|
|
794
|
-
TrafficControllerSite.make_status @police_key
|
|
795
|
-
end
|
|
796
|
-
end
|
|
797
|
-
|
|
798
|
-
def handle_s0014 status_code, status_name=nil, options={}
|
|
799
|
-
case status_name
|
|
800
|
-
when 'status'
|
|
801
|
-
TrafficControllerSite.make_status @plan
|
|
802
|
-
when 'source'
|
|
803
|
-
TrafficControllerSite.make_status @plan_source
|
|
804
|
-
end
|
|
805
|
-
end
|
|
806
|
-
|
|
807
|
-
def handle_s0015 status_code, status_name=nil, options={}
|
|
808
|
-
case status_name
|
|
809
|
-
when 'status'
|
|
810
|
-
TrafficControllerSite.make_status @traffic_situation
|
|
811
|
-
when 'source'
|
|
812
|
-
TrafficControllerSite.make_status @traffic_situation_source
|
|
813
|
-
end
|
|
814
|
-
end
|
|
815
|
-
|
|
816
|
-
def handle_s0016 status_code, status_name=nil, options={}
|
|
817
|
-
case status_name
|
|
818
|
-
when 'number'
|
|
819
|
-
TrafficControllerSite.make_status @detector_logics.size
|
|
820
|
-
end
|
|
821
|
-
end
|
|
822
|
-
|
|
823
|
-
def handle_s0017 status_code, status_name=nil, options={}
|
|
824
|
-
case status_name
|
|
825
|
-
when 'number'
|
|
826
|
-
TrafficControllerSite.make_status @signal_groups.size
|
|
827
|
-
end
|
|
828
|
-
end
|
|
829
|
-
|
|
830
|
-
def handle_s0018 status_code, status_name=nil, options={}
|
|
831
|
-
case status_name
|
|
832
|
-
when 'number'
|
|
833
|
-
TrafficControllerSite.make_status @plans.size
|
|
834
|
-
end
|
|
835
|
-
end
|
|
836
|
-
|
|
837
|
-
def handle_s0019 status_code, status_name=nil, options={}
|
|
838
|
-
case status_name
|
|
839
|
-
when 'number'
|
|
840
|
-
TrafficControllerSite.make_status @num_traffic_situations
|
|
841
|
-
end
|
|
842
|
-
end
|
|
843
|
-
|
|
844
|
-
def handle_s0020 status_code, status_name=nil, options={}
|
|
845
|
-
case status_name
|
|
846
|
-
when 'intersection'
|
|
847
|
-
TrafficControllerSite.make_status @intersection
|
|
848
|
-
when 'controlmode'
|
|
849
|
-
TrafficControllerSite.make_status @control_mode
|
|
850
|
-
end
|
|
851
|
-
end
|
|
852
|
-
|
|
853
|
-
def handle_s0021 status_code, status_name=nil, options={}
|
|
854
|
-
case status_name
|
|
855
|
-
when 'detectorlogics'
|
|
856
|
-
TrafficControllerSite.make_status @detector_logics.map { |logic| bool_to_digit(logic.forced)}.join
|
|
857
|
-
end
|
|
858
|
-
end
|
|
859
|
-
|
|
860
|
-
def handle_s0022 status_code, status_name=nil, options={}
|
|
861
|
-
case status_name
|
|
862
|
-
when 'status'
|
|
863
|
-
TrafficControllerSite.make_status @plans.keys.join(',')
|
|
864
|
-
end
|
|
865
|
-
end
|
|
866
|
-
|
|
867
|
-
def handle_s0023 status_code, status_name=nil, options={}
|
|
868
|
-
case status_name
|
|
869
|
-
when 'status'
|
|
870
|
-
dynamic_bands = @plans.map { |nr,plan| plan.dynamic_bands_string }
|
|
871
|
-
str = dynamic_bands.compact.join(',')
|
|
872
|
-
TrafficControllerSite.make_status str
|
|
873
|
-
end
|
|
874
|
-
end
|
|
875
|
-
|
|
876
|
-
def handle_s0024 status_code, status_name=nil, options={}
|
|
877
|
-
case status_name
|
|
878
|
-
when 'status'
|
|
879
|
-
TrafficControllerSite.make_status '1-0'
|
|
880
|
-
end
|
|
881
|
-
end
|
|
882
|
-
|
|
883
|
-
def handle_s0026 status_code, status_name=nil, options={}
|
|
884
|
-
case status_name
|
|
885
|
-
when 'status'
|
|
886
|
-
TrafficControllerSite.make_status '0-00'
|
|
887
|
-
end
|
|
888
|
-
end
|
|
889
|
-
|
|
890
|
-
def handle_s0027 status_code, status_name=nil, options={}
|
|
891
|
-
case status_name
|
|
892
|
-
when 'status'
|
|
893
|
-
status = @day_time_table.map do |i,item|
|
|
894
|
-
"#{i}-#{item[:plan]}-#{item[:hour]}-#{item[:min]}"
|
|
895
|
-
end.join(',')
|
|
896
|
-
TrafficControllerSite.make_status status
|
|
897
|
-
end
|
|
898
|
-
end
|
|
899
|
-
|
|
900
|
-
def handle_s0028 status_code, status_name=nil, options={}
|
|
901
|
-
case status_name
|
|
902
|
-
when 'status'
|
|
903
|
-
times = @plans.map {|nr,plan| "#{"%02d" % plan.nr}-#{"%02d" % plan.cycle_time}"}.join(",")
|
|
904
|
-
TrafficControllerSite.make_status times
|
|
905
|
-
end
|
|
906
|
-
rescue StandardError => e
|
|
907
|
-
puts e
|
|
908
|
-
end
|
|
909
|
-
|
|
910
|
-
def handle_s0029 status_code, status_name=nil, options={}
|
|
911
|
-
case status_name
|
|
912
|
-
when 'status'
|
|
913
|
-
TrafficControllerSite.make_status @inputs.forced_string
|
|
914
|
-
end
|
|
915
|
-
end
|
|
916
|
-
|
|
917
|
-
def handle_s0030 status_code, status_name=nil, options={}
|
|
918
|
-
case status_name
|
|
919
|
-
when 'status'
|
|
920
|
-
TrafficControllerSite.make_status ''
|
|
921
|
-
end
|
|
922
|
-
end
|
|
923
|
-
|
|
924
|
-
def handle_s0031 status_code, status_name=nil, options={}
|
|
925
|
-
case status_name
|
|
926
|
-
when 'status'
|
|
927
|
-
TrafficControllerSite.make_status ''
|
|
928
|
-
end
|
|
929
|
-
end
|
|
930
|
-
|
|
931
|
-
def handle_s0032 status_code, status_name=nil, options={}
|
|
932
|
-
case status_name
|
|
933
|
-
when 'intersection'
|
|
934
|
-
TrafficControllerSite.make_status @intersection
|
|
935
|
-
when 'status'
|
|
936
|
-
TrafficControllerSite.make_status 'local'
|
|
937
|
-
when 'source'
|
|
938
|
-
TrafficControllerSite.make_status @intersection_source
|
|
939
|
-
end
|
|
940
|
-
end
|
|
941
|
-
|
|
942
|
-
def handle_s0033 status_code, status_name=nil, options={}
|
|
943
|
-
case status_name
|
|
944
|
-
when 'status'
|
|
945
|
-
TrafficControllerSite.make_status get_priority_list
|
|
946
|
-
end
|
|
947
|
-
end
|
|
948
|
-
|
|
949
|
-
def handle_s0091 status_code, status_name=nil, options={}
|
|
950
|
-
if Proxy.version_meets_requirement? options[:sxl_version], '>=1.1'
|
|
951
|
-
case status_name
|
|
952
|
-
when 'user'
|
|
953
|
-
TrafficControllerSite.make_status 0
|
|
954
|
-
end
|
|
955
|
-
else
|
|
956
|
-
case status_name
|
|
957
|
-
when 'user'
|
|
958
|
-
TrafficControllerSite.make_status 'nobody'
|
|
959
|
-
when 'status'
|
|
960
|
-
TrafficControllerSite.make_status 'logout'
|
|
961
|
-
end
|
|
962
|
-
end
|
|
963
|
-
end
|
|
964
|
-
|
|
965
|
-
def handle_s0092 status_code, status_name=nil, options={}
|
|
966
|
-
if Proxy.version_meets_requirement? options[:sxl_version], '>=1.1'
|
|
967
|
-
case status_name
|
|
968
|
-
when 'user'
|
|
969
|
-
TrafficControllerSite.make_status 0
|
|
970
|
-
end
|
|
971
|
-
else
|
|
972
|
-
case status_name
|
|
973
|
-
when 'user'
|
|
974
|
-
TrafficControllerSite.make_status 'nobody'
|
|
975
|
-
when 'status'
|
|
976
|
-
TrafficControllerSite.make_status 'logout'
|
|
977
|
-
end
|
|
978
|
-
end
|
|
979
|
-
end
|
|
980
|
-
|
|
981
|
-
def handle_s0095 status_code, status_name=nil, options={}
|
|
982
|
-
case status_name
|
|
983
|
-
when 'status'
|
|
984
|
-
TrafficControllerSite.make_status RSMP::VERSION
|
|
985
|
-
end
|
|
986
|
-
end
|
|
987
|
-
|
|
988
|
-
def handle_s0096 status_code, status_name=nil, options={}
|
|
989
|
-
now = clock.now
|
|
990
|
-
case status_name
|
|
991
|
-
when 'year'
|
|
992
|
-
TrafficControllerSite.make_status now.year.to_s.rjust(4, "0")
|
|
993
|
-
when 'month'
|
|
994
|
-
TrafficControllerSite.make_status now.month.to_s.rjust(2, "0")
|
|
995
|
-
when 'day'
|
|
996
|
-
TrafficControllerSite.make_status now.day.to_s.rjust(2, "0")
|
|
997
|
-
when 'hour'
|
|
998
|
-
TrafficControllerSite.make_status now.hour.to_s.rjust(2, "0")
|
|
999
|
-
when 'minute'
|
|
1000
|
-
TrafficControllerSite.make_status now.min.to_s.rjust(2, "0")
|
|
1001
|
-
when 'second'
|
|
1002
|
-
TrafficControllerSite.make_status now.sec.to_s.rjust(2, "0")
|
|
1003
|
-
end
|
|
1004
|
-
end
|
|
1005
|
-
|
|
1006
|
-
def handle_s0097 status_code, status_name=nil, options={}
|
|
1007
|
-
case status_name
|
|
1008
|
-
when 'checksum'
|
|
1009
|
-
TrafficControllerSite.make_status '1'
|
|
1010
|
-
when 'timestamp'
|
|
1011
|
-
now = clock.to_s
|
|
1012
|
-
TrafficControllerSite.make_status now
|
|
1013
|
-
end
|
|
1014
|
-
end
|
|
1015
|
-
|
|
1016
|
-
def handle_s0098 status_code, status_name=nil, options={}
|
|
1017
|
-
settings = node.site_settings.slice('components','signal_plans','inputs','startup_sequence')
|
|
1018
|
-
json = JSON.generate(settings)
|
|
1019
|
-
case status_name
|
|
1020
|
-
when 'config'
|
|
1021
|
-
TrafficControllerSite.make_status json
|
|
1022
|
-
when 'timestamp'
|
|
1023
|
-
now = clock.to_s
|
|
1024
|
-
TrafficControllerSite.make_status now
|
|
1025
|
-
when 'version'
|
|
1026
|
-
TrafficControllerSite.make_status Digest::MD5.hexdigest(json)
|
|
1027
|
-
end
|
|
1028
|
-
end
|
|
1029
|
-
|
|
1030
|
-
def handle_s0205 status_code, status_name=nil, options={}
|
|
1031
|
-
case status_name
|
|
1032
|
-
when 'start'
|
|
1033
|
-
TrafficControllerSite.make_status clock.to_s
|
|
1034
|
-
when 'vehicles'
|
|
1035
|
-
TrafficControllerSite.make_status 0
|
|
1036
|
-
end
|
|
1037
|
-
end
|
|
1038
|
-
|
|
1039
|
-
def handle_s0206 status_code, status_name=nil, options={}
|
|
1040
|
-
case status_name
|
|
1041
|
-
when 'start'
|
|
1042
|
-
TrafficControllerSite.make_status clock.to_s
|
|
1043
|
-
when 'speed'
|
|
1044
|
-
TrafficControllerSite.make_status 0
|
|
1045
|
-
end
|
|
1046
|
-
end
|
|
1047
|
-
|
|
1048
|
-
def handle_s0207 status_code, status_name=nil, options={}
|
|
1049
|
-
case status_name
|
|
1050
|
-
when 'start'
|
|
1051
|
-
TrafficControllerSite.make_status clock.to_s
|
|
1052
|
-
when 'occupancy'
|
|
1053
|
-
values = [-1,0,50,100]
|
|
1054
|
-
output = @detector_logics.each_with_index.map {|dl,i| values[i%values.size] }.join(",")
|
|
1055
|
-
TrafficControllerSite.make_status output
|
|
1056
|
-
end
|
|
1057
|
-
end
|
|
1058
|
-
|
|
1059
|
-
def handle_s0208 status_code, status_name=nil, options={}
|
|
1060
|
-
case status_name
|
|
1061
|
-
when 'start'
|
|
1062
|
-
TrafficControllerSite.make_status clock.to_s
|
|
1063
|
-
when 'P'
|
|
1064
|
-
TrafficControllerSite.make_status 0
|
|
1065
|
-
when 'PS'
|
|
1066
|
-
TrafficControllerSite.make_status 0
|
|
1067
|
-
when 'L'
|
|
1068
|
-
TrafficControllerSite.make_status 0
|
|
1069
|
-
when 'LS'
|
|
1070
|
-
TrafficControllerSite.make_status 0
|
|
1071
|
-
when 'B'
|
|
1072
|
-
TrafficControllerSite.make_status 0
|
|
1073
|
-
when 'SP'
|
|
1074
|
-
TrafficControllerSite.make_status 0
|
|
1075
|
-
when 'MC'
|
|
1076
|
-
TrafficControllerSite.make_status 0
|
|
1077
|
-
when 'C'
|
|
1078
|
-
TrafficControllerSite.make_status 0
|
|
1079
|
-
when 'F'
|
|
1080
|
-
TrafficControllerSite.make_status 0
|
|
108
|
+
raise InvalidMessage, "unknown status code #{code}"
|
|
1081
109
|
end
|
|
1082
110
|
end
|
|
1083
111
|
end
|
|
1084
112
|
end
|
|
1085
|
-
end
|
|
113
|
+
end
|