001package jmri.jmrix.ecos; 002 003import java.util.regex.Matcher; 004import java.util.regex.Pattern; 005import jmri.DccLocoAddress; 006import jmri.IdTag; 007import jmri.IdTagManager; 008import jmri.InstanceManager; 009import jmri.LocoAddress; 010import jmri.PhysicalLocationReporter; 011import jmri.implementation.AbstractReporter; 012import jmri.util.PhysicalLocation; 013import org.slf4j.Logger; 014import org.slf4j.LoggerFactory; 015 016/** 017 * Extend jmri.AbstractReporter for Ecos Reporters Implemenation for providing 018 * status of rail com decoders at this reporter location. 019 * <p> 020 * The reporter will decode the rail com packets and add the information to the 021 * rail com tag. 022 * 023 * @author Kevin Dickerson Copyright (C) 2012 024 */ 025public class EcosReporter extends AbstractReporter implements PhysicalLocationReporter { 026 027 public EcosReporter(String systemName, String userName) { // a human-readable Reporter number must be specified! 028 super(systemName, userName); // can't use prefix here, as still in construction 029 } 030 031 /** 032 * Provide an int value for use in scripts, etc. This will be the numeric 033 * locomotive address last seen, unless the last message said the loco was 034 * exiting. Note that there may still some other locomotive in the 035 * transponding zone! 036 * 037 * @return -1 if the last message specified exiting 038 */ 039 @Override 040 public int getState() { 041 return lastLoco; 042 } 043 044 @Override 045 public void setState(int s) { 046 lastLoco = s; 047 } 048 int lastLoco = -1; 049 050 private int object; 051 private int port; 052 053 public int getObjectId() { 054 return object; 055 } 056 057 public int getPort() { 058 return port; 059 } 060 061 public void setObjectPort(int object, int port) { 062 this.object = object; 063 this.port = port; 064 } 065 066 //This could possibly do with a debounce option being added 067 public void decodeDetails(String msg) { 068 int start = msg.indexOf('[') + 1; 069 int end = msg.indexOf(']'); 070 String[] result = msg.substring(start, end).split(","); 071 result[1] = result[1].trim(); 072 if (!result[1].equals("0000")) { 073 IdTag idTag = jmri.InstanceManager.getDefault(jmri.IdTagManager.class).provideIdTag(result[1]); 074 setReport(idTag); 075 } else { 076 setReport(null); 077 } 078 } 079 080 // Methods to support PhysicalLocationReporter interface 081 082 /** 083 * Get the locomotive address we're reporting about from the current report. 084 * 085 * Note: We ignore the string passed in, because Ecos Reporters don't send 086 * String type reports. 087 */ 088 @Override 089 public LocoAddress getLocoAddress(String rep) { 090 // For now, we assume the current report. 091 // IdTag.getTagID() is a system-name-ized version of the loco address. I think. 092 // Matcher.group(1) : loco address (I think) 093 IdTag cr = (IdTag) this.getCurrentReport(); 094 IdTagManager tm = InstanceManager.getDefault(IdTagManager.class); 095 Pattern p = Pattern.compile("" + tm.getSystemPrefix() + tm.typeLetter() + "(\\d+)"); 096 Matcher m = p.matcher(cr.getTagID()); 097 if (m.find()) { 098 log.debug("Parsed address: {}", m.group(1)); 099 // I have no idea what kind of loco address an Ecos reporter uses, 100 // so we'll default to DCC for now. 101 return (new DccLocoAddress(Integer.parseInt(m.group(1)), LocoAddress.Protocol.DCC)); 102 } else { 103 return (null); 104 } 105 } 106 107 /** 108 * Get the direction (ENTER/EXIT) of the report. Because of the way Ecos. 109 * Reporters work (or appear to), all reports are ENTER type. 110 */ 111 @Override 112 public PhysicalLocationReporter.Direction getDirection(String rep) { 113 // TEMPORARY: Assume we're always Entering, if asked. 114 return (PhysicalLocationReporter.Direction.ENTER); 115 } 116 117 /** 118 * Get the PhysicalLocation of the Reporter 119 * <p> 120 * Reports its own location, for now. Not sure if that's the right thing or 121 * not. NOT DONE YET 122 */ 123 @Override 124 public PhysicalLocation getPhysicalLocation() { 125 return (this.getPhysicalLocation(null)); 126 } 127 128 /** 129 * Get the PhysicalLocation of the Reporter. 130 * 131 * @param s is not used 132 */ 133 @Override 134 public PhysicalLocation getPhysicalLocation(String s) { 135 return (PhysicalLocation.getBeanPhysicalLocation(this)); 136 } 137 138 private final static Logger log = LoggerFactory.getLogger(EcosReporter.class); 139 140}