001package jmri.jmrix.acela; 002 003import jmri.implementation.AbstractTurnout; 004import org.slf4j.Logger; 005import org.slf4j.LoggerFactory; 006 007/** 008 * Implementation of the Turnout Object for Acela 009 * <p> 010 * Based in part on SerialTurnout.java 011 * 012 * @author Dave Duchamp Copyright (C) 2004 013 * 014 * @author Bob Coleman Copyright (C) 2007, 2008 Based on CMRI serial example, 015 * modified to establish Acela support. 016 */ 017public class AcelaTurnout extends AbstractTurnout { 018 019 private AcelaSystemConnectionMemo _memo = null; 020 021 /** 022 * Create a Turnout object, with only system name. 023 * <p> 024 * 'SystemName' was previously validated in AcelaTurnoutManager 025 * 026 * @param systemName the system name for this Turnout 027 * @param memo the memo for the system connection 028 */ 029 public AcelaTurnout(String systemName, AcelaSystemConnectionMemo memo) { 030 super(systemName); 031 _memo = memo; 032 initializeTurnout(systemName); 033 } 034 035 /** 036 * Create a Turnout object, with both system and user names. 037 * <p> 038 * 'systemName' was previously validated in AcelaTurnoutManager 039 * 040 * @param systemName the system name for this Turnout 041 * @param userName the user name for this Turnout 042 * @param memo the memo for the system connection 043 */ 044 public AcelaTurnout(String systemName, String userName, AcelaSystemConnectionMemo memo) { 045 super(systemName, userName); 046 _memo = memo; 047 initializeTurnout(systemName); 048 } 049 050 /** 051 * Set up system dependent instance variables and set system independent 052 * instance variables to default values. 053 * Note: most instance variables are in AbstractTurnout.java 054 */ 055 private void initializeTurnout(String systemName) { 056 // Extract the Bit from the name 057 mBit = AcelaAddress.getBitFromSystemName(systemName, _memo.getSystemPrefix()); 058 059 // Set initial state 060 setState(UNKNOWN); 061 // Set defaults for all other instance variables 062 } 063 064 /** 065 * System dependent instance variables 066 */ 067 protected int mState = UNKNOWN; // current state of this turnout 068 int mBit = -1; // global address from 0 069 070 /** 071 * {@inheritDoc} 072 */ 073 @Override 074 protected void forwardCommandChangeToLayout(int newState) { 075 try { 076 sendMessage(stateChangeCheck(newState)); 077 } catch (IllegalArgumentException ex) { 078 log.error("new state invalid, Turnout not set"); 079 } 080 } 081 082 /** 083 * Send a message to the layout to lock or unlock the turnout push buttons. 084 * <p> 085 * This implementation does nothing, as Acela turnouts do not support 086 * lockout. 087 * 088 * @param pushButtonLockout true to lockout turnout push buttons; false 089 * otherwise 090 */ 091 @Override 092 protected void turnoutPushbuttonLockout(boolean pushButtonLockout) { 093 // Acela turnouts do not currently support lockout 094 } 095 096 // Acela turnouts do support inversion 097 @Override 098 public boolean canInvert() { 099 return true; 100 } 101 102 // method which takes a turnout state as a parameter and adjusts it as necessary 103 // to reflect the turnout invert property 104 private int adjustStateForInversion(int rawState) { 105 if (getInverted() && (rawState == CLOSED || rawState == THROWN)) { 106 if (rawState == CLOSED) { 107 return THROWN; 108 } else { 109 return CLOSED; 110 } 111 } else { 112 return rawState; 113 } 114 } 115 116 protected void sendMessage(boolean closed) { 117 int newState; 118 if (closed) { 119 newState = adjustStateForInversion(CLOSED); 120 } else { 121 newState = adjustStateForInversion(THROWN); 122 } 123 124 AcelaNode mNode = AcelaAddress.getNodeFromSystemName(mSystemName, _memo); 125 126 if (mNode != null) { 127 switch (newState) { 128 case THROWN: 129 mNode.setOutputBit(mBit, true); 130 break; 131 case CLOSED: 132 mNode.setOutputBit(mBit, false); 133 break; 134 default: 135 log.warn("illegal state requested for Turnout: {}", getSystemName()); 136 break; 137 } 138 } 139 140 if (newState != mState) { 141 int oldState = mState; 142 mState = newState; 143 144 // notify listeners, if any 145 firePropertyChange("KnownState", oldState, newState); 146 } 147 } 148 149 private final static Logger log = LoggerFactory.getLogger(AcelaTurnout.class); 150 151}