175 lines
10 KiB
Python
175 lines
10 KiB
Python
# Sample script to assign containers and trailers to flat cars.
|
|
#
|
|
#
|
|
# Author: Daniel Boudreau, copyright 2015
|
|
# Part of the JMRI distribution
|
|
#
|
|
# To use this script you must provide the type names for containers and trailers, and the type names for the flatcars to use.
|
|
# You must also enter the train name that will service them. The train should not service the flatcars, this script will
|
|
# do the flatcar assignments based on the container or trailer destinations. Run this script after the train is built. The containers
|
|
# and trailers must resside on the same track as the flatcars.
|
|
#
|
|
# When there isn't enough flatcars for the containers or trailers, the script will produce a warning message and remove them
|
|
# from the train.
|
|
#
|
|
# Some minor issues with this script:
|
|
# It will never assign two 20 foot containers and one 40 foot container to the same flatcar. It can do one of each.
|
|
# It doesn't consider the best allocation of flatcars, it can assign a single trailer to a flatcar that can hold two trailers,
|
|
# even of there's a flatcar available that can only hold one trailer.
|
|
#
|
|
|
|
|
|
import jmri
|
|
import javax.swing.JOptionPane;
|
|
|
|
class AssignTrailersToCars(jmri.jmrit.automat.AbstractAutomaton):
|
|
|
|
def init(self):
|
|
|
|
# train (use train name)
|
|
self.trainName = "85"
|
|
|
|
# the flatcar load name
|
|
self.loadNameTrailers = "Trailers"
|
|
self.loadNameContainers = "Containers"
|
|
|
|
# flatcar names and the number of container that can be carried
|
|
self.container20 = [["Flatcar-COFC", 4]]
|
|
self.container40 = [["Flatcar-COFC", 2]]
|
|
|
|
# flatcar names and the number of trailers that can be carried. This defines the order in which flatcars are allocated.
|
|
self.trailerPup = [["Flatcar-TOFC-(X)", 3], ["Flatcar-TOFC", 2], ["Flatcar-TOFC-(S)", 1], ["Flatcar-COFC", 2]]
|
|
self.trailer = [["Flatcar-TOFC", 2], ["Flatcar-TOFC-(S)", 1], ["Flatcar-TOFC-(X)", 2], ["Flatcar-COFC", 2]]
|
|
# Try to place reefer on single flatcars first, as an example of how to change the order flatcars are allocated
|
|
self.trailerReefer = [["Flatcar-TOFC-(S)", 1], ["Flatcar-TOFC", 2], ["Flatcar-TOFC-(X)", 2], ["Flatcar-COFC", 2]]
|
|
|
|
# containers and trailers, which flatcars can carry them, flatcar load name
|
|
self.units = [["Container-20", self.container20, self.loadNameContainers], ["Container-40", self.container40, self.loadNameContainers],
|
|
["Trailer-Pup", self.trailerPup, self.loadNameTrailers], ["Trailer-UPS", self.trailer, self.loadNameTrailers],
|
|
["Trailer-USMail", self.trailer, self.loadNameTrailers], ["Trailer-Reefer", self.trailerReefer, self.loadNameTrailers],
|
|
["Trailer", self.trailer, self.loadNameTrailers]]
|
|
|
|
# used when creating kernel names
|
|
self.regex = "_$_"
|
|
|
|
print ('Assigning flatcars to train ({})'.format(self.trainName))
|
|
|
|
return
|
|
|
|
def handle(self):
|
|
|
|
# first some checking
|
|
# determine if trailer, container, and flatcar names exist
|
|
carTypes = jmri.InstanceManager.getDefault(jmri.jmrit.operations.rollingstock.cars.CarTypes)
|
|
for unitArray in self.units:
|
|
unitName = unitArray[0]
|
|
if (carTypes.containsName(unitName) == False):
|
|
print ('Error car type ({}) not found'.format(unitName))
|
|
return False
|
|
flatcarOptions = unitArray[1]
|
|
flatcarLoadName = unitArray[2]
|
|
for flatcarOption in flatcarOptions:
|
|
number = flatcarOption[1]
|
|
flatcarName = flatcarOption[0]
|
|
if (carTypes.containsName(flatcarName) == False):
|
|
print ('Error flatcar ({}) for ({}) not found'.format(flatcarName, unitName))
|
|
return False
|
|
print ('{} ({}) can be carried by flatcar ({}) load name ({})'.format(number, unitName, flatcarName, flatcarLoadName))
|
|
|
|
# get the train manager
|
|
trainManager = jmri.InstanceManager.getDefault(jmri.jmrit.operations.trains.TrainManager)
|
|
# determine if train exists and is built
|
|
train = trainManager.getTrainByName(self.trainName)
|
|
if train == None:
|
|
print ('Error Train ({}) not found'.format(self.trainName))
|
|
return False
|
|
if not train.isBuilt():
|
|
print ('Error Train ({}) not built'.format(self.trainName))
|
|
return False
|
|
|
|
# get the car manager
|
|
carManager = jmri.InstanceManager.getDefault(jmri.jmrit.operations.rollingstock.cars.CarManager)
|
|
# get the kernel manager
|
|
kernelManager = jmri.InstanceManager.getDefault(jmri.jmrit.operations.rollingstock.cars.KernelManager)
|
|
|
|
# get a list of cars from the manager
|
|
carList = carManager.getByTrainDestinationList(train)
|
|
flatcarList = carManager.getAvailableTrainList(train)
|
|
|
|
print ('{} cars assigned to train ({})'.format(carList.size(), self.trainName))
|
|
|
|
for unitArray in self.units:
|
|
unitName = unitArray[0]
|
|
flatcarOptions = unitArray[1]
|
|
flatcarLoadName = unitArray[2]
|
|
print ('Searching for ({}):'.format(unitName))
|
|
for unit in carList:
|
|
if unit.getTypeName() == unitName:
|
|
print (' Loading ({}) ({}) destination ({}, {}) final destination ({}, {})'.format(unit.toString(), unitName, unit.getDestinationName(), unit.getDestinationTrackName(), unit.getFinalDestinationName(), unit.getFinalDestinationTrackName()))
|
|
if not unit.getKernel() == None:
|
|
print (' ({}) assigned to kernel ({})'.format(unit.toString(), unit.getKernelName()))
|
|
continue
|
|
else:
|
|
print (' ({}) isn''t assigned to a kernel'.format(unit.toString()))
|
|
for flatcarOption in flatcarOptions:
|
|
flatcarName = flatcarOption[0]
|
|
number = flatcarOption[1]
|
|
for flatcar in flatcarList:
|
|
if flatcar.getTypeName() == flatcarName and flatcar.getTrack() == unit.getTrack():
|
|
print (' Found flatcar ({}) type ({})'.format(flatcar.toString(), flatcarName))
|
|
if flatcar.getKernel() == None:
|
|
# create new kernel using train name and unit's id
|
|
kernel = kernelManager.newKernel(self.trainName + self.regex + unit.toString())
|
|
print (' Add ({}) and flatcar ({}) to kernel ({})'.format(unit.toString(), flatcar.toString(), kernel.getName()))
|
|
unit.setKernel(kernel)
|
|
flatcar.setKernel(kernel)
|
|
# show flatcar first in the manifest or switch list, then the units being carried
|
|
flatcar.setBlocking(0)
|
|
unit.setBlocking(1)
|
|
# now add flatcar to train
|
|
# force flatcar to destination
|
|
flatcar.setDestination(unit.getDestination(), unit.getDestinationTrack(), True)
|
|
flatcar.setFinalDestination(unit.getFinalDestination())
|
|
flatcar.setFinalDestinationTrack(unit.getFinalDestinationTrack())
|
|
flatcar.setRouteLocation(unit.getRouteLocation())
|
|
flatcar.setRouteDestination(unit.getRouteDestination())
|
|
flatcar.setLoadName(flatcarLoadName)
|
|
flatcar.setTrain(train)
|
|
train.setModified(True)
|
|
break
|
|
elif flatcar.getKernel().getSize() <= number:
|
|
kernel = flatcar.getKernel()
|
|
# determine if kernel is going to the same destination as this unit
|
|
if not unit.getDestination() == flatcar.getDestination() or not unit.getDestinationTrack() == flatcar.getDestinationTrack():
|
|
print (' Can''t use flatcar ({}) destination ({}, {})'.format(flatcar.toString(), flatcar.getDestinationName(), flatcar.getDestinationTrackName()))
|
|
continue
|
|
if not unit.getFinalDestination() == flatcar.getFinalDestination() or not unit.getFinalDestinationTrack() == flatcar.getFinalDestinationTrack():
|
|
print (' Can''t use flatcar ({}) final destination ({}, {})'.format())
|
|
continue
|
|
if not flatcarLoadName == flatcar.getLoadName():
|
|
print (' Can''t use flatcar ({}) load name ({})'.format(flatcar.toString(), flatcar.getLoadName()))
|
|
continue
|
|
print (' Add ({}) to kernel ({})'.format(unit.toString(), kernel.getName()))
|
|
unit.setKernel(kernel)
|
|
unit.setBlocking(kernel.getSize())
|
|
train.setModified(True)
|
|
break
|
|
else:
|
|
print (' Flatcar ({}) full'.format(flatcar.toString()))
|
|
else:
|
|
continue
|
|
break
|
|
if unit.getKernel() == None:
|
|
title = "Warning couldn't find enough flatcars for train (" + self.trainName + ")"
|
|
message = "Warning (" + unit.toString() + ") type (" + unit.getTypeName() + ") at (" + unit.getLocationName() + ") not assigned to a flatcar, train (" + self.trainName + ")"
|
|
print (message)
|
|
javax.swing.JOptionPane.showMessageDialog(None, message, title, javax.swing.JOptionPane.WARNING_MESSAGE)
|
|
# remove trailer from train
|
|
unit.setRouteLocation(None)
|
|
unit.setRouteDestination(None)
|
|
unit.setTrain(None)
|
|
train.setModified(True)
|
|
return False # all done, don't repeat again
|
|
|
|
AssignTrailersToCars().start() # create one of these, and start it running
|