aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/org/traccar/protocol/WialonProtocolDecoder.java146
-rw-r--r--test/org/traccar/protocol/WialonProtocolDecoderTest.java3
-rwxr-xr-xtools/hex.sh2
3 files changed, 93 insertions, 58 deletions
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<Position> positions = new LinkedList<Position>();
+
+ 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;
diff --git a/test/org/traccar/protocol/WialonProtocolDecoderTest.java b/test/org/traccar/protocol/WialonProtocolDecoderTest.java
index 7b85dbd65..678126df0 100644
--- a/test/org/traccar/protocol/WialonProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/WialonProtocolDecoderTest.java
@@ -28,6 +28,9 @@ public class WialonProtocolDecoderTest {
verify(decoder.decode(null, null,
"#D#190114;051312;4459.6956;N;04105.9930;E;35;306;204.000000;12;NA;452986639;NA;106.000000;NA;sats_gps:1:9,sats_glonass:1:3,balance:2:12123.000000,stay_balance:1:0"));
+ verify(decoder.decode(null, null,
+ "#B#080914;073235;5027.50625;N;03026.19321;E;0.700;0.000;NA;4;NA;NA;NA;;NA;Батарея:3:100 %|080914;073420;5027.50845;N;03026.18854;E;1.996;292.540;NA;4;NA;NA;NA;;NA;Батарея:3:100 %"));
+
}
}
diff --git a/tools/hex.sh b/tools/hex.sh
index 7571531fe..2c3faa1ab 100755
--- a/tools/hex.sh
+++ b/tools/hex.sh
@@ -1,2 +1,2 @@
-echo 504f5354202f20485454502f312e310d0a436f6e74656e742d4c656e6774683a203133330d0a436f6e74656e742d547970653a206170706c69636174696f6e2f782d7777772d666f726d2d75726c656e636f6465640d0a486f73743a2064656d6f2e747261636361722e6f72673a353035350d0a436f6e6e656374696f6e3a204b6565702d416c6976650d0a557365722d4167656e743a20416e64726f69640d0a0d0a6c61743d33342e303532323334266c6f6e3d2d3131382e3234333638322674696d657374616d703d31333936383334373930267265715f74696d657374616d703d313339363833343739302661636375726163793d312e3026616c7469747564653d36352e302669643d313233343536373839266f66667365743d25324231322533413030 | perl -ne 's/([0-9a-f]{2})/print chr hex $1/gie' | nc -v -w 10 localhost 5055
+echo 2342233038303931343b3037333233353b353032372e35303632353b4e3b30333032362e31393332313b453b302e3730303b302e3030303b4e413b343b4e413b4e413b4e413b3b4e413bd091d0b0d182d0b0d180d0b5d18f3a333a31303020257c3038303931343b3037333432303b353032372e35303834353b4e3b30333032362e31383835343b453b312e3939363b3239322e3534303b4e413b343b4e413b4e413b4e413b3b4e413bd091d0b0d182d0b0d180d0b5d18f3a333a31303020250d0a | perl -ne 's/([0-9a-f]{2})/print chr hex $1/gie' | nc -v -w 10 localhost 5039
#echo -n -e "\x0f\x00\x00\x00\x4e\x52\x30\x39\x46\x30\x34\x31\x35\x35\x00" >/dev/udp/localhost/5053