From 60ab068beaf34b7856cf69d3ba8ddff42ed9335b Mon Sep 17 00:00:00 2001 From: juzzs_desktop <335918956@qq.com> Date: Sun, 28 Apr 2019 09:22:04 +0800 Subject: support gt06 extend Protocol --- .../org/traccar/protocol/Gt06ProtocolDecoder.java | 290 ++++++++++++++++++++- 1 file changed, 284 insertions(+), 6 deletions(-) (limited to 'src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java') diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index 1f8fb66dd..cdc7ef45e 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -15,6 +15,7 @@ */ package org.traccar.protocol; +import com.fasterxml.jackson.databind.ObjectMapper; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; @@ -39,14 +40,191 @@ import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; -import java.util.Calendar; -import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.TimeZone; +import java.util.Calendar; +import java.util.Date; +import java.util.LinkedList; +import java.util.HashMap; import java.util.regex.Pattern; public class Gt06ProtocolDecoder extends BaseProtocolDecoder { + static class ComplexBMS { + private Long time; + private Short relativeSoc; + private Integer remainingCap; + private Short absoluteSoc; + private Integer fullCap; + private Short soh; + private Integer innerTemp; + private Integer realCurrent; + private Integer voltage; + private Integer cycleIndex; + private List batterysVol; + private Integer currChargingInterval; + private Integer maxChargingInterval; + private String barcode; + private String version; + private String manufacturer; + private Integer batteryStatus; + private Integer controllerStatus; + private Integer controllerFaultCode; + + public Long getTime() { + return time; + } + + public void setTime(Long time) { + this.time = time; + } + + public Short getRelativeSoc() { + return relativeSoc; + } + + public void setRelativeSoc(Short relativeSoc) { + this.relativeSoc = relativeSoc; + } + + public Integer getRemainingCap() { + return remainingCap; + } + + public void setRemainingCap(Integer remainingCap) { + this.remainingCap = remainingCap; + } + + public Short getAbsoluteSoc() { + return absoluteSoc; + } + + public void setAbsoluteSoc(Short absoluteSoc) { + this.absoluteSoc = absoluteSoc; + } + + public Integer getFullCap() { + return fullCap; + } + + public void setFullCap(Integer fullCap) { + this.fullCap = fullCap; + } + + public Short getSoh() { + return soh; + } + + public void setSoh(Short soh) { + this.soh = soh; + } + + public Integer getInnerTemp() { + return innerTemp; + } + + public void setInnerTemp(Integer innerTemp) { + this.innerTemp = innerTemp; + } + + public Integer getRealCurrent() { + return realCurrent; + } + + public void setRealCurrent(Integer realCurrent) { + this.realCurrent = realCurrent; + } + + public Integer getVoltage() { + return voltage; + } + + public void setVoltage(Integer voltage) { + this.voltage = voltage; + } + + public Integer getCycleIndex() { + return cycleIndex; + } + + public void setCycleIndex(Integer cycleIndex) { + this.cycleIndex = cycleIndex; + } + + public List getBatterysVol() { + return batterysVol; + } + + public void setBatterysVol(List batterysVol) { + this.batterysVol = batterysVol; + } + + public Integer getCurrChargingInterval() { + return currChargingInterval; + } + + public void setCurrChargingInterval(Integer currChargingInterval) { + this.currChargingInterval = currChargingInterval; + } + + public Integer getMaxChargingInterval() { + return maxChargingInterval; + } + + public void setMaxChargingInterval(Integer maxChargingInterval) { + this.maxChargingInterval = maxChargingInterval; + } + + public String getBarcode() { + return barcode; + } + + public void setBarcode(String barcode) { + this.barcode = barcode; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getManufacturer() { + return manufacturer; + } + + public void setManufacturer(String manufacturer) { + this.manufacturer = manufacturer; + } + + public Integer getBatteryStatus() { + return batteryStatus; + } + + public void setBatteryStatus(Integer batteryStatus) { + this.batteryStatus = batteryStatus; + } + + public Integer getControllerStatus() { + return controllerStatus; + } + + public void setControllerStatus(Integer controllerStatus) { + this.controllerStatus = controllerStatus; + } + + public Integer getControllerFaultCode() { + return controllerFaultCode; + } + + public void setControllerFaultCode(Integer controllerFaultCode) { + this.controllerFaultCode = controllerFaultCode; + } + } + private final Map photos = new HashMap<>(); public Gt06ProtocolDecoder(Protocol protocol) { @@ -96,6 +274,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_OBD = 0x8C; public static final int MSG_DTC = 0x65; public static final int MSG_PID = 0x66; + public static final int MSG_BMS_DATA = 0x40; + public static final int MSG_MEDIA_DATA = 0x41; private static boolean isSupported(int type) { return hasGps(type) || hasLbs(type) || hasStatus(type); @@ -186,7 +366,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { response.writeShort(index); response.writeShort(Checksum.crc16(Checksum.CRC16_X25, response.nioBuffer(2, response.writerIndex() - 2))); - response.writeByte('\r'); response.writeByte('\n'); // ending + response.writeByte('\r'); + response.writeByte('\n'); // ending channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } } @@ -391,7 +572,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; } - private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { int length = buf.readUnsignedByte(); int dataLength = length - 5; @@ -611,7 +792,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } private Object decodeBasicOther(Channel channel, ByteBuf buf, - DeviceSession deviceSession, int type, int dataLength) { + DeviceSession deviceSession, int type, int dataLength) throws Exception { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -664,6 +845,44 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readSlice(commandLength - 1).toString(StandardCharsets.US_ASCII)); } + } else if (type == MSG_BMS_DATA) { + getLastLocation(position, new Date()); + + ComplexBMS bms = new ComplexBMS(); + + buf.skipBytes(8); // skip sn + bms.setTime(buf.readUnsignedInt() * 1000); + bms.setRelativeSoc(buf.readUnsignedByte()); + bms.setRemainingCap(buf.readUnsignedShort()); + bms.setAbsoluteSoc(buf.readUnsignedByte()); + bms.setFullCap(buf.readUnsignedShort()); + bms.setSoh(buf.readUnsignedByte()); + bms.setInnerTemp(buf.readUnsignedShort()); + bms.setRealCurrent(buf.readUnsignedShort()); + bms.setVoltage(buf.readUnsignedShort()); + bms.setCycleIndex(buf.readUnsignedShort()); + List batterysVol = new LinkedList<>(); + for (int i = 0; i < 14; i++) { + batterysVol.add(buf.readUnsignedShort()); + } + bms.setBatterysVol(batterysVol); + bms.setCurrChargingInterval(buf.readUnsignedShort()); + bms.setMaxChargingInterval(buf.readUnsignedShort()); + bms.setBarcode(buf.readCharSequence(16, StandardCharsets.US_ASCII).toString().trim()); + bms.setVersion(Integer.toString(buf.readUnsignedShort())); + bms.setManufacturer(buf.readCharSequence(16, StandardCharsets.US_ASCII).toString().trim()); + bms.setBatteryStatus(buf.readInt()); + + bms.setControllerStatus(buf.readInt()); + bms.setControllerFaultCode(buf.readInt()); + + ObjectMapper objectMapper = new ObjectMapper(); + String bmsStr = objectMapper.writeValueAsString(bms); + position.set(Position.KEY_BMS_INFO, bmsStr); + + sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null); + + return position; } else if (isSupported(type)) { if (hasGps(type)) { @@ -749,7 +968,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - buf.readUnsignedShort(); // length + int dataLength = buf.readUnsignedShort(); // length int type = buf.readUnsignedByte(); if (type == MSG_STRING_INFO) { @@ -904,6 +1123,65 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; + } else { + return decodeExtendedOther(channel, buf, deviceSession, type, dataLength); + } + + return null; + } + + private Object decodeExtendedOther(Channel channel, ByteBuf buf, + DeviceSession deviceSession, int type, int dataLength) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + if (type == MSG_MEDIA_DATA) { + + buf.skipBytes(8); // skip sn + + long dt = buf.readUnsignedInt() * 1000; + + buf.skipBytes(4 + 4 + 2 + 1 + 1 + 2); // skip gps + + buf.skipBytes(2 + 2 + 2 + 2); // skip cell + + int mediaId = buf.readInt(); + int mediaLen = buf.readInt(); + int mediaType = buf.readUnsignedByte(); + int mediaFormat = buf.readUnsignedByte(); + int eventType = buf.readUnsignedByte(); + int mediaPkgIndex = buf.readUnsignedShort(); + int mediaPkgLen = buf.readableBytes() - (2 + 2 + 2); + if (mediaType != 0 || mediaFormat != 0) { + sendResponse(channel, true, type, buf.getShort(buf.writerIndex() - 6), null); + return null; + } + ByteBuf photo; + if (mediaPkgIndex == 0) { + photo = Unpooled.buffer(mediaLen); + if (photos.containsKey(mediaId)) { + photos.remove(mediaId).release(); + } + photos.put(mediaId, photo); + } else { + photo = photos.get(mediaId); + } + if (null != photo) { + buf.readBytes(photo, mediaPkgLen); + if (photo.writableBytes() <= 0) { + Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); + getLastLocation(position, new Date(dt)); + position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(device.getUniqueId(), + photo, "jpg")); + photos.remove(mediaId).release(); + + sendResponse(channel, true, type, buf.getShort(buf.writerIndex() - 6), null); + + return position; + } + } + sendResponse(channel, true, type, buf.getShort(buf.writerIndex() - 6), null); } return null; -- cgit v1.2.3