update 电单车协议

This commit is contained in:
Guoqs
2024-09-18 16:44:24 +08:00
parent 502488166c
commit c0e981cdb8
12 changed files with 88 additions and 41 deletions

View File

@@ -13,8 +13,8 @@ import com.jsowell.common.util.DateUtils;
import com.jsowell.pile.domain.AdapayMemberAccount; import com.jsowell.pile.domain.AdapayMemberAccount;
import com.jsowell.pile.domain.MemberPlateNumberRelation; import com.jsowell.pile.domain.MemberPlateNumberRelation;
import com.jsowell.pile.domain.OrderBasicInfo; import com.jsowell.pile.domain.OrderBasicInfo;
import com.jsowell.pile.domain.ykcCommond.EBikeStartChargingCommand;
import com.jsowell.pile.domain.ykcCommond.ReservationChargingCommand; import com.jsowell.pile.domain.ykcCommond.ReservationChargingCommand;
import com.jsowell.pile.domain.ykcCommond.StartChargingCommand;
import com.jsowell.pile.domain.ykcCommond.StopChargingCommand; import com.jsowell.pile.domain.ykcCommond.StopChargingCommand;
import com.jsowell.pile.dto.*; import com.jsowell.pile.dto.*;
import com.jsowell.pile.service.*; import com.jsowell.pile.service.*;
@@ -85,11 +85,11 @@ public class TempController extends BaseController {
public RestApiResponse<?> tempStartCharging(@RequestBody QueryOrderDTO dto) { public RestApiResponse<?> tempStartCharging(@RequestBody QueryOrderDTO dto) {
RestApiResponse<?> response = null; RestApiResponse<?> response = null;
try { try {
StartChargingCommand command = StartChargingCommand.builder() EBikeStartChargingCommand command = new EBikeStartChargingCommand();
.pileSn(dto.getPileSn()) command.setPileSn(dto.getPileSn());
.connectorCode(dto.getConnectorCode()) command.setConnectorCode(dto.getConnectorCode());
.chargeAmount(new BigDecimal("1")) command.setChargeAmount(new BigDecimal("1"));
.build();
eBikeSendCommandService.sendStartChargingCommand(command); eBikeSendCommandService.sendStartChargingCommand(command);
response = new RestApiResponse<>(); response = new RestApiResponse<>();
} catch (Exception e) { } catch (Exception e) {

View File

@@ -65,7 +65,7 @@ public class PowerHeartbeatHandler extends AbstractEBikeHandler {
// 组装数据 // 组装数据
RealTimeMonitorData realTimeMonitorData = new RealTimeMonitorData(); RealTimeMonitorData realTimeMonitorData = new RealTimeMonitorData();
realTimeMonitorData.setPileSn(message.getPhysicalId() + ""); realTimeMonitorData.setPileSn(message.getPhysicalId() + "");
realTimeMonitorData.setConnectorCode(message.getPort()); realTimeMonitorData.setConnectorCode(message.getConnectorCode());
realTimeMonitorData.setPileConnectorCode(realTimeMonitorData.getPileSn() + realTimeMonitorData.getConnectorCode()); realTimeMonitorData.setPileConnectorCode(realTimeMonitorData.getPileSn() + realTimeMonitorData.getConnectorCode());
realTimeMonitorData.setTransactionCode(message.getOrderCode()); realTimeMonitorData.setTransactionCode(message.getOrderCode());
realTimeMonitorData.setConnectorStatus(message.getPortStatus()); realTimeMonitorData.setConnectorStatus(message.getPortStatus());
@@ -83,7 +83,7 @@ public class PowerHeartbeatHandler extends AbstractEBikeHandler {
*/ */
private void updatePileStatus(EBikeMessageCmd06 message) { private void updatePileStatus(EBikeMessageCmd06 message) {
String pileSn = message.getPhysicalId() + ""; String pileSn = message.getPhysicalId() + "";
String connectorCode = message.getPort(); String connectorCode = message.getConnectorCode();
String portStatus = message.getPortStatus(); String portStatus = message.getPortStatus();
pileConnectorInfoService.updateConnectorStatus(pileSn + connectorCode, PortStatusEnum.eBikeStatusTransformDBStatus(portStatus)); pileConnectorInfoService.updateConnectorStatus(pileSn + connectorCode, PortStatusEnum.eBikeStatusTransformDBStatus(portStatus));
} }

View File

@@ -26,7 +26,7 @@ public class EBikeMessageCmd02 extends AbsEBikeMessage2 {
/** /**
* 端口号 * 端口号
*/ */
private String portNumber; private String connectorCode;
/** /**
* 余额卡内金额 * 余额卡内金额
@@ -61,7 +61,7 @@ public class EBikeMessageCmd02 extends AbsEBikeMessage2 {
startIndex += length; startIndex += length;
length = 1; length = 1;
this.portNumber = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length)) + ""; this.connectorCode = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length)) + "";
startIndex += length; startIndex += length;
length = 2; length = 2;

View File

@@ -14,7 +14,7 @@ public class EBikeMessageCmd03 extends AbsEBikeMessage2 {
private int chargingTime; // 充电时长, 单位:"秒" private int chargingTime; // 充电时长, 单位:"秒"
private int maxPower; // 最大功率, 单位:"0.1W" private int maxPower; // 最大功率, 单位:"0.1W"
private int consumedEnergy; // 耗电量, 单位:"0.01度" private int consumedEnergy; // 耗电量, 单位:"0.01度"
private String portNumber; // 端口号 private String connectorCode; // 端口号
private int startMode; // 在线/离线启动/验证码 private int startMode; // 在线/离线启动/验证码
private int cardNumberOrVerificationCode; // 卡号/验证码 private int cardNumberOrVerificationCode; // 卡号/验证码
private int stopReason; // 停止原因 private int stopReason; // 停止原因
@@ -40,7 +40,7 @@ public class EBikeMessageCmd03 extends AbsEBikeMessage2 {
startIndex += length; startIndex += length;
length = 1; length = 1;
this.portNumber = YouDianUtils.convertPortNumberToString(BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length))); this.connectorCode = YouDianUtils.convertPortNumberToString(BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length)));
startIndex += length; startIndex += length;
length = 1; length = 1;

View File

@@ -13,7 +13,7 @@ public class EBikeMessageCmd04 extends AbsEBikeMessage2 {
/** /**
* 端口号 * 端口号
*/ */
private String portNumber; private String connectorCode;
/** /**
* 在线/离线启动 * 在线/离线启动
@@ -40,7 +40,7 @@ public class EBikeMessageCmd04 extends AbsEBikeMessage2 {
int startIndex = 12; int startIndex = 12;
int length = 1; int length = 1;
this.portNumber = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length)) + ""; this.connectorCode = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length)) + "";
startIndex += length; startIndex += length;
length = 1; length = 1;

View File

@@ -16,7 +16,7 @@ public class EBikeMessageCmd06 extends AbsEBikeMessage2 {
/** /**
* 端口号当前充电的端口号。注00表示1号端口01表示2号端口; port+1为实际端口 * 端口号当前充电的端口号。注00表示1号端口01表示2号端口; port+1为实际端口
*/ */
private String port; private String connectorCode;
/** /**
* 各端口状态: 1=充电中, 2=已扫码暂未检测到功率等待插入充电器充电柜专有如单车桩出现此值为出错值请忽略3=有充电器但未充电已充满电5=浮充,其他值=出错值请忽略 * 各端口状态: 1=充电中, 2=已扫码暂未检测到功率等待插入充电器充电柜专有如单车桩出现此值为出错值请忽略3=有充电器但未充电已充满电5=浮充,其他值=出错值请忽略
@@ -108,7 +108,7 @@ public class EBikeMessageCmd06 extends AbsEBikeMessage2 {
int startIndex = 12; int startIndex = 12;
int length = 1; int length = 1;
this.port = YouDianUtils.convertPortNumberToString(BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length))); this.connectorCode = YouDianUtils.convertPortNumberToString(BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length)));
startIndex += length; startIndex += length;
length = 1; length = 1;

View File

@@ -2,12 +2,12 @@ package com.jsowell.pile.domain.ebike.serversend;
import com.google.common.primitives.Bytes; import com.google.common.primitives.Bytes;
import com.jsowell.common.YouDianUtils; import com.jsowell.common.YouDianUtils;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.util.BytesUtil; import com.jsowell.common.util.BytesUtil;
import com.jsowell.pile.domain.ebike.AbsEBikeMessage2; import com.jsowell.pile.domain.ebike.AbsEBikeMessage2;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.apache.avro.specific.SpecificData;
/** /**
* 服务器开始、停止充电操作82指令 * 服务器开始、停止充电操作82指令
@@ -17,8 +17,6 @@ import org.apache.avro.specific.SpecificData;
@AllArgsConstructor @AllArgsConstructor
public class EBikeMessageCmd82 extends AbsEBikeMessage2 { public class EBikeMessageCmd82 extends AbsEBikeMessage2 {
private SpecificData data;
// 费率模式:=0计时=1包月=2计量=3计次。包月、计次默认充满自停计时、计量可手动设置时长和电量 // 费率模式:=0计时=1包月=2计量=3计次。包月、计次默认充满自停计时、计量可手动设置时长和电量
private int rateMode; // 费率模式 (1字节) private int rateMode; // 费率模式 (1字节)
@@ -26,7 +24,7 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage2 {
private int balanceOrValidity; // 余额/有效期 (4字节) private int balanceOrValidity; // 余额/有效期 (4字节)
// 端口号指充电桩的插口号端口号从0开始如0x00-0x0F则代表第1路-第16路0x00=第1路0x09=第十路0x0A=第十一路FF=设备智能选择端口(服务器下发) // 端口号指充电桩的插口号端口号从0开始如0x00-0x0F则代表第1路-第16路0x00=第1路0x09=第十路0x0A=第十一路FF=设备智能选择端口(服务器下发)
private int portNumber; // 端口号 (指实际端口号, 发指令的时候自动转换为桩能识别的byte字节) private String connectorCode; // 端口号 (指实际端口号, 发指令的时候自动转换为桩能识别的byte字节)
// 充电命令=0(停止充电)(远程停止充电需要下发对当前正在充电的订单号,如果订单号对不上则无法远程停止),=1(开始充电)设备充电与否依据此字段 // 充电命令=0(停止充电)(远程停止充电需要下发对当前正在充电的订单号,如果订单号对不上则无法远程停止),=1(开始充电)设备充电与否依据此字段
private int chargeCommand; // 充电命令 (1字节) private int chargeCommand; // 充电命令 (1字节)
@@ -69,7 +67,7 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage2 {
startIndex += length; startIndex += length;
length = 1; length = 1;
this.portNumber = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length)); this.connectorCode = YouDianUtils.convertPortNumberToString(BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length)));
startIndex += length; startIndex += length;
length = 1; length = 1;
@@ -124,14 +122,35 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage2 {
this.maxFullChargePowerCheckTime = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length)); this.maxFullChargePowerCheckTime = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(messageBytes, startIndex, length));
} }
// 获取字节数组 @Override
public byte[] getMessageBytes() { public byte[] getMessageBytes() {
// 包头
byte[] headerBytes = BytesUtil.stringToHexBytes(Constants.EBIKE_HEADER, 3);
// 物理ID
byte[] physicalIdBytes = YouDianUtils.getPhysicalIdBytes(physicalId);
// 消息ID
byte[] messageIdBytes = BytesUtil.intToBytesLittle(messageId, 2);
// 命令
byte[] commandBytes = new byte[]{(byte) 0x82};
// 数据
byte[] dataBytes = this.getBytes();
// 长度 物理ID+消息ID+命令+数据(n) +校验(2)每包最多256字节
byte[] lengthBytes = BytesUtil.intToBytesLittle(9 + dataBytes.length);
// 拼接
byte[] concat = Bytes.concat(headerBytes, lengthBytes, physicalIdBytes, messageIdBytes, commandBytes, dataBytes);
// 校验和
byte[] checksumBytes = YouDianUtils.getCheckFieldBytes(concat);
return Bytes.concat(concat, checksumBytes);
}
// 获取字节数组
public byte[] getBytes() {
// 费率模式 // 费率模式
byte[] rateModeBytes = BytesUtil.intToBytesLittle(rateMode, 1); byte[] rateModeBytes = BytesUtil.intToBytesLittle(rateMode, 1);
// 余额/有效期 // 余额/有效期
byte[] balanceOrValidityBytes = BytesUtil.intToBytesLittle(balanceOrValidity, 4); byte[] balanceOrValidityBytes = BytesUtil.intToBytesLittle(balanceOrValidity, 4);
// 端口号 // 端口号
byte[] portNumberBytes = YouDianUtils.convertPortNumberToBytes(portNumber); byte[] connectorCodeBytes = YouDianUtils.convertPortNumberToBytes(Integer.parseInt(connectorCode));
// 充电命令 // 充电命令
byte[] chargeCommandBytes = BytesUtil.intToBytesLittle(chargeCommand, 1); byte[] chargeCommandBytes = BytesUtil.intToBytesLittle(chargeCommand, 1);
// 充电时长/电量 // 充电时长/电量
@@ -158,7 +177,7 @@ public class EBikeMessageCmd82 extends AbsEBikeMessage2 {
// byte[] fullChargePowerBytes = BytesUtil.stringToHexBytes(fullChargePower, 1); // byte[] fullChargePowerBytes = BytesUtil.stringToHexBytes(fullChargePower, 1);
// 最大充满功率最长判断时间 // 最大充满功率最长判断时间
// byte[] maxFullChargePowerCheckTimeBytes = BytesUtil.stringToHexBytes(maxFullChargePowerCheckTime, 1); // byte[] maxFullChargePowerCheckTimeBytes = BytesUtil.stringToHexBytes(maxFullChargePowerCheckTime, 1);
return Bytes.concat(rateModeBytes, balanceOrValidityBytes, portNumberBytes, chargeCommandBytes, return Bytes.concat(rateModeBytes, balanceOrValidityBytes, connectorCodeBytes, chargeCommandBytes,
chargeDurationOrPowerBytes, orderNumberBytes, maxChargeDurationBytes, overloadPowerBytes chargeDurationOrPowerBytes, orderNumberBytes, maxChargeDurationBytes, overloadPowerBytes
// , qrCodeLightBytes, longChargeModeBytes, extraFloatChargeTimeBytes // , qrCodeLightBytes, longChargeModeBytes, extraFloatChargeTimeBytes
// , skipShortCircuitDetectionBytes, noUserPullOutCheckBytes, forceAutoStopWhenFullBytes // , skipShortCircuitDetectionBytes, noUserPullOutCheckBytes, forceAutoStopWhenFullBytes

View File

@@ -0,0 +1,28 @@
package com.jsowell.pile.domain.ykcCommond;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* 启动充电指令
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper=false)
@SuperBuilder
public class EBikeStartChargingCommand extends StartChargingCommand{
/**
* 费率模式
*/
private int rateMode;
/**
* 余额或者有效期
*/
private int balanceOrValidity;
}

View File

@@ -1,9 +1,9 @@
package com.jsowell.pile.domain.ykcCommond; package com.jsowell.pile.domain.ykcCommond;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -13,7 +13,7 @@ import java.math.BigDecimal;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Builder @SuperBuilder
public class StartChargingCommand { public class StartChargingCommand {
/** /**
* 交易流水号 * 交易流水号

View File

@@ -1,7 +1,7 @@
package com.jsowell.pile.service; package com.jsowell.pile.service;
import com.jsowell.pile.domain.ebike.deviceupload.ChargingOperationResponse; import com.jsowell.pile.domain.ebike.deviceupload.ChargingOperationResponse;
import com.jsowell.pile.domain.ykcCommond.StartChargingCommand; import com.jsowell.pile.domain.ykcCommond.EBikeStartChargingCommand;
import com.jsowell.pile.domain.ykcCommond.StopChargingCommand; import com.jsowell.pile.domain.ykcCommond.StopChargingCommand;
/** /**
@@ -13,7 +13,7 @@ public interface EBikeSendCommandService {
* 启动充电 * 启动充电
* @param command * @param command
*/ */
ChargingOperationResponse sendStartChargingCommand(StartChargingCommand command) throws Exception; ChargingOperationResponse sendStartChargingCommand(EBikeStartChargingCommand command) throws Exception;
/** /**
* 停止充电 * 停止充电

View File

@@ -122,12 +122,12 @@ public class PileRemoteService {
return; return;
} }
log.info("【=====平台下发指令=====】: 电单车远程启动充电, 桩号:{}, 枪口号:{}", pileSn, connectorCode); log.info("【=====平台下发指令=====】: 电单车远程启动充电, 桩号:{}, 枪口号:{}", pileSn, connectorCode);
StartChargingCommand startChargingCommand = StartChargingCommand.builder() EBikeStartChargingCommand startChargingCommand = new EBikeStartChargingCommand();
.pileSn(pileSn) startChargingCommand.setPileSn(pileSn);
.connectorCode(connectorCode) startChargingCommand.setConnectorCode(connectorCode);
.transactionCode(transactionCode) startChargingCommand.setTransactionCode(transactionCode);
.chargeAmount(chargeAmount) startChargingCommand.setChargeAmount(chargeAmount);
.build();
try { try {
ChargingOperationResponse startChargingResponse = eBikeSendCommandService.sendStartChargingCommand(startChargingCommand); ChargingOperationResponse startChargingResponse = eBikeSendCommandService.sendStartChargingCommand(startChargingCommand);
log.info("StartChargingResponse:{}", JSON.toJSONString(startChargingResponse)); log.info("StartChargingResponse:{}", JSON.toJSONString(startChargingResponse));

View File

@@ -7,7 +7,7 @@ import com.jsowell.common.util.id.IdUtils;
import com.jsowell.pile.domain.ebike.AbsEBikeMessage2; import com.jsowell.pile.domain.ebike.AbsEBikeMessage2;
import com.jsowell.pile.domain.ebike.deviceupload.ChargingOperationResponse; import com.jsowell.pile.domain.ebike.deviceupload.ChargingOperationResponse;
import com.jsowell.pile.domain.ebike.serversend.EBikeMessageCmd82; import com.jsowell.pile.domain.ebike.serversend.EBikeMessageCmd82;
import com.jsowell.pile.domain.ykcCommond.StartChargingCommand; import com.jsowell.pile.domain.ykcCommond.EBikeStartChargingCommand;
import com.jsowell.pile.domain.ykcCommond.StopChargingCommand; import com.jsowell.pile.domain.ykcCommond.StopChargingCommand;
import com.jsowell.pile.service.EBikeSendCommandService; import com.jsowell.pile.service.EBikeSendCommandService;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
@@ -32,7 +32,7 @@ public class EBikeSendCommandServiceImpl implements EBikeSendCommandService {
* 电单车发送启动充电指令 * 电单车发送启动充电指令
*/ */
@Override @Override
public ChargingOperationResponse sendStartChargingCommand(StartChargingCommand command) throws Exception { public ChargingOperationResponse sendStartChargingCommand(EBikeStartChargingCommand command) throws Exception {
String pileSn = command.getPileSn(); String pileSn = command.getPileSn();
String connectorCode = command.getConnectorCode(); String connectorCode = command.getConnectorCode();
String transactionCode = command.getTransactionCode(); String transactionCode = command.getTransactionCode();
@@ -47,12 +47,12 @@ public class EBikeSendCommandServiceImpl implements EBikeSendCommandService {
message.setCommand("82"); message.setCommand("82");
// 充电模式 // 充电模式
message.setRateMode(3); message.setRateMode(command.getRateMode());
// 余额(分)或有效期 // 余额(分)或有效期
int balance = command.getChargeAmount().multiply(new BigDecimal("100")).intValue(); int balance = command.getChargeAmount().multiply(new BigDecimal("100")).intValue();
message.setBalanceOrValidity(balance); message.setBalanceOrValidity(balance);
// 端口号 // 端口号
message.setPortNumber(Integer.parseInt(connectorCode)); message.setConnectorCode(connectorCode);
// 充电命令 // 充电命令
message.setChargeCommand(1); message.setChargeCommand(1);
// 充电时长/功率 // 充电时长/功率
@@ -96,11 +96,11 @@ public class EBikeSendCommandServiceImpl implements EBikeSendCommandService {
message.setCommand("82"); message.setCommand("82");
// 充电模式 // 充电模式
message.setRateMode(3); message.setRateMode(2);
// 余额或有效期 // 余额或有效期
message.setBalanceOrValidity(1234); message.setBalanceOrValidity(1000);
// 端口号 // 端口号
message.setPortNumber(Integer.parseInt(connectorCode)); message.setConnectorCode(connectorCode);
// 充电命令 // 充电命令
message.setChargeCommand(0); message.setChargeCommand(0);
// 充电时长/功率 // 充电时长/功率