diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/AbsEBikeMessage.java b/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/AbsEBikeMessage.java index 3f161625f..dcc1d8133 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/AbsEBikeMessage.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/AbsEBikeMessage.java @@ -1,10 +1,7 @@ package com.jsowell.netty.domain.ebike; import com.jsowell.common.util.BytesUtil; -import com.jsowell.netty.domain.ebike.deviceupload.DeviceRegister; -import com.jsowell.netty.domain.ebike.deviceupload.EBikeMessageCmd03; -import com.jsowell.netty.domain.ebike.deviceupload.EBikeMessageCmd20; -import com.jsowell.netty.domain.ebike.deviceupload.SettlementInfo; +import com.jsowell.netty.domain.ebike.deviceupload.*; import com.jsowell.netty.domain.ebike.serversend.EBikeMessageCmd82; import com.jsowell.netty.domain.ebike.serversend.SpecificDataCmd82; import lombok.Getter; @@ -44,6 +41,8 @@ public abstract class AbsEBikeMessage { return new EBikeMessageCmd03(header, length, physicalId, messageId, command, null, checksum, new SettlementInfo(dataBytes)); case "20": return new EBikeMessageCmd20(header, length, physicalId, messageId, command, null, checksum, new DeviceRegister(dataBytes)); + case "06": + return new EBikeMessageCmd06(header, length, physicalId, messageId, command, null, checksum, new PowerHeartbeat(dataBytes)); default: throw new IllegalArgumentException("Unsupported command: " + command); } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/ConfirmOrder.java b/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/ConfirmOrder.java new file mode 100644 index 000000000..fcb63a31c --- /dev/null +++ b/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/ConfirmOrder.java @@ -0,0 +1,42 @@ +package com.jsowell.netty.domain.ebike.deviceupload; + +import com.jsowell.common.util.BytesUtil; +import lombok.Data; + +import java.util.Arrays; + +@Data +public class ConfirmOrder { + /** + * 端口号 + */ + private String portNumber; + + /** + * 在线/离线启动 + */ + private String startMode; + + /** + * 卡片ID + */ + private String cardId; + + /** + * 充电时长 + */ + private String chargingTime; + + /** + * 订单编号 + */ + private String orderCode; + + public ConfirmOrder(byte[] dataBytes) { + this.portNumber = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, 0, 1)) + ""; + this.startMode = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, 1, 2)) + ""; + this.cardId = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, 2, 6)) + ""; + this.chargingTime = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, 6, 8)) + ""; + this.orderCode = BytesUtil.bcd2StrLittle(Arrays.copyOfRange(dataBytes, 8, 24)); + } +} diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/EBikeMessageCmd04.java b/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/EBikeMessageCmd04.java new file mode 100644 index 000000000..5a539987a --- /dev/null +++ b/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/EBikeMessageCmd04.java @@ -0,0 +1,26 @@ +package com.jsowell.netty.domain.ebike.deviceupload; + +import com.jsowell.netty.domain.ebike.AbsEBikeMessage; + +/** + * 充电端口订单确认(04指令) + * 这是老版本指令,和06相对应,有06指令时无此命令(2019年6月份后生产的机型已无此指令) + */ +public class EBikeMessageCmd04 extends AbsEBikeMessage { + + private ConfirmOrder confirmOrder; + + public EBikeMessageCmd04(String header, int length, int physicalId, int messageId, String command, Object payload, int checksum, ConfirmOrder confirmOrder) { + super(header, length, physicalId, messageId, command, payload, checksum); + this.confirmOrder = confirmOrder; + } + + @Override + public void parsePayload(byte[] dataBytes) { + this.confirmOrder = new ConfirmOrder(dataBytes); + } + + public ConfirmOrder getSettlementInfo() { + return confirmOrder; + } +} \ No newline at end of file diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/EBikeMessageCmd06.java b/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/EBikeMessageCmd06.java new file mode 100644 index 000000000..3a58628d9 --- /dev/null +++ b/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/EBikeMessageCmd06.java @@ -0,0 +1,27 @@ +package com.jsowell.netty.domain.ebike.deviceupload; + +import com.jsowell.netty.domain.ebike.AbsEBikeMessage; + +/** + * 端口充电时功率心跳包(06指令) + * 这是新版本指令,和04相对应,有04指令时无此命令 + * 此命令设备开始充电后(82命令应答后)每隔设5分钟发送1次(无重发机制), 充电结束后即停止发送 + */ +public class EBikeMessageCmd06 extends AbsEBikeMessage { + + private PowerHeartbeat powerHeartbeat; + + public EBikeMessageCmd06(String header, int length, int physicalId, int messageId, String command, Object payload, int checksum, PowerHeartbeat powerHeartbeat) { + super(header, length, physicalId, messageId, command, payload, checksum); + this.powerHeartbeat = powerHeartbeat; + } + + @Override + public void parsePayload(byte[] dataBytes) { + this.powerHeartbeat = new PowerHeartbeat(dataBytes); + } + + public PowerHeartbeat getPowerHeartbeat() { + return powerHeartbeat; + } +} \ No newline at end of file diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/PowerHeartbeat.java b/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/PowerHeartbeat.java new file mode 100644 index 000000000..3d2c901e0 --- /dev/null +++ b/jsowell-netty/src/main/java/com/jsowell/netty/domain/ebike/deviceupload/PowerHeartbeat.java @@ -0,0 +1,159 @@ +package com.jsowell.netty.domain.ebike.deviceupload; + +import com.jsowell.common.util.BytesUtil; +import lombok.Getter; +import lombok.Setter; + +import java.util.Arrays; + +/** + * 功率心跳包 + */ +@Getter +@Setter +public class PowerHeartbeat { + /** + * 端口号:当前充电的端口号。注:00表示1号端口,01表示2号端口 + */ + private String port; + + /** + * 各端口状态: 1=充电中, 2=已扫码,暂未检测到功率,等待插入充电器(充电柜专有,如单车桩出现此值为出错值请忽略),3=有充电器但未充电(已充满电),5=浮充,其他值=出错值请忽略 + */ + private String portStatus; + + /** + * 充电时长:开始充电到当前为止,已经充电多长时间 + */ + private String chargingTime; + + /** + * 当前订单累计电量:当前端口的订单,开始充电到当前为止,已经消耗的电量 + */ + private String totalUsedElectricity; + + /** + * 在线/离线启动:=0表示启动时,处于离线状态 ;=1表示启动时,处于在线状态; 3=验证码启动(仅支持带按键和屏幕的机型) + */ + private String startMode; + + /** + * 实时功率:心跳包发送时的当前功率 + */ + private String realTimePower; + + /** + * 心跳包期间最大功率:心跳包期间出现过的最大功率 + */ + private String maxPower; + + /** + * 心跳包期间最小功率:心跳包期间出现过的最小功率 + */ + private String minPower; + + /** + * 心跳包期间平均功率:心跳包期间出现过的平均功率 + */ + private String avgPower; + + /** + * 订单编号:当前充电的订单编号 + */ + private String orderCode; + + /** + * 该时间段内消耗电量:此数据需除以4800后才是真实的电量,该字段属于调试使用,服务器无需关心此字段 + */ + private String timePeriodElectricity; + + /** + * 峰值功率:整个充电过程中出现过的最大功率,有些版本无此字段 + */ + private String peakPower; + + /** + * 设备的当前电压 + */ + private String voltage; + + /** + * 设备的当前电流,可以计量芯片采集也可以通过计算得出,0.001A为单位,1000表示1A电流 + */ + private String current; + + /** + * 设备的当前环境温度,仅针对有此功能的机型 + */ + private String ambientTemperature; + + /** + * 端口温度,仅针对有此功能的机型 + */ + private String portTemperature; + + /** + * 上发指令当时的时间,有时候不准确,该字段属于调试使用,服务器无需关心此字段 + */ + private String timestamp; + + /** + * 占位时长:(充电柜专用,其他设备忽略此字段)表示充满后占用设备的时长,单位为分钟 + */ + private String occupancyTime; + + + public PowerHeartbeat(byte[] dataBytes) { + int startIndex = 0; + int length = 1; + this.port = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 1; + this.portStatus = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 2; + this.chargingTime = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 2; + this.totalUsedElectricity = BytesUtil.bcd2StrLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)); + + length = 1; + this.startMode = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 2; + this.realTimePower = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 2; + this.maxPower = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 2; + this.minPower = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 2; + this.avgPower = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 16; + this.orderCode = BytesUtil.bcd2StrLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)); + + length = 2; + this.peakPower = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 2; + this.voltage = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 2; + this.current = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 1; + this.ambientTemperature = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 1; + this.portTemperature = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 4; + this.timestamp = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + + length = 2; + this.occupancyTime = BytesUtil.bytesToIntLittle(Arrays.copyOfRange(dataBytes, startIndex, startIndex = startIndex + length)) + ""; + } +}