diff --git a/jsowell-common/src/main/java/com/jsowell/common/YouDianUtils.java b/jsowell-common/src/main/java/com/jsowell/common/YouDianUtils.java index 96b055443..cfdb7e3f5 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/YouDianUtils.java +++ b/jsowell-common/src/main/java/com/jsowell/common/YouDianUtils.java @@ -140,9 +140,9 @@ public class YouDianUtils { * @return */ public static String convertPortNumberToString(int portNumber) { - if (portNumber < 0 || portNumber > 15) { - throw new IllegalArgumentException("Port number must be between 0 and 15."); - } + // if (portNumber < 0 || portNumber > 15) { + // throw new IllegalArgumentException("Port number must be between 0 and 15."); + // } // 转换为字节数组 return String.format("%02d", portNumber + 1); diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/AbsEBikeMessage2.java b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/AbsEBikeMessage2.java new file mode 100644 index 000000000..d8289c0cb --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/AbsEBikeMessage2.java @@ -0,0 +1,72 @@ +package com.jsowell.pile.domain.ebike; + +import com.jsowell.common.YouDianUtils; +import com.jsowell.common.util.BytesUtil; +import lombok.*; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AbsEBikeMessage2 { + protected String header; // 包头 (3字节) + protected int msgLength; // 长度 (2字节) + protected int physicalId; // 物理ID (4字节) + protected int messageId; // 消息ID (2字节) + protected String command; // 命令 (1字节) + protected Object payload; // 数据 (n字节) + protected int checksum; // 校验 (2字节) + + protected void parseMessage(byte[] messageBytes) { + if (messageBytes == null || messageBytes.length < 14 || messageBytes.length > 256) { + throw new IllegalArgumentException("Invalid message bytes"); + } + + // 读取包头 + int startIndex = 0; + int length = 3; + byte[] headerBytes = BytesUtil.copyBytes(messageBytes, startIndex, length); + this.header = new String(headerBytes, StandardCharsets.UTF_8); + + // 读取长度 + startIndex += length; + length = 2; + byte[] lengthBytes = BytesUtil.copyBytes(messageBytes, startIndex, length); + this.msgLength = BytesUtil.bytesToIntLittle(lengthBytes); + + // 验证长度 + if (msgLength != (messageBytes.length - 5)) { + throw new IllegalArgumentException("Invalid message length"); + } + + // 读取物理ID + startIndex += length; + length = 4; + byte[] physicalIdBytes = BytesUtil.copyBytes(messageBytes, startIndex, length); + this.physicalId = YouDianUtils.convertToPhysicalId(physicalIdBytes); + + // 读取消息ID + startIndex += length; + length = 2; + byte[] messageIdBytes = BytesUtil.copyBytes(messageBytes, startIndex, length); + this.messageId = BytesUtil.bytesToIntLittle(messageIdBytes); + + // 读取命令 + startIndex += length; + length = 1; + byte[] commandBytes = BytesUtil.copyBytes(messageBytes, startIndex, length); + this.command = BytesUtil.bcd2StrLittle(commandBytes); + + // 读取数据 + // byte[] dataBytes = BytesUtil.copyBytes(messageBytes, startIndex, length); + + // 读取校验 + byte[] checksumBytes = Arrays.copyOfRange(messageBytes, messageBytes.length - 2, messageBytes.length); + this.checksum = BytesUtil.bytesToIntLittle(checksumBytes); + + } +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/deviceupload/ChargingOperationResponse.java b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/deviceupload/ChargingOperationResponse.java new file mode 100644 index 000000000..a81c5a881 --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/deviceupload/ChargingOperationResponse.java @@ -0,0 +1,75 @@ +package com.jsowell.pile.domain.ebike.deviceupload; + +import com.alibaba.fastjson2.JSON; +import com.jsowell.common.YouDianUtils; +import com.jsowell.common.util.BytesUtil; +import com.jsowell.pile.domain.ebike.AbsEBikeMessage2; +import lombok.Data; + +/** + * 启动充电回复 + */ +@Data +public class ChargingOperationResponse extends AbsEBikeMessage2 { + /** + * 应答:执行开始充电命令,=0执行成功(启动或停止充电), + * =1端口未插充电器(不执行), + * =2端口状态和充电命令相同(不执行), + * =3端口故障(执行), + * =4无此端口号(不执行), + * =5有多个待充端口(响应FF充电命令,不执行,只针对双路,双路设备的二维码只有一个,且端口号为FF,当2个口都插了充电器, + * 服务器下发充电端口为FF时,设备检测到有2个口待充电,不知道充哪个,就会返回此应答), + * =6多路设备功率超标(不执行) + */ + private int result; + + /** + * 交易流水号 + */ + private String transactionCode; + + /** + * 充电端口 + */ + private String portNumber; + + /** + * 待充端口:当应答=5的时候,此数据才是有效的。按照bit定义各待充端口状态,0=非待充,1=待充 + */ + private String waitPortNumber; + + public ChargingOperationResponse(byte[] dataBytes) { + int startIndex = 0; + int length = 1; + this.result = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(dataBytes, startIndex, length)); + + startIndex += length; + length = 16; + this.transactionCode = BytesUtil.bcd2Str(BytesUtil.copyBytes(dataBytes, startIndex, length)); + + startIndex += length; + length = 1; + this.portNumber = YouDianUtils.convertPortNumberToString(BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(dataBytes, startIndex, length))); + + // startIndex += length; + // length = 2; + // this.waitPortNumber = YouDianUtils.convertPortNumberToString(BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(dataBytes, startIndex, length))); + } + + @Override + protected void parseMessage(byte[] messageBytes) { + super.parseMessage(messageBytes); + // 截取数据 + byte[] bytes = BytesUtil.copyBytes(messageBytes, 11, this.msgLength); + ChargingOperationResponse response = new ChargingOperationResponse(bytes); + System.out.println(JSON.toJSONString(response)); + } + + public static void main(String[] args) { + String s = "444e591d00198bca07da0c8200132738810124091416463569289954500000007907"; + byte[] messageBytes = BytesUtil.hexStringToByteArray(s); + ChargingOperationResponse response = new ChargingOperationResponse(messageBytes); + response.parseMessage(messageBytes); + System.out.println(response); + } +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/EBikeSendCommandService.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/EBikeSendCommandService.java index 57761bfb2..d6b18e721 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/EBikeSendCommandService.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/EBikeSendCommandService.java @@ -1,5 +1,6 @@ package com.jsowell.pile.service; +import com.jsowell.pile.domain.ebike.deviceupload.ChargingOperationResponse; import com.jsowell.pile.domain.ykcCommond.StartChargingCommand; import com.jsowell.pile.domain.ykcCommond.StopChargingCommand; @@ -12,12 +13,13 @@ public interface EBikeSendCommandService { * 启动充电 * @param command */ - void sendStartChargingCommand(StartChargingCommand command) throws Exception; + ChargingOperationResponse sendStartChargingCommand(StartChargingCommand command) throws Exception; /** * 停止充电 * @param command */ - void sendStopChargingCommand(StopChargingCommand command) throws Exception; + ChargingOperationResponse sendStopChargingCommand(StopChargingCommand command) throws Exception; + } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/PileRemoteService.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/PileRemoteService.java index 5700f3599..81165b00d 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/PileRemoteService.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/PileRemoteService.java @@ -1,5 +1,6 @@ package com.jsowell.pile.service; +import com.alibaba.fastjson2.JSON; import com.google.common.collect.Lists; import com.jsowell.common.constant.CacheConstants; import com.jsowell.common.core.domain.ykc.YKCDataProtocol; @@ -11,6 +12,7 @@ import com.jsowell.common.util.BytesUtil; import com.jsowell.common.util.StringUtils; import com.jsowell.pile.domain.PileBillingTemplate; import com.jsowell.pile.domain.PileFirmwareInfo; +import com.jsowell.pile.domain.ebike.deviceupload.ChargingOperationResponse; import com.jsowell.pile.domain.ykcCommond.*; import com.jsowell.pile.dto.PublishBillingTemplateDTO; import com.jsowell.pile.dto.RemoteAccountBalanceUpdateDTO; @@ -127,7 +129,8 @@ public class PileRemoteService { .chargeAmount(chargeAmount) .build(); try { - eBikeSendCommandService.sendStartChargingCommand(startChargingCommand); + ChargingOperationResponse startChargingResponse = eBikeSendCommandService.sendStartChargingCommand(startChargingCommand); + log.info("StartChargingResponse:{}", JSON.toJSONString(startChargingResponse)); } catch (Exception e) { log.error("电单车远程启动充电error", e); } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/EBikeSendCommandServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/EBikeSendCommandServiceImpl.java index 9aa50d5b3..41e6410eb 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/EBikeSendCommandServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/EBikeSendCommandServiceImpl.java @@ -5,6 +5,7 @@ import com.jsowell.common.protocol.SyncPromise; import com.jsowell.common.util.*; import com.jsowell.common.util.id.IdUtils; import com.jsowell.pile.domain.ebike.AbsEBikeMessage; +import com.jsowell.pile.domain.ebike.deviceupload.ChargingOperationResponse; import com.jsowell.pile.domain.ebike.serversend.EBikeMessageCmd82; import com.jsowell.pile.domain.ykcCommond.StartChargingCommand; import com.jsowell.pile.domain.ykcCommond.StopChargingCommand; @@ -31,7 +32,7 @@ public class EBikeSendCommandServiceImpl implements EBikeSendCommandService { * 电单车发送启动充电指令 */ @Override - public void sendStartChargingCommand(StartChargingCommand command) throws Exception { + public ChargingOperationResponse sendStartChargingCommand(StartChargingCommand command) throws Exception { String pileSn = command.getPileSn(); String connectorCode = command.getConnectorCode(); String transactionCode = command.getTransactionCode(); @@ -75,8 +76,9 @@ public class EBikeSendCommandServiceImpl implements EBikeSendCommandService { data.setFullChargePower(0); data.setMaxFullChargePowerCheckTime(0); message.setData(data); - byte[] send = this.send(message); - log.info("电单车发送启动充电指令response:{}", BytesUtil.binary(send, 16)); + byte[] response = this.send(message); + log.info("电单车发送启动充电指令response:{}", BytesUtil.binary(response, 16)); + return new ChargingOperationResponse(response); } /** @@ -84,7 +86,7 @@ public class EBikeSendCommandServiceImpl implements EBikeSendCommandService { * @param command */ @Override - public void sendStopChargingCommand(StopChargingCommand command) throws Exception { + public ChargingOperationResponse sendStopChargingCommand(StopChargingCommand command) throws Exception { String pileSn = command.getPileSn(); String connectorCode = command.getConnectorCode(); String transactionCode = command.getTransactionCode(); @@ -124,8 +126,9 @@ public class EBikeSendCommandServiceImpl implements EBikeSendCommandService { data.setFullChargePower(0); data.setMaxFullChargePowerCheckTime(0); message.setData(data); - byte[] send = this.send(message); - log.info("电单车发送停止充电指令response:{}", BytesUtil.binary(send, 16)); + byte[] response = this.send(message); + log.info("电单车发送停止充电指令response:{}", BytesUtil.binary(response, 16)); + return new ChargingOperationResponse(response); } /**