Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

-Deleted a duplicate of the original request document.

-Cleaned up the Encoder a bit and made the commands all return strings.
-Wrote a ton of RegEx in the Decoder. It currently seems to successfully classify 5 types of messages: Detections, Status messages, What I am calling "generic" messages that it sends to acknowledge most commands, the RTMINFO response, and the INFO response. Anything else it classifies as unknown.
-Next up is actually doing something with those messages.
  • Loading branch information...
commit 06b8749acefa7e3acef9d9d10b0f746194a192c4 1 parent cddfc7f
@Teltnuag Teltnuag authored
View
83 ReceiverMultiplex/ReceiverMultiplex/Decoder.cs
@@ -3,11 +3,92 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Text.RegularExpressions;
namespace ReceiverMultiplex
{
public class Decoder
{
+ enum messageTypes { DETECTION, STATUS, GENERIC, RTMINFO, INFO, UNKNOWN };
+ //"Words"
+ private static string timestamp = "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}"; //Note: The timestamp given during the main part of the message is given in UTC, regardless of the offset.
+ private static string receiverSerial = "[0-9]{6}";
+ private static string transmitterSerial = "[A-Z0-9]{3}-[A-Z0-9]{4}"; //Note: The only serials we have seen were specifically of the form [A-Z][0-9]{2}-[0-9]{4}, so this may be more open than need be.
+ private static string detectionCounter = "[0-9]{3}";
+ private static string hexSum = "#[A-F0-9]{2}";
+ private static string detectionData = "([0-9]+,)*"; //Little worried about this one, as it could catch many things. However, this might just solve the different transmitter type problem. Note that it ends with a comma.
+ private static string status = "(OK|FAILURE|INVALID)";
+ private static string p = "[0-9]"; //Currently always 0, but we should provide as much functionality for the possibility of that changing in the future.
+ private static string decimalSum = "#[0-9]{2}";
+ private static string byteCount = "\\[[0-9]{4}\\]"; //Escape sequences for escape sequences...
+ private static string infoSerial = "[0-9A-Z]+-[0-9A-Z]+:";
+ private static string studyName = "'[0-9A-Z]*'";
+ private static string map = "[A-Z0-9]+-[0-9]+"; //I have no idea what this is.
+ private static string codespace = "\\[ ([0-9]{4}( |/))*\\]"; //Nor this.
+ private static string firmwareVersion = "FW=([0-9]+\\.)*[0-9]+";
+ private static string hardwareVersion = "HW=[0-9]+";
+ private static string DC = "DC=[0-9]+";
+ private static string PC = "PC=[0-9]+";
+ private static string LV = "LV=[0-9]+\\.[0-9]+";
+ private static string BV = "BV=[0-9]+\\.[0-9]+";
+ private static string BU = "BU=[0-9]+\\.[0-9]+";
+ private static string I = "I=[0-9]+\\.[0-9]+";
+ private static string T = "T=[0-9]+\\.[0-9]+";
+ private static string DU = "DU=[0-9]+\\.[0-9]+";
+ private static string RU = "RU=[0-9]+\\.[0-9]+";
+ private static string XYZ = "XYZ=-?[0-9]+\\.[0-9]+:-?[0-9]+\\.[0-9]+:-?[0-9]+\\.[0-9]+"; //This doesn't show up if the lousy thing is in storage mode.
+ private static string state = "[A-Z]+"; //RECORDING or STORAGE is what we've seen
+ private static string RTMType = "(OFF|232|485)";
+ private static string SI = "SI=(POLL|[0-9]+)";
+ private static string BL = "BL=(U|[0-9]+)";
+ private static string BI = "BI=(WFS|[0-9]+)";
+ private static string MA = "MA=(U|[0-9]+)";
+ private static string FMT = "FMT=([A-Z_ ])*";
+ private static string endline = "\\r\\n";
+
+ //"Sentences"
+ private static string detectionEvent = receiverSerial + ',' + detectionCounter + ',' + timestamp + ',' + transmitterSerial + ',' + detectionData + hexSum; //Note that detectionData ends with a comma, and that the transmitterSerial is considered part of the info field
+ //[0-9]{6},[0-9]{3},[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[A-Z0-9]{3}-[A-Z0-9]{4},([0-9]+,)*#[A-F0-9]{2}\r\n
+ //Responses arrive in the format *SSSSSS.P#CC[LLLL],response,status,#HH\r\n
+ //The responsePrefix handles the *SSSSSS.P#CC[LLLL], portion.
+ //The responseSuffix handles the ,status,#HH portion.
+ private static string responsePrefix = "\\*" + receiverSerial + '.' + p + decimalSum + byteCount + ',';
+ private static string responseSuffix = ',' + status + ',' + hexSum;
+ private static string genericResponse = responsePrefix + responseSuffix.Substring(1); //Most commands do not have a value for "response"
+ private static string RTMInfoResponse = RTMType + ',' + SI + ',' + BL + ',' + BI + ',' + MA + ',' + FMT;
+ //232|485|OFF,SI=POLL|X,BL=U|X,BI=WFS|X,MA=U|X,FMT=SER SEQ UTC CS
+ private static string infoResponse = infoSerial + receiverSerial + ',' + studyName + ',' + map + " " + codespace + ',' + firmwareVersion + ',' + hardwareVersion;
+ //SN, study string, map, codespace list, FW Version, HW Version
+ private static string statusResponse = "STS," + DC + ',' + PC + ',' + LV + ',' + BV + ',' + BU + ',' + I + ',' + T + ',' + DU + ',' + RU;
+ //STS,DC=X,PC=X,LV=X.X,BV=X.X,BU=X.X,I=X.X,T=X.X,DU=X.X,RU=X.X,XYZ=-X.XX:-Y.YY:Z.ZZ
+ /* Note that there are actually two varieties of this, one that is periodically sent out during RTM mode,
+ * and one that is explicitly requested by the STATUS command. From our test data, the XYZ will not show up
+ * if the receiver is in STORAGE mode. There is an additonal field in the manual STATUS command that
+ * tells you what the state of the receiver is. Thanks for not documenting that.*/
+
+ public int Decode(string message)
+ //Will presumably return an instance of your event class
+ {
+ int messageType = getMessageType(message);
+
+ return messageType; //magic
+ }
+
+ private int getMessageType(string unparsedMessage)
+ {
+ if (Regex.IsMatch(unparsedMessage, detectionEvent))
+ return (int)messageTypes.DETECTION;
+ else if (Regex.IsMatch(unparsedMessage, statusResponse))
+ return (int)messageTypes.STATUS;
+ else if (Regex.IsMatch(unparsedMessage, genericResponse))
+ return (int)messageTypes.GENERIC;
+ else if (Regex.IsMatch(unparsedMessage, RTMInfoResponse))
+ return (int)messageTypes.RTMINFO;
+ else if (Regex.IsMatch(unparsedMessage, infoResponse))
+ return (int)messageTypes.INFO;
+ else
+ return (int)messageTypes.UNKNOWN;
+ }
}
-}
+}
View
121 ReceiverMultiplex/ReceiverMultiplex/Encoder.cs
@@ -11,9 +11,7 @@ public class Encoder
private String prefix; //Will be made to be *SSSSSS.P#CC,
public Encoder(int serial, int p = 0)
- {
- UpdatePrefix(serial, p);
- }
+ { UpdatePrefix(serial, p); }
public void UpdatePrefix(int serial, int p = 0) //Sets the prefix part of the commands. This must be called if the serial were to be changed for some reason, or if the p-value was changed.
{
@@ -42,22 +40,16 @@ public Encoder(int serial, int p = 0)
}
}
- public void STATUS() //Read status string
- {
- SendCommand("STATUS");
- }
+ public String STATUS() //Read status string
+ { return BuildCommand("STATUS"); }
- public void INFO()
- {
- SendCommand("INFO");
- }
+ public String INFO()
+ { return BuildCommand("INFO"); }
- public void BAUDRATE(int baud) //Set the serial port baud rate (default rate is 9600, 8N1 protocol)
- {
- SendCommand("BAUDRATE=" + baud.ToString());
- }
+ public String BAUDRATE(int baud) //Set the serial port baud rate (default rate is 9600, 8N1 protocol)
+ { return BuildCommand("BAUDRATE=" + baud.ToString()); }
- public void TIME(int year, int month, int day, int hour, int minutes, int seconds) //Set receiver clock, x = 24 hour UTC time as YYYY-MM-DD HH:MM:SS or local time as YYYY-MM-DD HH:MM:SS +ZZZZ
+ public String TIME(int year, int month, int day, int hour, int minutes, int seconds) //Set receiver clock, x = 24 hour UTC time as YYYY-MM-DD HH:MM:SS or local time as YYYY-MM-DD HH:MM:SS +ZZZZ
{
try
{
@@ -110,15 +102,16 @@ public void BAUDRATE(int baud) //Set the serial port baud rate (default rate is
Seconds = "0" + Seconds;
}
- SendCommand("TIME=" + year.ToString() + "-" + Month + "-" + Day + " " + Hour + ":" + Minutes + ":" + Seconds);
+ return BuildCommand("TIME=" + year.ToString() + "-" + Month + "-" + Day + " " + Hour + ":" + Minutes + ":" + Seconds);
}
catch(InvalidCommandException e)
{
Console.WriteLine(e.Message);
+ return null;
}
}
- public void TIME(int year, int month, int day, int hour, int minutes, int seconds, char offsetSign, int offsetHours, int offsetMinutes)
+ public String TIME(int year, int month, int day, int hour, int minutes, int seconds, char offsetSign, int offsetHours, int offsetMinutes)
{
try
{
@@ -178,91 +171,69 @@ public void TIME(int year, int month, int day, int hour, int minutes, int second
Offset = offsetSign + offsetHours.ToString() + offsetMinutes.ToString();
}
- SendCommand("TIME=" + year.ToString() + "-" + Month + "-" + Day + " " + Hour + ":" + Minutes + ":" + Seconds + " " + Offset);
+ return BuildCommand("TIME=" + year.ToString() + "-" + Month + "-" + Day + " " + Hour + ":" + Minutes + ":" + Seconds + " " + Offset);
}
catch(InvalidCommandException e)
{
Console.WriteLine(e.Message);
+ return null;
}
}
- public void START() //Start recording
- {
- SendCommand("START");
- }
+ public String START() //Start recording
+ { return BuildCommand("START"); }
- public void STOP() //Stop recording (Recording restarts after an hour)
- {
- SendCommand("STOP");
- }
+ public String STOP() //Stop recording (Recording restarts after an hour)
+ { return BuildCommand("STOP"); }
- public void ERASE() //Erase data (must be stopped)
- {
- SendCommand("ERASE");
- }
+ public String ERASE() //Erase data (must be stopped)
+ { return BuildCommand("ERASE"); }
- public void RTMINFO() //Read Real-Time mode configuration
- {
- SendCommand("RTMINFO");
- }
+ public String RTMINFO() //Read Real-Time mode configuration
+ { return BuildCommand("RTMINFO"); }
- public void RTMOFF() //Disables RTM output
- {
- SendCommand("RTMOFF");
- }
+ public String RTMOFF() //Disables RTM output
+ { return BuildCommand("RTMOFF"); }
- public void RTM232() //Resets RTM state and enables output on the RS232 lines
- {
- SendCommand("RTM232");
- }
+ public String RTM232() //Resets RTM state and enables output on the RS232 lines
+ { return BuildCommand("RTM232"); }
- public void RTM485() //Resets RTM state and enables output on the RS485 lines
- {
- SendCommand("RTM485");
- }
+ public String RTM485() //Resets RTM state and enables output on the RS485 lines
+ { return BuildCommand("RTM485"); }
- public void RTMNOW() //Resets RTM schedule (used for Polling)
- {
- SendCommand("RTMNOW");
- }
+ public String RTMNOW() //Resets RTM schedule (used for Polling)
+ { return BuildCommand("RTMNOW"); }
- public void RTMPROFILE(int profile) //Select a RTM output method where x = 0,1,2...
+ public String RTMPROFILE(int profile) //Select a RTM output method where x = 0,1,2...
{
if (profile < 0)
throw new InvalidCommandException("Invalid profile. Valid range is nonnegative integers.");
- SendCommand("RTMPROFILE=" + profile);
+ return BuildCommand("RTMPROFILE=" + profile);
}
- public void RTMAUTOERASE(int threshold) //Set the auto erase threshold. x = % of log to keep free, 0-50
+ public String RTMAUTOERASE(int threshold) //Set the auto erase threshold. x = % of log to keep free, 0-50
{
if (threshold < 0 || threshold > 50)
throw new InvalidCommandException("Invalid auto-erase threshold. Valid range is 0-50.");
- SendCommand("RTMAUTOERASE=" + threshold);
+ return BuildCommand("RTMAUTOERASE=" + threshold);
}
- public void STORAGE() //Put the receiver in low power state for storage (must be stopped)
- {
- SendCommand("STORAGE");
- }
+ public String STORAGE() //Put the receiver in low power state for storage (must be stopped)
+ { return BuildCommand("STORAGE"); }
- public void RESET() //Reset receiver (must be stopped)
- {
- SendCommand("RESET");
- }
+ public String RESET() //Reset receiver (must be stopped)
+ { return BuildCommand("RESET"); }
- public void QUIT() //Exit command session (Disables serial drivers)
- {
- SendCommand("QUIT");
- }
+ public String QUIT() //Exit command session (Disables serial drivers)
+ { return BuildCommand("QUIT"); }
- public void RESETBATTERY() //Resets the battery indicator. ONLY TO BE USED AFTER INSTALLING A FRESH BATTERY!
- {
- SendCommand("RESETBATTERY");
- }
+ public String RESETBATTERY() //Resets the battery indicator. ONLY TO BE USED AFTER INSTALLING A FRESH BATTERY!
+ { return BuildCommand("RESETBATTERY"); }
- public void SendCommand(String command) //Sends the actual command -- public so a user could in theory send their own command by console using this.
- {
- //domagic(prefix + command + "\r");
- }
+ public String CustomCommand(String command) //Allows for the sending of any other command.
+ { return BuildCommand(command); }
+
+ private String BuildCommand(String command) //Returns the actual command
+ { return (prefix + command + "\r"); }
}
}
View
BIN  docs/VR2C_Requests.pdf
Binary file not shown
Please sign in to comment.
Something went wrong with that request. Please try again.