From d63222309ed80155033d6458a163acd76f46f9a6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 19 Aug 2018 12:33:13 +1200 Subject: Extend Atrack text format support --- .../traccar/protocol/AtrackProtocolDecoder.java | 97 +++++++++++++++++++--- .../protocol/AtrackProtocolDecoderTest.java | 13 +-- 2 files changed, 95 insertions(+), 15 deletions(-) diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java index 4a2d4b848..ff4e0efeb 100644 --- a/src/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java @@ -104,20 +104,79 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { } private void readTextCustomData(Position position, String data, String form) { + CellTower cellTower = new CellTower(); String[] keys = form.substring(1).split("%"); String[] values = data.split(",|\r\n"); for (int i = 0; i < Math.min(keys.length, values.length); i++) { switch (keys[i]) { + case "SA": + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[i])); + break; case "MV": position.set(Position.KEY_POWER, Integer.parseInt(values[i]) * 0.1); break; case "BV": position.set(Position.KEY_BATTERY, Integer.parseInt(values[i]) * 0.1); break; + case "GQ": + cellTower.setSignalStrength(Integer.parseInt(values[i])); + break; + case "CE": + cellTower.setCellId(Long.parseLong(values[i])); + break; + case "LC": + cellTower.setLocationAreaCode(Integer.parseInt(values[i])); + break; + case "CN": + cellTower.setMobileCountryCode(Integer.parseInt(values[i].substring(0, 3))); + cellTower.setMobileNetworkCode(Integer.parseInt(values[i].substring(3))); + break; + case "PC": + position.set(Position.PREFIX_COUNT + 1, Integer.parseInt(values[i])); + break; + case "AT": + position.setAltitude(Integer.parseInt(values[i])); + break; + case "RP": + position.set(Position.KEY_RPM, Integer.parseInt(values[i])); + break; + case "GS": + position.set(Position.KEY_RSSI, Integer.parseInt(values[i])); + break; + case "DT": + position.set(Position.KEY_ARCHIVE, Integer.parseInt(values[i]) == 1); + break; + case "VN": + position.set(Position.KEY_VIN, values[i]); + break; + case "TR": + position.set(Position.KEY_THROTTLE, Integer.parseInt(values[i])); + break; + case "ET": + position.set(Position.PREFIX_TEMP + 1, Integer.parseInt(values[i])); + break; + case "FL": + position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(values[i])); + break; + case "FC": + position.set(Position.KEY_FUEL_CONSUMPTION, Integer.parseInt(values[i])); + break; + case "AV1": + position.set(Position.PREFIX_ADC + 1, Integer.parseInt(values[i])); + break; default: break; } } + + if (cellTower.getMobileCountryCode() != null + && cellTower.getMobileNetworkCode() != null + && cellTower.getCellId() != null + && cellTower.getLocationAreaCode() != null) { + position.setNetwork(new Network(cellTower)); + } else if (cellTower.getSignalStrength() != null) { + position.set(Position.KEY_RSSI, cellTower.getSignalStrength()); + } } private void readBinaryCustomData(Position position, ByteBuf buf, String form) { @@ -282,11 +341,6 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { } private static final Pattern PATTERN = new PatternBuilder() - .text("@P,") - .number("x+,") // checksum - .number("d+,") // length - .number("d+,") // index - .number("(d+),") // imei .number("(d+),") // date and time .number("d+,") // rtc date and time .number("d+,") // device date and time @@ -308,18 +362,41 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { .optional(2) .compile(); - private Position decodeText(Channel channel, SocketAddress remoteAddress, String sentence) { + private List decodeText(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { - return null; + int startIndex = 0; + for (int i = 0; i < 4; i++) { + startIndex = sentence.indexOf(',', startIndex + 1); } + int endIndex = sentence.indexOf(',', startIndex + 1); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + String imei = sentence.substring(startIndex + 1, endIndex); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; } + List positions = new LinkedList<>(); + String[] lines = sentence.substring(endIndex + 1).split("\r\n"); + + for (String line : lines) { + Position position = decodeTextLine(deviceSession, line); + if (position != null) { + positions.add(position); + } + } + + return positions; + } + + + private Position decodeTextLine(DeviceSession deviceSession, String sentence) { + + Parser parser = new Parser(PATTERN, sentence); + if (!parser.matches()) { + return null; + } + Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); diff --git a/test/org/traccar/protocol/AtrackProtocolDecoderTest.java b/test/org/traccar/protocol/AtrackProtocolDecoderTest.java index 7ac6635f7..0c8e49eb1 100644 --- a/test/org/traccar/protocol/AtrackProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AtrackProtocolDecoderTest.java @@ -10,13 +10,13 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { AtrackProtocolDecoder decoder = new AtrackProtocolDecoder(new AtrackProtocol()); - verifyPosition(decoder, buffer( + verifyPositions(decoder, buffer( "@P,3A34,146,41431,353816057242284,20180622015809,20180622015809,20180622015809,9720689,4014230,61,2,0,20,1,0,0,0,0,2000,2000,12160,42,624,002,20009,20014,\r\n")); - verifyPosition(decoder, buffer( + verifyPositions(decoder, buffer( "@P,1126,121,104547,358901048091554,20180412143513,20180412143514,20180413060000,16423389,48178700,108,2,6.5,9,0,0,0,0,0,2000,2000,\r\n")); - verifyPosition(decoder, buffer( + verifyPositions(decoder, buffer( "@P,434E,124,104655,358901048091554,20180412143706,20180412143706,20180413060107,16423389,48178700,108,121,6.5,10,0,0,0,0,0,2000,2000,\r\n")); verifyPositions(decoder, binary( @@ -34,12 +34,15 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { decoder.setCustom(true); - verifyPosition(decoder, buffer( + verifyPositions(decoder, buffer( + "@P,6254,235,989,356961075931165,1534381563,1534381564,1534381564,-88429188,44271225,70,2,200563,8,1,0,0,0,,2000,2000,,%CI%CE%CN%GQ%GS%FL%ML%VN%PD%FC%EL%ET%CD%AT%MF%MV,0,310260,18,9,0,0,2T1KR32E28C706185,0,0,0,54,8901260881215247759,252,489,123")); + + verifyPositions(decoder, buffer( "@P,27A6,663,707,356961075931165,1534211298,1534211297,1534211437,-88429190,44271135,288,2,200235,8,1,0,0,0,,2000,2000,,%CI%CE%CN%GQ%GS%FL%ML%VN%PD%FC%EL%ET%CD%AT%MF%MV,0,310260,17,9,0,0,2T1KR32E28C706185,0,0,0,80,8901260881215247759,251,59,124\r\n", "1534211353,1534211357,1534211437,-88429190,44271135,288,2,200235,7,1,0,0,0,,2000,2000,,%CI%CE%CN%GQ%GS%FL%ML%VN%PD%FC%EL%ET%CD%AT%MF%MV,0,310260,17,2,0,0,2T1KR32E28C706185,0,0,0,79,8901260881215247759,251,60,124\r\n", "1534211417,1534211417,1534211437,-88429190,44271135,288,2,200235,7,1,0,0,0,,2000,2000,,%CI%CE%CN%GQ%GS%FL%ML%VN%PD%FC%EL%ET%CD%AT%MF%MV,0,310260,17,2,0,0,2T1KR32E28C706185,0,0,0,78,8901260881215247759,251,56,124\r\n")); - verifyPosition(decoder, buffer( + verifyPositions(decoder, buffer( "@P,CA4B,122,1,358683064932578,1533633976,1533633975,1533633975,121562641,25082649,72,0,1638,15,0,0,1,0,,2000,2000,,%CI%MV%BV,143,0\r\n")); verifyPositions(decoder, binary( -- cgit v1.2.3