mirror of
https://gitee.com/san-bing/JChargePointProtocol
synced 2026-05-14 14:59:57 +08:00
!27 Merge branch 'master' into Feat_远程账户余额更新
* 离线卡数据同步(0x44) 离线卡数据同步应答(0x43) * Merge branch 'master' into Feat_远程账户余额更新 * 离线卡数据同步(0x44) 离线卡数据同步应答(0x43) * 下发卡个数 参数校验 * Merge branch 'master' into Feat_远程账户余额更新 * 离线卡数据同步(0x44) 离线卡数据同步应答(0x43) * 远程账户余额更新(0x42) 余额更新应答(0x41)
This commit is contained in:
@@ -6,16 +6,28 @@
|
|||||||
*/
|
*/
|
||||||
package sanbing.jcpp.app.adapter;
|
package sanbing.jcpp.app.adapter;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import sanbing.jcpp.app.service.PileProtocolService;
|
import sanbing.jcpp.app.service.PileProtocolService;
|
||||||
import sanbing.jcpp.proto.gen.ProtocolProto;
|
import sanbing.jcpp.proto.gen.ProtocolProto;
|
||||||
import sanbing.jcpp.proto.gen.ProtocolProto.*;
|
import sanbing.jcpp.proto.gen.ProtocolProto.CardInfo;
|
||||||
|
import sanbing.jcpp.proto.gen.ProtocolProto.FlagPriceProto;
|
||||||
import java.math.BigDecimal;
|
import sanbing.jcpp.proto.gen.ProtocolProto.OfflineCardSyncRequest;
|
||||||
import java.util.HashMap;
|
import sanbing.jcpp.proto.gen.ProtocolProto.PeriodProto;
|
||||||
|
import sanbing.jcpp.proto.gen.ProtocolProto.PricingModelFlag;
|
||||||
|
import sanbing.jcpp.proto.gen.ProtocolProto.PricingModelProto;
|
||||||
|
import sanbing.jcpp.proto.gen.ProtocolProto.PricingModelRule;
|
||||||
|
import sanbing.jcpp.proto.gen.ProtocolProto.PricingModelType;
|
||||||
|
import sanbing.jcpp.proto.gen.ProtocolProto.SetPricingRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author baigod
|
* @author baigod
|
||||||
@@ -174,4 +186,33 @@ public class TestController {
|
|||||||
return ResponseEntity.ok("success");
|
return ResponseEntity.ok("success");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/api/limitUpdateRequest")
|
||||||
|
public ResponseEntity<String> limitUpdateRequest() {
|
||||||
|
|
||||||
|
pileProtocolService.limitUpdateRequest(ProtocolProto.LimitUpdateRequest.newBuilder()
|
||||||
|
.setCardNo("1000000000123456")
|
||||||
|
.setPileCode("20231212000010")
|
||||||
|
.setGunCode("01")
|
||||||
|
.setLimitYuan("1000")
|
||||||
|
.build());
|
||||||
|
|
||||||
|
return ResponseEntity.ok("success");
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/api/offlineCardSyncRequest")
|
||||||
|
public ResponseEntity<String> offlineCardSyncRequest() {
|
||||||
|
|
||||||
|
List<CardInfo> cardInfos = Lists.newArrayList(CardInfo.newBuilder().setCardNo("1000000000123456").setLogicCardNo("1000000000123456").build(),
|
||||||
|
CardInfo.newBuilder().setCardNo("1000000000123457").setLogicCardNo("1000000000123457").build(),
|
||||||
|
CardInfo.newBuilder().setCardNo("1000000000123458").setLogicCardNo("1000000000123458").build());
|
||||||
|
|
||||||
|
pileProtocolService.offlineCardSyncRequest(OfflineCardSyncRequest.newBuilder()
|
||||||
|
.setPileCode("20231212000010")
|
||||||
|
.setTotal(cardInfos.size())
|
||||||
|
.addAllCardInfo(cardInfos)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
return ResponseEntity.ok("success");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -136,4 +136,23 @@ public interface PileProtocolService {
|
|||||||
*/
|
*/
|
||||||
void postLockStatus(UplinkQueueMessage uplinkQueueMessage, Callback callback);
|
void postLockStatus(UplinkQueueMessage uplinkQueueMessage, Callback callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程账户余额更新
|
||||||
|
*/
|
||||||
|
void limitUpdateRequest(ProtocolProto.LimitUpdateRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 远程账户余额更新应答
|
||||||
|
*/
|
||||||
|
void onLimitUpdateResponse(UplinkQueueMessage uplinkQueueMessage, Callback callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 离线卡数据同步
|
||||||
|
*/
|
||||||
|
void offlineCardSyncRequest(ProtocolProto.OfflineCardSyncRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 离线卡数据同步应答
|
||||||
|
*/
|
||||||
|
void onOfflineCardSyncResponse(UplinkQueueMessage uplinkQueueMessage, Callback callback);
|
||||||
}
|
}
|
||||||
@@ -453,6 +453,57 @@ public class DefaultPileProtocolService implements PileProtocolService {
|
|||||||
callback.onSuccess();
|
callback.onSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLimitUpdateResponse(UplinkQueueMessage uplinkQueueMessage, Callback callback) {
|
||||||
|
log.info("接收到充电桩远程账户余额更新应答 {}", uplinkQueueMessage);
|
||||||
|
|
||||||
|
// TODO 处理相关业务逻辑
|
||||||
|
|
||||||
|
callback.onSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void limitUpdateRequest(LimitUpdateRequest 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.LIMIT_UPDATE_REQUEST.name())
|
||||||
|
.setLimitUpdateRequest(request);
|
||||||
|
downlinkCallService.sendDownlinkMessage(downlinkRequestMessageBuilder,request.getPileCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void offlineCardSyncRequest(OfflineCardSyncRequest 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.OFFLINE_CARD_SYNC_REQUEST.name())
|
||||||
|
.setOfflineCardSyncRequest(request);
|
||||||
|
downlinkCallService.sendDownlinkMessage(downlinkRequestMessageBuilder,request.getPileCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOfflineCardSyncResponse(UplinkQueueMessage uplinkQueueMessage, Callback callback) {
|
||||||
|
log.info("接收到充电桩离线卡数据同步应答 {}", uplinkQueueMessage);
|
||||||
|
|
||||||
|
// TODO 处理相关业务逻辑
|
||||||
|
|
||||||
|
callback.onSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
private static Period createPeriod(int sn, LocalTime beginTime, LocalTime endTime, PricingModelFlag flag) {
|
private static Period createPeriod(int sn, LocalTime beginTime, LocalTime endTime, PricingModelFlag flag) {
|
||||||
Period period = new Period();
|
Period period = new Period();
|
||||||
period.setSn(sn);
|
period.setSn(sn);
|
||||||
|
|||||||
@@ -224,6 +224,14 @@ public class ProtocolUplinkConsumerService extends AbstractConsumerService imple
|
|||||||
|
|
||||||
pileProtocolService.postLockStatus(uplinkQueueMsg, callback);
|
pileProtocolService.postLockStatus(uplinkQueueMsg, callback);
|
||||||
|
|
||||||
|
} else if (uplinkQueueMsg.hasLimitUpdateResponse()) {
|
||||||
|
|
||||||
|
pileProtocolService.onLimitUpdateResponse(uplinkQueueMsg, callback);
|
||||||
|
|
||||||
|
} else if (uplinkQueueMsg.hasOfflineCardSyncResponse()) {
|
||||||
|
|
||||||
|
pileProtocolService.onOfflineCardSyncResponse(uplinkQueueMsg, callback);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
callback.onSuccess();
|
callback.onSuccess();
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ message UplinkQueueMessage {
|
|||||||
BmsHandshakeProto bmsHandshakeProto = 37;
|
BmsHandshakeProto bmsHandshakeProto = 37;
|
||||||
OtaResponse otaResponse = 38;
|
OtaResponse otaResponse = 38;
|
||||||
GroundLockStatusProto groundLockStatusProto = 39;
|
GroundLockStatusProto groundLockStatusProto = 39;
|
||||||
|
LimitUpdateResponse limitUpdateResponse = 40;
|
||||||
|
OfflineCardSyncResponse offlineCardSyncResponse = 41;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,6 +99,8 @@ message DownlinkRequestMessage {
|
|||||||
TransactionRecordResponse transactionRecordResponse = 27;
|
TransactionRecordResponse transactionRecordResponse = 27;
|
||||||
RestartPileRequest restartPileRequest = 28;
|
RestartPileRequest restartPileRequest = 28;
|
||||||
OtaRequest otaRequest = 29;
|
OtaRequest otaRequest = 29;
|
||||||
|
LimitUpdateRequest limitUpdateRequest = 30;
|
||||||
|
OfflineCardSyncRequest offlineCardSyncRequest = 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DownlinkResponseMessage {
|
message DownlinkResponseMessage {
|
||||||
@@ -434,3 +438,35 @@ message GroundLockStatusProto {
|
|||||||
int32 reserved = 8; // 预留位
|
int32 reserved = 8; // 预留位
|
||||||
optional string additionalInfo = 20; // 附加信息
|
optional string additionalInfo = 20; // 附加信息
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message LimitUpdateRequest {
|
||||||
|
string pileCode = 1; // 充电桩编码
|
||||||
|
string gunCode = 2; // 枪编号
|
||||||
|
string cardNo = 3; // 物理卡号
|
||||||
|
string limitYuan = 4; // 余额
|
||||||
|
}
|
||||||
|
|
||||||
|
message LimitUpdateResponse {
|
||||||
|
string pileCode = 1; // 充电桩编码
|
||||||
|
string cardNo = 2; // 物理卡号
|
||||||
|
bool success = 3;
|
||||||
|
optional string errorMsg = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message OfflineCardSyncRequest {
|
||||||
|
string pileCode = 1; // 充电桩编码
|
||||||
|
int32 total = 2; // 下发卡个数
|
||||||
|
repeated CardInfo cardInfo = 3; // 卡号集合
|
||||||
|
}
|
||||||
|
|
||||||
|
message CardInfo {
|
||||||
|
string cardNo = 1; // 物理卡号
|
||||||
|
string logicCardNo = 2; // 逻辑卡号
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message OfflineCardSyncResponse {
|
||||||
|
string pileCode = 1; // 充电桩编码
|
||||||
|
bool success = 3;
|
||||||
|
optional string errorMsg = 4;
|
||||||
|
}
|
||||||
@@ -30,4 +30,8 @@ public enum DownlinkCmdEnum {
|
|||||||
REMOTE_RESTART_PILE,
|
REMOTE_RESTART_PILE,
|
||||||
|
|
||||||
OTA_REQUEST,
|
OTA_REQUEST,
|
||||||
|
|
||||||
|
LIMIT_UPDATE_REQUEST,
|
||||||
|
|
||||||
|
OFFLINE_CARD_SYNC_REQUEST
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<configuration status="INFO" monitorInterval="30">
|
<configuration status="INFO" monitorInterval="30">
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<Property name="LOG_DIR">/home/sanbing/logs/jcpp</Property>
|
<Property name="LOG_DIR">./logs/jcpp</Property>
|
||||||
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss:SSS} [%X{TRACE_ID}] [%t] %p %c{1} %m%n%throwable</Property>
|
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss:SSS} [%X{TRACE_ID}] [%t] %p %c{1} %m%n%throwable</Property>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|||||||
@@ -101,3 +101,18 @@
|
|||||||
|
|
||||||
#### 0x61 地锁数据上送
|
#### 0x61 地锁数据上送
|
||||||
`68 14 00 01 00 61 20 23 12 12 00 00 10 01 00 00 00 00 00 00 00 00 3D 6D`
|
`68 14 00 01 00 61 20 23 12 12 00 00 10 01 00 00 00 00 00 00 00 00 3D 6D`
|
||||||
|
#### 0x42 远程账户余额更新
|
||||||
|
`68 18 04 00 00 42 20 23 12 12 00 00 10 01 30 31 00 00 00 00 00 00 a0 86 01 00 4e ac`
|
||||||
|
|
||||||
|
#### 0x41 远程账户余额更新应答
|
||||||
|
`68 14 19 00 00 41 20 23 12 12 00 00 10 10 00 00 00 00 12 34 56 00 bc 16`
|
||||||
|
|
||||||
|
|
||||||
|
#### 0x44 离线卡数据同步
|
||||||
|
`68 3f 02 00 00 44 20 23 12 12 00 00 10 03 00 00 00 10 00 00 00 00 12 34 56 10 00 00 00 00 12 34 56 10 00 00 00 00 12 34 57 10 00 00 00 00 12 34 57 10 00 00 00 00 12 34 58 10 00 00 00 00 12 34 58 ba 94`
|
||||||
|
|
||||||
|
#### 0x43 离线卡数据同步应答
|
||||||
|
#### 成功
|
||||||
|
`68 0d 19 00 00 43 20 23 12 12 00 00 10 01 00 38 83`
|
||||||
|
#### 失败
|
||||||
|
`68 0d 19 00 00 43 20 23 12 12 00 00 10 00 01 f8 d3`
|
||||||
@@ -41,6 +41,10 @@ public class AbstractYunKuaiChongCmdExe {
|
|||||||
|
|
||||||
private static final DecimalFormat PRICING_ID_DECIMAL_FORMAT = new DecimalFormat("0000");
|
private static final DecimalFormat PRICING_ID_DECIMAL_FORMAT = new DecimalFormat("0000");
|
||||||
|
|
||||||
|
|
||||||
|
protected static final String UNKNOWN_MSG = "未知的异常";
|
||||||
|
|
||||||
|
|
||||||
protected static String decodeTradeNo(byte[] tradeNo) {
|
protected static String decodeTradeNo(byte[] tradeNo) {
|
||||||
String tradeNoStr = BCDUtil.toString(tradeNo);
|
String tradeNoStr = BCDUtil.toString(tradeNo);
|
||||||
return CharSequenceUtil.strip(tradeNoStr, "0", null);
|
return CharSequenceUtil.strip(tradeNoStr, "0", null);
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ public enum YunKuaiChongDownlinkCmdEnum {
|
|||||||
|
|
||||||
OTA_REQUEST(0x94),
|
OTA_REQUEST(0x94),
|
||||||
|
|
||||||
|
LIMIT_UPDATE_REQUEST(0x42),
|
||||||
|
|
||||||
|
OFFLINE_CARD_SYNC_REQUEST(0x44),
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
private final Integer cmd;
|
private final Integer cmd;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||||
|
* 微信:mohan_88888
|
||||||
|
* 抖音:程序员三丙
|
||||||
|
* 付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||||
|
*/
|
||||||
|
package sanbing.jcpp.protocol.yunkuaichong.v150.cmd;
|
||||||
|
|
||||||
|
import static sanbing.jcpp.protocol.yunkuaichong.enums.YunKuaiChongDownlinkCmdEnum.LIMIT_UPDATE_REQUEST;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
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.ProtocolProto;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云快充1.5.0 远程账户余额更新
|
||||||
|
*
|
||||||
|
* @author bawan
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@YunKuaiChongCmd(0x42)
|
||||||
|
public class YunKuaiChongV150LimitUpdateRequestDLCmd extends YunKuaiChongDownlinkCmdExe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(TcpSession tcpSession, YunKuaiChongDwonlinkMessage message, ProtocolContext ctx) {
|
||||||
|
log.info("{} 云快充1.5.0 远程账户余额更新", tcpSession);
|
||||||
|
|
||||||
|
if (!message.getMsg().hasLimitUpdateRequest()) {
|
||||||
|
log.error("云快充1.5.0 远程账户余额更新消息体为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化 buf
|
||||||
|
ByteBuf msgBody = Unpooled.buffer(20);
|
||||||
|
ProtocolProto.LimitUpdateRequest request = message.getMsg().getLimitUpdateRequest();
|
||||||
|
msgBody.writeBytes(encodePileCode(request.getPileCode()));
|
||||||
|
msgBody.writeBytes(encodeGunCode(request.getGunCode()));
|
||||||
|
msgBody.writeBytes(BCDUtil.toBytes(request.getCardNo()));
|
||||||
|
msgBody.writeIntLE(new BigDecimal(request.getLimitYuan()).movePointRight(2).intValue());
|
||||||
|
|
||||||
|
super.encodeAndWriteFlush(LIMIT_UPDATE_REQUEST, msgBody, tcpSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||||
|
* 微信:mohan_88888
|
||||||
|
* 抖音:程序员三丙
|
||||||
|
* 付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||||
|
*/
|
||||||
|
package sanbing.jcpp.protocol.yunkuaichong.v150.cmd;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
|
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.ProtocolProto;
|
||||||
|
import sanbing.jcpp.protocol.ProtocolContext;
|
||||||
|
import sanbing.jcpp.protocol.listener.tcp.TcpSession;
|
||||||
|
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkCmdExe;
|
||||||
|
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkMessage;
|
||||||
|
import sanbing.jcpp.protocol.yunkuaichong.annotation.YunKuaiChongCmd;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云快充1.5.0 余额更新应答
|
||||||
|
*
|
||||||
|
* @author bawan
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@YunKuaiChongCmd(0x41)
|
||||||
|
public class YunKuaiChongV150LimitUpdateResponseULCmd extends YunKuaiChongUplinkCmdExe {
|
||||||
|
|
||||||
|
private static final Map<Byte, String> UPDATE_RESULT;
|
||||||
|
|
||||||
|
static {
|
||||||
|
UPDATE_RESULT = Map.of(
|
||||||
|
(byte) 0x00,"修改成功",
|
||||||
|
(byte) 0x01,"设备编号错误",
|
||||||
|
(byte) 0x02,"卡号错误"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@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);
|
||||||
|
|
||||||
|
// 物理卡号
|
||||||
|
String cardNo = CharSequenceUtil.EMPTY;
|
||||||
|
if(byteBuf.readableBytes() >= 8) {
|
||||||
|
byte[] cardNoBytes = new byte[8];
|
||||||
|
byteBuf.readBytes(cardNoBytes);
|
||||||
|
cardNo = BCDUtil.toString(cardNoBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改结果 0x00-修改成功 0x01-设备编号错误 0x02-卡号错误
|
||||||
|
byte updateResult = byteBuf.readByte();
|
||||||
|
|
||||||
|
ProtocolProto.UplinkQueueMessage queueMessage = uplinkMessageBuilder(pileCode, tcpSession, message)
|
||||||
|
.setLimitUpdateResponse(ProtocolProto.LimitUpdateResponse.newBuilder()
|
||||||
|
.setPileCode(pileCode)
|
||||||
|
.setCardNo(cardNo)
|
||||||
|
.setSuccess(updateResult == 0x00)
|
||||||
|
.setErrorMsg(UPDATE_RESULT.getOrDefault(updateResult,UNKNOWN_MSG))
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
// 转发到后端
|
||||||
|
tcpSession.getForwarder().sendMessage(queueMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||||
|
* 微信:mohan_88888
|
||||||
|
* 抖音:程序员三丙
|
||||||
|
* 付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||||
|
*/
|
||||||
|
package sanbing.jcpp.protocol.yunkuaichong.v150.cmd;
|
||||||
|
|
||||||
|
import static sanbing.jcpp.protocol.yunkuaichong.enums.YunKuaiChongDownlinkCmdEnum.OFFLINE_CARD_SYNC_REQUEST;
|
||||||
|
|
||||||
|
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.ProtocolProto;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云快充1.5.0 离线卡数据同步
|
||||||
|
*
|
||||||
|
* @author bawan
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@YunKuaiChongCmd(0x44)
|
||||||
|
public class YunKuaiChongV150OfflineCardSyncRequestDLCmd extends YunKuaiChongDownlinkCmdExe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(TcpSession tcpSession, YunKuaiChongDwonlinkMessage message, ProtocolContext ctx) {
|
||||||
|
log.info("{} 云快充1.5.0 离线卡数据同步", tcpSession);
|
||||||
|
|
||||||
|
if (!message.getMsg().hasOfflineCardSyncRequest()) {
|
||||||
|
log.error("云快充1.5.0 离线卡数据同步消息体为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtocolProto.OfflineCardSyncRequest request = message.getMsg().getOfflineCardSyncRequest();
|
||||||
|
|
||||||
|
if (request.getTotal() > 15) {
|
||||||
|
log.error("云快充1.5.0 离线卡数据同步 下发卡个数最大支持: 15个当前: {}个", request.getTotal());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 初始化 buf
|
||||||
|
ByteBuf msgBody = Unpooled.buffer(bufferInitialCapacity(request));
|
||||||
|
msgBody.writeBytes(encodePileCode(request.getPileCode()));
|
||||||
|
msgBody.writeIntLE(request.getTotal());
|
||||||
|
request.getCardInfoList().forEach(cardInfo -> {
|
||||||
|
msgBody.writeBytes(BCDUtil.toBytes(cardInfo.getLogicCardNo()));
|
||||||
|
msgBody.writeBytes(BCDUtil.toBytes(cardInfo.getCardNo()));
|
||||||
|
});
|
||||||
|
|
||||||
|
super.encodeAndWriteFlush(OFFLINE_CARD_SYNC_REQUEST, msgBody, tcpSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 桩编号 BCD 码 7
|
||||||
|
* 下发卡个数 BIN 码 1 最大 15 个
|
||||||
|
* n卡逻辑卡号 BCD 码 8 离线卡逻辑卡号
|
||||||
|
* ........ ........ ........ ........
|
||||||
|
* n卡物理卡号 BIN 码 8 离线卡物理卡号
|
||||||
|
* @param request request
|
||||||
|
* @return bufferInitialCapacity
|
||||||
|
*/
|
||||||
|
private int bufferInitialCapacity(ProtocolProto.OfflineCardSyncRequest request) {
|
||||||
|
return (8 + 8) * request.getCardInfoCount() + 7 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||||
|
* 微信: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;
|
||||||
|
import sanbing.jcpp.infrastructure.util.codec.BCDUtil;
|
||||||
|
import sanbing.jcpp.proto.gen.ProtocolProto;
|
||||||
|
import sanbing.jcpp.protocol.ProtocolContext;
|
||||||
|
import sanbing.jcpp.protocol.listener.tcp.TcpSession;
|
||||||
|
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkCmdExe;
|
||||||
|
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkMessage;
|
||||||
|
import sanbing.jcpp.protocol.yunkuaichong.annotation.YunKuaiChongCmd;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云快充1.5.0 离线卡数据同步应答
|
||||||
|
*
|
||||||
|
* @author bawan
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@YunKuaiChongCmd(0x43)
|
||||||
|
public class YunKuaiChongV150OfflineCardSyncResponseULCmd extends YunKuaiChongUplinkCmdExe {
|
||||||
|
|
||||||
|
private static final Map<Byte, Map<Byte, String>> FAILURE_REASON;
|
||||||
|
|
||||||
|
|
||||||
|
private static final String SUCCESS = "成功";
|
||||||
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
FAILURE_REASON = Map.of(
|
||||||
|
(byte) 0x00,Map.of((byte)0x01,"卡号格式错误",(byte)0x02,"储存空间不足"),
|
||||||
|
(byte) 0x01,Map.of((byte)0x00,SUCCESS)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@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);
|
||||||
|
|
||||||
|
// 保存结果 0x00-失败 0x01-成功
|
||||||
|
byte saveResult = byteBuf.readByte();
|
||||||
|
byte failureReason = 0x00;
|
||||||
|
|
||||||
|
if (byteBuf.readableBytes() >= 1) {
|
||||||
|
// 失败原因 0x01-卡号格式错误 0x02-储存空间不足
|
||||||
|
failureReason = byteBuf.readByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtocolProto.UplinkQueueMessage queueMessage = uplinkMessageBuilder(pileCode, tcpSession, message)
|
||||||
|
.setOfflineCardSyncResponse(ProtocolProto.OfflineCardSyncResponse.newBuilder()
|
||||||
|
.setPileCode(pileCode)
|
||||||
|
.setSuccess(saveResult == 0x01)
|
||||||
|
.setErrorMsg(errorMsg(saveResult, failureReason))
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
// 转发到后端
|
||||||
|
tcpSession.getForwarder().sendMessage(queueMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String errorMsg(byte saveResult, byte failureReason) {
|
||||||
|
if(saveResult == 0x01) {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
Map<Byte, String> saveResultMap = FAILURE_REASON.get(saveResult);
|
||||||
|
if(null == saveResultMap) {
|
||||||
|
return UNKNOWN_MSG;
|
||||||
|
}
|
||||||
|
return saveResultMap.getOrDefault(failureReason,UNKNOWN_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ public class YunKuaiChongV150OtaResponseULCmd extends YunKuaiChongUplinkCmdExe {
|
|||||||
.setOtaResponse(ProtocolProto.OtaResponse.newBuilder()
|
.setOtaResponse(ProtocolProto.OtaResponse.newBuilder()
|
||||||
.setPileCode(pileCode)
|
.setPileCode(pileCode)
|
||||||
.setSuccess(upgradeStatus == 0x00)
|
.setSuccess(upgradeStatus == 0x00)
|
||||||
.setErrorMsg(UPGRADE_STATUS.get(upgradeStatus))
|
.setErrorMsg(UPGRADE_STATUS.getOrDefault(upgradeStatus,UNKNOWN_MSG))
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
// 转发到后端
|
// 转发到后端
|
||||||
|
|||||||
Reference in New Issue
Block a user