aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java74
-rw-r--r--src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java17
2 files changed, 89 insertions, 2 deletions
diff --git a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java
index a2fccb707..0f815ca7b 100644
--- a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java
@@ -1,5 +1,6 @@
/*
* Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2020 Roeland Boeters (roeland@geodelta.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +20,9 @@ import io.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
import org.traccar.Protocol;
+import org.traccar.helper.DateBuilder;
+import org.traccar.helper.Parser;
+import org.traccar.helper.PatternBuilder;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.CellTower;
import org.traccar.model.Network;
@@ -30,7 +34,10 @@ import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
import java.util.TimeZone;
+import java.util.regex.Pattern;
public class MictrackProtocolDecoder extends BaseProtocolDecoder {
@@ -38,6 +45,19 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
+ private static final Pattern PATTERN_LOW_ALTITUDE = new PatternBuilder()
+ .number("(dd)(dd)(dd).d+,") // time (hhmmss.sss)
+ .expression("([AV]),") // validity
+ .number("(d+)(dd.d+),") // latitude
+ .expression("([NS]),")
+ .number("(d+)(dd.d+),") // longitude
+ .expression("([EW]),")
+ .number("(d+.?d*)?,") // speed
+ .number("(d+.?d*)?,") // course
+ .number("(d+.?d*)?,") // altitude
+ .number("(dd)(dd)(dd)") // date (ddmmyy)
+ .compile();
+
private Date decodeTime(String data) throws ParseException {
DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
@@ -142,8 +162,18 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder {
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ String sentence = ((String) msg).trim();
+
+ if (sentence.startsWith("MT")) {
+ return decodeStandard(channel, remoteAddress, sentence);
+ } else {
+ return decodeLowAltitude(channel, remoteAddress, sentence);
+ }
+ }
- String[] fragments = ((String) msg).split(";");
+ private Object decodeStandard(
+ Channel channel, SocketAddress remoteAddress, String sentence) throws Exception {
+ String[] fragments = sentence.split(";");
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, fragments[2]);
if (deviceSession == null) {
@@ -178,4 +208,46 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder {
return position;
}
+ private Object decodeLowAltitude(
+ Channel channel, SocketAddress remoteAddress, String sentence) throws Exception {
+ String deviceId = sentence.substring(0, sentence.indexOf("$"));
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, deviceId);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ String[] fragments = sentence.substring(sentence.indexOf("$")).split("\\$");
+
+ List<Position> positions = new LinkedList<>();
+
+ for (String message : fragments) {
+ Parser parser = new Parser(PATTERN_LOW_ALTITUDE, message);
+
+ if (parser.matches()) {
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ DateBuilder dateBuilder = new DateBuilder()
+ .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
+
+ position.setValid(parser.next().equals("A"));
+ position.setLatitude(parser.nextCoordinate());
+ position.setLongitude(parser.nextCoordinate());
+
+ position.setSpeed(parser.nextDouble(0));
+ position.setCourse(parser.nextDouble(0));
+ position.setAltitude(parser.nextDouble(0));
+
+ dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
+ position.setTime(dateBuilder.getDate());
+
+ positions.add(position);
+ }
+ }
+
+ return positions;
+ }
+
}
diff --git a/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java
index 794b2b57e..605a02b92 100644
--- a/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java
@@ -6,7 +6,7 @@ import org.traccar.ProtocolTest;
public class MictrackProtocolDecoderTest extends ProtocolTest {
@Test
- public void testDecode() throws Exception {
+ public void testDecodeStandard() throws Exception {
MictrackProtocolDecoder decoder = new MictrackProtocolDecoder(null);
@@ -31,7 +31,22 @@ public class MictrackProtocolDecoderTest extends ProtocolTest {
verifyAttributes(decoder, text(
"MT;5;866425031379169;RH;5+190116112648+0+0+0+0+11+3954+1"));
+ }
+
+ @Test
+ public void testDecodeLowAltitude() throws Exception {
+
+ MictrackProtocolDecoder decoder = new MictrackProtocolDecoder(null);
+
+ verifyPositions(decoder, text(
+ "861108032038761$062232.00,A,2238.2832,N,11401.7381,E,0.01,309.62,95.0,131117"));
+
+ verifyPositions(decoder, text(
+ "861108032038761$062232.00,A,2238.2832,N,11401.7381,E,0.01,309.62,95.0,131117$062332.00,A,2238.2836,N,11401.7386,E,0.06,209.62,95.0,131117"));
+ verifyPositions(decoder, text(
+ "861108032038761$062232.00,A,2238.2832,N,11401.7381,E,0.01,309.62,95.0,131117"),
+ position("2017-11-13 06:22:32.000", true, 22.63806, 114.028976));
}
}