mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-04-20 02:55:04 +08:00
update 电单车协议
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
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.*;
|
||||
@@ -12,13 +13,13 @@ import java.util.Arrays;
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class AbsEBikeMessage {
|
||||
private String header; // 包头 (3字节)
|
||||
private int length; // 长度 (2字节)
|
||||
private int physicalId; // 物理ID (4字节)
|
||||
private int messageId; // 消息ID (2字节)
|
||||
private String command; // 命令 (1字节)
|
||||
private Object payload; // 数据 (n字节)
|
||||
private int checksum; // 校验 (2字节)
|
||||
protected String header; // 包头 (3字节)
|
||||
protected int length; // 长度 (2字节)
|
||||
protected int physicalId; // 物理ID (4字节)
|
||||
protected int messageId; // 消息ID (2字节)
|
||||
protected String command; // 命令 (1字节)
|
||||
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;
|
||||
@@ -106,32 +107,44 @@ public abstract class AbsEBikeMessage {
|
||||
public abstract byte[] getMessageBytes();
|
||||
|
||||
public static void main(String[] args) {
|
||||
String s = "44 4e 59 00 0d 3b 37 ab 04 b9 00 22 54 33 cc 66 03 7b".replace(" ", "");
|
||||
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";
|
||||
s = s.replace(" ", "");
|
||||
byte[] messageBytes = BytesUtil.hexStringToByteArray(s);
|
||||
// 读取包头
|
||||
byte[] headerBytes = Arrays.copyOfRange(messageBytes, 0, 3);
|
||||
String header = new String(headerBytes, StandardCharsets.UTF_8);
|
||||
System.out.println("header: " + header);
|
||||
|
||||
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);
|
||||
|
||||
// 读取物理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);
|
||||
|
||||
// 读取消息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 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[] dataBytes = Arrays.copyOfRange(messageBytes, 12, messageBytes.length - 2);
|
||||
@@ -142,6 +155,9 @@ public abstract class AbsEBikeMessage {
|
||||
byte[] checksumBytes = Arrays.copyOfRange(messageBytes, messageBytes.length - 2, messageBytes.length);
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.jsowell.pile.domain.ebike.serversend;
|
||||
|
||||
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;
|
||||
@@ -26,7 +28,23 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage {
|
||||
|
||||
@Override
|
||||
public byte[] getMessageBytes() {
|
||||
return new byte[0];
|
||||
// 包头
|
||||
byte[] headerBytes = BytesUtil.str2AscLittle(header);
|
||||
// 长度
|
||||
byte[] lengthBytes = BytesUtil.intToBytesLittle(length);
|
||||
// 物理ID
|
||||
byte[] physicalIdBytes = BytesUtil.intToBytesLittle(physicalId);
|
||||
// 消息ID
|
||||
byte[] messageIdBytes = BytesUtil.intToBytesLittle(messageId);
|
||||
// 命令
|
||||
byte[] commandBytes = BytesUtil.str2Bcd(command);
|
||||
// 数据
|
||||
byte[] payloadBytes = specificData.getBytes();
|
||||
// 拼接
|
||||
byte[] concat = Bytes.concat(headerBytes, lengthBytes, physicalIdBytes, messageIdBytes, commandBytes, payloadBytes);
|
||||
// 校验和
|
||||
byte[] checksumBytes = YouDianUtils.getCheckFieldBytes(concat);
|
||||
return Bytes.concat(concat, checksumBytes);
|
||||
}
|
||||
|
||||
public SpecificData getSpecificData() {
|
||||
@@ -102,5 +120,46 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage {
|
||||
byte maxFullChargePowerCheckTimeBytes = dataBytes[37];
|
||||
this.maxFullChargePowerCheckTime = BytesUtil.bcd2StrLittle(new byte[]{maxFullChargePowerCheckTimeBytes});
|
||||
}
|
||||
|
||||
// 获取字节数组
|
||||
public byte[] getBytes() {
|
||||
// 费率模式
|
||||
byte[] rateModeBytes = BytesUtil.str2Bcd(rateMode);
|
||||
// 余额/有效期
|
||||
byte[] balanceOrValidityBytes = BytesUtil.str2Bcd(balanceOrValidity);
|
||||
// 端口号
|
||||
byte[] portNumberBytes = BytesUtil.str2Bcd(portNumber);
|
||||
// 充电命令
|
||||
byte[] chargeCommandBytes = BytesUtil.str2Bcd(chargeCommand);
|
||||
// 充电时长/电量
|
||||
byte[] chargeDurationOrPowerBytes = BytesUtil.str2Bcd(chargeDurationOrPower);
|
||||
// 订单编号
|
||||
byte[] orderNumberBytes = BytesUtil.str2Bcd(orderNumber);
|
||||
// 最大充电时长
|
||||
byte[] maxChargeDurationBytes = BytesUtil.str2Bcd(maxChargeDuration);
|
||||
// 过载功率
|
||||
byte[] overloadPowerBytes = BytesUtil.str2Bcd(overloadPower);
|
||||
// 二维码灯
|
||||
byte[] qrCodeLightBytes = BytesUtil.str2Bcd(qrCodeLight);
|
||||
// 长充模式
|
||||
byte[] longChargeModeBytes = BytesUtil.str2Bcd(longChargeMode);
|
||||
// 额外浮充时间
|
||||
byte[] extraFloatChargeTimeBytes = BytesUtil.str2Bcd(extraFloatChargeTime);
|
||||
// 是否跳过短路检测
|
||||
byte[] skipShortCircuitDetectionBytes = BytesUtil.str2Bcd(skipShortCircuitDetection);
|
||||
// 不判断用户拔出
|
||||
byte[] noUserPullOutCheckBytes = BytesUtil.str2Bcd(noUserPullOutCheck);
|
||||
// 强制带充满自停
|
||||
byte[] forceAutoStopWhenFullBytes = BytesUtil.str2Bcd(forceAutoStopWhenFull);
|
||||
// 充满功率
|
||||
byte[] fullChargePowerBytes = BytesUtil.str2Bcd(fullChargePower);
|
||||
// 最大充满功率最长判断时间
|
||||
byte[] maxFullChargePowerCheckTimeBytes = BytesUtil.str2Bcd(maxFullChargePowerCheckTime);
|
||||
return Bytes.concat(rateModeBytes, balanceOrValidityBytes, portNumberBytes, chargeCommandBytes,
|
||||
chargeDurationOrPowerBytes, orderNumberBytes, maxChargeDurationBytes, overloadPowerBytes,
|
||||
qrCodeLightBytes, longChargeModeBytes, extraFloatChargeTimeBytes, skipShortCircuitDetectionBytes,
|
||||
noUserPullOutCheckBytes, forceAutoStopWhenFullBytes, fullChargePowerBytes,
|
||||
maxFullChargePowerCheckTimeBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,34 @@
|
||||
package com.jsowell.pile.service.impl;
|
||||
|
||||
import com.jsowell.common.enums.ykc.PileChannelEntity;
|
||||
import com.jsowell.common.util.BytesUtil;
|
||||
import com.jsowell.pile.domain.ebike.AbsEBikeMessage;
|
||||
import com.jsowell.pile.service.EBikeSendCommandService;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class EBikeSendCommandServiceImpl implements EBikeSendCommandService {
|
||||
@Override
|
||||
public void send(String pileSn, AbsEBikeMessage msg) {
|
||||
// 获取桩的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);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user