Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DCC++ ESP (WiFi enabled DCC++) customizations #4533

Merged
merged 2 commits into from Dec 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions java/src/jmri/jmrix/dccpp/DCCppConstants.java
Expand Up @@ -135,7 +135,9 @@ public final class DCCppConstants {
public final static String PROGRAM_REPLY_REGEX = "\\s*r\\s*(\\d+)\\|(\\d+)\\|(\\d+)\\s+([-]*\\d+)\\s*";
public final static String PROGRAM_BIT_REPLY_REGEX = "\\s*r\\s*(\\d+)\\|(\\d+)\\|(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*";
public final static String CURRENT_REPLY_REGEX = "\\s*a\\s*(\\d+)";
public final static String CURRENT_REPLY_NAMED_REGEX = "\\s*a\\s*(\\w+)\\s*(\\d+)";
public final static String TRACK_POWER_REPLY_REGEX = "\\s*p\\s*([0,1])\\s*";
public final static String TRACK_POWER_REPLY_NAMED_REGEX = "\\s*p\\s*(\\d+)\\s+(\\w+)\\s*";
public final static String SENSOR_REPLY_REGEX = "\\s*[Qq]\\s*(\\d+)\\s*";
public final static String SENSOR_DEF_REPLY_REGEX = "\\s*Q\\s*(\\d+)\\s+(\\d+)\\s+([0|1])\\s*";
public final static String SENSOR_ACTIVE_REPLY_REGEX = "\\s*Q\\s*(\\d+)\\s*";
Expand All @@ -148,6 +150,7 @@ public final class DCCppConstants {
// public final static String STATUS_REPLY_REGEX = "i(DCC\\+\\+.*): BUILD (.*)"; // V1.0
// public final static String STATUS_REPLY_REGEX = "i(DCC\\+\\+[^:]*): BUILD (.*)"; // V1.0 / V1.1
public final static String STATUS_REPLY_REGEX = "i(DCC\\+\\+[^:]*):(?:\\sBUILD)? (.*)"; // V1.0 / V1.1 / V1.2
public final static String STATUS_REPLY_ESP32_REGEX = "iDCC\\+\\+.*ESP32.*: V-([\\d\\.]+)\\s+/\\s+(.*)"; // V1.0
//public final static String STATUS_REPLY_REGEX = "i(DCC\\+\\+\\s?.*):\\s?(?:BUILD)? (.*)"; // V1.0 / V1.1 / V1.2
public final static String FREE_MEMORY_REPLY_REGEX = "\\s*f\\s*(\\d+)\\s*";
public final static String WRITE_EEPROM_REPLY_REGEX = "\\s*e\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*";
Expand Down
61 changes: 49 additions & 12 deletions java/src/jmri/jmrix/dccpp/DCCppReply.java
@@ -1,6 +1,5 @@
package jmri.jmrix.dccpp;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
Expand Down Expand Up @@ -45,7 +44,6 @@

public class DCCppReply extends jmri.jmrix.AbstractMRReply {

private ArrayList<Integer> valueList = new ArrayList<Integer>();
protected String myRegex;
protected StringBuilder myReply;

Expand All @@ -61,7 +59,6 @@ public DCCppReply() {
public DCCppReply(DCCppReply reply) {
super(reply);
setBinary(false);
valueList = new ArrayList<Integer>(reply.valueList);
myRegex = reply.myRegex;
myReply = reply.myReply;
}
Expand All @@ -70,11 +67,6 @@ public DCCppReply(DCCppReply reply) {
public DCCppReply(String reply) {
super();
setBinary(false);
valueList = new ArrayList<Integer>();
//char charList[] = reply.toCharArray();
//for(int i=0;i<charList.length;i++){
// valueList.add((int)charList[i]);
//}
myRegex = "";
myReply = new StringBuilder(reply);
_nDataChars = toString().length();
Expand Down Expand Up @@ -163,8 +155,14 @@ public String toMonitorString(){
text += "\tBuild: " + getStatusBuildDateString();
break;
case DCCppConstants.POWER_REPLY:
text = "Power Status: ";
text += ((char) (getElement(1) & 0x00FF) == '1' ? "ON" : "OFF");
if(isNamedPowerReply()) {
text = "Power Status: \n";
text += "\tName:" + getPowerDistrictName();
text += "\tStatus:" + getPowerDistrictStatus();
} else {
text = "Power Status: ";
text += ((char) (getElement(1) & 0x00FF) == '1' ? "ON" : "OFF");
}
break;
case DCCppConstants.CURRENT_REPLY:
text = "Current: " + getCurrentString() + " / 1024";
Expand Down Expand Up @@ -209,7 +207,6 @@ public void parseReply(String s) {
DCCppReply r = DCCppReply.parseDCCppReply(s);
log.debug("in parseReply() string: {}", s);
if (r != null) {
this.valueList = r.valueList;
this.myRegex = r.myRegex;
this.myReply = r.myReply;
this._nDataChars = r._nDataChars;
Expand All @@ -235,7 +232,10 @@ public static DCCppReply parseDCCppReply(String s) {
DCCppReply r = new DCCppReply(s);
switch(s.charAt(0)) {
case DCCppConstants.STATUS_REPLY:
if (s.matches(DCCppConstants.STATUS_REPLY_REGEX)) {
if (s.matches(DCCppConstants.STATUS_REPLY_ESP32_REGEX)) {
log.debug("Status Reply: {}", r.toString());
r.myRegex = DCCppConstants.STATUS_REPLY_ESP32_REGEX;
} else if (s.matches(DCCppConstants.STATUS_REPLY_REGEX)) {
log.debug("Status Reply: {}", r.toString());
r.myRegex = DCCppConstants.STATUS_REPLY_REGEX;
}
Expand Down Expand Up @@ -278,11 +278,15 @@ public static DCCppReply parseDCCppReply(String s) {
case DCCppConstants.POWER_REPLY:
if (s.matches(DCCppConstants.TRACK_POWER_REPLY_REGEX)) {
r.myRegex = DCCppConstants.TRACK_POWER_REPLY_REGEX;
} else if (s.matches(DCCppConstants.TRACK_POWER_REPLY_NAMED_REGEX)) {
r.myRegex = DCCppConstants.TRACK_POWER_REPLY_NAMED_REGEX;
}
return(r);
case DCCppConstants.CURRENT_REPLY:
if (s.matches(DCCppConstants.CURRENT_REPLY_REGEX)) {
r.myRegex = DCCppConstants.CURRENT_REPLY_REGEX;
} else if (s.matches(DCCppConstants.CURRENT_REPLY_NAMED_REGEX)) {
r.myRegex = DCCppConstants.CURRENT_REPLY_NAMED_REGEX;
}
return(r);
case DCCppConstants.WRITE_EEPROM_REPLY:
Expand Down Expand Up @@ -724,8 +728,35 @@ public int getReadValueInt() {
return(Integer.parseInt(this.getReadValueString()));
}

public String getPowerDistrictName() {
if (this.isNamedPowerReply()) {
return(this.getValueString(2));
} else {
log.error("NamedPowerReply Parser called on non-NamedPowerReply message type {} message {}", this.getOpCodeChar(), this.toString());
return("");
}
}

public String getPowerDistrictStatus() {
if (this.isNamedPowerReply()) {
if(this.getValueString(1).equals(DCCppConstants.POWER_OFF)) {
return("OFF");
} else if(this.getValueString(1).equals(DCCppConstants.POWER_ON)) {
return("ON");
} else {
return("OVERLOAD");
}
} else {
log.error("NamedPowerReply Parser called on non-NamedPowerReply message type {} message {}", this.getOpCodeChar(), this.toString());
return("");
}
}

public String getCurrentString() {
if (this.isCurrentReply()) {
if(this.isNamedCurrentReply()) {
return(this.getValueString(2));
}
return(this.getValueString(1));
} else {
log.error("CurrentReply Parser called on non-CurrentReply message type {} message {}", this.getOpCodeChar(), this.toString());
Expand Down Expand Up @@ -1000,7 +1031,9 @@ public String getCommTypeValueString() {
public boolean isProgramReply() { return (this.matches(DCCppConstants.PROGRAM_REPLY_REGEX)); }
public boolean isProgramBitReply() { return (this.matches(DCCppConstants.PROGRAM_BIT_REPLY_REGEX)); }
public boolean isPowerReply() { return (this.getOpCodeChar() == DCCppConstants.POWER_REPLY); }
public boolean isNamedPowerReply() { return(this.matches(DCCppConstants.TRACK_POWER_REPLY_NAMED_REGEX)); }
public boolean isCurrentReply() { return (this.getOpCodeChar() == DCCppConstants.CURRENT_REPLY); }
public boolean isNamedCurrentReply() { return(this.matches(DCCppConstants.CURRENT_REPLY_NAMED_REGEX)); }
public boolean isMemoryReply() { return (this.getOpCodeChar() == DCCppConstants.MEMORY_REPLY); }
public boolean isVersionReply() { return (this.getOpCodeChar() == DCCppConstants.STATUS_REPLY); }
// public boolean isListPacketRegsReply() { return (this.getOpCodeChar() == DCCppConstants.LISTPACKET_REPLY); }
Expand All @@ -1012,6 +1045,7 @@ public boolean isSensorReply() { return((this.getOpCodeChar() == DCCppConstants.
public boolean isMADCFailReply() { return(this.getOpCodeChar() == DCCppConstants.MADC_FAIL_REPLY); }
public boolean isMADCSuccessReply() { return(this.getOpCodeChar() == DCCppConstants.MADC_SUCCESS_REPLY); }
public boolean isStatusReply() { return(this.getOpCodeChar() == DCCppConstants.STATUS_REPLY); }
public boolean isESPStatusReply() { return(this.matches(DCCppConstants.STATUS_REPLY_ESP32_REGEX)); }
public boolean isFreeMemoryReply() { return(this.matches(DCCppConstants.FREE_MEMORY_REPLY_REGEX)); }
public boolean isOutputListReply() { return(this.matches(DCCppConstants.OUTPUT_LIST_REPLY_REGEX)); }
public boolean isOutputCmdReply() { return(this.matches(DCCppConstants.OUTPUT_REPLY_REGEX)); }
Expand All @@ -1025,7 +1059,9 @@ public boolean isValidReplyFormat() {
(this.matches(DCCppConstants.LIST_SENSORS_REPLY_REGEX)) ||
(this.matches(DCCppConstants.PROGRAM_REPLY_REGEX)) ||
(this.matches(DCCppConstants.TRACK_POWER_REPLY_REGEX)) ||
(this.matches(DCCppConstants.TRACK_POWER_REPLY_NAMED_REGEX)) ||
(this.matches(DCCppConstants.CURRENT_REPLY_REGEX)) ||
(this.matches(DCCppConstants.CURRENT_REPLY_NAMED_REGEX)) ||
(this.matches(DCCppConstants.SENSOR_REPLY_REGEX)) ||
(this.matches(DCCppConstants.BROKEN_SENSOR_REPLY_REGEX)) ||
(this.matches(DCCppConstants.SENSOR_DEF_REPLY_REGEX)) ||
Expand All @@ -1035,6 +1071,7 @@ public boolean isValidReplyFormat() {
(this.matches(DCCppConstants.MADC_FAIL_REPLY_REGEX)) ||
(this.matches(DCCppConstants.MADC_SUCCESS_REPLY_REGEX)) ||
(this.matches(DCCppConstants.STATUS_REPLY_REGEX)) ||
(this.matches(DCCppConstants.STATUS_REPLY_ESP32_REGEX)) ||
(this.isVersionReply())
) {
return(true);
Expand Down
35 changes: 35 additions & 0 deletions java/test/jmri/jmrix/dccpp/DCCppReplyTest.java
Expand Up @@ -74,6 +74,41 @@ public void testCommTypeReply() {

}

// Test named power districts
@Test
public void testNamedPowerDistrictReply() {
DCCppReply l = DCCppReply.parseDCCppReply("p 0 MAIN");
Assert.assertTrue(l.isNamedPowerReply());
Assert.assertEquals('p', l.getOpCodeChar());
Assert.assertEquals("MAIN", l.getPowerDistrictName());
Assert.assertEquals("OFF", l.getPowerDistrictStatus());

l = DCCppReply.parseDCCppReply("p 1 MAIN");
Assert.assertTrue(l.isNamedPowerReply());
Assert.assertEquals('p', l.getOpCodeChar());
Assert.assertEquals("MAIN", l.getPowerDistrictName());
Assert.assertEquals("ON", l.getPowerDistrictStatus());

l = DCCppReply.parseDCCppReply("p 2 MAIN");
Assert.assertTrue(l.isNamedPowerReply());
Assert.assertEquals('p', l.getOpCodeChar());
Assert.assertEquals("MAIN", l.getPowerDistrictName());
Assert.assertEquals("OVERLOAD", l.getPowerDistrictStatus());
}

// Test named power districts
@Test
public void testNamedCurrentReply() {
DCCppReply l = DCCppReply.parseDCCppReply("a MAIN 0");
Assert.assertTrue(l.isNamedCurrentReply());
Assert.assertEquals('a', l.getOpCodeChar());
Assert.assertEquals("0", l.getCurrentString());

l = DCCppReply.parseDCCppReply("a MAIN 100");
Assert.assertTrue(l.isNamedCurrentReply());
Assert.assertEquals('a', l.getOpCodeChar());
Assert.assertEquals("100", l.getCurrentString());
}
// The minimal setup for log4J
@Before
public void setUp() {
Expand Down