2580 lines
117 KiB
Python
2580 lines
117 KiB
Python
# This script runs a loco around the track, controlling the speed
|
|
# according to signals and following the blocks.
|
|
#
|
|
# Author: Ken Cameron, copyright 2009,2010
|
|
# Part of the JMRI distribution
|
|
#
|
|
# The start button is inactive until data has been entered.
|
|
#
|
|
# The test button is to force re-evaluation of all block and signal values.
|
|
#
|
|
# If the loco id isn't showing in the block table, do a 'stop'/'start the
|
|
# run' to reestablish the loco position.
|
|
#
|
|
# Notes:
|
|
# 1. This script expects a fully developed set of blocks and signals
|
|
# to exist.
|
|
# 2. Best way for that is using the 'Layout Editor' to develop the
|
|
# configuration.
|
|
# 3. However, on turnouts, the non-throat (frog) ends of the turnout should
|
|
# not have a track segment attached, the block boundary must be the
|
|
# turnout anchor point. The throat end (points) may have additional
|
|
# track segments in the same block as the turnout.
|
|
# 4. The layout must be laid out like a CTC type panel, meaning string line
|
|
# left to right across the panel. If you need to have multiple lines
|
|
# to build the whole layout place a track segment of the same block
|
|
# at the end of the first line and the start of the next line and
|
|
# use a 'hidden' track segment (same block) to connect
|
|
# those track segments.
|
|
# 5. The script keys off the loco id being passed from block to block
|
|
# by the block manager. If you have detector issues and the blocks
|
|
# falsely cycle, this may not work. You may have to add internal
|
|
# sensors to 'buffer' these false cycles using Logix to clean
|
|
# things up.
|
|
# 6. FIXED: You no longer need usernames for everything. It will use
|
|
# system or user names depending on what you have in your panel.
|
|
# 7. If you create memory values and memory labels on your panel and
|
|
# tie them to the blocks, you will always see the loco id displayed.
|
|
# That is the block value that the script is looking for when
|
|
# tracking the loco.
|
|
# NEW FOR Version 2
|
|
# 8. It now has options for a rate of speed (still needs the matching
|
|
# throttle setting) for speeds to compute stopping. But it only uses
|
|
# this for stopping on approach to a red signal. When this is added as
|
|
# an 'autopilot' to the throttle interface, it will consider more of
|
|
# these inputs. A zero in the rate will cause it to ignore it.
|
|
# 9. If the blocks have the length set (and the rate above) it will try
|
|
# to delay stopping in a red block until 80% into the block.
|
|
# NEW FOR Version 3
|
|
# 10. Requires the length of blocks be known. In turn it computes the
|
|
# fastest speed that will stop within the next two blocks based
|
|
# on the most restrictive speeds that may be in the next blocks.
|
|
#
|
|
# Still needing work:
|
|
# 1. Improve the method for 'findNextBlock' as it currently uses the
|
|
# direction from the current block. To work for 'physically designed'
|
|
# panels, it would need to focus on the connectivity of the blocks
|
|
# more and less on the direction attributes. It currently fails
|
|
# if a block transitioned more than 90 degrees within a single
|
|
# block.
|
|
# 2. Add option to delay halting if it looses sight of the loco.
|
|
# This may help some layouts where the detection 'blinks' out
|
|
# for a few seconds due to dirt etc...
|
|
# Currently you must use something like 'DebounceSensor.py' if you
|
|
# have sensors that don't hold due to the above.
|
|
# 3. Learn about the neat features the 'operations' data is adding.
|
|
# This would help with knowing lengths of trains, grades of track,
|
|
# etc to aid in controlling how to stop within a block.
|
|
#
|
|
# Changes:
|
|
# 07/23/2009 - Added a Halt button that tries to -1 the throttle to
|
|
# stop now and not be smooth. Plus a few other fixes
|
|
# like the system vs user name thing.
|
|
#
|
|
# 08/30/2009 - Added methods so this can be run from a master script
|
|
# for running mulitple throttles. Also improved many
|
|
# reliblity issues in the code.
|
|
#
|
|
# Much thanks go to the Medina Railroad Museum who was asked for
|
|
# something to help out when they have larger number of visitors
|
|
# and few staff but want the trains to run around without taking
|
|
# staff to keep them from running into each other. What started
|
|
# as a simple request grew into this script. I am planning on
|
|
# turning it into real code as a next step.
|
|
# http://railroadmuseum.net/
|
|
#
|
|
# Portions of this script are taken from a number of scripts
|
|
# by Bob Jacobsen
|
|
#
|
|
# A AbstractAutomaton is used to get a throttle and run the loco.
|
|
#
|
|
# A PropertyChangeListener is used to report block information.
|
|
# It could have been with AbstractAutomaton but this allows for
|
|
# independent action with a block change.
|
|
#
|
|
# Same thing for also watching signals.
|
|
#
|
|
# A WindowListener is used to report when the window is closing and
|
|
# allow for the removal of the PropertyChangeListener.
|
|
#
|
|
|
|
import jmri
|
|
import java
|
|
import java.awt
|
|
import java.awt.event
|
|
import java.beans
|
|
import java.util
|
|
import javax.swing
|
|
import java.util.Calendar
|
|
|
|
HighDebug = 3
|
|
MediumDebug = 2
|
|
LowDebug = 1
|
|
NoneDebug = 0
|
|
|
|
# set up a throttle with the loco address
|
|
class LocoThrot(jmri.jmrit.automat.AbstractAutomaton) :
|
|
# initialize variables
|
|
locoAddress = None
|
|
currentBlock = None
|
|
currentDirection = jmri.Path.NONE
|
|
currentBlocks = []
|
|
currentNextBlocks = []
|
|
next1Block = None
|
|
next2Block = None
|
|
next3Block = None
|
|
priorBlocks = []
|
|
priornext1Blocks = []
|
|
priorSignal = None
|
|
priorSignalAspect = None
|
|
currentSignal = None
|
|
currentSignalAspect = None
|
|
nearSignal = None
|
|
nearSignalAspect = None
|
|
next1Signal = None
|
|
next1SignalAspect = None
|
|
next2Signal = None
|
|
next2SignalAspect = None
|
|
isRunning = False
|
|
isStarting = False
|
|
isAborting = True
|
|
currentThrottle = None
|
|
scriptFrame = None
|
|
scriptFrameOldX = None
|
|
scriptFarmeOldY = None
|
|
listenerBlocks = []
|
|
listenerBlockListeners = []
|
|
listenerSignals = []
|
|
listenerSignalListeners = []
|
|
greenSignalIcon = None
|
|
greenFlashSignalIcon = None
|
|
yellowSignalIcon = None
|
|
yellowFlashSignalIcon = None
|
|
redSignalIcon = None
|
|
redFlashSignalIcon = None
|
|
darkSignalIcon = None
|
|
unknownSignalIcon = None
|
|
speedChangeTimer = None
|
|
speedChangeListener = None
|
|
shrinkGrow = True
|
|
fullScrollRows = 15
|
|
speedPane = None
|
|
rosterInstance = None
|
|
oldLocoAddress = None
|
|
didWeMoveCounter = 0
|
|
holdMoving = False
|
|
stopBlock = None
|
|
hornDelayTimer = None
|
|
hornDelayListener = None
|
|
throttleManager = None
|
|
askChangeThrottle = False
|
|
askFinishStartButton = False
|
|
methodLocoAddress = None
|
|
methodBlockDirection = None
|
|
methodLocoDirection = None
|
|
methodLocoHeadlight = None
|
|
methodShortHorn = None
|
|
methodLongHorn = None
|
|
methodBlockStart = None
|
|
methodPushShrink = None
|
|
methodPushStart = None
|
|
methodPushStop = None
|
|
methodPushTest = None
|
|
methodBlockStop = None
|
|
methodlocoDistRed = None
|
|
haltOnSignalHeadAppearance = YELLOW
|
|
debugLevel = LowDebug
|
|
movementDetected = False
|
|
|
|
def init(self):
|
|
#print("start begin:.\n")
|
|
self.setName("RT3: no loco")
|
|
self.setup()
|
|
#print("start end:.\n")
|
|
return
|
|
|
|
def handle(self):
|
|
if (self.isAborting == True) :
|
|
return 0
|
|
#self.msgText("handle begin:.")
|
|
self.waitMsec(100)
|
|
if (self.askChangeThrottle) :
|
|
self.getNewThrottle()
|
|
self.askChangeThrottle = False
|
|
if (self.askFinishStartButton) :
|
|
self.doFinishStartButton()
|
|
self.askFinishStartButton = False
|
|
if (self.methodLocoAddress != None) :
|
|
self.locoAddress.text = self.methodLocoAddress
|
|
self.methodLocoAddress = None
|
|
self.whenLocoChanged(self)
|
|
if (self.methodBlockDirection != None) :
|
|
if (self.methodBlockDirection == True) :
|
|
self.blockDirection.setSelected(True)
|
|
else :
|
|
self.blockDirection.setSelected(False)
|
|
self.methodBlockDirection = None
|
|
self.whenLocoChanged(self)
|
|
if (self.methodLocoDirection != None) :
|
|
if (self.methodLocoDirection == True) :
|
|
self.locoForward.setSelected(True)
|
|
else :
|
|
self.locoForward.setSelected(False)
|
|
self.methodLocoDirection = None
|
|
self.whenLocoChanged(self)
|
|
if (self.methodLocoHeadlight != None) :
|
|
if (self.methodLocoHeadlight == True) :
|
|
self.locoHeadlight.setSelected(True)
|
|
else :
|
|
self.locoHeadlight.setSelected(False)
|
|
self.methodLocoHeadlight = None
|
|
self.whenLocoHeadlight(self)
|
|
if (self.methodShortHorn != None) :
|
|
self.methodShortHorn = None
|
|
self.doShortHorn()
|
|
if (self.methodLongHorn != None) :
|
|
self.methodLongHorn = None
|
|
self.doLongHorn()
|
|
if (self.methodBlockStart != None) :
|
|
self.blockStart.text = self.methodBlockStart
|
|
self.methodBlockStart = None
|
|
self.whenLocoChanged(self)
|
|
if (self.methodPushShrink != None) :
|
|
self.methodPushShrink = None
|
|
self.whenShrinkButtonClicked(self)
|
|
if (self.stopButton.isEnabled() == True and self.methodPushStop != None) :
|
|
self.methodPushStop = None
|
|
self.whenStopButtonClicked(self)
|
|
if (self.testButton.isEnabled() == True and self.methodPushTest != None) :
|
|
self.methodPushTest = None
|
|
self.callBackForDidWeMove(self)
|
|
if (self.startButton.isEnabled() == True and self.methodPushStart != None) :
|
|
self.methodPushStart = None
|
|
self.whenStartButtonClicked(self)
|
|
if (self.methodBlockStop != None) :
|
|
self.blockStop.text = self.methodBlockStop
|
|
self.methodBlockStop = None
|
|
self.whenStopBlockChanged(self)
|
|
if (self.methodlocoDistRed != None) :
|
|
self.locoDistRed.text = self.methodlocoDistRed
|
|
self.methodlocoDistRed = None
|
|
self.whenLocoChanged(self)
|
|
# This handles tracking how many overlapping events happened
|
|
# and insures we run the didWeMove the right number of times
|
|
if ((self.didWeMoveCounter > 0 and self.holdMoving == False) or self.isStarting == True) :
|
|
#self.msgText("didWeMoveCounterCheck: " + str(self.didWeMoveCounter) + " - calling didWeMove")
|
|
self.didWeMove()
|
|
self.didWeMoveCounter = 0
|
|
#self.msgText("didWeMoveCounterCheck: decremented counter down to " + str(self.didWeMoveCounter))
|
|
#self.msgText("handle done")
|
|
return 1 #continue if 1, run once if 0
|
|
|
|
# allow changes of a signal dropping on the appearance to trigger halting
|
|
def setSignalAppearanceHalt(self, signalIndication) :
|
|
self.haltOnSignalHeadAppearance = signalIndication
|
|
return
|
|
|
|
# show what level of signal appearance causes a halt on dropping signal
|
|
def returnSignalAppearanceHalt(self) :
|
|
return(str(self.haltOnSignalHeadAppearance))
|
|
|
|
def getNewThrottle(self) :
|
|
self.holdMoving = True
|
|
if (self.currentThrottle != None) :
|
|
oldId = self.currentThrottle.getLocoAddress()
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("stop and release the current loco: " + str(oldId))
|
|
self.doStop();
|
|
self.currentThrottle.release(None)
|
|
self.currentThrottle = None
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Throttle " + str(oldId) + " released")
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Getting throttle") #add text to scroll field
|
|
id = int(self.locoAddress.text)
|
|
if (self.throttleManager.addressTypeUnique() == True) :
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("id values are not ambiguous")
|
|
isLong = self.throttleManager.canBeLongAddress(id)
|
|
else :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("id values are ambiguous")
|
|
isLong = True
|
|
if (self.throttleManager.canBeShortAddress(id)) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("id could be a short.")
|
|
if (self.locoLong.isSelected() == False) :
|
|
isLong = False
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Getting throttle " + str(id) + " " + str(isLong))
|
|
throttle = self.getThrottle(id, isLong)
|
|
self.currentThrottle = throttle
|
|
if (self.currentThrottle == None) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Couldn't assign throttle! - Run stopped")
|
|
self.doHalt()
|
|
else :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("got throttle: " + str(self.currentThrottle.getLocoAddress()))
|
|
self.currentThrottle.setIsForward(self.locoForward.isSelected())
|
|
self.currentThrottle.setF0(self.locoHeadlight.isSelected())
|
|
self.currentThrottle.setF1(self.locoBell.isSelected())
|
|
self.holdMoving = False
|
|
return
|
|
|
|
# return userName if available, else systemName
|
|
def giveBlockName(self, block) :
|
|
if (block == None) :
|
|
return 'None'
|
|
else :
|
|
if ((block.getUserName() == None) or (block.getUserName() == '')) :
|
|
return block.getSystemName()
|
|
else :
|
|
return block.getUserName()
|
|
|
|
# return userName if available, else systemName
|
|
def giveSignalName(self, sig) :
|
|
if (sig == None) :
|
|
return 'None'
|
|
else :
|
|
if ((sig.getUserName() == None) or (sig.getUserName() == '')) :
|
|
return sig.getSystemName()
|
|
else :
|
|
return sig.getUserName()
|
|
|
|
# return userName if available, else systemName
|
|
def giveTurnoutName(self, to) :
|
|
if (to == None) :
|
|
return 'None'
|
|
else :
|
|
if ((to.getUserName() == None) or (to.getUserName() == '')) :
|
|
return to.getSystemName()
|
|
else :
|
|
return to.getUserName()
|
|
|
|
# return userName if available, else systemName
|
|
def giveSensorName(self, sen) :
|
|
if (sen == None) :
|
|
return 'None'
|
|
else :
|
|
if ((sen.getUserName() == None) or (sen.getUserName() == '')) :
|
|
return sen.getSystemName()
|
|
else :
|
|
return sen.getUserName()
|
|
|
|
# Isolate the callback handling from the didWeMove processing
|
|
# this makes dealing with multiple events simpler
|
|
def callBackForDidWeMove(self, event) :
|
|
self.didWeMoveCounter = self.didWeMoveCounter + 1
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("callBackForDidWeMove(" + str(event) + ")")
|
|
self.msgText("counter = " + str(self.didWeMoveCounter))
|
|
# the handle() will invoke the didWeMove() as needed
|
|
return
|
|
|
|
# figure out if we moved and where
|
|
def didWeMove(self) :
|
|
self.movementDetected = False
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("didWeMove start: " + self.giveBlockName(self.currentBlock) + ":" + self.giveBlockName(self.next1Block))
|
|
if (self.currentThrottle == None) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("didWeMove called while currentThrottle was None")
|
|
return
|
|
# allow for a 2nd try. In case the id in block didn't move, but we hit the next signal
|
|
# try reading the blocks one more time in case we now see that we did move.
|
|
|
|
tryCount = 0
|
|
tryCountLimit = 2
|
|
while (tryCount < tryCountLimit) :
|
|
tryCount = tryCount + 1
|
|
if (self.debugLevel >= HighDebug) :
|
|
if (self.currentBlock != None) :
|
|
self.msgText("Current block: " + self.giveBlockName(self.currentBlock))
|
|
newCurrentBlocks = self.findCurrentBlocks()
|
|
if (len(newCurrentBlocks) == 0) :
|
|
self.msgText("Can't find loco!! Doing halt!!")
|
|
self.doHalt()
|
|
# new current block must be farthest connected to current block in current direction chain
|
|
oldCurrent = self.currentBlock
|
|
oldSignal = self.currentSignal
|
|
oldnext1Signal = self.next1Signal
|
|
oldnext2Signal = self.next2Signal
|
|
oldAspect = self.currentSignalAspect
|
|
oldFarAspect = self.next1SignalAspect
|
|
oldnext2Block = self.next1Block
|
|
tryBlock = self.currentBlock
|
|
nearSignal = None
|
|
next1Signal = None
|
|
next2Signal = None
|
|
newCurrent = None
|
|
watchSignal = None
|
|
giveUpTimer = 0
|
|
while (giveUpTimer < 10) :
|
|
giveUpTimer = giveUpTimer + 1
|
|
newCurrent = self.findNewCurrentBlock(tryBlock, newCurrentBlocks, self.currentDirection)
|
|
if (newCurrent == None) :
|
|
newBlockText = "None"
|
|
else :
|
|
newBlockText = self.giveBlockName(newCurrent)
|
|
#self.msgText("try " + str(giveUpTimer) + " " + self.giveBlockName(tryBlock) + " " + newBlockText)
|
|
if ((newCurrent == tryBlock) or (newCurrent == None)) :
|
|
break
|
|
else :
|
|
tryBlock = newCurrent
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("tryBlock: " + self.giveBlockName(tryBlock) + " oldCurrent: " + self.giveBlockName(oldCurrent) + " isStarting: " + str(self.isStarting))
|
|
if (tryBlock != oldCurrent or self.isStarting == True) :
|
|
# we did move somewhere
|
|
self.blockNow.text = " "
|
|
self.blockNowLength.text = " "
|
|
self.blockNext.text = " "
|
|
self.blockNextLength.text = " "
|
|
self.blockBeyond.text = " "
|
|
self.blockBeyondLength.text = " "
|
|
self.stopDistance.text = "0"
|
|
self.stopDistanceForSpeed.text = "0"
|
|
self.currentBlock = tryBlock
|
|
self.blockStart.text = self.giveBlockName(self.currentBlock)
|
|
self.blockNow.text = self.giveBlockName(self.currentBlock)
|
|
self.blockNowLength.text = str(self.currentBlock.getLengthIn())
|
|
self.next1Block = self.findNextBlock(self.currentBlock)
|
|
self.next2Block = None
|
|
self.next3Block = None
|
|
self.testAddBlockListener(self.currentBlock)
|
|
if (self.next1Block != None) :
|
|
self.blockNext.text = self.giveBlockName(self.next1Block)
|
|
self.blockNextLength.text = str(self.next1Block.getLengthIn())
|
|
self.stopDistance.text = str(float(self.stopDistance.text) + self.next1Block.getLengthIn())
|
|
self.testAddBlockListener(self.next1Block)
|
|
self.next2Block = self.findNextBlock(self.next1Block)
|
|
if (self.next2Block != None) :
|
|
self.blockBeyond.text = self.giveBlockName(self.next2Block)
|
|
self.blockBeyondLength.text = str(self.next2Block.getLengthIn())
|
|
self.stopDistance.text = str(float(self.stopDistance.text) + self.next2Block.getLengthIn())
|
|
self.testAddBlockListener(self.next2Block)
|
|
self.next3Block = self.findNextBlock(self.next2Block)
|
|
self.priorBlock = oldCurrent
|
|
self.priorBlocks = self.currentBlocks
|
|
# find signals from currentBlock
|
|
if (self.currentBlock != None and self.next1Block != None) :
|
|
nearSignal = jmri.InstanceManager.getDefault(jmri.jmrit.display.layoutEditor.LayoutBlockManager).getFacingSignalHead(self.currentBlock, self.next1Block)
|
|
if (nearSignal != None) :
|
|
self.testAddSignalListener(nearSignal)
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("finding nearSignal between " + self.giveBlockName(self.currentBlock) + " and " + self.giveBlockName(self.next1Block) + " found " + self.giveSignalName(nearSignal))
|
|
if (self.next1Block != None and self.next2Block != None) :
|
|
next1Signal = jmri.InstanceManager.getDefault(jmri.jmrit.display.layoutEditor.LayoutBlockManager).getFacingSignalHead(self.next1Block, self.next2Block)
|
|
if (next1Signal != None) :
|
|
self.testAddSignalListener(next1Signal)
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("finding next1Signal between " + self.giveBlockName(self.next1Block) + " and " + self.giveBlockName(self.next2Block) + " found " + self.giveSignalName(next1Signal))
|
|
if (self.next2Block != None and self.next3Block != None) :
|
|
next2Signal = jmri.InstanceManager.getDefault(jmri.jmrit.display.layoutEditor.LayoutBlockManager).getFacingSignalHead(self.next2Block, self.next3Block)
|
|
if (next2Signal != None) :
|
|
self.testAddSignalListener(next2Signal)
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("finding next2Signal between " + self.giveBlockName(self.next2Block) + " and " + self.giveBlockName(self.next3Block) + " found " + self.giveSignalName(next2Signal))
|
|
if (self.blockAhead2.isSelected() == False) :
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("3 block test: " + self.giveBlockName(self.currentBlock))
|
|
if (nearSignal != None) :
|
|
watchSignal = nearSignal
|
|
else :
|
|
if (next1Signal != None) :
|
|
watchSignal = next1Signal
|
|
else :
|
|
if (next2Signal != None) :
|
|
watchSignal = next2Signal
|
|
else :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("4 block test: " + self.giveBlockName(self.next1Block))
|
|
if (next1Signal != None) :
|
|
watchSignal = next1Signal
|
|
else :
|
|
if (next2Signal != None) :
|
|
watchSignal = next2Signal
|
|
# if we didn't find a signal, treat as RED
|
|
if (watchSignal == None) :
|
|
watchAspect = RED
|
|
else :
|
|
watchAspect = watchSignal.getAppearance()
|
|
# if we moved or the signal head changed or the aspect changed
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("test blocks: " + self.giveBlockName(oldCurrent) + ":" + self.giveBlockName(self.currentBlock) + ":" + self.giveBlockName(self.next1Block))
|
|
self.msgText("test signals: " + self.giveSignalName(oldSignal) + ":" + self.giveSignalName(watchSignal))
|
|
self.msgText("test aspects: " + self.textSignalAspect(oldAspect) + ":" + self.textSignalAspect(watchAspect))
|
|
# set flag is we just moved, needed for some timer controls
|
|
if oldCurrent != self.currentBlock :
|
|
self.movementDetected = True
|
|
if (self.movementDetected or oldSignal != watchSignal or oldAspect != watchAspect or self.isStarting == True) :
|
|
# something changed, we calc the new speed
|
|
if (oldCurrent == self.currentBlock and oldSignal == watchSignal and self.compareSignalAspects(oldAspect, watchAspect) < 0 and self.isStarting == False) :
|
|
# signal dropped, that's bad
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("signal dropped, same signal being watched.")
|
|
if (self.compareSignalAspects(self.haltOnSignalHeadAppearance, watchAspect) >= 0) : # Only stop on dropping below this
|
|
self.findNewSpeed(self.currentBlock, self.next1Block, watchSignal)
|
|
else :
|
|
self.msgText("Signal dropped in front of train. Halting!!")
|
|
if (tryCount < tryCountLimit) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Doing change retry: " + str(tryCount))
|
|
continue
|
|
else :
|
|
self.doHalt()
|
|
else :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("We moved, signal or aspect changed.")
|
|
self.findNewSpeed(self.currentBlock, self.next1Block, watchSignal)
|
|
else :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("nothing changed to effect speed")
|
|
# this is for display updates
|
|
if (nearSignal != None) :
|
|
self.signalNext.setIcon(self.cvtAppearanceIcon(nearSignal))
|
|
self.signalNextText.text = self.giveSignalName(nearSignal)
|
|
else :
|
|
self.signalNext.setIcon(None)
|
|
self.signalNextText.text = ""
|
|
if (next1Signal != None) :
|
|
self.signalBeyond.setIcon(self.cvtAppearanceIcon(next1Signal))
|
|
self.signalBeyondText.text = self.giveSignalName(next1Signal)
|
|
self.next1SignalAspect = next1Signal.getAppearance()
|
|
else :
|
|
self.signalBeyond.setIcon(None)
|
|
self.signalBeyondText.text = ""
|
|
if (next2Signal != None) :
|
|
self.next2SignalAspect = next2Signal.getAppearance()
|
|
self.nearSignal = nearSignal
|
|
self.next1Signal = next1Signal
|
|
self.next2Signal = next2Signal
|
|
# we passed normal, so don't repeat
|
|
tryCount = tryCountLimit
|
|
# if we have a stop block
|
|
if (self.stopBlock != None and self.currentBlock == self.stopBlock) :
|
|
if (self.currentThrottle.getSpeedSetting() == 0) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Found stop block, doing stop.")
|
|
self.doStop()
|
|
self.isStarting = False
|
|
self.releaseExtraListeners()
|
|
#self.msgText("didMove: done")
|
|
return
|
|
|
|
# check lists of block and signal listeners and release ones not needed
|
|
def releaseExtraListeners(self) :
|
|
numBlocksL = len(self.listenerBlockListeners)
|
|
numBlocks = len(self.listenerBlocks)
|
|
#self.msgText("start with Blocks: " + str(numBlocks) + " Listeners: " + str(numBlocksL))
|
|
if (numBlocksL != numBlocks or numBlocksL <= 0 or numBlocks <= 0) :
|
|
# blocks out of sync, stop and take it from the top
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Block lists out of sync! Blocks: " + str(numBlocks) + " Listeners: " + str(numBlocksL))
|
|
self.doHalt()
|
|
self.releaseBlockListParts()
|
|
else :
|
|
while (numBlocks > 0) :
|
|
numBlocks = numBlocks - 1
|
|
testBlock = self.listenerBlocks[numBlocks]
|
|
#self.msgText("testing block: " + self.giveBlockName(testBlock))
|
|
if (testBlock != None) :
|
|
if (testBlock != self.currentBlock) :
|
|
if (testBlock != self.next1Block) :
|
|
if (testBlock != self.next2Block) :
|
|
#self.msgText("we don't need block: " + self.giveBlockName(testBlock))
|
|
l = self.listenerBlockListeners[numBlocks]
|
|
testBlock.removePropertyChangeListener(l)
|
|
self.listenerBlockListeners.pop(numBlocks)
|
|
self.listenerBlocks.pop(numBlocks)
|
|
numSignals = len(self.listenerSignals)
|
|
numSignalsL = len(self.listenerSignalListeners)
|
|
#self.msgText("starting Signals: " + str(numSignals) + " Listeners:" + str(numSignalsL))
|
|
if (numSignals != numSignalsL or numSignalsL <= 0 or numSignals <= 0) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Signal lists out of sync! Signals: " + str(numSignals) + " Listeners:" + str(numSignalsL))
|
|
self.doHalt()
|
|
self.releaseSignalListParts()
|
|
else :
|
|
while (numSignals > 0) :
|
|
numSignals = numSignals - 1
|
|
testSignal = self.listenerSignals[numSignals]
|
|
#self.msgText("releaseExtraListeners() testing signal: " + self.giveSignalName(testSignal))
|
|
if (testSignal != self.currentSignal and testSignal != self.nearSignal and testSignal != self.next1Signal and testSignal != self.next2Signal) :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("releaseExtraListeners() releasing: " + self.giveSignalName(testSignal))
|
|
l = self.listenerSignalListeners[numSignals]
|
|
testSignal.removePropertyChangeListener(l)
|
|
self.listenerSignalListeners.pop(numSignals)
|
|
self.listenerSignals.pop(numSignals)
|
|
#self.msgText("num signalListeners: " + str(len(self.listenerSignalListeners)) + " " + str(len(self.listenerSignals)))
|
|
return
|
|
|
|
# return true if thing is in thingList
|
|
def isInList(self, thing, thingList) :
|
|
found = False
|
|
for b in thingList :
|
|
if (b == thing) :
|
|
found = True
|
|
return found
|
|
|
|
# see if block is in the listenerBlocks, add listener if not
|
|
def testAddBlockListener(self, bk) :
|
|
if (self.isInList(bk, self.listenerBlocks) == False) :
|
|
# isn't in list, setup listener and add to list
|
|
bl = self.BlockListener()
|
|
bl.setCallBack(self.callBackForDidWeMove)
|
|
bk.addPropertyChangeListener(bl)
|
|
self.listenerBlocks.append(bk)
|
|
self.listenerBlockListeners.append(bl)
|
|
return
|
|
|
|
# see if signal is in the listenerSignals, add listener if not
|
|
def testAddSignalListener(self, sig) :
|
|
if (self.isInList(sig, self.listenerSignals) == False) :
|
|
# isn't in list, setup listener and add to list
|
|
sl = self.SignalListener()
|
|
sl.setCallBack(self.callBackForDidWeMove)
|
|
sig.addPropertyChangeListener(sl)
|
|
self.listenerSignals.append(sig)
|
|
self.listenerSignalListeners.append(sl)
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("testAddSignalListener(" + self.giveSignalName(sig) + ")")
|
|
return
|
|
|
|
# release signal listeners and clean lists
|
|
def releaseSignalListParts(self) :
|
|
while(len(self.listenerSignals) > 0) :
|
|
s = self.listenerSignals.pop(0)
|
|
l = self.listenerSignalListeners.pop(0)
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("releasing listener for signal " + self.giveSignalName(s))
|
|
s.removePropertyChangeListener(l)
|
|
return
|
|
|
|
# release block listeners and clean lists
|
|
def releaseBlockListParts(self) :
|
|
while(len(self.listenerBlocks) > 0) :
|
|
b = self.listenerBlocks.pop(0)
|
|
l = self.listenerBlockListeners.pop(0)
|
|
#self.msgText("releasing listener for block " + self.giveBlockName(b))
|
|
b.removePropertyChangeListener(l)
|
|
return
|
|
|
|
# release all listeners, part of the exit cleanup
|
|
def releaseAllListeners(self, event) :
|
|
self.releaseSignalListParts()
|
|
self.releaseBlockListParts()
|
|
if (self.speedChangeTimer != None) :
|
|
for i in self.speedChangeTimer.getActionListeners() :
|
|
self.speedChangeTimer.removeActionListener(i)
|
|
if (self.hornDelayTimer != None) :
|
|
for i in self.hornDelayTimer.getActionListeners() :
|
|
self.hornDelayTimer.removeActionListener(i)
|
|
if (self.currentThrottle != None) :
|
|
#self.msgText("releasing throttle")
|
|
self.currentThrottle.setSpeedSetting(0)
|
|
self.currentThrottle.release(None)
|
|
self.isAborting = True
|
|
return
|
|
|
|
# take list of new current blocks, a current block, and a current direction
|
|
# return new current block at edge of current blocks
|
|
def findNewCurrentBlock(self, cBlock, cList, cDir) :
|
|
nBlock = None
|
|
dMask = jmri.Path.EAST | jmri.Path.WEST
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("dmask: " + str(dMask) + " orig cDir: " + str(cDir))
|
|
cDir = cDir & dMask # only looking for east/west
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText(" filtered cDir: " + str(cDir) + " currentDirection: " + str(self.currentDirection))
|
|
if (cDir == jmri.Path.NONE) :
|
|
if (self.blockDirection.isSelected() == True) :
|
|
cDir = jmri.Path.EAST
|
|
else :
|
|
cDir = jmri.Path.WEST
|
|
if (cBlock == None) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("findNewCurrentBlock: bad current block passed!")
|
|
return None
|
|
if (len(cList) <= 0) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("findNewCurrentBlock: empty cList")
|
|
else :
|
|
pList = cBlock.getPaths()
|
|
for p in pList :
|
|
pB = p.getBlock()
|
|
if (p.checkPathSet()) :
|
|
dirTest = p.getToBlockDirection() & dMask
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("findNewCurrentBlock: testing for " + jmri.Path.decodeDirection(cDir) + " from " + self.giveBlockName(cBlock) + " to " + self.giveBlockName(pB) + " pointing " + jmri.Path.decodeDirection(dirTest))
|
|
if ((cDir & dirTest) == cDir) :
|
|
for c in cList :
|
|
if (c == pB) :
|
|
nBlock = pB
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("findNewCurrentBlock found " + self.giveBlockName(pB))
|
|
break
|
|
else :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("findNewCurrentBlock not in cList: " + self.giveBlockName(c))
|
|
if (nBlock != None) :
|
|
break
|
|
else :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("findNewCurrentBlock path not traversable: " + self.giveBlockName(cBlock) + " to " + self.giveBlockName(pB))
|
|
return nBlock
|
|
|
|
# figure out signal names and decide speeds
|
|
def findNewSpeed(self, cBlock, nBlock, wSig) :
|
|
if (self.isRunning) :
|
|
if (cBlock == None) :
|
|
if (nBlock == None) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Failed to find either blocks")
|
|
self.doHalt()
|
|
else :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Failed to find current block")
|
|
self.doHalt()
|
|
else :
|
|
if (nBlock == None) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("next block doesn't exist, treating as red.")
|
|
self.speedFromAppearance(RED)
|
|
self.priorSignal = self.currentSignal
|
|
self.priorSignalAspect = self.currentSignalAspect
|
|
self.currentSignal = None
|
|
self.currentSignalAspect = RED
|
|
self.next1Signal = None
|
|
self.next1SignalAspect = RED
|
|
else :
|
|
useAspect = RED
|
|
if (wSig != None) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Found currentSignal: " + self.giveSignalName(wSig) + " displaying: " + self.cvtAppearanceText(wSig))
|
|
useAspect = wSig.getAppearance()
|
|
if (self.useStopFromDistance.isSelected() == True) :
|
|
stopDistAspect = self.speedFromStopDistance()
|
|
signalRank = self.rankSignalAspect(signalAspect)
|
|
stopDistRank = self.rankSignalAspect(stopDistAspect)
|
|
if (stopDistRank >= signalRank) :
|
|
useAspect = signalAspect
|
|
else :
|
|
useAspect = stopDistAspect
|
|
self.speedFromAppearance(useAspect)
|
|
self.priorSignal = self.currentSignal
|
|
self.priorSignalAspect = self.currentSignalAspect
|
|
self.currentSignal = wSig
|
|
self.currentSignalAspect = wSig.getAppearance()
|
|
else :
|
|
self.msgText("Failed finding signal!")
|
|
self.doHalt()
|
|
return
|
|
|
|
# return rate from signal aspect
|
|
def rateFromSignalAspect(self, sigAspect) :
|
|
ret = 0
|
|
txt = "UNKNOWN"
|
|
try :
|
|
if (sigAspect & RED != 0) :
|
|
txt = "RED"
|
|
ret = float(self.locoRateRed.text)
|
|
elif (sigAspect & FLASHRED != 0) :
|
|
txt = "FLASHRED"
|
|
ret = float(self.locoRateRedFlash.text)
|
|
elif (sigAspect & YELLOW != 0) :
|
|
txt = "YELLOW"
|
|
ret = float(self.locoRateYellow.text)
|
|
elif (sigAspect & FLASHYELLOW != 0) :
|
|
txt = "FLASHYELLOW"
|
|
ret = float(self.locoRateYellowFlash.text)
|
|
elif (sigAspect & GREEN != 0) :
|
|
txt = "GREEN"
|
|
ret = float(self.locoRateGreen.text)
|
|
elif (sigAspect & FLASHGREEN != 0) :
|
|
txt = "FLASHGREEN"
|
|
ret = float(self.locoRateGreenFlash.text)
|
|
except ValueError :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("rateFromSignalAspect: no value for aspect " + txt)
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("rateFromSignalAspect(" + self.textSignalAspect(sigAspect) + "): " + str(ret))
|
|
return ret
|
|
|
|
# convert signal appearance to a ranked value
|
|
def rankSignalAspect(self, sigAspect) :
|
|
ret = 0
|
|
if (sigAspect & RED != 0) :
|
|
ret = 1
|
|
elif (sigAspect & FLASHRED != 0) :
|
|
ret = 2
|
|
elif (sigAspect & YELLOW != 0) :
|
|
ret = 3
|
|
elif (sigAspect & FLASHYELLOW != 0) :
|
|
ret = 4
|
|
elif (sigAspect & GREEN != 0) :
|
|
ret = 5
|
|
elif (sigAspect & FLASHGREEN != 0) :
|
|
ret = 6
|
|
return ret
|
|
|
|
# return speed change distance sum for rank change
|
|
def rankSpeedChangeDistance(self, rankOld, rankNew) :
|
|
ret = 0
|
|
if (rankOld >= 1 and rankNew <= 1) :
|
|
ret = ret + float(self.locoDistRed.text)
|
|
if (rankOld >= 2 and rankNew <= 2) :
|
|
ret = ret + float(self.locoDistRedFlash.text)
|
|
if (rankOld >= 3 and rankNew <= 3) :
|
|
ret = ret + float(self.locoDistYellow.text)
|
|
if (rankOld >= 4 and rankNew <= 4) :
|
|
ret = ret + float(self.locoDistYellowFlash.text)
|
|
if (rankOld >= 5 and rankNew <= 5) :
|
|
ret = ret + float(self.locoDistGreen.text)
|
|
if (rankOld >= 6 and rankNew <= 6) :
|
|
ret = ret + float(self.locoDistGreenFlash.text)
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("rankSpeedChangeDistance(" + str(rankOld) + ", " + str(rankNew) + "): " + str(ret))
|
|
return ret
|
|
|
|
# convert signal appearance to text
|
|
def textSignalAspect(self, sigAspect) :
|
|
ret = "???"
|
|
if (sigAspect == None) :
|
|
ret = "None"
|
|
elif (sigAspect & RED != 0) :
|
|
ret = "RED"
|
|
elif (sigAspect & FLASHRED != 0) :
|
|
ret = "FLASHRED"
|
|
elif (sigAspect & YELLOW != 0) :
|
|
ret = "YELLOW"
|
|
elif (sigAspect & FLASHYELLOW != 0) :
|
|
ret = "FLASHYELLOW"
|
|
elif (sigAspect & GREEN != 0) :
|
|
ret = "GREEN"
|
|
elif (sigAspect & FLASHGREEN != 0) :
|
|
ret = "FLASHGREEN"
|
|
return ret
|
|
|
|
# compare two signal appearances
|
|
def compareSignalAspects(self, oldSigState, newSigState) :
|
|
ret = "0"
|
|
if (newSigState == None) :
|
|
# this is wrong
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("compare signals got a None for new signal state")
|
|
self.doHalt()
|
|
return
|
|
if (oldSigState == None) :
|
|
# startup case
|
|
ret = 1
|
|
else :
|
|
newSigValue = self.rankSignalAspect(newSigState)
|
|
oldSigValue = self.rankSignalAspect(oldSigState)
|
|
#self.msgText("compareSignalAspects: " + self.textSignalAspect(oldSigState) + " went " + self.textSignalAspect(newSigState))
|
|
if (newSigValue < oldSigValue) :
|
|
ret = -1
|
|
elif (newSigValue > oldSigValue) :
|
|
ret = 1
|
|
return ret
|
|
|
|
# set speed from signal appearance. update stopDistanceForSpeed with distance and return aspect to match.
|
|
def speedFromStopDistance(self) :
|
|
distLimit = float(self.stopDistance.text)
|
|
speedAspect = RED
|
|
stopDistance = 0
|
|
next = float(self.locoDistRed.text)
|
|
distLimit = distLimit - next
|
|
if (distLimit >= 0) :
|
|
stopDistance = stopDistance + next
|
|
speedAspect = RED
|
|
next = float(self.locoDistRedFlash.text)
|
|
distLimit = distLimit - next
|
|
if (distLimit >= 0) :
|
|
stopDistance = stopDistance + next
|
|
speedAspect = FLASHRED
|
|
next = float(self.locoDistYellow.text)
|
|
distLimit = distLimit - next
|
|
if (distLimit >= 0) :
|
|
stopDistance = stopDistance + next
|
|
speedAspect = YELLOW
|
|
next = float(self.locoDistYellowFlash.text)
|
|
distLimit = distLimit - next
|
|
if (distLimit >= 0) :
|
|
stopDistance = stopDistance + next
|
|
speedAspect = FLASHYELLOW
|
|
next = float(self.locoDistGreen.text)
|
|
distLimit = distLimit - next
|
|
if (distLimit >= 0) :
|
|
stopDistance = stopDistance + next
|
|
speedAspect = GREEN
|
|
next = float(self.locoDistGreenFlash.text)
|
|
distLimit = distLimit - next
|
|
if (distLimit >= 0) :
|
|
stopDistance = stopDistance + next
|
|
speedAspect = FLASHGREEN
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("speedFromStopDistance() " + str(stopDistance) + " " + self.cvtAspectToText(speedAspect))
|
|
self.stopDistanceForSpeed.text = str(stopDistance)
|
|
return speedAspect
|
|
|
|
# set speed from signal appearance
|
|
def speedFromAppearance(self, sigState) :
|
|
rep = ""
|
|
if (sigState == RED or self.currentBlock == self.stopBlock) :
|
|
rep = rep + "doRed "
|
|
self.doSpeedRed()
|
|
elif (sigState == FLASHRED) :
|
|
rep = rep + "doRedFlash "
|
|
self.doSpeedRedFlash()
|
|
elif (sigState == YELLOW or self.next1Block == self.stopBlock) :
|
|
rep = rep + "doYellow "
|
|
self.doSpeedYellow()
|
|
elif (sigState == FLASHYELLOW) :
|
|
rep = rep + "doYellowFlash "
|
|
self.doSpeedYellowFlash()
|
|
elif (sigState == GREEN) :
|
|
rep = rep + "doGreen "
|
|
self.doSpeedGreen()
|
|
elif (sigState == FLASHGREEN) :
|
|
rep = rep + "doGreenFlash "
|
|
self.doSpeedGreenFlash()
|
|
else :
|
|
rep = rep + "unknown "
|
|
self.msgText("speedFromAppearance, unknown value! " + str(sigState))
|
|
self.doHalt()
|
|
#self.msgText("speedFromAppearance: " + self.giveSignalName(sig) + " displaying: " + self.cvtAppearanceText(sig) + " so we did: " + rep)
|
|
return
|
|
|
|
# convert signal appearance to english
|
|
def cvtAppearanceText(self, sig) :
|
|
rep = ""
|
|
if (sig.getHeld()) :
|
|
rep = rep + "Held "
|
|
if (sig.getLit()) :
|
|
rep = rep + "Lit "
|
|
rep = rep + self.cvtAspectToText(sig.getAppearance())
|
|
#self.msgText("cvtAppearanceText: " + self.giveSignalName(sig) + " displaying: " + rep)
|
|
return rep
|
|
|
|
# convert signal appearance to english
|
|
def cvtAspectToText(self, sigState) :
|
|
rep = ""
|
|
if (sigState == RED) :
|
|
rep = rep + "Red "
|
|
elif (sigState == FLASHRED) :
|
|
rep = rep + "Flashing Red "
|
|
elif (sigState == YELLOW) :
|
|
rep = rep + "Yellow "
|
|
elif (sigState == FLASHYELLOW) :
|
|
rep = rep + "Flashing Yellow "
|
|
elif (sigState == GREEN) :
|
|
rep = rep + "Green "
|
|
elif (sigState == FLASHGREEN) :
|
|
rep = rep + "Flashing Green "
|
|
elif (sigState == DARK) :
|
|
rep = rep + "Dark "
|
|
else :
|
|
rep = rep + "Unknown "
|
|
#self.msgText("cvtAppearanceText: " + self.giveSignalName(sig) + " displaying: " + rep)
|
|
return rep
|
|
|
|
# convert signal appearance to icon
|
|
def cvtAppearanceIcon(self, sig) :
|
|
rep = self.darkSignalIcon
|
|
if (sig.getLit()) :
|
|
sigState = sig.getAppearance()
|
|
if (sigState == RED) :
|
|
rep = self.redSignalIcon
|
|
elif (sigState == FLASHRED) :
|
|
rep = self.redFlashSignalIcon
|
|
elif (sigState == YELLOW) :
|
|
rep = self.yellowSignalIcon
|
|
elif (sigState == FLASHYELLOW) :
|
|
rep = self.yellowFlashSignalIcon
|
|
elif (sigState == GREEN) :
|
|
rep = self.greenSignalIcon
|
|
elif (sigState == FLASHGREEN) :
|
|
rep = self.greenFlashSignalIcon
|
|
else :
|
|
rep = self.unknownSignalIcon
|
|
#self.msgText("cvtAppearanceIcon: " + self.giveSignalName(sig) + " displaying: " + rep)
|
|
return rep
|
|
|
|
# compare two lists, reply true or false
|
|
def compareLists(self, aList, bList) :
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("comparing lists")
|
|
doesMatchA = True
|
|
doesMatchB = True
|
|
for a in aList :
|
|
try :
|
|
i = bList.index(a)
|
|
except :
|
|
doesMatchA = False
|
|
if (doesMatchA) :
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("comparing lists: all of a in b")
|
|
for b in bList :
|
|
try :
|
|
i = aList.index(b)
|
|
except :
|
|
doesMatchB = False
|
|
if (doesMatchB) :
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("comparing lists: all of b in a")
|
|
return doesMatchA and doesMatchB
|
|
|
|
def doSpeedGreenFlash(self):
|
|
if (self.speedChangeTimer != None) :
|
|
self.speedChangeTimer.stop()
|
|
if (self.currentThrottle != None) :
|
|
i = 0
|
|
try :
|
|
i = int(self.locoSpeedGreenFlash.text) * 0.01
|
|
except :
|
|
if (self.debugLevel >= NoneDebug) :
|
|
self.msgText("doSpeedGreenFlash: Invalid value! " + self.locoSpeedGreenFlash.text)
|
|
self.currentThrottle.setSpeedSetting(i)
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("doSpeedGreenFlash: " + str(i))
|
|
self.locoSpeed.text = str(100 * i)
|
|
return
|
|
|
|
def doSpeedGreen(self):
|
|
if (self.speedChangeTimer != None) :
|
|
self.speedChangeTimer.stop()
|
|
if (self.currentThrottle != None) :
|
|
i = 0
|
|
try :
|
|
i = int(self.locoSpeedGreen.text) * 0.01
|
|
except :
|
|
if (self.debugLevel >= NoneDebug) :
|
|
self.msgText("doSpeedGreen: Invalid value! " + self.locoSpeedGreen.text)
|
|
self.currentThrottle.setSpeedSetting(i)
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("doSpeedGreen: " + str(i))
|
|
self.locoSpeed.text = str(100 * i)
|
|
return
|
|
|
|
def doSpeedYellowFlash(self):
|
|
if (self.speedChangeTimer != None) :
|
|
self.speedChangeTimer.stop()
|
|
if (self.currentThrottle != None) :
|
|
i = 0
|
|
try :
|
|
i = int(self.locoSpeedYellowFlash.text) * 0.01
|
|
except :
|
|
if (self.debugLevel >= NoneDebug) :
|
|
self.msgText("doSpeedYellowFlash: Invalid value! " + self.locoSpeedYellowFlash.text)
|
|
self.currentThrottle.setSpeedSetting(i)
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("doSpeedYellowFlash: " + str(i))
|
|
self.locoSpeed.text = str(100 * i)
|
|
return
|
|
|
|
def doSpeedYellow(self):
|
|
if (self.speedChangeTimer != None) :
|
|
self.speedChangeTimer.stop()
|
|
if (self.currentThrottle != None) :
|
|
doYellowNow = True
|
|
if (self.movementDetected) :
|
|
# compute how long to delay speed change
|
|
dist = self.currentBlock.getLengthIn()
|
|
rate = self.rateFromSignalAspect(FLASHGREEN)
|
|
speedChgDist = self.rankSpeedChangeDistance(self.rankSignalAspect(FLASHGREEN), self.rankSignalAspect(FLASHYELLOW))
|
|
if (self.priorSignalAspect != None) :
|
|
rate = self.rateFromSignalAspect(self.priorSignalAspect)
|
|
speedChgDist = self.rankSpeedChangeDistance(self.rankSignalAspect(self.priorSignalAspect), self.rankSignalAspect(FLASHYELLOW))
|
|
if (dist > 0 and rate > 0) :
|
|
# the delay distance is the reserved space plus 10% from far end of block
|
|
# the less one covers the delay of the handle() routine
|
|
delay = (((dist* 0.90) - speedChgDist) / rate ) - 1
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("doSpeedYellow: dist: " + str(dist) + " rate: " + str(rate) + " speedChgDist: " + str(speedChgDist) + " delay: " + str(delay))
|
|
if (delay > 1) :
|
|
currentDelay = 0
|
|
if (self.speedChangeTimer == None) :
|
|
if (self.speedChangeListener == None) :
|
|
self.speedChangeListener = self.SpeedChangeTimeoutReceiver()
|
|
self.speedChangeTimer = javax.swing.Timer(int(delay * 0), self.speedChangeListener)
|
|
self.speedChangeTimer.setInitialDelay(int(delay * 1000))
|
|
self.speedChangeTimer.setRepeats(False);
|
|
self.speedChangeListener.setCallBack(self.yellowDelayHandler)
|
|
self.speedChangeTimer.setInitialDelay(int(delay * 1000))
|
|
self.speedChangeTimer.start()
|
|
doYellowNow = False
|
|
else :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("yellow delay less that 1 second")
|
|
if (doYellowNow) :
|
|
i = 0
|
|
try :
|
|
i = int(self.locoSpeedYellow.text) * 0.01
|
|
except :
|
|
if (self.debugLevel >= NoneDebug) :
|
|
self.msgText("doSpeedYellow: Invalid value! " + self.locoSpeedYellow.text)
|
|
self.currentThrottle.setSpeedSetting(i)
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("doSpeedYellow: " + str(i))
|
|
self.locoSpeed.text = str(100 * i)
|
|
return
|
|
|
|
def doSpeedRedFlash(self):
|
|
if (self.speedChangeTimer != None) :
|
|
self.speedChangeTimer.stop()
|
|
if (self.currentThrottle != None) :
|
|
i = 0
|
|
try :
|
|
i = int(self.locoSpeedRedFlash.text) * 0.01
|
|
except :
|
|
if (self.debugLevel >= NoneDebug) :
|
|
self.msgText("doSpeedRedFlash: Invalid value! " + self.locoSpeedRedFlash.text)
|
|
self.currentThrottle.setSpeedSetting(i)
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("doSpeedRedFlash: " + str(i))
|
|
self.locoSpeed.text = str(100 * i)
|
|
return
|
|
|
|
def doSpeedRed(self):
|
|
if (self.speedChangeTimer != None) :
|
|
self.speedChangeTimer.stop()
|
|
if (self.currentThrottle != None and self.currentThrottle.getSpeedSetting() != 0) :
|
|
i = 0
|
|
try :
|
|
i = int(self.locoSpeedRed.text) * 0.01
|
|
except :
|
|
if (self.debugLevel >= NoneDebug) :
|
|
self.msgText("doSpeedRed: Invalid value! " + self.locoSpeedRed.text)
|
|
self.currentThrottle.setSpeedSetting(i)
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("doSpeedRed: " + str(i))
|
|
self.locoSpeed.text = str(100 * i)
|
|
# compute how long to delay stopping
|
|
dist = self.currentBlock.getLengthIn()
|
|
rate = float(self.locoRateRed.text)
|
|
stopDist = float(self.locoDistRed.text)
|
|
if (self.priorSignalAspect != None) :
|
|
stopDist = self.rankSpeedChangeDistance(self.rankSignalAspect(self.priorSignalAspect), self.rankSignalAspect(RED))
|
|
if (self.movementDetected == True and dist != 0 and rate != 0) :
|
|
# the stop distance is the reserved space plus 10% from far end of block
|
|
# the less one covers the delay of the handle() routine
|
|
delay = ((dist - stopDist) / rate * 0.90) - 1
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("doSpeedRed: dist: " + str(dist) + " rate: " + str(rate) + " stopDist: " + str(stopDist) + " delay: " + str(delay))
|
|
if (delay > 1) :
|
|
currentDelay = 0
|
|
if (self.speedChangeTimer == None) :
|
|
if (self.speedChangeListener == None) :
|
|
self.speedChangeListener = self.SpeedChangeTimeoutReceiver()
|
|
self.speedChangeTimer = javax.swing.Timer(int(delay * 0), self.speedChangeListener)
|
|
self.speedChangeTimer.setInitialDelay(int(delay * 1000))
|
|
self.speedChangeTimer.setRepeats(False);
|
|
self.speedChangeListener.setCallBack(self.redDelayHandler)
|
|
self.speedChangeTimer.setInitialDelay(int(delay * 1000))
|
|
self.speedChangeTimer.start()
|
|
else :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("stop delay less that 1 second")
|
|
self.doStop()
|
|
else :
|
|
self.doStop()
|
|
return
|
|
|
|
# handle the timeout for slowing to yellow
|
|
def yellowDelayHandler(self, event) :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("yellowDelayHandler: slow to yellow now!")
|
|
self.speedChangeTimer.stop()
|
|
if (self.currentThrottle != None) :
|
|
i = int(self.locoSpeedYellow.text) * 0.01
|
|
self.currentThrottle.setSpeedSetting(i)
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("yellowDelayHandler: " + str(i))
|
|
self.locoSpeed.text = self.locoSpeedYellow.text
|
|
return
|
|
|
|
# handle the timeout for stopping on red
|
|
def redDelayHandler(self, event) :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("redDelayHandler, stopping now!")
|
|
self.speedChangeTimer.stop()
|
|
self.doStop()
|
|
return
|
|
|
|
# stopping for normal issues, allows for restarting automaticly
|
|
def doStop(self):
|
|
if (self.speedChangeTimer != None) :
|
|
self.speedChangeTimer.stop()
|
|
if (self.currentThrottle != None) :
|
|
self.currentThrottle.setSpeedSetting(0)
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("doStop")
|
|
self.locoSpeed.text = "0"
|
|
if (self.currentBlock != None) :
|
|
self.blockStart.text = self.giveBlockName(self.currentBlock)
|
|
if (self.stopBlock != None and self.currentBlock == self.stopBlock) :
|
|
self.handleHalting()
|
|
return
|
|
|
|
# doHalt is for stopping due to error conditions, won't restart
|
|
def doHalt(self) :
|
|
if (self.currentThrottle != None) :
|
|
self.currentThrottle.setSpeedSetting(-1)
|
|
self.msgText("doHalt, something was in error!!")
|
|
self.locoSpeed.text = "0"
|
|
if (self.currentBlock != None) :
|
|
self.blockStart.text = self.giveBlockName(self.currentBlock)
|
|
self.handleHalting()
|
|
self.msgText("*** Run halted ***")
|
|
return
|
|
|
|
# deal with the buttons and stuff when we wait for humans
|
|
def handleHalting(self) :
|
|
self.stopButton.setEnabled(False)
|
|
self.haltButton.setEnabled(False)
|
|
self.startButton.setEnabled(True)
|
|
self.isRunning = False
|
|
return
|
|
|
|
# process the stop block
|
|
def whenStopBlockChanged(self, event) :
|
|
self.blockStop.text = self.blockStop.text.strip()
|
|
if (self.blockStop.text == "") :
|
|
self.stopBlock = None
|
|
else :
|
|
self.stopBlock = blocks.getBlock(self.blockStop.text)
|
|
return
|
|
|
|
# validate loco values
|
|
def whenLocoFieldChanged(self, event) :
|
|
isBad = False
|
|
ptr = event.getSource()
|
|
msg = "whenLocoFieldChanged: " + ptr.getName() + " - "
|
|
try :
|
|
i = int(ptr.text)
|
|
if (i < 0 or i > 9999) :
|
|
msg = msg + "Loco id out of range: " + ptr.text
|
|
ptr.text = str(i)
|
|
msg = msg + ptr.text
|
|
except :
|
|
isBad = True
|
|
msg = msg + "Invalid loco value: " + ptr.text
|
|
ptr.text = ""
|
|
if (isBad) or (self.debugLevel >= MediumDebug) :
|
|
self.msgText(msg)
|
|
return
|
|
|
|
# validate speed values
|
|
def whenSpeedFieldChanged(self, event) :
|
|
isBad = False
|
|
ptr = event.getSource()
|
|
msg = "whenSpeedFieldChanged: " + ptr.getName() + " - "
|
|
i = 0
|
|
try :
|
|
i = int(ptr.text)
|
|
ptr.text = str(i)
|
|
msg = msg + ptr.text
|
|
except ValueError :
|
|
isBad = True
|
|
msg = msg + "Invalid speed value: " + ptr.text
|
|
ptr.text = ""
|
|
if (i < 0) :
|
|
isBad = True
|
|
msg = msg + "Negitive value for speed: " + ptr.text
|
|
ptr.text = ""
|
|
if (i > 100) :
|
|
isBad = True
|
|
msg = msg + "Too large value for speed: " + ptr.text
|
|
ptr.text = ""
|
|
if (isBad) or (self.debugLevel >= MediumDebug) :
|
|
self.msgText(msg)
|
|
return
|
|
|
|
# validate distance values
|
|
def whenDistanceFieldChanged(self, event) :
|
|
isBad = False
|
|
ptr = event.getSource()
|
|
msg = "whenDistanceFieldChanged: " + ptr.getName() + " - "
|
|
f = 0
|
|
try :
|
|
f = float(round(float(ptr.text) * 100) / 100.00)
|
|
ptr.text = str(f)
|
|
msg = msg + ptr.text
|
|
except ValueError :
|
|
isBad = True
|
|
msg = msg + "Invalid distance value: " + ptr.text
|
|
ptr.text = ""
|
|
if (f < 0) :
|
|
isBad = True
|
|
msg = msg + "Negitive value for distance: " + ptr.text
|
|
ptr.text = ""
|
|
if (isBad) or (self.debugLevel >= MediumDebug) :
|
|
self.msgText(msg)
|
|
return
|
|
|
|
# enable the button when OK
|
|
def whenLocoChanged(self, event) :
|
|
# keep track of whether both fields have been changed
|
|
if (self.isRunning) :
|
|
self.doStop()
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("whenLocoChanged: was running, now stopped")
|
|
isOk = True
|
|
startBlock = None
|
|
self.locoAddress.text = self.locoAddress.text.strip()
|
|
if (self.locoAddress.text == "") :
|
|
isOk = False
|
|
else :
|
|
self.scriptFrame.setTitle("Run Loco " + self.locoAddress.text)
|
|
self.setName("RT3: " + self.locoAddress.text)
|
|
if (self.locoAddress.text != self.oldLocoAddress) :
|
|
# clear old block assignments
|
|
self.clearLocoFromBlocks(self.oldLocoAddress)
|
|
self.oldLocoAddress = self.locoAddress.text
|
|
if (self.loadFromRoster.isSelected() == True) :
|
|
# take the loco id and try looking up values in roster
|
|
if (self.rosterInstance == None) :
|
|
self.rosterInstance = jmri.jmrit.roster.Roster.getDefault()
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("got roster instance")
|
|
rosterEntries = self.rosterInstance.matchingList(None, None, self.locoAddress.text, None, None, None, None)
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("found " + str(rosterEntries.size()) + " entries matching |" + str(id) + "|")
|
|
for ent in rosterEntries :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("posible entries: " + ent.fileName)
|
|
if (rosterEntries.size() == 1) :
|
|
ent = rosterEntries.get(0)
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Reading roster: " + ent.fileName)
|
|
v = ent.getAttribute('RT_locoSpeedGreenFlash')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoSpeedGreenFlash.text = v.strip()
|
|
v = ent.getAttribute('RT_locoRateGreenFlash')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoRateGreenFlash.text = v.strip()
|
|
v = ent.getAttribute('RT_locoDistGreenFlash')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoDistGreenFlash.text = v.strip()
|
|
v = ent.getAttribute('RT_locoSpeedGreen')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoSpeedGreen.text = v.strip()
|
|
v = ent.getAttribute('RT_locoRateGreen')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoRateGreen.text = v.strip()
|
|
v = ent.getAttribute('RT_locoDistGreen')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoDistGreen.text = v.strip()
|
|
v = ent.getAttribute('RT_locoSpeedYellowFlash')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoSpeedYellowFlash.text = v.strip()
|
|
v = ent.getAttribute('RT_locoRateYellowFlash')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoRateYellowFlash.text = v.strip()
|
|
v = ent.getAttribute('RT_locoDistYellowFlash')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoDistYellowFlash.text = v.strip()
|
|
v = ent.getAttribute('RT_locoSpeedYellow')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoSpeedYellow.text = v.strip()
|
|
v = ent.getAttribute('RT_locoRateYellow')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoRateYellow.text = v.strip()
|
|
v = ent.getAttribute('RT_locoDistYellow')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoDistYellow.text = v.strip()
|
|
v = ent.getAttribute('RT_locoSpeedRedFlash')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoSpeedRedFlash.text = v.strip()
|
|
v = ent.getAttribute('RT_locoRateRedFlash')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoRateRedFlash.text = v.strip()
|
|
v = ent.getAttribute('RT_locoDistRedFlash')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoDistRedFlash.text = v.strip()
|
|
v = ent.getAttribute('RT_locoSpeedRed')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoSpeedRed.text = v.strip()
|
|
v = ent.getAttribute('RT_locoRateRed')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoRateRed.text = v.strip()
|
|
v = ent.getAttribute('RT_locoDistRed')
|
|
if (v != None and v.strip() != "") :
|
|
self.locoDistRed.text = v.strip()
|
|
self.locoLong.setSelected(ent.isLongAddress())
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Read completed: " + ent.fileName)
|
|
self.oldLocoAddress = self.locoAddress.text
|
|
if (self.locoSpeedRed.text == "") :
|
|
isOk = False
|
|
if (self.locoSpeedRedFlash.text == "") :
|
|
isOk = False
|
|
if (self.locoSpeedYellow.text == "") :
|
|
isOk = False
|
|
if (self.locoSpeedYellowFlash.text == "") :
|
|
isOk = False
|
|
if (self.locoSpeedGreen.text == "") :
|
|
isOk = False
|
|
if (self.locoSpeedGreenFlash.text == "") :
|
|
isOk = False
|
|
self.blockStart.text = self.blockStart.text.strip()
|
|
if (self.blockStart.text == "") :
|
|
isOk = False
|
|
else :
|
|
startBlock = blocks.getBlock(self.blockStart.text)
|
|
if (self.testIfBlockNameValid(self.blockStart.text) == False) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Invalid block name: " + self.blockStart.text + " please try again")
|
|
isOk = False
|
|
else:
|
|
if (startBlock.getState() != ACTIVE) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Block: " + self.blockStart.text + " is not occupied!")
|
|
isOk = False
|
|
if (isOk) :
|
|
# clear id from any existing blocks
|
|
for b in blocks.getNamedBeanSet() :
|
|
if (b != blocks.getBlock(self.blockStart.text) and b.getValue() == self.locoAddress.text) :
|
|
b.setValue("")
|
|
if (self.blockDirection.isSelected()) :
|
|
self.currentDirection = jmri.Path.EAST
|
|
else :
|
|
self.currentDirecion = jmri.Path.WEST
|
|
self.startButton.setEnabled(True)
|
|
self.haltButton.setEnabled(True)
|
|
self.testAddBlockListener(blocks.getBlock(self.blockStart.text))
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Enabled Start")
|
|
return
|
|
|
|
# handle the Move Green button on
|
|
def whenLocoMoveOnGreen(self, event) :
|
|
self.doLocoMove(event, int(self.locoSpeedGreen.text) * 0.01)
|
|
return
|
|
|
|
# handle the Move Yellow button on
|
|
def whenLocoMoveOnYellow(self, event) :
|
|
self.doLocoMove(event, int(self.locoSpeedYellow.text) * 0.01)
|
|
return
|
|
|
|
# handle the Move Red button on
|
|
def whenLocoMoveOnRed(self, event) :
|
|
self.doLocoMove(event, int(self.locoSpeedRed.text) * 0.01)
|
|
return
|
|
|
|
# handle the Move button off
|
|
def whenLocoMoveOff(self, event) :
|
|
self.doLocoMove(event, 0)
|
|
return
|
|
|
|
def doLocoMove(self, event, state) :
|
|
if (self.currentThrottle != None) :
|
|
wasState = self.currentThrottle.getSpeedSetting()
|
|
self.currentThrottle.setSpeedSetting(state)
|
|
if (self.debugLevel >= LowDebug) and (state != wasState) :
|
|
self.msgText("changed speed to: " + str(state) + " was " + str(wasState))
|
|
return
|
|
|
|
# handle the horn button on
|
|
def whenLocoHornOn(self, event) :
|
|
self.doLocoHorn(event, True)
|
|
return
|
|
|
|
# handle the horn button off
|
|
def whenLocoHornOff(self, event) :
|
|
self.doLocoHorn(event, False)
|
|
return
|
|
|
|
def doLocoHorn(self, event, state) :
|
|
if (self.currentThrottle != None) :
|
|
wasState = self.currentThrottle.getF2()
|
|
self.currentThrottle.setF2(state)
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("changed horn to: " + str(state) + " was " + str(wasState))
|
|
return
|
|
|
|
def doShortHorn(self) :
|
|
self.doTimedHorn(1*1000)
|
|
return
|
|
|
|
def doLongHorn(self) :
|
|
self.doTimedHorn(2*1000)
|
|
return
|
|
|
|
def doTimedHorn(self, delay) :
|
|
if (self.currentThrottle != None) :
|
|
self.currentThrottle.setF2(True)
|
|
if (self.hornDelayTimer == None) :
|
|
self.hornDelayListener = self.HornTimeoutReceiver()
|
|
self.hornDelayListener.setCallBack(self.hornDelayHandler)
|
|
self.hornDelayTimer = javax.swing.Timer(int(delay), self.hornDelayListener)
|
|
self.hornDelayTimer.setInitialDelay(int(delay))
|
|
self.hornDelayTimer.setRepeats(False);
|
|
self.hornDelayTimer.setInitialDelay(int(delay))
|
|
self.hornDelayTimer.start()
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("Started Timed Horn")
|
|
return
|
|
|
|
def hornDelayHandler(self, event) :
|
|
if (self.hornDelayTimer != None) :
|
|
self.hornDelayTimer.stop()
|
|
if (self.currentThrottle != None) :
|
|
self.currentThrottle.setF2(False)
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("Stopped Timed Horn")
|
|
return
|
|
|
|
# handle the Headlight button
|
|
def whenLocoHeadlight(self, event) :
|
|
if (self.currentThrottle != None) :
|
|
wasState = self.currentThrottle.getF0()
|
|
state = self.locoHeadlight.isSelected()
|
|
self.currentThrottle.setF0(state)
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("changed light to: " + str(state) + " was " +str( wasState))
|
|
return
|
|
|
|
# handle the Bell button
|
|
def whenLocoBell(self, event) :
|
|
if (self.currentThrottle != None) :
|
|
wasState = self.currentThrottle.getF1()
|
|
state = self.locoBell.isSelected()
|
|
self.currentThrottle.setF1(state)
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("changed bell to: " + str(state) + " was " + str(wasState))
|
|
return
|
|
|
|
# test for block name
|
|
def testIfBlockNameValid(self, userName) :
|
|
foundStart = False
|
|
b = blocks.getByUserName(userName)
|
|
if (b != None and self.giveBlockName(b) == userName) :
|
|
foundStart = True
|
|
return foundStart
|
|
|
|
# define what button does when clicked and attach that routine to the button
|
|
def whenStartButtonClicked(self, event) :
|
|
self.msgText("Run started") # add text
|
|
if (self.testIfBlockNameValid(self.blockStart.text) == False) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Invalid block name: " + self.blockStart.text + " please try again")
|
|
else :
|
|
c = blocks.getBlock(self.blockStart.text)
|
|
if (c == None) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Invalid block name: " + self.blockStart.text + " please try again")
|
|
else :
|
|
# clear any prior block entries
|
|
self.clearLocoFromBlocks(self.locoAddress.text)
|
|
c.setValue(self.locoAddress.text)
|
|
self.currentBlock = c
|
|
self.priorSignal = None
|
|
self.priorSignalAspect = None
|
|
self.currentSignal = None
|
|
self.currentSignalAspect = None
|
|
self.next1Block = None
|
|
self.next1Signal = None
|
|
self.next1SignalAspect = None
|
|
# set flags so things get done from handle() routine
|
|
self.askChangeThrottle = True
|
|
self.askFinishStartButton = True
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("whenStartButtonClicked, done") # add text
|
|
return
|
|
|
|
# split out so it can happen from the handle() routine
|
|
def doFinishStartButton(self) :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("Change button states") # add text
|
|
self.stopButton.setEnabled(True)
|
|
self.haltButton.setEnabled(True)
|
|
self.startButton.setEnabled(False)
|
|
self.isRunning = True
|
|
self.isStarting = True
|
|
self.currentBlocks = None
|
|
self.priorBlocks = None
|
|
if (self.blockDirection.isSelected() == True) :
|
|
self.currentDirection = jmri.Path.EAST
|
|
self.currentBlock.setDirection(jmri.Path.EAST)
|
|
else :
|
|
self.currentDirection = jmri.Path.WEST
|
|
self.currentBlock.setDirection(jmri.Path.WEST)
|
|
self.didWeMoveCounter = self.didWeMoveCounter + 1
|
|
if (self.isRunning) :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Starting current:" + self.giveBlockName(self.currentBlock))
|
|
return
|
|
|
|
def whenStopButtonClicked(self, event):
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("Slow loco to stop") # add text
|
|
self.doStop()
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("*** Run stopped ***")
|
|
self.stopButton.setEnabled(False)
|
|
self.handleHalting()
|
|
self.whenLocoChanged(event)
|
|
return
|
|
|
|
def whenHaltButtonClicked(self, event):
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Button Halt loco NOW!") # add text
|
|
self.doHalt()
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("*** Run halted ***")
|
|
self.handleHalting()
|
|
self.whenLocoChanged(event)
|
|
return
|
|
|
|
def whenLocoDirectionButtonClicked(self, event) :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("Button Loco Direction clicked")
|
|
if (self.currentThrottle != None) :
|
|
self.currentThrottle.setIsForward(self.locoForward.isSelected())
|
|
return
|
|
|
|
def whenBlockDirectionButtonClicked(self, event) :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("Button Block Direction clicked")
|
|
self.methodBlockDirection = self.blockDirection.isSelected()
|
|
return
|
|
|
|
def whenShrinkButtonClicked(self, event):
|
|
if (self.shrinkGrow == True) :
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("Shrink Display!") # add text
|
|
self.speedPane.setVisible(False)
|
|
self.shrinkGrow = False
|
|
self.fullScrollRows = self.scrollArea.getRows()
|
|
self.scrollArea.setRows(self.fullScrollRows / 2)
|
|
self.scriptFrame.pack()
|
|
else :
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("Grow Display!")
|
|
self.speedPane.setVisible(True)
|
|
self.shrinkGrow = True
|
|
self.scrollArea.setRows(self.fullScrollRows)
|
|
self.scriptFrame.pack()
|
|
return
|
|
|
|
def whenSaveToRosterButtonClicked(self, event):
|
|
if (self.locoAddress.text != "") :
|
|
if (self.rosterInstance == None) :
|
|
self.rosterInstance = jmri.jmrit.roster.Roster.getDefault()
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("got roster instance")
|
|
id = int(self.locoAddress.text)
|
|
rosterEntries = self.rosterInstance.matchingList(None, None, str(id), None, None, None, None)
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("found " + str(rosterEntries.size()) + " entries matching |" + str(id) + "|")
|
|
for ent in rosterEntries :
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("posible entries: " + ent.fileName)
|
|
if (rosterEntries.size() == 1) :
|
|
ent = rosterEntries.get(0)
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Saving to roster: " + ent.fileName)
|
|
ent.putAttribute('RT_locoSpeedGreenFlash', self.locoSpeedGreenFlash.text)
|
|
ent.putAttribute('RT_locoRateGreenFlash', self.locoRateGreenFlash.text)
|
|
ent.putAttribute('RT_locoDistGreenFlash', self.locoDistGreenFlash.text)
|
|
ent.putAttribute('RT_locoSpeedGreen', self.locoSpeedGreen.text)
|
|
ent.putAttribute('RT_locoRateGreen', self.locoRateGreen.text)
|
|
ent.putAttribute('RT_locoDistGreen', self.locoDistGreen.text)
|
|
ent.putAttribute('RT_locoSpeedYellowFlash', self.locoSpeedYellowFlash.text)
|
|
ent.putAttribute('RT_locoRateYellowFlash', self.locoRateYellowFlash.text)
|
|
ent.putAttribute('RT_locoDistYellowFlash', self.locoDistYellowFlash.text)
|
|
ent.putAttribute('RT_locoSpeedYellow', self.locoSpeedYellow.text)
|
|
ent.putAttribute('RT_locoRateYellow', self.locoRateYellow.text)
|
|
ent.putAttribute('RT_locoDistYellow', self.locoDistYellow.text)
|
|
ent.putAttribute('RT_locoSpeedRedFlash', self.locoSpeedRedFlash.text)
|
|
ent.putAttribute('RT_locoRateRedFlash', self.locoRateRedFlash.text)
|
|
ent.putAttribute('RT_locoDistRedFlash', self.locoDistRedFlash.text)
|
|
ent.putAttribute('RT_locoSpeedRed', self.locoSpeedRed.text)
|
|
ent.putAttribute('RT_locoRateRed', self.locoRateRed.text)
|
|
ent.putAttribute('RT_locoDistRed', self.locoDistRed.text)
|
|
ent.updateFile()
|
|
self.rosterInstance.writeRosterFile()
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Save completed: " + ent.fileName)
|
|
return
|
|
|
|
def findCurrentBlocks(self) :
|
|
# search the block list for the matching loco
|
|
blockList = []
|
|
for b in blocks.getNamedBeanSet() :
|
|
if (b.getValue() == self.locoAddress.text and b.getState() == ACTIVE) :
|
|
blockList.append(b)
|
|
return blockList
|
|
|
|
def clearLocoFromBlocks(self, oldId) :
|
|
# search the block list for the matching loco
|
|
blockList = []
|
|
for b in blocks.getNamedBeanSet() :
|
|
if (b.getValue() == oldId) :
|
|
b.setValue(None)
|
|
return
|
|
|
|
def findNextBlock(self, cB) :
|
|
# look down list of getToBlockDirection for match
|
|
# use 'suggestion' flag if current block doesn't have direction
|
|
bTrav = None
|
|
bNoTrav = None
|
|
dirFlag = cB.getDirection()
|
|
if (dirFlag == jmri.Path.NONE) :
|
|
if (self.currentDirection == None) :
|
|
if (self.blockDirection.isSelected() == True) :
|
|
dirFlag = jmri.Path.EAST
|
|
self.currentDirection = jmri.Path.EAST
|
|
else :
|
|
dirFlag = jmri.Path.WEST
|
|
self.currentDirection = jmri.Path.WEST
|
|
else :
|
|
dirFlag = self.currentDirection
|
|
pathList = cB.getPaths()
|
|
if (self.debugLevel >= HighDebug) :
|
|
self.msgText("searching " + str(len(pathList)) + " paths from " + self.giveBlockName(cB))
|
|
for p in pathList :
|
|
blockTest = p.getBlock()
|
|
dirTest = p.getToBlockDirection()
|
|
if (dirTest & dirFlag != 0) :
|
|
if (p.checkPathSet()) :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("findNextBlock path traversable: " + self.giveBlockName(cB) + " to " + self.giveBlockName(blockTest) + " dirTest: " + jmri.Path.decodeDirection(dirTest) + ":" + str(dirTest) + " dirFlag: " + jmri.Path.decodeDirection(dirFlag) + ":" + str(dirFlag) + " result: " + str(dirTest & dirFlag))
|
|
bTrav = blockTest
|
|
else :
|
|
if (self.debugLevel >= MediumDebug) :
|
|
self.msgText("findNextBlock path not traversable: " + self.giveBlockName(cB) + " to " + self.giveBlockName(blockTest))
|
|
bNoTrav = blockTest
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("findNextBlock Found " + self.giveBlockName(blockTest))
|
|
if (bTrav == None) :
|
|
return bNoTrav
|
|
return bTrav
|
|
|
|
# ActionListener - used for the stop timeout
|
|
class SpeedChangeTimeoutReceiver(java.awt.event.ActionListener):
|
|
cb = None
|
|
|
|
def actionPerformed(self, event) :
|
|
if (self.cb != None) :
|
|
self.cb(event)
|
|
return
|
|
|
|
def setCallBack(self, cbf) :
|
|
self.cb = cbf
|
|
return
|
|
|
|
# ActionListener - used for the horn timeout
|
|
class HornTimeoutReceiver(java.awt.event.ActionListener):
|
|
cb = None
|
|
|
|
def actionPerformed(self, event) :
|
|
if (self.cb != None) :
|
|
self.cb(event)
|
|
return
|
|
|
|
def setCallBack(self, cbf) :
|
|
self.cb = cbf
|
|
return
|
|
|
|
# WindowListener is a interface class and therefore all of it's
|
|
# methods should be implemented even if not used to avoid AttributeErrors
|
|
class WinListener(java.awt.event.WindowListener):
|
|
f = None
|
|
cleanUp = None
|
|
|
|
def setCallBack(self, fr, c):
|
|
self.f = fr
|
|
self.cleanUp = c
|
|
return
|
|
|
|
def windowClosing(self, event):
|
|
if (self.cleanUp != None) :
|
|
self.cleanUp(event)
|
|
self.f.dispose() # close the pane (window)
|
|
return
|
|
|
|
def windowActivated(self,event):
|
|
return
|
|
|
|
def windowDeactivated(self,event):
|
|
return
|
|
|
|
def windowOpened(self,event):
|
|
return
|
|
|
|
def windowClosed(self,event):
|
|
return
|
|
|
|
def windowIconified(self, event):
|
|
return
|
|
|
|
def windowDeiconified(self, event):
|
|
return
|
|
|
|
#To detect block status, first define the listener.
|
|
class BlockListener(java.beans.PropertyChangeListener):
|
|
cb = None
|
|
|
|
def setCallBack(self, ptr) :
|
|
self.cb = ptr
|
|
return
|
|
|
|
def propertyChange(self, event):
|
|
if (self.cb != None) :
|
|
self.cb(event)
|
|
return
|
|
|
|
#To detect block status, first define the listener.
|
|
class SignalListener(java.beans.PropertyChangeListener):
|
|
cb = None
|
|
|
|
def setCallBack(self, ptr) :
|
|
self.cb = ptr
|
|
return
|
|
|
|
def propertyChange(self, event):
|
|
if (self.cb != None) :
|
|
self.cb(event)
|
|
return
|
|
|
|
# method for creating a TimeStamp.
|
|
def formatTime(self, ts):
|
|
ptHrs = str(ts.get(java.util.Calendar.HOUR_OF_DAY))
|
|
if len(ptHrs) == 1 :
|
|
ptHrs = "0" + ptHrs
|
|
|
|
ptMins = str(ts.get(java.util.Calendar.MINUTE))
|
|
if len(ptMins) == 1 :
|
|
ptMins = "0" + ptMins
|
|
|
|
ptSecs = str(ts.get(java.util.Calendar.SECOND))
|
|
if len(ptSecs) == 1 :
|
|
ptSecs = "0" + ptSecs
|
|
ptMs = str(ts.get(java.util.Calendar.MILLISECOND))
|
|
pTime = ptHrs + ":" + ptMins + ":" + ptSecs + "." + ptMs
|
|
return pTime
|
|
|
|
# method for creating a DateStamp.
|
|
def formatDate(self, ts):
|
|
ptDays = str(ts.get(java.util.Calendar.DATE))
|
|
if len(ptDays) == 1 :
|
|
ptDays = "0" + ptDays
|
|
|
|
ptMonths = str(ts.get(java.util.Calendar.MONTH) + 1)
|
|
if len(ptMonths) == 1 :
|
|
ptMonths = "0" + ptMonths
|
|
|
|
ptYears = str(ts.get(java.util.Calendar.YEAR))
|
|
pDate = ptMonths + "/" + ptDays + "/" + ptYears
|
|
return pDate
|
|
|
|
# handle adding to message window
|
|
def msgText(self, txt) :
|
|
if (self.scrollTimeStamp.isSelected() == True) :
|
|
ts = java.util.Calendar.getInstance()
|
|
self.scrollArea.append(self.formatTime(ts) + ": " + txt + "\n")
|
|
else :
|
|
self.scrollArea.append(txt + "\n")
|
|
if (self.autoScroll.isSelected() == True) :
|
|
self.scrollArea.setCaretPosition(self.scrollArea.getDocument().getLength())
|
|
return
|
|
|
|
# setup the user interface
|
|
def setup(self) :
|
|
|
|
# get other setup things
|
|
|
|
self.greenSignalIcon = jmri.jmrit.catalog.NamedIcon("resources/icons/smallschematics/searchlights/right-green-short.gif", "GreenCabSignal")
|
|
self.greenFlashSignalIcon = jmri.jmrit.catalog.NamedIcon("resources/icons/smallschematics/searchlights/right-flashgreen-short.gif", "GreenFlashCabSignal")
|
|
self.yellowSignalIcon = jmri.jmrit.catalog.NamedIcon("resources/icons/smallschematics/searchlights/right-yellow-short.gif", "YellowCabSignal")
|
|
self.yellowFlashSignalIcon = jmri.jmrit.catalog.NamedIcon("resources/icons/smallschematics/searchlights/right-flashyellow-short.gif", "YellowFlashCabSignal")
|
|
self.redSignalIcon = jmri.jmrit.catalog.NamedIcon("resources/icons/smallschematics/searchlights/right-red-short.gif", "RedCabSignal")
|
|
self.redFlashSignalIcon = jmri.jmrit.catalog.NamedIcon("resources/icons/smallschematics/searchlights/right-flashred-short.gif", "RedFlashCabSignal")
|
|
self.darkSignalIcon = jmri.jmrit.catalog.NamedIcon("resources/icons/smallschematics/searchlights/right-dark-short.gif", "DarkCabSignal")
|
|
self.unknownSignalIcon = jmri.jmrit.catalog.NamedIcon("resources/icons/misc/Question-black.gif", "UnknownCabSignal")
|
|
self.throttleManager = jmri.InstanceManager.getDefault(jmri.ThrottleManager)
|
|
if (self.throttleManager == None) :
|
|
print("No command station found!!\nRT has no way to control the trains.\n")
|
|
return
|
|
|
|
# start to initialise the GUI
|
|
sizeRateField = 4
|
|
sizeSpeedField = 3
|
|
|
|
# create buttons and define action
|
|
self.startButton = javax.swing.JButton("Start")
|
|
self.startButton.setEnabled(False) # button starts as grayed out (disabled)
|
|
self.startButton.actionPerformed = self.whenStartButtonClicked
|
|
|
|
self.stopButton = javax.swing.JButton("Stop")
|
|
self.stopButton.setEnabled(False) # button starts as grayed out (disabled)
|
|
self.stopButton.setToolTipText("Stops the run - there is a delay as the loco slows")
|
|
self.stopButton.actionPerformed = self.whenStopButtonClicked
|
|
|
|
self.haltButton = javax.swing.JButton("Halt")
|
|
self.haltButton.setEnabled(False) # button starts as grayed out (disabled)
|
|
self.haltButton.setToolTipText("Emergency halt the run - should be an abrupt stop")
|
|
self.haltButton.actionPerformed = self.whenHaltButtonClicked
|
|
|
|
self.shrinkButton = javax.swing.JButton("Shrink")
|
|
self.shrinkButton.setEnabled(True)
|
|
self.shrinkButton.setToolTipText("Shrink/Grow the window")
|
|
self.shrinkButton.actionPerformed = self.whenShrinkButtonClicked
|
|
|
|
self.testButton = javax.swing.JButton("Test")
|
|
self.testButton.setEnabled(True) # button starts as grayed out (disabled)
|
|
self.testButton.setToolTipText("run the didWeMove test")
|
|
self.testButton.actionPerformed = self.callBackForDidWeMove
|
|
|
|
self.saveToRosterButton = javax.swing.JButton("Save Settings")
|
|
self.saveToRosterButton.setEnabled(True)
|
|
self.saveToRosterButton.setToolTipText("Saves setting in roster, if found.")
|
|
self.saveToRosterButton.actionPerformed = self.whenSaveToRosterButtonClicked
|
|
|
|
# address of the loco
|
|
self.locoAddress = javax.swing.JTextField(5) # sized to hold 5 characters, initially empty
|
|
self.locoAddress.actionPerformed = self.whenLocoChanged # if user hit return or enter
|
|
self.locoAddress.focusLost = self.whenLocoChanged # if user tabs away
|
|
self.locoAddress.requestFocusInWindow()
|
|
|
|
# long/short address flag
|
|
self.locoLong = javax.swing.JCheckBox()
|
|
self.locoLong.setToolTipText("Check to use long address")
|
|
self.locoLong.setSelected(True)
|
|
if (self.throttleManager.addressTypeUnique() == True) :
|
|
self.locoLong.setEnabled(False)
|
|
self.locoLong.actionPerformed = self.whenLocoChanged
|
|
self.locoLong.focusLost = self.whenLocoChanged
|
|
|
|
# loco direction flag
|
|
self.locoForward = javax.swing.JCheckBox()
|
|
self.locoForward.setToolTipText("Sets forward loco direction")
|
|
self.locoForward.setSelected(True)
|
|
self.locoForward.actionPerformed = self.whenLocoDirectionButtonClicked
|
|
self.locoForward.focusLost = self.whenLocoDirectionButtonClicked
|
|
|
|
# loco headlight flag
|
|
self.locoHeadlight = javax.swing.JCheckBox()
|
|
self.locoHeadlight.setToolTipText("Controls loco hightlight")
|
|
self.locoHeadlight.actionPerformed = self.whenLocoHeadlight
|
|
self.locoHeadlight.focusLost = self.whenLocoHeadlight
|
|
|
|
# loco bell flag
|
|
self.locoBell = javax.swing.JCheckBox()
|
|
self.locoBell.setToolTipText("Controls loco bell")
|
|
self.locoBell.actionPerformed = self.whenLocoBell
|
|
self.locoBell.focusLost = self.whenLocoBell
|
|
|
|
# loco horn/whistle flag
|
|
self.locoHorn = javax.swing.JButton("Horn")
|
|
self.locoHorn.setToolTipText("Controls loco horn")
|
|
self.locoHorn.mousePressed = self.whenLocoHornOn
|
|
self.locoHorn.mouseReleased = self.whenLocoHornOff
|
|
|
|
# loco move buttons
|
|
self.locoMoveGreen = javax.swing.JButton("Move @ Clear")
|
|
self.locoMoveGreen.setToolTipText("Moves loco at Clear speed")
|
|
self.locoMoveGreen.mousePressed = self.whenLocoMoveOnGreen
|
|
self.locoMoveGreen.mouseReleased = self.whenLocoMoveOff
|
|
self.locoMoveYellow = javax.swing.JButton("Move @ Limited")
|
|
self.locoMoveYellow.setToolTipText("Moves loco at Limited speed")
|
|
self.locoMoveYellow.mousePressed = self.whenLocoMoveOnYellow
|
|
self.locoMoveYellow.mouseReleased = self.whenLocoMoveOff
|
|
self.locoMoveRed = javax.swing.JButton("Move @ Restricted")
|
|
self.locoMoveRed.setToolTipText("Moves loco at Restricted speed")
|
|
self.locoMoveRed.mousePressed = self.whenLocoMoveOnRed
|
|
self.locoMoveRed.mouseReleased = self.whenLocoMoveOff
|
|
|
|
# create the speed fields for a Green Flash Signal
|
|
self.locoSpeedGreenFlash = javax.swing.JTextField(sizeSpeedField) # sized to hold 5 characters
|
|
self.locoSpeedGreenFlash.setToolTipText("Green Flash Speed is a number from 1 to 100%")
|
|
self.locoSpeedGreenFlash.actionPerformed = self.whenSpeedFieldChanged
|
|
self.locoSpeedGreenFlash.focusLost = self.whenSpeedFieldChanged
|
|
self.locoSpeedGreenFlash.text = "70"
|
|
self.locoSpeedGreenFlash.setName("locoSpeedGreenFlash")
|
|
|
|
# create the physical speed field for a Green Flash Signal
|
|
self.locoRateGreenFlash = javax.swing.JTextField(sizeRateField) # sized to hold 5 characters
|
|
self.locoRateGreenFlash.setToolTipText("Throttle as Distance/Second, approaching green flash signal")
|
|
self.locoRateGreenFlash.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoRateGreenFlash.focusLost = self.whenDistanceFieldChanged
|
|
self.locoRateGreenFlash.text = "0"
|
|
self.locoRateGreenFlash.setName("locoRateGreenFlash")
|
|
|
|
# create the distance field for a Green Flash Signal
|
|
self.locoDistGreenFlash = javax.swing.JTextField(5) # sized to hold 5 characters
|
|
self.locoDistGreenFlash.setToolTipText("Distance to Green Speed from Green Flash signal speed, inches")
|
|
self.locoDistGreenFlash.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoDistGreenFlash.focusLost = self.whenDistanceFieldChanged
|
|
self.locoDistGreenFlash.text = "6"
|
|
self.locoDistGreenFlash.setName("locoDistGreenFlash")
|
|
|
|
# create the speed fields for a Green Signal
|
|
self.locoSpeedGreen = javax.swing.JTextField(sizeSpeedField) # sized to hold 5 characters
|
|
self.locoSpeedGreen.setToolTipText("Green Speed is a number from 1 to 100%")
|
|
self.locoSpeedGreen.actionPerformed = self.whenSpeedFieldChanged
|
|
self.locoSpeedGreen.focusLost = self.whenSpeedFieldChanged
|
|
self.locoSpeedGreen.text = "45"
|
|
self.locoSpeedGreen.setName("locoSpeedGreen")
|
|
|
|
# create the physical speed field for a Green Signal
|
|
self.locoRateGreen = javax.swing.JTextField(sizeRateField) # sized to hold 5 characters
|
|
self.locoRateGreen.setToolTipText("Throttle as Distance/Second, approaching Green signal")
|
|
self.locoRateGreen.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoRateGreen.focusLost = self.whenDistanceFieldChanged
|
|
self.locoRateGreen.text = "9"
|
|
self.locoRateGreen.setName("locoRateGreen")
|
|
|
|
# create the distance field for a Green Signal
|
|
self.locoDistGreen = javax.swing.JTextField(5) # sized to hold 5 characters
|
|
self.locoDistGreen.setToolTipText("Distance to Yellow Flash Speed from Green signal speed, inches")
|
|
self.locoDistGreen.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoDistGreen.focusLost = self.whenDistanceFieldChanged
|
|
self.locoDistGreen.text = "6"
|
|
self.locoDistGreen.setName("locoDistGreen")
|
|
|
|
# create the speed fields for a Yellow Flash Signal
|
|
self.locoSpeedYellowFlash = javax.swing.JTextField(sizeSpeedField) # sized to hold 5 characters
|
|
self.locoSpeedYellowFlash.setToolTipText("Yellow Flash Speed is a number from 1 to 100%")
|
|
self.locoSpeedYellowFlash.actionPerformed = self.whenSpeedFieldChanged
|
|
self.locoSpeedYellowFlash.focusLost = self.whenSpeedFieldChanged
|
|
self.locoSpeedYellowFlash.text = "45"
|
|
self.locoSpeedYellowFlash.setName("locoSpeedYellowFlash")
|
|
|
|
# create the physical speed field for a Yellow Flash Signal
|
|
self.locoRateYellowFlash = javax.swing.JTextField(sizeRateField) # sized to hold 5 characters
|
|
self.locoRateYellowFlash.setToolTipText("Throttle as Distance/Second, approaching yello flash signal")
|
|
self.locoRateYellowFlash.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoRateYellowFlash.focusLost = self.whenDistanceFieldChanged
|
|
self.locoRateYellowFlash.text = "0"
|
|
self.locoRateYellowFlash.setName("locoRateYellowFlash")
|
|
|
|
# create the distance field for a Yellow Flash Signal
|
|
self.locoDistYellowFlash = javax.swing.JTextField(5) # sized to hold 5 characters
|
|
self.locoDistYellowFlash.setToolTipText("Distance to Yellow Speed from Yellow Flash signal speed, inches")
|
|
self.locoDistYellowFlash.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoDistYellowFlash.focusLost = self.whenDistanceFieldChanged
|
|
self.locoDistYellowFlash.text = "6"
|
|
self.locoDistYellowFlash.setName("locoDistYellowFlash")
|
|
|
|
# create the speed fields for a Yellow Signal
|
|
self.locoSpeedYellow = javax.swing.JTextField(sizeSpeedField) # sized to hold 5 characters
|
|
self.locoSpeedYellow.setToolTipText("Yellow Speed is a number from 1 to 100%")
|
|
self.locoSpeedYellow.actionPerformed = self.whenSpeedFieldChanged
|
|
self.locoSpeedYellow.focusLost = self.whenSpeedFieldChanged
|
|
self.locoSpeedYellow.text = "30"
|
|
self.locoSpeedYellow.setName("locoSpeedYellow")
|
|
|
|
# create the physical speed field for a Yellow Signal
|
|
self.locoRateYellow = javax.swing.JTextField(sizeRateField) # sized to hold 5 characters
|
|
self.locoRateYellow.setToolTipText("Throttle as Distance/Second, approaching yellow signal")
|
|
self.locoRateYellow.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoRateYellow.focusLost = self.whenDistanceFieldChanged
|
|
self.locoRateYellow.text = "6"
|
|
self.locoRateYellow.setName("locoRateYellow")
|
|
|
|
# create the distance field for a Yellow Signal
|
|
self.locoDistYellow = javax.swing.JTextField(5) # sized to hold 5 characters
|
|
self.locoDistYellow.setToolTipText("Distance to Red Flash Speed from Yellow signal speed, inches")
|
|
self.locoDistYellow.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoDistYellow.focusLost = self.whenDistanceFieldChanged
|
|
self.locoDistYellow.text = "6"
|
|
self.locoDistYellow.setName("locoDistYellow")
|
|
|
|
# create the speed fields for a Red Flash Signal
|
|
self.locoSpeedRedFlash = javax.swing.JTextField(sizeSpeedField) # sized to hold 5 characters
|
|
self.locoSpeedRedFlash.setToolTipText("Red Flash Speed is a number from 1 to 100%")
|
|
self.locoSpeedRedFlash.actionPerformed = self.whenSpeedFieldChanged
|
|
self.locoSpeedRedFlash.focusLost = self.whenSpeedFieldChanged
|
|
self.locoSpeedRedFlash.text = "20"
|
|
self.locoSpeedRedFlash.setName("locoSpeedRedFlash")
|
|
|
|
# create the physical speed field for a Red Flash Signal
|
|
self.locoRateRedFlash = javax.swing.JTextField(sizeRateField) # sized to hold 5 characters
|
|
self.locoRateRedFlash.setToolTipText("Throttle as Distance/Second, approaching red flash signal")
|
|
self.locoRateRedFlash.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoRateRedFlash.focusLost = self.whenDistanceFieldChanged
|
|
self.locoRateRedFlash.text = "0"
|
|
self.locoRateRedFlash.setName("locoRateRedFlash")
|
|
|
|
# create the distance field for a Red Flash Signal
|
|
self.locoDistRedFlash = javax.swing.JTextField(5) # sized to hold 5 characters
|
|
self.locoDistRedFlash.setToolTipText("Distance to Red Speed from Red Flash signal speed, inches")
|
|
self.locoDistRedFlash.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoDistRedFlash.focusLost = self.whenDistanceFieldChanged
|
|
self.locoDistRedFlash.text = "0"
|
|
self.locoDistRedFlash.setName("locoDistRedFlash")
|
|
|
|
# create the speed fields for a Red Signal
|
|
self.locoSpeedRed = javax.swing.JTextField(sizeSpeedField) # sized to hold 5 characters
|
|
self.locoSpeedRed.setToolTipText("Red Speed is a number from 1 to 100%, creep to Red Signal")
|
|
self.locoSpeedRed.actionPerformed = self.whenSpeedFieldChanged
|
|
self.locoSpeedRed.focusLost = self.whenSpeedFieldChanged
|
|
self.locoSpeedRed.text = "15"
|
|
self.locoSpeedRed.setName("locoSpeedRed")
|
|
|
|
# create the physical speed field for a Red Signal
|
|
self.locoRateRed = javax.swing.JTextField(sizeRateField) # sized to hold 5 characters
|
|
self.locoRateRed.setToolTipText("Throttle as Distance/Second, approaching red signal")
|
|
self.locoRateRed.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoRateRed.focusLost = self.whenDistanceFieldChanged
|
|
self.locoRateRed.text = "3"
|
|
self.locoRateRed.setName("locoRateRed")
|
|
|
|
# create the distance field for a Red Signal
|
|
self.locoDistRed = javax.swing.JTextField(5) # sized to hold 5 characters
|
|
self.locoDistRed.setToolTipText("Distance to stop from Red signal speed, inches")
|
|
self.locoDistRed.actionPerformed = self.whenDistanceFieldChanged
|
|
self.locoDistRed.focusLost = self.whenDistanceFieldChanged
|
|
self.locoDistRed.text = "10"
|
|
self.locoDistRed.setName("locoDistRed")
|
|
|
|
# create current speed display
|
|
self.locoSpeed = javax.swing.JLabel()
|
|
self.locoSpeed.text = "0"
|
|
|
|
# create the starting block field
|
|
self.blockStart = javax.swing.JTextField(10)
|
|
self.blockStart.setToolTipText("Starting Block Name")
|
|
self.blockStart.actionPerformed = self.whenLocoChanged
|
|
self.blockStart.focusLost = self.whenLocoChanged
|
|
self.blockStart.setName("blockStart")
|
|
|
|
# create the starting block direction
|
|
self.blockDirection = javax.swing.JCheckBox()
|
|
self.blockDirection.setToolTipText("Starting Block Direction")
|
|
self.blockDirection.actionPerformed = self.whenBlockDirectionButtonClicked
|
|
self.blockDirection.focusLost = self.whenBlockDirectionButtonClicked
|
|
self.blockDirection.setSelected(True)
|
|
|
|
# create flag for looking any extra block ahead
|
|
self.blockAhead2 = javax.swing.JCheckBox()
|
|
self.blockAhead2.setSelected(False)
|
|
self.blockAhead2.setToolTipText("for 4 block mode")
|
|
|
|
# create flag for enable lookahead stopping
|
|
self.useStopFromDistance = javax.swing.JCheckBox()
|
|
self.useStopFromDistance.setSelected(False)
|
|
self.useStopFromDistance.setToolTipText("reduce current signal viewed due to distant stop")
|
|
|
|
# create the stopping block field
|
|
self.blockStop = javax.swing.JTextField(10)
|
|
self.blockStop.setToolTipText("Stopping Block Name")
|
|
self.blockStop.actionPerformed = self.whenStopBlockChanged
|
|
self.blockStop.focusLost = self.whenStopBlockChanged
|
|
|
|
# create the current block field
|
|
self.blockNow = javax.swing.JLabel()
|
|
self.blockNowLength = javax.swing.JLabel()
|
|
|
|
# create the current/next signal field
|
|
self.signalNext = javax.swing.JLabel()
|
|
self.signalNextText = javax.swing.JLabel()
|
|
|
|
# create the next block field
|
|
self.blockNext = javax.swing.JLabel()
|
|
self.blockNextLength = javax.swing.JLabel()
|
|
|
|
# create the next/beyond signal field
|
|
self.signalBeyond = javax.swing.JLabel()
|
|
self.signalBeyondText = javax.swing.JLabel()
|
|
|
|
# create the beyond block field
|
|
self.blockBeyond = javax.swing.JLabel()
|
|
self.blockBeyondLength = javax.swing.JLabel()
|
|
|
|
# create the stop distance field
|
|
self.stopDistance = javax.swing.JLabel()
|
|
self.stopDistanceForSpeed = javax.swing.JLabel()
|
|
|
|
# load from roster flag
|
|
self.loadFromRoster = javax.swing.JCheckBox()
|
|
self.loadFromRoster.setToolTipText("Load settings from roster entry if found.")
|
|
self.loadFromRoster.setSelected(True)
|
|
|
|
# auto-scroll message window flag
|
|
self.autoScroll = javax.swing.JCheckBox()
|
|
self.autoScroll.setToolTipText("Sets message window to auto-scroll")
|
|
self.autoScroll.setSelected(True)
|
|
|
|
# time stamp message window flag
|
|
self.scrollTimeStamp = javax.swing.JCheckBox()
|
|
self.scrollTimeStamp.setToolTipText("Insert time stamp on message window")
|
|
self.scrollTimeStamp.setSelected(True)
|
|
|
|
# create a text area
|
|
self.scrollArea = javax.swing.JTextArea(15, 70) # define a text area with it's size
|
|
if (self.debugLevel >= LowDebug) :
|
|
self.msgText("Enter the loco number, direction and addr mode")
|
|
self.msgText("Set min and max speed")
|
|
self.msgText("Enter block name loco is in")
|
|
srcollField = javax.swing.JScrollPane(self.scrollArea) # put text area in scroll field
|
|
|
|
# create a frame to hold the buttons and fields
|
|
# also create a window listener. This is used mainly to remove the property change listener
|
|
# when the window is closed by clicking on the window close button
|
|
w = self.WinListener()
|
|
self.scriptFrame = javax.swing.JFrame("Run Loco") # argument is the frames title
|
|
self.scriptFrame.contentPane.setLayout(javax.swing.BoxLayout(self.scriptFrame.contentPane, javax.swing.BoxLayout.Y_AXIS))
|
|
self.scriptFrame.addWindowListener(w)
|
|
w.setCallBack(self.scriptFrame, self.releaseAllListeners)
|
|
# put the text field on a line preceded by a label
|
|
temppanel1 = javax.swing.JPanel()
|
|
temppanel1.add(javax.swing.JLabel("Loco Address:"))
|
|
temppanel1.add(self.locoAddress)
|
|
temppanel1.add(javax.swing.JLabel(" LongAddr?"))
|
|
temppanel1.add(self.locoLong)
|
|
temppanel1.add(javax.swing.JLabel(" Forward?"))
|
|
temppanel1.add(self.locoForward)
|
|
|
|
temppanel1a = javax.swing.JPanel()
|
|
temppanel1a.add(javax.swing.JLabel("Headlight:"))
|
|
temppanel1a.add(self.locoHeadlight)
|
|
temppanel1a.add(javax.swing.JLabel("Bell:"))
|
|
temppanel1a.add(self.locoBell)
|
|
temppanel1a.add(self.locoHorn)
|
|
temppanel1a.add(self.locoMoveGreen)
|
|
temppanel1a.add(self.locoMoveYellow)
|
|
temppanel1a.add(self.locoMoveRed)
|
|
|
|
# build speed table
|
|
gLayout = java.awt.GridBagLayout()
|
|
gConstraints = java.awt.GridBagConstraints()
|
|
self.speedPane = javax.swing.JPanel()
|
|
pane2Border = javax.swing.BorderFactory.createEtchedBorder()
|
|
pane2Titled = javax.swing.BorderFactory.createTitledBorder(pane2Border, "Speed Settings")
|
|
self.speedPane.setBorder(pane2Titled)
|
|
self.speedPane.setLayout(gLayout)
|
|
gConstraints.gridx = 0
|
|
gConstraints.gridy = 0
|
|
gConstraints.gridwidth = 1
|
|
gConstraints.gridheight = 1
|
|
gConstraints.ipadx = 12
|
|
gConstraints.ipady = 3
|
|
gConstraints.insets = java.awt.Insets(3, 3, 3, 3)
|
|
|
|
self.speedPane.add(javax.swing.JLabel("locoDistRed"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("Throttle"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel(" "), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("Inch/Sec"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("Speed Chg Distance"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
|
|
self.speedPane.add(javax.swing.JLabel(" "), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("Indication"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx+ 1
|
|
self.speedPane.add(javax.swing.JLabel("Throttle"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel(" "), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("Inch/Sec"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("Speed Chg Distance"), gConstraints)
|
|
gConstraints.gridx = 0
|
|
gConstraints.gridy = gConstraints.gridy + 1
|
|
|
|
self.speedPane.add(javax.swing.JLabel(self.greenFlashSignalIcon), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoSpeedGreenFlash, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("%"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx+ 1
|
|
self.speedPane.add(self.locoRateGreenFlash, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx+ 1
|
|
self.speedPane.add(self.locoDistGreenFlash, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx+ 1
|
|
|
|
self.speedPane.add(javax.swing.JLabel(" "), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel(self.greenSignalIcon), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoSpeedGreen, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("%"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx+ 1
|
|
self.speedPane.add(self.locoRateGreen, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx+ 1
|
|
self.speedPane.add(self.locoDistGreen, gConstraints)
|
|
gConstraints.gridx = 0
|
|
gConstraints.gridy = gConstraints.gridy + 1
|
|
|
|
self.speedPane.add(javax.swing.JLabel(self.yellowFlashSignalIcon), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoSpeedYellowFlash, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("%"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoRateYellowFlash, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoDistYellowFlash, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx+ 1
|
|
|
|
self.speedPane.add(javax.swing.JLabel(" "), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel(self.yellowSignalIcon), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoSpeedYellow, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("%"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoRateYellow, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx+ 1
|
|
self.speedPane.add(self.locoDistYellow, gConstraints)
|
|
gConstraints.gridx = 0
|
|
gConstraints.gridy = gConstraints.gridy + 1
|
|
|
|
self.speedPane.add(javax.swing.JLabel(self.redFlashSignalIcon), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoSpeedRedFlash, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("%"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoRateRedFlash, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoDistRedFlash, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx+ 1
|
|
|
|
self.speedPane.add(javax.swing.JLabel(" "), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel(self.redSignalIcon), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoSpeedRed, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(javax.swing.JLabel("%"), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.locoRateRed, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx+ 1
|
|
self.speedPane.add(self.locoDistRed, gConstraints)
|
|
gConstraints.gridx = 0
|
|
gConstraints.gridy = gConstraints.gridy + 1
|
|
|
|
self.speedPane.add(javax.swing.JLabel("Load From Roster: "), gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.loadFromRoster, gConstraints)
|
|
gConstraints.gridx = gConstraints.gridx + 1
|
|
self.speedPane.add(self.saveToRosterButton, gConstraints)
|
|
|
|
# build block info
|
|
temppanel3 = javax.swing.JPanel()
|
|
temppanel3.add(javax.swing.JLabel("Block Starting: "))
|
|
temppanel3.add(self.blockStart)
|
|
temppanel3.add(javax.swing.JLabel(" Eastbound: "))
|
|
temppanel3.add(self.blockDirection)
|
|
temppanel3.add(javax.swing.JLabel(" Check block ahead: "))
|
|
temppanel3.add(self.blockAhead2)
|
|
temppanel3.add(javax.swing.JLabel(" Lookahead for Stop: "))
|
|
temppanel3.add(self.useStopFromDistance)
|
|
temppanel3.add(javax.swing.JLabel(" Stopping Block: "))
|
|
temppanel3.add(self.blockStop)
|
|
temppanel3.add(javax.swing.JLabel(" AutoScroll Messages: "))
|
|
temppanel3.add(self.autoScroll)
|
|
temppanel3.add(javax.swing.JLabel(" Time Stamp Messages: "))
|
|
temppanel3.add(self.scrollTimeStamp)
|
|
|
|
temppanel4 = javax.swing.JPanel()
|
|
temppanel4.add(javax.swing.JLabel("Speed: "), gConstraints)
|
|
temppanel4.add(self.locoSpeed, gConstraints)
|
|
temppanel4.add(javax.swing.JLabel("% "), gConstraints)
|
|
temppanel4.add(javax.swing.JLabel(" Now:"))
|
|
temppanel4.add(self.blockNow)
|
|
temppanel4.add(javax.swing.JLabel(" "))
|
|
temppanel4.add(self.signalNext)
|
|
temppanel4.add(self.signalNextText)
|
|
temppanel4.add(javax.swing.JLabel(" "))
|
|
temppanel4.add(self.blockNowLength)
|
|
temppanel4.add(javax.swing.JLabel("in Next:"))
|
|
temppanel4.add(self.blockNext)
|
|
temppanel4.add(javax.swing.JLabel(" "))
|
|
temppanel4.add(self.signalBeyond)
|
|
temppanel4.add(self.signalBeyondText)
|
|
temppanel4.add(javax.swing.JLabel(" "))
|
|
temppanel4.add(self.blockNextLength)
|
|
temppanel4.add(javax.swing.JLabel("in Beyond:"))
|
|
temppanel4.add(self.blockBeyond)
|
|
temppanel4.add(javax.swing.JLabel(" "))
|
|
temppanel4.add(self.blockBeyondLength)
|
|
temppanel4.add(javax.swing.JLabel(" in "))
|
|
temppanel4.add(javax.swing.JLabel("Min Stop Dist: "))
|
|
temppanel4.add(self.stopDistance)
|
|
temppanel4.add(javax.swing.JLabel(" : "))
|
|
temppanel4.add(self.stopDistanceForSpeed)
|
|
|
|
self.greenFlashSignalIcon.setRotation(1, temppanel4)
|
|
self.greenSignalIcon.setRotation(1, temppanel4)
|
|
self.yellowFlashSignalIcon.setRotation(1, temppanel4)
|
|
self.yellowSignalIcon.setRotation(1, temppanel4)
|
|
self.redFlashSignalIcon.setRotation(1, temppanel4)
|
|
self.redSignalIcon.setRotation(1, temppanel4)
|
|
self.darkSignalIcon.setRotation(1, temppanel4)
|
|
|
|
butPanel = javax.swing.JPanel()
|
|
butPanel.add(self.startButton)
|
|
butPanel.add(self.stopButton)
|
|
butPanel.add(self.testButton)
|
|
butPanel.add(self.haltButton)
|
|
butPanel.add(self.shrinkButton)
|
|
|
|
# Put contents in frame and display
|
|
self.scriptFrame.contentPane.add(temppanel1)
|
|
self.scriptFrame.contentPane.add(temppanel1a)
|
|
self.scriptFrame.contentPane.add(self.speedPane)
|
|
self.scriptFrame.contentPane.add(temppanel3)
|
|
self.scriptFrame.contentPane.add(temppanel4)
|
|
self.scriptFrame.contentPane.add(srcollField)
|
|
self.scriptFrame.contentPane.add(butPanel)
|
|
self.scriptFrame.pack()
|
|
self.scriptFrame.show()
|
|
self.isAborting = False
|
|
return
|
|
|
|
def setLoco(self, locoId) :
|
|
self.methodLocoAddress = locoId
|
|
return
|
|
|
|
def setLocoEast(self) :
|
|
self.methodBlockDirection = True
|
|
return
|
|
|
|
def setLocoWest(self) :
|
|
self.methodBlockDirection = False
|
|
return
|
|
|
|
def setLocoForward(self) :
|
|
self.methodLocoForward = True
|
|
return
|
|
|
|
def setLocoReverse(self) :
|
|
self.methodLocoForward = False
|
|
return
|
|
|
|
def locoHeadlightOn(self) :
|
|
self.methodLocoHeadlight = True
|
|
return
|
|
|
|
def locoHeadlightOff(self) :
|
|
self.methodLocoHeadlight = False
|
|
return
|
|
|
|
def soundShortHorn(self) :
|
|
self.methodShortHorn = True
|
|
return
|
|
|
|
def soundLongHorn(self) :
|
|
self.methodLongHorn = True
|
|
return
|
|
|
|
def pushShrink(self) :
|
|
self.methodPushShrink = True
|
|
return
|
|
|
|
def setStartBlock(self, blockId) :
|
|
self.methodBlockStart = blockId
|
|
return
|
|
|
|
def pushStart(self) :
|
|
self.methodPushStart = True
|
|
return
|
|
|
|
def pushStop(self) :
|
|
self.methodPushStop = True
|
|
return
|
|
|
|
def pushTest(self) :
|
|
self.methodPushTest = True
|
|
return
|
|
|
|
def setStopBlock(self, blockId) :
|
|
self.methodBlockStop = blockId
|
|
return
|
|
|
|
def setStopDistance(self, dist) :
|
|
self.methodlocoDistRed = dist
|
|
return
|
|
|
|
def updateMemoryWithCurrentSpeed(self, memoryId) :
|
|
mem = jmri.InstanceManager.memoryManagerInstance().provideMemory(memoryId)
|
|
if (mem != None) :
|
|
if (self.currentThrottle != None) :
|
|
mem.setValue(str((int)(round(self.currentThrottle.getSpeedSetting() * 100, 0))))
|
|
else :
|
|
mem.setValue("0")
|
|
return
|
|
|
|
def returnCurrentSpeed(self) :
|
|
if (self.currentThrottle != None) :
|
|
v = str((int)(round(self.currentThrottle.getSpeedSetting() * 100, 0)))
|
|
else :
|
|
v = "0"
|
|
return(v)
|
|
|
|
def updateMemoryWithCurrentBlock(self, memoryId) :
|
|
mem = jmri.InstanceManager.memoryManagerInstance().provideMemory(memoryId)
|
|
if (mem != None) :
|
|
if (self.currentBlock != None) :
|
|
mem.setValue(self.giveBlockName(self.currentBlock))
|
|
else :
|
|
mem.setValue("")
|
|
return
|
|
|
|
def returnCurrentBlock(self) :
|
|
if (self.currentBlock != None) :
|
|
v = self.giveBlockName(self.currentBlock)
|
|
else :
|
|
v = ""
|
|
return(v)
|
|
|
|
def setDebugNone(self) :
|
|
self.debugLevel = NoneDebug
|
|
return()
|
|
|
|
def setDebugLow(self) :
|
|
self.debugLevel = LowDebug
|
|
return()
|
|
|
|
def setDebugMedium(self) :
|
|
self.debugLevel = MediumDebug
|
|
return()
|
|
|
|
def setDebugHigh(self) :
|
|
self.debugLevel = HighDebug
|
|
return()
|
|
|
|
# if you are running the RobotThrottle completely interactive,
|
|
# the following two lines are all you need
|
|
rb1 = LocoThrot()
|
|
rb1.start()
|
|
#rb1.setSignalAppearanceHalt(GREEN)
|
|
# However, if you are automating the automation, then
|
|
## Options for doing more via scripts or Logix Jython command line option
|
|
## this will set the loco number, if a matching roster entry is found, it will load the values
|
|
## rb1.setLoco("111")
|
|
## rb1.setLocoEast()
|
|
## rb1.setLocoWest()
|
|
## rb1.locoHeadlightOn()
|
|
## rb1.locoHeadlightOff()
|
|
## rb1.soundShortHorn()
|
|
## rb1.soundLongHorn()
|
|
## this will set the starting block
|
|
## rb1.setStartBlock("LB25")
|
|
## this will enable the loco to move according to the signals
|
|
## rb1.pushStart()
|
|
## rb1.pushStop()
|
|
## this sets a block to stop at
|
|
## rb1.setStopBlock("LB27")
|
|
## shrink the display size
|
|
## rb1.pushShrink()
|
|
## turn off all debug messages
|
|
## rb1.setDebugNone()
|
|
## turn on all debug messages
|
|
## rb1.setDebugHigh()
|
|
|