174 lines
8.8 KiB
Python
174 lines
8.8 KiB
Python
# Configure a two-column CTC machine - test (headless, mouthless) version
|
|
#
|
|
# Uses only internal Sensors and Turnouts so it can be run as a sample.
|
|
#
|
|
# Author: Bob Jacobsen, copyright 2017, 2021
|
|
# Part of the JMRI distribution
|
|
import java
|
|
import jmri
|
|
from jmri.jmrit import Sound
|
|
from jmri.jmrit.ussctc import CodeButton
|
|
from jmri.jmrit.ussctc import CodeLine
|
|
from jmri.jmrit.ussctc import OccupancyLock
|
|
from jmri.jmrit.ussctc import PhysicalBell
|
|
from jmri.jmrit.ussctc import RouteLock
|
|
from jmri.jmrit.ussctc import SignalHeadSection
|
|
from jmri.jmrit.ussctc import Station
|
|
from jmri.jmrit.ussctc import TimeLock
|
|
from jmri.jmrit.ussctc import TrackCircuitSection
|
|
from jmri.jmrit.ussctc import TrafficLock
|
|
from jmri.jmrit.ussctc import TurnoutSection
|
|
from jmri.jmrit.ussctc import VetoedBell
|
|
|
|
# First, we define Turnouts and Sensors used by this example
|
|
# These are normally defined in a panel file with names specific
|
|
# to the layout
|
|
|
|
# initialize objects on layout
|
|
turnouts.provideTurnout("Code Indication Start") .state = CLOSED
|
|
turnouts.provideTurnout("Code Send Start") .state = CLOSED
|
|
turnouts.provideTurnout("Bell") .state = CLOSED
|
|
sensors.provideSensor("Bell Cutout") .state = INACTIVE
|
|
|
|
sensors. provideSensor( "TC Sta 1 Left Approach") .state = INACTIVE
|
|
sensors. provideSensor( "TC Sta 1 OS") .state = INACTIVE
|
|
sensors. provideSensor( "TC Sta 2 Main") .state = INACTIVE
|
|
sensors. provideSensor( "TC Sta 2 Siding") .state = INACTIVE
|
|
sensors. provideSensor( "TC Sta 2 OS") .state = INACTIVE
|
|
sensors. provideSensor( "TC Sta 2 Right Approach") .state = INACTIVE
|
|
|
|
turnouts.provideTurnout("Sta 1 Layout TO") .state = CLOSED
|
|
|
|
turnouts.provideTurnout("Sta 2 Layout TO") .state = CLOSED
|
|
|
|
# initialize_options objects on panel
|
|
turnouts.provideTurnout("Sta 1 Code") .state = CLOSED
|
|
sensors. provideSensor( "Sta 1 Code") .state = INACTIVE
|
|
|
|
turnouts.provideTurnout("Sta 1 TO 1 N") .state = CLOSED
|
|
sensors. provideSensor( "Sta 1 TO 1 N") .state = ACTIVE
|
|
turnouts.provideTurnout("Sta 1 TO 1 R") .state = CLOSED
|
|
sensors. provideSensor( "Sta 1 TO 1 R") .state = INACTIVE
|
|
|
|
turnouts.provideTurnout("Sta 1 SI 2 L") .state = CLOSED
|
|
sensors. provideSensor( "Sta 1 SI 2 L") .state = INACTIVE
|
|
turnouts.provideTurnout("Sta 1 SI 2 C") .state = CLOSED
|
|
sensors. provideSensor( "Sta 1 SI 2 C") .state = ACTIVE
|
|
turnouts.provideTurnout("Sta 1 SI 2 R") .state = CLOSED
|
|
sensors. provideSensor( "Sta 1 SI 2 R") .state = INACTIVE
|
|
|
|
turnouts.provideTurnout("Sta 1 Left Approach TC") .state = CLOSED
|
|
turnouts.provideTurnout("Sta 1 OS TC") .state = CLOSED
|
|
|
|
|
|
turnouts.provideTurnout("Sta 2 Code") .state = CLOSED
|
|
sensors. provideSensor( "Sta 2 Code") .state = INACTIVE
|
|
|
|
turnouts.provideTurnout("Sta 2 TO 3 N") .state = CLOSED
|
|
sensors. provideSensor( "Sta 2 TO 3 N") .state = ACTIVE
|
|
turnouts.provideTurnout("Sta 2 TO 3 R") .state = CLOSED
|
|
sensors. provideSensor( "Sta 2 TO 3 R") .state = INACTIVE
|
|
|
|
turnouts.provideTurnout("Sta 2 SI 4 L") .state = CLOSED
|
|
sensors. provideSensor( "Sta 2 SI 4 L") .state = INACTIVE
|
|
turnouts.provideTurnout("Sta 2 SI 4 C") .state = CLOSED
|
|
sensors. provideSensor( "Sta 2 SI 4 C") .state = ACTIVE
|
|
turnouts.provideTurnout("Sta 2 SI 4 R") .state = CLOSED
|
|
sensors. provideSensor( "Sta 2 SI 4 R") .state = INACTIVE
|
|
|
|
turnouts.provideTurnout("Sta 2 Main TC") .state = CLOSED
|
|
turnouts.provideTurnout("Sta 2 Siding TC") .state = CLOSED
|
|
turnouts.provideTurnout("Sta 2 OS TC") .state = CLOSED
|
|
turnouts.provideTurnout("Sta 2 Right Approach TC") .state = CLOSED
|
|
|
|
# signals must be provided by panel file, including signal logic
|
|
|
|
|
|
# The core of the sample script starts here, defining & connecting
|
|
# the USS CTC objects to run the sample panel
|
|
|
|
# The bell and code line are shared by all Stations
|
|
|
|
bell = VetoedBell("Bell Cutout", PhysicalBell("Bell")) # a layout output (real bell); no computer sound available in CI
|
|
|
|
codeline = CodeLine("Code Indication Start", "Code Send Start", "IT101", "IT102", "IT103", "IT104")
|
|
|
|
# Set up Station 1 - stations are numbered 1, 2, 3 etc.
|
|
# Station 1 is levers 1 and 2
|
|
|
|
station1 = Station("1", codeline, CodeButton("Sta 1 Code", "Sta 1 Code"))
|
|
|
|
turnout1 = TurnoutSection("Sta 1 Layout TO", "Sta 1 TO 1 N", "Sta 1 TO 1 R", "Sta 1 TO 1 N", "Sta 1 TO 1 R", station1)
|
|
station1.add(turnout1)
|
|
|
|
station1.add(TrackCircuitSection("TC Sta 1 Left Approach", "Sta 1 Left Approach TC", station1, bell))
|
|
station1.add(TrackCircuitSection("TC Sta 1 OS", "Sta 1 OS TC", station1, bell))
|
|
|
|
rightward = ["2 Upper", "2 Lower"]
|
|
leftward = ["2 Main", "2 Siding"]
|
|
signal2 = SignalHeadSection(rightward, leftward, "Sta 1 SI 2 L", "Sta 1 SI 2 C", "Sta 1 SI 2 R", "Sta 1 SI 2 L", "Sta 1 SI 2 R", station1);
|
|
station1.add(signal2)
|
|
|
|
occupancyLock1 = OccupancyLock("TC Sta 1 OS") # Turnout locked if occupied
|
|
routeLock1 = RouteLock(["2 Upper", "2 Lower", "2 Main", "2 Siding"]); # Turnout locked if route set across it
|
|
timeLock1 = TimeLock(signal2); # Provide time lock after certain signal changes
|
|
turnout1.addLocks([occupancyLock1, routeLock1, timeLock1]); # Add to turnout; see below for Traffic locks on signal
|
|
|
|
# Set up Station 2 - levers 3 and 4
|
|
|
|
station2 = Station("2", codeline, CodeButton("Sta 2 Code", "Sta 2 Code"))
|
|
|
|
turnout3 = TurnoutSection("Sta 2 Layout TO", "Sta 2 TO 3 N", "Sta 2 TO 3 R", "Sta 2 TO 3 N", "Sta 2 TO 3 R", station2)
|
|
station2.add(turnout3)
|
|
|
|
station2.add(TrackCircuitSection("TC Sta 2 Main", "Sta 2 Main TC", station2))
|
|
station2.add(TrackCircuitSection("TC Sta 2 Siding", "Sta 2 Siding TC", station2))
|
|
station2.add(TrackCircuitSection("TC Sta 2 OS", "Sta 2 OS TC", station2, bell))
|
|
station2.add(TrackCircuitSection("TC Sta 2 Right Approach", "Sta 2 Right Approach TC", station2, bell))
|
|
|
|
rightward = ["4 Main", "4 Siding"]
|
|
leftward = ["4 Upper", "4 Lower"]
|
|
signal4 = SignalHeadSection(rightward, leftward, "Sta 2 SI 4 L", "Sta 2 SI 4 C", "Sta 2 SI 4 R", "Sta 2 SI 4 L", "Sta 2 SI 4 R", station2);
|
|
station2.add(signal4)
|
|
|
|
occupancyLock2 = OccupancyLock("TC Sta 2 OS")
|
|
routeLock2 = RouteLock(["4 Upper", "4 Lower", "4 Main", "4 Siding"]);
|
|
timeLock2 = TimeLock(signal4);
|
|
turnout3.addLocks([occupancyLock2, routeLock2, timeLock2]);
|
|
|
|
# traffic locks - lock signal if route is set toward it already - note far route depends on Turnout settings, i.e. siding or main
|
|
viaMain2 = TrafficLock(signal4, SignalHeadSection.CODE_LEFT, [jmri.BeanSetting(turnouts.provideTurnout("Sta 1 Layout TO"), THROWN), jmri.BeanSetting(turnouts.provideTurnout("Sta 2 Layout TO"), THROWN)])
|
|
viaSiding2 = TrafficLock(signal4, SignalHeadSection.CODE_LEFT, [jmri.BeanSetting(turnouts.provideTurnout("Sta 1 Layout TO"), CLOSED), jmri.BeanSetting(turnouts.provideTurnout("Sta 2 Layout TO"), CLOSED)])
|
|
signal2.addRightwardLocks([viaMain2,viaSiding2])
|
|
|
|
viaMain4 = TrafficLock(signal2, SignalHeadSection.CODE_RIGHT, [jmri.BeanSetting(turnouts.provideTurnout("Sta 2 Layout TO"), THROWN), jmri.BeanSetting(turnouts.provideTurnout("Sta 1 Layout TO"), THROWN)])
|
|
viaSiding4 = TrafficLock(signal2, SignalHeadSection.CODE_RIGHT, [jmri.BeanSetting(turnouts.provideTurnout("Sta 2 Layout TO"), CLOSED), jmri.BeanSetting(turnouts.provideTurnout("Sta 1 Layout TO"), CLOSED)])
|
|
signal4.addLeftwardLocks([viaMain4,viaSiding4])
|
|
|
|
|
|
|
|
# Optionally, set timings
|
|
print "Setting timings"
|
|
|
|
jmri.implementation.AbstractTurnout.DELAYED_FEEDBACK_INTERVAL = 5000 # turnout throw time
|
|
print "Turnout throw delay: ", jmri.implementation.AbstractTurnout.DELAYED_FEEDBACK_INTERVAL/1000., "seconds"
|
|
|
|
jmri.jmrit.ussctc.SignalHeadSection.MOVEMENT_DELAY = 4000
|
|
print"Signal movement delay: ", jmri.jmrit.ussctc.SignalHeadSection.MOVEMENT_DELAY/1000., "seconds"
|
|
|
|
jmri.jmrit.ussctc.CodeLine.CODE_SEND_DELAY = 1000
|
|
print "Code send delay: ", jmri.jmrit.ussctc.CodeLine.CODE_SEND_DELAY/1000., "seconds"
|
|
|
|
# Start pulses for code and indication
|
|
jmri.jmrit.ussctc.CodeLine.START_PULSE_LENGTH = 500
|
|
print "Length of start pulse to relay box: ", jmri.jmrit.ussctc.CodeLine.START_PULSE_LENGTH/1000., "seconds"
|
|
|
|
# force some time between indications
|
|
jmri.jmrit.ussctc.CodeLine.INTER_INDICATION_DELAY = 500
|
|
print "Length of inter-indication delay: ", jmri.jmrit.ussctc.CodeLine.INTER_INDICATION_DELAY/1000., "seconds"
|
|
|
|
# set the "run time" duration. Prototypically several minutes, model railroaders don't want to wait that long
|
|
jmri.jmrit.ussctc.SignalHeadSection.DEFAULT_RUN_TIME_LENGTH = 30000
|
|
memories.provideMemory("IMUSS CTC:SIGNALHEADSECTION:1:TIME").setValue(jmri.jmrit.ussctc.SignalHeadSection.DEFAULT_RUN_TIME_LENGTH)
|
|
print "Running time for", jmri.jmrit.ussctc.SignalHeadSection.DEFAULT_RUN_TIME_LENGTH/1000., "seconds"
|