mirror of
https://gitee.com/san-bing/JChargePointProtocol
synced 2026-05-04 18:09:54 +08:00
* !44 comment * !39 添加下行日志打印 * !36 扩展计价领域模型 * !35 webui 初步成型 * !34 webui 初步成型
This commit is contained in:
@@ -10,6 +10,7 @@ package sanbing.jcpp.infrastructure.proto;
|
||||
import sanbing.jcpp.infrastructure.proto.model.PricingModel;
|
||||
import sanbing.jcpp.infrastructure.proto.model.PricingModel.FlagPrice;
|
||||
import sanbing.jcpp.infrastructure.proto.model.PricingModel.Period;
|
||||
import sanbing.jcpp.infrastructure.proto.model.PricingModel.TimePeriodItem;
|
||||
import sanbing.jcpp.infrastructure.util.trace.Tracer;
|
||||
import sanbing.jcpp.infrastructure.util.trace.TracerContextUtil;
|
||||
import sanbing.jcpp.proto.gen.ProtocolProto.*;
|
||||
@@ -17,7 +18,7 @@ import sanbing.jcpp.proto.gen.ProtocolProto.*;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author baigod
|
||||
* @author 九筒
|
||||
*/
|
||||
public class ProtoConverter {
|
||||
|
||||
@@ -30,39 +31,109 @@ public class ProtoConverter {
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将业务层PricingModel转换为Protobuf格式
|
||||
* 根据计费规则自动选择对应的价格配置结构
|
||||
*/
|
||||
public static PricingModelProto toPricingModel(PricingModel pricingModel) {
|
||||
// 创建 PricingModelProto 实例
|
||||
PricingModelProto.Builder builder = PricingModelProto.newBuilder();
|
||||
|
||||
// 设置字段
|
||||
// 设置基本信息
|
||||
builder.setType(PricingModelType.valueOf(pricingModel.getType().name()));
|
||||
builder.setRule(PricingModelRule.valueOf(pricingModel.getRule().name()));
|
||||
builder.setStandardElec(pricingModel.getStandardElec().toPlainString());
|
||||
builder.setStandardServ(pricingModel.getStandardServ().toPlainString());
|
||||
|
||||
// 转换 flagPriceList
|
||||
for (Map.Entry<PricingModelFlag, FlagPrice> entry : pricingModel.getFlagPriceList().entrySet()) {
|
||||
PricingModelFlag flag = entry.getKey();
|
||||
FlagPrice flagPrice = entry.getValue();
|
||||
// 根据计费规则构建对应的价格配置
|
||||
switch (pricingModel.getRule()) {
|
||||
case STANDARD:
|
||||
// 标准计费:全天统一价格
|
||||
StandardPricingProto standardPricing = StandardPricingProto.newBuilder()
|
||||
.setElecPrice(pricingModel.getStandardElec().toPlainString())
|
||||
.setServPrice(pricingModel.getStandardServ().toPlainString())
|
||||
.build();
|
||||
builder.setStandardPricing(standardPricing);
|
||||
break;
|
||||
|
||||
FlagPriceProto flagPriceProto = FlagPriceProto.newBuilder()
|
||||
.setFlag(PricingModelFlag.valueOf(flag.name())) // 枚举转换
|
||||
.setElec(flagPrice.getElec().toPlainString())
|
||||
.setServ(flagPrice.getServ().toPlainString())
|
||||
.build();
|
||||
case PEAK_VALLEY_PRICING:
|
||||
// 峰谷计价:按电网峰谷政策分时段
|
||||
PeakValleyPricingProto.Builder peakValleyBuilder = PeakValleyPricingProto.newBuilder();
|
||||
|
||||
builder.putFlagPrice(flag.ordinal(), flagPriceProto); // 按 ordinal 值作为 key 存入
|
||||
}
|
||||
// 转换 flagPriceList
|
||||
if (pricingModel.getFlagPriceList() != null) {
|
||||
for (Map.Entry<PricingModelFlag, FlagPrice> entry : pricingModel.getFlagPriceList().entrySet()) {
|
||||
PricingModelFlag flag = entry.getKey();
|
||||
FlagPrice flagPrice = entry.getValue();
|
||||
|
||||
// 转换 PeriodsList
|
||||
for (Period period : pricingModel.getPeriodsList()) {
|
||||
PeriodProto periodProto = PeriodProto.newBuilder()
|
||||
.setSn(period.getSn())
|
||||
.setBegin(period.getBegin().toString()) // 假设 begin 是 LocalTime, 转换为字符串
|
||||
.setEnd(period.getEnd().toString()) // 假设 end 是 LocalTime, 转换为字符串
|
||||
.setFlag(PricingModelFlag.valueOf(period.getFlag().name()))
|
||||
.build();
|
||||
builder.addPeriod(periodProto);
|
||||
FlagPriceProto flagPriceProto = FlagPriceProto.newBuilder()
|
||||
.setFlag(PricingModelFlag.valueOf(flag.name()))
|
||||
.setElec(flagPrice.getElec().toPlainString())
|
||||
.setServ(flagPrice.getServ().toPlainString())
|
||||
.build();
|
||||
|
||||
peakValleyBuilder.putFlagPrice(flag.ordinal(), flagPriceProto);
|
||||
}
|
||||
}
|
||||
|
||||
// 转换 PeriodsList
|
||||
if (pricingModel.getPeriodsList() != null) {
|
||||
for (Period period : pricingModel.getPeriodsList()) {
|
||||
PeriodProto periodProto = PeriodProto.newBuilder()
|
||||
.setSn(period.getSn())
|
||||
.setBegin(period.getBegin().toString())
|
||||
.setEnd(period.getEnd().toString())
|
||||
.setFlag(PricingModelFlag.valueOf(period.getFlag().name()))
|
||||
.build();
|
||||
peakValleyBuilder.addPeriod(periodProto);
|
||||
}
|
||||
}
|
||||
|
||||
builder.setPeakValleyPricing(peakValleyBuilder.build());
|
||||
break;
|
||||
|
||||
case TIME_PERIOD_PRICING:
|
||||
// 时段计价:运营商自定义时段价格
|
||||
TimePeriodPricingProto.Builder timePeriodBuilder = TimePeriodPricingProto.newBuilder();
|
||||
|
||||
if (pricingModel.getTimePeriodItems() != null) {
|
||||
// 转换自定义时段计价数据
|
||||
for (TimePeriodItem item : pricingModel.getTimePeriodItems()) {
|
||||
TimePeriodItemProto.Builder itemBuilder = TimePeriodItemProto.newBuilder()
|
||||
.setPeriodNo(item.getPeriodNo())
|
||||
.setStartTime(item.getStartTime().toString())
|
||||
.setEndTime(item.getEndTime().toString())
|
||||
.setElecPrice(item.getElecPrice().toPlainString())
|
||||
.setServPrice(item.getServPrice().toPlainString());
|
||||
|
||||
if (item.getDescription() != null) {
|
||||
itemBuilder.setDescription(item.getDescription());
|
||||
}
|
||||
|
||||
timePeriodBuilder.addPeriods(itemBuilder.build());
|
||||
}
|
||||
} else if (pricingModel.getPeriodsList() != null) {
|
||||
// 兼容处理:将峰谷时段数据转换为时段计价格式
|
||||
for (Period period : pricingModel.getPeriodsList()) {
|
||||
FlagPrice flagPrice = pricingModel.getFlagPriceList() != null ?
|
||||
pricingModel.getFlagPriceList().get(period.getFlag()) : null;
|
||||
|
||||
TimePeriodItemProto.Builder itemBuilder = TimePeriodItemProto.newBuilder()
|
||||
.setPeriodNo(period.getSn())
|
||||
.setStartTime(period.getBegin().toString())
|
||||
.setEndTime(period.getEnd().toString());
|
||||
|
||||
if (flagPrice != null) {
|
||||
itemBuilder.setElecPrice(flagPrice.getElec().toPlainString())
|
||||
.setServPrice(flagPrice.getServ().toPlainString());
|
||||
}
|
||||
|
||||
timePeriodBuilder.addPeriods(itemBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
builder.setTimePeriodPricing(timePeriodBuilder.build());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported pricing rule: " + pricingModel.getRule());
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
|
||||
@@ -17,65 +17,86 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 计费模型 - 支持标准计费、峰谷计价、时段计价三种模式
|
||||
*/
|
||||
@Data
|
||||
public class PricingModel {
|
||||
|
||||
private UUID id;
|
||||
|
||||
// 计数器,供充电桩协议使用
|
||||
// 序列号,用于充电桩协议通信
|
||||
private int sequenceNumber;
|
||||
|
||||
private String pileCode;
|
||||
|
||||
private PricingModelType type;
|
||||
private PricingModelType type; // 计费类型:充电/放电
|
||||
|
||||
private PricingModelRule rule;
|
||||
private PricingModelRule rule; // 计费规则:标准/峰谷/时段
|
||||
|
||||
/**
|
||||
* 标准电价(单位元)
|
||||
* 标准电价(元/度)- 标准计费模式使用
|
||||
*/
|
||||
private BigDecimal standardElec;
|
||||
|
||||
/**
|
||||
* 标准服务费(单位元)
|
||||
* 标准服务费(元/度)- 标准计费模式使用
|
||||
*/
|
||||
private BigDecimal standardServ;
|
||||
|
||||
/**
|
||||
* 分时电价
|
||||
* 峰谷价格配置 - 峰谷计费模式使用
|
||||
* key: 时段标志(尖峰/峰/平/谷/深谷)
|
||||
* value: 对应的电费和服务费
|
||||
*/
|
||||
private Map<PricingModelFlag, FlagPrice> flagPriceList;
|
||||
|
||||
/**
|
||||
* 分时时段
|
||||
* 峰谷时段划分 - 峰谷计费模式使用
|
||||
*/
|
||||
private List<Period> periodsList;
|
||||
|
||||
/**
|
||||
* 自定义时段配置 - 时段计价模式使用
|
||||
*/
|
||||
private List<TimePeriodItem> timePeriodItems;
|
||||
|
||||
/**
|
||||
* 峰谷时段定义 - 用于峰谷计价模式
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public static class Period {
|
||||
private int sn;
|
||||
|
||||
// 起始时间
|
||||
private LocalTime begin;
|
||||
|
||||
// 结束时间
|
||||
private LocalTime end;
|
||||
|
||||
// 尖峰平谷标识
|
||||
private PricingModelFlag flag;
|
||||
private int sn; // 时段序号
|
||||
private LocalTime begin; // 起始时间
|
||||
private LocalTime end; // 结束时间
|
||||
private PricingModelFlag flag; // 时段标志(尖峰/峰/平/谷/深谷)
|
||||
}
|
||||
|
||||
/**
|
||||
* 峰谷价格定义 - 对应各时段标志的价格
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class FlagPrice {
|
||||
private BigDecimal elec; // 电费价格(元/度)
|
||||
private BigDecimal serv; // 服务费价格(元/度)
|
||||
}
|
||||
|
||||
// 分时电价,单位元
|
||||
private BigDecimal elec;
|
||||
|
||||
// 分时服务费,单位元
|
||||
private BigDecimal serv;
|
||||
/**
|
||||
* 自定义时段定义 - 用于时段计价模式
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class TimePeriodItem {
|
||||
private int periodNo; // 时段编号(从1开始)
|
||||
private LocalTime startTime; // 开始时间
|
||||
private LocalTime endTime; // 结束时间
|
||||
private BigDecimal elecPrice; // 该时段电费(元/度)
|
||||
private BigDecimal servPrice; // 该时段服务费(元/度)
|
||||
private String description; // 时段名称(如"早高峰")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,7 +55,9 @@ message UplinkQueueMessage {
|
||||
int64 sessionIdLSB = 4;
|
||||
string messageKey = 5;
|
||||
string protocolName = 6;
|
||||
int64 ts = 7;
|
||||
bytes requestData = 10;
|
||||
SessionCloseEventProto sessionCloseEventProto = 20;
|
||||
LoginRequest loginRequest = 21;
|
||||
HeartBeatRequest heartBeatRequest = 22;
|
||||
VerifyPricingRequest verifyPricingRequest = 23;
|
||||
@@ -77,7 +79,7 @@ message UplinkQueueMessage {
|
||||
OfflineCardBalanceUpdateResponse offlineCardBalanceUpdateResponse = 40;
|
||||
OfflineCardSyncResponse offlineCardSyncResponse = 41;
|
||||
TimeSyncResponse timeSyncResponse = 42;
|
||||
|
||||
BmsDemandChargerOutputProto bmsDemandChargerOutputProto = 43;
|
||||
}
|
||||
|
||||
message DownlinkRequestMessage {
|
||||
@@ -110,6 +112,19 @@ message DownlinkResponseMessage {
|
||||
optional string error = 2;
|
||||
}
|
||||
|
||||
message SessionCloseEventProto {
|
||||
string pileCode = 2; // 充电桩编码
|
||||
SessionCloseReason reason = 3; // 会话关闭原因
|
||||
optional string additionalInfo = 20; // 附加信息
|
||||
}
|
||||
|
||||
enum SessionCloseReason {
|
||||
SESSION_CLOSE_UNKNOWN = 0; // 未知原因
|
||||
SESSION_CLOSE_DESTRUCTION = 1; // 自然销毁(空闲超时)
|
||||
SESSION_CLOSE_ON_CHANNEL_INACTIVE = 2; // 通道不活跃
|
||||
SESSION_CLOSE_MANUALLY = 3; // 手动关闭
|
||||
}
|
||||
|
||||
message LoginRequest {
|
||||
string pileCode = 2;
|
||||
string credential = 3;
|
||||
@@ -159,13 +174,17 @@ message QueryPricingResponse {
|
||||
PricingModelProto pricingModel = 1;
|
||||
}
|
||||
|
||||
// 计费模型配置 - 支持三种计费方式
|
||||
message PricingModelProto {
|
||||
PricingModelType type = 3;
|
||||
PricingModelRule rule = 4;
|
||||
string standardElec = 5;
|
||||
string standardServ = 6;
|
||||
map<int32, FlagPriceProto> flagPrice = 8;
|
||||
repeated PeriodProto period = 9;
|
||||
PricingModelType type = 3; // 计费类型:充电/放电
|
||||
PricingModelRule rule = 4; // 计费规则:标准/峰谷/时段
|
||||
|
||||
// 计费配置:根据rule字段确定使用哪种配置
|
||||
oneof pricing_config {
|
||||
StandardPricingProto standardPricing = 5; // 标准计费:固定价格
|
||||
PeakValleyPricingProto peakValleyPricing = 6; // 峰谷计价:按尖峰平谷分时段
|
||||
TimePeriodPricingProto timePeriodPricing = 7; // 时段计价:自定义时段价格
|
||||
}
|
||||
}
|
||||
|
||||
message PeriodProto {
|
||||
@@ -181,14 +200,42 @@ message FlagPriceProto {
|
||||
string serv = 3;
|
||||
}
|
||||
|
||||
// 标准计费配置 - 全天统一价格
|
||||
message StandardPricingProto {
|
||||
string elecPrice = 1; // 电费价格(元/度)
|
||||
string servPrice = 2; // 服务费价格(元/度)
|
||||
}
|
||||
|
||||
// 峰谷计价配置 - 按电网峰谷政策分时计费
|
||||
message PeakValleyPricingProto {
|
||||
map<int32, FlagPriceProto> flagPrice = 1; // 各时段价格映射表
|
||||
repeated PeriodProto period = 2; // 时段划分配置
|
||||
}
|
||||
|
||||
// 时段计价配置 - 运营商自定义时段计费
|
||||
message TimePeriodPricingProto {
|
||||
repeated TimePeriodItemProto periods = 1; // 自定义时段列表
|
||||
}
|
||||
|
||||
// 时段计价单个时段定义
|
||||
message TimePeriodItemProto {
|
||||
int32 periodNo = 1; // 时段编号(从1开始)
|
||||
string startTime = 2; // 开始时间(HH:mm:ss格式)
|
||||
string endTime = 3; // 结束时间(HH:mm:ss格式)
|
||||
string elecPrice = 4; // 该时段电费(元/度)
|
||||
string servPrice = 5; // 该时段服务费(元/度)
|
||||
optional string description = 6; // 时段名称(如"早高峰")
|
||||
}
|
||||
|
||||
enum PricingModelType {
|
||||
CHARGE = 0; // 充电费率模型
|
||||
DISCHARGE = 1; // 放电费率模型
|
||||
}
|
||||
|
||||
enum PricingModelRule {
|
||||
STANDARD = 0;
|
||||
SPLIT_TIME = 1;
|
||||
STANDARD = 0; // 标准计费:全天统一价格
|
||||
PEAK_VALLEY_PRICING = 1; // 峰谷计费:按电网峰谷政策
|
||||
TIME_PERIOD_PRICING = 2; // 时段计费:运营商自定义
|
||||
}
|
||||
|
||||
enum PricingModelFlag {
|
||||
@@ -213,7 +260,6 @@ enum GunRunStatus {
|
||||
}
|
||||
|
||||
message GunRunStatusProto {
|
||||
int64 ts = 1;
|
||||
string pileCode = 4;
|
||||
string gunCode = 5;
|
||||
GunRunStatus GunRunStatus = 41;
|
||||
@@ -222,7 +268,6 @@ message GunRunStatusProto {
|
||||
}
|
||||
|
||||
message ChargingProgressProto {
|
||||
int64 ts = 1;
|
||||
string pileCode = 4;
|
||||
string gunCode = 5;
|
||||
string tradeNo = 6;
|
||||
@@ -265,7 +310,6 @@ message RestartPileRequest {
|
||||
}
|
||||
|
||||
message RemoteStartChargingResponse {
|
||||
int64 ts = 1;
|
||||
string pileCode = 4;
|
||||
string gunCode = 5;
|
||||
string tradeNo = 6;
|
||||
@@ -274,7 +318,6 @@ message RemoteStartChargingResponse {
|
||||
optional string additionalInfo = 20;
|
||||
}
|
||||
message RestartPileResponse {
|
||||
int64 ts = 1;
|
||||
string pileCode = 4;
|
||||
bool success = 7;
|
||||
}
|
||||
@@ -285,7 +328,6 @@ message RemoteStopChargingRequest {
|
||||
}
|
||||
|
||||
message RemoteStopChargingResponse {
|
||||
int64 ts = 1;
|
||||
string pileCode = 4;
|
||||
string gunCode = 5;
|
||||
bool success = 7;
|
||||
@@ -344,7 +386,6 @@ message TransactionRecordRequest {
|
||||
}
|
||||
|
||||
message BmsChargingErrorProto {
|
||||
int64 ts = 1;
|
||||
string pileCode = 4;
|
||||
string gunCode = 5;
|
||||
string tradeNo = 6;
|
||||
@@ -358,7 +399,6 @@ message TransactionRecordResponse {
|
||||
}
|
||||
|
||||
message BmsParamConfigReportProto {
|
||||
int64 ts = 1; // 时间戳
|
||||
string pileCode = 2; // 桩编码
|
||||
string gunCode = 3; // 枪编码
|
||||
string tradeNo = 4; // 交易号
|
||||
@@ -376,7 +416,6 @@ message BmsParamConfigReportProto {
|
||||
}
|
||||
|
||||
message BmsChargingInfoProto {
|
||||
int64 ts = 1; // 时间戳
|
||||
string pileCode = 4;
|
||||
string gunCode = 5;
|
||||
string tradeNo = 6;
|
||||
@@ -404,7 +443,6 @@ message OtaResponse {
|
||||
}
|
||||
|
||||
message BmsAbortProto {
|
||||
int64 ts = 1; // 时间戳
|
||||
string pileCode = 4;
|
||||
string gunCode = 5;
|
||||
string tradeNo = 6;
|
||||
@@ -412,7 +450,6 @@ message BmsAbortProto {
|
||||
}
|
||||
|
||||
message BmsHandshakeProto {
|
||||
int64 ts = 1; // 时间戳
|
||||
string pileCode = 2; // 桩编码
|
||||
string gunCode = 3; // 枪编码
|
||||
string tradeNo = 4; // 交易流水号
|
||||
@@ -433,7 +470,6 @@ message BmsHandshakeProto {
|
||||
}
|
||||
|
||||
message GroundLockStatusProto {
|
||||
int64 ts = 1; // 时间戳
|
||||
string pileCode = 2; // 桩编号
|
||||
string gunCode = 3; // 枪号
|
||||
int32 lockStatus = 4; // 车位锁状态
|
||||
@@ -485,3 +521,11 @@ message TimeSyncResponse {
|
||||
string pileCode = 1;
|
||||
string time = 2;
|
||||
}
|
||||
|
||||
message BmsDemandChargerOutputProto {
|
||||
string pileCode = 4;
|
||||
string gunCode = 5;
|
||||
string tradeNo = 6;
|
||||
optional string additionalInfo = 20;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user