use of jmri.DccLocoAddress in project JMRI by JMRI.
the class AbstractThrottleManager method cancelThrottleRequest.
/**
* Cancel a request for a throttle
*
* @param address The decoder address desired.
* @param isLong True if this is a request for a DCC long (extended)
* address.
* @param l The ThrottleListener cancelling request for a throttle.
*/
@Override
public void cancelThrottleRequest(int address, boolean isLong, ThrottleListener l) {
if (throttleListeners != null) {
DccLocoAddress la = new DccLocoAddress(address, isLong);
cancelThrottleRequest(la, l);
}
/*if (addressThrottles.contains(la)){
addressThrottles.get(la).decrementUse();
}*/
}
use of jmri.DccLocoAddress in project JMRI by JMRI.
the class CbusThrottleManager method reply.
@Override
public synchronized void reply(CanReply m) {
int opc = m.getElement(0);
int rcvdIntAddr = (m.getElement(2) & 0x3f) * 256 + m.getElement(3);
boolean rcvdIsLong = (m.getElement(2) & 0xc0) != 0;
int handle = m.getElement(1);
int errCode = m.getElement(3);
DccLocoAddress rcvdDccAddr;
String errStr = "";
Iterator<Integer> itr;
switch(opc) {
case CbusConstants.CBUS_PLOC:
rcvdDccAddr = new DccLocoAddress(rcvdIntAddr, rcvdIsLong);
log.debug("Throttle manager received PLOC with session handle " + m.getElement(1) + " for address " + rcvdIntAddr);
if ((_handleExpected) && rcvdDccAddr.equals(_dccAddr)) {
log.debug("PLOC was expected");
// We're expecting an engine report and it matches our address
handle = m.getElement(1);
CbusThrottle throttle;
throttleRequestTimer.stop();
throttle = new CbusThrottle((CanSystemConnectionMemo) adapterMemo, rcvdDccAddr, handle);
// Initialise throttle from PLOC data to allow taking over moving trains
throttle.throttleInit(m.getElement(4), m.getElement(5), m.getElement(6), m.getElement(7));
notifyThrottleKnown(throttle, rcvdDccAddr);
softThrottles.put(handle, throttle);
_handleExpected = false;
}
break;
case CbusConstants.CBUS_ERR:
// TODO: should be a better way to do this with constants or properties
switch(errCode) {
case CbusConstants.ERR_LOCO_STACK_FULL:
errStr = "loco stack full for address " + rcvdIntAddr;
break;
case CbusConstants.ERR_LOCO_ADDRESS_TAKEN:
errStr = "loco address taken for address " + rcvdIntAddr;
break;
case CbusConstants.ERR_INVALID_REQUEST:
errStr = "invalid request for address " + rcvdIntAddr;
break;
case CbusConstants.ERR_SESSION_NOT_PRESENT:
errStr = "session not present for session " + handle;
break;
case CbusConstants.ERR_CONSIST_EMPTY:
errStr = "consist empty for consist " + handle;
break;
case CbusConstants.ERR_LOCO_NOT_FOUND:
errStr = "loco not found for session " + handle;
break;
case CbusConstants.ERR_CAN_BUS_ERROR:
errStr = "CAN bus error";
break;
case CbusConstants.ERR_SESSION_CANCELLED:
errStr = "Throttle session cancelled for loco ";
break;
default:
log.warn("Unhandled error code: {}", errCode);
break;
}
log.debug("Throttle manager received ERR " + errStr);
rcvdDccAddr = new DccLocoAddress(rcvdIntAddr, rcvdIsLong);
switch(errCode) {
case CbusConstants.ERR_LOCO_STACK_FULL:
case CbusConstants.ERR_LOCO_ADDRESS_TAKEN:
log.debug("PLOC expected but received ERR address" + rcvdDccAddr.toString());
if ((_handleExpected) && rcvdDccAddr.equals(_dccAddr)) {
// We were expecting an engine report and it matches our address
log.debug("Failed throttle request due to ERR");
_handleExpected = false;
throttleRequestTimer.stop();
JOptionPane.showMessageDialog(null, "CBUS ERR:" + errStr);
failedThrottleRequest(_dccAddr, "CBUS ERR:" + errStr);
} else {
log.debug("ERR address not matched");
}
break;
case CbusConstants.ERR_SESSION_NOT_PRESENT:
if ((_handleExpected) && rcvdDccAddr.equals(_dccAddr)) {
// We were expecting an engine report and it matches our address
_handleExpected = false;
}
JOptionPane.showMessageDialog(null, "CBUS ERR:" + errStr);
break;
case CbusConstants.ERR_CONSIST_EMPTY:
case CbusConstants.ERR_LOCO_NOT_FOUND:
// and will never issue these errors
break;
case CbusConstants.ERR_CAN_BUS_ERROR:
case CbusConstants.ERR_INVALID_REQUEST:
JOptionPane.showMessageDialog(null, "CBUS ERR:" + errStr);
break;
case CbusConstants.ERR_SESSION_CANCELLED:
// There will be a session cancelled error for the other throttle(s)
// when you are stealing, but as you don't yet have a session id, it
// won't match so you will ignore it, then a PLOC will come with that
// session id and your requested loco number which is giving it to you.
// Inform the throttle associated with this session handle, if any
itr = softThrottles.keySet().iterator();
while (itr.hasNext()) {
CbusThrottle throttle = softThrottles.get(itr.next());
if (throttle.getHandle() == handle) {
JOptionPane.showMessageDialog(null, errStr + throttle.getLocoAddress().toString());
throttle.throttleTimedOut();
// Attempt to dispode of the throttle
super.disposeThrottle(throttle, null);
break;
}
}
break;
default:
break;
}
break;
case CbusConstants.CBUS_DSPD:
// Find a throttle corresponding to the handle
itr = softThrottles.keySet().iterator();
while (itr.hasNext()) {
CbusThrottle throttle = softThrottles.get(itr.next());
if (throttle.getHandle() == handle) {
// Set the throttle session to match the DSPD packet received
throttle.updateSpeedSetting(m.getElement(2) & 0x7f);
throttle.updateIsForward((m.getElement(2) & 0x80) == 0x80);
}
}
break;
case CbusConstants.CBUS_DFUN:
// Find a throttle corresponding to the handle
itr = softThrottles.keySet().iterator();
while (itr.hasNext()) {
CbusThrottle throttle = softThrottles.get(itr.next());
if (throttle.getHandle() == handle) {
// Set the throttle session to match the DFUN packet received
log.debug("DFUN group: " + m.getElement(2) + " Fns: " + m.getElement(3) + " for session: " + m.getElement(1));
switch(m.getElement(2)) {
case 1:
throttle.updateFunctionGroup1(m.getElement(3));
break;
case 2:
throttle.updateFunctionGroup2(m.getElement(3));
break;
case 3:
throttle.updateFunctionGroup3(m.getElement(3));
break;
case 4:
throttle.updateFunctionGroup4(m.getElement(3));
break;
case 5:
throttle.updateFunctionGroup5(m.getElement(3));
break;
default:
log.error("Unrecognised function group");
break;
}
}
}
break;
case CbusConstants.CBUS_DFNON:
case CbusConstants.CBUS_DFNOF:
// Find a throttle corresponding to the handle
itr = softThrottles.keySet().iterator();
while (itr.hasNext()) {
CbusThrottle throttle = softThrottles.get(itr.next());
if (throttle.getHandle() == handle) {
throttle.updateFunction(m.getElement(2), (opc == CbusConstants.CBUS_DFNON) ? true : false);
}
}
break;
case CbusConstants.CBUS_ESTOP:
case CbusConstants.CBUS_RESTP:
stopAll();
break;
default:
break;
}
}
use of jmri.DccLocoAddress in project JMRI by JMRI.
the class EcosReporter method getLocoAddress.
// Methods to support PhysicalLocationReporter interface
/**
* getLocoAddress()
*
* get the locomotive address we're reporting about from the current report.
*
* Note: We ignore the string passed in, because Ecos Reporters don't send
* String type reports.
*/
@Override
public LocoAddress getLocoAddress(String rep) {
// For now, we assume the current report.
// IdTag.getTagID() is a system-name-ized version of the loco address. I think.
// Matcher.group(1) : loco address (I think)
IdTag cr = (IdTag) this.getCurrentReport();
IdTagManager tm = InstanceManager.getDefault(IdTagManager.class);
Pattern p = Pattern.compile("" + tm.getSystemPrefix() + tm.typeLetter() + "(\\d+)");
Matcher m = p.matcher(cr.getTagID());
if (m.find()) {
log.debug("Parsed address: " + m.group(1));
// so we'll default to DCC for now.
return (new DccLocoAddress(Integer.parseInt(m.group(1)), LocoAddress.Protocol.DCC));
} else {
return (null);
}
}
use of jmri.DccLocoAddress in project JMRI by JMRI.
the class XNetConsist method addToCSConsist.
/*
* Add a Locomotive to a Lenz Double Header
* @param address is the Locomotive address to add to the locomotive
* @param directionNormal is True if the locomotive is traveling
* the same direction as the consist, or false otherwise.
*/
private synchronized void addToCSConsist(DccLocoAddress LocoAddress, boolean directionNormal) {
if (ConsistAddress.equals(LocoAddress)) {
// Something went wrong here, we are trying to add a
// trailing locomotive to the consist with the same
// address as the lead locomotive. This isn't supposed to
// happen.
log.error("Attempted to add " + LocoAddress.toString() + " to consist " + ConsistAddress.toString());
_state = IDLESTATE;
notifyConsistListeners(_locoAddress, ConsistListener.CONSIST_ERROR | ConsistListener.ALREADY_CONSISTED);
return;
}
// question, we need to disolve the consist
if (ConsistList.size() == 2 && ConsistList.contains(LocoAddress)) {
XNetMessage msg = XNetMessage.getDisolveDoubleHeaderMsg(ConsistList.get(0).getNumber());
tc.sendXNetMessage(msg, this);
}
// We need to make sure the directions are set correctly
// In order to do this, we have to pull up both throttles,
// and check that the direction of the trailing locomotive
// is correct relative to the lead locomotive.
DccLocoAddress address = ConsistList.get(0);
XNetThrottle lead = new XNetThrottle(systemMemo, address, tc);
XNetThrottle trail = new XNetThrottle(systemMemo, LocoAddress, tc);
if (directionNormal) {
if (log.isDebugEnabled()) {
log.debug("DOUBLE HEADER: Set direction of trailing locomotive same as lead locomotive");
}
trail.setIsForward(lead.getIsForward());
sendDirection(lead, lead.getIsForward());
sendDirection(trail, lead.getIsForward());
} else {
if (log.isDebugEnabled()) {
log.debug("DOUBLE HEADER: Set direction of trailing locomotive opposite lead locomotive");
}
trail.setIsForward(!lead.getIsForward());
sendDirection(lead, lead.getIsForward());
sendDirection(trail, !lead.getIsForward());
}
// All we have to do here is create an apropriate XNetMessage,
// and send it.
XNetMessage msg = XNetMessage.getBuildDoubleHeaderMsg(address.getNumber(), LocoAddress.getNumber());
tc.sendXNetMessage(msg, this);
_state = ADDREQUESTSENTSTATE;
}
use of jmri.DccLocoAddress in project JMRI by JMRI.
the class UhlenbrockLnThrottleManager method notifyChangedSlot.
/**
* SlotListener contract. Get notification that an address has changed slot.
* This method creates a throttle for all ThrottleListeners of that address
* and notifies them via the ThrottleListener.notifyThrottleFound method.
*/
@Override
public void notifyChangedSlot(LocoNetSlot s) {
DccThrottle throttle = new LocoNetThrottle((LocoNetSystemConnectionMemo) adapterMemo, s);
notifyThrottleKnown(throttle, new DccLocoAddress(s.locoAddr(), isLongAddress(s.locoAddr())));
if (waitingForNotification.containsKey(s.locoAddr())) {
Thread r = waitingForNotification.get(s.locoAddr());
synchronized (r) {
r.interrupt();
}
waitingForNotification.remove(s.locoAddr());
}
}
Aggregations