# # Use a USB device as a throttle # # Author: Lionel Jeanson, adapted from Bob Jacobsen, copyright 2008/2009 # # Part of the JMRI distribution # # The list of available devices is accessible by right clicking on the Jysntrument icon once started. # # You want to have a look at the driver file this script will look for you hardware # If required; copy default.py to XYZ.py where XYZ is from the line "Driver "XYZ" not found, loading default one" from the trace # Then customize your XYZ.py to match your device layout # Use JMRI Debug->USB Input Control to check each device component name and possible values # # The customizable part bellow are the throttles calls # import sys import thread import java import java.awt import java.awt.event import jmri import java.util.Calendar as Calendar import javax.swing.ImageIcon as ImageIcon import javax.swing.JButton as JButton import javax.swing.JCheckBoxMenuItem as JCheckBoxMenuItem import java.util.TimerTask as TimerTask import java.util.Timer as Timer import jmri.jmrit.jython.Jynstrument as Jynstrument import jmri.util.ThreadingUtil as ThreadingUtil import org.jdom2.Element as Element import java.beans.PropertyChangeListener as PropertyChangeListener # Some default speeds that will be used in the program speedMaxSpeed = 1 speedCruiseSpeed = 0.8 # this one is customizable speedSlowSpeed = 0.3 # that one too speedStopSpeed = 0 EStopSpeed = -1 # Some constants used by the program valueSpeedTimerRepeat = 100 # repeat time in ms for speed set task valueSpeedDivider = 15 # a divider for the value given by the pad, then used to increment speed delay4doubleTap = 250 # max delay in ms for double tap => EStop (on 2xStop button) and MaxSpeed (on 2xCruise button) class USBThrottle(Jynstrument, PropertyChangeListener): #Property listener part: USB value def propertyChange(self, event): # Customize bellow for throttles calls: if (event.propertyName == "Value") : # USB if (event.oldValue.getController() == self.desiredController ) : # print "Value change event from controller "+event.toString() component = event.oldValue.getComponent().toString() value = event.newValue throttle = None roster = None if (self.getContext().getCurentThrottleController() != None) : throttle = self.getContext().getCurentThrottleController().getThrottle() fnThrottle = self.getContext().getCurentThrottleController().getFunctionThrottle() roster = self.getContext().getCurentThrottleController().getFunctionRosterEntry() else: return # no throttle, no control, exit # Uncomment bellow line to see component name and its value # print "Component \""+component+"\" value changed to ",value try: # Change current ThrottleFrame if ((component == self.driver.componentNextThrottleFrame) and (value == self.driver.valueNextThrottleFrame)) : #NEXT ThreadingUtil.runOnGUI(lambda : self.getContext().nextThrottleFrame() ) if ((component == self.driver.componentPreviousThrottleFrame) and (value == self.driver.valuePreviousThrottleFrame)) : #PREVIOUS ThreadingUtil.runOnGUI(lambda : self.getContext().previousThrottleFrame() ) if ((component == self.driver.componentNextRunningThrottleFrame) and (value == self.driver.valueNextRunningThrottleFrame)) : #NEXT RUNNING ThreadingUtil.runOnGUI(lambda : self.getContext().nextRunningThrottleFrame() ) if ((component == self.driver.componentPreviousRunningThrottleFrame) and (value == self.driver.valuePreviousRunningThrottleFrame)) : #PREVIOUS RUNNING ThreadingUtil.runOnGUI(lambda : self.getContext().previousRunningThrottleFrame() ) except AttributeError: pass if (throttle == None): try: # Browse through roster if ((component == self.driver.componentNextRosterBrowse) and (value == self.driver.valueNextRoster)): #NEXT ThreadingUtil.runOnGUI(lambda : self.getContext().getCurentThrottleController().getRosterEntrySelector().setRosterListSelectedIndex(self.getContext().getCurentThrottleController().getRosterEntrySelector().getRosterListSelectedIndex() + 1) ) if ((component == self.driver.componentPreviousRosterBrowse) and (value == self.driver.valuePreviousRoster)) : #PREVIOUS ThreadingUtil.runOnGUI(lambda : self.getContext().getCurentThrottleController().getRosterEntrySelector().setRosterListSelectedIndex(self.getContext().getCurentThrottleController().getRosterEntrySelector().getRosterListSelectedIndex() - 1) ) except AttributeError: pass try: # Request a throttle if ((component == self.driver.componentRosterSelect) and (value == self.driver.valueRosterSelect)): ThreadingUtil.runOnGUI(lambda : self.getContext().getCurentThrottleController().getRosterEntrySelector().setSelectedRosterEntry() ) except AttributeError: pass # From there; current throttle control, hence require a throttle if (throttle != None) : # Release current throttle try: if ((component == self.driver.componentThrottleRelease) and (value == self.driver.valueThrottleRelease)): ThreadingUtil.runOnGUI(lambda : self.getContext().getCurentThrottleController().dispatchAddress() ) except AttributeError: pass try: # Speed - dynamic controler (joystick going back to neutral position) self.speedTimerTask.setThrottle( throttle ) if ((component == self.driver.componentSpeedIncrease) or (component == self.driver.componentSpeedDecrease) or (component == self.driver.componentSpeed)): if ((component == self.driver.componentSpeedIncrease) and (value == self.driver.valueSpeedIncrease)) : self.speedTimerTask.setSpeedIncrement( 0.03 ) if ((component == self.driver.componentSpeedDecrease) and (value == self.driver.valueSpeedDecrease)) : self.speedTimerTask.setSpeedIncrement( -0.03 ) if (component == self.driver.componentSpeed) : try: self.vsd = valueSpeedDivider * self.driver.componentSpeedMultiplier except AttributeError: self.vsd = valueSpeedDivider self.speedTimerTask.setSpeedIncrement(value / self.vsd) if ( abs(value) > self.driver.valueSpeedTrigger ) : self.speedTimerTask.resume() else : self.speedTimerTask.pause() except AttributeError: self.speedTimerTask.pause() # just in case, stop it, really should never get there # try: # # Speed v2 - static controler (lever on RailDriver or AAR105) # if (component == self.driver.componentSpeedSet): # setSpeed = value * self.driver.componentValueSpeedMaxForward * self.driver.componentSpeedMaxForward # if ((setSpeed > 0) and (self.isReversed)) : # it was previously going backward # throttle.setIsForward(not throttle.getIsForward()) # self.isReversed = False # if (setSpeed == -0) : setSpeed = 0 # avoid neg 0 # if (setSpeed < 0): # going backward # setSpeed = value * self.driver.componentValueSpeedMaxReverse * self.driver.componentSpeedMaxReverse # if (not self.isReversed): # going backward for the first time # throttle.setIsForward(not throttle.getIsForward()) # self.isReversed = True # throttle.setSpeedSetting(setSpeed) # except AttributeError: # pass # Direction try: if ((component == self.driver.componentDirectionForward) and (value == self.driver.valueDirectionForward)) : throttle.setIsForward(True) if ((component == self.driver.componentDirectionBackward) and (value == self.driver.valueDirectionBackward)) : throttle.setIsForward(False) except AttributeError: pass try: if ((component == self.driver.componentDirectionSwitch) and (value == self.driver.valueDirectionSwitch)) : throttle.setIsForward(not throttle.getIsForward()) except AttributeError: pass # Speed presets try: # STOP if ((component == self.driver.componentStopSpeed) and (value == self.driver.valueStopSpeed)) : if ( Calendar.getInstance().getTimeInMillis() - self.lastTimeStopButton < delay4doubleTap ) : throttle.setSpeedSetting(EStopSpeed) # EStop on double tap else: throttle.setSpeedSetting(speedStopSpeed) self.lastTimeStopButton = Calendar.getInstance().getTimeInMillis() except AttributeError: pass try: # EStop if ((component == self.driver.componentEStopSpeed) and (value == self.driver.valueEStopSpeed)): throttle.setSpeedSetting(EStopSpeed) except AttributeError: pass try: # EStop if ((component == self.driver.componentEStopSpeedBis) and (value == self.driver.valueEStopSpeedBis)): throttle.setSpeedSetting(EStopSpeed) except AttributeError: pass try: # SLOW if ((component == self.driver.componentSlowSpeed) and (value == self.driver.valueSlowSpeed)) : throttle.setSpeedSetting(speedSlowSpeed) except AttributeError: pass try: # CRUISE if ((component == self.driver.componentCruiseSpeed) and (value == self.driver.valueCruiseSpeed)) : if ( Calendar.getInstance().getTimeInMillis() - self.lastTimeCruiseButton < delay4doubleTap ) : # EStop on double tap throttle.setSpeedSetting(speedMaxSpeed) # Max speed on double tap else: if (self.driver.cruiseSpeed == None) : throttle.setSpeedSetting(speedCruiseSpeed) else: throttle.setSpeedSetting(self.driver.cruiseSpeed) self.lastTimeCruiseButton = Calendar.getInstance().getTimeInMillis() except AttributeError: pass try: # MAX if ((component == self.driver.componentMaxSpeed) and (value == self.driver.valueMaxSpeed)) : throttle.setSpeedSetting(speedMaxSpeed) except AttributeError: pass # Functions if (fnThrottle == None): fnThrottle = throttle # print "Using ",fnThrottle.getLocoAddress()," for functions" try: if ((component == self.driver.componentF0) and (value == self.driver.valueF0)) : fnThrottle.setF0( not fnThrottle.getF0() ) if ((roster != None) and (not roster.getFunctionLockable(0)) and (component == self.driver.componentF0) and (value == self.driver.valueF0Off)) : fnThrottle.setF0( not fnThrottle.getF0() ) except AttributeError: pass try: if ((component == self.driver.componentF1) and (value == self.driver.valueF1)) : fnThrottle.setF1( not fnThrottle.getF1() ) if ((roster != None) and (not roster.getFunctionLockable(1)) and (component == self.driver.componentF1) and (value == self.driver.valueF1Off)) : fnThrottle.setF1( not fnThrottle.getF1() ) except AttributeError: pass try: if ((component == self.driver.componentF2) and (value == self.driver.valueF2)) : fnThrottle.setF2( not fnThrottle.getF2() ) if ((roster != None) and (not roster.getFunctionLockable(2)) and (component == self.driver.componentF2) and (value == self.driver.valueF2Off)) : fnThrottle.setF2( not fnThrottle.getF2() ) except AttributeError: pass try: if ((component == self.driver.componentF3) and (value == self.driver.valueF3)) : fnThrottle.setF3( not fnThrottle.getF3() ) if ((roster != None) and (not roster.getFunctionLockable(3)) and (component == self.driver.componentF3) and (value == self.driver.valueF3Off)) : fnThrottle.setF3( not fnThrottle.getF3() ) except AttributeError: pass try: if ((component == self.driver.componentF4) and (value == self.driver.valueF4)) : fnThrottle.setF4( not fnThrottle.getF4() ) if ((roster != None) and (not roster.getFunctionLockable(4)) and (component == self.driver.componentF4) and (value == self.driver.valueF4Off)) : fnThrottle.setF4( not fnThrottle.getF4() ) except AttributeError: pass try: if ((component == self.driver.componentF5) and (value == self.driver.valueF5)) : fnThrottle.setF5( not fnThrottle.getF5() ) if ((roster != None) and (not roster.getFunctionLockable(5)) and (component == self.driver.componentF5) and (value == self.driver.valueF5Off)) : fnThrottle.setF5( not fnThrottle.getF5() ) except AttributeError: pass try: if ((component == self.driver.componentF6) and (value == self.driver.valueF6)) : fnThrottle.setF6( not fnThrottle.getF6() ) if ((roster != None) and (not roster.getFunctionLockable(6)) and (component == self.driver.componentF6) and (value == self.driver.valueF6Off)) : fnThrottle.setF6( not fnThrottle.getF6() ) except AttributeError: pass try: if ((component == self.driver.componentF7) and (value == self.driver.valueF7)) : fnThrottle.setF7( not fnThrottle.getF7() ) if ((roster != None) and (not roster.getFunctionLockable(7)) and (component == self.driver.componentF7) and (value == self.driver.valueF7Off)) : fnThrottle.setF7( not fnThrottle.getF7() ) except AttributeError: pass try: if ((component == self.driver.componentF8) and (value == self.driver.valueF8)) : fnThrottle.setF8( not fnThrottle.getF8() ) if ((roster != None) and (not roster.getFunctionLockable(8)) and (component == self.driver.componentF8) and (value == self.driver.valueF8Off)) : fnThrottle.setF8( not fnThrottle.getF8() ) except AttributeError: pass try: if ((component == self.driver.componentF9) and (value == self.driver.valueF9)) : fnThrottle.setF9( not fnThrottle.getF9() ) if ((roster != None) and (not roster.getFunctionLockable(9)) and (component == self.driver.componentF9) and (value == self.driver.valueF9Off)) : fnThrottle.setF9( not fnThrottle.getF9() ) except AttributeError: pass try: if ((component == self.driver.componentF10) and (value == self.driver.valueF10)) : fnThrottle.setF10( not fnThrottle.getF10() ) if ((roster != None) and (not roster.getFunctionLockable(10)) and (component == self.driver.componentF10) and (value == self.driver.valueF10Off)) : fnThrottle.setF10( not fnThrottle.getF10() ) except AttributeError: pass try: if ((component == self.driver.componentF11) and (value == self.driver.valueF11)) : fnThrottle.setF11( not fnThrottle.getF11() ) if ((roster != None) and (not roster.getFunctionLockable(11)) and (component == self.driver.componentF11) and (value == self.driver.valueF11Off)) : fnThrottle.setF11( not fnThrottle.getF11() ) except AttributeError: pass try: if ((component == self.driver.componentF12) and (value == self.driver.valueF12)) : fnThrottle.setF12( not fnThrottle.getF12() ) if ((roster != None) and (not roster.getFunctionLockable(12)) and (component == self.driver.componentF12) and (value == self.driver.valueF12Off)) : fnThrottle.setF12( not fnThrottle.getF12() ) except AttributeError: pass try: if ((component == self.driver.componentF13) and (value == self.driver.valueF13)) : fnThrottle.setF13( not fnThrottle.getF13() ) if ((roster != None) and (not roster.getFunctionLockable(13)) and (component == self.driver.componentF13) and (value == self.driver.valueF13Off)) : fnThrottle.setF13( not fnThrottle.getF13() ) except AttributeError: pass try: if ((component == self.driver.componentF14) and (value == self.driver.valueF14)) : fnThrottle.setF14( not fnThrottle.getF14() ) if ((roster != None) and (not roster.getFunctionLockable(14)) and (component == self.driver.componentF14) and (value == self.driver.valueF14Off)) : fnThrottle.setF14( not fnThrottle.getF14() ) except AttributeError: pass try: if ((component == self.driver.componentF15) and (value == self.driver.valueF15)) : fnThrottle.setF15( not fnThrottle.getF15() ) if ((roster != None) and (not roster.getFunctionLockable(15)) and (component == self.driver.componentF15) and (value == self.driver.valueF15Off)) : fnThrottle.setF15( not fnThrottle.getF15() ) except AttributeError: pass try: if ((component == self.driver.componentF16) and (value == self.driver.valueF16)) : fnThrottle.setF16( not fnThrottle.getF16() ) if ((roster != None) and (not roster.getFunctionLockable(16)) and (component == self.driver.componentF16) and (value == self.driver.valueF16Off)) : fnThrottle.setF16( not fnThrottle.getF16() ) except AttributeError: pass try: if ((component == self.driver.componentF17) and (value == self.driver.valueF17)) : fnThrottle.setF17( not fnThrottle.getF17() ) if ((roster != None) and (not roster.getFunctionLockable(17)) and (component == self.driver.componentF17) and (value == self.driver.valueF17Off)) : fnThrottle.setF17( not fnThrottle.getF17() ) except AttributeError: pass try: if ((component == self.driver.componentF18) and (value == self.driver.valueF18)) : fnThrottle.setF18( not fnThrottle.getF18() ) if ((roster != None) and (not roster.getFunctionLockable(18)) and (component == self.driver.componentF18) and (value == self.driver.valueF18Off)) : fnThrottle.setF18( not fnThrottle.getF18() ) except AttributeError: pass try: if ((component == self.driver.componentF19) and (value == self.driver.valueF19)) : fnThrottle.setF19( not fnThrottle.getF19() ) if ((roster != None) and (not roster.getFunctionLockable(19)) and (component == self.driver.componentF19) and (value == self.driver.valueF19Off)) : fnThrottle.setF19( not fnThrottle.getF19() ) except AttributeError: pass try: if ((component == self.driver.componentF20) and (value == self.driver.valueF20)) : fnThrottle.setF20( not fnThrottle.getF20() ) if ((roster != None) and (not roster.getFunctionLockable(20)) and (component == self.driver.componentF20) and (value == self.driver.valueF20Off)) : fnThrottle.setF20( not fnThrottle.getF20() ) except AttributeError: pass try: if ((component == self.driver.componentF21) and (value == self.driver.valueF21)) : fnThrottle.setF21( not fnThrottle.getF21() ) if ((roster != None) and (not roster.getFunctionLockable(21)) and (component == self.driver.componentF21) and (value == self.driver.valueF21Off)) : fnThrottle.setF21( not fnThrottle.getF21() ) except AttributeError: pass try: if ((component == self.driver.componentF22) and (value == self.driver.valueF22)) : fnThrottle.setF22( not fnThrottle.getF22() ) if ((roster != None) and (not roster.getFunctionLockable(22)) and (component == self.driver.componentF22) and (value == self.driver.valueF22Off)) : fnThrottle.setF22( not fnThrottle.getF22() ) except AttributeError: pass try: if ((component == self.driver.componentF23) and (value == self.driver.valueF23)) : fnThrottle.setF23( not fnThrottle.getF23() ) if ((roster != None) and (not roster.getFunctionLockable(23)) and (component == self.driver.componentF23) and (value == self.driver.valueF23Off)) : fnThrottle.setF23( not fnThrottle.getF23() ) except AttributeError: pass try: if ((component == self.driver.componentF24) and (value == self.driver.valueF24)) : fnThrottle.setF24( not fnThrottle.getF24() ) if ((roster != None) and (not roster.getFunctionLockable(24)) and (component == self.driver.componentF24) and (value == self.driver.valueF24Off)) : fnThrottle.setF24( not fnThrottle.getF24() ) except AttributeError: pass try: if ((component == self.driver.componentF25) and (value == self.driver.valueF25)) : fnThrottle.setF25( not fnThrottle.getF25() ) if ((roster != None) and (not roster.getFunctionLockable(25)) and (component == self.driver.componentF25) and (value == self.driver.valueF25Off)) : fnThrottle.setF25( not fnThrottle.getF25() ) except AttributeError: pass try: if ((component == self.driver.componentF26) and (value == self.driver.valueF26)) : fnThrottle.setF26( not fnThrottle.getF26() ) if ((roster != None) and (not roster.getFunctionLockable(26)) and (component == self.driver.componentF26) and (value == self.driver.valueF26Off)) : fnThrottle.setF26( not fnThrottle.getF26() ) except AttributeError: pass try: if ((component == self.driver.componentF27) and (value == self.driver.valueF27)) : fnThrottle.setF27( not fnThrottle.getF27() ) if ((roster != None) and (not roster.getFunctionLockable(27)) and (component == self.driver.componentF27) and (value == self.driver.valueF27Off)) : fnThrottle.setF27( not fnThrottle.getF27() ) except AttributeError: pass try: if ((component == self.driver.componentF28) and (value == self.driver.valueF28)) : fnThrottle.setF28( not fnThrottle.getF28() ) if ((roster != None) and (not roster.getFunctionLockable(28)) and (component == self.driver.componentF28) and (value == self.driver.valueF28Off)) : fnThrottle.setF28( not fnThrottle.getF28() ) except AttributeError: pass try: if ((component == self.driver.componentF29) and (value == self.driver.valueF29)) : fnThrottle.setF29( not fnThrottle.getF29() ) if ((roster != None) and (not roster.getFunctionLockable(29)) and (component == self.driver.componentF29) and (value == self.driver.valueF29Off)) : fnThrottle.setF29( not fnThrottle.getF29() ) except AttributeError: pass # # Advanced Functions (strings defined in the rosterEntry property "advancedFunctionNames" comma separated list, and then used in the driver as componentAdvFunctionX and valueAdvFunctionX) # like advF1 = F2;F3 means that F2 and F3 will be toggled when advF1 is triggered, and if F2 or F3 are lockable then they will be toggled back if the value is valueAdvFunctionXOff # try: if (component == self.driver.componentAdvancedF0) : self.advFunctions.call(roster, "0", (value == self.driver.valueAdvancedF0), fnThrottle) if (component == self.driver.componentAdvancedF1) : self.advFunctions.call(roster, "1", (value == self.driver.valueAdvancedF1), fnThrottle) if (component == self.driver.componentAdvancedF2) : self.advFunctions.call(roster, "2", (value == self.driver.valueAdvancedF2), fnThrottle) if (component == self.driver.componentAdvancedF3) : self.advFunctions.call(roster, "3", (value == self.driver.valueAdvancedF3), fnThrottle) if (component == self.driver.componentAdvancedF4) : self.advFunctions.call(roster, "4", (value == self.driver.valueAdvancedF4), fnThrottle) except AttributeError: pass #Jynstrument main and mandatory methods def getExpectedContextClassName(self): return "jmri.jmrit.throttle.ThrottleWindow" def init(self): self.speedTimerTask = SpeedTimerTask() #Speed increase thread self.speedTimer = Timer() self.speedTimer.schedule(self.speedTimerTask, 0, valueSpeedTimerRepeat) self.label = JButton(ImageIcon(self.getFolder() + "/USBControl.png","USBThrottle")) #label self.label.addMouseListener(self.getMouseListeners()[0]) # In order to get the popupmenu on the button too self.add(self.label) self.desiredController = None self.ctrlMenuItem = [] self.USBDriver = None self.driver = None self.model = jmri.jmrix.jinput.TreeModel.instance() # USB controllers model mi = JCheckBoxMenuItem ("None") self.getPopUpMenu().add( mi ) mi.addItemListener( ControllerItemListener(None, self) ) self.ctrlMenuItem.append(mi) for ctrl in self.model.controllers(): mi = JCheckBoxMenuItem (ctrl.getName()) self.getPopUpMenu().add( mi ) mi.addItemListener( ControllerItemListener(ctrl, self) ) self.ctrlMenuItem.append(mi) if ( len(self.ctrlMenuItem) == 0 ): print "No matching USB device found" else: self.ctrlMenuItem[0].setSelected(True) # by default connect to the first one self.lastTimeStopButton = Calendar.getInstance().getTimeInMillis() self.lastTimeCruiseButton = Calendar.getInstance().getTimeInMillis() self.model.addPropertyChangeListener(self) # Listen to USB device changes to update the list of available controllers in the menu # On quit clean up resources def quit(self): self.model.removePropertyChangeListener(self) self.speedTimerTask.cancel() self.speedTimer.cancel() self.speedTimer.purge() for mi in self.ctrlMenuItem : self.getPopUpMenu().remove( mi ) self.model = None self.ctrlMenuItem = None self.speedTimerTask = None self.speedTimer = None self.driver = None self.USBDriver = None # Menu entry changed for Current controller and update driver def setSelectedController(self, ctrl, item): for mi in self.ctrlMenuItem : if ( mi != item ): # Force deselection of other ones mi.setSelected(False) self.desiredController = ctrl # we will compare against this reference in the property change event to be sure we are listening to the right one if (ctrl != None) : sys.path.append(self.getFolder()) # Load a driver try: if (self.driver != None): del self.driver if (self.USBDriver != None): del self.USBDriver dd=ctrl.getName() dd=self.formatDriverName(dd) print "Trying to import driver by name \""+ dd +".py\" ..." self.USBDriver = __import__(dd) print "...driver \""+ dd +".py\" imported" except ImportError: # On error try by device type name try: print "...driver by name not found in \""+self.getFolder()+"\"" dd=ctrl.getType().toString() dd=self.formatDriverName(dd) print "Trying to import driver by type \""+ dd +".py\" ..." self.USBDriver = __import__(dd) print "...driver \""+ dd +".py\" imported" except ImportError: # On error load a default one print "...driver by type not found in \""+self.getFolder()+"\", importing default one" self.USBDriver = __import__("Default") print "Default.py driver imported" reload(self.USBDriver) sys.path.remove(self.getFolder()) self.driver = self.USBDriver.USBDriver() def formatDriverName(self, strparam): strparam=strparam.replace(" ", "") strparam=strparam.replace(",", "") strparam=strparam.replace(".", "") strparam=strparam.replace("(", "") strparam=strparam.replace(")", "") strparam=strparam.replace("{", "") strparam=strparam.replace("}", "") strparam=strparam.replace("[", "") strparam=strparam.replace("]", "") return strparam def setXml(self, elt): if (elt.getChildren("USBThrottle") == None): return ctrl = elt.getChildren("USBThrottle")[0].getAttributeValue("DesiredController") if (ctrl == None): return for mi in self.ctrlMenuItem : if ( mi.getText() == ctrl ): mi.setSelected(True) break def getXml(self): elt = Element("USBThrottle") for mi in self.ctrlMenuItem : if (mi.isSelected()) : elt.setAttribute("DesiredController", mi.getText()) break return elt # Item listeners for the PopUp menu class ControllerItemListener( java.awt.event.ItemListener): def __init__(self, ctrl, jyns): self.ctrl = ctrl self.jyns = jyns def itemStateChanged(self, evt): if (evt.getStateChange() == java.awt.event.ItemEvent.SELECTED ): self.jyns.setSelectedController( self.ctrl, evt.getItem() ) # Speed timer class, to increase speed regularly once button pushed, thread stopped on button release class SpeedTimerTask(TimerTask): def __init__(self): self.sync = thread.allocate_lock() # Protects properties getters and setters self.speedIncrement = 0 self.throttle = None self.isPaused = True def pause(self): self.sync.acquire() self.isPaused = True self.sync.release() def resume(self): self.sync.acquire() self.isPaused = False self.sync.release() def setSpeedIncrement(self, si): self.sync.acquire() self.speedIncrement = si self.sync.release() def getSpeedIncrement(self): self.sync.acquire() si = self.speedIncrement self.sync.release() return si def setThrottle(self, throt): self.sync.acquire() self.throttle = throt self.sync.release() def getThrottle(self): self.sync.acquire() throt = self.throttle self.sync.release() return throt def run(self): if (self.isPaused) : return throttle = self.getThrottle() spi = self.getSpeedIncrement() if (throttle != None) : ns = throttle.getSpeedSetting() + spi if (ns < 0 ) : ns = 0 if (ns > 1 ) : ns = 1 throttle.setSpeedSetting( ns ) class AdvFunctions(): def call(self, rosterEntry, advFn, status, throttle): if ((rosterEntry == None) or (advFn == None) or (status==None) or (throttle==None)): return todoStr = rosterEntry.getAttribute("advF"+advFn) if (todoStr == None): return None # poor man parser, should unserialize a json object instead todo = todoStr.split(";") for task in todo: task = task.lstrip() # Actual function call if (task.startswith("F")): task = task.rstrip() setter = None getter = None ok = False for fct in throttle.getClass().getMethods(): fctName = fct.getName() if (fctName == "set"+task): setter=fct if (fctName == "get"+task): getter=fct if (setter != None and getter != None): ok = True break if (ok): if (not rosterEntry.getFunctionLockable(int(task[1:]))): setter.invoke(throttle, status) elif (status): state = getter.invoke(throttle) setter.invoke(throttle, not state) continue # Play sound if (task.startswith("P") and status): path = task[1:] self.play(path, throttle) continue return True def play(self, sndPath, throttle): assert (sndPath!=None), "sndPath is null" sourceName="IAS"+sndPath+"-"+str(throttle.getLocoAddress()) bufferName="IAB"+sndPath source = audio.getAudio(sourceName) if (source == None): buffer = audio.getAudio(bufferName) if (buffer == None): buffer = audio.provideAudio(bufferName) buffer.setURL(sndPath) source = audio.provideAudio(sourceName) source.setAssignedBuffer(bufferName) # would need to update location here source.play()