!50 0x19 云快充1.5.0 充电结束、0x52 云快充1.5.0 充电桩工作参数设置、0x51 云快充1.5.0 充电桩工作参数设置应答

* 0x19 云快充1.5.0 充电结束、0x52 云快充1.5.0  充电桩工作参数设置、0x51 云快充1.5.0  充电桩工作参数设置应答
This commit is contained in:
八万
2025-10-28 05:57:34 +00:00
committed by 三丙
parent 32334b6ba7
commit 26cec08d61
12 changed files with 332 additions and 5 deletions

View File

@@ -180,4 +180,14 @@ c0 57 01 00
#### 成功
`68 38 19 00 00 47 20 23 12 12 00 00 10 10 00 00 00 00 12 34 56 01 10 00 00 00 00 12 34 57 01 10 00 00 00 00 12 34 58 01 10 00 00 00 00 12 34 59 01 10 00 00 00 00 12 34 60 01 9a 7c`
#### 失败
`68 38 19 00 00 47 20 23 12 12 00 00 10 10 00 00 00 00 12 34 56 00 10 00 00 00 00 12 34 57 00 10 00 00 00 00 12 34 58 00 10 00 00 00 00 12 34 59 00 10 00 00 00 00 12 34 60 00 28 95`
`68 38 19 00 00 47 20 23 12 12 00 00 10 10 00 00 00 00 12 34 56 00 10 00 00 00 00 12 34 57 00 10 00 00 00 00 12 34 58 00 10 00 00 00 00 12 34 59 00 10 00 00 00 00 12 34 60 00 28 95`
#### 0x19 结束充电(充电桩 -> JCPP
`68 2c 19 00 00 19 00 00 00 00 00 00 00 00 00 20 23 12 12 00 00 10 20 23 12 12 00 00 10 01 09 09 00 09 00 0f 0f 0f 00 0f 00 01 00 00 00 00 4a 37`
#### 0x51 充电桩工作参数设置应答(充电桩 -> JCPP
`68 0c 19 00 00 51 20 23 12 12 00 00 10 01 2f d9`
#### 0x52 充电桩工作参数设置JCPP -> 充电桩)
`68 0d 02 00 00 52 20 23 12 12 00 00 10 00 f0 4d 1c`

View File

@@ -54,6 +54,9 @@ public class YunKuaiChongDownlinkCmdConverter implements DownlinkCmdConverter {
COMMAND_MAP.put(DownlinkCmdEnum.SYNC_TIME_REQUEST, 0x56);
COMMAND_MAP.put(DownlinkCmdEnum.OFFLINE_CARD_CLEAR_REQUEST, 0x46);
COMMAND_MAP.put(DownlinkCmdEnum.OFFLINE_CARD_QUERY_REQUEST, 0x48);
COMMAND_MAP.put(DownlinkCmdEnum.WORK_PARAM_SETTING_REQUEST, 0x52);
}

View File

@@ -0,0 +1,98 @@
/**
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
* 微信mohan_88888
* 抖音:程序员三丙
* 付费课程知识星球https://t.zsxq.com/aKtXo
*/
package sanbing.jcpp.protocol.yunkuaichong.v150.cmd;
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.V150;
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.V160;
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.V170;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.extern.slf4j.Slf4j;
import sanbing.jcpp.infrastructure.util.codec.BCDUtil;
import sanbing.jcpp.infrastructure.util.jackson.JacksonUtil;
import sanbing.jcpp.proto.gen.UplinkProto;
import sanbing.jcpp.protocol.ProtocolContext;
import sanbing.jcpp.protocol.annotation.ProtocolCmd;
import sanbing.jcpp.protocol.listener.tcp.TcpSession;
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkCmdExe;
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkMessage;
/**
* 云快充1.5.0 充电结束
*
* @author bawan
*/
@Slf4j
@ProtocolCmd(value = 0x19, protocolNames = {V150, V160, V170})
public class YunKuaiChongV150EndChargeULCmd extends YunKuaiChongUplinkCmdExe {
@Override
public void execute(TcpSession tcpSession, YunKuaiChongUplinkMessage yunKuaiChongUplinkMessage, ProtocolContext ctx) {
log.debug("{} 云快充1.5.0充电结束", tcpSession);
ByteBuf byteBuf = Unpooled.wrappedBuffer(yunKuaiChongUplinkMessage.getMsgBody());
// 交易流水号
byte[] tradeNoBytes = new byte[16];
byteBuf.readBytes(tradeNoBytes);
String tradeNo = BCDUtil.toString(tradeNoBytes);
// 桩编号
byte[] pileCodeBytes = new byte[7];
byteBuf.readBytes(pileCodeBytes);
String pileCode = BCDUtil.toString(pileCodeBytes);
// 枪号
byte gunCodeByte = byteBuf.readByte();
String gunCode = BCDUtil.toString(gunCodeByte);
ObjectNode additionalInfo = JacksonUtil.newObjectNode();
// 4 BMS 中止荷电状态
additionalInfo.put("BMS 中止荷电状态 SOC", byteBuf.readByte());
// 5 BMS 动力蓄电池单体最低电压
additionalInfo.put("BMS 动力蓄电池单体最低电压", byteBuf.readShortLE());
// 6 BMS 动力蓄电池单体最高电压
additionalInfo.put("BMS 动力蓄电池单体最高电压", byteBuf.readShortLE());
// 7 BMS 动力蓄电池最低温度
additionalInfo.put("BMS 动力蓄电池最低温度", byteBuf.readByte());
// 8 BMS 动力蓄电池最高温度
additionalInfo.put("BMS 动力蓄电池最高温度", byteBuf.readByte());
// 9 电桩累计充电时间
additionalInfo.put("电桩累计充电时间", byteBuf.readShortLE());
// 10 电桩输出能量
additionalInfo.put("电桩输出能量", byteBuf.readShortLE());
// 11 电桩充电机编号
byte[] chargerCode = new byte[4];
byteBuf.readBytes(chargerCode);
additionalInfo.put("电桩充电机编号", BCDUtil.toString(chargerCode));
// 转发到后端
UplinkProto.UplinkQueueMessage uplinkQueueMessage = uplinkMessageBuilder(pileCode, tcpSession, yunKuaiChongUplinkMessage)
.setEndChargeProto(UplinkProto.EndChargeProto.newBuilder()
.setTradeNo(tradeNo)
.setPileCode(pileCode)
.setGunCode(gunCode)
.setAdditionalInfo(additionalInfo.toString())
.build())
.build();
tcpSession.getForwarder().sendMessage(uplinkQueueMessage);
}
}

View File

@@ -0,0 +1,54 @@
/**
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
* 微信mohan_88888
* 抖音:程序员三丙
* 付费课程知识星球https://t.zsxq.com/aKtXo
*/
package sanbing.jcpp.protocol.yunkuaichong.v150.cmd;
import static sanbing.jcpp.protocol.domain.DownlinkCmdEnum.WORK_PARAM_SETTING_REQUEST;
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.V150;
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.V160;
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.V170;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.extern.slf4j.Slf4j;
import sanbing.jcpp.proto.gen.DownlinkProto;
import sanbing.jcpp.protocol.ProtocolContext;
import sanbing.jcpp.protocol.annotation.ProtocolCmd;
import sanbing.jcpp.protocol.listener.tcp.TcpSession;
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongDownlinkCmdExe;
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongDwonlinkMessage;
/**
* 云快充1.5.0 充电桩工作参数设置
*
* @author bawan
*/
@Slf4j
@ProtocolCmd(value = 0x52, protocolNames = {V150, V160, V170})
public class YunKuaiChongV150WorkParamSettingRequestDLCmd extends YunKuaiChongDownlinkCmdExe {
@Override
public void execute(TcpSession tcpSession, YunKuaiChongDwonlinkMessage message, ProtocolContext ctx) {
log.info("{} 云快充1.5.0 充电桩工作参数设置", tcpSession);
if (!message.getMsg().hasWorkParamSettingRequest()) {
log.error("云快充1.5.0 充电桩工作参数设置消息体为空");
return;
}
DownlinkProto.WorkParamSettingRequest request = message.getMsg().getWorkParamSettingRequest();
// 初始化 buf
ByteBuf msgBody = Unpooled.buffer(9);
msgBody.writeBytes(encodePileCode(request.getPileCode()));
msgBody.writeByte(request.getAllow()?0x00:0x01);
msgBody.writeByte(request.getMaxAllowOutPower());
super.encodeAndWriteFlush(WORK_PARAM_SETTING_REQUEST, msgBody, tcpSession);
}
}

View File

@@ -0,0 +1,60 @@
/**
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
* 微信mohan_88888
* 抖音:程序员三丙
* 付费课程知识星球https://t.zsxq.com/aKtXo
*/
package sanbing.jcpp.protocol.yunkuaichong.v150.cmd;
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.V150;
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.V160;
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.V170;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.extern.slf4j.Slf4j;
import sanbing.jcpp.infrastructure.util.codec.BCDUtil;
import sanbing.jcpp.proto.gen.UplinkProto;
import sanbing.jcpp.protocol.ProtocolContext;
import sanbing.jcpp.protocol.annotation.ProtocolCmd;
import sanbing.jcpp.protocol.listener.tcp.TcpSession;
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkCmdExe;
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkMessage;
/**
* 云快充1.5.0 充电桩工作参数设置应答
*
* @author bawan
*/
@Slf4j
@ProtocolCmd(value = 0x51, protocolNames = {V150, V160, V170})
public class YunKuaiChongV150WorkParamSettingResponseULCmd extends YunKuaiChongUplinkCmdExe {
@Override
public void execute(TcpSession tcpSession, YunKuaiChongUplinkMessage message, ProtocolContext ctx) {
log.info("{} 云快充1.5.0 充电桩工作参数设置应答", tcpSession);
ByteBuf byteBuf = Unpooled.wrappedBuffer(message.getMsgBody());
// 桩编号
byte[] pileCodeBytes = new byte[7];
byteBuf.readBytes(pileCodeBytes);
String pileCode = BCDUtil.toString(pileCodeBytes);
// 设置结果
byte settingResult = byteBuf.readByte();
UplinkProto.UplinkQueueMessage queueMessage = uplinkMessageBuilder(pileCode, tcpSession, message)
.setWorkParamSettingResponse(UplinkProto.WorkParamSettingResponse.newBuilder()
.setPileCode(pileCode)
.setSuccess(settingResult==0x01)
.build())
.build();
// 转发到后端
tcpSession.getForwarder().sendMessage(queueMessage);
}
}