mirror of
https://gitee.com/san-bing/JChargePointProtocol
synced 2026-05-04 18:09:54 +08:00
修正云快充OTA升级中的一些BUG,并优化代码
This commit is contained in:
@@ -18,6 +18,7 @@ import sanbing.jcpp.protocol.yunkuaichong.enums.YunKuaiChongDownlinkCmdEnum;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DecimalFormat;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
@@ -153,22 +154,71 @@ public class AbstractYunKuaiChongCmdExe {
|
||||
return new BigDecimal(value).divide(new BigDecimal(magnification), scale, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
protected static ByteBuf writeParamFillZero(String param,int maxLength) {
|
||||
if (param.length() > maxLength) {
|
||||
throw new IllegalArgumentException(String.format("云快充1.5.0 param: %s too large",param));
|
||||
/**
|
||||
* 高性能版本:直接写入目标ByteBuf,避免创建中间ByteBuf对象
|
||||
* 将字符串参数写入ByteBuf,不足指定长度用0填充(右侧填充)
|
||||
* 使用ASCII编码,适用于协议中的字符串字段
|
||||
*
|
||||
* @param target 目标ByteBuf
|
||||
* @param param 要写入的字符串参数,可以为null
|
||||
* @param maxLength 目标长度(字节数)
|
||||
* @throws IllegalArgumentException 如果参数字节长度超过maxLength
|
||||
*/
|
||||
protected static void writeParamFillZero(ByteBuf target, String param, int maxLength) {
|
||||
if (maxLength <= 0) {
|
||||
throw new IllegalArgumentException("maxLength must be positive");
|
||||
}
|
||||
|
||||
if (param == null) {
|
||||
param = "";
|
||||
}
|
||||
|
||||
// 使用ASCII编码,适用于协议字段
|
||||
byte[] paramBytes = param.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
// 检查长度
|
||||
if (paramBytes.length > maxLength) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("云快充1.5.0 参数: %s 字节长度 %d 超过最大长度 %d",
|
||||
param, paramBytes.length, maxLength));
|
||||
}
|
||||
|
||||
// 确保目标ByteBuf有足够的写入空间
|
||||
target.ensureWritable(maxLength);
|
||||
|
||||
// 写入数据
|
||||
target.writeBytes(paramBytes);
|
||||
|
||||
// 填充剩余空间
|
||||
int remainingBytes = maxLength - paramBytes.length;
|
||||
if (remainingBytes > 0) {
|
||||
target.writeZero(remainingBytes);
|
||||
}
|
||||
ByteBuf msgBody = Unpooled.buffer(maxLength);
|
||||
msgBody.writeBytes(param.getBytes());
|
||||
msgBody.writeZero(maxLength-param.length());
|
||||
return msgBody;
|
||||
}
|
||||
|
||||
protected static ByteBuf writeParamFillZero(int param,int maxLength) {
|
||||
ByteBuf msgBody = Unpooled.buffer(maxLength);
|
||||
msgBody.writeByte(param);
|
||||
int index = msgBody.writerIndex();
|
||||
msgBody.writeZero(maxLength-index);
|
||||
return msgBody;
|
||||
/**
|
||||
* 高性能版本:将整数参数作为字节值直接写入ByteBuf,不足指定长度用0填充(右侧填充)
|
||||
*
|
||||
* @param target 目标ByteBuf
|
||||
* @param param 要写入的整数参数(将作为字节值写入,只使用低8位)
|
||||
* @param maxLength 目标长度(字节数)
|
||||
*/
|
||||
protected static void writeParamFillZero(ByteBuf target, int param, int maxLength) {
|
||||
if (maxLength <= 0) {
|
||||
throw new IllegalArgumentException("maxLength must be positive");
|
||||
}
|
||||
|
||||
// 确保目标ByteBuf有足够的写入空间
|
||||
target.ensureWritable(maxLength);
|
||||
|
||||
// 将整数作为字节值写入(只使用低8位)
|
||||
target.writeByte(param & 0xFF);
|
||||
|
||||
// 计算剩余空间并填充0
|
||||
int remainingBytes = maxLength - 1; // 已经写入了1个字节
|
||||
if (remainingBytes > 0) {
|
||||
target.writeZero(remainingBytes);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public enum YunKuaiChongDownlinkCmdEnum {
|
||||
|
||||
REMOTE_RESTART_PILE(0x92),
|
||||
|
||||
REMOTE_UPDATE(0x94),
|
||||
OTA_REQUEST(0x94),
|
||||
|
||||
;
|
||||
private final Integer cmd;
|
||||
|
||||
@@ -1,52 +1,58 @@
|
||||
/**
|
||||
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||
* 微信:mohan_88888
|
||||
* 抖音:程序员三丙
|
||||
* 付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||
*/
|
||||
package sanbing.jcpp.protocol.yunkuaichong.v150.cmd;
|
||||
|
||||
import static sanbing.jcpp.protocol.yunkuaichong.enums.YunKuaiChongDownlinkCmdEnum.REMOTE_UPDATE;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import sanbing.jcpp.proto.gen.ProtocolProto;
|
||||
import sanbing.jcpp.proto.gen.ProtocolProto.OtaRequest;
|
||||
import sanbing.jcpp.protocol.ProtocolContext;
|
||||
import sanbing.jcpp.protocol.listener.tcp.TcpSession;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongDownlinkCmdExe;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongDwonlinkMessage;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.annotation.YunKuaiChongCmd;
|
||||
|
||||
import static sanbing.jcpp.protocol.yunkuaichong.enums.YunKuaiChongDownlinkCmdEnum.OTA_REQUEST;
|
||||
|
||||
|
||||
/**
|
||||
* 云快充1.5.0 远程更新
|
||||
*
|
||||
* @author bawan
|
||||
*/
|
||||
@Slf4j
|
||||
@YunKuaiChongCmd(0x94)
|
||||
public class YunKuaiChongV150RemoteUpdateDLCmd extends YunKuaiChongDownlinkCmdExe {
|
||||
public class YunKuaiChongV150OtaRequestDLCmd extends YunKuaiChongDownlinkCmdExe {
|
||||
|
||||
@Override
|
||||
public void execute(TcpSession tcpSession, YunKuaiChongDwonlinkMessage message, ProtocolContext ctx) {
|
||||
log.info("{} 云快充1.5.0 远程更新", tcpSession);
|
||||
// check
|
||||
if (message.getMsg().hasOtaRequest()) {
|
||||
|
||||
if (!message.getMsg().hasOtaRequest()) {
|
||||
log.error("云快充1.5.0 远程更新消息体为空");
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化 buf
|
||||
ByteBuf msgBody = Unpooled.buffer(94);
|
||||
// buf 转换
|
||||
ProtocolProto.OtaRequest request = message.getMsg().getOtaRequest();
|
||||
// buf 转换 - 使用高性能版本直接写入,避免创建中间ByteBuf对象
|
||||
OtaRequest request = message.getMsg().getOtaRequest();
|
||||
msgBody.writeBytes(encodePileCode(request.getPileCode()));
|
||||
msgBody.writeByte(request.getPileModel());
|
||||
msgBody.writeBytes(writeParamFillZero(request.getPilePower(),2));
|
||||
msgBody.writeBytes(writeParamFillZero(request.getAddress(),16));
|
||||
msgBody.writeBytes(writeParamFillZero(request.getPort(),2));
|
||||
msgBody.writeBytes(writeParamFillZero(request.getUsername(),16));
|
||||
msgBody.writeBytes(writeParamFillZero(request.getPassword(),16));
|
||||
msgBody.writeBytes(writeParamFillZero(request.getFilePath(),32));
|
||||
writeParamFillZero(msgBody, request.getPilePower(), 2);
|
||||
writeParamFillZero(msgBody, request.getAddress(), 16);
|
||||
writeParamFillZero(msgBody, request.getPort(), 2);
|
||||
writeParamFillZero(msgBody, request.getUsername(), 16);
|
||||
writeParamFillZero(msgBody, request.getPassword(), 16);
|
||||
writeParamFillZero(msgBody, request.getFilePath(), 32);
|
||||
msgBody.writeByte(request.getExecutionControl());
|
||||
msgBody.writeByte(request.getDownloadTimeout());
|
||||
|
||||
super.encodeAndWriteFlush(REMOTE_UPDATE,msgBody,tcpSession);
|
||||
super.encodeAndWriteFlush(OTA_REQUEST, msgBody, tcpSession);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
/**
|
||||
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||
* 微信:mohan_88888
|
||||
* 抖音:程序员三丙
|
||||
* 付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||
*/
|
||||
package sanbing.jcpp.protocol.yunkuaichong.v150.cmd;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -13,6 +17,8 @@ import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkCmdExe;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkMessage;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.annotation.YunKuaiChongCmd;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 云快充1.5.0 远程更新应答
|
||||
@@ -21,7 +27,7 @@ import sanbing.jcpp.protocol.yunkuaichong.annotation.YunKuaiChongCmd;
|
||||
*/
|
||||
@Slf4j
|
||||
@YunKuaiChongCmd(0x93)
|
||||
public class YunKuaiChongV150RemoteUpdateAckULCmd extends YunKuaiChongUplinkCmdExe {
|
||||
public class YunKuaiChongV150OtaResponseULCmd extends YunKuaiChongUplinkCmdExe {
|
||||
|
||||
private static final Map<Byte, String> UPGRADE_STATUS;
|
||||
|
||||
Reference in New Issue
Block a user