001package jmri.jmrix.tams; 002 003/** 004 * Encodes a message to a Tams MasterControl command station. 005 * <p> 006 * The {@link TamsReply} class handles the response from the command station. 007 * <p> 008 * Based on work by Bob Jacobsen and Kevin Dickerson 009 * 010 * @author Jan Boen 011 */ 012public class TamsMessage extends jmri.jmrix.AbstractMRMessage { 013 014 static private final int TamsProgrammingTimeout = 5000;//ms 015 016 //The oneByteReply is used to tell TamsReply if one or more bytes are expected 017 //The lastByteReply is gives the value of the last byte to be expected, for sensors this is always 0x00 018 //Has been set to sensor value as we expect this to the most common binary type of reply 019 //Is used in conjunction with isBinary() = true 020 //When receiving an ASCII reply we scan for ] which indicates end of reply. Anything after this can be ignored 021 // accessor to get one element of the TamsMessage 022 @Override 023 public int getElement(int n) { 024 return _dataChars[n]; 025 } 026 027 //Extend the class with extra Tams Specific variables 028 private char _replyType = 'X'; //C(ommand Station), S(ensor), T(urnout), P(ower), L(oco), X(Undefined), M(anual) via PacketGen 029 030 public char getReplyType() { 031 return _replyType; 032 } 033 034 public void setReplyType(char rt) { 035 _replyType = rt; 036 } 037 038 private boolean _replyOneByte = true;//Will it be a single byte reply? 039 040 public boolean getReplyOneByte() { 041 return _replyOneByte; 042 } 043 044 public void setReplyOneByte(boolean rob) { 045 _replyOneByte = rob; 046 } 047 048 private int _replyLastByte = TamsConstants.EOM00;//What will be the last byte of a multi byte reply? 049 050 public int getReplyLastByte() { 051 return _replyLastByte; 052 } 053 054 public void setReplyLastByte(int rlb) { 055 _replyLastByte = rlb; 056 } 057 058 public TamsMessage() { 059 super(); 060 } 061 062 // create a new one 063 public TamsMessage(int i) { 064 super(i); 065 } 066 067 // copy one 068 public TamsMessage(TamsMessage m) { 069 super(m); 070 } 071 072 // from String 073 public TamsMessage(String m) { 074 super(m); 075 setBinary(false); 076 } 077 078 // from binary 079 public TamsMessage(int[] m) {//an array of int will be interpreted as binary 080 this((m.length)); 081 //int i = 0; // counter of byte in output message 082 int j = 0; // counter of byte in input packet 083 // add each byte of the input message 084 for (j = 0; j < m.length; j++) { 085 this.setElement(j, m[j]);//changed i to j 086 //i++; 087 } 088 setBinary(true);//Is a binary reply 089 setReplyOneByte(false);//By default we set false and then check if we must change 090 if ((this.getElement(1) == (TamsConstants.XSTATUS & TamsConstants.MASKFF)) || (this.getElement(1) == (TamsConstants.XEVENT & TamsConstants.MASKFF))) { 091 setReplyOneByte(true); 092 } 093 setReplyLastByte(TamsConstants.EOM00);//By default we set 0x00 and then check if we must change 094 if (this.getElement(1) == (TamsConstants.XEVTLOK & TamsConstants.MASKFF)) { 095 setReplyLastByte(TamsConstants.EOM80); 096 } 097 //log.info(jmri.util.StringUtil.appendTwoHexFromInt(this.getElement(1),"")); 098 setRetries(5); 099 //log.info("Binary reply will be: one byte= " + getReplyOneByte() + ", last byte= " + getReplyLastByte()); 100 } 101 102 static public final int POLLTIMEOUT = 100; 103 104 // static methods to return a formatted message 105 //Binary messages 106 //Set power OFF via XPwrOff (0xA6) 107 static public TamsMessage setXPwrOff() { 108 TamsMessage m = new TamsMessage(2); 109 m.setElement(0, TamsConstants.LEADINGX & TamsConstants.MASKFF); 110 m.setElement(1, TamsConstants.XPWROFF & TamsConstants.MASKFF); 111 m.setBinary(true); 112 m.setReplyOneByte(true); 113 m.setReplyType('P'); 114 //log.info("Preformatted Tams message = " + Integer.toHexString(m.getElement(0)) + " " + Integer.toHexString(m.getElement(1))); 115 return m; 116 } 117 118 //Set power ON via XPwrOn (0xA7) 119 static public TamsMessage setXPwrOn() { 120 TamsMessage m = new TamsMessage(2); 121 m.setElement(0, TamsConstants.LEADINGX & TamsConstants.MASKFF); 122 m.setElement(1, TamsConstants.XPWRON & TamsConstants.MASKFF); 123 m.setBinary(true); 124 m.setReplyOneByte(true); 125 m.setReplyType('P'); 126 //log.info("Preformatted Tams message = " + Integer.toHexString(m.getElement(0)) + " " + Integer.toHexString(m.getElement(1))); 127 return m; 128 } 129 130 //Get power status via XStatus (0xA2) 131 static public TamsMessage getXStatus() { 132 TamsMessage m = new TamsMessage(2); 133 m.setElement(0, TamsConstants.LEADINGX & TamsConstants.MASKFF); 134 m.setElement(1, TamsConstants.XSTATUS & TamsConstants.MASKFF); 135 m.setBinary(true); 136 m.setReplyOneByte(true); 137 m.setReplyType('P'); 138 //log.info("Preformatted Tams getXStatus = " + Integer.toHexString(m.getElement(0)) + " " + Integer.toHexString(m.getElement(1))); 139 //log.info("isBinary= " + m.isBinary() + ", one byte reply " + m.getReplyOneByte() + ", reply type " + m.getReplyType()); 140 return m; 141 } 142 143 //Get sensor status via XEvtSen (0xCB) 144 //Only reports changes since last poll 145 static public TamsMessage getXEvtSen() { 146 TamsMessage m = new TamsMessage(2); 147 m.setElement(0, TamsConstants.LEADINGX & TamsConstants.MASKFF); 148 m.setElement(1, TamsConstants.XEVTSEN & TamsConstants.MASKFF); 149 m.setBinary(true); 150 m.setReplyOneByte(false); 151 m.setReplyLastByte(TamsConstants.EOM00);//No more sensor data is following 152 m.setReplyType('S'); 153 //log.info("Preformatted Tams message = " + Integer.toHexString(m.getElement(0)) + " " + Integer.toHexString(m.getElement(1))); 154 return m; 155 } 156 157 //Get loco changes via XEvtLok (0xC9) 158 //Only reports changes which have not been initiated from PC 159 static public TamsMessage getXEvtLok() { 160 TamsMessage m = new TamsMessage(2); 161 m.setElement(0, TamsConstants.LEADINGX & TamsConstants.MASKFF); 162 m.setElement(1, TamsConstants.XEVTLOK & TamsConstants.MASKFF); 163 m.setBinary(true); 164 m.setReplyOneByte(false); 165 m.setReplyLastByte(TamsConstants.EOM80);//No more loco data is following 166 m.setReplyType('L'); 167 //log.info("Preformatted Tams message = " + Integer.toHexString(m.getElement(0)) + " " + Integer.toHexString(m.getElement(1))); 168 return m; 169 } 170 171 //Get turnout changes via XEvtTrn (0xCA) 172 //Only reports changes which have not been initiated from PC 173 static public TamsMessage getXEvtTrn() { 174 TamsMessage m = new TamsMessage(2); 175 m.setElement(0, TamsConstants.LEADINGX & 0xFF); 176 m.setElement(1, TamsConstants.XEVTTRN & 0xFF); 177 m.setBinary(true); 178 m.setReplyOneByte(false); 179 m.setReplyType('T'); 180 //log.info("Preformatted Tams message = " + Integer.toHexString(m.getElement(0)) + " " + Integer.toHexString(m.getElement(1))); 181 return m; 182 } 183 184 //Set Tams MC to report only sensors which have been changed on polling 185 static public TamsMessage setXSR() { 186 TamsMessage m = new TamsMessage("xSR 1"); 187 m.setBinary(false); 188 m.setReplyOneByte(false); 189 m.setReplyType('S'); 190 return m; 191 } 192 193 //Set Tams MC so that a sensor module with at least 1 bit set is reporting its status 194 static public TamsMessage setXSensOff() { 195 TamsMessage m = new TamsMessage(2); 196 m.setElement(0, TamsConstants.LEADINGX & 0xFF); 197 m.setElement(1, TamsConstants.XSENSOFF & 0xFF); 198 m.setBinary(true); 199 m.setReplyOneByte(false); 200 m.setReplyType('S'); 201 return m; 202 } 203 204 //Command Station messages 205 static public TamsMessage getReadPagedCV(int cv) { //Rxxx 206 TamsMessage m = new TamsMessage("xPTRP " + cv); 207 m.setNeededMode(jmri.jmrix.AbstractMRTrafficController.PROGRAMINGMODE); 208 m.setTimeout(TamsProgrammingTimeout); 209 m.setBinary(false); 210 m.setReplyType('C'); 211 return m; 212 } 213 214 static public TamsMessage getWritePagedCV(int cv, int val) { //Pxxx xxx 215 TamsMessage m = new TamsMessage("xPTWP " + cv + ", " + val); 216 m.setNeededMode(jmri.jmrix.AbstractMRTrafficController.PROGRAMINGMODE); 217 m.setTimeout(TamsProgrammingTimeout); 218 m.setBinary(false); 219 m.setReplyType('C'); 220 return m; 221 } 222 223 static public TamsMessage getReadRegister(int reg) { //Vx 224 TamsMessage m = new TamsMessage("xPTRR " + reg); 225 m.setNeededMode(jmri.jmrix.AbstractMRTrafficController.PROGRAMINGMODE); 226 m.setTimeout(TamsProgrammingTimeout); 227 m.setBinary(false); 228 m.setReplyType('C'); 229 return m; 230 } 231 232 static public TamsMessage getWriteRegister(int reg, int val) { //Sx xxx 233 TamsMessage m = new TamsMessage("xPTWR " + reg + ", " + val); 234 m.setNeededMode(jmri.jmrix.AbstractMRTrafficController.PROGRAMINGMODE); 235 m.setTimeout(TamsProgrammingTimeout); 236 m.setBinary(false); 237 m.setReplyType('C'); 238 return m; 239 } 240 241 static public TamsMessage getReadDirectByteCV(int cv) { //Rxxx 242 TamsMessage m = new TamsMessage("xPTRD " + cv); 243 m.setNeededMode(jmri.jmrix.AbstractMRTrafficController.PROGRAMINGMODE); 244 m.setTimeout(TamsProgrammingTimeout); 245 m.setBinary(false); 246 m.setReplyType('C'); 247 return m; 248 } 249 250 static public TamsMessage getWriteDirectByteCV(int cv, int val) { //Pxxx xxx 251 TamsMessage m = new TamsMessage("xPTWD " + cv + ", " + val); 252 m.setNeededMode(jmri.jmrix.AbstractMRTrafficController.PROGRAMINGMODE); 253 m.setTimeout(TamsProgrammingTimeout); 254 m.setBinary(false); 255 m.setReplyType('C'); 256 return m; 257 } 258 259 static public TamsMessage getReadDirectBitCV(int cv) { //Rxxx 260 TamsMessage m = new TamsMessage("xPTRB " + cv); 261 m.setNeededMode(jmri.jmrix.AbstractMRTrafficController.PROGRAMINGMODE); 262 m.setTimeout(TamsProgrammingTimeout); 263 m.setBinary(false); 264 m.setReplyType('C'); 265 return m; 266 } 267 268 static public TamsMessage getWriteDirectBitCV(int cv, int bit, int val) { //Pxxx xxx 269 TamsMessage m = new TamsMessage("xPTWB " + cv + ", " + bit + ", " + val); 270 m.setNeededMode(jmri.jmrix.AbstractMRTrafficController.PROGRAMINGMODE); 271 m.setTimeout(TamsProgrammingTimeout); 272 m.setBinary(false); 273 m.setReplyType('C'); 274 return m; 275 } 276 277 static public TamsMessage getWriteOpsModeCVMsg(int adr, int cv, int val) { //Pxxx xxx 278 TamsMessage m = new TamsMessage("xPD " + adr + ", " + cv + ", " + val); 279 m.setNeededMode(jmri.jmrix.AbstractMRTrafficController.PROGRAMINGMODE); 280 m.setTimeout(TamsProgrammingTimeout); 281 m.setBinary(false); 282 m.setReplyType('C'); 283 return m; 284 } 285 286 static public TamsMessage getWriteOpsModeAccCVMsg(int adr, int cv, int val) { //Pxxx xxx 287 TamsMessage m = new TamsMessage("xPA " + adr + ", " + cv + ", " + val); 288 m.setNeededMode(jmri.jmrix.AbstractMRTrafficController.PROGRAMINGMODE); 289 m.setTimeout(TamsProgrammingTimeout); 290 m.setBinary(false); 291 m.setReplyType('C'); 292 return m; 293 } 294}