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:
@@ -14,6 +14,7 @@ import com.jsowell.pile.domain.AdapayMemberAccount;
|
||||
import com.jsowell.pile.domain.MemberPlateNumberRelation;
|
||||
import com.jsowell.pile.domain.OrderBasicInfo;
|
||||
import com.jsowell.pile.domain.ykcCommond.ReservationChargingCommand;
|
||||
import com.jsowell.pile.domain.ykcCommond.StartChargingCommand;
|
||||
import com.jsowell.pile.dto.*;
|
||||
import com.jsowell.pile.service.*;
|
||||
import com.jsowell.pile.service.programlogic.AbstractProgramLogic;
|
||||
@@ -83,7 +84,11 @@ public class TempController extends BaseController {
|
||||
public RestApiResponse<?> tempStartCharging(@RequestBody QueryOrderDTO dto) {
|
||||
RestApiResponse<?> response = null;
|
||||
try {
|
||||
eBikeSendCommandService.startCharging(dto.getPileSn(), dto.getConnectorCode());
|
||||
StartChargingCommand command = StartChargingCommand.builder()
|
||||
.pileSn(dto.getPileSn())
|
||||
.connectorCode(dto.getConnectorCode())
|
||||
.build();
|
||||
eBikeSendCommandService.sendStartChargingCommand(command);
|
||||
response = new RestApiResponse<>();
|
||||
} catch (Exception e) {
|
||||
logger.error("电单车开始充电 error", e);
|
||||
|
||||
@@ -10,6 +10,8 @@ import java.math.BigDecimal;
|
||||
* @author jsowell
|
||||
*/
|
||||
public class Constants {
|
||||
// 电单车协议包头
|
||||
public static final String EBIKE_HEADER = "DNY";
|
||||
|
||||
// 十六进制前缀
|
||||
public static final String HEX_PREFIX = "0x";
|
||||
|
||||
@@ -380,7 +380,7 @@ public class BytesUtil {
|
||||
// int i = BytesUtil.bytesToIntLittle(length);
|
||||
// System.out.println(i);
|
||||
|
||||
String testStr = "DNY";
|
||||
String testStr = Constants.EBIKE_HEADER;
|
||||
byte[] hexBytes = stringToHexBytes(testStr, 3);
|
||||
System.out.println("Hex Bytes: " + bytesToHex(hexBytes));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.jsowell.netty.decoder;
|
||||
|
||||
import com.jsowell.common.constant.Constants;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
@@ -47,7 +48,7 @@ public class StartAndLengthFieldFrameDecoder extends ByteToMessageDecoder {
|
||||
buffer.getBytes(beginReader, headerBytes, 0, HEADER_LENGTH_DNY);
|
||||
String header = new String(headerBytes, StandardCharsets.UTF_8);
|
||||
// log.info("检查包头是否是DNY, header:{}", header);
|
||||
if ("DNY".equals(header)) {
|
||||
if (Constants.EBIKE_HEADER.equals(header)) {
|
||||
// 处理 DNY 协议
|
||||
decodeDnyMessage(buffer, out, beginReader);
|
||||
return;
|
||||
@@ -73,7 +74,7 @@ public class StartAndLengthFieldFrameDecoder extends ByteToMessageDecoder {
|
||||
byte[] headerBytes = new byte[HEADER_LENGTH_DNY];
|
||||
buffer.getBytes(beginReader, headerBytes, 0, HEADER_LENGTH_DNY);
|
||||
String header = new String(headerBytes, StandardCharsets.UTF_8);
|
||||
return "DNY".equals(header);
|
||||
return Constants.EBIKE_HEADER.equals(header);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.jsowell.pile.domain.ebike.serversend;
|
||||
|
||||
import com.google.common.primitives.Bytes;
|
||||
import com.jsowell.common.YouDianUtils;
|
||||
import com.jsowell.common.constant.Constants;
|
||||
import com.jsowell.common.util.BytesUtil;
|
||||
import com.jsowell.pile.domain.ebike.AbsEBikeMessage;
|
||||
import lombok.*;
|
||||
@@ -35,7 +36,7 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage {
|
||||
@Override
|
||||
public byte[] getMessageBytes() {
|
||||
// 包头
|
||||
byte[] headerBytes = BytesUtil.stringToHexBytes(header, 3);
|
||||
byte[] headerBytes = BytesUtil.stringToHexBytes(Constants.EBIKE_HEADER, 3);
|
||||
// 物理ID
|
||||
byte[] physicalIdBytes = YouDianUtils.getPhysicalIdBytes(physicalId);
|
||||
// 消息ID
|
||||
@@ -75,13 +76,13 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage {
|
||||
private int chargeCommand; // 充电命令 (1字节)
|
||||
|
||||
// 告知设备的充电时长/电量, 如是0x0000则说明是充满自停, 其他数值则按照时长/电量充电, 且充满不会自停,
|
||||
private int chargeDurationOrPower; // 充电时长/电量 (2字节)
|
||||
private int chargeTimeOrPower; // 充电时长/电量 (2字节)
|
||||
|
||||
// 生成给桩的交易流水号, 桩协议叫订单编号
|
||||
private String transactionCode; // 订单编号 (16字节)
|
||||
|
||||
// 最大充电时长、过载功率:(只对当前端口当前订单有效,不影响其他端口)动态设置此参数,如果参数为0表示不修改,会使用设备的设置值,默认10小时
|
||||
private int maxChargeDuration; // 最大充电时长 (2字节)
|
||||
private int maxChargeTime; // 最大充电时长 (2字节)
|
||||
private int overloadPower; // 过载功率 (2字节)
|
||||
|
||||
// 二维码灯:0=打开,1=关闭,针对部分有二维码灯的设备有效。此设置是针对下一次插头插入时是否点亮二维码背光灯,保存在内存中,断电重启后就会失效
|
||||
@@ -112,13 +113,13 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage {
|
||||
this.chargeCommand = BytesUtil.bytesToIntLittle(new byte[]{chargeCommandBytes});
|
||||
|
||||
byte[] chargeDurationOrPowerBytes = Arrays.copyOfRange(dataBytes, 7, 9);
|
||||
this.chargeDurationOrPower = BytesUtil.bytesToIntLittle(chargeDurationOrPowerBytes);
|
||||
this.chargeTimeOrPower = BytesUtil.bytesToIntLittle(chargeDurationOrPowerBytes);
|
||||
|
||||
byte[] orderNumberBytes = Arrays.copyOfRange(dataBytes, 9, 25);
|
||||
this.transactionCode = BytesUtil.bcd2StrLittle(orderNumberBytes);
|
||||
|
||||
byte[] maxChargeDurationBytes = Arrays.copyOfRange(dataBytes, 25, 27);
|
||||
this.maxChargeDuration = BytesUtil.bytesToIntLittle(maxChargeDurationBytes);
|
||||
this.maxChargeTime = BytesUtil.bytesToIntLittle(maxChargeDurationBytes);
|
||||
|
||||
byte[] overloadPowerBytes = Arrays.copyOfRange(dataBytes, 27, 29);
|
||||
this.overloadPower = BytesUtil.bytesToIntLittle(overloadPowerBytes);
|
||||
@@ -159,11 +160,11 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage {
|
||||
// 充电命令
|
||||
byte[] chargeCommandBytes = BytesUtil.intToBytesLittle(chargeCommand, 1);
|
||||
// 充电时长/电量
|
||||
byte[] chargeDurationOrPowerBytes = BytesUtil.intToBytesLittle(chargeDurationOrPower, 2);
|
||||
byte[] chargeDurationOrPowerBytes = BytesUtil.intToBytesLittle(chargeTimeOrPower, 2);
|
||||
// 订单编号
|
||||
byte[] orderNumberBytes = BytesUtil.ensureLength(BytesUtil.str2Bcd(transactionCode), 16);
|
||||
// 最大充电时长
|
||||
byte[] maxChargeDurationBytes = BytesUtil.intToBytesLittle(maxChargeDuration, 2);
|
||||
byte[] maxChargeDurationBytes = BytesUtil.intToBytesLittle(maxChargeTime, 2);
|
||||
// 过载功率
|
||||
byte[] overloadPowerBytes = BytesUtil.intToBytesLittle(overloadPower, 2);
|
||||
// 二维码灯
|
||||
|
||||
@@ -15,4 +15,9 @@ import lombok.NoArgsConstructor;
|
||||
public class StopChargingCommand {
|
||||
private String pileSn;
|
||||
private String connectorCode;
|
||||
|
||||
/**
|
||||
* 交易流水号
|
||||
*/
|
||||
private String transactionCode;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
package com.jsowell.pile.service;
|
||||
|
||||
import com.jsowell.pile.domain.ykcCommond.StartChargingCommand;
|
||||
import com.jsowell.pile.domain.ykcCommond.StopChargingCommand;
|
||||
|
||||
/**
|
||||
* 电单车发送命令服务
|
||||
*/
|
||||
public interface EBikeSendCommandService {
|
||||
// void send(String pileSn, AbsEBikeMessage msg);
|
||||
|
||||
void startCharging(String pileSn, String connectorCode);
|
||||
/**
|
||||
* 启动充电
|
||||
* @param command
|
||||
*/
|
||||
void sendStartChargingCommand(StartChargingCommand command);
|
||||
|
||||
/**
|
||||
* 停止充电
|
||||
* @param command
|
||||
*/
|
||||
void sendStopChargingCommand(StopChargingCommand command);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,9 +3,12 @@ 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.common.util.StringUtils;
|
||||
import com.jsowell.common.util.id.IdUtils;
|
||||
import com.jsowell.pile.domain.ebike.AbsEBikeMessage;
|
||||
import com.jsowell.pile.domain.ebike.serversend.EBikeMessageCmd82;
|
||||
import com.jsowell.pile.domain.ykcCommond.StartChargingCommand;
|
||||
import com.jsowell.pile.domain.ykcCommond.StopChargingCommand;
|
||||
import com.jsowell.pile.service.EBikeSendCommandService;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
@@ -20,15 +23,23 @@ import java.util.Objects;
|
||||
@Service
|
||||
public class EBikeSendCommandServiceImpl implements EBikeSendCommandService {
|
||||
|
||||
// 过载功率, 单位0.1W, 2450 * 0.1 = 2450W
|
||||
private final int OVER_LOAD_POWER = 2450;
|
||||
|
||||
/**
|
||||
* 电单车发送启动充电指令
|
||||
* @param pileSn 电单车桩号
|
||||
* @param connectorCode 枪口号
|
||||
*/
|
||||
@Override
|
||||
public void startCharging(String pileSn, String connectorCode) {
|
||||
public void sendStartChargingCommand(StartChargingCommand command) {
|
||||
String pileSn = command.getPileSn();
|
||||
String connectorCode = command.getConnectorCode();
|
||||
String transactionCode = command.getTransactionCode();
|
||||
if (StringUtils.isBlank(transactionCode)) {
|
||||
transactionCode = IdUtils.generateTransactionCode(pileSn, connectorCode);
|
||||
}
|
||||
|
||||
// 组装参数
|
||||
EBikeMessageCmd82 message = new EBikeMessageCmd82();
|
||||
message.setHeader("DNY");
|
||||
message.setPhysicalId(Integer.parseInt(pileSn));
|
||||
message.setMessageId(RandomUtil.getRandomNumber(4));
|
||||
message.setCommand("82");
|
||||
@@ -44,16 +55,63 @@ public class EBikeSendCommandServiceImpl implements EBikeSendCommandService {
|
||||
data.setChargeCommand(1);
|
||||
// 充电时长/功率
|
||||
int chargeDurationOrPower = 0;
|
||||
data.setChargeDurationOrPower(chargeDurationOrPower);
|
||||
data.setChargeTimeOrPower(chargeDurationOrPower);
|
||||
|
||||
// 订单编号
|
||||
String transactionCode = IdUtils.generateTransactionCode(pileSn, connectorCode);
|
||||
data.setTransactionCode(transactionCode);
|
||||
|
||||
// 最大充电时长
|
||||
data.setMaxChargeDuration(0);
|
||||
data.setMaxChargeTime(0);
|
||||
// 过载功率
|
||||
data.setOverloadPower(3000);
|
||||
data.setOverloadPower(OVER_LOAD_POWER);
|
||||
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 command
|
||||
*/
|
||||
@Override
|
||||
public void sendStopChargingCommand(StopChargingCommand command) {
|
||||
String pileSn = command.getPileSn();
|
||||
String connectorCode = command.getConnectorCode();
|
||||
String transactionCode = command.getTransactionCode();
|
||||
|
||||
// 组装参数
|
||||
EBikeMessageCmd82 message = new EBikeMessageCmd82();
|
||||
message.setPhysicalId(Integer.parseInt(pileSn));
|
||||
message.setMessageId(RandomUtil.getRandomNumber(4));
|
||||
message.setCommand("82");
|
||||
|
||||
EBikeMessageCmd82.SpecificData data = new EBikeMessageCmd82.SpecificData();
|
||||
// 充电模式
|
||||
data.setRateMode(3);
|
||||
// 余额或有效期
|
||||
data.setBalanceOrValidity(1234);
|
||||
// 端口号
|
||||
data.setPortNumber(Integer.parseInt(connectorCode));
|
||||
// 充电命令
|
||||
data.setChargeCommand(0);
|
||||
// 充电时长/功率
|
||||
int chargeDurationOrPower = 0;
|
||||
data.setChargeTimeOrPower(chargeDurationOrPower);
|
||||
|
||||
// 订单编号
|
||||
data.setTransactionCode(transactionCode);
|
||||
|
||||
// 最大充电时长
|
||||
data.setMaxChargeTime(0);
|
||||
// 过载功率
|
||||
data.setOverloadPower(OVER_LOAD_POWER);
|
||||
data.setQrCodeLight(0);
|
||||
data.setLongChargeMode(0);
|
||||
data.setExtraFloatChargeTime(0);
|
||||
|
||||
@@ -281,6 +281,7 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
log.info("【=====平台下发充电指令=====】:订单id:{}, 桩号:{}, 枪口号:{}, 逻辑卡号:{}, 物理卡号:{}, 账户余额:{}",
|
||||
transactionCode, pileSn, BytesUtil.bcd2Str(connectorCodeByteArr), logicCardNum, physicsCardNum, chargeAmount);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user