From 88ca6762643ea942e0a5c9694819a999e5410b60 Mon Sep 17 00:00:00 2001 From: Guoqs <123@jsowell.com> Date: Tue, 16 Dec 2025 11:41:40 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E6=9E=90=E7=94=B5=E8=A1=A8=E8=B5=B7?= =?UTF-8?q?=E6=AD=A2=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/jsowell/common/util/YKCUtils.java | 38 ++ .../TransactionRecordsRequestHandler.java | 499 +++++++++--------- 2 files changed, 287 insertions(+), 250 deletions(-) diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/YKCUtils.java b/jsowell-common/src/main/java/com/jsowell/common/util/YKCUtils.java index 5a7ec7f6d..1f314bf4b 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/util/YKCUtils.java +++ b/jsowell-common/src/main/java/com/jsowell/common/util/YKCUtils.java @@ -19,6 +19,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import java.math.BigDecimal; +import java.math.RoundingMode; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; @@ -274,6 +275,43 @@ public class YKCUtils { return divide.toString(); } + /** + * 减去倍数 + * @param value + * @param magnification + * @param scale + * @return + */ + public static BigDecimal reduceMagnification(long value, int magnification, int scale) { + return new BigDecimal(value).divide(new BigDecimal(magnification), scale, RoundingMode.HALF_UP); + } + + /** + * 读取5字节小端字节序的数字 + * @param bytes + * @return + */ + public static long readLongLE5Byte(byte[] bytes) { + // 确保字节数组的长度至少为 5 + if (bytes.length < 5) { + throw new IllegalArgumentException("字节数组长度必须至少为5字节"); + } + + // 使用小端字节序读取 5 字节数字 + int byte1 = bytes[0] & 0xFF; + int byte2 = bytes[1] & 0xFF; + int byte3 = bytes[2] & 0xFF; + int byte4 = bytes[3] & 0xFF; + int byte5 = bytes[4] & 0xFF; + + // 将读取的字节合并成一个 long 值 + return ((long) byte1) | + ((long) byte2 << 8) | + ((long) byte3 << 16) | + ((long) byte4 << 24) | + ((long) byte5 << 32); + } + /** * 获取价格byte数组 * 价格转换为byte数组 diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/TransactionRecordsRequestHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/TransactionRecordsRequestHandler.java index fee486785..0a7a3ce8c 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/TransactionRecordsRequestHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/TransactionRecordsRequestHandler.java @@ -28,7 +28,6 @@ import com.jsowell.pile.service.programlogic.AbstractProgramLogic; import com.jsowell.pile.service.programlogic.ProgramLogicFactory; import com.jsowell.thirdparty.common.CommonService; import com.jsowell.thirdparty.platform.service.impl.BatteryChargeReportService; -import com.jsowell.thirdparty.platform.service.impl.ChargeAlgorithmService; import io.netty.channel.ChannelHandlerContext; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.rabbit.core.RabbitTemplate; @@ -97,253 +96,253 @@ public class TransactionRecordsRequestHandler extends AbstractYkcHandler { - // public static void main(String[] args) { - // // BigDecimal totalElectricity = new BigDecimal("23.73"); - // // if (totalElectricity.compareTo(BigDecimal.TEN) > 0) { - // // // 充电度数大于10度 - // // System.out.println("123"); - // // } - // - // - // // 获取消息体 - // // String msg = "000000000000000000000000000000008823000000030601a08c2e0d0404170000380d0404170000000000000000000000000000000000000000000000000000000000000000400d0300ee250000ee250000c84b000000000000000000000000000000000000e0bb040000cee1040000ee250000ee250000c84b00000000000000000000000000000000000000010000380d04041745a511101970000000"; - // // byte[] msgBody = BytesUtil.str2Bcd(msg); - // // - // // int startIndex = 0; - // // int length = 16; - // // - // // // 交易流水号 - // // byte[] orderCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String transactionCode = BytesUtil.bcd2Str(orderCodeByteArr); - // // - // // // 桩编码 - // // startIndex += length; - // // length = 7; - // // byte[] pileSnByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String pileSn = BytesUtil.bcd2Str(pileSnByteArr); - // // - // // // 枪号 - // // startIndex += length; - // // length = 1; - // // byte[] connectorCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String connectorCode = BytesUtil.bcd2Str(connectorCodeByteArr); - // // - // // - // // // 开始时间 CP56Time2a 格式 - // // startIndex += length; - // // length = 7; - // // byte[] startTimeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // // String binary = BytesUtil.binary(startTimeByteArr, 16); - // // Date startDate = Cp56Time2aUtil.byte2Hdate(startTimeByteArr); - // // String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startDate); - // // - // // - // // // 结束时间 CP56Time2a 格式 - // // startIndex += length; - // // byte[] endTimeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // Date endDate = Cp56Time2aUtil.byte2Hdate(endTimeByteArr); - // // String endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endDate); - // // - // // // 尖单价 精确到小数点后五位(尖电费+尖服务费,见费率帧) - // // startIndex += length; - // // length = 4; - // // byte[] sharpPriceByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String sharpPrice = YKCUtils.convertDecimalPoint(sharpPriceByteArr, 5); - // // - // // // 尖电量 精确到小数点后四位 - // // startIndex += length; - // // length = 4; - // // byte[] sharpUsedElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String sharpUsedElectricity = YKCUtils.convertDecimalPoint(sharpUsedElectricityByteArr, 4); - // // - // // // 计损尖电量 - // // startIndex += length; - // // byte[] sharpPlanLossElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String sharpPlanLossElectricity = YKCUtils.convertDecimalPoint(sharpPlanLossElectricityByteArr, 4); - // // - // // // 尖金额 - // // startIndex += length; - // // byte[] sharpAmountByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String sharpAmount = YKCUtils.convertDecimalPoint(sharpAmountByteArr, 4); - // // - // // // 峰单价 精确到小数点后五位(峰电费+峰服务费) - // // startIndex += length; - // // byte[] peakPriceByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String peakPrice = YKCUtils.convertDecimalPoint(peakPriceByteArr, 5); - // // - // // // 峰电量 - // // startIndex += length; - // // byte[] peakUsedElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String peakUsedElectricity = YKCUtils.convertDecimalPoint(peakUsedElectricityByteArr, 4); - // // - // // // 计损峰电量 - // // startIndex += length; - // // byte[] peakPlanLossElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String peakPlanLossElectricity = YKCUtils.convertDecimalPoint(peakPlanLossElectricityByteArr, 4); - // // - // // // 峰金额 - // // startIndex += length; - // // byte[] peakAmountByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String peakAmount = YKCUtils.convertDecimalPoint(peakAmountByteArr, 4); - // // - // // // 平单价 精确到小数点后五位(平电费+平服务费) - // // startIndex += length; - // // byte[] flatPriceByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String flatPrice = YKCUtils.convertDecimalPoint(flatPriceByteArr, 5); - // // - // // // 平电量 - // // startIndex += length; - // // byte[] flatUsedElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String flatUsedElectricity = YKCUtils.convertDecimalPoint(flatUsedElectricityByteArr, 4); - // // - // // // 计损平电量 - // // startIndex += length; - // // byte[] flatPlanLossElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String flatPlanLossElectricity = YKCUtils.convertDecimalPoint(flatPlanLossElectricityByteArr, 4); - // // - // // // 平金额 - // // startIndex += length; - // // byte[] flatAmountByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String flatAmount = YKCUtils.convertDecimalPoint(flatAmountByteArr, 4); - // // - // // // 谷单价 精确到小数点后五位(谷电费+谷 服务费) - // // startIndex += length; - // // byte[] valleyPriceByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String valleyPrice = YKCUtils.convertDecimalPoint(valleyPriceByteArr, 5); - // // - // // // 谷电量 - // // startIndex += length; - // // byte[] valleyUsedElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String valleyUsedElectricity = YKCUtils.convertDecimalPoint(valleyUsedElectricityByteArr, 4); - // // - // // // 计损谷电量 - // // startIndex += length; - // // byte[] valleyPlanLossElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String valleyPlanLossElectricity = YKCUtils.convertDecimalPoint(valleyPlanLossElectricityByteArr, 4); - // // - // // // 谷金额 - // // startIndex += length; - // // byte[] valleyAmountByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String valleyAmount = YKCUtils.convertDecimalPoint(valleyAmountByteArr, 4); - // // - // // // 电表总起值 - // // startIndex += length; - // // length = 5; - // // byte[] ammeterTotalStartByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String ammeterTotalStart = YKCUtils.convertDecimalPoint(ammeterTotalStartByteArr, 4); - // // - // // // 电表总止值 - // // startIndex += length; - // // byte[] ammeterTotalEndByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String ammeterTotalEnd = YKCUtils.convertDecimalPoint(ammeterTotalEndByteArr, 4); - // // - // // // 总电量 - // // startIndex += length; - // // length = 4; - // // byte[] totalElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // // String totalElectricity = YKCUtils.convertDecimalPoint(totalElectricityByteArr, 4); - // // - // // // 计损总电量 - // // startIndex += length; - // // byte[] planLossTotalElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String planLossTotalElectricity = YKCUtils.convertDecimalPoint(planLossTotalElectricityByteArr, 4); - // // - // // // 消费金额 精确到小数点后四位,包含电费、 服务费 - // // startIndex += length; - // // byte[] consumptionAmountByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String consumptionAmount = YKCUtils.convertDecimalPoint(consumptionAmountByteArr, 4); - // // - // // // VIN 码 VIN 码,此处 VIN 码和充电时 VIN 码不同, 正序直接上传, 无需补 0 和反序 - // // startIndex += length; - // // length = 17; - // // byte[] vinCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String vinCode = BytesUtil.ascii2Str(vinCodeByteArr); - // // - // // /** - // // * 交易标识 - // // * 0x01: app 启动 - // // * 0x02:卡启动 - // // * 0x04:离线卡启动 - // // * 0x05: vin 码启动充电 - // // */ - // // startIndex += length; - // // length = 1; - // // byte[] transactionIdentifierByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String transactionIdentifier = BytesUtil.bcd2Str(transactionIdentifierByteArr); - // // - // // // 交易时间 CP56Time2a 格式 - // // startIndex += length; - // // length = 7; - // // byte[] transactionTimeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // Date transactionDate = Cp56Time2aUtil.byte2Hdate(transactionTimeByteArr); - // // String transactionTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, transactionDate); - // // - // // // 停止原因 - // // startIndex += length; - // // length = 1; - // // byte[] stopReasonByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // String stopReason = BytesUtil.bin2HexStr(stopReasonByteArr); - // // int i = Integer.parseInt(stopReason, 16); - // // String stopReasonMsg = YKCChargingStopReasonEnum.getMsgByCode(i); - // - // - // // 物理卡号 不足 8 位补 0 - // // startIndex += length; - // // length = 8; - // // byte[] cardNumByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - // // // byte[] logicCardNum = BytesUtil.checkLengthAndBehindAppendZero(cardNumByteArr, 16); - // // String logicCard = BytesUtil.binary(cardNumByteArr, 16); - // // log.info("桩号:{}, 发送交易记录物理卡号:{}", pileSn, logicCard); - // // - // // log.info("[===交易记录===]交易流水号:{}, 桩编号:{}, 枪号:{}, 开始时间:{}, 结束时间:{}, 尖单价:{}, 尖电量:{}, 计损尖电量:{}, 尖金额:{}, " + - // // "峰单价:{}, 峰电量:{}, 计损峰电量:{}, 峰金额:{}, 平单价:{}, 平电量:{}, 计损平电量:{}, 平金额:{}, " + - // // "谷单价:{}, 谷电量:{}, 计损谷电量:{}, 谷金额:{}, 电表总起值:{}, 电表总止值:{}, 总电量:{}, 计损总电量:{}, 消费金额:{}, " + - // // "电动汽车唯一标识:{}, 交易标识:{}, 交易日期、时间:{}, 停止原因码:{}, 停止原因描述:{}, 物理卡号:{}", - // // transactionCode, pileSn, connectorCode, startTime, endTime, sharpPrice, sharpUsedElectricity, sharpPlanLossElectricity, sharpAmount, - // // peakPrice, peakUsedElectricity, peakPlanLossElectricity, peakAmount, flatPrice, flatUsedElectricity, flatPlanLossElectricity, flatAmount, - // // valleyPrice, valleyUsedElectricity, valleyPlanLossElectricity, valleyAmount, ammeterTotalStart, ammeterTotalEnd, totalElectricity, planLossTotalElectricity, - // // consumptionAmount, vinCode, transactionIdentifier, transactionTime, stopReason, stopReasonMsg, logicCard); - // // - // // // 交易记录封装到对象里 - // // TransactionRecordsData data = TransactionRecordsData.builder() - // // // .orderCode(transactionCode) - // // .transactionCode(transactionCode) - // // .pileSn(pileSn) - // // .connectorCode(connectorCode) - // // .startTime(startTime) - // // .endTime(endTime) - // // .sharpPrice(sharpPrice) - // // .sharpUsedElectricity(sharpUsedElectricity) - // // .sharpPlanLossElectricity(sharpPlanLossElectricity) - // // .sharpAmount(sharpAmount) - // // .peakPrice(peakPrice) - // // .peakUsedElectricity(peakUsedElectricity) - // // .peakPlanLossElectricity(peakPlanLossElectricity) - // // .peakAmount(peakAmount) - // // .flatPrice(flatPrice) - // // .flatUsedElectricity(flatUsedElectricity) - // // .flatPlanLossElectricity(flatPlanLossElectricity) - // // .flatAmount(flatAmount) - // // .valleyPrice(valleyPrice) - // // .valleyUsedElectricity(valleyUsedElectricity) - // // .valleyPlanLossElectricity(valleyPlanLossElectricity) - // // .valleyAmount(valleyAmount) - // // .ammeterTotalStart(ammeterTotalStart) - // // .ammeterTotalEnd(ammeterTotalEnd) - // // // .totalElectricity(totalElectricity) - // // .planLossTotalElectricity(planLossTotalElectricity) - // // .consumptionAmount(consumptionAmount) - // // .vinCode(vinCode) - // // .transactionIdentifier(transactionIdentifier) - // // .transactionTime(transactionTime) - // // .stopReasonMsg(stopReasonMsg) - // // .logicCard(logicCard) - // // .build(); - // // - // // boolean flag = !StringUtils.equals("0000000000000000", "a511101970000000"); - // // System.out.println(flag); - // - // } + public static void main(String[] args) { + // 获取消息体 + String msg = "882400000067090125110515234024428824000000670901a00f170f050b199d640b11050b19a0860100000000000000000000000000a086010080b605000000000080b60500a086010080cf32000000000072ef0400a0860100000000000000000000000000800944e100806060e1000086380000000000008638004c4331484d594246315230303130303235059d640b11050b194500000000000000006877"; + byte[] msgBody = BytesUtil.str2Bcd(msg); + + int startIndex = 0; + int length = 16; + + // 交易流水号 + byte[] transactionCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String transactionCode = BytesUtil.bcd2Str(transactionCodeByteArr); + + // 桩编码 + startIndex += length; + length = 7; + byte[] pileSnByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String pileSn = BytesUtil.bcd2Str(pileSnByteArr); + + // 枪号 + startIndex += length; + length = 1; + byte[] connectorCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String connectorCode = BytesUtil.bcd2Str(connectorCodeByteArr); + + + // 开始时间 CP56Time2a 格式 + startIndex += length; + length = 7; + byte[] startTimeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + // String binary = BytesUtil.binary(startTimeByteArr, 16); + Date startDate = Cp56Time2aUtil.byte2Hdate(startTimeByteArr); + String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startDate); + + + // 结束时间 CP56Time2a 格式 + startIndex += length; + byte[] endTimeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + Date endDate = Cp56Time2aUtil.byte2Hdate(endTimeByteArr); + String endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endDate); + + // 尖单价 精确到小数点后五位(尖电费+尖服务费,见费率帧) + startIndex += length; + length = 4; + byte[] sharpPriceByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String sharpPrice = YKCUtils.convertDecimalPoint(sharpPriceByteArr, 5); + + // 尖电量 精确到小数点后四位 + startIndex += length; + length = 4; + byte[] sharpUsedElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String sharpUsedElectricity = YKCUtils.convertDecimalPoint(sharpUsedElectricityByteArr, 4); + + // 计损尖电量 + startIndex += length; + byte[] sharpPlanLossElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String sharpPlanLossElectricity = YKCUtils.convertDecimalPoint(sharpPlanLossElectricityByteArr, 4); + + // 尖金额 + startIndex += length; + byte[] sharpAmountByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String sharpAmount = YKCUtils.convertDecimalPoint(sharpAmountByteArr, 4); + + // 峰单价 精确到小数点后五位(峰电费+峰服务费) + startIndex += length; + byte[] peakPriceByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String peakPrice = YKCUtils.convertDecimalPoint(peakPriceByteArr, 5); + + // 峰电量 + startIndex += length; + byte[] peakUsedElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String peakUsedElectricity = YKCUtils.convertDecimalPoint(peakUsedElectricityByteArr, 4); + + // 计损峰电量 + startIndex += length; + byte[] peakPlanLossElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String peakPlanLossElectricity = YKCUtils.convertDecimalPoint(peakPlanLossElectricityByteArr, 4); + + // 峰金额 + startIndex += length; + byte[] peakAmountByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String peakAmount = YKCUtils.convertDecimalPoint(peakAmountByteArr, 4); + + // 平单价 精确到小数点后五位(平电费+平服务费) + startIndex += length; + byte[] flatPriceByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String flatPrice = YKCUtils.convertDecimalPoint(flatPriceByteArr, 5); + + // 平电量 + startIndex += length; + byte[] flatUsedElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String flatUsedElectricity = YKCUtils.convertDecimalPoint(flatUsedElectricityByteArr, 4); + + // 计损平电量 + startIndex += length; + byte[] flatPlanLossElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String flatPlanLossElectricity = YKCUtils.convertDecimalPoint(flatPlanLossElectricityByteArr, 4); + + // 平金额 + startIndex += length; + byte[] flatAmountByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String flatAmount = YKCUtils.convertDecimalPoint(flatAmountByteArr, 4); + + // 谷单价 精确到小数点后五位(谷电费+谷 服务费) + startIndex += length; + byte[] valleyPriceByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String valleyPrice = YKCUtils.convertDecimalPoint(valleyPriceByteArr, 5); + + // 谷电量 + startIndex += length; + byte[] valleyUsedElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String valleyUsedElectricity = YKCUtils.convertDecimalPoint(valleyUsedElectricityByteArr, 4); + + // 计损谷电量 + startIndex += length; + byte[] valleyPlanLossElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String valleyPlanLossElectricity = YKCUtils.convertDecimalPoint(valleyPlanLossElectricityByteArr, 4); + + // 谷金额 + startIndex += length; + byte[] valleyAmountByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String valleyAmount = YKCUtils.convertDecimalPoint(valleyAmountByteArr, 4); + + // 电表总起值 + startIndex += length; + length = 5; + byte[] ammeterTotalStartByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + // 打印出来,格式为16进制 + // log.info("电表总起值:{}", BytesUtil.binary(ammeterTotalStartByteArr, 16)); + log.info("电表总起值:{}", YKCUtils.readLongLE5Byte(ammeterTotalStartByteArr)); + // String ammeterTotalStart = YKCUtils.convertDecimalPoint(ammeterTotalStartByteArr, 4); + String ammeterTotalStart = YKCUtils.reduceMagnification(YKCUtils.readLongLE5Byte(ammeterTotalStartByteArr), 10000, 4).toString(); + + // 电表总止值 + startIndex += length; + byte[] ammeterTotalEndByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + // String ammeterTotalEnd = YKCUtils.convertDecimalPoint(ammeterTotalEndByteArr, 4); + String ammeterTotalEnd = YKCUtils.reduceMagnification(YKCUtils.readLongLE5Byte(ammeterTotalEndByteArr), 10000, 4).toString(); + + // 总电量 + startIndex += length; + length = 4; + byte[] totalElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String totalElectricity = YKCUtils.convertDecimalPoint(totalElectricityByteArr, 4); + + // 计损总电量 + startIndex += length; + byte[] planLossTotalElectricityByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String planLossTotalElectricity = YKCUtils.convertDecimalPoint(planLossTotalElectricityByteArr, 4); + + // 消费金额 精确到小数点后四位,包含电费、 服务费 + startIndex += length; + byte[] consumptionAmountByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String consumptionAmount = YKCUtils.convertDecimalPoint(consumptionAmountByteArr, 4); + + // VIN 码 VIN 码,此处 VIN 码和充电时 VIN 码不同, 正序直接上传, 无需补 0 和反序 + startIndex += length; + length = 17; + byte[] vinCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String vinCode = YKCUtils.parseVin(vinCodeByteArr); // 解析vin + + /** + * 交易标识 + * 0x01: app 启动 + * 0x02:卡启动 + * 0x04:离线卡启动 + * 0x05: vin 码启动充电 + */ + startIndex += length; + length = 1; + byte[] transactionIdentifierByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String transactionIdentifier = BytesUtil.bcd2Str(transactionIdentifierByteArr); + + // 交易时间 CP56Time2a 格式 + startIndex += length; + length = 7; + byte[] transactionTimeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + Date transactionDate = Cp56Time2aUtil.byte2Hdate(transactionTimeByteArr); + String transactionTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, transactionDate); + + // 停止原因 + startIndex += length; + length = 1; + byte[] stopReasonByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + String stopReason = BytesUtil.bin2HexStr(stopReasonByteArr); + int i = Integer.parseInt(stopReason, 16); + String stopReasonMsg = YKCChargingStopReasonEnum.getMsgByCode(i); + + // 物理卡号 不足 8 位补 0 + startIndex += length; + length = 8; + byte[] cardNumByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); + // log.info("交易记录确认cardNumByteArr:{}", cardNumByteArr); + String logicCard = BytesUtil.binary(cardNumByteArr, 16); + // log.info("桩号:{}, 发送交易记录物理卡号:{}", pileSn, logicCard); + + log.info("[===交易记录===]交易流水号:{}, 桩编号:{}, 枪号:{}, 开始时间:{}, 结束时间:{}, 尖单价:{}, 尖电量:{}, 计损尖电量:{}, 尖金额:{}, " + + "峰单价:{}, 峰电量:{}, 计损峰电量:{}, 峰金额:{}, 平单价:{}, 平电量:{}, 计损平电量:{}, 平金额:{}, " + + "谷单价:{}, 谷电量:{}, 计损谷电量:{}, 谷金额:{}, 电表总起值:{}, 电表总止值:{}, 总电量:{}, 计损总电量:{}, 消费金额:{}, " + + "vin码:{}, 交易标识:{}, 交易日期、时间:{}, 停止原因码:{}, 停止原因描述:{}, 物理卡号:{}", + transactionCode, pileSn, connectorCode, startTime, endTime, sharpPrice, sharpUsedElectricity, sharpPlanLossElectricity, sharpAmount, + peakPrice, peakUsedElectricity, peakPlanLossElectricity, peakAmount, flatPrice, flatUsedElectricity, flatPlanLossElectricity, flatAmount, + valleyPrice, valleyUsedElectricity, valleyPlanLossElectricity, valleyAmount, ammeterTotalStart, ammeterTotalEnd, totalElectricity, planLossTotalElectricity, + consumptionAmount, vinCode, transactionIdentifier, transactionTime, stopReason, stopReasonMsg, logicCard); + + // 交易记录封装到对象里 + TransactionRecordsData data = TransactionRecordsData.builder() + // .orderCode(transactionCode) + .transactionCode(transactionCode) + .pileSn(pileSn) + .connectorCode(connectorCode) + .startTime(startTime) + .endTime(endTime) + .sharpPrice(sharpPrice) + .sharpUsedElectricity(sharpUsedElectricity) + .sharpPlanLossElectricity(sharpPlanLossElectricity) + .sharpAmount(sharpAmount) + .peakPrice(peakPrice) + .peakUsedElectricity(peakUsedElectricity) + .peakPlanLossElectricity(peakPlanLossElectricity) + .peakAmount(peakAmount) + .flatPrice(flatPrice) + .flatUsedElectricity(flatUsedElectricity) + .flatPlanLossElectricity(flatPlanLossElectricity) + .flatAmount(flatAmount) + .valleyPrice(valleyPrice) + .valleyUsedElectricity(valleyUsedElectricity) + .valleyPlanLossElectricity(valleyPlanLossElectricity) + .valleyAmount(valleyAmount) + .ammeterTotalStart(ammeterTotalStart) + .ammeterTotalEnd(ammeterTotalEnd) + .totalElectricity(totalElectricity) + .planLossTotalElectricity(planLossTotalElectricity) + .consumptionAmount(consumptionAmount) + .vinCode(vinCode) + .transactionIdentifier(transactionIdentifier) + .transactionTime(transactionTime) + .stopReasonCode(stopReason) + .stopReasonMsg(stopReasonMsg) + .logicCard(logicCard) + .build(); + + // 保存交易记录到redis (缓存时间1天) + + boolean flag = !StringUtils.equals("0000000000000000", "a511101970000000"); + System.out.println(flag); + + } @Override public byte[] supplyProcess(YKCDataProtocol ykcDataProtocol, ChannelHandlerContext channel) { @@ -472,12 +471,12 @@ public class TransactionRecordsRequestHandler extends AbstractYkcHandler { startIndex += length; length = 5; byte[] ammeterTotalStartByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - String ammeterTotalStart = YKCUtils.convertDecimalPoint(ammeterTotalStartByteArr, 4); + String ammeterTotalStart = YKCUtils.reduceMagnification(YKCUtils.readLongLE5Byte(ammeterTotalStartByteArr), 10000, 4).toString(); // 电表总止值 startIndex += length; byte[] ammeterTotalEndByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - String ammeterTotalEnd = YKCUtils.convertDecimalPoint(ammeterTotalEndByteArr, 4); + String ammeterTotalEnd = YKCUtils.reduceMagnification(YKCUtils.readLongLE5Byte(ammeterTotalEndByteArr), 10000, 4).toString(); // 总电量 startIndex += length;