001package jmri.jmrix.roco.z21;
002
003import jmri.jmrix.lenz.XNetReply;
004
005/**
006 * Represents a single response from the XpressNet, with extensions
007 * from Roco for the Z21.
008 *
009 * @author Paul Bender Copyright (C) 2018
010 *
011 */
012public class Z21XNetReply extends XNetReply {
013
014    // Create a new reply.
015    public Z21XNetReply() {
016        super();
017    }
018
019    // Create a new reply from an existing reply
020    public Z21XNetReply(Z21XNetReply reply) {
021        super(reply);
022    }
023
024    /**
025     * Create a reply from an XNetMessage.
026     * @param message message to create reply from.
027     */
028    public Z21XNetReply(Z21XNetMessage message) {
029        super(message);
030    }
031
032    /**
033     * Create a reply from a string of hex characters.
034     * @param message hex character string.
035     */
036    public Z21XNetReply(String message) {
037        super(message);
038    }
039
040    /**
041     * Is this message a service mode response?
042     */
043    @Override
044    public boolean isServiceModeResponse() {
045        return ((getElement(0) == Z21Constants.LAN_X_CV_RESULT_XHEADER && 
046                (getElement(1) == Z21Constants.LAN_X_CV_RESULT_DB0)) ||
047                super.isServiceModeResponse());
048    }
049
050    @Override
051    public boolean isFeedbackMessage() {
052        return (this.getElement(0) == Z21Constants.LAN_X_TURNOUT_INFO ||
053                 super.isFeedbackMessage());
054    }
055
056    /**
057     * @return a string representation of the reply suitable for display in the
058     * XpressNet monitor.
059     */
060    @Override
061    public String toMonitorString(){
062        String text;
063
064        if (getElement(0) == Z21Constants.LAN_X_CV_RESULT_XHEADER ) {
065            if (getElement(1) == Z21Constants.LAN_X_CV_RESULT_DB0 ) {
066                int value = getElement(4) & 0xFF;
067                int cv = ( (getElement(2)&0xFF) << 8) + 
068                          ( getElement(3)& 0xFF ) + 1;
069                text = Bundle.getMessage("Z21LAN_X_CV_RESULT",cv,value);
070            } else {
071                text = super.toMonitorString();
072            }
073        } else if((getElement(0)&0xE0)==0xE0 && ((getElement(0)&0x0f) >= 7 && (getElement(0)&0x0f) <=15 )) {
074            //This is a Roco specific throttle information message.
075            //Data Byte 0 and 1 contain the locomotive address
076            int messageaddress = ((getElement(1) & 0x3F) << 8) + (getElement(2) & 0xff);
077            text = "Z21 Mobile decoder info reply for address " + messageaddress + ":";
078            //The message is for this throttle.
079            int b2 = getElement(3) & 0xff;
080            int b3 = getElement(4) & 0xff;
081            int b4 = getElement(5) & 0xff;
082            int b5 = getElement(6) & 0xff;
083            int b6 = getElement(7) & 0xff;
084            int b7 = getElement(8) & 0xff;
085            // byte 2 contains the speed step mode and availability
086            // information.
087            // byte 3 contains the direction and the speed information
088            text += " " + parseSpeedAndDirection(b2, b3);
089            // byte 4 contains flags for whether or not the locomotive
090            // is in a double header and for smart search.  These aren't used
091            // here.
092
093            // byte 4 and 5 contain function information for F0-F12
094            text += " " + parseFunctionStatus(b4, b5);
095            // byte 6 and 7 contain function information for F13-F28
096            text += " " + parseFunctionHighStatus(b6, b7);
097        } else if(getElement(0) == Z21Constants.LAN_X_TURNOUT_INFO) {
098             int address = (getElement(1) << 8 ) + getElement(2) +1;
099             String state = "";
100             switch(getElement(3)) {
101                 case 0x03:
102                     state += "inconsistent";
103                     break;
104                 case 0x02:
105                     state += "Thrown";
106                     break;
107                 case 0x01:
108                     state += "Closed";
109                     break;
110                 default:
111                     state += "Unknown";
112             }
113             text = Bundle.getMessage("Z21LAN_X_TURNOUT_INFO",address, state);
114        } else {
115            text = super.toMonitorString();
116        }
117        return text;
118    }
119
120}