001package jmri.jmrix.bachrus; 002 003import org.slf4j.Logger; 004import org.slf4j.LoggerFactory; 005 006/** 007 * Carries the reply to an SprogMessage 008 * 009 * The format of a KPF-Zeller message is <code>*0000;V3.0%\n</code> 010 * but because we terminate on ";", it comes across as 011 * <code>V3.0%\n*0000;</code> 012 * 013 * @author Bob Jacobsen Copyright (C) 2001 014 * @author Andrew Crosland Copyright (C) 2010 015 */ 016public class SpeedoReply extends jmri.jmrix.AbstractMRReply { 017 // This should be an extension af AbstractMRReply and needs re-factoring 018 019 // create a new one 020 public SpeedoReply() { 021 super(); 022 } 023 024 // copy one 025 public SpeedoReply(SpeedoReply m) { 026 this(); 027 if (m == null) { 028 log.error("copy ctor of null message"); 029 return; 030 } 031 _nDataChars = m._nDataChars; 032 if (m.isUnsolicited()) { 033 setUnsolicited(); 034 } 035 for (int i = 0; i < _nDataChars; i++) { 036 _dataChars[i] = m._dataChars[i]; 037 } 038 } 039 040 // from String 041 public SpeedoReply(String s) { 042 this(); 043 _nDataChars = s.length(); 044 for (int i = 0; i < _nDataChars; i++) { 045 _dataChars[i] = s.charAt(i); 046 } 047 } 048 049 public int getCount() { 050 log.debug("getCount of n= {} '{}'", _nDataChars, this); 051 // KPF-Zeller formatting 052 if (_nDataChars == 13) { 053 try { 054 log.trace("selected out '{}'", this.toString().substring(8, 12)); 055 return Integer.parseInt(this.toString().substring(8, 12), 10); 056 } catch (NumberFormatException ex) { 057 log.trace("return 0 because of fault"); 058 return 0; 059 } 060 } 061 // drM SPC200R 062 if (_nDataChars == 7 && 063 (_dataChars[0] == 0x50 || _dataChars[0] == 0x51 || _dataChars[0] == 0x52 || _dataChars[0] == 0x53) ) { 064 // Check for invalid speed flag (0x2D = 45) 065 for (int i = 3; i <= 6; i++) { 066 if (_dataChars[i] == 0x2D) { 067 return -1; 068 } 069 } 070 int hundreds = _dataChars[3]; 071 int tens = _dataChars[4]; 072 int units = _dataChars[5]; 073 int tenths = _dataChars[6]; 074 075 // Basic range check (optional) 076 if (hundreds > 9 || tens > 9 || units > 9 || tenths > 9) { 077 return -1; 078 } 079 080 Float speed = hundreds * 100 + tens * 10 + units + tenths / 10.0f; 081 int scaled = Math.round(speed * 10); // e.g. 123.4 -> 1234 082 log.trace("Speed float {} int {}", speed, scaled); 083 return scaled; 084 } 085 // bachrus formatting 086 // don't return 0 as it will cause an exception 087 if (_nDataChars < 9) { 088 return -1; 089 } 090 try { 091 return Integer.parseInt(this.toString().substring(2, 8), 16); 092 } catch (NumberFormatException ex) { 093 return 0; 094 } 095 } 096 097 /** 098 * Series numbers define the actual hardware, i.e. wheel circumference. 099 * <dl> 100 * <dt>0</dt><dd>none, ignore</dd> 101 * <dt>4</dt><dd>Reader 40</dd> 102 * <dt>5</dt><dd>Reader 50</dd> 103 * <dt>6</dt><dd>Reader 60</dd> 104 * <dt>103</dt><dd>KPR-Zeller</dd> 105 * <dt>200</dt><dd>drM SPC200R</dd> 106 * </dl> 107 * @return type code for specific reply content 108 */ 109 public int getSeries() { 110 log.debug("getSeries of n= {} '{}'", _nDataChars, this); 111 // KPF-Zeller formatting 112 if (_nDataChars == 13) { 113 return 103; 114 } 115 // drM SPC200R formatting 116 if (_nDataChars == 7) { 117 return 200; 118 } 119 // bachrus formatting 120 if (_nDataChars < 7) { 121 return 0; 122 } 123 try { 124 return Integer.parseInt(this.toString().substring(1, 2)); 125 } catch (NumberFormatException ex) { 126 return 0; 127 } 128 } 129 130 @Override 131 public int match(String s) { 132 // find a specific string in the reply 133 String rep = new String(_dataChars, 0, _nDataChars); 134 return rep.indexOf(s); 135 } 136 137 static public final int maxSize = 32; 138 139 @Override 140 public int maxSize() { 141 return maxSize; 142 } 143 144 /** 145 * skipPrefix is not used at this point in time, but is 146 * defined as abstract in AbstractMRReply 147 */ 148 @Override 149 protected int skipPrefix(int index) { 150 return -1; 151 } 152 153 private final static Logger log = LoggerFactory.getLogger(SpeedoReply.class); 154 155}