Module: RSMP::TLC::Modules::Modes

Included in:
TrafficController
Defined in:
lib/rsmp/tlc/modules/modes.rb

Overview

Operating modes and functional positions for traffic controllers Handles mode switching (NormalControl/YellowFlash/Dark) and control modes

Instance Method Summary collapse

Instance Method Details

#check_functional_position_timeoutObject



27
28
29
30
31
32
33
34
# File 'lib/rsmp/tlc/modules/modes.rb', line 27

def check_functional_position_timeout
  return unless @functional_position_timeout
  return unless clock.now >= @functional_position_timeout

  switch_functional_position @previous_functional_position, reverting: true, source: 'calendar_clock'
  @functional_position_timeout = nil
  @previous_functional_position = nil
end

#dark?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/rsmp/tlc/modules/modes.rb', line 36

def dark?
  @function_position == 'Dark'
end

#handle_m0001(arg, _options = {}) ⇒ Object

M0001 - Set functional position



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rsmp/tlc/modules/modes.rb', line 49

def handle_m0001(arg, _options = {})
  @node.verify_security_code 2, arg['securityCode']

  # timeout is specified in minutes, but we take 1 to mean 1s
  # this is not according to the curent rsmp spec, but is done
  # to speed up testing
  timeout = arg['timeout'].to_i
  if timeout == 1
    timeout = 1
  else
    timeout *= 60
  end

  switch_functional_position arg['status'],
                             timeout: timeout,
                             source: 'forced'
end

#handle_m0005(arg, _options = {}) ⇒ Object

M0005 - Enable/disable emergency route



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/rsmp/tlc/modules/modes.rb', line 74

def handle_m0005(arg, _options = {})
  @node.verify_security_code 2, arg['securityCode']
  route = arg['emergencyroute'].to_i
  enable = (arg['status'] == 'True')
  @last_emergency_route = route

  if enable
    if @emergency_routes.add? route
      log "Enabling emergency route #{route}", level: :info
    else
      log "Emergency route #{route} already enabled", level: :info
    end
  elsif @emergency_routes.delete? route
    log "Disabling emergency route #{route}", level: :info
  else
    log "Emergency route #{route} already disabled", level: :info
  end
end

#handle_m0007(arg, _options = {}) ⇒ Object

M0007 - Set fixed time control



68
69
70
71
# File 'lib/rsmp/tlc/modules/modes.rb', line 68

def handle_m0007(arg, _options = {})
  @node.verify_security_code 2, arg['securityCode']
  set_fixed_time_control arg['status'], source: 'forced'
end

#handle_s0006(_status_code, status_name = nil, options = {}) ⇒ Object

S0006 - Emergency route status (deprecated, use S0035)



198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/rsmp/tlc/modules/modes.rb', line 198

def handle_s0006(_status_code, status_name = nil, options = {})
  if Proxy.version_meets_requirement? options[:sxl_version],
                                      '>=1.2.0'
    log 'S0006 is depreciated, use S0035 instead.',
        level: :warning
  end
  status = @emergency_routes.any?
  case status_name
  when 'status'
    TrafficControllerSite.make_status status
  when 'emergencystage'
    TrafficControllerSite.make_status status ? @last_emergency_route : 0
  end
end

#handle_s0007(_status_code, status_name = nil, _options = {}) ⇒ Object

S0007 - Intersection status



94
95
96
97
98
99
100
101
102
103
# File 'lib/rsmp/tlc/modules/modes.rb', line 94

def handle_s0007(_status_code, status_name = nil, _options = {})
  case status_name
  when 'intersection'
    TrafficControllerSite.make_status @intersection
  when 'status'
    TrafficControllerSite.make_status @function_position != 'Dark'
  when 'source'
    TrafficControllerSite.make_status @function_position_source
  end
end

#handle_s0008(_status_code, status_name = nil, _options = {}) ⇒ Object

S0008 - Manual control status



106
107
108
109
110
111
112
113
114
115
# File 'lib/rsmp/tlc/modules/modes.rb', line 106

def handle_s0008(_status_code, status_name = nil, _options = {})
  case status_name
  when 'intersection'
    TrafficControllerSite.make_status @intersection
  when 'status'
    TrafficControllerSite.make_status @manual_control
  when 'source'
    TrafficControllerSite.make_status @manual_control_source
  end
end

#handle_s0009(_status_code, status_name = nil, _options = {}) ⇒ Object

S0009 - Fixed time control status



118
119
120
121
122
123
124
125
126
127
# File 'lib/rsmp/tlc/modules/modes.rb', line 118

def handle_s0009(_status_code, status_name = nil, _options = {})
  case status_name
  when 'intersection'
    TrafficControllerSite.make_status @intersection
  when 'status'
    TrafficControllerSite.make_status @fixed_time_control
  when 'source'
    TrafficControllerSite.make_status @fixed_time_control_source
  end
end

#handle_s0010(_status_code, status_name = nil, _options = {}) ⇒ Object

S0010 - Isolated control status



130
131
132
133
134
135
136
137
138
139
# File 'lib/rsmp/tlc/modules/modes.rb', line 130

def handle_s0010(_status_code, status_name = nil, _options = {})
  case status_name
  when 'intersection'
    TrafficControllerSite.make_status @intersection
  when 'status'
    TrafficControllerSite.make_status @isolated_control
  when 'source'
    TrafficControllerSite.make_status @isolated_control_source
  end
end

#handle_s0011(_status_code, status_name = nil, _options = {}) ⇒ Object

S0011 - Yellow flash status



142
143
144
145
146
147
148
149
150
151
# File 'lib/rsmp/tlc/modules/modes.rb', line 142

def handle_s0011(_status_code, status_name = nil, _options = {})
  case status_name
  when 'intersection'
    TrafficControllerSite.make_status @intersection
  when 'status'
    TrafficControllerSite.make_status TrafficControllerSite.to_rmsp_bool(@function_position == 'YellowFlash')
  when 'source'
    TrafficControllerSite.make_status @function_position_source
  end
end

#handle_s0012(_status_code, status_name = nil, _options = {}) ⇒ Object

S0012 - All red status



154
155
156
157
158
159
160
161
162
163
# File 'lib/rsmp/tlc/modules/modes.rb', line 154

def handle_s0012(_status_code, status_name = nil, _options = {})
  case status_name
  when 'intersection'
    TrafficControllerSite.make_status @intersection
  when 'status'
    TrafficControllerSite.make_status @all_red
  when 'source'
    TrafficControllerSite.make_status @all_red_source
  end
end

#handle_s0013(_status_code, status_name = nil, _options = {}) ⇒ Object

S0013 - Police key status



166
167
168
169
170
171
172
173
# File 'lib/rsmp/tlc/modules/modes.rb', line 166

def handle_s0013(_status_code, status_name = nil, _options = {})
  case status_name
  when 'intersection'
    TrafficControllerSite.make_status @intersection
  when 'status'
    TrafficControllerSite.make_status @police_key
  end
end

#handle_s0020(_status_code, status_name = nil, _options = {}) ⇒ Object

S0020 - Control mode



176
177
178
179
180
181
182
183
# File 'lib/rsmp/tlc/modules/modes.rb', line 176

def handle_s0020(_status_code, status_name = nil, _options = {})
  case status_name
  when 'intersection'
    TrafficControllerSite.make_status @intersection
  when 'controlmode'
    TrafficControllerSite.make_status @control_mode
  end
end

#handle_s0032(_status_code, status_name = nil, _options = {}) ⇒ Object

S0032 - Coordination status



186
187
188
189
190
191
192
193
194
195
# File 'lib/rsmp/tlc/modules/modes.rb', line 186

def handle_s0032(_status_code, status_name = nil, _options = {})
  case status_name
  when 'intersection'
    TrafficControllerSite.make_status @intersection
  when 'status'
    TrafficControllerSite.make_status 'local'
  when 'source'
    TrafficControllerSite.make_status @intersection_source
  end
end

#handle_s0035(_status_code, status_name = nil, _options = {}) ⇒ Object

S0035 - Emergency routes (replaces S0006)



214
215
216
217
218
219
220
# File 'lib/rsmp/tlc/modules/modes.rb', line 214

def handle_s0035(_status_code, status_name = nil, _options = {})
  case status_name
  when 'emergencyroutes'
    list = @emergency_routes.sort.map { |route| { 'id' => route.to_s } }
    TrafficControllerSite.make_status list
  end
end

#normal_control?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/rsmp/tlc/modules/modes.rb', line 44

def normal_control?
  @function_position == 'NormalControl'
end

#reset_modesObject



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/rsmp/tlc/modules/modes.rb', line 7

def reset_modes
  @function_position = 'NormalControl'
  @function_position_source = 'startup'
  @previous_functional_position = nil
  @functional_position_timeout = nil

  @booting = false
  @is_starting = false
  @control_mode = 'control'
  @manual_control = false
  @manual_control_source = 'startup'
  @fixed_time_control = false
  @fixed_time_control_source = 'startup'
  @isolated_control = false
  @isolated_control_source = 'startup'
  @all_red = false
  @all_red_source = 'startup'
  @police_key = 0
end

#set_fixed_time_control(status, source:) ⇒ Object



222
223
224
225
# File 'lib/rsmp/tlc/modules/modes.rb', line 222

def set_fixed_time_control(status, source:)
  @fixed_time_control = status
  @fixed_time_control_source = source
end

#switch_functional_position(mode, source:, timeout: nil, reverting: false) ⇒ Object



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/rsmp/tlc/modules/modes.rb', line 227

def switch_functional_position(mode, source:, timeout: nil, reverting: false)
  unless %w[NormalControl YellowFlash Dark].include? mode
    raise RSMP::MessageRejected,
          "Invalid functional position #{mode.inspect}, must be NormalControl, YellowFlash or Dark"
  end

  if reverting
    log "Reverting to functional position #{mode} after timeout", level: :info
  elsif timeout&.positive?
    log "Switching to functional position #{mode} with timeout #{(timeout / 60).round(1)}min", level: :info
    @previous_functional_position = @function_position
    now = clock.now
    @functional_position_timeout = now + timeout
  else
    log "Switching to functional position #{mode}", level: :info
  end
  initiate_startup_sequence if (mode == 'NormalControl') && (@function_position != 'NormalControl')
  @function_position = mode
  @function_position_source = source
  # Update signal group states immediately to reflect new functional position
  @signal_groups.each(&:timer)
  mode
end

#yellow_flash?Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/rsmp/tlc/modules/modes.rb', line 40

def yellow_flash?
  @function_position == 'YellowFlash'
end