From 0f2a1c47fd62aeeae8e4513280e2950fdf596cf6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 6 Jan 2017 21:59:44 +1300 Subject: Implement TZ AVL05 protocol (fix #2751) --- src/org/traccar/model/Position.java | 1 + src/org/traccar/protocol/TzoneProtocolDecoder.java | 113 ++++++++++++--------- test/org/traccar/ProtocolTest.java | 3 + .../traccar/protocol/TzoneProtocolDecoderTest.java | 6 ++ 4 files changed, 73 insertions(+), 50 deletions(-) diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index b43f2455e..6163227b3 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -92,6 +92,7 @@ public class Position extends Message { public static final String ALARM_POWER_CUT = "powerCut"; public static final String ALARM_JAMMING = "jamming"; public static final String ALARM_TEMPERATURE = "temperature"; + public static final String ALARM_PARKING = "parking"; private String protocol; diff --git a/src/org/traccar/protocol/TzoneProtocolDecoder.java b/src/org/traccar/protocol/TzoneProtocolDecoder.java index a0ed41caf..e457f6d33 100644 --- a/src/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/org/traccar/protocol/TzoneProtocolDecoder.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. @@ -22,8 +22,6 @@ import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; -import org.traccar.model.CellTower; -import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; @@ -42,6 +40,12 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_LOW_BATTERY; case 0x11: return Position.ALARM_OVERSPEED; + case 0x14: + return Position.ALARM_BREAKING; + case 0x15: + return Position.ALARM_ACCELETATION; + case 0x30: + return Position.ALARM_PARKING; case 0x42: return Position.ALARM_GEOFENCE_EXIT; case 0x43: @@ -62,7 +66,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { if (buf.readUnsignedShort() != 0x2424) { return null; } - buf.readUnsignedShort(); // model + int hardware = buf.readUnsignedShort(); // model buf.readUnsignedInt(); // firmware String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); @@ -71,30 +75,39 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { return null; } - buf.skipBytes(6); // device time - Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + position.setDeviceTime(new DateBuilder() + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate()); + // GPS info int blockLength = buf.readUnsignedShort(); int blockEnd = buf.readerIndex() + blockLength; - if (blockLength == 0) { + if (blockLength < 22) { return null; } position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - double lat = buf.readUnsignedInt() / 600000.0; - double lon = buf.readUnsignedInt() / 600000.0; + double lat; + double lon; + + if (hardware == 0x10A || hardware == 0x10B) { + lat = buf.readUnsignedInt() / 600000.0; + lon = buf.readUnsignedInt() / 600000.0; + } else { + lat = buf.readUnsignedInt() / 100000.0 / 60.0; + lon = buf.readUnsignedInt() / 100000.0 / 60.0; + } - DateBuilder dateBuilder = new DateBuilder() + position.setFixTime(new DateBuilder() .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate()); position.setSpeed(buf.readUnsignedShort() * 0.01); @@ -119,11 +132,6 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { blockLength = buf.readUnsignedShort(); blockEnd = buf.readerIndex() + blockLength; - if (blockLength > 0) { - position.setNetwork(new Network( - CellTower.fromLacCid(buf.readUnsignedShort(), buf.readUnsignedShort()))); - } - buf.readerIndex(blockEnd); // Status info @@ -131,8 +139,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { blockLength = buf.readUnsignedShort(); blockEnd = buf.readerIndex() + blockLength; - if (blockLength > 0) { - + if (blockLength >= 13) { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); buf.readUnsignedByte(); // terminal info position.set(Position.PREFIX_IO + 1, buf.readUnsignedShort()); @@ -142,61 +149,67 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_POWER, buf.readUnsignedShort()); position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); - position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort()); + } + if (blockLength >= 15) { + position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort()); } buf.readerIndex(blockEnd); - // Cards + if (hardware == 0x10A || hardware == 0x10B) { - int index = 1; - for (int i = 0; i < 4; i++) { + // Cards - blockLength = buf.readUnsignedShort(); - blockEnd = buf.readerIndex() + blockLength; + int index = 1; + for (int i = 0; i < 4; i++) { - if (blockLength > 0) { + blockLength = buf.readUnsignedShort(); + blockEnd = buf.readerIndex() + blockLength; - int count = buf.readUnsignedByte(); - for (int j = 0; j < count; j++) { + if (blockLength > 0) { - int length = buf.readUnsignedByte(); + int count = buf.readUnsignedByte(); + for (int j = 0; j < count; j++) { - boolean odd = length % 2 != 0; - if (odd) { - length += 1; - } + int length = buf.readUnsignedByte(); - String num = ChannelBuffers.hexDump(buf.readBytes(length / 2)); + boolean odd = length % 2 != 0; + if (odd) { + length += 1; + } - if (odd) { - num = num.substring(1); - } + String num = ChannelBuffers.hexDump(buf.readBytes(length / 2)); - position.set("card" + index, num); + if (odd) { + num = num.substring(1); + } + + position.set("card" + index, num); + } } + + buf.readerIndex(blockEnd); } - buf.readerIndex(blockEnd); - } + buf.skipBytes(buf.readUnsignedShort()); // temperature + buf.skipBytes(buf.readUnsignedShort()); // lock - buf.skipBytes(buf.readUnsignedShort()); // temperature - buf.skipBytes(buf.readUnsignedShort()); // lock + // Passengers - // Passengers + blockLength = buf.readUnsignedShort(); + blockEnd = buf.readerIndex() + blockLength; - blockLength = buf.readUnsignedShort(); - blockEnd = buf.readerIndex() + blockLength; + if (blockLength > 0) { - if (blockLength > 0) { + position.set("passengersOn", buf.readUnsignedMedium()); + position.set("passengersOff", buf.readUnsignedMedium()); - position.set("passengersOn", buf.readUnsignedMedium()); - position.set("passengersOff", buf.readUnsignedMedium()); + } - } + buf.readerIndex(blockEnd); - buf.readerIndex(blockEnd); + } return position; } diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index 43be1a59e..20e033e3b 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -154,6 +154,9 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue("latitude >= -90", position.getLatitude() >= -90); Assert.assertTrue("latitude <= 90", position.getLatitude() <= 90); + Assert.assertTrue("longitude >= -180", position.getLongitude() >= -180); + Assert.assertTrue("longitude <= 180", position.getLongitude() <= 180); + } Assert.assertTrue("altitude >= -12262", position.getAltitude() >= -12262); diff --git a/test/org/traccar/protocol/TzoneProtocolDecoderTest.java b/test/org/traccar/protocol/TzoneProtocolDecoderTest.java index 2ae776f36..08a36ec64 100644 --- a/test/org/traccar/protocol/TzoneProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TzoneProtocolDecoderTest.java @@ -11,6 +11,12 @@ public class TzoneProtocolDecoderTest extends ProtocolTest { TzoneProtocolDecoder decoder = new TzoneProtocolDecoder(new TzoneProtocol()); + verifyPosition(decoder, binary( + "545a005024240153011000000863835025559464110103080a22001609011bed79245964a9110103080a22000a0000550c00000604396f04222c000daac000151701a204870000000000000003000959000546190d0a")); + + verifyPosition(decoder, binary( + "545A005224240153010E000008638350256668551008130616090016050079F63D2527FAF710081306160900A000002F0D33000803015B07013D7976000DAAE0400537016C049E000000000000000300800002B65EEA0D0A")); + verifyPosition(decoder, binary( "545a00582424010b022000000860041028904798100803030c2700160a007da96203356669100803030c2700000000000e000004002813730010aa4000000617017100000000000080000000000000000000000000000000007701fe0d0a")); -- cgit v1.2.3