diff options
Diffstat (limited to 'src/main/java/org/traccar/protocol/T800xProtocolDecoder.java')
-rw-r--r-- | src/main/java/org/traccar/protocol/T800xProtocolDecoder.java | 149 |
1 files changed, 133 insertions, 16 deletions
diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index b23e3fa70..b15688df0 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -54,8 +54,12 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GPS = 0x02; public static final int MSG_HEARTBEAT = 0x03; public static final int MSG_ALARM = 0x04; - public static final int MSG_NETWORK = 0x05; + public static final int MSG_NETWORK = 0x05; // 0x2727 + public static final int MSG_DRIVER_BEHAVIOR_1 = 0x05; // 0x2626 + public static final int MSG_DRIVER_BEHAVIOR_2 = 0x06; // 0x2626 public static final int MSG_BLE = 0x10; + public static final int MSG_GPS_2 = 0x13; + public static final int MSG_ALARM_2 = 0x14; public static final int MSG_COMMAND = 0x81; private void sendResponse(Channel channel, short header, int type, int index, ByteBuf imei, int alarm) { @@ -73,7 +77,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } } - private String decodeAlarm(int value) { + private String decodeAlarm1(int value) { switch (value) { case 1: return Position.ALARM_POWER_CUT; @@ -103,6 +107,28 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } } + private String decodeAlarm2(int value) { + switch (value) { + case 1: + case 4: + return Position.ALARM_REMOVING; + case 2: + return Position.ALARM_TAMPERING; + case 3: + return Position.ALARM_SOS; + case 5: + return Position.ALARM_FALL_DOWN; + case 6: + return Position.ALARM_LOW_BATTERY; + case 14: + return Position.ALARM_GEOFENCE_ENTER; + case 15: + return Position.ALARM_GEOFENCE_EXIT; + default: + return null; + } + } + private Date readDate(ByteBuf buf) { return new DateBuilder() .setYear(BcdUtil.readInteger(buf, 2)) @@ -132,15 +158,16 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return null; } - if (type != MSG_GPS && type != MSG_ALARM) { + boolean positionType = type == MSG_GPS || type == MSG_GPS_2 || type == MSG_ALARM || type == MSG_ALARM_2; + if (!positionType) { sendResponse(channel, header, type, index, imei, 0); } - if (type == MSG_GPS || type == MSG_ALARM) { + if (positionType) { return decodePosition(channel, deviceSession, buf, type, index, imei); - } else if (type == MSG_NETWORK) { + } else if (type == MSG_NETWORK && header == 0x2727) { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -159,6 +186,52 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return position; + } else if ((type == MSG_DRIVER_BEHAVIOR_1 || type == MSG_DRIVER_BEHAVIOR_2) && header == 0x2626) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + switch (buf.readUnsignedByte()) { + case 0: + case 4: + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 1: + case 3: + case 5: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 2: + if (type == MSG_DRIVER_BEHAVIOR_1) { + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + } else { + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + } + break; + default: + break; + } + + position.setTime(readDate(buf)); + + if (type == MSG_DRIVER_BEHAVIOR_2) { + int status = buf.readUnsignedByte(); + position.setValid(!BitUtil.check(status, 7)); + buf.skipBytes(5); // acceleration + } else { + position.setValid(true); + } + + position.setAltitude(buf.readFloatLE()); + position.setLongitude(buf.readFloatLE()); + position.setLatitude(buf.readFloatLE()); + position.setSpeed(UnitsConverter.knotsFromKph(BcdUtil.readInteger(buf, 4) * 0.1)); + position.setCourse(buf.readUnsignedShort()); + + position.set(Position.KEY_RPM, buf.readUnsignedShort()); + + return position; + } else if (type == MSG_BLE) { return decodeBle(channel, deviceSession, buf, type, index, imei); @@ -181,6 +254,11 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { return null; } + private double decodeBleTemp(ByteBuf buf) { + int value = buf.readUnsignedShort(); + return (BitUtil.check(value, 15) ? -BitUtil.to(value, 15) : BitUtil.to(value, 15)) * 0.01; + } + private Position decodeBle( Channel channel, DeviceSession deviceSession, ByteBuf buf, int type, int index, ByteBuf imei) { @@ -230,7 +308,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { position.set("tag" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", buf.readUnsignedByte() * 0.01 + 2); buf.readUnsignedByte(); // battery level - position.set("tag" + i + "Temp", buf.readUnsignedShort() * 0.01); + position.set("tag" + i + "Temp", decodeBleTemp(buf)); position.set("tag" + i + "Humidity", buf.readUnsignedShort() * 0.01); position.set("tag" + i + "LightSensor", buf.readUnsignedShort()); position.set("tag" + i + "Rssi", buf.readUnsignedByte() - 128); @@ -239,7 +317,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { position.set("tag" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", buf.readUnsignedByte() * 0.01 + 2); buf.readUnsignedByte(); // battery level - position.set("tag" + i + "Temp", buf.readUnsignedShort() * 0.01); + position.set("tag" + i + "Temp", decodeBleTemp(buf)); position.set("tag" + i + "Door", buf.readUnsignedByte() > 0); position.set("tag" + i + "Rssi", buf.readUnsignedByte() - 128); break; @@ -295,12 +373,19 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { position.set("ac", BitUtil.check(io, 13)); position.set(Position.PREFIX_IN + 3, BitUtil.check(io, 12)); position.set(Position.PREFIX_IN + 4, BitUtil.check(io, 11)); - position.set(Position.PREFIX_OUT + 1, BitUtil.check(io, 7)); - position.set(Position.PREFIX_OUT + 2, BitUtil.check(io, 8)); - position.set(Position.PREFIX_OUT + 3, BitUtil.check(io, 9)); + + if (type == MSG_GPS_2 || type == MSG_ALARM_2) { + position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); + buf.readUnsignedByte(); // reserved + } else { + position.set(Position.PREFIX_OUT + 1, BitUtil.check(io, 7)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(io, 8)); + position.set(Position.PREFIX_OUT + 3, BitUtil.check(io, 9)); + } if (header != 0x2626) { - for (int i = 1; i <= 2; i++) { + int adcCount = type == MSG_GPS_2 || type == MSG_ALARM_2 ? 5 : 2; + for (int i = 1; i <= adcCount; i++) { String value = ByteBufUtil.hexDump(buf.readSlice(2)); if (!value.equals("ffff")) { position.set(Position.PREFIX_ADC + i, Integer.parseInt(value) * 0.01); @@ -311,7 +396,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } int alarm = buf.readUnsignedByte(); - position.set(Position.KEY_ALARM, decodeAlarm(alarm)); + position.set(Position.KEY_ALARM, header != 0x2727 ? decodeAlarm1(alarm) : decodeAlarm2(alarm)); if (header != 0x2727) { @@ -389,13 +474,45 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(); // distance upload interval buf.readUnsignedByte(); // heartbeat - } else if (buf.readableBytes() >= 2) { - - position.set(Position.KEY_POWER, BcdUtil.readInteger(buf, 4) * 0.01); + } else { + if (buf.readableBytes() >= 2) { + position.set(Position.KEY_POWER, BcdUtil.readInteger(buf, 4) * 0.01); + } + if (buf.readableBytes() >= 19) { + position.set(Position.KEY_OBD_SPEED, BcdUtil.readInteger(buf, 4) * 0.01); + position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.001); + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt() * 0.001); + position.set(Position.KEY_RPM, buf.readUnsignedShort()); + int value; + value = buf.readUnsignedByte(); + if (value != 0xff) { + position.set("airInput", value); + } + if (value != 0xff) { + position.set("airPressure", value); + } + if (value != 0xff) { + position.set(Position.KEY_COOLANT_TEMP, value - 40); + } + if (value != 0xff) { + position.set("airTemp", value - 40); + } + if (value != 0xff) { + position.set(Position.KEY_ENGINE_LOAD, value); + } + if (value != 0xff) { + position.set(Position.KEY_THROTTLE, value); + } + if (value != 0xff) { + position.set(Position.KEY_FUEL_LEVEL, value); + } + } } - sendResponse(channel, header, type, index, imei, alarm); + if (type == MSG_ALARM || type == MSG_ALARM_2) { + sendResponse(channel, header, type, index, imei, alarm); + } return position; } |