diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2017-11-15 23:59:42 +1300 |
---|---|---|
committer | Anton Tananaev <anton.tananaev@gmail.com> | 2017-11-15 23:59:42 +1300 |
commit | 3c77c1287c494208200cfe53d56ffd4bed8ec5ce (patch) | |
tree | 1525e2a96b06c6c266a06cf930c4e92585037834 | |
parent | 09ee4cc93d600edce023f414c9d373639c137975 (diff) | |
download | trackermap-server-3c77c1287c494208200cfe53d56ffd4bed8ec5ce.tar.gz trackermap-server-3c77c1287c494208200cfe53d56ffd4bed8ec5ce.tar.bz2 trackermap-server-3c77c1287c494208200cfe53d56ffd4bed8ec5ce.zip |
Implement GV65 CAN message support
-rw-r--r-- | src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 132 | ||||
-rw-r--r-- | test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 9 |
2 files changed, 141 insertions, 0 deletions
diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 46a530efa..fb0023dba 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -31,8 +31,12 @@ import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.LinkedList; import java.util.List; +import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -523,6 +527,131 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private Object decodeCan(Channel channel, SocketAddress remoteAddress, String sentence) throws ParseException { + Position position = new Position(); + position.setProtocol(getProtocolName()); + + int index = 0; + String[] values = sentence.split(","); + + index += 1; // header + index += 1; // protocol version + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); + position.setDeviceId(deviceSession.getDeviceId()); + + index += 1; // device name + index += 1; // report type + index += 1; // canbus state + long reportMask = Long.parseLong(values[index++], 16); + + if (BitUtil.check(reportMask, 0)) { + position.set(Position.KEY_VIN, values[index++]); + } + if (BitUtil.check(reportMask, 1)) { + position.set(Position.KEY_IGNITION, Integer.parseInt(values[index++]) > 0); + } + if (BitUtil.check(reportMask, 2)) { + index += 1; // total distance + } + if (BitUtil.check(reportMask, 3)) { + position.set("totalFuelConsumption", Double.parseDouble(values[index++])); + } + if (BitUtil.check(reportMask, 5)) { + position.set(Position.KEY_RPM, Integer.parseInt(values[index++])); + } + if (BitUtil.check(reportMask, 4)) { + position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(Integer.parseInt(values[index++]))); + } + if (BitUtil.check(reportMask, 6)) { + position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[index++])); + } + if (BitUtil.check(reportMask, 7)) { + index += 1; // fuel consumption + } + if (BitUtil.check(reportMask, 8)) { + index += 1; // fuel level + } + if (BitUtil.check(reportMask, 9)) { + index += 1; // range + } + if (BitUtil.check(reportMask, 10)) { + if (!values[index++].isEmpty()) { + position.set(Position.KEY_THROTTLE, Integer.parseInt(values[index - 1])); + } + } + if (BitUtil.check(reportMask, 11)) { + position.set(Position.KEY_HOURS, Double.parseDouble(values[index++])); + } + if (BitUtil.check(reportMask, 12)) { + index += 1; // driving time + } + if (BitUtil.check(reportMask, 13)) { + index += 1; // idle time + } + if (BitUtil.check(reportMask, 14)) { + index += 1; // idle fuel + } + if (BitUtil.check(reportMask, 15)) { + index += 1; // axle weight + } + if (BitUtil.check(reportMask, 16)) { + index += 1; // tachograph info + } + if (BitUtil.check(reportMask, 17)) { + index += 1; // indicators + } + if (BitUtil.check(reportMask, 18)) { + index += 1; // lights + } + if (BitUtil.check(reportMask, 19)) { + index += 1; // doors + } + if (BitUtil.check(reportMask, 20)) { + index += 1; // total vehicle overspeed time + } + if (BitUtil.check(reportMask, 21)) { + index += 1; // total engine overspeed time + } + if (BitUtil.check(reportMask, 29)) { + index += 1; // expansion + } + + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + if (BitUtil.check(reportMask, 30)) { + position.setValid(Integer.parseInt(values[index++]) > 0); + if (!values[index].isEmpty()) { + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); + position.setCourse(Integer.parseInt(values[index++])); + position.setAltitude(Double.parseDouble(values[index++])); + position.setLongitude(Double.parseDouble(values[index++])); + position.setLatitude(Double.parseDouble(values[index++])); + position.setTime(dateFormat.parse(values[index++])); + } else { + index += 6; // no location + getLastLocation(position, null); + } + } else { + getLastLocation(position, null); + } + + if (BitUtil.check(reportMask, 31)) { + index += 4; // cell + } + + index += 1; // reserved + + if (ignoreFixTime) { + position.setTime(dateFormat.parse(values[index])); + } else { + position.setDeviceTime(dateFormat.parse(values[index])); + } + + return position; + } + private void decodeStatus(Position position, Parser parser) { if (parser.hasNext(3)) { int ignition = parser.nextHexInt(0); @@ -869,6 +998,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { case "OBD": result = decodeObd(channel, remoteAddress, sentence); break; + case "CAN": + result = decodeCan(channel, remoteAddress, sentence); + break; case "FRI": result = decodeFri(channel, remoteAddress, sentence); break; diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index d18897354..d9e36ef47 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,6 +10,15 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + verifyAttributes(decoder, buffer( + "+RESP:GTCAN,310201,153759012347650,gv65,0,1,C03FFFFF,,2,H89394,63.14,200,0,87,,P43.60,0,0,17.53,11.61,5.92,0.00,0,0,4002,0,1,0.76,35.00,0,,,,0,0,,0000,0000,0000,0000,00,20040101000052,05A6$")); + + verifyPosition(decoder, buffer( + "+RESP:GTCAN,310603,863286023346480,gv65,00,1,C03FFFFF,,2,H2843820,373.76,1440,44,77,M23,P35.00,1810,,59.48,42.68,16.80,15.42,,,610,,0,,,0,42.7,263,27.2,-2.156478,51.899989,20171021151805,0234,0010,15D6,9AD2,00,20171021151807,0B28$")); + + verifyPosition(decoder, buffer( + "+RESP:GTCAN,310603,863286023346480,gv65,02,1,C03FFFFF,,0,H2843820,373.80,0,4,75,M12,,1800,,59.49,42.69,16.80,15.42,,,0,,0,,,0,0.7,75,24.3,-2.155148,51.899400,20171021151837,0234,0010,15D6,9AD2,00,20171021152355,0B2E$")); + verifyPositions(decoder, buffer( "+RESP:GTERI,380603,869606020025833,gv65,00000002,12003,10,1,1,0.0,172,24.6,-81.931875,26.577439,20171002045352,0310,0260,72BD,8E5B,00,1052.1,01383:52:12,0,100,210700,2,1,28FF4560A3150483,1,05B0,20171002045402,9548$")); |