From 0bf776895d82bf70a0e29c67a064024cd24a8927 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 10 Sep 2014 23:30:11 +1200 Subject: Support Wialon black box --- .../traccar/protocol/WialonProtocolDecoder.java | 146 +++++++++++++-------- 1 file changed, 89 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/org/traccar/protocol/WialonProtocolDecoder.java b/src/org/traccar/protocol/WialonProtocolDecoder.java index 1ece527d8..6ed597d2f 100644 --- a/src/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/org/traccar/protocol/WialonProtocolDecoder.java @@ -16,6 +16,8 @@ package org.traccar.protocol; import java.util.Calendar; +import java.util.LinkedList; +import java.util.List; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -36,7 +38,6 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } private static final Pattern pattern = Pattern.compile( - "#S?D#" + "(\\d{2})(\\d{2})(\\d{2});" + // Date (DDMMYY) "(\\d{2})(\\d{2})(\\d{2});" + // Time (HHMMSS) "(\\d{2})(\\d{2}\\.\\d+);" + // Latitude (DDMM.MMMM) @@ -45,7 +46,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { "([EW]);" + "(\\d+\\.?\\d*);" + // Speed "(\\d+\\.?\\d*);" + // Course - "(\\d+\\.?\\d*);" + // Altitude + "(?:(\\d+\\.?\\d*)|NA);" + // Altitude "(\\d+)" + // Satellites ".*"); // Full format @@ -59,6 +60,69 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { channel.write(response.toString()); } } + + private Position decodePosition(String substring) { + + // Parse message + Matcher parser = pattern.matcher(substring); + if (deviceId == null || !parser.matches()) { + return null; + } + + // Create new position + Position position = new Position(); + ExtendedInfoFormatter extendedInfo = new ExtendedInfoFormatter("wialon"); + position.setDeviceId(deviceId); + + Integer index = 1; + + // Date and Time + Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + time.clear(); + time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++))); + time.set(Calendar.MONTH, Integer.valueOf(parser.group(index++)) - 1); + time.set(Calendar.YEAR, 2000 + Integer.valueOf(parser.group(index++))); + time.set(Calendar.HOUR_OF_DAY, 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()); + + // 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 + position.setSpeed(Double.valueOf(parser.group(index++)) * 0.539957); + + // Course + position.setCourse(Double.valueOf(parser.group(index++))); + + // Altitude + String altitude = parser.group(index++); + if (altitude != null) { + position.setAltitude(Double.valueOf(altitude)); + } else { + position.setAltitude(0.0); + } + + // Satellites + int satellites = Integer.valueOf(parser.group(index++)); + position.setValid(satellites >= 3); + extendedInfo.set("satellites", satellites); + + // Extended info + position.setExtendedInfo(extendedInfo.toString()); + + return position; + } @Override protected Object decode( @@ -84,65 +148,33 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } // Parse message - else if ((sentence.startsWith("#SD#") || sentence.startsWith("#D#")) && deviceId != null) { + else if (sentence.startsWith("#SD#") || sentence.startsWith("#D#")) { - // Parse message - Matcher parser = pattern.matcher(sentence); - if (!parser.matches()) { - return null; - } + Position position = decodePosition( + sentence.substring(sentence.indexOf('#', 1) + 1)); - // Create new position - Position position = new Position(); - ExtendedInfoFormatter extendedInfo = new ExtendedInfoFormatter("wialon"); - position.setDeviceId(deviceId); - - Integer index = 1; - - // Date and Time - Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - time.clear(); - time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++))); - time.set(Calendar.MONTH, Integer.valueOf(parser.group(index++)) - 1); - time.set(Calendar.YEAR, 2000 + Integer.valueOf(parser.group(index++))); - time.set(Calendar.HOUR_OF_DAY, 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()); - - // 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 - position.setSpeed(Double.valueOf(parser.group(index++)) * 0.539957); - - // Course - position.setCourse(Double.valueOf(parser.group(index++))); - - // Altitude - position.setAltitude(Double.valueOf(parser.group(index++))); - - // Satellites - int satellites = Integer.valueOf(parser.group(index++)); - position.setValid(satellites >= 3); - extendedInfo.set("satellites", satellites); + if (position != null) { + sendResponse(channel, "#AD#", 1); + return position; + } + } + + else if (sentence.startsWith("#B#")) { - // Extended info - position.setExtendedInfo(extendedInfo.toString()); - - // Send response - sendResponse(channel, "#AD#", 1); + String[] messages = sentence.substring(sentence.indexOf('#', 1) + 1).split("\\|"); + List positions = new LinkedList(); + + for (String message : messages) { + Position position = decodePosition(message); + if (position != null) { + positions.add(position); + } + } - return position; + if (!positions.isEmpty()) { + sendResponse(channel, "#AB#", positions.size()); + return positions; + } } return null; -- cgit v1.2.3