From 773768093c6c78906e54abe128cb1b4ca9430313 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 18 Apr 2018 15:51:38 +1200 Subject: Support Atrack text message format --- .../traccar/protocol/AtrackProtocolDecoder.java | 92 +++++++++++++++++++--- .../protocol/AtrackProtocolDecoderTest.java | 6 ++ 2 files changed, 87 insertions(+), 11 deletions(-) diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java index 8138f0fcb..ac208c0f2 100644 --- a/src/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java @@ -219,7 +219,8 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); - private Position decodeString(Channel channel, SocketAddress remoteAddress, String sentence) { + private Position decodeInfo(Channel channel, SocketAddress remoteAddress, String sentence) { + Position position = new Position(getProtocolName()); getLastLocation(position, null); @@ -258,21 +259,70 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { } } - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + private static final Pattern PATTERN = new PatternBuilder() + .text("@P,") + .number("x+,") // checksum + .number("d+,") // length + .number("d+,") // index + .number("(d+),") // imei + .number("(dddd)(dd)(dd)") // date (yymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("d+,") // rtc date and time + .number("d+,") // device date and time + .number("(-?d+),") // longitude + .number("(-?d+),") // latitude + .number("(d+),") // course + .number("(d+),") // report id + .number("(d+.d+),") // odometer + .number("(d+),") // hdop + .number("(d+),") // inputs + .number("(d+),") // speed + .number("(d+),") // outputs + .number("(d+),") // adc + .number("[^,]*,") // driver + .number("(d+),") // temp1 + .number("(d+),") // temp2 + .any() + .compile(); - ChannelBuffer buf = (ChannelBuffer) msg; + private Position decodeText(Channel channel, SocketAddress remoteAddress, String sentence) { - if (buf.getUnsignedShort(buf.readerIndex()) == 0xfe02) { - if (channel != null) { - channel.write(buf, remoteAddress); // keep-alive message - } + Parser parser = new Parser(PATTERN, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { return null; - } else if (buf.getByte(buf.readerIndex()) == '$') { - return decodeString(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII).trim()); } + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(true); + position.setTime(parser.nextDateTime()); + position.setLongitude(parser.nextInt() * 0.000001); + position.setLatitude(parser.nextInt() * 0.000001); + position.setCourse(parser.nextInt()); + + position.set(Position.KEY_EVENT, parser.nextInt()); + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 100); + position.set(Position.KEY_HDOP, parser.nextInt() * 0.1); + position.set(Position.KEY_INPUT, parser.nextInt()); + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + + position.set(Position.KEY_OUTPUT, parser.nextInt()); + position.set(Position.PREFIX_ADC + 1, parser.nextInt()); + position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); + position.set(Position.PREFIX_TEMP + 2, parser.nextInt()); + + return position; + } + + private List decodeBinary(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + buf.skipBytes(2); // prefix buf.readUnsignedShort(); // checksum buf.readUnsignedShort(); // length @@ -360,4 +410,24 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { return positions; } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ChannelBuffer buf = (ChannelBuffer) msg; + + if (buf.getUnsignedShort(buf.readerIndex()) == 0xfe02) { + if (channel != null) { + channel.write(buf, remoteAddress); // keep-alive message + } + return null; + } else if (buf.getByte(buf.readerIndex()) == '$') { + return decodeInfo(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII).trim()); + } else if (buf.getByte(buf.readerIndex() + 2) == ',') { + return decodeText(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII).trim()); + } else { + return decodeBinary(channel, remoteAddress, buf); + } + } + } diff --git a/test/org/traccar/protocol/AtrackProtocolDecoderTest.java b/test/org/traccar/protocol/AtrackProtocolDecoderTest.java index bd606c320..1fe579c76 100644 --- a/test/org/traccar/protocol/AtrackProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AtrackProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { AtrackProtocolDecoder decoder = new AtrackProtocolDecoder(new AtrackProtocol()); + verifyPosition(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( + "@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( "4050b5ed004a2523000310c83713f8c05a88b43e5a88b43f5a88b43f021e0ad5fffdc0a800f3020003059100080000000000000007d007d046554c533a463d3230393120743d3137204e3d3039303100")); -- cgit v1.2.3