001package jmri.jmrix.ecos; 002 003import java.util.HashMap; 004import java.util.List; 005import jmri.LocoAddress; 006import jmri.SpeedStepMode; 007import jmri.beans.Bean; 008import jmri.jmrit.roster.Roster; 009import jmri.jmrit.roster.RosterEntry; 010 011/** 012 * Stores all the loco information from the ECoS into JMRI 013 * 014 * @author Kevin Dickerson 015 */ 016public class EcosLocoAddress extends Bean implements jmri.LocoAddress { 017 018 private String _ecosObject = null; 019 private int _dccAddress = 0; 020 private String _ecosDescription = null; 021 private String _rosterId = null; 022 private String _ecosProtocolString = null; 023 private LocoAddress.Protocol _protocol = LocoAddress.Protocol.DCC; 024 private SpeedStepMode _speedSteps = SpeedStepMode.NMRA_DCC_128; 025 boolean direction; 026 int currentSpeed; 027 private boolean doNotAddToRoster = false; 028 public static int MFX_DCCAddressOffset = 20000; 029 030 public EcosLocoAddress(int dCCAddress) { 031 _dccAddress = dCCAddress; 032 } 033 034 public EcosLocoAddress(String ecosObject, String rosterAtt) { 035 _ecosObject = ecosObject; 036 //We see if there is a matching roster entry with out object against it 037 //if so we add the rosterId to the ecoclocoaddress entry. 038 List<RosterEntry> l = Roster.getDefault().getEntriesWithAttributeKeyValue(rosterAtt, ecosObject); 039 //It should be unique 040 if (l.size() > 0) { 041 _rosterId = l.get(0).getId(); 042 } 043 } 044 045 HashMap<Integer, Integer> cvValues = new HashMap<Integer, Integer>(); 046 047 public void setCV(int cv, int value) { 048 cvValues.put(cv, value); 049 } 050 051 public int getCV(int cv) { 052 if (cvValues.containsKey(cv)) { 053 return cvValues.get(cv); 054 } 055 return -1; 056 } 057 058 public String getCVAsString(int cv) { 059 int val = getCV(cv); 060 if (val == -1) { 061 return null; 062 } 063 return "" + val; //Do correctly 064 065 } 066 067 public void setLocoAddress(int dCCAddress) { 068 _dccAddress = dCCAddress; 069 } 070 071 /** 072 * @return the loco address configured on the ECoS for this loco 073 */ 074 @Override 075 public int getNumber() { 076 return _dccAddress; 077 } 078 079 /** 080 * @return the loco object as a string on the ECOS for this loco 081 */ 082 public String getEcosObject() { 083 return _ecosObject; 084 } 085 086 /** 087 * @return the loco object as a integer on the ECOS for this loco 088 */ 089 public int getEcosObjectAsInt() { 090 return Integer.parseInt(_ecosObject); 091 } 092 093 public void doNotAddToRoster() { 094 doNotAddToRoster = true; 095 } 096 097 public void allowAddToRoster() { 098 doNotAddToRoster = false; 099 } 100 101 public boolean addToRoster() { 102 return !doNotAddToRoster; 103 } 104 105 protected void setSpeed(int speed) { 106 int oldspeed = currentSpeed; 107 currentSpeed = speed; 108 firePropertyChange("Speed", oldspeed, currentSpeed); // NOI18N 109 } 110 111 public int getSpeed() { 112 return currentSpeed; 113 } 114 115 protected void setDirection(String line) { 116 setDirection(getDirection(line)); 117 } 118 119 protected void setDirection(boolean dir) { 120 boolean olddir = direction; 121 direction = dir; 122 firePropertyChange("Direction", olddir, direction); 123 } 124 125 public boolean getDirection() { 126 return direction; 127 } 128 129 public String getDirectionAsString() { 130 if (direction) { 131 return Bundle.getMessage("Forward"); 132 } 133 return Bundle.getMessage("Reverse"); 134 } 135 136 //Should this option be made public? should setting the object only be available when the Loco is created. 137 //It needs a bit of a re-think! 138 //It is set this way because of adhoc locos being created for throttles. 139 public void setEcosObject(String ecosObject) { 140 _ecosObject = ecosObject; 141 } 142 143 /** 144 * @return the loco object description held on the ECOS for this loco 145 */ 146 public String getEcosDescription() { 147 return _ecosDescription; 148 } 149 150 public void setEcosDescription(String description) { 151 if (description.startsWith("\"")) description = description.substring(1, description.length()); 152 if (description.endsWith("\"")) description = description.substring(0, description.length() - 1); 153 String oldValue = _ecosDescription; 154 _ecosDescription = description; 155 firePropertyChange("name", oldValue, _ecosDescription); // NOI18N 156 } 157 158 /** 159 * @return the JMRI Roster ID for this loco 160 */ 161 public String getRosterId() { 162 return _rosterId; 163 } 164 165 public void setRosterId(String roster) { 166 String oldValue = _rosterId; 167 _rosterId = roster; 168 firePropertyChange("RosterId", oldValue, _rosterId); // NOI18N 169 } 170 171 //Protocol is here as it is a potential value from the ecos 172 // We may not actually use it. 173 public String getECOSProtocol() { 174 return _ecosProtocolString; 175 } 176 177 //@TODO Need to udate this to return the new Protocol option from LocoAddress 178 public SpeedStepMode getSpeedStepMode() { 179 return _speedSteps; 180 } 181 182 public void setProtocol(String protocol) { 183 //funcexists 184 String oldValue = _ecosProtocolString; 185 _ecosProtocolString = protocol; 186 firePropertyChange("protocol", oldValue, _ecosProtocolString); 187 if (protocol.startsWith("DCC")) { 188 _protocol = LocoAddress.Protocol.DCC; 189 } else if (protocol.startsWith("MM")) { 190 _protocol = LocoAddress.Protocol.MOTOROLA; 191 } else if (protocol.startsWith("SX")) { //SX32 192 _protocol = LocoAddress.Protocol.SELECTRIX; 193 } else if (protocol.startsWith("LBG")) { //LBG14 194 _protocol = LocoAddress.Protocol.SELECTRIX; 195 } 196 if (protocol.endsWith("128")) { 197 _speedSteps = SpeedStepMode.NMRA_DCC_128; 198 } else if (protocol.endsWith("28")) { 199 _speedSteps = SpeedStepMode.NMRA_DCC_28; 200 } else if (protocol.endsWith("27")) { 201 _speedSteps = SpeedStepMode.NMRA_DCC_27; 202 } else if (protocol.endsWith("14")) { 203 _speedSteps = SpeedStepMode.NMRA_DCC_14; 204 } 205 } 206 207 @Override 208 public LocoAddress.Protocol getProtocol() { 209 return _protocol; 210 } 211 212 /* 213 The Temporary Entry Field is used to determine if JMRI has had to create the entry on an ad-hoc basis 214 for the throttle. If this is set to True, the throttle can evaluate this field to determine if the 215 loco should be removed from the Ecos Database when closing the application. 216 */ 217 boolean _tempEntry = false; 218 219 public void setEcosTempEntry(boolean boo) { 220 _tempEntry = boo; 221 } 222 223 public boolean getEcosTempEntry() { 224 return _tempEntry; 225 } 226 227 public void reply(EcosReply m) { 228 String msg = m.toString(); 229 if (m.getResultCode() != 0) { 230 return; //The result is not valid therefore we can not set it. 231 } 232 if (msg.startsWith("<REPLY get(" + _ecosObject + ",") || msg.startsWith("<EVENT " + _ecosObject + ">")) { 233 if (msg.contains("speed")) { 234 setSpeed(Integer.parseInt(EcosReply.getContentDetails(msg, "speed"))); 235 } 236 if (msg.contains("dir")) { 237 setDirection(getDirection(msg)); 238 } 239 if (msg.contains("protocol")) { 240 setProtocol(EcosReply.getContentDetails(msg, "protocol")); 241 } 242 if (msg.contains("name")) { 243 String name = EcosReply.getContentDetails(msg, "name").trim(); 244 setEcosDescription(name); 245 } 246 } 247 } 248 249 boolean getDirection(String line) { 250 boolean newDirection = false; 251 if (EcosReply.getContentDetails(line, "dir").equals("0")) { 252 newDirection = true; 253 } 254 return newDirection; 255 } 256 257 public void dispose() { 258 // nothing to do 259 } 260 261}