Class: RSMP::TLC::TrafficController

Overview

TrafficController is the main component of a TrafficControllerSite. It handles all command and status for the main component, and keeps track of signal plans, detector logics, inputs, etc. which do not have dedicated components.

Constant Summary

Constants inherited from ComponentBase

ComponentBase::AGGREGATED_STATUS_KEYS

Instance Attribute Summary collapse

Attributes inherited from ComponentBase

#aggregated_status, #aggregated_status_bools, #alarms, #c_id, #component_type, #grouped, #name, #node, #ntsoid, #statuses, #xnid

Instance Method Summary collapse

Methods included from Modules::Helpers

#bool_string_to_digit, #bool_to_digit, #find_plan, #string_to_bool

Methods included from Modules::Display

#format_signal_group_status, #output_states

Methods included from Modules::StartupSequence

#end_startup_sequence, #initiate_startup_sequence, #startup_state

Methods included from Modules::TrafficData

#handle_s0205, #handle_s0206, #handle_s0207, #handle_s0208

Methods included from Modules::DetectorLogics

#add_detector_logic, #handle_m0021, #handle_s0002, #handle_s0016, #handle_s0021, #handle_s0031

Methods included from Modules::Outputs

#handle_m0020, #handle_s0004, #handle_s0030

Methods included from Modules::Inputs

#apply_input_changes, #extract_input_bits, #handle_m0006, #handle_m0012, #handle_m0013, #handle_m0019, #handle_s0003, #handle_s0029, #input_logic, #parse_input_status, #set_input, #setup_inputs, #validate_input_ranges

Methods included from Modules::SignalGroups

#add_signal_group, #handle_m0022, #priority_list, #prune_priorities, #signal_priority_changed

Methods included from Modules::Plans

#current_plan, #find_plan, #handle_m0002, #handle_m0003, #handle_m0014, #handle_m0015, #handle_m0016, #handle_m0017, #handle_m0018, #handle_m0023, #handle_s0014, #handle_s0015, #handle_s0018, #handle_s0019, #handle_s0022, #handle_s0023, #handle_s0024, #handle_s0026, #handle_s0027, #handle_s0028, #switch_plan, #switch_traffic_situation

Methods included from Modules::Modes

#check_functional_position_timeout, #dark?, #handle_m0001, #handle_m0005, #handle_m0007, #handle_s0006, #handle_s0007, #handle_s0008, #handle_s0009, #handle_s0010, #handle_s0011, #handle_s0012, #handle_s0013, #handle_s0020, #handle_s0032, #handle_s0035, #normal_control?, #reset_modes, #set_fixed_time_control, #switch_functional_position, #yellow_flash?

Methods included from Modules::System

#clock, #datetime_components, #handle_m0004, #handle_m0103, #handle_m0104, #handle_s0005, #handle_s0091, #handle_s0092, #handle_s0095, #handle_s0096

Methods inherited from Component

#acknowledge_alarm, #activate_alarm, #deactivate_alarm, #resume_alarm, #suspend_alarm

Methods inherited from ComponentBase

#aggregated_status_changed, #clear_aggregated_status, #clear_alarm_timestamps, #get_alarm_state, #inspect, #log, #now, #set_aggregated_status, #update_metadata

Constructor Details

#initialize(node:, id:, **options) ⇒ TrafficController

Returns a new instance of TrafficController.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rsmp/tlc/traffic_controller.rb', line 23

def initialize(node:, id:, **options)
  super(
    node: node,
    id: id,
    type: options[:type],
    name: options[:name],
    ntsoid: options[:ntsoid],
    xnid: options[:xnid],
    grouped: true
  )
  @signal_groups = []
  @detector_logics = []
  @plans = options[:signal_plans]
  @num_traffic_situations = 1
  setup_inputs(options[:inputs])
  @startup_sequence = StartupSequence.new(options[:startup_sequence])
  @live_output = options[:live_output]
  reset
end

Instance Attribute Details

#cycle_counterObject (readonly)

Returns the value of attribute cycle_counter.



20
21
22
# File 'lib/rsmp/tlc/traffic_controller.rb', line 20

def cycle_counter
  @cycle_counter
end

#cycle_timeObject (readonly)

Returns the value of attribute cycle_time.



20
21
22
# File 'lib/rsmp/tlc/traffic_controller.rb', line 20

def cycle_time
  @cycle_time
end

#functional_positionObject (readonly)

Returns the value of attribute functional_position.



20
21
22
# File 'lib/rsmp/tlc/traffic_controller.rb', line 20

def functional_position
  @functional_position
end

#planObject (readonly)

Returns the value of attribute plan.



20
21
22
# File 'lib/rsmp/tlc/traffic_controller.rb', line 20

def plan
  @plan
end

#posObject (readonly)

Returns the value of attribute pos.



20
21
22
# File 'lib/rsmp/tlc/traffic_controller.rb', line 20

def pos
  @pos
end

#startup_sequenceObject (readonly)

Returns the value of attribute startup_sequence.



20
21
22
# File 'lib/rsmp/tlc/traffic_controller.rb', line 20

def startup_sequence
  @startup_sequence
end

Instance Method Details

#get_status(code, name = nil, options = {}) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rsmp/tlc/traffic_controller.rb', line 105

def get_status(code, name = nil, options = {})
  case code
  when 'S0001', 'S0002', 'S0003', 'S0004', 'S0005', 'S0006', 'S0007',
       'S0008', 'S0009', 'S0010', 'S0011', 'S0012', 'S0013', 'S0014',
       'S0015', 'S0016', 'S0017', 'S0018', 'S0019', 'S0020', 'S0021',
       'S0022', 'S0023', 'S0024', 'S0026', 'S0027', 'S0028',
       'S0029', 'S0030', 'S0031', 'S0032', 'S0033', 'S0035',
       'S0091', 'S0092', 'S0095', 'S0096', 'S0097', 'S0098',
       'S0205', 'S0206', 'S0207', 'S0208'
    send("handle_#{code.downcase}", code, name, options)
  else
    raise InvalidMessage, "unknown status code #{code}"
  end
end

#handle_command(command_code, arg, options = {}) ⇒ Object



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

def handle_command(command_code, arg, options = {})
  case command_code
  when 'M0001', 'M0002', 'M0003', 'M0004', 'M0005', 'M0006', 'M0007',
       'M0012', 'M0013', 'M0014', 'M0015', 'M0016', 'M0017', 'M0018',
       'M0019', 'M0020', 'M0021', 'M0022', 'M0023',
       'M0103', 'M0104'

    send("handle_#{command_code.downcase}", arg, options)
  else
    raise UnknownCommand, "Unknown command #{command_code}"
  end
end

#move_cycle_counterObject



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/rsmp/tlc/traffic_controller.rb', line 80

def move_cycle_counter
  plan = current_plan
  counter = if plan
              Time.now.to_i % plan.cycle_time
            else
              0
            end
  changed = counter != @cycle_counter
  @cycle_counter = counter
  changed
end

#resetObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rsmp/tlc/traffic_controller.rb', line 43

def reset
  reset_modes
  @cycle_counter = 0
  @plan = 1
  @plan_source = 'startup'
  @intersection = 0
  @intersection_source = 'startup'
  @emergency_routes = Set.new
  @last_emergency_route = nil
  @traffic_situation = 0
  @traffic_situation_source = 'startup'
  @day_time_table = {}
  @time_int = nil
  @inputs.reset
  @signal_priorities = []
  @dynamic_bands_timeout = 0
end

#status_updates_sentObject

this method is called by the supervisor proxy each time status updates have been send we can then prune our priority request list



76
77
78
# File 'lib/rsmp/tlc/traffic_controller.rb', line 76

def status_updates_sent
  prune_priorities
end

#timer(_now) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rsmp/tlc/traffic_controller.rb', line 61

def timer(_now)
  # TODO: use monotone timer, to avoid jumps in case the user sets the system time
  return unless move_cycle_counter

  check_functional_position_timeout
  @startup_sequence.advance if @startup_sequence.active?

  @signal_groups.each(&:timer)
  @signal_priorities.each(&:timer)

  output_states
end