001package jmri.jmrix.lenz.hornbyelite;
002
003import javax.annotation.Nonnull;
004import jmri.Turnout;
005import jmri.jmrix.lenz.XNetAddress;
006import jmri.jmrix.lenz.XNetSystemConnectionMemo;
007import org.slf4j.Logger;
008import org.slf4j.LoggerFactory;
009
010/**
011 * Implement XNet turnout manager - Specific to Hornby Elite
012 * <p>
013 * System names are "XTnnn", where X is the user-configurable system prefix,
014 * nnn is the turnout number without padding.
015 *
016 * @author Paul Bender Copyright (C) 2008
017 */
018public class EliteXNetTurnoutManager extends jmri.jmrix.lenz.XNetTurnoutManager {
019
020    public EliteXNetTurnoutManager(XNetSystemConnectionMemo memo) {
021        super(memo);
022    }
023
024    // XNet-specific methods
025
026    @Override
027    public Turnout createNewTurnout(@Nonnull String systemName, String userName) {
028        // check if the output bit is available
029        int bitNum = XNetAddress.getBitFromSystemName(systemName, getSystemPrefix());
030        if (bitNum == -1) {
031            return (null);
032        }
033        // create the new Turnout object
034        Turnout t = new EliteXNetTurnout(getSystemPrefix(), bitNum, tc);
035        t.setUserName(userName);
036        return t;
037    }
038
039    @Override
040    public boolean allowMultipleAdditions(@Nonnull String systemName) {
041        return true;
042    }
043
044    /**
045     * Listen for turnouts, creating them as needed
046     */
047    @Override
048    public void message(jmri.jmrix.lenz.XNetReply l) {
049        log.debug("received message: {}", l);
050        if (l.isFeedbackBroadcastMessage()) {
051            int numDataBytes = l.getElement(0) & 0x0f;
052            for (int i = 1; i < numDataBytes; i += 2) {
053                // parse message type
054                int addr = l.getTurnoutMsgAddr(i);    // Acc. Address 1 on 
055                // Hornby reads as 
056                // XpressNet address 2
057                // in the message.
058                if (addr >= 0) {
059                    log.debug("message has address: {}", addr);
060                    // reach here for switch command; make sure we know 
061                    // about this one
062                    String s = getSystemNamePrefix() +(addr - 1);
063                    forwardMessageToTurnout(s,l);
064                    if ((addr & 0x01) == 1) {
065                        // If the address we got was odd, we need to check to 
066                        // see if the even address should be added as well.
067                        int a2 = l.getElement(i + 1);
068                        if ((a2 & 0x0c) != 0) {
069                            // reach here for switch command; make sure we know 
070                            // about this one
071                            s = getSystemNamePrefix() + (addr);
072                            forwardMessageToTurnout(s,l);
073                        }
074                    }
075                }
076            }
077        }
078    }
079
080    private static final Logger log = LoggerFactory.getLogger(EliteXNetTurnoutManager.class);
081
082}