Files
2026-06-17 14:00:51 +02:00

188 lines
7.9 KiB
Python

# Author: Lionel Jeanson copyright 2017
#
# Inspired from ThrottleBridge.py
# Author: Paul Bender, copyright 2004,2010
#
# Part of the JMRI distribution
#
# Listen for a given (3 as a default) DCC throttle commands
# and forward them to the curently selected one in throttle window
# or call advanced function if any defined for curently selected roster entry
#
# See JMRI output or log in case of issue.
#
# Customize at will.
listenToDCCThrottle = 3
import jmri
import jmri.ThrottleListener as ThrottleListener
import jmri.jmrit.jython.Jynstrument as Jynstrument
import java.beans.PropertyChangeListener as PropertyChangeListener
import javax.swing.JButton as JButton
import javax.swing.ImageIcon as ImageIcon
import time
class DCCThrottle(Jynstrument, ThrottleListener, PropertyChangeListener):
#Jynstrument main and mandatory methods
def getExpectedContextClassName(self):
return "jmri.jmrit.throttle.ThrottleWindow"
def init(self):
self.label = JButton(ImageIcon(self.getFolder() + "/DCCThrottle.png","DCCThrottle")) #label
self.label.addMouseListener(self.getMouseListeners()[0]) # In order to get the popupmenu on the button too
self.add(self.label)
# create a dcc throttle and request one from the ThrottleManager
self.masterThrottle = None
if ( jmri.InstanceManager.throttleManagerInstance().requestThrottle(listenToDCCThrottle, self) == False):
print "Couldn't request a throttle for "+locoAddress
# Advanced functions
self.advFunctions = AdvFunctions()
def quit(self):
if (self.masterThrottle != None):
self.masterThrottle.removePropertyChangeListener(self)
self.masterThrottle = None
self.advFunctions = None
#Property listener part
def propertyChange(self, event):
panelThrottle = None
if (self.getContext().getCurentThrottleController() != None) :
panelThrottle = self.getContext().getCurentThrottleController().getThrottle()
roster = self.getContext().getCurentThrottleController().getRosterEntry()
if(panelThrottle == None):
return
if(event.propertyName == "IsForward"):
panelThrottle.setIsForward(event.newValue)
return
if(event.propertyName == "SpeedSetting"):
panelThrottle.setSpeedSetting(event.newValue)
return
if(event.propertyName == "F0"):
if (roster != None) and (self.advFunctions.call(roster, "0", event.newValue, panelThrottle) != None):
return
panelThrottle.setFunction(0,event.newValue)
return
if(event.propertyName == "F1"):
if (roster != None) and (self.advFunctions.call(roster, "1", event.newValue, panelThrottle) != None):
return
panelThrottle.setFunction(1,event.newValue)
return
if(event.propertyName == "F2"):
if (roster != None) and (self.advFunctions.call(roster, "2", event.newValue, panelThrottle) != None):
return
panelThrottle.setFunction(2,event.newValue)
return
if(event.propertyName == "F3"):
if (roster != None) and (self.advFunctions.call(roster, "3", event.newValue, panelThrottle) != None):
return
panelThrottle.setFunction(3,event.newValue)
return
if(event.propertyName == "F4"):
if (roster != None) and (self.advFunctions.call(roster, "4", event.newValue, panelThrottle) != None):
return
panelThrottle.setFunction(4,event.newValue)
return
if(event.propertyName == "F5"):
if (roster != None) and (self.advFunctions.call(roster, "5", event.newValue, panelThrottle) != None):
return
panelThrottle.setFunction(5,event.newValue)
return
if(event.propertyName == "F6"):
if (roster != None) and (self.advFunctions.call(roster, "6", event.newValue, panelThrottle) != None):
return
panelThrottle.setFunction(6,event.newValue)
return
if(event.propertyName == "F7"):
if (roster != None) and (self.advFunctions.call(roster, "7", event.newValue, panelThrottle) != None):
return
panelThrottle.setFunction(7,event.newValue)
return
if(event.propertyName == "F8"):
if (roster != None) and (self.advFunctions.call(roster, "8", event.newValue, panelThrottle) != None):
return
panelThrottle.setFunction(8,event.newValue)
return
if(event.propertyName == "F9"):
if (roster != None) and (self.advFunctions.call(roster, "9", event.newValue, panelThrottle) != None):
return
panelThrottle.setFunction(9,event.newValue)
return
#ThrottleListener part (real dccThrottle)
def notifyThrottleFound(self, dccThrottle):
self.masterThrottle = dccThrottle
self.masterThrottle.addPropertyChangeListener(self)
def notifyFailedThrottleRequest(self, locoAddress, reason):
self.masterThrottle = None
# Sleep a bit and try again
try:
time.sleep(1)
except BaseException:
pass
if ( jmri.InstanceManager.throttleManagerInstance().requestThrottle(listenToDCCThrottle, self) == False):
print "Couldn't request a throttle for "+locoAddress
def notifyDecisionRequired(LocoAddress, decision):
pass # Throttle steal / share decisions are delegated to the ThrottleManager
class AdvFunctions():
def call(self, rosterEntry, advFn, status, throttle):
assert (rosterEntry!=None), "rosterEntry is null"
assert (advFn!=None), "advFn is null"
assert (status!=None), "status is null"
assert (throttle!=None), "throttle is null"
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)
else:
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()