mirror of
https://gitee.com/san-bing/JChargePointProtocol
synced 2026-05-04 01:49:58 +08:00
!43 离线卡数据清除(0x46) 离线卡数据清除应答(0x45)
* merge master * merge master * Merge branch 'master' into Feat_离线卡数据清除、离线卡数据查询 * merge master * Merge branch 'master' into Feat_离线卡数据清除、离线卡数据查询 * 离线卡数据清除(0x46) 离线卡数据清除应答(0x45) * 离线卡数据清除(0x46) 离线卡数据清除应答(0x45) * 离线卡数据清除(0x46) 离线卡数据清除应答(0x45) * 离线卡数据清除(0x46) 离线卡数据清除应答(0x45)
This commit is contained in:
@@ -323,4 +323,33 @@ public class TestController extends BaseController {
|
||||
return ResponseEntity.ok("success");
|
||||
}
|
||||
|
||||
@GetMapping("/api/offlineCardClearRequest")
|
||||
public ResponseEntity<String> offlineCardClearRequest() {
|
||||
|
||||
List<String> cardNoList = Lists.newArrayList("1000000000123456", "1000000000123457", "1000000000123458", "1000000000123459", "1000000000123460");
|
||||
|
||||
pileProtocolService.offlineCardClearRequest(OfflineCardClearRequest.newBuilder()
|
||||
.setPileCode("20231212000010")
|
||||
.setTotal(cardNoList.size())
|
||||
.addAllCardNo(cardNoList)
|
||||
.build());
|
||||
|
||||
return ResponseEntity.ok("success");
|
||||
}
|
||||
|
||||
@GetMapping("/api/offlineCardQueryRequest")
|
||||
public ResponseEntity<String> offlineCardQueryRequest() {
|
||||
|
||||
List<String> cardNoList = Lists.newArrayList("1000000000123456", "1000000000123457", "1000000000123458", "1000000000123459", "1000000000123460");
|
||||
|
||||
|
||||
pileProtocolService.offlineCardQueryRequest(OfflineCardQueryRequest.newBuilder()
|
||||
.setPileCode("20231212000010")
|
||||
.setTotal(cardNoList.size())
|
||||
.addAllCardNo(cardNoList)
|
||||
.build());
|
||||
|
||||
return ResponseEntity.ok("success");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,12 +7,12 @@
|
||||
package sanbing.jcpp.app.service;
|
||||
|
||||
import sanbing.jcpp.infrastructure.queue.Callback;
|
||||
import sanbing.jcpp.proto.gen.DownlinkProto;
|
||||
import sanbing.jcpp.proto.gen.DownlinkProto.OfflineCardBalanceUpdateRequest;
|
||||
import sanbing.jcpp.proto.gen.DownlinkProto.OfflineCardSyncRequest;
|
||||
import sanbing.jcpp.proto.gen.DownlinkProto.OtaRequest;
|
||||
import sanbing.jcpp.proto.gen.DownlinkProto.SetPricingRequest;
|
||||
import sanbing.jcpp.proto.gen.UplinkProto.UplinkQueueMessage;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@@ -184,6 +184,25 @@ public interface PileProtocolService {
|
||||
*/
|
||||
void onTimeSyncResponse(UplinkQueueMessage uplinkQueueMessage, Callback callback);
|
||||
|
||||
/**
|
||||
* 离线卡数据清除
|
||||
*/
|
||||
void offlineCardClearRequest(DownlinkProto.OfflineCardClearRequest request);
|
||||
|
||||
/**
|
||||
* 离线卡数据清除应答
|
||||
*/
|
||||
void onOfflineCardClearResponse(UplinkQueueMessage uplinkQueueMessage, Callback callback);
|
||||
|
||||
/**
|
||||
* 离线卡数据查询
|
||||
*/
|
||||
void offlineCardQueryRequest(DownlinkProto.OfflineCardQueryRequest request);
|
||||
|
||||
/**
|
||||
* 离线卡数据查询应答
|
||||
*/
|
||||
void onOfflineCardQueryResponse(UplinkQueueMessage uplinkQueueMessage, Callback callback);
|
||||
/**
|
||||
* 充电过程BMS需求与充电机输出
|
||||
*/
|
||||
|
||||
@@ -748,6 +748,57 @@ public class DefaultPileProtocolService implements PileProtocolService {
|
||||
callback.onSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offlineCardClearRequest(OfflineCardClearRequest 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_CLEAR_REQUEST.name())
|
||||
.setOfflineCardClearRequest(request);
|
||||
downlinkCallService.sendDownlinkMessage(downlinkRequestMessageBuilder,request.getPileCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOfflineCardClearResponse(UplinkQueueMessage uplinkQueueMessage, Callback callback) {
|
||||
log.info("接收到充电桩离线卡数据清除应答 {}", uplinkQueueMessage);
|
||||
|
||||
// TODO 处理相关业务逻辑
|
||||
|
||||
callback.onSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offlineCardQueryRequest(OfflineCardQueryRequest 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_QUERY_REQUEST.name())
|
||||
.setOfflineCardQueryRequest(request);
|
||||
downlinkCallService.sendDownlinkMessage(downlinkRequestMessageBuilder,request.getPileCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOfflineCardQueryResponse(UplinkQueueMessage uplinkQueueMessage, Callback callback) {
|
||||
log.info("接收到充电桩离线卡数据查询应答 {}", uplinkQueueMessage);
|
||||
|
||||
|
||||
// TODO 处理相关业务逻辑
|
||||
|
||||
callback.onSuccess();
|
||||
}
|
||||
|
||||
private static Period createPeriod(int sn, LocalTime beginTime, LocalTime endTime, PricingModelFlag flag) {
|
||||
Period period = new Period();
|
||||
period.setSn(sn);
|
||||
|
||||
@@ -245,6 +245,14 @@ public class ProtocolUplinkConsumerService extends AbstractConsumerService {
|
||||
|
||||
pileProtocolService.onTimeSyncResponse(uplinkQueueMsg, callback);
|
||||
|
||||
}else if (uplinkQueueMsg.hasOfflineCardClearResponse()) {
|
||||
|
||||
pileProtocolService.onOfflineCardClearResponse(uplinkQueueMsg, callback);
|
||||
|
||||
}else if (uplinkQueueMsg.hasOfflineCardQueryResponse()) {
|
||||
|
||||
pileProtocolService.onOfflineCardQueryResponse(uplinkQueueMsg, callback);
|
||||
|
||||
} else if (uplinkQueueMsg.hasBmsDemandChargerOutputProto()) {
|
||||
|
||||
pileProtocolService.postBmsDemandChargerOutput(uplinkQueueMsg, callback);
|
||||
|
||||
@@ -36,6 +36,8 @@ message DownlinkRequestMessage {
|
||||
OfflineCardSyncRequest offlineCardSyncRequest = 31;
|
||||
TimeSyncRequest timeSyncRequest = 32;
|
||||
StartChargeResponse startChargeResponse = 33;
|
||||
OfflineCardClearRequest offlineCardClearRequest = 34;
|
||||
OfflineCardQueryRequest offlineCardQueryRequest = 35;
|
||||
}
|
||||
|
||||
// 下行响应消息
|
||||
@@ -246,3 +248,15 @@ message TimeSyncRequest {
|
||||
string pileCode = 1;
|
||||
string time = 2;
|
||||
}
|
||||
|
||||
message OfflineCardClearRequest {
|
||||
string pileCode = 1; // 充电桩编码
|
||||
int32 total = 2; // 清除离线卡的个数
|
||||
repeated string cardNo = 3; // 物理卡号集合
|
||||
}
|
||||
|
||||
message OfflineCardQueryRequest {
|
||||
string pileCode = 1; // 充电桩编码
|
||||
int32 total = 2; // 查询离线卡的个数
|
||||
repeated string cardNo = 3; // 物理卡号集合
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ message UplinkQueueMessage {
|
||||
TimeSyncResponse timeSyncResponse = 42;
|
||||
BmsDemandChargerOutputProto bmsDemandChargerOutputProto = 43;
|
||||
StartChargeRequest startChargeRequest = 44;
|
||||
OfflineCardClearResponse offlineCardClearResponse = 45;
|
||||
OfflineCardQueryResponse offlineCardQueryResponse = 46;
|
||||
}
|
||||
|
||||
// 会话关闭事件
|
||||
@@ -339,6 +341,34 @@ message TimeSyncResponse {
|
||||
string time = 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
message OfflineCardClearResponse {
|
||||
string pileCode = 1; // 充电桩编码
|
||||
repeated ClearResult clearResult = 2; // 清除卡号结果集合
|
||||
}
|
||||
|
||||
message ClearResult {
|
||||
string cardNo = 1; // 物理卡号
|
||||
bool success = 2;
|
||||
optional string errorMsg = 3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
message OfflineCardQueryResponse {
|
||||
string pileCode = 1; // 充电桩编码
|
||||
repeated QueryResult queryResult = 2; // 查询卡号结果集合
|
||||
}
|
||||
|
||||
message QueryResult {
|
||||
string cardNo = 1; // 物理卡号
|
||||
bool exist = 2;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// BMS需求充电机输出
|
||||
message BmsDemandChargerOutputProto {
|
||||
string pileCode = 4;
|
||||
|
||||
@@ -15,6 +15,8 @@ import java.util.function.Function;
|
||||
|
||||
public class PropertyUtils {
|
||||
|
||||
private PropertyUtils() {}
|
||||
|
||||
public static Map<String, String> getProps(String properties) {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
if (StringUtils.isNotEmpty(properties)) {
|
||||
|
||||
@@ -41,5 +41,9 @@ public enum DownlinkCmdEnum {
|
||||
|
||||
OFFLINE_CARD_SYNC_REQUEST,
|
||||
|
||||
OFFLINE_CARD_CLEAR_REQUEST,
|
||||
|
||||
OFFLINE_CARD_QUERY_REQUEST,
|
||||
|
||||
START_CHARGE_ACK
|
||||
}
|
||||
@@ -141,3 +141,21 @@
|
||||
|
||||
#### 0x55 对时设置应答
|
||||
`68 12 01 00 00 55 20 23 12 12 00 00 10 E0 2E 0C 0C 15 08 19 AB 37`
|
||||
|
||||
#### 0x46 离线卡数据清除
|
||||
`68 37 03 00 00 46 20 23 12 12 00 00 10 05 00 00 00 10 00 00 00 00 12 34 56 10 00 00 00 00 12 34 57 10 00 00 00 00 12 34 58 10 00 00 00 00 12 34 59 10 00 00 00 00 12 34 60 76 2f`
|
||||
|
||||
#### 0x45 离线卡数据清除应答
|
||||
#### 成功
|
||||
`68 3d 19 00 00 45 20 23 12 12 00 00 10 10 00 00 00 00 12 34 56 01 02 10 00 00 00 00 12 34 57 01 02 10 00 00 00 00 12 34 58 01 02 10 00 00 00 00 12 34 59 01 02 10 00 00 00 00 12 34 60 01 02 67 ed`
|
||||
#### 失败
|
||||
`68 3d 19 00 00 45 20 23 12 12 00 00 10 10 00 00 00 00 12 34 56 00 01 10 00 00 00 00 12 34 57 00 01 10 00 00 00 00 12 34 58 00 01 10 00 00 00 00 12 34 59 00 01 10 00 00 00 00 12 34 60 00 01 70 ec`
|
||||
|
||||
#### 0x48 离线卡数据查询
|
||||
`68 37 02 00 00 48 05 00 00 00 20 23 12 12 00 00 10 10 00 00 00 00 12 34 56 10 00 00 00 00 12 34 57 10 00 00 00 00 12 34 58 10 00 00 00 00 12 34 59 10 00 00 00 00 12 34 60 a9 e1`
|
||||
|
||||
#### 0x47 离线卡数据查询应答
|
||||
#### 成功
|
||||
`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`
|
||||
@@ -49,6 +49,8 @@ public class AbstractYunKuaiChongCmdExe {
|
||||
private static final DecimalFormat PRICING_ID_DECIMAL_FORMAT = new DecimalFormat("0000");
|
||||
|
||||
|
||||
protected static final String SUCCESS = "成功";
|
||||
|
||||
protected static final String UNKNOWN_MSG = "未知的异常";
|
||||
|
||||
|
||||
@@ -82,7 +84,7 @@ public class AbstractYunKuaiChongCmdExe {
|
||||
}
|
||||
|
||||
protected static byte[] encodePileCode(String pileCode) {
|
||||
if (StringUtils.length(pileCode) > 32) {
|
||||
if (StringUtils.length(pileCode) > 14) {
|
||||
throw new IllegalArgumentException("云快充可接受最大桩编号为14位");
|
||||
}
|
||||
|
||||
@@ -113,14 +115,14 @@ public class AbstractYunKuaiChongCmdExe {
|
||||
|
||||
/**
|
||||
* 编码卡号为BCD格式
|
||||
* 云快充协议卡号为6字节(12位BCD码),需要做长度校验和补0操作
|
||||
* 云快充协议卡号为8字节(16位BCD码),需要做长度校验和补0操作
|
||||
*/
|
||||
protected static byte[] encodeCardNo(String cardNo) {
|
||||
if (StringUtils.length(cardNo) > 12) {
|
||||
throw new IllegalArgumentException("云快充可接受最大卡号为12位");
|
||||
if (StringUtils.length(cardNo) > 16) {
|
||||
throw new IllegalArgumentException("云快充可接受最大卡号为16位");
|
||||
}
|
||||
|
||||
String cardNoStr = StringUtils.leftPad(cardNo, 12, '0');
|
||||
String cardNoStr = StringUtils.leftPad(cardNo, 16, '0');
|
||||
|
||||
return BCDUtil.toBytes(cardNoStr);
|
||||
}
|
||||
|
||||
@@ -52,6 +52,10 @@ public class YunKuaiChongDownlinkCmdConverter implements DownlinkCmdConverter {
|
||||
COMMAND_MAP.put(DownlinkCmdEnum.OFFLINE_CARD_BALANCE_UPDATE_REQUEST, 0x42);
|
||||
COMMAND_MAP.put(DownlinkCmdEnum.OFFLINE_CARD_SYNC_REQUEST, 0x44);
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,7 +45,7 @@ public class YunKuaiChongV150OfflineCardBalanceUpdateRequestDLCmd extends YunKua
|
||||
OfflineCardBalanceUpdateRequest request = message.getMsg().getOfflineCardBalanceUpdateRequest();
|
||||
msgBody.writeBytes(encodePileCode(request.getPileCode()));
|
||||
msgBody.writeBytes(encodeGunCode(request.getGunCode()));
|
||||
msgBody.writeBytes(BCDUtil.toBytes(request.getCardNo()));
|
||||
msgBody.writeBytes(encodeCardNo(request.getCardNo()));
|
||||
msgBody.writeIntLE(new BigDecimal(request.getLimitYuan()).movePointRight(2).intValue());
|
||||
|
||||
super.encodeAndWriteFlush(OFFLINE_CARD_BALANCE_UPDATE_REQUEST, msgBody, tcpSession);
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||
* 微信:mohan_88888
|
||||
* 抖音:程序员三丙
|
||||
* 付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||
*/
|
||||
package sanbing.jcpp.protocol.yunkuaichong.v150.cmd;
|
||||
|
||||
import static sanbing.jcpp.protocol.domain.DownlinkCmdEnum.OFFLINE_CARD_CLEAR_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 = 0x46, protocolNames = {V150, V160, V170})
|
||||
public class YunKuaiChongV150OfflineCardClearRequestDLCmd extends YunKuaiChongDownlinkCmdExe {
|
||||
|
||||
@Override
|
||||
public void execute(TcpSession tcpSession, YunKuaiChongDwonlinkMessage message, ProtocolContext ctx) {
|
||||
log.info("{} 云快充1.5.0 离线卡数据清除", tcpSession);
|
||||
|
||||
if (!message.getMsg().hasOfflineCardClearRequest()) {
|
||||
log.error("云快充1.5.0 离线卡数据清除消息体为空");
|
||||
return;
|
||||
}
|
||||
|
||||
DownlinkProto.OfflineCardClearRequest request = message.getMsg().getOfflineCardClearRequest();
|
||||
|
||||
if (request.getTotal()>24 || request.getCardNoCount()>24) {
|
||||
log.error("云快充1.5.0 离线卡数据清除 下发卡个数最大支持: 24个当前: {}个", request.getTotal());
|
||||
return;
|
||||
}
|
||||
// 初始化 buf
|
||||
ByteBuf msgBody = Unpooled.buffer(bufferInitialCapacity(request));
|
||||
msgBody.writeBytes(encodePileCode(request.getPileCode()));
|
||||
msgBody.writeIntLE(request.getTotal());
|
||||
request.getCardNoList().forEach(cardNo -> msgBody.writeBytes(encodeCardNo(cardNo)));
|
||||
|
||||
super.encodeAndWriteFlush(OFFLINE_CARD_CLEAR_REQUEST, msgBody, tcpSession);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 桩编号 BCD 码 7
|
||||
* 下发卡个数 BIN 码 1 最大 15 个
|
||||
* ........ ........ ........ ........
|
||||
* n卡物理卡号 BIN 码 8 离线卡物理卡号
|
||||
* @param request request
|
||||
* @return bufferInitialCapacity
|
||||
*/
|
||||
private int bufferInitialCapacity(DownlinkProto.OfflineCardClearRequest request) {
|
||||
return 7 + 1 + (8 * request.getCardNoCount());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||
* 微信: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 java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
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 = 0x45, protocolNames = {V150, V160, V170})
|
||||
public class YunKuaiChongV150OfflineCardClearResponseULCmd extends YunKuaiChongUplinkCmdExe {
|
||||
|
||||
private static final Map<Byte, Map<Byte, String>> CLEAR_RESULT;
|
||||
|
||||
|
||||
static {
|
||||
CLEAR_RESULT = Map.of(
|
||||
(byte) 0x00,Map.of((byte)0x01,"卡号格式错误"),
|
||||
(byte) 0x01,Map.of((byte)0x02,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);
|
||||
// 清除结果集合
|
||||
List<UplinkProto.ClearResult> clearResultList = Lists.newArrayList();
|
||||
while (byteBuf.readableBytes() >= 10) {
|
||||
byte[] cardNoBytes = new byte[8];
|
||||
// 离线卡物理卡号
|
||||
byteBuf.readBytes(cardNoBytes);
|
||||
String cardNo = BCDUtil.toString(cardNoBytes);
|
||||
// 清除标记 0x00 清除失败 0x01 清除成功
|
||||
byte clearFlag = byteBuf.readByte();
|
||||
// 失败原因 0x01 卡号格式错误 0x02 清除成功
|
||||
byte failureReason = byteBuf.readByte();
|
||||
// clearResult
|
||||
UplinkProto.ClearResult clearResult = UplinkProto.ClearResult.newBuilder()
|
||||
.setCardNo(cardNo)
|
||||
.setSuccess(clearFlag == 0x01)
|
||||
.setErrorMsg(errorMsg(clearFlag,failureReason))
|
||||
.build();
|
||||
// add
|
||||
clearResultList.add(clearResult);
|
||||
}
|
||||
|
||||
UplinkProto.UplinkQueueMessage queueMessage = uplinkMessageBuilder(pileCode, tcpSession, message)
|
||||
.setOfflineCardClearResponse(UplinkProto.OfflineCardClearResponse.newBuilder()
|
||||
.setPileCode(pileCode)
|
||||
.addAllClearResult(clearResultList)
|
||||
.build())
|
||||
.build();
|
||||
// 转发到后端
|
||||
tcpSession.getForwarder().sendMessage(queueMessage);
|
||||
}
|
||||
|
||||
|
||||
private String errorMsg(byte clearResult, byte failureReason) {
|
||||
if(clearResult == 0x01) {
|
||||
return SUCCESS;
|
||||
}
|
||||
Map<Byte, String> clearResultMap = CLEAR_RESULT.get(clearResult);
|
||||
if(null == clearResultMap) {
|
||||
return UNKNOWN_MSG;
|
||||
}
|
||||
return clearResultMap.getOrDefault(failureReason,UNKNOWN_MSG);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||
* 微信:mohan_88888
|
||||
* 抖音:程序员三丙
|
||||
* 付费课程知识星球:https://t.zsxq.com/aKtXo
|
||||
*/
|
||||
package sanbing.jcpp.protocol.yunkuaichong.v150.cmd;
|
||||
|
||||
import static sanbing.jcpp.protocol.domain.DownlinkCmdEnum.OFFLINE_CARD_QUERY_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 = 0x48, protocolNames = {V150, V160, V170})
|
||||
public class YunKuaiChongV150OfflineCardQueryRequestDLCmd extends YunKuaiChongDownlinkCmdExe {
|
||||
|
||||
@Override
|
||||
public void execute(TcpSession tcpSession, YunKuaiChongDwonlinkMessage message, ProtocolContext ctx) {
|
||||
log.info("{} 云快充1.5.0 离线卡数据查询", tcpSession);
|
||||
|
||||
if (!message.getMsg().hasOfflineCardQueryRequest()) {
|
||||
log.error("云快充1.5.0 离线卡数据查询消息体为空");
|
||||
return;
|
||||
}
|
||||
|
||||
DownlinkProto.OfflineCardQueryRequest request = message.getMsg().getOfflineCardQueryRequest();
|
||||
|
||||
if (request.getTotal()>26 || request.getCardNoCount()>26) {
|
||||
log.error("云快充1.5.0 离线卡数据查询 下发卡个数最大支持: 26个当前: {}个", request.getTotal());
|
||||
return;
|
||||
}
|
||||
// 初始化 buf
|
||||
ByteBuf msgBody = Unpooled.buffer(bufferInitialCapacity(request));
|
||||
msgBody.writeIntLE(request.getTotal());
|
||||
msgBody.writeBytes(encodePileCode(request.getPileCode()));
|
||||
request.getCardNoList().forEach(cardNo -> msgBody.writeBytes(encodeCardNo(cardNo)));
|
||||
|
||||
super.encodeAndWriteFlush(OFFLINE_CARD_QUERY_REQUEST, msgBody, tcpSession);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 桩编号 BCD 码 7
|
||||
* 下发卡个数 BIN 码 1 最大 15 个
|
||||
* ........ ........ ........ ........
|
||||
* n卡物理卡号 BIN 码 8 离线卡物理卡号
|
||||
* @param request request
|
||||
* @return bufferInitialCapacity
|
||||
*/
|
||||
private int bufferInitialCapacity(DownlinkProto.OfflineCardQueryRequest request) {
|
||||
return 7 + 1 + ( 8 * request.getCardNoCount());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* 开源代码,仅供学习和交流研究使用,商用请联系三丙
|
||||
* 微信: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 java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
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 = 0x47, protocolNames = {V150, V160, V170})
|
||||
public class YunKuaiChongV150OfflineCardQueryResponseULCmd 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);
|
||||
|
||||
// 清除结果集合
|
||||
List<UplinkProto.QueryResult> queryResultList = Lists.newArrayList();
|
||||
while (byteBuf.readableBytes() >= 9) {
|
||||
byte[] cardNoBytes = new byte[8];
|
||||
// 离线卡物理卡号
|
||||
byteBuf.readBytes(cardNoBytes);
|
||||
String cardNo = BCDUtil.toString(cardNoBytes);
|
||||
// 查询结果 0x00 不存在 0x01 存在
|
||||
byte queryResultByte = byteBuf.readByte();
|
||||
// clearResult
|
||||
UplinkProto.QueryResult queryResult = UplinkProto.QueryResult.newBuilder()
|
||||
.setCardNo(cardNo)
|
||||
.setExist(queryResultByte == 0x01)
|
||||
.build();
|
||||
// add
|
||||
queryResultList.add(queryResult);
|
||||
}
|
||||
|
||||
UplinkProto.UplinkQueueMessage queueMessage = uplinkMessageBuilder(pileCode, tcpSession, message)
|
||||
.setOfflineCardQueryResponse(UplinkProto.OfflineCardQueryResponse.newBuilder()
|
||||
.setPileCode(pileCode)
|
||||
.addAllQueryResult(queryResultList)
|
||||
.build())
|
||||
.build();
|
||||
// 转发到后端
|
||||
tcpSession.getForwarder().sendMessage(queueMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ package sanbing.jcpp.protocol.yunkuaichong.v150.cmd;
|
||||
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.DownlinkProto.OfflineCardSyncRequest;
|
||||
import sanbing.jcpp.protocol.ProtocolContext;
|
||||
import sanbing.jcpp.protocol.annotation.ProtocolCmd;
|
||||
@@ -41,7 +40,7 @@ public class YunKuaiChongV150OfflineCardSyncRequestDLCmd extends YunKuaiChongDow
|
||||
|
||||
OfflineCardSyncRequest request = message.getMsg().getOfflineCardSyncRequest();
|
||||
|
||||
if (request.getTotal() > 15) {
|
||||
if (request.getTotal()>15 || request.getCardInfoCount()>15) {
|
||||
log.error("云快充1.5.0 离线卡数据同步 下发卡个数最大支持: 15个当前: {}个", request.getTotal());
|
||||
return;
|
||||
}
|
||||
@@ -50,8 +49,8 @@ public class YunKuaiChongV150OfflineCardSyncRequestDLCmd extends YunKuaiChongDow
|
||||
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()));
|
||||
msgBody.writeBytes(encodeCardNo(cardInfo.getLogicCardNo()));
|
||||
msgBody.writeBytes(encodeCardNo(cardInfo.getCardNo()));
|
||||
});
|
||||
|
||||
super.encodeAndWriteFlush(OFFLINE_CARD_SYNC_REQUEST, msgBody, tcpSession);
|
||||
|
||||
@@ -35,10 +35,6 @@ public class YunKuaiChongV150OfflineCardSyncResponseULCmd extends YunKuaiChongUp
|
||||
|
||||
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,"储存空间不足"),
|
||||
|
||||
Reference in New Issue
Block a user