!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

@@ -373,7 +373,7 @@ public class TestController extends BaseController {
return ResponseEntity.ok("success");
}
@GetMapping("/api/offlineCardClearRequest")
@GetMapping("/offlineCardClearRequest")
public ResponseEntity<String> offlineCardClearRequest() {
List<String> cardNoList = Lists.newArrayList("1000000000123456", "1000000000123457", "1000000000123458", "1000000000123459", "1000000000123460");
@@ -387,7 +387,7 @@ public class TestController extends BaseController {
return ResponseEntity.ok("success");
}
@GetMapping("/api/offlineCardQueryRequest")
@GetMapping("/offlineCardQueryRequest")
public ResponseEntity<String> offlineCardQueryRequest() {
List<String> cardNoList = Lists.newArrayList("1000000000123456", "1000000000123457", "1000000000123458", "1000000000123459", "1000000000123460");
@@ -402,4 +402,18 @@ public class TestController extends BaseController {
return ResponseEntity.ok("success");
}
@GetMapping("/workParamSettingRequest")
public ResponseEntity<String> workParamSettingRequest() {
pileProtocolService.workParamSettingRequest(WorkParamSettingRequest.newBuilder()
.setPileCode("20231212000010")
.setAllow(true)
.setMaxAllowOutPower(240)
.build());
return ResponseEntity.ok("success");
}
}

View File

@@ -214,4 +214,19 @@ public interface PileProtocolService {
* 服务器下发充电桩字符型参数反馈
*/
void onSetQrcodeResponse(UplinkQueueMessage uplinkQueueMsg, Callback callback);
/**
* 充电桩工作参数设置
*/
void workParamSettingRequest(DownlinkProto.WorkParamSettingRequest request);
/**
* 充电桩工作参数设置应答
*/
void onWorkParamSettingRequest(UplinkQueueMessage uplinkQueueMsg, Callback callback);
/**
* 结束充电
*/
void onEndCharge(UplinkQueueMessage uplinkQueueMsg, Callback callback);
}

View File

@@ -970,4 +970,40 @@ public class DefaultPileProtocolService implements PileProtocolService {
}
}
@Override
public void workParamSettingRequest(WorkParamSettingRequest request) {
UUID messageId = UUID.randomUUID();
UUID requestId = UUID.randomUUID();
DownlinkRequestMessage.Builder downlinkRequestMessageBuilder = DownlinkRequestMessage.newBuilder()
.setMessageIdMSB(messageId.getMostSignificantBits())
.setMessageIdLSB(messageId.getLeastSignificantBits())
.setPileCode(request.getPileCode())
.setRequestIdMSB(requestId.getMostSignificantBits())
.setRequestIdLSB(requestId.getLeastSignificantBits())
.setDownlinkCmd(DownlinkCmdEnum.WORK_PARAM_SETTING_REQUEST.name())
.setWorkParamSettingRequest(request);
downlinkCallService.sendDownlinkMessage(downlinkRequestMessageBuilder,request.getPileCode());
}
@Override
public void onWorkParamSettingRequest(UplinkQueueMessage uplinkQueueMsg, Callback callback) {
log.info("接收到充电桩工作参数设置应答 {}", uplinkQueueMsg);
// TODO 处理相关业务逻辑
callback.onSuccess();
}
@Override
public void onEndCharge(UplinkQueueMessage uplinkQueueMsg, Callback callback) {
log.info("接收到 结束充电 {}", uplinkQueueMsg);
// TODO 处理相关业务逻辑
callback.onSuccess();
}
}

View File

@@ -265,7 +265,15 @@ public class ProtocolUplinkConsumerService extends AbstractConsumerService {
pileProtocolService.onSetQrcodeResponse(uplinkQueueMsg, callback);
} else {
} else if (uplinkQueueMsg.hasWorkParamSettingResponse()) {
pileProtocolService.onWorkParamSettingRequest(uplinkQueueMsg, callback);
} else if (uplinkQueueMsg.hasEndChargeProto()) {
pileProtocolService.onEndCharge(uplinkQueueMsg, callback);
} else {
callback.onSuccess();
}

View File

@@ -39,6 +39,7 @@ message DownlinkRequestMessage {
SetQrcodeRequest setQrcodeRequest = 34;
OfflineCardClearRequest offlineCardClearRequest = 35;
OfflineCardQueryRequest offlineCardQueryRequest = 36;
WorkParamSettingRequest workParamSettingRequest = 37;
}
// 下行响应消息
@@ -273,3 +274,9 @@ message OfflineCardQueryRequest {
repeated string cardNo = 3; // 物理卡号集合
}
message WorkParamSettingRequest {
string pileCode = 1; // 桩编号
bool allow = 2; // 是否允许工作
int32 maxAllowOutPower = 3; // 充电桩最大允许输出功率
}

View File

@@ -48,6 +48,8 @@ message UplinkQueueMessage {
SetQrcodeResponse setQrcodeResponse = 45;
OfflineCardClearResponse offlineCardClearResponse = 46;
OfflineCardQueryResponse offlineCardQueryResponse = 47;
EndChargeProto endChargeProto = 48;
WorkParamSettingResponse workParamSettingResponse = 49;
}
// 会话关闭事件
@@ -384,3 +386,19 @@ message SetQrcodeResponse {
int32 type = 7;
int32 startAddr = 8;
}
message EndChargeProto {
string tradeNo = 1; // 交易流水号
string pileCode = 2; // 桩编号枪号
string gunCode = 3; // 枪号
optional string additionalInfo = 4;
}
message WorkParamSettingResponse {
string pileCode = 1;
bool success = 2;
}

View File

@@ -47,5 +47,9 @@ public enum DownlinkCmdEnum {
OFFLINE_CARD_QUERY_REQUEST,
START_CHARGE_ACK
START_CHARGE_ACK,
WORK_PARAM_SETTING_REQUEST,
;
}

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);
}
}