001package jmri.jmrix.tmcc; 002 003import jmri.Turnout; 004import jmri.implementation.AbstractTurnout; 005import org.slf4j.Logger; 006import org.slf4j.LoggerFactory; 007 008/** 009 * Extend jmri.AbstractTurnout for TMCC serial layouts. 010 * <p> 011 * This object doesn't listen to the TMCC communications. This is because it 012 * should be the only object that is sending messages for this turnout; more 013 * than one Turnout object pointing to a single device is not allowed. 014 * 015 * @author Bob Jacobsen Copyright (C) 2003, 2006 016 */ 017public class SerialTurnout extends AbstractTurnout { 018 019 // data members 020 int _number; // turnout number 021 private SerialTrafficController tc = null; 022 protected String _prefix = "T"; // default to "T" 023 024 /** 025 * Create a turnout. TMCC turnouts use the number 1-99 as their 026 * numerical identification. The TMCC SC-2 reserves 0 as a special reset 027 * address, but the TMCC SC-1 allows 0 to be a turnout; however, the SC-1 028 * documentation examples and callouts all use 1 as the first turnout 029 * address. 030 * 031 * @param prefix the connection prefix 032 * @param number the TMCC turnout number from 1 to 99 033 * @param memo the connection memo 034 */ 035 public SerialTurnout(String prefix, int number, TmccSystemConnectionMemo memo) { 036 super(prefix + "T" + number); 037 tc = memo.getTrafficController(); 038 _number = number; 039 _prefix = prefix; 040 // At construction, don't register for messages (see package doc) 041 } 042 043 /** 044 * {@inheritDoc} 045 */ 046 @Override 047 protected void forwardCommandChangeToLayout(int newState) { 048 049 // sort out states 050 if ((newState & Turnout.CLOSED) != 0) { 051 // first look for the double case, which we can't handle 052 if ((newState & Turnout.THROWN) != 0) { 053 // this is the disaster case! 054 log.error("Cannot command both CLOSED and THROWN {}", newState); 055 return; 056 } else { 057 // send a CLOSED command 058 sendMessage(true ^ getInverted()); 059 } 060 } else { 061 // send a THROWN command 062 sendMessage(false ^ getInverted()); 063 } 064 } 065 066 @Override 067 protected void turnoutPushbuttonLockout(boolean _pushButtonLockout) { 068 if (log.isDebugEnabled()) { 069 log.debug("Send command to {} Pushbutton {}T{}", (_pushButtonLockout ? "Lock" : "Unlock"), _prefix, _number); 070 } 071 } 072 073 protected void sendMessage(boolean closed) { 074 SerialMessage m = new SerialMessage(); 075 m.setOpCode(0xFE); 076 if (closed) { 077 m.putAsWord(0x4000 + _number * 128); 078 } else { 079 m.putAsWord(0x401F + _number * 128); 080 } 081 tc.sendSerialMessage(m, null); 082 tc.sendSerialMessage(m, null); 083 tc.sendSerialMessage(m, null); 084 tc.sendSerialMessage(m, null); 085 } 086 087 private final static Logger log = LoggerFactory.getLogger(SerialTurnout.class); 088 089}