001package jmri.jmrix.srcp;
002
003import jmri.Turnout;
004import jmri.implementation.AbstractTurnout;
005import org.slf4j.Logger;
006import org.slf4j.LoggerFactory;
007
008/**
009 * SRCP implementation of the Turnout interface.
010 * <p>
011 * This object doesn't listen to the SRCP 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 * Extend jmri.AbstractTurnout for SRCP layouts
016 *
017 * @author Bob Jacobsen Copyright (C) 2001, 2008
018 * @author Paul Bender Copyright (C) 2014
019 */
020public class SRCPTurnout extends AbstractTurnout {
021
022    /**
023     * SRCP turnouts use the NMRA number (0-511) as their numerical
024     * identification.
025     *
026     * @param number the turnout number
027     * @param memo   the associated connection
028     */
029    public SRCPTurnout(int number, SRCPBusConnectionMemo memo) {
030        super(memo.getSystemPrefix() + memo.getTurnoutManager().typeLetter() + number);
031        _number = number;
032        _bus = memo.getBus();
033
034        // set the traffic controller
035        tc = memo.getTrafficController();
036
037        // send message requesting initialization
038        String text = "INIT " + _bus + " GA " + _number + " N\n";
039
040        // create and send the message itself
041        tc.sendSRCPMessage(new SRCPMessage(text), null);
042
043        // At construction, register for messages
044    }
045
046    public int getNumber() {
047        return _number;
048    }
049
050    /**
051     * {@inheritDoc}
052     */
053    @Override
054    protected void forwardCommandChangeToLayout(int newState) {
055        // sort out states
056        if ((newState & Turnout.CLOSED) != 0) {
057            // first look for the double case, which we can't handle
058            if ((newState & Turnout.THROWN) != 0) {
059                // this is the disaster case!
060                log.error("Cannot command both CLOSED and THROWN {}", newState);
061                return;
062            } else {
063                // send a CLOSED command
064                sendMessage(!getInverted());
065            }
066        } else {
067            // send a THROWN command
068            sendMessage(getInverted());
069        }
070    }
071
072    @Override
073    protected void turnoutPushbuttonLockout(boolean _pushButtonLockout) {
074        log.debug("Send command to {} Pushbutton {}T{}",
075                (_pushButtonLockout ? "Lock" : "Unlock"),
076                tc.getSystemConnectionMemo().getSystemPrefix(),
077                _number);
078    }
079
080    // data members
081    private int _number; // turnout number
082    private int _bus;    // bus number
083    private SRCPTrafficController tc = null; // traffic controller
084
085    protected void sendMessage(boolean closed) {
086        // get the message text
087        String text;
088        if (closed) {
089            text = "SET " + _bus + " GA " + _number + " 0 0 -1\n";
090        } else // thrown
091        {
092            text = "SET " + _bus + " GA " + _number + " 0 1 -1\n";
093        }
094
095        // create and send the message itself
096        tc.sendSRCPMessage(new SRCPMessage(text), null);
097
098    }
099
100    private final static Logger log = LoggerFactory.getLogger(SRCPTurnout.class);
101
102}