aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar/protocol/T800xProtocolDecoder.java')
-rw-r--r--src/main/java/org/traccar/protocol/T800xProtocolDecoder.java149
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;
}