From 024b3ead9f2e14922177d1def29486815b44aa7a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 9 Feb 2017 16:58:14 +1300 Subject: Implement new Aquila protocol --- .../traccar/protocol/AquilaProtocolDecoder.java | 78 ++++++++++++++++++---- .../protocol/AquilaProtocolDecoderTest.java | 6 ++ 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/src/org/traccar/protocol/AquilaProtocolDecoder.java b/src/org/traccar/protocol/AquilaProtocolDecoder.java index 60a9c4708..49462ddd8 100644 --- a/src/org/traccar/protocol/AquilaProtocolDecoder.java +++ b/src/org/traccar/protocol/AquilaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,7 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // gsm .number("(d+),") // speed .number("(d+),") // distance + .groupBegin() .number("d+,") // driver code .number("(d+),") // fuel .number("([01]),") // io 1 @@ -65,26 +66,57 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder { .number("([01]),") // course bit 1 .number("([01]),") // course bit 2 .number("([01]),") // course bit 3 + .or() + .number("(d+),") // course + .number("(?:d+,){3}") // reserved + .number("[01],") // over speed start + .number("[01],") // over speed end + .number("(?:d+,){3}") // reserved + .number("([01]),") // power status + .number("(?:d+,){2}") // reserved + .number("[01],") // ignition on event + .number("([01]),") // ignition + .number("[01],") // ignition off event + .number("(?:d+,){5}") // reserved + .number("[01],") // low battery + .number("[01],") // corner packet + .number("(?:d+,){6}") // reserved + .number("[01],") // hard acceleration + .number("[01],") // hard breaking + .number("[01],[01],[01],[01],") // course bits + .number("(d+),") // external voltage + .number("(d+),") // internal voltage + .number("(?:d+,){6}") // reserved + .expression("P([^,]+),") // obd + .expression("D([^,]+),") // dtcs + .number("-?d+,") // accelerometer x + .number("-?d+,") // accelerometer y + .number("-?d+,") // accelerometer z + .number("d+,") // delta distance + .groupEnd() .text("*") - .number("(xx)") // checksum + .number("xx") // checksum .compile(); @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + org.traccar.helper.PatternUtil.MatchResult matchResult = + org.traccar.helper.PatternUtil.checkPattern(PATTERN.pattern(), (String) msg); + Parser parser = new Parser(PATTERN, (String) msg); if (!parser.matches()) { return null; } - Position position = new Position(); - position.setProtocol(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(); + position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); position.set(Position.KEY_EVENT, parser.nextInt()); @@ -104,16 +136,36 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); position.set(Position.KEY_ODOMETER, parser.next()); - position.set(Position.KEY_FUEL, parser.next()); - position.set(Position.PREFIX_IO + 1, parser.next()); - position.set(Position.KEY_CHARGE, parser.next()); - position.set(Position.PREFIX_IO + 2, parser.next()); - position.set(Position.KEY_IGNITION, parser.nextInt() == 1); + if (parser.hasNext(9)) { + + position.set(Position.KEY_FUEL, parser.next()); + position.set(Position.PREFIX_IO + 1, parser.next()); + position.set(Position.KEY_CHARGE, parser.next()); + position.set(Position.PREFIX_IO + 2, parser.next()); + + position.set(Position.KEY_IGNITION, parser.nextInt() == 1); + + int course = (parser.nextInt() << 3) + (parser.nextInt() << 2) + (parser.nextInt() << 1) + parser.nextInt(); + if (course > 0 && course <= 8) { + position.setCourse((course - 1) * 45); + } + + } else { + + position.setCourse(parser.nextInt()); + + position.set(Position.KEY_CHARGE, parser.next()); + position.set(Position.KEY_IGNITION, parser.nextInt() == 1); + position.set(Position.KEY_POWER, parser.nextInt()); + position.set(Position.KEY_BATTERY, parser.nextInt()); + + String obd = parser.next(); + position.set("obd", obd.substring(1, obd.length() - 1)); + + String dtcs = parser.next(); + position.set(Position.KEY_DTCS, dtcs.substring(1, dtcs.length() - 1).replace('|', ' ')); - int course = (parser.nextInt() << 3) + (parser.nextInt() << 2) + (parser.nextInt() << 1) + parser.nextInt(); - if (course > 0 && course <= 8) { - position.setCourse((course - 1) * 45); } return position; diff --git a/test/org/traccar/protocol/AquilaProtocolDecoderTest.java b/test/org/traccar/protocol/AquilaProtocolDecoderTest.java index a62e20e1e..3e823d74d 100644 --- a/test/org/traccar/protocol/AquilaProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AquilaProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class AquilaProtocolDecoderTest extends ProtocolTest { AquilaProtocolDecoder decoder = new AquilaProtocolDecoder(new AquilaProtocol()); + verifyPosition(decoder, text( + "$$CLIENT_1ZF,130329214,1,12.962985,77.576484,140127165433,A,22,0,0,140,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1253,420,1,0,1,0,0,1,P(01:410104000102|05:410521|0C:410C0000|0D:410D65|21:4121161C),D(P0121|B2105),-895,745,-145,300,*26")); + + verifyPosition(decoder, text( + "$$CLIENT_1NS,101010119,1,22.845943,75.949059,170202184000,A,27,0,0,120,31141,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,399,3709,0,0,0,0,0,0,P(01:|04:|05:|0B:|0C:|0D:|10:|1C:|21:|23:|30:|31:|1F:|11:|00:|00:|),D(),-89,44,-1062,0,*49")); + verifyPosition(decoder, text( "$$CLIENT_1DT,151028368,1,19.108438,72.925308,160628154920,A,22,0,0,131,3503,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,*1D")); -- cgit v1.2.3