diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/ReservationChargingResponseHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/ReservationChargingResponseHandler.java index 2fb31b644..b4dbf0c08 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/ReservationChargingResponseHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/yunkuaichong/ReservationChargingResponseHandler.java @@ -45,6 +45,15 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler { // log.info("[====远程更新应答====] param:{}, channel:{}", JSON.toJSONString(ykcDataProtocol), channel.toString()); // 消息体 byte[] msgBody = ykcDataProtocol.getMsgBody(); + String responseFrameType = YKCUtils.frameType2Str(ykcDataProtocol.getFrameType()); + boolean yuxinResponse = StringUtils.equals(responseFrameType, yuxinType); + String rawMessage = BytesUtil.bin2HexStr(ykcDataProtocol.getBytes()); + int minMsgBodyLength = yuxinResponse ? 27 : 26; + if (msgBody == null || msgBody.length < minMsgBodyLength) { + log.warn("预约充电响应长度异常, 帧类型:{}, 报文体长度:{}, 原始报文:{}", + responseFrameType, msgBody == null ? null : msgBody.length, rawMessage); + return null; + } int startIndex = 0; int length = 16; @@ -66,8 +75,6 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler { startIndex += length; length = 1; byte[] connectorCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length); - String responseFrameType = YKCUtils.frameType2Str(ykcDataProtocol.getFrameType()); - boolean yuxinResponse = StringUtils.equals(responseFrameType, yuxinType); String connectorCode = yuxinResponse ? parseYuxinConnectorCode(connectorCodeByteArr) : BytesUtil.bcd2Str(connectorCodeByteArr); String reservationType = null; @@ -93,27 +100,41 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler { String failedReasonMsg = yuxinResponse ? getYuxinFailedReasonMsg(failedReason) : failedReason; if (yuxinResponse) { - log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 预约方式:{}, 结果:{}, 失败原因:{}", - responseFrameType, transactionCode, pileSn, connectorCode, reservationType, resultCode, failedReasonMsg); + log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 预约方式:{}, 结果:{}({}), 失败原因:{}({}), 原始报文:{}", + responseFrameType, transactionCode, pileSn, connectorCode, reservationType, resultCode, + getYuxinSetupResultMsg(resultCode), failedReason, failedReasonMsg, rawMessage); + if (!StringUtils.equals(resultCode, "01")) { + log.warn("羽信预约充电设置失败, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 预约方式:{}, 失败原因:{}({}), 原始报文:{}", + transactionCode, pileSn, connectorCode, reservationType, failedReason, failedReasonMsg, rawMessage); + } } else { - log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 结果:{}, 失败原因:{}", - responseFrameType, transactionCode, pileSn, connectorCode, resultCode, failedReason); + log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 结果:{}, 失败原因:{}, 原始报文:{}", + responseFrameType, transactionCode, pileSn, connectorCode, resultCode, failedReason, rawMessage); } // 根据请求id,在集合中找到与外部线程通信的SyncPromise对象 String requestFrameType = YKCFrameTypeCode.PileAnswersRelation.getRequestFrameType(responseFrameType); if (StringUtils.isBlank(requestFrameType)) { - requestFrameType = YKCUtils.frameType2Str(YKCFrameTypeCode.RESERVATION_CHARGING_SETUP_CODE.getBytes()); + requestFrameType = yuxinResponse + ? YKCUtils.frameType2Str(YKCFrameTypeCode.YUXIN_RESERVATION_CHARGING_SETUP_CODE.getBytes()) + : YKCUtils.frameType2Str(YKCFrameTypeCode.RESERVATION_CHARGING_SETUP_CODE.getBytes()); } String msgId = ctx.channel().id().toString() + "_" + requestFrameType; log.info("同步获取响应数据-收到消息, msgId:{}", msgId); SyncPromise syncPromise = RpcUtil.getSyncPromiseMap().get(msgId); - if(syncPromise != null) { + if (syncPromise != null) { // 设置响应结果 syncPromise.setRpcResult(ykcDataProtocol.getBytes()); // 唤醒外部线程 log.info("同步获取响应数据-唤醒外部线程, SyncPromise:{}", JSON.toJSONString(syncPromise)); syncPromise.wake(); + } else { + log.warn("同步获取响应数据-未找到等待线程, msgId:{}, responseFrameType:{}, requestFrameType:{}, 原始报文:{}", + msgId, responseFrameType, requestFrameType, rawMessage); + } + + if (yuxinResponse) { + return null; } // 如果收到成功, 从redis取值, 保存到数据库 @@ -147,4 +168,13 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler { } return failedReason; } + + private String getYuxinSetupResultMsg(String resultCode) { + if (StringUtils.equals(resultCode, "00")) { + return "失败"; + } else if (StringUtils.equals(resultCode, "01")) { + return "成功"; + } + return resultCode; + } } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/YKCPushCommandServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/YKCPushCommandServiceImpl.java index 688bfbf4b..5696ae006 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/YKCPushCommandServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/YKCPushCommandServiceImpl.java @@ -47,6 +47,7 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService { private static final BigDecimal DEFAULT_YUXIN_CHARGING_PARAM = BigDecimal.ZERO; private static final int DEFAULT_YUXIN_CHARGING_STRATEGY = 0; private static final int DEFAULT_YUXIN_RESERVATION_TIMEOUT = 0; + private static final int YUXIN_RESERVATION_RESPONSE_TIMEOUT_SECONDS = 5; @Autowired private PileBillingTemplateService pileBillingTemplateService; @@ -789,7 +790,8 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService { log.info("羽信预约充电下发原始报文, pileSn:{}, rawMessage:{}", pileSn, BytesUtil.bin2HexStr(msg)); byte[] response; try { - response = this.supplySend(msg, pileSn, YKCFrameTypeCode.YUXIN_RESERVATION_CHARGING_SETUP_CODE); + response = this.supplySend(msg, pileSn, YKCFrameTypeCode.YUXIN_RESERVATION_CHARGING_SETUP_CODE, + YUXIN_RESERVATION_RESPONSE_TIMEOUT_SECONDS, TimeUnit.SECONDS); } catch (Exception e) { log.error("发送羽信预约充电消息异常", e); response = null;