From 256e358be53acd9e2eea229a636520df323e041f Mon Sep 17 00:00:00 2001 From: Guoqs <123@jsowell.com> Date: Mon, 2 Sep 2024 19:55:02 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E7=94=B5=E5=8D=95=E8=BD=A6=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/uniapp/customer/TempController.java | 19 ++++ .../common/enums/ykc/PileChannelEntity.java | 3 +- .../com/jsowell/common/util/BytesUtil.java | 61 +++++++++++- .../com/jsowell/common/util/RandomUtil.java | 10 +- .../com/jsowell/common/util/id/IdUtils.java | 2 +- .../DeviceGetServerTimeHandler.java | 4 +- .../electricbicycles/HeartbeatHandler.java | 3 +- .../HostGetServerTimeHandler.java | 4 +- .../electricbicycles/RegistrationHandler.java | 4 +- .../SettlementUploadHandler.java | 4 +- .../pile/domain/ebike/AbsEBikeMessage.java | 52 +++++------ .../pile/domain/ebike/EBikeCommandEnum.java | 41 ++++---- .../ebike/serversend/EBikeMessageCmd81.java | 4 - .../ebike/serversend/EBikeMessageCmd82.java | 93 +++++++++++-------- .../pile/service/EBikeSendCommandService.java | 6 +- .../impl/EBikeSendCommandServiceImpl.java | 50 ++++++++-- 16 files changed, 245 insertions(+), 115 deletions(-) diff --git a/jsowell-admin/src/main/java/com/jsowell/api/uniapp/customer/TempController.java b/jsowell-admin/src/main/java/com/jsowell/api/uniapp/customer/TempController.java index bd112af4c..887e667c0 100644 --- a/jsowell-admin/src/main/java/com/jsowell/api/uniapp/customer/TempController.java +++ b/jsowell-admin/src/main/java/com/jsowell/api/uniapp/customer/TempController.java @@ -72,6 +72,25 @@ public class TempController extends BaseController { @Autowired private PileRemoteService pileRemoteService; + @Autowired + private EBikeSendCommandService eBikeSendCommandService; + + /** + * 电单车开始充电 + * http://localhost:8080/temp/tempStartCharging + */ + @PostMapping("/tempStartCharging") + public RestApiResponse tempStartCharging(@RequestBody QueryOrderDTO dto) { + RestApiResponse response = null; + try { + eBikeSendCommandService.startCharging(dto.getPileSn()); + } catch (Exception e) { + logger.error("电单车开始充电 error", e); + response = new RestApiResponse<>(ReturnCodeEnum.CODE_FAILED); + } + return response; + } + /** * 对时 * http://localhost:8080/temp/proofreadTimeTest diff --git a/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/PileChannelEntity.java b/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/PileChannelEntity.java index 3010be375..8e81d95ef 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/PileChannelEntity.java +++ b/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/PileChannelEntity.java @@ -55,6 +55,7 @@ public class PileChannelEntity { * @return */ public static ChannelHandlerContext getChannelByPileSn(String pileSn) { + output(); return manager.get(pileSn); } @@ -78,7 +79,7 @@ public class PileChannelEntity { public static void output() { for (HashMap.Entry entry : manager.entrySet()) { System.out.println("pileSn:" + entry.getKey() + - ",ChannelId:" + entry.getValue().channel().id().asLongText()); + ",ChannelId:" + entry.getValue().channel().id().asShortText()); } } diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/BytesUtil.java b/jsowell-common/src/main/java/com/jsowell/common/util/BytesUtil.java index 099dc078e..307285fbc 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/util/BytesUtil.java +++ b/jsowell-common/src/main/java/com/jsowell/common/util/BytesUtil.java @@ -272,6 +272,55 @@ public class BytesUtil { return stringBuilder.toString(); } + /** + * 将字符串转换为指定长度的16进制字节数组。 + * + * @param str 需要转换的字符串 + * @param targetLength 目标字节数组的长度 + * @return 对应的16进制字节数组 + */ + public static byte[] stringToHexBytes(String str, int targetLength) { + if (str == null) { + throw new IllegalArgumentException("字符串不能为null"); + } + + int strLength = str.length(); + if (targetLength < strLength) { + throw new IllegalArgumentException("目标字节数组长度必须大于等于字符串长度"); + } + + byte[] hexBytes = new byte[targetLength]; + for (int i = 0; i < strLength; i++) { + char c = str.charAt(i); + hexBytes[i] = (byte) c; + } + + // 剩余部分用0填充 + for (int i = strLength; i < targetLength; i++) { + hexBytes[i] = 0; + } + + return hexBytes; + } + + /** + * 将字节数组转换为十六进制字符串,用于打印查看。 + * + * @param bytes 字节数组 + * @return 十六进制字符串 + */ + private static String bytesToHex(byte[] bytes) { + StringBuilder hexString = new StringBuilder(); + for (byte b : bytes) { + String hex = Integer.toHexString(0xFF & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } + /** * @函数功能: 10进制串转为BCD码 * @输入参数: 10进制串 @@ -326,12 +375,14 @@ public class BytesUtil { return revert(temp); } - - public static void main(String[] args) { - byte[] length = new byte[] {0x09, 0x00}; - int i = BytesUtil.bytesToIntLittle(length); - System.out.println(i); + // byte[] length = new byte[] {0x09, 0x00}; + // int i = BytesUtil.bytesToIntLittle(length); + // System.out.println(i); + + String testStr = "DNY"; + byte[] hexBytes = stringToHexBytes(testStr, 3); + System.out.println("Hex Bytes: " + bytesToHex(hexBytes)); } /** diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/RandomUtil.java b/jsowell-common/src/main/java/com/jsowell/common/util/RandomUtil.java index 4c7a56ab4..b7e5dc469 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/util/RandomUtil.java +++ b/jsowell-common/src/main/java/com/jsowell/common/util/RandomUtil.java @@ -14,7 +14,7 @@ import java.util.Set; public class RandomUtil { private static final String SYMBOLS_NUM = "0123456789"; // 纯数字 //如果需加入字母就改成0123456789abcdefg........... - private static final String SYMBOLS_NUM_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789"; + // private static final String SYMBOLS_NUM_ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789"; private static final Random RANDOM = new SecureRandom(); @@ -24,7 +24,7 @@ public class RandomUtil { * @return 随机数字 */ public static String getSMSVerificationCode() { - return getRandomNumber(6); + return getRandomNumberStr(6); } /** @@ -33,7 +33,7 @@ public class RandomUtil { * @param length 需要的长度 * @return 随机数 */ - public static String getRandomNumber(int length) { + public static String getRandomNumberStr(int length) { char[] nonceChars = new char[length]; //指定长度,自己可以设置 for (int index = 0; index < nonceChars.length; ++index) { nonceChars[index] = SYMBOLS_NUM.charAt(RANDOM.nextInt(SYMBOLS_NUM.length())); @@ -41,6 +41,10 @@ public class RandomUtil { return new String(nonceChars); } + public static int getRandomNumber(int length) { + return Integer.parseInt(getRandomNumberStr(length)); + } + /** * 获取一组不重复的6位数随机数 * diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/id/IdUtils.java b/jsowell-common/src/main/java/com/jsowell/common/util/id/IdUtils.java index 35489dd26..56f13ea4e 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/util/id/IdUtils.java +++ b/jsowell-common/src/main/java/com/jsowell/common/util/id/IdUtils.java @@ -87,7 +87,7 @@ public class IdUtils { public static String generateTransactionCode(String pileConnectorCode) { String timeNow = DateUtils.dateTimeNow(DateUtils.YYMMDDHHMMSS); // 随机生成一个四位整数 - String randomNumber = RandomUtil.getRandomNumber(4); + String randomNumber = RandomUtil.getRandomNumberStr(4); return pileConnectorCode + timeNow + randomNumber; } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/DeviceGetServerTimeHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/DeviceGetServerTimeHandler.java index 2afe0e5ba..2b42144d1 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/DeviceGetServerTimeHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/DeviceGetServerTimeHandler.java @@ -3,6 +3,7 @@ package com.jsowell.netty.handler.electricbicycles; import com.alibaba.fastjson2.JSON; import com.jsowell.common.core.domain.ebike.EBikeDataProtocol; import com.jsowell.common.util.BytesUtil; +import com.jsowell.common.util.YKCUtils; import com.jsowell.netty.factory.EBikeOperateFactory; import com.jsowell.pile.domain.ebike.AbsEBikeMessage; import com.jsowell.pile.domain.ebike.EBikeCommandEnum; @@ -17,7 +18,8 @@ import org.springframework.stereotype.Component; @Slf4j @Component public class DeviceGetServerTimeHandler extends AbstractEBikeHandler { - private final String type = EBikeCommandEnum.DEVICE_GET_SERVER_TIME.getCode(); + // private final String type = EBikeCommandEnum.DEVICE_GET_SERVER_TIME.getCode(); + private final String type = YKCUtils.frameType2Str(EBikeCommandEnum.DEVICE_GET_SERVER_TIME.getBytes()); @Override public void afterPropertiesSet() throws Exception { diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java index c191d449a..3c57fa995 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java @@ -5,6 +5,7 @@ import com.jsowell.common.constant.Constants; import com.jsowell.common.core.domain.ebike.EBikeDataProtocol; import com.jsowell.common.enums.ebike.PortStatusEnum; import com.jsowell.common.util.StringUtils; +import com.jsowell.common.util.YKCUtils; import com.jsowell.netty.factory.EBikeOperateFactory; import com.jsowell.pile.domain.ebike.AbsEBikeMessage; import com.jsowell.pile.domain.ebike.EBikeCommandEnum; @@ -24,7 +25,7 @@ import java.util.List; @Slf4j @Component public class HeartbeatHandler extends AbstractEBikeHandler { - private final String type = EBikeCommandEnum.HEARTBEAT_2.getCode(); + private final String type = YKCUtils.frameType2Str(EBikeCommandEnum.HEARTBEAT_2.getBytes()); @Autowired private PileBasicInfoService pileBasicInfoService; diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HostGetServerTimeHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HostGetServerTimeHandler.java index 0d9bf4eee..add8ced5a 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HostGetServerTimeHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HostGetServerTimeHandler.java @@ -3,6 +3,7 @@ package com.jsowell.netty.handler.electricbicycles; import com.alibaba.fastjson2.JSON; import com.jsowell.common.core.domain.ebike.EBikeDataProtocol; import com.jsowell.common.util.BytesUtil; +import com.jsowell.common.util.YKCUtils; import com.jsowell.netty.factory.EBikeOperateFactory; import com.jsowell.pile.domain.ebike.AbsEBikeMessage; import com.jsowell.pile.domain.ebike.EBikeCommandEnum; @@ -17,7 +18,8 @@ import org.springframework.stereotype.Component; @Slf4j @Component public class HostGetServerTimeHandler extends AbstractEBikeHandler { - private final String type = EBikeCommandEnum.HOST_GET_SERVER_TIME.getCode(); + // private final String type = EBikeCommandEnum.HOST_GET_SERVER_TIME.getCode(); + private final String type = YKCUtils.frameType2Str(EBikeCommandEnum.HOST_GET_SERVER_TIME.getBytes()); @Override public void afterPropertiesSet() throws Exception { diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java index a9a6ebb7c..f0ce4eb2a 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java @@ -3,6 +3,7 @@ package com.jsowell.netty.handler.electricbicycles; import com.alibaba.fastjson2.JSON; import com.jsowell.common.constant.Constants; import com.jsowell.common.core.domain.ebike.EBikeDataProtocol; +import com.jsowell.common.util.YKCUtils; import com.jsowell.netty.factory.EBikeOperateFactory; import com.jsowell.pile.domain.ebike.AbsEBikeMessage; import com.jsowell.pile.domain.ebike.EBikeCommandEnum; @@ -19,7 +20,8 @@ import org.springframework.stereotype.Component; @Slf4j @Component public class RegistrationHandler extends AbstractEBikeHandler { - private final String type = EBikeCommandEnum.REGISTRATION.getCode(); + // private final String type = EBikeCommandEnum.REGISTRATION.getCode(); + private final String type = YKCUtils.frameType2Str(EBikeCommandEnum.REGISTRATION.getBytes()); @Autowired private PileBasicInfoService pileBasicInfoService; diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java index 85d9cb3ba..273835d89 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java @@ -2,6 +2,7 @@ package com.jsowell.netty.handler.electricbicycles; import com.alibaba.fastjson2.JSON; import com.jsowell.common.core.domain.ebike.EBikeDataProtocol; +import com.jsowell.common.util.YKCUtils; import com.jsowell.netty.factory.EBikeOperateFactory; import com.jsowell.pile.domain.ebike.AbsEBikeMessage; import com.jsowell.pile.domain.ebike.EBikeCommandEnum; @@ -16,7 +17,8 @@ import org.springframework.stereotype.Component; @Slf4j @Component public class SettlementUploadHandler extends AbstractEBikeHandler { - private final String type = EBikeCommandEnum.SETTLEMENT_UPLOAD.getCode(); + // private final String type = EBikeCommandEnum.SETTLEMENT_UPLOAD.getCode(); + private final String type = YKCUtils.frameType2Str(EBikeCommandEnum.SETTLEMENT_UPLOAD.getBytes()); @Override public void afterPropertiesSet() throws Exception { diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/AbsEBikeMessage.java b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/AbsEBikeMessage.java index a74cd0953..d6c52fc9a 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/AbsEBikeMessage.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/AbsEBikeMessage.java @@ -1,18 +1,19 @@ package com.jsowell.pile.domain.ebike; -import com.google.common.primitives.Bytes; import com.jsowell.common.YouDianUtils; import com.jsowell.common.util.BytesUtil; import com.jsowell.pile.domain.ebike.deviceupload.*; -import lombok.Getter; -import lombok.Setter; +import lombok.*; import java.nio.charset.StandardCharsets; import java.util.Arrays; @Getter @Setter -public abstract class AbsEBikeMessage { +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AbsEBikeMessage { protected String header; // 包头 (3字节) protected int length; // 长度 (2字节) protected int physicalId; // 物理ID (4字节) @@ -21,17 +22,9 @@ public abstract class AbsEBikeMessage { protected Object payload; // 数据 (n字节) protected int checksum; // 校验 (2字节) - public AbsEBikeMessage(String header, int length, int physicalId, int messageId, String command, Object payload, int checksum) { - this.header = header; - this.length = length; - this.physicalId = physicalId; - this.messageId = messageId; - this.command = command; - this.payload = payload; - this.checksum = checksum; - } + public void parsePayload(byte[] dataBytes) { - public abstract void parsePayload(byte[] dataBytes); + }; private static AbsEBikeMessage createMessageInstance(String command, String header, int length, int physicalId, int messageId, int checksum, byte[] dataBytes) { switch (command) { @@ -104,10 +97,13 @@ public abstract class AbsEBikeMessage { } } - public abstract byte[] getMessageBytes(); + public byte[] getMessageBytes() { + return null; + }; public static void main(String[] args) { - String s = "44 4E 59 26 00 3B 37 AB 04 02 00 82 00 64 01 00 00 01 01 00 00 12 34 56 78 12 34 56 78 12 34 56 78 12 34 56 78 80 70 88 13 F8 08"; + String s = "444e592700198bca00072482333000000030313000300000000000000000000000000000003000300030e104"; + String msg82 = "44 4E 59 26 00 3B 37 AB 04 02 00 82 00 64 01 00 00 01 01 00 00 12 34 56 78 12 34 56 78 12 34 56 78 12 34 56 78 80 70 88 13 F8 08"; s = s.replace(" ", ""); byte[] messageBytes = BytesUtil.hexStringToByteArray(s); // 读取包头 @@ -115,36 +111,36 @@ public abstract class AbsEBikeMessage { String header = new String(headerBytes, StandardCharsets.UTF_8); System.out.println("header: " + header); - byte[] header2 = header.getBytes(); - System.out.println("反序列header: " + header2); + // byte[] header2 = header.getBytes(); + // System.out.println("反序列header: " + header2); // 读取长度 byte[] lengthBytes = Arrays.copyOfRange(messageBytes, 3, 5); int length = BytesUtil.bytesToIntLittle(lengthBytes); System.out.println("length: " + length); - byte[] length2 = BytesUtil.intToBytesLittle(length); - System.out.println("反序列length: " + length2); + // byte[] length2 = BytesUtil.intToBytesLittle(length); + // System.out.println("反序列length: " + length2); // 读取物理ID byte[] physicalIdBytes = Arrays.copyOfRange(messageBytes, 5, 9); int physicalId = BytesUtil.bytesToIntLittle(physicalIdBytes); System.out.println("physicalId: " + physicalId); - byte[] physicalId2 = BytesUtil.intToBytesLittle(physicalId, 4); - System.out.println("反序列physicalId: " + physicalId2); + // byte[] physicalId2 = BytesUtil.intToBytesLittle(physicalId, 4); + // System.out.println("反序列physicalId: " + physicalId2); // 读取消息ID byte[] messageIdBytes = Arrays.copyOfRange(messageBytes, 9, 11); int messageId = BytesUtil.bytesToIntLittle(messageIdBytes); System.out.println("messageId: " + messageId); - byte[] messageId2 = BytesUtil.intToBytesLittle(messageId); - System.out.println("反序列messageId: " + messageId2); + // byte[] messageId2 = BytesUtil.intToBytesLittle(messageId); + // System.out.println("反序列messageId: " + messageId2); // 读取命令 byte commandByte = messageBytes[11]; String command = BytesUtil.bcd2StrLittle(new byte[]{commandByte}); System.out.println("command: " + command); - byte[] command2 = BytesUtil.str2Bcd(command); - System.out.println("反序列command: " + command2); + // byte[] command2 = BytesUtil.str2Bcd(command); + // System.out.println("反序列command: " + command2); // 读取数据 byte[] dataBytes = Arrays.copyOfRange(messageBytes, 12, messageBytes.length - 2); @@ -156,8 +152,8 @@ public abstract class AbsEBikeMessage { int checksum = BytesUtil.bytesToIntLittle(checksumBytes); System.out.println("checksum: " + checksum); - byte[] concat = Bytes.concat(header2, length2, physicalId2, messageId2, command2); - System.out.println("concat: " + BytesUtil.printHexBinary(concat)); + // byte[] concat = Bytes.concat(header2, length2, physicalId2, messageId2, command2); + // System.out.println("concat: " + BytesUtil.printHexBinary(concat)); } } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/EBikeCommandEnum.java b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/EBikeCommandEnum.java index 36196b3ef..eac6caf35 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/EBikeCommandEnum.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/EBikeCommandEnum.java @@ -1,5 +1,6 @@ package com.jsowell.pile.domain.ebike; +import com.jsowell.common.util.BytesUtil; import com.jsowell.pile.domain.ebike.deviceupload.*; import lombok.extern.slf4j.Slf4j; @@ -9,14 +10,14 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public enum EBikeCommandEnum { // HEARTBEAT("01", "设备心跳包"), - HOST_GET_SERVER_TIME("12", "主机获取服务器时间", EBikeMessageCmd12.class), - REGISTRATION("20", "设备注册包", EBikeMessageCmd20.class), - DEVICE_GET_SERVER_TIME("22", "设备获取服务器时间", EBikeMessageCmd22.class), - HEARTBEAT_2("21", "设备心跳包", EBikeMessageCmd21.class), - CARD_OPERATION("02", "刷卡操作", EBikeMessageCmd02.class), - SETTLEMENT_UPLOAD("03", "结算消费信息上传", EBikeMessageCmd03.class), - CHARGE_PORT_CONFIRMATION("04", "充电端口订单确认", EBikeMessageCmd04.class), - POWER_HEARTBEAT("06", "端口充电时功率心跳包", EBikeMessageCmd06.class), + HOST_GET_SERVER_TIME(0x12, "主机获取服务器时间", EBikeMessageCmd12.class), + REGISTRATION(0x20, "设备注册包", EBikeMessageCmd20.class), + DEVICE_GET_SERVER_TIME(0x22, "设备获取服务器时间", EBikeMessageCmd22.class), + HEARTBEAT_2(0x21, "设备心跳包", EBikeMessageCmd21.class), + CARD_OPERATION(0x02, "刷卡操作", EBikeMessageCmd02.class), + SETTLEMENT_UPLOAD(0x03, "结算消费信息上传", EBikeMessageCmd03.class), + CHARGE_PORT_CONFIRMATION(0x04, "充电端口订单确认", EBikeMessageCmd04.class), + POWER_HEARTBEAT(0x06, "端口充电时功率心跳包", EBikeMessageCmd06.class), // CHARGER_HEARTBEAT("41", "充电柜专有心跳包", EBikeMessageCmd41.class), // ALARM_PUSH("42", "报警推送指令", EBikeMessageCmd20.class), // CHARGE_COMPLETE("43", "充电完成通知,但不结算", EBikeMessageCmd20.class), @@ -24,17 +25,17 @@ public enum EBikeCommandEnum { ; - EBikeCommandEnum(String code, String desc, Class msgClass) { + EBikeCommandEnum(int code, String desc, Class msgClass) { this.code = code; this.desc = desc; this.msgClass = msgClass; } - private final String code; // 帧类型code + private final int code; // 帧类型code private final String desc; // 帧类型名称 private final Class msgClass; - public String getCode() { + public int getCode() { return code; } @@ -46,13 +47,17 @@ public enum EBikeCommandEnum { return msgClass; } - public static Class getMsgClassByCode(String code) { - for (EBikeCommandEnum e : EBikeCommandEnum.values()) { - if (e.getCode().equals(code)) { - return e.getMsgClass(); - } - } - return null; + public byte[] getBytes() { + return BytesUtil.intToBytesLittle(code, 1); } + // public static Class getMsgClassByCode(String code) { + // for (EBikeCommandEnum e : EBikeCommandEnum.values()) { + // if (e.getCode().equals(code)) { + // return e.getMsgClass(); + // } + // } + // return null; + // } + } \ No newline at end of file diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/serversend/EBikeMessageCmd81.java b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/serversend/EBikeMessageCmd81.java index ef04ece8f..a74265f9f 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/serversend/EBikeMessageCmd81.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/serversend/EBikeMessageCmd81.java @@ -9,10 +9,6 @@ import com.jsowell.pile.domain.ebike.AbsEBikeMessage; */ public class EBikeMessageCmd81 extends AbsEBikeMessage { - public EBikeMessageCmd81(String header, int length, int physicalId, int messageId, String command, Object payload, int checksum) { - super(header, length, physicalId, messageId, command, payload, checksum); - } - @Override public void parsePayload(byte[] dataBytes) { diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/serversend/EBikeMessageCmd82.java b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/serversend/EBikeMessageCmd82.java index 2b24358a5..d29f6f1a2 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/serversend/EBikeMessageCmd82.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/domain/ebike/serversend/EBikeMessageCmd82.java @@ -4,42 +4,59 @@ import com.google.common.primitives.Bytes; import com.jsowell.common.YouDianUtils; import com.jsowell.common.util.BytesUtil; import com.jsowell.pile.domain.ebike.AbsEBikeMessage; -import lombok.Getter; -import lombok.Setter; +import lombok.*; import java.util.Arrays; /** * 服务器开始、停止充电操作(82指令) */ +@Data +@NoArgsConstructor +@AllArgsConstructor public class EBikeMessageCmd82 extends AbsEBikeMessage { - private SpecificData specificData; + private SpecificData data; - public EBikeMessageCmd82(String header, int length, int physicalId, int messageId, String command, Object payload, int checksum, SpecificData specificData) { - super(header, length, physicalId, messageId, command, payload, checksum); - this.specificData = specificData; - } + // public EBikeMessageCmd82(String header, int length, int physicalId, int messageId, String command, Object payload, int checksum, SpecificData specificData) { + // super(header, length, physicalId, messageId, command, payload, checksum); + // this.specificData = specificData; + // } + + // public EBikeMessageCmd82(SpecificData specificData) { + // super(header, length, physicalId, messageId, command, payload, checksum); + // this.specificData = specificData; + // } @Override public void parsePayload(byte[] dataBytes) { - this.specificData = new SpecificData(dataBytes); + this.data = new SpecificData(dataBytes); + } + + public static void main(String[] args) { + int i = 0x82; + byte[] commandBytes = new byte[]{(byte) i}; + System.out.println(BytesUtil.bcd2StrLittle(commandBytes)); + int i2 = 82; + byte[] commandBytes2 = new byte[]{(byte) i2}; + System.out.println(BytesUtil.bcd2StrLittle(commandBytes2)); } @Override public byte[] getMessageBytes() { // 包头 - byte[] headerBytes = BytesUtil.str2AscLittle(header); - // 长度 - byte[] lengthBytes = BytesUtil.intToBytesLittle(length); + byte[] headerBytes = BytesUtil.stringToHexBytes(header, 3); // 物理ID - byte[] physicalIdBytes = BytesUtil.intToBytesLittle(physicalId); + byte[] physicalIdBytes = BytesUtil.intToBytesLittle(physicalId, 4); // 消息ID - byte[] messageIdBytes = BytesUtil.intToBytesLittle(messageId); + byte[] messageIdBytes = BytesUtil.intToBytesLittle(messageId, 2); // 命令 - byte[] commandBytes = BytesUtil.str2Bcd(command); + // byte[] commandBytes = BytesUtil.intToBytesLittle(Integer.parseInt(command), 1); + byte[] commandBytes = new byte[]{(byte) 0x82}; // 数据 - byte[] payloadBytes = specificData.getBytes(); + byte[] payloadBytes = data.getBytes(); + // 长度 物理ID+消息ID+命令+数据(n) +校验(2),每包最多256字节 + byte[] lengthBytes = BytesUtil.intToBytesLittle(9 + payloadBytes.length); // 拼接 byte[] concat = Bytes.concat(headerBytes, lengthBytes, physicalIdBytes, messageIdBytes, commandBytes, payloadBytes); // 校验和 @@ -47,12 +64,13 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage { return Bytes.concat(concat, checksumBytes); } - public SpecificData getSpecificData() { - return specificData; + public SpecificData getData() { + return data; } @Getter @Setter + @NoArgsConstructor public static class SpecificData { private String rateMode; // 费率模式 (1字节) private String balanceOrValidity; // 余额/有效期 (4字节) @@ -124,42 +142,43 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage { // 获取字节数组 public byte[] getBytes() { // 费率模式 - byte[] rateModeBytes = BytesUtil.str2Bcd(rateMode); + byte[] rateModeBytes = BytesUtil.stringToHexBytes(rateMode, 1); // 余额/有效期 - byte[] balanceOrValidityBytes = BytesUtil.str2Bcd(balanceOrValidity); + byte[] balanceOrValidityBytes = BytesUtil.stringToHexBytes(balanceOrValidity, 4); // 端口号 - byte[] portNumberBytes = BytesUtil.str2Bcd(portNumber); + byte[] portNumberBytes = BytesUtil.stringToHexBytes(portNumber, 1); // 充电命令 - byte[] chargeCommandBytes = BytesUtil.str2Bcd(chargeCommand); + byte[] chargeCommandBytes = BytesUtil.stringToHexBytes(chargeCommand, 1); // 充电时长/电量 - byte[] chargeDurationOrPowerBytes = BytesUtil.str2Bcd(chargeDurationOrPower); + byte[] chargeDurationOrPowerBytes = BytesUtil.stringToHexBytes(chargeDurationOrPower, 2); // 订单编号 - byte[] orderNumberBytes = BytesUtil.str2Bcd(orderNumber); + byte[] orderNumberBytes = BytesUtil.stringToHexBytes(orderNumber, 16); // 最大充电时长 - byte[] maxChargeDurationBytes = BytesUtil.str2Bcd(maxChargeDuration); + byte[] maxChargeDurationBytes = BytesUtil.stringToHexBytes(maxChargeDuration, 2); // 过载功率 - byte[] overloadPowerBytes = BytesUtil.str2Bcd(overloadPower); + byte[] overloadPowerBytes = BytesUtil.stringToHexBytes(overloadPower, 2); // 二维码灯 - byte[] qrCodeLightBytes = BytesUtil.str2Bcd(qrCodeLight); + byte[] qrCodeLightBytes = BytesUtil.stringToHexBytes(qrCodeLight, 1); // 长充模式 - byte[] longChargeModeBytes = BytesUtil.str2Bcd(longChargeMode); + // byte[] longChargeModeBytes = BytesUtil.stringToHexBytes(longChargeMode, 1); // 额外浮充时间 - byte[] extraFloatChargeTimeBytes = BytesUtil.str2Bcd(extraFloatChargeTime); + // byte[] extraFloatChargeTimeBytes = BytesUtil.stringToHexBytes(extraFloatChargeTime, 2); // 是否跳过短路检测 - byte[] skipShortCircuitDetectionBytes = BytesUtil.str2Bcd(skipShortCircuitDetection); + // byte[] skipShortCircuitDetectionBytes = BytesUtil.stringToHexBytes(skipShortCircuitDetection, 1); // 不判断用户拔出 - byte[] noUserPullOutCheckBytes = BytesUtil.str2Bcd(noUserPullOutCheck); + // byte[] noUserPullOutCheckBytes = BytesUtil.stringToHexBytes(noUserPullOutCheck, 1); // 强制带充满自停 - byte[] forceAutoStopWhenFullBytes = BytesUtil.str2Bcd(forceAutoStopWhenFull); + // byte[] forceAutoStopWhenFullBytes = BytesUtil.stringToHexBytes(forceAutoStopWhenFull, 1); // 充满功率 - byte[] fullChargePowerBytes = BytesUtil.str2Bcd(fullChargePower); + // byte[] fullChargePowerBytes = BytesUtil.stringToHexBytes(fullChargePower, 1); // 最大充满功率最长判断时间 - byte[] maxFullChargePowerCheckTimeBytes = BytesUtil.str2Bcd(maxFullChargePowerCheckTime); + // byte[] maxFullChargePowerCheckTimeBytes = BytesUtil.stringToHexBytes(maxFullChargePowerCheckTime, 1); return Bytes.concat(rateModeBytes, balanceOrValidityBytes, portNumberBytes, chargeCommandBytes, - chargeDurationOrPowerBytes, orderNumberBytes, maxChargeDurationBytes, overloadPowerBytes, - qrCodeLightBytes, longChargeModeBytes, extraFloatChargeTimeBytes, skipShortCircuitDetectionBytes, - noUserPullOutCheckBytes, forceAutoStopWhenFullBytes, fullChargePowerBytes, - maxFullChargePowerCheckTimeBytes); + chargeDurationOrPowerBytes, orderNumberBytes, maxChargeDurationBytes, overloadPowerBytes, qrCodeLightBytes + // ,longChargeModeBytes, extraFloatChargeTimeBytes, skipShortCircuitDetectionBytes, + // noUserPullOutCheckBytes, forceAutoStopWhenFullBytes, fullChargePowerBytes, + // maxFullChargePowerCheckTimeBytes + ); } } } \ No newline at end of file diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/EBikeSendCommandService.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/EBikeSendCommandService.java index b1402bc90..631c5a40c 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/EBikeSendCommandService.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/EBikeSendCommandService.java @@ -1,10 +1,10 @@ package com.jsowell.pile.service; -import com.jsowell.pile.domain.ebike.AbsEBikeMessage; - /** * 电单车发送命令服务 */ public interface EBikeSendCommandService { - void send(String pileSn, AbsEBikeMessage msg); + // void send(String pileSn, AbsEBikeMessage msg); + + void startCharging(String pileSn); } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/EBikeSendCommandServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/EBikeSendCommandServiceImpl.java index 35ce82bd1..f36577cc3 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/EBikeSendCommandServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/EBikeSendCommandServiceImpl.java @@ -2,7 +2,9 @@ package com.jsowell.pile.service.impl; import com.jsowell.common.enums.ykc.PileChannelEntity; import com.jsowell.common.util.BytesUtil; +import com.jsowell.common.util.RandomUtil; import com.jsowell.pile.domain.ebike.AbsEBikeMessage; +import com.jsowell.pile.domain.ebike.serversend.EBikeMessageCmd82; import com.jsowell.pile.service.EBikeSendCommandService; import io.netty.channel.ChannelHandlerContext; import lombok.extern.slf4j.Slf4j; @@ -14,21 +16,49 @@ import java.util.Objects; @Service public class EBikeSendCommandServiceImpl implements EBikeSendCommandService { @Override - public void send(String pileSn, AbsEBikeMessage msg) { + public void startCharging(String pileSn) { + EBikeMessageCmd82 message = new EBikeMessageCmd82(); + message.setHeader("DNY"); + message.setPhysicalId(Integer.parseInt(pileSn)); + message.setMessageId(RandomUtil.getRandomNumber(4)); + message.setCommand("82"); + EBikeMessageCmd82.SpecificData data = new EBikeMessageCmd82.SpecificData(); + data.setRateMode("3"); + data.setBalanceOrValidity("0"); + data.setPortNumber("0"); + data.setChargeCommand("1"); + data.setChargeDurationOrPower("0"); + data.setOrderNumber("0"); + data.setMaxChargeDuration("0"); + data.setOverloadPower("0"); + data.setQrCodeLight("0"); + data.setLongChargeMode("0"); + data.setExtraFloatChargeTime("0"); + data.setSkipShortCircuitDetection("0"); + data.setNoUserPullOutCheck("0"); + data.setForceAutoStopWhenFull("0"); + data.setFullChargePower("0"); + data.setMaxFullChargePowerCheckTime("0"); + message.setData(data); + this.send(message); + } + + /** + * 公共方法, 发送指令 + * @param msg + */ + private void send(AbsEBikeMessage msg) { + String pileSn = msg.getPhysicalId() + ""; + byte[] messageBytes = msg.getMessageBytes(); + PileChannelEntity.output(); + log.info("发送电单车命令, pileSn:{}, messageBytes:{}", pileSn, BytesUtil.binary(messageBytes, 16)); // 获取桩的channel ChannelHandlerContext ctx = PileChannelEntity.getChannelByPileSn(pileSn); if (Objects.isNull(ctx)) { log.error("电单车send命令失败, 桩号:{}无法获取到长连接, 请检查充电桩连接状态!", pileSn); throw new NullPointerException("channel"); } - if (Objects.isNull(msg)) { - log.error("电单车send命令失败, msg为空!"); - throw new NullPointerException("msg"); - } - String str = "44 4E 59 26 00 3B 37 AB 04 02 00 82 00 64 01 00 00 01 01 00 00 12 34 56 78 12 34 56 78 12 34 56 78 12 34 56 78 80 70 88 13 F8 08"; - byte[] messageBytes = BytesUtil.hexStringToByteArray(str); - ctx.writeAndFlush(messageBytes); - - + // ctx.writeAndFlush(messageBytes); } + }