部分站外充电机帧

master
tq 5 months ago
parent 717a905e74
commit 9f920ca6d2

@ -0,0 +1,28 @@
using System.Text;
using Newtonsoft.Json;
namespace Common.Util;
public static class HttpUtil
{
private static readonly HttpClient httpClient = new HttpClient();
/// <summary>
/// 发送post请求
/// </summary>
/// <param name="data"></param>
/// <param name="url"></param>
/// <typeparam name="T"></typeparam>
public static async void SendPostRequest<T>(T data, string url)
{
string jsonStr = JsonConvert.SerializeObject(data);
var content = new StringContent(jsonStr, Encoding.UTF8, "application/json");
HttpResponseMessage response = await httpClient.PostAsync(url, content);
if (response.IsSuccessStatusCode)
{
await response.Content.ReadAsStringAsync();
}
}
}

@ -51,7 +51,7 @@ namespace Entity.DbModel.Station
/// </summary>
[SugarColumn(ColumnName = "charger_no")]
public string ChargerNo { get; set; }
/// <summary>
/// Desc:充电枪编号
/// Default:
@ -59,6 +59,14 @@ namespace Entity.DbModel.Station
/// </summary>
[SugarColumn(ColumnName = "charger_gun_no")]
public string ChargerGunNo { get; set; }
/// <summary>
/// Desc:站外充电枪编号,1枪或2枪
/// Default:
/// Nullable:True
/// </summary>
[SugarColumn(ColumnName = "out_charger_gun_no")]
public string OutChargerGunNo { get; set; }
/// <summary>
/// Desc:0站内充电 1站外充电

@ -11,6 +11,38 @@ public class ChargeOrderRepository : BaseRepository<ChargeOrder>
{
}
public void SaveChargeGunOrder(string chargeOrderNo, string chargerNo, string chargerGunNo,
string outChargerGunNo)
{
ChargeOrder order = new ChargeOrder();
order.Sn = chargeOrderNo;
order.CmdStatus = 0;
order.ChargerNo = chargerNo;
order.ChargerGunNo = chargerGunNo;
order.OutChargerGunNo = outChargerGunNo;
order.ChargeMode = 1;
order.StartMode = 1;
order.CloudChargeOrder = chargeOrderNo;
order.CreatedTime = DateTime.Now;
ChargeOrder chargeOrder = Insert(order);
}
public ChargeOrder? GetLatestChargeGunOrder(string pn, string chargerCode)
{
try
{
var chargeOrder = DbBaseClient.Queryable<ChargeOrder>()
.Where(co => co.OutChargerGunNo == pn && co.ChargerNo == chargerCode)
.OrderByDescending(co => co.CreatedTime)
.First();
return chargeOrder;
}
catch (Exception e)
{
return null;
}
}
public ChargeOrder? QueryLatestByBatterySn(string? batterySn)
{
if (string.IsNullOrWhiteSpace(batterySn))
@ -33,6 +65,7 @@ public class ChargeOrderRepository : BaseRepository<ChargeOrder>
{
return new List<ChargeOrder>(0);
}
return QueryListByClause(it => it.SwapOrderSn == swapOrderNo && it.BatteryNo == batteryNo, it => it.CreatedTime,
OrderByType.Asc);
}

@ -1,4 +1,5 @@
using Autofac;
using System.Collections.Concurrent;
using Autofac;
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac;
using HybirdFrameworkCore.Autofac.Attribute;
@ -14,8 +15,10 @@ using Service.Charger.Codec;
using Service.Charger.Common;
using Service.Charger.Handler;
using Service.Charger.Msg;
using Service.Charger.Msg.Charger.OutCharger.Req;
using Service.Charger.Msg.Charger.Req;
using Service.Charger.Msg.Charger.Resp;
using Service.Charger.Msg.Host.OutCharger.Req;
using Service.Charger.Msg.Host.Req;
using Service.Charger.Msg.Host.Req.Bms;
@ -47,7 +50,18 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
/// 是否已经开始充电
/// </summary>
public bool IsCharged { get; set; } = false;
/// <summary>
/// 站外两枪时是否在充电
/// </summary>
public ConcurrentDictionary<byte, bool> GunCharged = new ConcurrentDictionary<byte, bool>
{
[1] = false,
[2] = false
};
public bool IsStopped { get; set; } = false;
public bool IsCanSendStopCmd { get; set; } = true;
@ -129,7 +143,11 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
/// 充电机遥测数据
/// </summary>
public UploadTelemetryData UploadTelemetryData = new UploadTelemetryData();
/// <summary>
/// 两个充电桩的遥测
/// </summary>
public ConcurrentDictionary<byte, PileUploadTelemetry> PileUploadTelemetry = new();
/// <summary>
///充电机实时充电功率
/// </summary>
@ -454,7 +472,57 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 3.7.1 监控平台远程启动充电桩充电
/// </summary>
/// <param name="pn">充电枪ID号</param>
/// <param name="socValue">SOC 限制</param>
/// <param name="changePower">功率调节指令类型</param>
/// <param name="changePowerCmdType">功率调节参数</param>
/// <param name="chargeOrderNo"></param>
/// <returns>充电流水号</returns>
public Result<string> SendStartOutCharger(byte pn, byte socValue, short changePower=360,byte changePowerCmdType=1 ,
string? chargeOrderNo = null)
{
if (!Connected)
{
return Result<string>.Fail($"充电机{BinNo}未连接");
}
if (string.IsNullOrWhiteSpace(chargeOrderNo))
{
chargeOrderNo = ChargerUtils.GenChargeOrderSn();
}
Log().Info(
$"SendStartOutCharger pn={pn}, socValue={socValue}, changePower={changePower}, changePowerCmdType={changePowerCmdType}, chargeOrderNo={chargeOrderNo}");
PileStartCharge pileStartCharge = new PileStartCharge(pn, socValue, changePowerCmdType, changePower,chargeOrderNo);
this.Channel.WriteAndFlushAsync(pileStartCharge);
return Result<string>.Success(chargeOrderNo);
}
/// <summary>
/// 3.7.3 监控平台远程停止充电桩充电
/// </summary>
/// <param name="pn"></param>
/// <param name="stopReason"></param>
/// <returns></returns>
public Result<string> SendStopOutCharger(byte pn, byte stopReason)
{
if (!Connected)
{
return Result<string>.Fail($"充电机{BinNo}未连接");
}
Log().Info(
$"SendStartOutCharger pn={pn}, stopReason={stopReason}");
PileStopCharge pileStopCharge=new PileStopCharge(pn,stopReason);
this.Channel.WriteAndFlushAsync(pileStopCharge);
return Result<string>.Success();
}
/// <summary>
///
/// </summary>

@ -8,6 +8,8 @@ using Newtonsoft.Json;
using Service.Charger.Common;
using Service.Charger.Msg;
using Service.Charger.Msg.Bms;
using Service.Charger.Msg.Charger.OutCharger.Req;
using Service.Charger.Msg.Charger.OutCharger.Resp;
using Service.Charger.Msg.Charger.Req;
using Service.Charger.Msg.Charger.Resp;
@ -239,6 +241,16 @@ public class Decoder : ByteToMessageDecoder
148 => ModelConvert.Decode<SysCode>(bytes),
_ => throw new InvalidOperationException("This should never be reached"),
},
51 => recordType switch
{
2 => ModelConvert.Decode<PileStartChargeRes>(bytes),
4 => ModelConvert.Decode<PileStopChargeRes>(bytes),
5 => ModelConvert.Decode<PileStartChargeCompleteReq>(bytes),
7 => ModelConvert.Decode<PileChargeCompleteReq>(bytes),
12 => ModelConvert.Decode<PileUploadTelemetry>(bytes),
11 => ModelConvert.Decode<PileUploadRemoteSignal>(bytes),
_ => throw new InvalidOperationException("This should never be reached"),
},
#endregion
42 => ModelConvert.Decode<RecordCharge>(bytes),

@ -58,7 +58,49 @@ public static class ChargerUtils
return StaticStationInfo.StationNo + DateTime.Now.ToString(ChargerConst.DateFormat) +
GetRandomNumLimit99();
}
/// <summary>
/// 根据云平台下发,计算本地充电机枪号
/// </summary>
/// <param name="number"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static byte GetTheGun(string number)
{
int parsedNumber;
if (int.TryParse(number, out parsedNumber))
{
if (parsedNumber % 2 == 0)
{
return 2;
}
else
{
return 1;
}
}
else
{
throw new ArgumentException("转换失败");
}
}
public static string GetOutChargerCode(string number)
{
int parsedNumber;
if (int.TryParse(number, out parsedNumber))
{
// 除2,向上取整,拿到本地充电机code
int ceilResult = (int)Math.Ceiling(parsedNumber / 2.0);
return ceilResult.ToString();
}
else
{
throw new ArgumentException("转换失败");
}
}
/// <summary>
/// 计算Byte随机数值
/// </summary>

@ -0,0 +1,49 @@
using DotNetty.Transport.Channels;
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac.Attribute;
using log4net;
using Repository.Station;
using Service.Charger.Client;
using Service.Charger.Msg.Charger.OutCharger.Req;
using Service.Charger.Msg.Host.Resp.OutCharger;
namespace Service.Charger.Handler.OutCharger;
/// <summary>
/// 3.7.7 充电桩上送停止完成帧
/// </summary>
[Order(8)]
[Scope("InstancePerDependency")]
public class PileChargeCompleteHandler : SimpleChannelInboundHandler<PileChargeCompleteReq>, IBaseHandler
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PileChargeCompleteHandler));
public ChargeOrderRepository ChargeOrderRepository { get; set; }
protected override void ChannelRead0(IChannelHandlerContext ctx, PileChargeCompleteReq msg)
{
if (ClientMgr.TryGetClient(ctx.Channel, out var sn, out var client))
{
Log.Info($"receive {msg} from {sn}");
if (msg.Result == 0)
{
ChargeOrder? chargeOrder = ChargeOrderRepository.GetLatestChargeGunOrder(msg.Pn.ToString(), sn);
if (chargeOrder == null)
{
return;
}
chargeOrder.EndTime = DateTime.Now;
chargeOrder.StopReason = 0;
chargeOrder.CanUpload = 1;
client.GunCharged[msg.Pn] = false;
ChargeOrderRepository.Update(chargeOrder);
}
PileChargeCompleteRes res = new PileChargeCompleteRes(msg.Pn,0);
ctx.Channel.WriteAndFlushAsync(res);
}
}
}

@ -0,0 +1,37 @@
using DotNetty.Transport.Channels;
using HybirdFrameworkCore.Autofac.Attribute;
using log4net;
using Service.Charger.Client;
using Service.Charger.Msg.Charger.OutCharger.Req;
using Service.Charger.Msg.Host.Resp.OutCharger;
namespace Service.Charger.Handler.OutCharger;
[Order(8)]
[Scope("InstancePerDependency")]
public class PileStartChargeCompleteHandler : SimpleChannelInboundHandler<PileStartChargeCompleteReq>, IBaseHandler
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PileStartChargeCompleteHandler));
protected override void ChannelRead0(IChannelHandlerContext ctx, PileStartChargeCompleteReq msg)
{
if (ClientMgr.TryGetClient(ctx.Channel, out var sn, out var client))
{
Log.Info($"receive {msg} from {sn}");
if (client == null)
{
return;
}
if (msg.Result == 0)
{
client.GunCharged[msg.Pn] = true;
}
// 响应启动完成帧
PileStartChargeCompleteRes res=new PileStartChargeCompleteRes(msg.Pn,0,0);
ctx.Channel.WriteAndFlushAsync(res);
}
}
}

@ -0,0 +1,61 @@
using System.Text;
using Common.Util;
using DotNetty.Transport.Channels;
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac.Attribute;
using log4net;
using Newtonsoft.Json;
using Repository.Station;
using Service.Charger.Client;
using Service.Charger.Msg.Charger.OutCharger.Resp;
using Service.Charger.Msg.Http.Resp;
namespace Service.Charger.Handler.OutCharger;
[Order(8)]
[Scope("InstancePerDependency")]
public class PileStartChargeResHandler : SimpleChannelInboundHandler<PileStartChargeRes>, IBaseHandler
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PileStartChargeResHandler));
public ChargeOrderRepository ChargeOrderRepository { get; set; }
protected override void ChannelRead0(IChannelHandlerContext ctx, PileStartChargeRes msg)
{
if (ClientMgr.TryGetClient(ctx.Channel, out var sn, out var client))
{
Log.Info($"receive {msg} from {sn}");
ChargeOrder? chargeOrder = ChargeOrderRepository.GetLatestChargeGunOrder(msg.Pn.ToString(), sn);
if (chargeOrder == null)
{
return;
}
PileStartChargeHttpRes chargeRes = new PileStartChargeHttpRes();
chargeRes.con = chargeOrder.Sn;
chargeRes.pn = chargeOrder.ChargerGunNo;
if (msg.Result == 0)
{
chargeOrder.StartTime = DateTime.Now;
chargeOrder.CmdStatus = 1;
ChargeOrderRepository.Update(chargeOrder);
chargeRes.rs = "1";
chargeRes.ec = "0";
// 9.2.1.2 站控应答开始充电操作
HttpUtil.SendPostRequest(chargeRes, "http://127.0.0.1:5034/api/OutCharger/ResStartOutCharger");
}
else
{
chargeRes.rs = "2";
chargeRes.ec = msg.FailReason.ToString();
HttpUtil.SendPostRequest(chargeRes, "http://127.0.0.1:5034/api/OutCharger/ResStartOutCharger");
}
}
}
}

@ -0,0 +1,46 @@
using Common.Util;
using DotNetty.Transport.Channels;
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac.Attribute;
using log4net;
using Repository.Station;
using Service.Charger.Client;
using Service.Charger.Msg.Charger.OutCharger.Resp;
using Service.Charger.Msg.Http.Resp;
namespace Service.Charger.Handler.OutCharger;
[Order(8)]
[Scope("InstancePerDependency")]
public class PileStopChargeResHandler : SimpleChannelInboundHandler<PileStopChargeRes>, IBaseHandler
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PileStopChargeResHandler));
public ChargeOrderRepository ChargeOrderRepository { get; set; }
protected override void ChannelRead0(IChannelHandlerContext ctx, PileStopChargeRes msg)
{
if (ClientMgr.TryGetClient(ctx.Channel, out var sn, out var client))
{
Log.Info($"receive {msg} from {sn}");
ChargeOrder? chargeOrder = ChargeOrderRepository.GetLatestChargeGunOrder(msg.pn.ToString(), sn);
if (chargeOrder == null)
{
return;
}
if (msg.rs == 0 || msg.rs == 1)
{
client.GunCharged[msg.pn] = false;
chargeOrder.EndTime = DateTime.Now;
ChargeOrderRepository.Update(chargeOrder);
PileStopChargeHttpRes res = new PileStopChargeHttpRes();
res.pn = chargeOrder.ChargerGunNo;
res.rs = msg.rs.ToString();
HttpUtil.SendPostRequest(res, "http://127.0.0.1:5034/api/OutCharger/ResStartOutCharger");
}
}
}
}

@ -0,0 +1,30 @@
using DotNetty.Transport.Channels;
using log4net;
using Service.Charger.Client;
using Service.Charger.Handler;
namespace Service.Charger.Msg.Charger.OutCharger.Req;
/// <summary>
/// 3.7.11 充电桩遥信数据上报
/// </summary>
public class PileUploadRemoteSignalHandler: SimpleChannelInboundHandler<PileUploadRemoteSignal>, IBaseHandler
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PileUploadRemoteSignalHandler));
protected override void ChannelRead0(IChannelHandlerContext ctx, PileUploadRemoteSignal msg)
{
if (ClientMgr.TryGetClient(ctx.Channel, out var sn, out var client))
{
//存储日志
Log.Info($"receive {msg} from {sn}");
client.Workstate = msg.WorkStatus;
client.IsCharged = msg.WorkStatus == 1 ? true : false;
client.TotalError = msg.TotalError;
client.TotalWarning = msg.TotalWarning;
}
}
}

@ -0,0 +1,30 @@
using DotNetty.Transport.Channels;
using HybirdFrameworkCore.Autofac.Attribute;
using log4net;
using Service.Charger.Client;
using Service.Charger.Msg.Charger.OutCharger.Req;
namespace Service.Charger.Handler.OutCharger;
/// <summary>
/// 3.7.12 充电桩遥测数据上报
/// </summary>
[Order(8)]
[Scope("InstancePerDependency")]
public class PileUploadTelemetryHandler : SimpleChannelInboundHandler<PileUploadTelemetry>, IBaseHandler
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PileUploadTelemetryHandler));
protected override void ChannelRead0(IChannelHandlerContext ctx, PileUploadTelemetry msg)
{
if (ClientMgr.TryGetClient(ctx.Channel, out var sn, out var client))
{
Log.Info($"receive {msg} from {sn}");
client.PileUploadTelemetry[msg.Pn] = msg;
client.RealTimeChargePower = msg.HighVoltageAcquisitionCurrent * msg.HighVoltageAcquisitionVoltage;
}
}
}

@ -0,0 +1,173 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Charger.OutCharger.Req;
/// <summary>
/// 3.7.7 充电桩上送停止完成帧
/// </summary>
public class PileChargeCompleteReq : ASDU
{
/// <summary>
/// 记录类型
/// </summary>
[Property(0, 8)]
public byte RecordType { get; set; }
/// <summary>
/// 充电枪ID号
/// 0x01充电枪10x02充电枪20x03双枪充电;(0x00&0xFF无效)
/// </summary>
[Property(8, 8)]
public byte Pn { get; set; }
/// <summary>
/// 成功标识
/// </summary>
[Property(16, 8)]
public byte Result { get; set; }
/// <summary>
/// 失败原因
/// </summary>
[Property(24, 8)]
public byte FailReason { get; set; }
/// <summary>
///BMS 中止充电原因
/// </summary>
[Property(32, 8)]
public byte SuspendingChargingReason { get; set; }
/// <summary>
///BMS 充电故障原因
/// </summary>
[Property(40, 16)]
public ushort CauseOfChargingFault { get; set; }
/// <summary>
///BMS 中止错误原因
/// </summary>
[Property(56, 8)]
public byte AbortErrorReason { get; set; }
/// <summary>
///中止荷电状态 SOC(%)
/// </summary>
[Property(64, 8, PropertyReadConstant.Bit, 1, 0)]
public float SuspendTheStateOfCharge { get; set; }
/// <summary>
///动力蓄电池单体最低电压(V)
/// </summary>
[Property(72, 16, PropertyReadConstant.Bit, 0.01, 2)]
public float MinimumVoltageOfTractionBattery { get; set; }
/// <summary>
///动力蓄电池单体最高电压(V)
/// </summary>
[Property(88, 16, PropertyReadConstant.Bit, 0.01, 2)]
public float MaximumVoltageOfTractionBattery { get; set; }
/// <summary>
///动力蓄电池最低温度(ºC)
/// </summary>
[Property(104, 8, PropertyReadConstant.Bit, 1, 0, 50)]
public float MinimumTemperatureOfTractionBattery { get; set; }
/// <summary>
///动力蓄电池最高温度(ºC)
/// </summary>
[Property(112, 8, PropertyReadConstant.Bit, 1, 0, 50)]
public byte MaximumTemperatureOfTractionBattery { get; set; }
/// <summary>
///接收SPN2560=0x00 的充电机辨识报文超时
/// </summary>
[Property(120, 2)]
public byte XOOIdentificationMessageTimeout { get; set; }
/// <summary>
///接收SPN2560=0xAA 的充电机辨识报文超时
/// </summary>
[Property(122, 2)]
public byte XAAIdentificationMessageTimeout { get; set; }
/// <summary>
///接收充电机的时间同步和充电机最大输出能力报文超时
/// </summary>
[Property(124, 2)]
public byte TimeSyncAndMaxOutCapTimeout { get; set; }
/// <summary>
///接收充电机完成充电准备报文超时
/// </summary>
[Property(126, 2)]
public byte ReceiveFinishPrepareChargeTimeout { get; set; }
/// <summary>
///接收充电机充电状态报文超时
/// </summary>
[Property(128, 2)]
public byte TimeReceiveChargerStatusMessage { get; set; }
/// <summary>
///接收充电机中止充电报文超时
/// </summary>
[Property(130, 2)]
public byte TimeReceiveChargingSuspensionMessage { get; set; }
/// <summary>
///接收充电机充电统计报文超时
/// </summary>
[Property(132, 2)]
public byte TimeReceiveChargingStatisticsMessageOfCharger { get; set; }
/// <summary>
///接收BMS和车辆的辨识报文超时
/// </summary>
[Property(134, 2)]
public byte TimeoutReceivingIdentificationMessageBms { get; set; }
/// <summary>
///接收电池充电参数报文超时
/// </summary>
[Property(136, 2)]
public byte TimeoutReceivingBatteryChargingParameterMessage { get; set; }
/// <summary>
///接收 BMS完成充电准备报文超时
/// </summary>
[Property(138, 2)]
public byte TimeoutReceivingBmsChargingPreparationMessage { get; set; }
/// <summary>
///接收电池充电要求报文超时
/// </summary>
[Property(140, 2)]
public byte TimeoutReceivingBatteryChargingMessage { get; set; }
/// <summary>
///接收电池充电总状态报文超时
/// </summary>
[Property(142, 2)]
public byte TimeoutReceivingBatteryChargingTotalStatusMessage { get; set; }
/// <summary>
///接收BMS中止充电报文超时
/// </summary>
[Property(144, 2)]
public byte TimeoutReceivingBmsChargingSuspensionMessage { get; set; }
/// <summary>
///接收BMS充电统计报文超时
/// </summary>
[Property(146, 2)]
public byte TimeoutReceivingBmsChargingStatisticsMessage { get; set; }
/// <summary>
///充电机检测到的其他错误
/// </summary>
[Property(148, 6)]
public byte OtherErrorsDetectedByTheCharger { get; set; }
}

@ -0,0 +1,137 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Charger.OutCharger.Req;
/// <summary>
/// 3.7.5 充电桩上送充电启动完成帧
/// </summary>
public class PileStartChargeCompleteReq : ASDU
{
/// <summary>
/// 记录类型
/// </summary>
[Property(0, 8)]
public byte RecordType { get; set; }
/// <summary>
/// 充电枪ID号
/// 0x01充电枪10x02充电枪20x03双枪充电;(0x00&0xFF无效)
/// </summary>
[Property(8, 8)]
public byte Pn { get; set; }
/// <summary>
/// 成功标识 0:成功1:失败
/// </summary>
[Property(16, 8)]
public byte Result { get; set; }
/// <summary>
/// 失败原因
/// 默认 0
/// </summary>
[Property(24, 8)]
public byte FailReason { get; set; }
/// <summary>
/// BMS 与充电桩通信协议版本号
/// </summary>
[Property(32, 24)]
public string? ConnProtocolVersion0 { get; set; }
/// <summary>
/// 充电桩与BMS 握手结果
/// </summary>
[Property(56, 8)]
public byte HandshakeResult { get; set; }
/// <summary>
/// 电池类型
/// </summary>
[Property(64, 8)]
public byte BatteryType { get; set; }
/// <summary>
/// 最高允许温度
/// </summary>
[Property(72, 8, PropertyReadConstant.Bit, 1, 0, 50)]
public Int16 MaxAllowTemp { get; set; }
/// <summary>
/// BMS最高允许充电电压
/// </summary>
[Property(80, 16, PropertyReadConstant.Bit, 0.1, 1, 0)]
public float BmsMaxAllowVoltage { get; set; }
/// <summary>
/// 单体最高允许充电电压
/// </summary>
[Property(96, 16, PropertyReadConstant.Bit, 0.01, 2, 0)]
public float SingleMaxAllowVoltage { get; set; }
/// <summary>
/// 最高允许充电电流
/// </summary>
[Property(112, 16, PropertyReadConstant.Bit, 0.1, 1, 400)]
public float MaxAllowCurrent { get; set; }
/// <summary>
/// 整车动力蓄电池额定总电压
/// </summary>
[Property(128, 16, PropertyReadConstant.Bit, 0.1, 1, 0)]
public float VehiclePowerBatteryTotalVoltage { get; set; }
/// <summary>
/// 整车动力蓄电池当前电压
/// </summary>
[Property(144, 16, PropertyReadConstant.Bit, 0.1, 1, 0)]
public float VehiclePowerBatteryCurrentVoltage { get; set; }
/// <summary>
/// 整车动力蓄电池额定容量
/// </summary>
[Property(160, 16, PropertyReadConstant.Bit, 0.1, 1, 0)]
public float VehiclePowerBatteryRatedCapacity { get; set; }
/// <summary>
///整车动力蓄电池标称容量
/// </summary>
[Property(176, 16, PropertyReadConstant.Bit, 0.1, 1, 0)]
public float VehiclePowerBatteryNormalCapacity { get; set; }
/// <summary>
///充电机最高输出电压
/// </summary>
[Property(192, 16, PropertyReadConstant.Bit, 0.1, 1, 0)]
public float ChargerMaxOutputVoltage { get; set; }
/// <summary>
///充电机最低输出电压
/// </summary>
[Property(208, 16, PropertyReadConstant.Bit, 0.1, 1, 0)]
public float ChargerMinOutputVoltage { get; set; }
/// <summary>
///充电机最大输出电流
/// </summary>
[Property(224, 16, PropertyReadConstant.Bit, 0.1, 1, 400)]
public float ChargerMaxOutputCurrent { get; set; }
/// <summary>
///充电机最小输出电流
/// </summary>
[Property(240, 16, PropertyReadConstant.Bit, 0.1, 1, 400)]
public float ChargerMinOutputCurrent { get; set; }
/// <summary>
/// VIN
/// </summary>
[Property(256, 136)]
public string Vin { get; set; }
/// <summary>
/// 整车动力蓄电 池荷电状态
/// </summary>
[Property(392, 8, PropertyReadConstant.Bit, 0.01, 2, 0)]
public byte ChargeState { get; set; }
}

@ -0,0 +1,306 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Charger.OutCharger.Req;
/// <summary>
/// 3.7.11 充电桩遥信数据上报
/// </summary>
public class PileUploadRemoteSignal: ASDU
{
/// <summary>
/// 记录类型
/// </summary>
[Property(0, 8)]
public byte RecordType { get; set; }
/// <summary>
/// 充电枪ID号
/// 0x01充电枪10x02充电枪20x03双枪充电;(0x00&0xFF无效)
/// </summary>
[Property(8, 8)]
public byte Pn { get; set; }
/// <summary>
/// 工作状态 00H:待机、01H:工作、02H:工作完成、03H:充/放电暂停
/// </summary>
[Property(16, 2)]
public byte WorkStatus { get; set; }
/// <summary>
/// 总故障0-正常、1-故障
/// </summary>
[Property(18, 1)]
public bool TotalError { get; set; }
/// <summary>
/// 总告警0-正常、1-告警
/// </summary>
[Property(19, 1)]
public bool TotalWarning { get; set; }
/// <summary>
/// 急停按钮动作故障0-正常、1-故障
/// </summary>
[Property(20, 1)]
public bool EmergencyStop { get; set; }
/// <summary>
/// 烟感故障0-正常、1-故障
/// </summary>
[Property(21, 1)]
public bool SmokeFault { get; set; }
/// <summary>
/// 充电桩交流输入断路器故障(系统供电断路器)0-正常、1-故障
/// </summary>
[Property(22, 1)]
public bool ChargeACInputCircuitBreakerFault { get; set; }
/// <summary>
/// 直流母线正极输出 接触器拒动/误 动故障0-正常、1-故障
/// </summary>
[Property(23, 1)]
public bool DcBusPositElecContactorRefuFault { get; set; }
/// <summary>
/// 直流母线负极输出 接触器拒动/误 动故障0-正常、1-故障
/// </summary>
[Property(24, 1)]
public bool DcBusNegatElecContactorRefuFault { get; set; }
/// <summary>
/// 直流母线正级输出 熔断器故障
/// </summary>
[Property(25, 1)]
public bool DcBusPositElecFusesFault { get; set; }
/// <summary>
/// 直流母线负级输出 熔断器故障
/// </summary>
[Property(26, 1)]
public bool DDcBusNegatElecFusesFault { get; set; }
/// <summary>
/// 充电接口电磁锁故障
/// </summary>
[Property(27, 1)]
public bool ChargingInterfaceLockError { get; set; }
/// <summary>
/// 充电桩风扇故障
/// </summary>
[Property(28, 1)]
public bool ChargerFanError { get; set; }
/// <summary>
/// 避雷器故障
/// </summary>
[Property(29, 1)]
public bool ArresterError { get; set; }
/// <summary>
/// 绝缘监测告警
/// </summary>
[Property(30, 1)]
public bool InsulationDetectionAlarm { get; set; }
/// <summary>
/// 绝缘监测故障
/// </summary>
[Property(31, 1)]
public bool InsulationDetectionError { get; set; }
/// <summary>
/// 电池极性反接故障
/// </summary>
[Property(32, 1)]
public bool BatteryPolarityReverseError { get; set; }
/// <summary>
/// 充电中车辆控制导引故障
/// </summary>
[Property(33, 1)]
public bool VeConGuidanceFailure { get; set; }
/// <summary>
/// 充电桩过温故障
/// </summary>
[Property(34, 1)]
public bool ChargingOverTempError { get; set; }
/// <summary>
/// 充电接口过温故障
/// </summary>
[Property(35, 1)]
public bool InterfaceOverFaulty { get; set; }
/// <summary>
/// 充电枪未归位告警
/// </summary>
[Property(36, 1)]
public bool ChargingGunNotHomingError { get; set; }
/// <summary>
/// BMS通信故障
/// </summary>
[Property(37, 1)]
public bool BmsConnError { get; set; }
/// <summary>
/// 充电桩输入电压过压故障
/// </summary>
[Property(38, 1)]
public bool ChargerInputOverVoltageError { get; set; }
/// <summary>
/// 充电桩输入电压欠压故障
/// </summary>
[Property(39, 1)]
public bool ChargerInputUnderVoltageError { get; set; }
/// <summary>
/// 直流母线输出过压故障
/// </summary>
[Property(40, 1)]
public bool DcBusOutputOverVoltageError { get; set; }
/// <summary>
/// 直流母线输出欠压故障
/// </summary>
[Property(41, 1)]
public bool DcBusOutputUnderVoltageError { get; set; }
/// <summary>
/// 直流母线输出过流故障
/// </summary>
[Property(42, 1)]
public bool DcBusOutputOverCurrentError { get; set; }
/// <summary>
/// 车辆连接状态 0-未连接、1-已连接
/// </summary>
[Property(43, 1)]
public bool VehicleConnStatus { get; set; }
/// <summary>
/// 充电桩充电枪座状态 0-已连接、1-未连接
/// </summary>
[Property(44, 1)]
public bool ChargeStationGunHolderStatus { get; set; }
/// <summary>
/// 充电接口电子锁状态 0-解锁、1-锁止
/// </summary>
[Property(45, 1)]
public bool ChargingInterfaceLockStatus { get; set; }
/// <summary>
/// 正极直流输出接触器状态 0-分断、1-闭合
/// </summary>
[Property(46, 1)]
public bool PositiveDcTransmissionContactorStatus { get; set; }
/// <summary>
/// 负极直流输出接触器状态 0-分断 1-闭合
/// </summary>
[Property(47, 1)]
public bool NegativeDcTransmissionContactorStatus { get; set; }
/// <summary>
/// 门禁故障 0-正常 1-故障
/// </summary>
[Property(48, 1)]
public bool EntranceGuardError { get; set; }
/// <summary>
/// 正极直流输出接触器粘连故障
/// </summary>
[Property(49, 1)]
public bool PConA3dhesionFailure { get; set; }
/// <summary>
/// 负极直流输出接触器粘连故故障
/// </summary>
[Property(50, 1)]
public bool NConadhesionFailure { get; set; }
/// <summary>
/// 泄放回路故障
/// </summary>
[Property(51, 1)]
public bool ReliefCircuitError { get; set; }
/// <summary>
/// 充电桩交流输入接触器据动/误动故(预留位置供其他适用)
/// </summary>
[Property(52, 1)]
public bool ConActivated { get; set; }
/// <summary>
/// 充电桩交流输入接触器粘连故障(预留位置供其他适用)
/// </summary>
[Property(53, 1)]
public bool ConAdhesionFailure { get; set; }
/// <summary>
/// 辅助电源故障
/// </summary>
[Property(54, 1)]
public bool AuxiliaryPowerError { get; set; }
/// <summary>
/// 模块输出反接
/// </summary>
[Property(55, 1)]
public bool ModuleOutputReverseError { get; set; }
/// <summary>
/// 充电桩交流接触器状态 0-分断 1-吸合
/// </summary>
[Property(56, 1)]
public bool AcContactorStatus { get; set; }
/// <summary>
/// 充电枪过温告警 0-正常 1-故障
/// </summary>
[Property(57, 1)]
public bool ChargingGunOverTempWarning { get; set; }
/// <summary>
/// 充电桩过温告警 0-正常 1-故障
/// </summary>
[Property(58, 1)]
public bool ChargerOverTempWarning { get; set; }
/// <summary>
/// 电表通信异常 0-正常 01H-故障
/// </summary>
[Property(59, 1)]
public bool MeterConnError { get; set; }
/// <summary>
/// 电表电度异常 0-正常 02H-故障
/// </summary>
[Property(60, 1)]
public bool MeterDataError { get; set; }
/// <summary>
/// 水浸告警 0-正常 03H-故障
/// </summary>
[Property(61, 1)]
public bool WaterloggingWarning { get; set; }
/// <summary>
/// 电池包辅助电源状态 0辅助电源未给电池包供电、1辅助电源正在给电池包供电
/// </summary>
[Property(62, 1)]
public bool BatteryPackAuxiliaryPowerStatus { get; set; }
/// <summary>
/// 逆功率报警 00H正常 01H故障
/// 发生该故障后一直保持,只到重合闸完成后,可以重合闸信号变为可用状态时才清零。
/// </summary>
[Property(63, 1)]
public bool ReversePowerWarning { get; set; }
}

@ -0,0 +1,205 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Charger.OutCharger.Req;
/// <summary>
/// 3.7.12 充电桩遥测数据上报
/// </summary>
public class PileUploadTelemetry : ASDU
{
/// <summary>
/// 记录类型
/// </summary>
[Property(0, 8)]
public byte RecordType { get; set; }
/// <summary>
/// 充电枪ID号
/// 0x01充电枪10x02充电枪20x03双枪充电;(0x00&0xFF无效)
/// </summary>
[Property(8, 8)]
public byte Pn { get; set; }
/// <summary>
/// 当前 SOC
/// </summary>
[Property(16, 8)]
public byte CurrentSoc { get; set; }
/// <summary>
/// 最高蓄电池温度
/// </summary>
[Property(24, 16, offset: 50)]
public Int16 MaxBatteryTemp { get; set; }
/// <summary>
/// 最高温度检测点编号
/// </summary>
[Property(40, 16)]
public ushort MaxTempDetectionPointNo { get; set; }
/// <summary>
/// 最低蓄电池温度数据分辨率1ºC/位,-50 ºC 偏移量;数据范围:-50ºC ~+200ºC
/// </summary>
[Property(56, 16, PropertyReadConstant.Bit, 1, 0, 50)]
public Int16 MinBatteryTemp { get; set; }
/// <summary>
/// 最低温度检测点编号
/// </summary>
[Property(72, 16)]
public ushort MinTempDetectionPointNo { get; set; }
/// <summary>
/// 单体电池最高电压
/// </summary>
[Property(88, 16, PropertyReadConstant.Bit, 0.01, 2, 0)]
public float SingleBatteryMaxVoltage { get; set; }
/// <summary>
/// 单体电池最低电压
/// </summary>
[Property(104, 16, PropertyReadConstant.Bit, 0.01, 2, 0)]
public float SingleBatteryMinVoltage { get; set; }
/// <summary>
/// 充电机环境温度
/// </summary>
[Property(120, 8, PropertyReadConstant.Bit, 1, 0, 50)]
public Int16 ChargerEnvTemp { get; set; }
/// <summary>
/// 充电导引电压
/// </summary>
[Property(128, 16, PropertyReadConstant.Bit, 0.01, 2, 0)]
public float ChargingPilotVoltage { get; set; }
/// <summary>
/// BMS 需求电压
/// </summary>
[Property(144, 16, PropertyReadConstant.Bit, 0.1, 1, 0)]
public float BmsNeedVoltage { get; set; }
/// <summary>
/// BMS 需求电流
/// </summary>
[Property(160, 16, PropertyReadConstant.Bit, 0.1, 1, 400)]
public float BmsNeedCurrent { get; set; }
/// <summary>
/// 充电模式 01H:恒压充电、02H恒流充电
/// </summary>
[Property(176, 8)]
public byte ChargeMode { get; set; }
/// <summary>
/// BMS 充电电压测量值
/// </summary>
[Property(184, 16, PropertyReadConstant.Bit, 0.1, 1, 0)]
public float BmsChargingVoltage { get; set; }
/// <summary>
/// BMS 充电电流测量值
/// </summary>
[Property(200, 16, PropertyReadConstant.Bit, 0.1, 1, 400)]
public float BmsChargingCurrent { get; set; }
/// <summary>
/// 估算剩余充电时间
/// </summary>
[Property(216, 16, PropertyReadConstant.Bit, 1, 0, 0)]
public ushort EstimatedRemainingTime { get; set; }
/// <summary>
/// 充电接口温度探头 1
/// </summary>
[Property(232, 8, PropertyReadConstant.Bit, 1, 0, 50)]
public Int16 ChargingInterfaceDetectionOneTemp { get; set; }
/// <summary>
/// 充电接口温度探头 2
/// </summary>
[Property(240, 8, PropertyReadConstant.Bit, 1, 0, 50)]
public Int16 ChargingInterfaceDetectionTwoTemp { get; set; }
/// <summary>
/// 充电接口温度探头 4
/// </summary>
[Property(248, 8, PropertyReadConstant.Bit, 1, 0, 50)]
public Int16 ChargingInterfaceDetectionFourTemp { get; set; }
/// <summary>
/// 直流电表当前电量
/// </summary>
[Property(256, 32, PropertyReadConstant.Bit, 0.01, 2)]
public float DcMeterCurrentPower { get; set; }
/// <summary>
/// 充电电压(直流电表电压)
/// </summary>
[Property(288, 16, PropertyReadConstant.Bit, 0.1, 1)]
public float DcMeterVoltage { get; set; }
/// <summary>
/// 充电电流(直流电表电流)
/// </summary>
[Property(304, 16, PropertyReadConstant.Bit, 0.1, 1)]
public float DcMeterCurrent { get; set; }
/// <summary>
/// 高压采集电压
/// </summary>
[Property(320, 16, PropertyReadConstant.Bit, 0.1, 1)]
public float HighVoltageAcquisitionVoltage { get; set; }
/// <summary>
/// 高压采集电流
/// </summary>
[Property(336, 16, PropertyReadConstant.Bit, 0.1, 1)]
public float HighVoltageAcquisitionCurrent { get; set; }
/// <summary>
/// 桩内部温度
/// </summary>
[Property(352, 8, PropertyReadConstant.Bit, 1, 0)]
public byte ChargerInsideTemp { get; set; }
/// <summary>
/// 本次充电时间
/// </summary>
[Property(360, 16)]
public ushort ChargingTime { get; set; }
/// <summary>
/// 模块进风口温度
/// </summary>
[Property(376, 8)]
public byte ModuleOneAirInletTemp { get; set; }
/// <summary>
/// 模块出风口温度
/// </summary>
[Property(384, 8)]
public byte ModuleTwoAirInletTemp { get; set; }
/// <summary>
/// 充电模式 0站内充电 1站外充电
/// </summary>
[Property(392, 8)]
public byte ChargeModel { get; set; }
/// <summary>
/// 充电启动方式 1站控启动 2本地充电
/// </summary>
[Property(400, 8)]
public byte ChargingStartMethod { get; set; }
/// <summary>
/// 交流电表当前电量
/// </summary>
[Property(408, 32, PropertyReadConstant.Bit, 0.01, 2)]
public float ACMeterCurrentBatteryValue { get; set; }
}

@ -0,0 +1,36 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Charger.OutCharger.Resp;
/// <summary>
/// 3.7.2 充电桩响应远程启动充电
/// </summary>
public class PileStartChargeRes : ASDU
{
/// <summary>
/// 记录类型
/// </summary>
[Property(0, 8)]
public byte RecordType { get; set; }
/// <summary>
/// 充电枪ID
/// 0x01充电枪10x02充电枪20x03双枪充电;(0x00&0xFF无效)
/// </summary>
[Property(8, 8)]
public byte Pn { get; set; }
/// <summary>
/// 启动结果
/// 0 成功 1 失败
/// </summary>
[Property(16, 8)]
public byte Result { get; set; }
/// <summary>
/// 失败原因
/// 默认 0
/// </summary>
[Property(24, 8)]
public byte FailReason { get; set; }
}

@ -0,0 +1,28 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Charger.OutCharger.Resp;
/// <summary>
/// 3.7.4 充电桩响应远程停止充电
/// </summary>
public class PileStopChargeRes : ASDU
{
/// <summary>
/// 记录类型
/// </summary>
[Property(0, 8)]
public byte RecordType { get; set; }
/// <summary>
/// 充电枪ID
/// 0x01充电枪10x02充电枪20x03双枪充电;(0x00&0xFF无效)
/// </summary>
[Property(8, 8)]
public byte pn { get; set; }
/// <summary>
/// 启动结果 0 成功 1 设备已停机 0xFF 其他
/// </summary>
[Property(16, 8)]
public byte rs { get; set; }
}

@ -0,0 +1,65 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Host.OutCharger.Req;
/// <summary>
/// 3.7.1 监控平台远程启动充电桩充电
/// </summary>
public class PileStartCharge : ASDU
{
/// <summary>
/// 记录类型
/// </summary>
[Property(0, 8)]
public byte RecordType { get; set; }
/// <summary>
/// 充电枪ID号
/// 0x01充电枪10x02充电枪20x03双枪充电;(0x00&0xFF无效)
/// </summary>
[Property(8, 8)]
public byte Pn { get; set; }
/// <summary>
/// SOC 限制
/// 百分比
/// </summary>
[Property(16, 8)]
public byte SocValue { get; set; }
/// <summary>
/// 功率调节指令类型
/// 默认 1 绝对功率值
/// </summary>
[Property(24, 8)]
public byte ChangePowerCmdType { get; set; } = 1;
/// <summary>
/// 功率调节参数
/// 0. 1kwh/位
/// </summary>
[Property(32, 16, PropertyReadConstant.Bit, 0.1, 1)]
public short ChangePower { get; set; }
/// <summary>
/// 充电流水号
/// </summary>
[Property(48, 256)]
public string ChargeOrderNo { get; set; }
public PileStartCharge(byte pn, byte socValue, byte changePowerCmdType, short changePower, string chargeOrderNo)
{
RecordType = 1;
FrameTypeNo = 51;
MsgBodyCount = 1;
TransReason = 3;
PublicAddr = 0;
MsgBodyAddr = new byte[] { 0, 0, 0 };
Pn = pn;
SocValue = socValue;
ChangePowerCmdType = changePowerCmdType;
ChangePower = changePower;
ChargeOrderNo = chargeOrderNo;
}
}

@ -0,0 +1,42 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Host.OutCharger.Req;
/// <summary>
/// 3.7.3 监控平台远程停止充电桩充电
/// </summary>
public class PileStopCharge : ASDU
{
/// <summary>
/// 记录类型
/// </summary>
[Property(0, 8)]
public byte RecordType { get; set; }
/// <summary>
/// 充电枪ID号
/// 0x01充电枪10x02充电枪20x03双枪充电;(0x00&0xFF无效)
/// </summary>
[Property(8, 8)]
public byte Pn { get; set; }
/// <summary>
/// 停止原因
/// </summary>
[Property(16, 8)]
public byte StopReason { get; set; }
public PileStopCharge(byte pn,byte stopReason)
{
RecordType = 3;
FrameTypeNo = 51;
MsgBodyCount = 1;
TransReason = 3;
PublicAddr = 0;
MsgBodyAddr = new byte[] { 0, 0, 0 };
Pn = pn;
StopReason = stopReason;
}
}

@ -0,0 +1,40 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Host.Resp.OutCharger;
/// <summary>
/// 3.7.8 监控平台应答充电桩停止完成帧
/// </summary>
public class PileChargeCompleteRes : ASDU
{
/// <summary>
/// 记录类型
/// </summary>
[Property(0, 8)]
public byte RecordType { get; set; }
/// <summary>
/// 充电枪ID号
/// 0x01充电枪10x02充电枪20x03双枪充电;(0x00&0xFF无效)
/// </summary>
[Property(8, 8)]
public byte Pn { get; set; }
/// <summary>
/// 成功标识 0:成功1:失败
/// </summary>
[Property(16, 8)]
public byte Result { get; set; }
public PileChargeCompleteRes(byte pn,byte result)
{
RecordType = 8;
FrameTypeNo = 51;
MsgBodyCount = 1;
TransReason = 4;
PublicAddr = 0;
MsgBodyAddr = new byte[] { 0, 0, 0 };
Pn = pn;
Result = result;
}
}

@ -0,0 +1,49 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Host.Resp.OutCharger;
/// <summary>
/// 3.7.6 监控平台应答充电桩启动完成帧
/// </summary>
public class PileStartChargeCompleteRes : ASDU
{
/// <summary>
/// 记录类型
/// </summary>
[Property(0, 8)]
public byte RecordType { get; set; }
/// <summary>
/// 充电枪ID号
/// 0x01充电枪10x02充电枪20x03双枪充电;(0x00&0xFF无效)
/// </summary>
[Property(8, 8)]
public byte Pn { get; set; }
/// <summary>
/// 成功标识 0:成功1:失败
/// </summary>
[Property(16, 8)]
public byte Result { get; set; }
/// <summary>
/// 失败原因
/// 0:成功1:交易流水号数据异常2:充电方式数据异常3:其他数据异常4:服务器异常5:服务器繁忙6:枪编号非法7 服务器判定启动完成帧超时0xFF:其他错误
/// </summary>
[Property(24, 8)]
public byte FailReason { get; set; }
public PileStartChargeCompleteRes(byte pn,byte result,byte failReason)
{
RecordType = 6;
FrameTypeNo = 51;
MsgBodyCount = 1;
TransReason = 4;
PublicAddr = 0;
MsgBodyAddr = new byte[] { 0, 0, 0 };
Pn = pn;
Result = result;
FailReason = failReason;
}
}

@ -0,0 +1,44 @@
namespace Service.Charger.Msg.Http.Req;
/// <summary>
/// 9.2.1.1 云平台下发开始充电操作
/// </summary>
public class PileStartChargeHttpReq
{
/// <summary>
/// 换电站编码
/// 换电站唯一码
/// </summary>
public string? sn { get; set; }
/// <summary>
/// 充电订单号
/// 云平台下发的充电订单编号,;当启动模式为本地主动启动(即插即充)时,该 值以 0 填充
/// </summary>
public string? con { get; set; }
/// <summary>
/// 充电枪编号
/// 充电枪的唯一标识码
/// </summary>
public string pn { get; set; }
/// <summary>
/// 充电方式
/// 0自动充满为止1按电量
/// </summary>
public int? ct { get; set; }
/// <summary>
/// 充电参数
/// 按充电方式判断除0外 电量:单位 kWh精确到 0.01 时间:单位 min精确到 0.01 金额:单位 元,精确到 0.01
/// </summary>
public string? cp { get; set; }
/// <summary>
/// 启动类型
/// 0运营平台启动1APP 启动2: 本地启动
/// </summary>
public int? st { get; set; }
}

@ -0,0 +1,20 @@
namespace Service.Charger.Msg.Http.Req;
/// <summary>
/// 9.2.17 云端下发充电枪停止充电
/// </summary>
public class PileStopChargeHttpReq
{
/// <summary>
/// 换电站编码
/// 换电站唯一码
/// </summary>
public string sn { get; set; }
/// <summary>
/// 充电枪编号
/// 充电枪的唯一标识码
/// </summary>
public string pn { get; set; }
}

@ -0,0 +1,27 @@
namespace Service.Charger.Msg.Http.Resp;
/// <summary>
/// 9.2.1.2 站控应答开始充电操作
/// </summary>
public class PileStartChargeHttpRes
{
/// <summary>
/// 执行结果
/// </summary>
public string? rs { get; set; }
/// <summary>
/// 充电订单号
/// </summary>
public string? con { get; set; }
/// <summary>
/// 充电枪编号
/// </summary>
public string? pn { get; set; }
/// <summary>
/// 故障码
/// </summary>
public string? ec { get; set; }
}

@ -0,0 +1,17 @@
namespace Service.Charger.Msg.Http.Resp;
/// <summary>
/// 9.2.1.8 站控响应充电枪停止充电操作
/// </summary>
public class PileStopChargeHttpRes
{
/// <summary>
/// 充电枪ID
/// 0x01充电枪10x02充电枪20x03双枪充电;(0x00&0xFF无效)
/// </summary>
public string pn { get; set; }
/// <summary>
/// 启动结果 0 成功 1 设备已停机 0xFF 其他
/// </summary>
public string rs { get; set; }
}

@ -0,0 +1,84 @@
using HybirdFrameworkCore.Entity;
using Microsoft.AspNetCore.Mvc;
using Repository.Station;
using Service.Charger.Client;
using Service.Charger.Common;
using Service.Charger.Msg.Http.Req;
using Service.Init;
namespace WebStarter.Controllers;
/// <summary>
/// 站外充电机管理
/// </summary>
[Produces("application/json")]
[ApiController]
[Route("api/[controller]")]
public class OutChargerController
{
private ChargeOrderRepository _chargeOrderRepository;
public OutChargerController(ChargeOrderRepository chargeOrderRepository)
{
_chargeOrderRepository = chargeOrderRepository;
}
/// <summary>
/// 云平台下发开始充电操作
/// </summary>
/// <param name="httpReq"></param>
/// <returns></returns>
[HttpPost]
[Route("SendStartOutCharger")]
public Result<bool> SendStartOutCharger([FromBody] PileStartChargeHttpReq httpReq)
{
string chargerCode = ChargerUtils.GetOutChargerCode(httpReq.pn);
byte chargerGunCode = ChargerUtils.GetTheGun(httpReq.pn);
ChargerClient? chargerClient = ClientMgr.GetBySn(chargerCode);
if (chargerClient == null)
{
return Result<bool>.Fail("充电机未连接");
}
if (string.IsNullOrWhiteSpace(httpReq.con))
{
httpReq.con = ChargerUtils.GenChargeOrderSn();
}
byte chargeSoc = StaticStationInfo.ChargeSoc;
// 下发充电枪充电
chargerClient.SendStartOutCharger(chargerGunCode, chargeSoc, 360, 1, httpReq.con);
// 初始化订单
_chargeOrderRepository.SaveChargeGunOrder(httpReq.con, chargerCode, httpReq.pn, chargerGunCode.ToString());
return Result<bool>.Success(true);
}
/// <summary>
/// 云端下发充电枪停止充电
/// </summary>
/// <param name="httpReq"></param>
/// <returns></returns>
[HttpPost]
[Route("SendStopOutCharger")]
public Result<bool> SendStopOutCharger([FromBody] PileStopChargeHttpReq httpReq)
{
string chargerCode = ChargerUtils.GetOutChargerCode(httpReq.pn);
byte chargerGunCode = ChargerUtils.GetTheGun(httpReq.pn);
ChargerClient? chargerClient = ClientMgr.GetBySn(chargerCode);
if (chargerClient == null)
{
return Result<bool>.Fail("充电机未连接");
}
// 下发充电枪停止充电
chargerClient.SendStopOutCharger(chargerGunCode, 0);
return Result<bool>.Success(true);
}
}
Loading…
Cancel
Save