diff options
Diffstat (limited to 'src/org/traccar/protocol/TotemProtocolDecoder.java')
-rw-r--r-- | src/org/traccar/protocol/TotemProtocolDecoder.java | 264 |
1 files changed, 190 insertions, 74 deletions
diff --git a/src/org/traccar/protocol/TotemProtocolDecoder.java b/src/org/traccar/protocol/TotemProtocolDecoder.java index 55698893c..58e975730 100644 --- a/src/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/org/traccar/protocol/TotemProtocolDecoder.java @@ -90,18 +90,69 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { "\\d+\\|" + // Serial Number "\\p{XDigit}{4}"); // Checksum + static private Pattern patternThird = Pattern.compile( + "\\$\\$" + // Header + "\\p{XDigit}{2}" + // Length + "(\\d+)\\|" + // IMEI + ".." + // Alarm Type + "(\\d{2})(\\d{2})(\\d{2})" + // Date (YYMMDD) + "(\\d{2})(\\d{2})(\\d{2})" + // Time (HHMMSS) + "(\\p{XDigit}{4})" + // IO Status + "[01]" + // Charging + "(\\d{2})" + // Battery + "(\\d{2})" + // External Power + "(\\d{4})" + // ADC 1 + "(\\d{4})" + // ADC 2 + "(\\d{3})" + // Temperature 1 + "(\\d{3})" + // Temperature 2 + "(\\p{XDigit}{8})" + // Location Code + "([AV])" + // Validity + "(\\d{2})" + // Satellites + "(\\d{3})" + // Course + "(\\d{3})" + // Speed + "(\\d{2}\\.\\d)" + // PDOP + "(\\d{7})" + // Milage + "(\\d{2})(\\d{2}\\.\\d{4})" + // Latitude (DDMM.MMMM) + "([NS])" + + "(\\d{3})(\\d{2}\\.\\d{4})" + // Longitude (DDDMM.MMMM) + "([EW])" + + "\\d{4}" + // Serial Number + "\\p{XDigit}{4}"); // Checksum + + private enum MessageFormat { + first, + second, + third + } + @Override protected Object decode( ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { String sentence = (String) msg; - - boolean first = sentence.contains("$GPRMC"); + + // Determine format + MessageFormat format = MessageFormat.third; + if (sentence.contains("$GPRMC")) { + format = MessageFormat.first; + } else { + int index = sentence.indexOf('|'); + if (index != -1 && sentence.indexOf('|', index + 1) != -1) { + format = MessageFormat.second; + } + } // Parse message - Matcher parser = first ? patternFirst.matcher(sentence) : patternSecond.matcher(sentence); - if (!parser.matches()) { + Matcher parser = null; + if (format == MessageFormat.first) { + parser = patternFirst.matcher(sentence); + } else if (format == MessageFormat.second) { + parser = patternSecond.matcher(sentence); + } else if (format == MessageFormat.third) { + parser = patternThird.matcher(sentence); + } + if (parser == null || !parser.matches()) { return null; } @@ -119,88 +170,153 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { Log.warning("Unknown device - " + imei); return null; } + + if (format == MessageFormat.first || format == MessageFormat.second) { - // Time - Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - time.clear(); - int year = 0; - if (!first) { - time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++))); - time.set(Calendar.MONTH, Integer.valueOf(parser.group(index++)) - 1); - year = Integer.valueOf(parser.group(index++)); - time.set(Calendar.YEAR, 2000 + year); - } - time.set(Calendar.HOUR, Integer.valueOf(parser.group(index++))); - time.set(Calendar.MINUTE, Integer.valueOf(parser.group(index++))); - time.set(Calendar.SECOND, Integer.valueOf(parser.group(index++))); - - // Validity - position.setValid(parser.group(index++).compareTo("A") == 0 ? true : false); - - // Latitude - Double latitude = Double.valueOf(parser.group(index++)); - latitude += Double.valueOf(parser.group(index++)) / 60; - if (parser.group(index++).compareTo("S") == 0) latitude = -latitude; - position.setLatitude(latitude); - - // Longitude - Double longitude = Double.valueOf(parser.group(index++)); - longitude += Double.valueOf(parser.group(index++)) / 60; - if (parser.group(index++).compareTo("W") == 0) longitude = -longitude; - position.setLongitude(longitude); - - // Speed - String speed = parser.group(index++); - if (speed != null) { - position.setSpeed(Double.valueOf(speed)); - } else { - position.setSpeed(0.0); - } + // Time + Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + time.clear(); + int year = 0; + if (format == MessageFormat.second) { + time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++))); + time.set(Calendar.MONTH, Integer.valueOf(parser.group(index++)) - 1); + year = Integer.valueOf(parser.group(index++)); + time.set(Calendar.YEAR, 2000 + year); + } + time.set(Calendar.HOUR, Integer.valueOf(parser.group(index++))); + time.set(Calendar.MINUTE, Integer.valueOf(parser.group(index++))); + time.set(Calendar.SECOND, Integer.valueOf(parser.group(index++))); - // Course - String course = parser.group(index++); - if (course != null) { - position.setCourse(Double.valueOf(course)); - } else { - position.setCourse(0.0); - } + // Validity + position.setValid(parser.group(index++).compareTo("A") == 0 ? true : false); - // Date - if (first) { - time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++))); + // Latitude + Double latitude = Double.valueOf(parser.group(index++)); + latitude += Double.valueOf(parser.group(index++)) / 60; + if (parser.group(index++).compareTo("S") == 0) latitude = -latitude; + position.setLatitude(latitude); + + // Longitude + Double longitude = Double.valueOf(parser.group(index++)); + longitude += Double.valueOf(parser.group(index++)) / 60; + if (parser.group(index++).compareTo("W") == 0) longitude = -longitude; + position.setLongitude(longitude); + + // Speed + String speed = parser.group(index++); + if (speed != null) { + position.setSpeed(Double.valueOf(speed)); + } else { + position.setSpeed(0.0); + } + + // Course + String course = parser.group(index++); + if (course != null) { + position.setCourse(Double.valueOf(course)); + } else { + position.setCourse(0.0); + } + + // Date + if (format == MessageFormat.first) { + time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++))); + time.set(Calendar.MONTH, Integer.valueOf(parser.group(index++)) - 1); + year = Integer.valueOf(parser.group(index++)); + time.set(Calendar.YEAR, 2000 + year); + } + if (year == 0) { + return null; // ignore invalid data + } + position.setTime(time.getTime()); + + // Altitude + position.setAltitude(0.0); + + // Accuracy + extendedInfo.set("hdop", parser.group(index++)); + + // IO Status + extendedInfo.set("io", parser.group(index++)); + + // Power + extendedInfo.set("battery", parser.group(index++)); + position.setPower(Double.valueOf(parser.group(index++))); + + // ADC + extendedInfo.set("adc", parser.group(index++)); + + // Location Code + extendedInfo.set("lac", parser.group(index++)); + + // Temperature + extendedInfo.set("temperature", parser.group(index++)); + + // Milage + extendedInfo.set("milage", parser.group(index++)); + + } else if (format == MessageFormat.third) { + + // Time + Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + time.clear(); + time.set(Calendar.YEAR, 2000 + Integer.valueOf(parser.group(index++))); time.set(Calendar.MONTH, Integer.valueOf(parser.group(index++)) - 1); - year = Integer.valueOf(parser.group(index++)); - time.set(Calendar.YEAR, 2000 + year); - } - if (year == 0) { - return null; // ignore invalid data - } - position.setTime(time.getTime()); + time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++))); + time.set(Calendar.HOUR, Integer.valueOf(parser.group(index++))); + time.set(Calendar.MINUTE, Integer.valueOf(parser.group(index++))); + time.set(Calendar.SECOND, Integer.valueOf(parser.group(index++))); + position.setTime(time.getTime()); + + // IO Status + extendedInfo.set("io", parser.group(index++)); + + // Power + extendedInfo.set("battery", Double.valueOf(parser.group(index++)) / 10); + position.setPower(Double.valueOf(parser.group(index++))); - // Altitude - position.setAltitude(0.0); + // ADC + extendedInfo.set("adc1", parser.group(index++)); + extendedInfo.set("adc2", parser.group(index++)); - // Accuracy - extendedInfo.set("hdop", parser.group(index++)); + // Temperature + extendedInfo.set("temperature1", parser.group(index++)); + extendedInfo.set("temperature2", parser.group(index++)); - // IO Status - extendedInfo.set("io", parser.group(index++)); + // Location Code + extendedInfo.set("lac", parser.group(index++)); - // Power - extendedInfo.set("battery", parser.group(index++)); - position.setPower(Double.valueOf(parser.group(index++))); + // Validity + position.setValid(parser.group(index++).compareTo("A") == 0 ? true : false); - // ADC - extendedInfo.set("adc", parser.group(index++)); + // Satellites + extendedInfo.set("satellites", parser.group(index++)); - // Location Code - extendedInfo.set("lac", parser.group(index++)); + // Course + position.setCourse(Double.valueOf(parser.group(index++))); - // Temperature - extendedInfo.set("temperature", parser.group(index++)); + // Speed + position.setSpeed(Double.valueOf(parser.group(index++))); - // Milage - extendedInfo.set("milage", parser.group(index++)); + // PDOP + extendedInfo.set("pdop", parser.group(index++)); + + // Milage + extendedInfo.set("milage", parser.group(index++)); + + // Latitude + Double latitude = Double.valueOf(parser.group(index++)); + latitude += Double.valueOf(parser.group(index++)) / 60; + if (parser.group(index++).compareTo("S") == 0) latitude = -latitude; + position.setLatitude(latitude); + + // Longitude + Double longitude = Double.valueOf(parser.group(index++)); + longitude += Double.valueOf(parser.group(index++)) / 60; + if (parser.group(index++).compareTo("W") == 0) longitude = -longitude; + position.setLongitude(longitude); + + } // Extended info position.setExtendedInfo(extendedInfo.toString()); |