001package jmri.jmrix.lenz.hornbyelite;
002
003import jmri.LocoAddress;
004import jmri.jmrix.lenz.XNetReply;
005import jmri.jmrix.lenz.XNetSystemConnectionMemo;
006import jmri.jmrix.lenz.XNetTrafficController;
007import org.slf4j.Logger;
008import org.slf4j.LoggerFactory;
009
010/**
011 * An implementation of DccThrottle with code specific to an XpressNet
012 * connection on the Hornby Elite.
013 *
014 * @author Paul Bender (C) 2008-2009
015 */
016public class EliteXNetThrottle extends jmri.jmrix.lenz.XNetThrottle {
017
018    /**
019     * Interval to check the status of the throttle
020     */
021    protected static final int statTimeoutValue = 5000;
022    private static final String MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE = "Momentary function request not supported by Elite.";
023
024    /**
025     * Constructor.
026     * @param memo system connection.
027     * @param tc traffic controller.
028     */
029    public EliteXNetThrottle(XNetSystemConnectionMemo memo, XNetTrafficController tc) {
030        super(memo, tc);
031        log.debug("Elite XNetThrottle constructor");
032    }
033
034    /**
035     * Constructor by address.
036     * @param memo system connection.
037     * @param address loco address.
038     * @param tc system connection traffic controller.
039     */
040    public EliteXNetThrottle(XNetSystemConnectionMemo memo, LocoAddress address, XNetTrafficController tc) {
041        super(memo, address, tc);
042        log.debug("Elite XNetThrottle constructor called for address {}",address);
043    }
044
045    /**
046     * Send the XpressNet message to set the Momentary state of locomotive
047     * functions F0, F1, F2, F3, F4.
048     */
049    @Override
050    protected void sendMomentaryFunctionGroup1() {
051        log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE);
052    }
053
054    /**
055     * Send the XpressNet message to set the momentary state of functions F5,
056     * F6, F7, F8.
057     */
058    @Override
059    protected void sendMomentaryFunctionGroup2() {
060        log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE);
061    }
062
063    /**
064     * Send the XpressNet message to set the momentary state of functions F9,
065     * F10, F11, F12.
066     */
067    @Override
068    protected void sendMomentaryFunctionGroup3() {
069        log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE);
070    }
071
072    /**
073     * Send the XpressNet message to set the momentary state of functions F13,
074     * F14, F15, F16, F17, F18, F19, F20.
075     */
076    @Override
077    protected void sendMomentaryFunctionGroup4() {
078        log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE);
079    }
080
081    /**
082     * Send the XpressNet message to set the momentary state of functions F21,
083     * F22, F23, F24, F25, F26, F27, F28.
084     */
085    @Override
086    protected void sendMomentaryFunctionGroup5() {
087        log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE);
088    }
089
090    /**
091     * Send a request to get the status of functions from the command station.
092     */
093    @Override
094    protected synchronized void sendFunctionStatusInformationRequest() {
095        log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE);
096    }
097
098    /**
099     * Handle incoming messages for this throttle.
100     */
101    @Override
102    public void message(XNetReply l) {
103        // First, we want to see if this throttle is waiting for a message
104        //or not.
105        log.debug("Throttle - received message ");
106        if (requestState == THROTTLEIDLE) {
107            log.debug("Current throttle status is THROTTLEIDLE");
108            // We haven't sent anything, but we might be told someone else
109            // has taken over this address
110            if (l.getElement(0) == 0xE5) {
111                log.debug("Throttle - message is LOCO_INFO_RESPONSE ");
112                if (l.getElement(1) == 0xF8) {
113                    /* This is a Hornby Elite specific response
114                     * which occurs when the Elite throttle changes 
115                     * speed.  If this is for this throttle,
116                     * we need to handle it.
117                     * The address is in bytes 3 and 4*/
118                    if (getDccAddressHigh() == l.getElement(2) && getDccAddressLow() == l.getElement(3)) {
119                        //Set the Is available flag to "False"                    
120                        log.info("Loco {} in use by another device", getDccAddress());
121                        setIsAvailable(false);
122                        // Set the speed step mode and availabliity
123                        // from byte 5
124                        parseSpeedAndAvailability(l.getElement(4));
125                        // Parse the speed step and direction from
126                        // byte 6.
127                        parseSpeedAndDirection(l.getElement(5));
128                    }
129                } else if (l.getElement(1) == 0xF9) {
130                    /* This is a Hornby Elite specific response
131                     * which occurs when the Elite throttle changes 
132                     * functions.  If this is for this throttle,
133                     * we need to handle it.
134                     * The address is in bytes 3 and 4*/
135                    if (getDccAddressHigh() == l.getElement(2) && getDccAddressLow() == l.getElement(3)) {
136                        // Set the Is available flag to "False"
137                        log.info("Loco {} in use by another device", getDccAddress());
138                        setIsAvailable(false);
139                        // Parse the function status from bytes 5 and 6.
140                        parseFunctionInformation(l.getElement(4),
141                                l.getElement(5));
142                    }
143                }
144            }
145        }
146        // We didn't find any Elite specific messages, so send the
147        // message on to the standard XpressNet throttle message handler
148        super.message(l);
149    }
150
151    /*
152     * Since the Elite sends status messages when the throttle changes,
153     * override the startStatusTimer/stopStatustimer method to do nothing. 
154     */
155    @Override
156    protected void startStatusTimer() {
157        // override default behavior
158    }
159
160    @Override
161    protected void stopStatusTimer() {
162        // override default behavior
163    }
164
165    // register for notification
166    private static final Logger log = LoggerFactory.getLogger(EliteXNetThrottle.class);
167
168}