mirror of
https://gitee.com/san-bing/JChargePointProtocol
synced 2026-05-04 01:49:58 +08:00
@@ -114,9 +114,41 @@ public class AbstractYunKuaiChongCmdExe {
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码卡号为BCD格式
|
||||
* 云快充协议卡号为8字节(16位BCD码),需要做长度校验和补0操作
|
||||
* 编码逻辑卡号为BCD格式
|
||||
* 云快充协议逻辑卡号为8字节(16位BCD码),需要做长度校验和补0操作
|
||||
*/
|
||||
protected static byte[] encodeLogicalCardNo(String cardNo) {
|
||||
if (StringUtils.length(cardNo) > 16) {
|
||||
throw new IllegalArgumentException("云快充可接受最大逻辑卡号为16位");
|
||||
}
|
||||
|
||||
String cardNoStr = StringUtils.leftPad(cardNo, 16, '0');
|
||||
|
||||
return BCDUtil.toBytes(cardNoStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码物理卡号为8字节long值
|
||||
* 根据云快充协议文档,物理卡号为8字节BIN码,直接使用long值
|
||||
*/
|
||||
protected static long encodePhysicalCardNo(String cardNo) {
|
||||
if (StringUtils.isEmpty(cardNo)) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
try {
|
||||
return Long.parseLong(cardNo);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("物理卡号必须是数字: " + cardNo, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码卡号为BCD格式(保持向后兼容)
|
||||
* 云快充协议卡号为8字节(16位BCD码),需要做长度校验和补0操作
|
||||
* @deprecated 请使用 encodeLogicalCardNo 或 encodePhysicalCardNo 方法
|
||||
*/
|
||||
@Deprecated
|
||||
protected static byte[] encodeCardNo(String cardNo) {
|
||||
if (StringUtils.length(cardNo) > 16) {
|
||||
throw new IllegalArgumentException("云快充可接受最大卡号为16位");
|
||||
|
||||
@@ -44,7 +44,7 @@ public class YunKuaiChongV150OfflineCardBalanceUpdateRequestDLCmd extends YunKua
|
||||
OfflineCardBalanceUpdateRequest request = message.getMsg().getOfflineCardBalanceUpdateRequest();
|
||||
msgBody.writeBytes(encodePileCode(request.getPileCode()));
|
||||
msgBody.writeBytes(encodeGunCode(request.getGunNo()));
|
||||
msgBody.writeBytes(encodeCardNo(request.getCardNo()));
|
||||
msgBody.writeLongLE(encodePhysicalCardNo(request.getCardNo()));
|
||||
msgBody.writeIntLE(new BigDecimal(request.getLimitYuan()).movePointRight(2).intValue());
|
||||
|
||||
super.encodeAndWriteFlush(OFFLINE_CARD_BALANCE_UPDATE_REQUEST, msgBody, tcpSession);
|
||||
|
||||
@@ -55,12 +55,11 @@ public class YunKuaiChongV150OfflineCardBalanceUpdateResponseULCmd extends YunKu
|
||||
byteBuf.readBytes(pileCodeBytes);
|
||||
String pileCode = BCDUtil.toString(pileCodeBytes);
|
||||
|
||||
// 物理卡号
|
||||
// 物理卡号 8字节long值(小端序)
|
||||
String cardNo = CharSequenceUtil.EMPTY;
|
||||
if(byteBuf.readableBytes() >= 8) {
|
||||
byte[] cardNoBytes = new byte[8];
|
||||
byteBuf.readBytes(cardNoBytes);
|
||||
cardNo = BCDUtil.toString(cardNoBytes);
|
||||
long physicalCardNoLong = byteBuf.readLongLE();
|
||||
cardNo = String.valueOf(physicalCardNoLong);
|
||||
}
|
||||
|
||||
// 修改结果 0x00-修改成功 0x01-设备编号错误 0x02-卡号错误
|
||||
|
||||
@@ -6,11 +6,6 @@
|
||||
*/
|
||||
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;
|
||||
@@ -21,6 +16,9 @@ import sanbing.jcpp.protocol.listener.tcp.TcpSession;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongDownlinkCmdExe;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongDwonlinkMessage;
|
||||
|
||||
import static sanbing.jcpp.protocol.domain.DownlinkCmdEnum.OFFLINE_CARD_CLEAR_REQUEST;
|
||||
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.*;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -51,7 +49,7 @@ public class YunKuaiChongV150OfflineCardClearRequestDLCmd extends YunKuaiChongDo
|
||||
ByteBuf msgBody = Unpooled.buffer(bufferInitialCapacity(request));
|
||||
msgBody.writeBytes(encodePileCode(request.getPileCode()));
|
||||
msgBody.writeIntLE(request.getTotal());
|
||||
request.getCardNoList().forEach(cardNo -> msgBody.writeBytes(encodeCardNo(cardNo)));
|
||||
request.getCardNoList().forEach(cardNo -> msgBody.writeLongLE(encodePhysicalCardNo(cardNo)));
|
||||
|
||||
super.encodeAndWriteFlush(OFFLINE_CARD_CLEAR_REQUEST, msgBody, tcpSession);
|
||||
}
|
||||
|
||||
@@ -7,15 +7,7 @@
|
||||
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;
|
||||
@@ -27,6 +19,11 @@ import sanbing.jcpp.protocol.listener.tcp.TcpSession;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkCmdExe;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkMessage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.*;
|
||||
|
||||
/**
|
||||
* 云快充1.5.0 离线卡数据清除应答
|
||||
*
|
||||
@@ -59,10 +56,9 @@ public class YunKuaiChongV150OfflineCardClearResponseULCmd extends YunKuaiChongU
|
||||
// 清除结果集合
|
||||
List<UplinkProto.ClearResult> clearResultList = Lists.newArrayList();
|
||||
while (byteBuf.readableBytes() >= 10) {
|
||||
byte[] cardNoBytes = new byte[8];
|
||||
// 离线卡物理卡号
|
||||
byteBuf.readBytes(cardNoBytes);
|
||||
String cardNo = BCDUtil.toString(cardNoBytes);
|
||||
// 离线卡物理卡号 8字节long值(小端序)
|
||||
long physicalCardNoLong = byteBuf.readLongLE();
|
||||
String cardNo = String.valueOf(physicalCardNoLong);
|
||||
// 清除标记 0x00 清除失败 0x01 清除成功
|
||||
byte clearFlag = byteBuf.readByte();
|
||||
// 失败原因 0x01 卡号格式错误 0x02 清除成功
|
||||
|
||||
@@ -6,11 +6,6 @@
|
||||
*/
|
||||
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;
|
||||
@@ -21,6 +16,9 @@ import sanbing.jcpp.protocol.listener.tcp.TcpSession;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongDownlinkCmdExe;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongDwonlinkMessage;
|
||||
|
||||
import static sanbing.jcpp.protocol.domain.DownlinkCmdEnum.OFFLINE_CARD_QUERY_REQUEST;
|
||||
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.*;
|
||||
|
||||
|
||||
/**
|
||||
* 云快充1.5.0 离线卡数据查询
|
||||
@@ -50,7 +48,7 @@ public class YunKuaiChongV150OfflineCardQueryRequestDLCmd extends YunKuaiChongDo
|
||||
ByteBuf msgBody = Unpooled.buffer(bufferInitialCapacity(request));
|
||||
msgBody.writeIntLE(request.getTotal());
|
||||
msgBody.writeBytes(encodePileCode(request.getPileCode()));
|
||||
request.getCardNoList().forEach(cardNo -> msgBody.writeBytes(encodeCardNo(cardNo)));
|
||||
request.getCardNoList().forEach(cardNo -> msgBody.writeLongLE(encodePhysicalCardNo(cardNo)));
|
||||
|
||||
super.encodeAndWriteFlush(OFFLINE_CARD_QUERY_REQUEST, msgBody, tcpSession);
|
||||
}
|
||||
|
||||
@@ -7,14 +7,7 @@
|
||||
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;
|
||||
@@ -26,6 +19,10 @@ import sanbing.jcpp.protocol.listener.tcp.TcpSession;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkCmdExe;
|
||||
import sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongUplinkMessage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static sanbing.jcpp.protocol.yunkuaichong.YunKuaiChongProtocolConstants.ProtocolNames.*;
|
||||
|
||||
|
||||
/**
|
||||
* 云快充1.5.0 离线卡数据查询应答
|
||||
@@ -50,10 +47,9 @@ public class YunKuaiChongV150OfflineCardQueryResponseULCmd extends YunKuaiChongU
|
||||
// 清除结果集合
|
||||
List<UplinkProto.QueryResult> queryResultList = Lists.newArrayList();
|
||||
while (byteBuf.readableBytes() >= 9) {
|
||||
byte[] cardNoBytes = new byte[8];
|
||||
// 离线卡物理卡号
|
||||
byteBuf.readBytes(cardNoBytes);
|
||||
String cardNo = BCDUtil.toString(cardNoBytes);
|
||||
// 离线卡物理卡号 8字节long值(小端序)
|
||||
long physicalCardNoLong = byteBuf.readLongLE();
|
||||
String cardNo = String.valueOf(physicalCardNoLong);
|
||||
// 查询结果 0x00 不存在 0x01 存在
|
||||
byte queryResultByte = byteBuf.readByte();
|
||||
// clearResult
|
||||
|
||||
@@ -49,8 +49,8 @@ public class YunKuaiChongV150OfflineCardSyncRequestDLCmd extends YunKuaiChongDow
|
||||
msgBody.writeBytes(encodePileCode(request.getPileCode()));
|
||||
msgBody.writeIntLE(request.getTotal());
|
||||
request.getCardInfoList().forEach(cardInfo -> {
|
||||
msgBody.writeBytes(encodeCardNo(cardInfo.getLogicCardNo()));
|
||||
msgBody.writeBytes(encodeCardNo(cardInfo.getCardNo()));
|
||||
msgBody.writeBytes(encodeLogicalCardNo(cardInfo.getLogicCardNo()));
|
||||
msgBody.writeLongLE(encodePhysicalCardNo(cardInfo.getCardNo()));
|
||||
});
|
||||
|
||||
super.encodeAndWriteFlush(OFFLINE_CARD_SYNC_REQUEST, msgBody, tcpSession);
|
||||
|
||||
@@ -58,9 +58,9 @@ public class YunKuaiChongV150RemoteStartDLCmd extends YunKuaiChongDownlinkCmdExe
|
||||
// 枪号
|
||||
msgBody.writeBytes(encodeGunCode(gunCode));
|
||||
// 逻辑卡号 BCD码
|
||||
msgBody.writeBytes(encodeCardNo(logicalCardNo));
|
||||
// 物理卡号
|
||||
msgBody.writeBytes(encodeCardNo(physicalCardNo));
|
||||
msgBody.writeBytes(encodeLogicalCardNo(logicalCardNo));
|
||||
// 物理卡号 8字节long值(小端序)
|
||||
msgBody.writeLongLE(encodePhysicalCardNo(physicalCardNo));
|
||||
// 账户余额
|
||||
msgBody.writeIntLE(new BigDecimal(limitYuan).multiply(new BigDecimal("100")).intValue());
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ public class YunKuaiChongV150StartChargeAckDLCmd extends YunKuaiChongDownlinkCmd
|
||||
// 枪号
|
||||
msgBody.writeBytes(encodeGunCode(gunCode));
|
||||
// 逻辑卡号
|
||||
msgBody.writeBytes(encodeCardNo(logicalCardNo));
|
||||
msgBody.writeBytes(encodeLogicalCardNo(logicalCardNo));
|
||||
// 账户余额
|
||||
msgBody.writeIntLE(new BigDecimal(limitYuan).multiply(new BigDecimal("100")).intValue());
|
||||
// 鉴权成功标志
|
||||
|
||||
@@ -65,10 +65,9 @@ public class YunKuaiChongV150StartChargeULCmd extends YunKuaiChongUplinkCmdExe {
|
||||
int needPasswordCode = byteBuf.readUnsignedByte();
|
||||
boolean needPassword = YunKuaiChongPasswordRequiredEnum.isPasswordRequired(needPasswordCode);
|
||||
|
||||
// 物理卡号
|
||||
byte[] cardNoBytes = new byte[8];
|
||||
byteBuf.readBytes(cardNoBytes);
|
||||
String cardNo = BCDUtil.toString(cardNoBytes);
|
||||
// 物理卡号 8字节long值(小端序)
|
||||
long physicalCardNoLong = byteBuf.readLongLE();
|
||||
String cardNo = String.valueOf(physicalCardNoLong);
|
||||
|
||||
// 密码
|
||||
byte[] passwordBytes = new byte[16];
|
||||
|
||||
@@ -150,10 +150,9 @@ public class YunKuaiChongV150TransactionRecordULCmd extends YunKuaiChongUplinkCm
|
||||
byte stopReasonByte = byteBuf.readByte();
|
||||
String stopReason = mapStopReason(stopReasonByte);
|
||||
|
||||
//31 物理卡号
|
||||
byte[] cardNoBytes = new byte[8];
|
||||
byteBuf.readBytes(cardNoBytes);
|
||||
String cardNo = BCDUtil.toString(cardNoBytes);
|
||||
//31 物理卡号 8字节long值(小端序)
|
||||
long physicalCardNoLong = byteBuf.readLongLE();
|
||||
String cardNo = String.valueOf(physicalCardNoLong);
|
||||
additionalInfo.put("物理卡号", cardNo);
|
||||
|
||||
// 构建峰谷电量明细
|
||||
|
||||
@@ -65,9 +65,9 @@ public class YunKuaiChongV160RemoteParallelStartDLCmd extends YunKuaiChongDownli
|
||||
// 枪号
|
||||
msgBody.writeBytes(encodeGunCode(gunCode));
|
||||
// 逻辑卡号 BCD码
|
||||
msgBody.writeBytes(encodeCardNo(logicalCardNo));
|
||||
// 物理卡号
|
||||
msgBody.writeBytes(encodeCardNo(physicalCardNo));
|
||||
msgBody.writeBytes(encodeLogicalCardNo(logicalCardNo));
|
||||
// 物理卡号 8字节long值(小端序)
|
||||
msgBody.writeLongLE(encodePhysicalCardNo(physicalCardNo));
|
||||
// 账户余额
|
||||
msgBody.writeIntLE(new BigDecimal(limitYuan).intValue());
|
||||
// 并充序号
|
||||
|
||||
@@ -174,10 +174,9 @@ public class YunKuaiChongV170TransactionRecordULCmd extends YunKuaiChongUplinkCm
|
||||
byte stopReasonByte = byteBuf.readByte();
|
||||
String stopReason = mapStopReason(stopReasonByte);
|
||||
|
||||
// 35. 物理卡号
|
||||
byte[] cardNoBytes = new byte[8];
|
||||
byteBuf.readBytes(cardNoBytes);
|
||||
String cardNo = BCDUtil.toString(cardNoBytes);
|
||||
// 35. 物理卡号 8字节long值(小端序)
|
||||
long physicalCardNoLong = byteBuf.readLongLE();
|
||||
String cardNo = String.valueOf(physicalCardNoLong);
|
||||
additionalInfo.put("物理卡号", cardNo);
|
||||
|
||||
// 构建峰谷电量明细
|
||||
|
||||
Reference in New Issue
Block a user