站外修改

zw
tq 3 months ago
parent 4f376c5567
commit 3b75448b04

@ -0,0 +1,8 @@
namespace Common.Const;
public enum ChargerModeConst
{
InVain,
OnSite,
OutsideTheStation
}

@ -1,4 +1,5 @@
using System.Collections.Concurrent;
using Common.Const;
using Entity.DbModel.Station;
using Entity.Dto.Resp;
using HybirdFrameworkCore.Autofac.Attribute;
@ -25,9 +26,10 @@ public class ChargerService
/// <summary>
/// 启动充电
/// </summary>
/// <param name="mode"></param>
/// <param name="binNo"></param>
/// <returns></returns>
public Result<bool> StartChargeByBinNo(string binNo)
public Result<bool> StartChargeByBinNo(byte mode,string binNo)
{
BinInfo? binInfo = BinInfoRepository.QueryByBinNo(binNo);
if (binInfo == null)
@ -45,12 +47,12 @@ public class ChargerService
{
return Result<bool>.Fail(@"充电机未连接");
}
byte chargeSoc = StaticStationInfo.ChargeSoc;
float? chargePower = EquipInfoRepository.QueryPowerByCode(binInfo.ChargerNo);
float? power = chargePower == null ? StaticStationInfo.ChargePower : chargePower;
return chargerClient.StartCharge(chargeSoc,(float)power, 1);
return chargerClient.StartCharge(mode,chargeSoc,(float)power, 1);
}
/// <summary>

@ -1,6 +1,7 @@
using System.Collections.Concurrent;
using System.Reflection;
using Autofac;
using Common.Const;
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac;
using HybirdFrameworkCore.Autofac.Attribute;
@ -41,6 +42,10 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
public ushort AuthTimes { get; set; } = 0;
public bool IsAuthed { get; set; } = false;
/// <summary>
/// 充电模式 00无效 01站内 02站外
/// </summary>
public byte ChargerMode{ get; set; } = 1;
/// <summary>
/// 参考 Service.Charger.Common.ChargingStatus
@ -51,26 +56,8 @@ 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
};
/// <summary>
/// 充电桩连接状态
/// </summary>
public ConcurrentDictionary<byte, bool> ChargedPile = new ConcurrentDictionary<byte, bool>
{
[1] = false,
[2] = false
};
public bool IsStopped { get; set; } = false;
public bool IsCanSendStopCmd { get; set; } = true;
@ -157,11 +144,7 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
/// 充放电机上传单体动力蓄电池电压极值统计
/// </summary>
public VoltageExtremumStatistics? VoltageExtremumStatistics = new VoltageExtremumStatistics();
/// <summary>
/// 充电桩的遥测
/// </summary>
public ConcurrentDictionary<byte, PileUploadTelemetry> PileUploadTelemetry = new();
/// <summary>
/// 充电桩的遥信
@ -171,12 +154,8 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
/// <summary>
/// 充电桩状态信息
/// </summary>
public ConcurrentDictionary<byte, ChargerPile> ChargerPile = new();
/// <summary>
/// 充电桩功率
/// </summary>
public ConcurrentDictionary<byte, float> ChargePilePower = new();
public ChargerPile ChargerPile { get; set; }
/// <summary>
///充电机实时充电功率
@ -321,11 +300,12 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
/// <summary>
/// 监控平台发送远程开始充电指令
/// </summary>
/// <param name="mode">充电模式</param>
/// <param name="socLimit">SOC限制.百分比</param>
/// <param name="changePowerCmdType">功率调节指令类型.默认1 绝对功率值</param>
/// <param name="changePower">1kw/位,默认3600</param>
/// <param name="chargeOrderNo">充电流水号</param>
public Result<string> SendRemoteStartCharging(byte socLimit, float changePower = 360, byte changePowerCmdType = 1,
public Result<string> SendRemoteStartCharging(byte mode,byte socLimit, float changePower = 360, byte changePowerCmdType = 1,
string? chargeOrderNo = null)
{
if (!Connected)
@ -333,6 +313,13 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
return Result<string>.Fail($"充电机{BinNo}未连接");
}
if (ChargerMode != mode)
{
SendChangeChargeMode(mode);
ChargerMode = mode;
Thread.Sleep(3000);
}
if (string.IsNullOrWhiteSpace(chargeOrderNo))
{
chargeOrderNo = ChargerUtils.GenChargeOrderSn();
@ -538,61 +525,7 @@ 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>
/// 3.7.9 监控平台发送充电桩功率调节指令
@ -637,7 +570,7 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
/// <summary>
///
/// </summary>
public Result<bool> StartCharge(byte chargeSoc, float chargePower, int startType)
public Result<bool> StartCharge(byte mode,byte chargeSoc, float chargePower, int startType)
{
if (string.IsNullOrWhiteSpace(BinNo))
{
@ -681,7 +614,7 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
redisHelper.SetKeyValueStr($"chargeNo{BinNo}Start", DateTime.Now.ToString("f"), TimeSpan.FromMinutes(1));
Result<string> chargeOrderNo = SendRemoteStartCharging(chargeSoc, chargePower);
Result<string> chargeOrderNo = SendRemoteStartCharging(mode,chargeSoc, chargePower);
if (!chargeOrderNo.IsSuccess)
{
return Result<bool>.Fail(chargeOrderNo.Msg);

@ -1,22 +0,0 @@
using DotNetty.Transport.Channels;
using log4net;
using Service.Charger.Client;
using Service.Charger.Msg.Charger.OutCharger.Resp;
namespace Service.Charger.Handler.OutCharger;
/// <summary>
/// 3.7.10 充电桩应答功率调节指令
/// </summary>
public class PileAdjustPowerHandler : SimpleChannelInboundHandler<PileAdjustPowerRes>, IBaseHandler
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PileAdjustPowerHandler));
protected override void ChannelRead0(IChannelHandlerContext ctx, PileAdjustPowerRes msg)
{
if (ClientMgr.TryGetClient(ctx.Channel, out var sn, out var client))
{
Log.Info($"receive {msg} from {sn}");
}
}
}

@ -1,47 +0,0 @@
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.StopReason = 0;
client.GunCharged[msg.Pn] = false;
ChargeOrderRepository.Update(chargeOrder);
}
PileChargeCompleteRes res = new PileChargeCompleteRes(msg.Pn,0);
ctx.Channel.WriteAndFlushAsync(res);
}
}
}

@ -1,40 +0,0 @@
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;
/// <summary>
/// 3.7.5 充电桩上送充电启动完成帧
/// </summary>
[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;
client.ChargerPile[msg.Pn].Vin = msg.Vin;
}
// 响应启动完成帧
PileStartChargeCompleteRes res=new PileStartChargeCompleteRes(msg.Pn,0,0);
ctx.Channel.WriteAndFlushAsync(res);
}
}
}

@ -1,64 +0,0 @@
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;
/// <summary>
/// 3.7.2 充电桩响应远程启动充电
/// </summary>
[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");
}
}
}
}

@ -1,45 +0,0 @@
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;
/// <summary>
/// 3.7.4 充电桩响应远程停止充电
/// </summary>
[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)
{
PileStopChargeHttpRes res = new PileStopChargeHttpRes();
res.pn = chargeOrder.ChargerGunNo;
res.rs = msg.rs.ToString();
HttpUtil.SendPostRequest(res, "http://127.0.0.1:5034/api/OutCharger/ResStopOutCharger");
}
}
}
}

@ -1,254 +0,0 @@
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.Common;
using Service.Charger.Msg.Charger.OutCharger.Req;
using Service.Charger.Msg.Host.Resp.OutCharger;
using Service.Charger.Msg.Http.Req;
using Service.Init;
namespace Service.Charger.Handler.OutCharger;
/// <summary>
/// 3.7.13 充电桩上送充电记录
/// </summary>
[Order(8)]
[Scope("InstancePerDependency")]
public class PileUploadChargeRecordHandler : SimpleChannelInboundHandler<PileUploadChargeRecord>, IBaseHandler
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PileUploadChargeRecordHandler));
public ChargeOrderRepository ChargeOrderRepository { get; set; }
protected override void ChannelRead0(IChannelHandlerContext ctx, PileUploadChargeRecord msg)
{
if (ClientMgr.TryGetClient(ctx.Channel, out var sn, out var client))
{
if (client == null)
{
return;
}
float[] powersPeriods = new float[4] { 0, 0, 0, 0 }; //元素索引顺序代表值1234
var acPowersPeriods = PeaksAndValleys(msg, powersPeriods);
Log.Info($"receive {msg} from {sn}");
ChargeOrder chargeOrder = ChargeOrderRepository.QueryByClause(it => it.Sn == msg.ChargeOrderNo);
var startTime = new DateTime(msg.StartYear + 2000, msg.StartMonth, msg.StartDay, msg.StartHour,
msg.StartMinute, msg.StartSecond);
var endTime = new DateTime(msg.EndYear + 2000, msg.EndMonth, msg.EndDay, msg.EndHour, msg.EndMinute,
msg.EndSecond);
float chargingPower = msg.ChargingPower;
var socBefore = msg.SocBefore;
byte socAfter = msg.SocAfter;
void UpdateChargeOrder(ChargeOrder order)
{
order.StartTime = startTime;
order.EndTime = endTime;
order.StartSoc = socBefore;
order.StopSoc = socAfter;
order.ChargeTimeCount = (int)(endTime - startTime).TotalMinutes;
order.ElecCount = Convert.ToDecimal(chargingPower);
order.AcElecCount = Convert.ToDecimal(msg.AcMeterElecCount);
order.StartAcElec = Convert.ToDecimal(msg.AcMeterDataBefore);
order.StopAcElec = Convert.ToDecimal(msg.AcMeterDataAfter);
order.StartDcElec = Convert.ToDecimal(msg.DcMeterDataBefore);
order.StopDcElec = Convert.ToDecimal(msg.DcMeterDataAfter);
order.SharpElecCount = Convert.ToDecimal(powersPeriods[0]);
order.PeakElecCount = Convert.ToDecimal(powersPeriods[1]);
order.FlatElecCount = Convert.ToDecimal(powersPeriods[2]);
order.ValleyElecCount = Convert.ToDecimal(powersPeriods[3]);
order.AcSharpElecCount = Convert.ToDecimal(acPowersPeriods[0]);
order.AcPeakElecCount = Convert.ToDecimal(acPowersPeriods[1]);
order.AcFlatElecCount = Convert.ToDecimal(acPowersPeriods[2]);
order.AcValleyElecCount = Convert.ToDecimal(acPowersPeriods[3]);
order.ChargeMode = msg.ChargeMode;
order.StartMode = msg.StartMode;
}
if (chargeOrder == null)
{
ChargeOrder newOrder = new ChargeOrder()
{
Sn = msg.ChargeOrderNo
};
UpdateChargeOrder(newOrder);
ChargeOrderRepository.Insert(newOrder);
PileEndChargeReq req = new PileEndChargeReq();
req.sn = StaticStationInfo.StationNo;
req.con = msg.ChargeOrderNo;
req.cosn = msg.ChargeOrderNo;
UploadChargeRecord(msg, client, req, sn, startTime, endTime, chargingPower, socBefore, socAfter);
}
else
{
UpdateChargeOrder(chargeOrder);
// 充电完成入库
ChargeOrderRepository.Update(chargeOrder);
PileEndChargeReq req = new PileEndChargeReq();
req.sn = StaticStationInfo.StationNo;
req.con = chargeOrder.CloudChargeOrder;
req.cosn = chargeOrder.Sn;
// 充电完成上报云平台
UploadChargeRecord(msg, client, req, sn, startTime, endTime, chargingPower, socBefore, socAfter);
}
}
ctx.Channel.WriteAndFlushAsync(new PileUploadChargeRecordRes(msg.Pn));
}
private static void UploadChargeRecord(PileUploadChargeRecord msg, ChargerClient client, PileEndChargeReq req,
string sn, DateTime startTime, DateTime endTime, float chargingPower, byte socBefore, byte socAfter)
{
ChargerPile chargerPile = client.ChargerPile[msg.Pn];
req.pn = ChargerUtils.ReverseCalculateChargerGun(msg.Pn, sn);
req.ct = chargerPile.ct;
req.cp = chargerPile.cp;
req.st = chargerPile.st;
req.cst = startTime;
req.cet = endTime;
req.ceq = chargingPower;
req.cssoc = socBefore;
req.cesoc = socAfter;
req.ctn = msg.ChargingTimeCount;
List<PeriodReq> periodList = new List<PeriodReq>();
// 利用反射组装充电时间段数据
for (int i = 1; i <= msg.ChargingTimeCount; i++)
{
PeriodReq periodReq = new PeriodReq();
// 获取属性
var startTimeHourProperty = typeof(PileUploadChargeRecord).GetProperty($"StartTime{i}");
var startTimeMinuteProperty = typeof(PileUploadChargeRecord).GetProperty($"StartTimeMinute{i}");
if (startTimeHourProperty != null && startTimeMinuteProperty != null)
{
// 获取值
byte startTimeHour = (byte)startTimeHourProperty.GetValue(msg);
byte startTimeMinute = (byte)startTimeMinuteProperty.GetValue(msg);
periodReq.StartTimeMinute = DateUtils.GetFormattedTime(startTimeHour, startTimeMinute);
}
var chargingPowerProperty = typeof(PileUploadChargeRecord).GetProperty($"ChargingPowerOfTime{i}");
var flagOfTimeProperty = typeof(PileUploadChargeRecord).GetProperty($"FlagOfTime{i}");
if (chargingPowerProperty != null && flagOfTimeProperty != null)
{
periodReq.ChargingPowerOfTime = (float)chargingPowerProperty.GetValue(msg);
periodReq.FlagOfTime = (byte)flagOfTimeProperty.GetValue(msg);
}
periodList.Add(periodReq);
}
req.ctl = periodList;
req.cvin = chargerPile.Vin;
HttpUtil.SendPostRequest(req, "http://127.0.0.1:5034/api/OutCharger/SendPileEndCharge");
}
private static float[] PeaksAndValleys(PileUploadChargeRecord msg, float[] powersPeriods)
{
if (msg.FlagOfTime1 >= 1 && msg.FlagOfTime1 <= 4)
{
powersPeriods[msg.FlagOfTime1 - 1] += msg.ChargingPowerOfTime1;
}
if (msg.FlagOfTime2 >= 1 && msg.FlagOfTime2 <= 4)
{
powersPeriods[msg.FlagOfTime2 - 1] += msg.ChargingPowerOfTime2;
}
if (msg.FlagOfTime3 >= 1 && msg.FlagOfTime3 <= 4)
{
powersPeriods[msg.FlagOfTime3 - 1] += msg.ChargingPowerOfTime3;
}
if (msg.FlagOfTime4 >= 1 && msg.FlagOfTime4 <= 4)
{
powersPeriods[msg.FlagOfTime4 - 1] += msg.ChargingPowerOfTime4;
}
if (msg.FlagOfTime5 >= 1 && msg.FlagOfTime5 <= 4)
{
powersPeriods[msg.FlagOfTime5 - 1] += msg.ChargingPowerOfTime5;
}
if (msg.FlagOfTime6 >= 1 && msg.FlagOfTime6 <= 4)
{
powersPeriods[msg.FlagOfTime6 - 1] += msg.ChargingPowerOfTime6;
}
if (msg.FlagOfTime7 >= 1 && msg.FlagOfTime7 <= 4)
{
powersPeriods[msg.FlagOfTime7 - 1] += msg.ChargingPowerOfTime7;
}
if (msg.FlagOfTime8 >= 1 && msg.FlagOfTime8 <= 4)
{
powersPeriods[msg.FlagOfTime8 - 1] += msg.ChargingPowerOfTime8;
}
float[] acPowersPeriods = new float[4] { 0, 0, 0, 0 }; //元素索引顺序代表值1234
if (msg.AcFlagOfTime1 >= 1 && msg.AcFlagOfTime1 <= 4)
{
acPowersPeriods[msg.AcFlagOfTime1 - 1] += msg.AcChargingPowerOfTime1;
}
if (msg.AcFlagOfTime2 >= 1 && msg.AcFlagOfTime2 <= 4)
{
acPowersPeriods[msg.AcFlagOfTime2 - 1] += msg.AcChargingPowerOfTime2;
}
if (msg.AcFlagOfTime3 >= 1 && msg.AcFlagOfTime3 <= 4)
{
acPowersPeriods[msg.AcFlagOfTime3 - 1] += msg.AcChargingPowerOfTime3;
}
if (msg.AcFlagOfTime4 >= 1 && msg.AcFlagOfTime4 <= 4)
{
acPowersPeriods[msg.AcFlagOfTime4 - 1] += msg.AcChargingPowerOfTime4;
}
if (msg.AcFlagOfTime5 >= 1 && msg.AcFlagOfTime5 <= 4)
{
acPowersPeriods[msg.AcFlagOfTime5 - 1] += msg.AcChargingPowerOfTime5;
}
if (msg.AcFlagOfTime6 >= 1 && msg.AcFlagOfTime6 <= 4)
{
acPowersPeriods[msg.AcFlagOfTime6 - 1] += msg.AcChargingPowerOfTime6;
}
if (msg.AcFlagOfTime7 >= 1 && msg.AcFlagOfTime7 <= 4)
{
acPowersPeriods[msg.AcFlagOfTime7 - 1] += msg.AcChargingPowerOfTime7;
}
if (msg.AcFlagOfTime8 >= 1 && msg.AcFlagOfTime8 <= 4)
{
acPowersPeriods[msg.AcFlagOfTime8 - 1] += msg.AcChargingPowerOfTime8;
}
return acPowersPeriods;
}
}

@ -1,36 +0,0 @@
using DotNetty.Transport.Channels;
using log4net;
using Service.Charger.Client;
using Service.Charger.Handler;
using Service.Charger.Msg.Charger.OutCharger.Req;
namespace Service.Charger.Handler.OutCharger;
/// <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.PileUploadRemoteSignal[msg.Pn] = msg;
client.Workstate = msg.WorkStatus;
client.GunCharged[msg.Pn] = msg.WorkStatus == 1 ? true : false;
client.ChargedPile[msg.Pn] = !msg.ChargeStationGunHolderStatus;
client.ChargerPile[msg.Pn].WorkStatus = msg.WorkStatus;
}
}
}

@ -1,30 +0,0 @@
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.ChargePilePower[msg.Pn] = msg.HighVoltageAcquisitionCurrent * msg.HighVoltageAcquisitionVoltage;
}
}
}

@ -3,7 +3,7 @@
namespace Service.Charger.Msg.Charger.Resp
{
/// <summary>
/// 3.4.4 充放电机应答辅助控制
/// 3.4.6 充放电设备应答充电速率设置
/// </summary>
public class AdjustChargeRateRes : ASDU
{

@ -7,11 +7,30 @@ namespace Service.Charger.Msg.Host.Req
/// </summary>
public class OutSideAllowChargingSoc : ASDU
{
/// <summary>
/// SOC 限制值
/// 记录类型
/// </summary>
[Property(0, 8)]
public byte RecordType { get; set; }
/// <summary>
/// SOC 限制值
/// </summary>
[Property(8, 8)]
public byte SocValue { get; set; }
public OutSideAllowChargingSoc(byte socValue)
{
FrameTypeNo = 45;
MsgBodyCount = 1;
TransReason = 4;
PublicAddr = 0;
MsgBodyAddr = new byte[] { 0, 0, 0 };
RecordType = 45;
SocValue = socValue;
}
}
}

@ -176,7 +176,7 @@ public class AutoChargeTask : ITask
{
//没有充电时候在充电
Result<bool>? result = ClientMgr.GetBySn(binInfo.ChargerNo)
?.StartCharge(chargeSoc, (float)power, 0);
?.StartCharge((byte)ChargerModeConst.OnSite,chargeSoc, (float)power, 0);
if (result is { IsSuccess: true })
{
Log.Info($"auto start charge {binInfo.ChargerNo}");

@ -1,4 +1,5 @@
using System.Collections.Concurrent;
using Common.Const;
using Common.Util;
using HybirdFrameworkCore.Autofac.Attribute;
using HybirdFrameworkCore.AutoTask;
@ -10,6 +11,7 @@ using Service.Charger.Msg.Http.Req;
using Service.Init;
namespace Service.Charger.MyTask;
/// <summary>
/// 9.2.1.7 站控上报充电枪充电遥测数据
/// </summary>
@ -32,7 +34,6 @@ public class PileChargeRealtimeTask : ITask
public void Handle()
{
ConcurrentDictionary<string, ChargerClient> chargerClients = ClientMgr.Dictionary;
if (chargerClients.Values.Count <= 0)
@ -43,43 +44,42 @@ public class PileChargeRealtimeTask : ITask
foreach (var clientPair in chargerClients)
{
ChargerClient client = clientPair.Value;
ProcessClient(client, 1);
ProcessClient(client, 2);
byte mode = (byte)ChargerModeConst.OutsideTheStation;
ProcessClient(client, mode);
}
}
private void ProcessClient(ChargerClient client, byte gunNumber)
private void ProcessClient(ChargerClient client, byte mode)
{
if (client.GunCharged[gunNumber])
if (client.IsCharged && client.ChargerMode == mode)
{
ChargerPile chargerPile = client.ChargerPile[gunNumber];
PileUploadTelemetry telemetry = client.PileUploadTelemetry[gunNumber];
PileUploadRemoteSignal pileUploadRemoteSignal = client.PileUploadRemoteSignal[gunNumber];
ChargerPile chargerPile = client.ChargerPile;
UploadTelemetryData uploadTelemetryData = client.UploadTelemetryData;
UploadRemoteSignalData uploadRemoteSignalData = client.UploadRemoteSignalData;
PileChargeRealtimeReq req = new PileChargeRealtimeReq
{
sn = StaticStationInfo.StationNo,
con = chargerPile.con,
cosn = chargerPile.cosn,
pn = chargerPile.pn,
rv = telemetry.BmsNeedVoltage,
re = telemetry.BmsNeedCurrent,
cm = telemetry.ChargeMode,
cdv = telemetry.BmsChargingVoltage,
cde = telemetry.BmsChargingCurrent,
soc = telemetry.CurrentSoc,
tr = telemetry.EstimatedRemainingTime,
pov = telemetry.DcMeterVoltage,
poe = telemetry.DcMeterCurrent,
tct = telemetry.ChargingTime,
lbtn = telemetry.MinTempDetectionPointNo,
lbt = telemetry.MinBatteryTemp,
hbtn = telemetry.MaxTempDetectionPointNo,
hbt = telemetry.MaxBatteryTemp,
hlbva = pileUploadRemoteSignal.ChargerInputOverVoltageError ? 1 :
pileUploadRemoteSignal.ChargerInputUnderVoltageError ? 2 : 0,
bia = pileUploadRemoteSignal.InsulationDetectionAlarm ? 1 : 0
rv = uploadTelemetryData.BmsNeedVoltage,
re = uploadTelemetryData.BmsNeedCurrent,
cm = uploadTelemetryData.ChargeMode,
cdv = uploadTelemetryData.BmsChargingVoltage,
cde = uploadTelemetryData.BmsChargingCurrent,
soc = uploadTelemetryData.CurrentSoc,
tr = uploadTelemetryData.EstimatedRemainingTime,
pov = uploadTelemetryData.DcMeterVoltage,
poe = uploadTelemetryData.DcMeterCurrent,
tct = uploadTelemetryData.ChargingTime,
lbtn = uploadTelemetryData.MinTempDetectionPointNo,
lbt = uploadTelemetryData.MinBatteryTemp,
hbtn = uploadTelemetryData.MaxTempDetectionPointNo,
hbt = uploadTelemetryData.MaxBatteryTemp,
hlbva = uploadRemoteSignalData.ChargerInputOverVoltageError ? 1 :
uploadRemoteSignalData.ChargerInputUnderVoltageError ? 2 : 0,
bia = uploadRemoteSignalData.InsulationDetectionAlarm ? 1 : 0
};
HttpUtil.SendPostRequest(req, "http://127.0.0.1:5034/api/OutCharger/SendPileChargeRealtime");

@ -1,14 +1,17 @@
using System.Collections.Concurrent;
using Common.Const;
using Common.Util;
using HybirdFrameworkCore.Autofac.Attribute;
using HybirdFrameworkCore.AutoTask;
using log4net;
using Service.Charger.Client;
using Service.Charger.Msg.Charger.OutCharger.Req;
using Service.Charger.Msg.Charger.Req;
using Service.Charger.Msg.Http.Req;
using Service.Init;
namespace Service.Charger.MyTask;
/// <summary>
/// 9.2.1.5 站控上报充电枪实时数据上报
/// </summary>
@ -40,13 +43,12 @@ public class PileRealtimeTask : ITask
foreach (var kvp in chargerClients)
{
ChargerClient client = kvp.Value;
byte mode = (byte)ChargerModeConst.OutsideTheStation;
HandleChargerPile(client, 1);
HandleChargerPile(client, 2);
HandleChargerPile(client, mode);
}
}
public bool Stoped()
{
@ -62,21 +64,23 @@ public class PileRealtimeTask : ITask
{
_stop = false;
}
private void HandleChargerPile(ChargerClient client, byte pileIndex)
private void HandleChargerPile(ChargerClient client, byte mode)
{
if (client.ChargedPile[pileIndex])
if (client.Connected && client.ChargerMode == mode)
{
ChargerPile chargerPile = client.ChargerPile[pileIndex];
PileUploadTelemetry pileUploadTelemetry = client.PileUploadTelemetry[pileIndex];
ChargerPile chargerPile = client.ChargerPile;
UploadTelemetryData uploadTelemetryData = client.UploadTelemetryData;
UploadRemoteSignalData uploadRemoteSignalData = client.UploadRemoteSignalData;
PileRealtimeReq req = new PileRealtimeReq
{
sn = StaticStationInfo.StationNo,
pn = chargerPile.pn,
ps = GetPileStatus(chargerPile.WorkStatus),
pov = pileUploadTelemetry.BmsChargingVoltage,
poe = pileUploadTelemetry.BmsChargingCurrent,
ps = GetPileStatus(uploadRemoteSignalData.WorkStatus),
pov = uploadTelemetryData.DcMeterVoltage,
poe = uploadTelemetryData.DcMeterCurrent,
ec = 0
};
@ -91,10 +95,8 @@ public class PileRealtimeTask : ITask
0 => 1,
1 => 3,
2 => 4,
3 => 5,
3 => 6,
_ => 1
};
}
}

@ -1,4 +1,5 @@
using AutoMapper;
using Common.Const;
using Entity.DbModel.Station;
using Entity.Dto.Req;
using Entity.Dto.Resp;
@ -137,7 +138,7 @@ public class ChargeController : ControllerBase
[Route("StartChargeByBinNo/{binNo}")]
public Result<bool> StartChargeByBinNo(string binNo)
{
return _chargerService.StartChargeByBinNo(binNo);
return _chargerService.StartChargeByBinNo((byte)ChargerModeConst.OnSite,binNo);
}
/// <summary>

@ -1,4 +1,5 @@
using Entity.Dto.Resp;
using Common.Const;
using Entity.Dto.Resp;
using HybirdFrameworkCore.Entity;
using Microsoft.AspNetCore.Mvc;
using Repository.Station;
@ -34,37 +35,33 @@ public class OutChargerController
public Result<bool> SendStartOutCharger([FromBody] PileStartChargeHttpReq httpReq)
{
string chargerCode = ChargerUtils.GetOutChargerCode(httpReq.pn);
byte chargerGunCode = ChargerUtils.GetTheGun(httpReq.pn);
var chargerCode = httpReq.pn;
ChargerClient? chargerClient = ClientMgr.GetBySn(chargerCode);
if (chargerClient == null)
{
return Result<bool>.Fail("充电机未连接");
}
string chargeGunOrder = ChargerUtils.GenChargeOrderSn();
if (string.IsNullOrWhiteSpace(httpReq.con))
{
httpReq.con = chargeGunOrder;
}
chargerClient.ChargerPile[chargerGunCode].ct = httpReq.ct;
chargerClient.ChargerPile[chargerGunCode].cp = httpReq.cp;
chargerClient.ChargerPile[chargerGunCode].st = httpReq.st;
chargerClient.ChargerPile[chargerGunCode].con = httpReq.con;
chargerClient.ChargerPile[chargerGunCode].cosn = chargeGunOrder;
chargerClient.ChargerPile[chargerGunCode].pn = httpReq.pn;
chargerClient.ChargerPile.ct = httpReq.ct;
chargerClient.ChargerPile.cp = httpReq.cp;
chargerClient.ChargerPile.st = httpReq.st;
chargerClient.ChargerPile.con = httpReq.con;
chargerClient.ChargerPile.cosn = chargeGunOrder;
chargerClient.ChargerPile.pn = httpReq.pn;
byte chargeSoc = StaticStationInfo.ChargeSoc;
// 下发充电枪充电
chargerClient.SendStartOutCharger(chargerGunCode, chargeSoc, 360, 1, chargeGunOrder);
chargerClient.SendRemoteStartCharging((byte)ChargerModeConst.OutsideTheStation, chargeSoc, 360, 1, chargeGunOrder);
// 初始化订单
_chargeOrderRepository.SaveChargeGunOrder(chargeGunOrder, httpReq.con, chargerCode, httpReq.pn,
chargerGunCode.ToString());
chargerCode);
return Result<bool>.Success(true);
}
@ -78,11 +75,8 @@ public class OutChargerController
[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);
ChargerClient? chargerClient = ClientMgr.GetBySn(httpReq.pn);
if (chargerClient == null)
{
@ -90,7 +84,7 @@ public class OutChargerController
}
// 下发充电枪停止充电
chargerClient.SendStopOutCharger(chargerGunCode, 0);
chargerClient.SendRemoteStopCharging();
return Result<bool>.Success(true);
}
@ -106,52 +100,20 @@ public class OutChargerController
[Route("SendPowerRegulation/{code}/{pn}/{power}")]
public Result<bool> SendPowerRegulation(string code,byte pn, float power)
{
if (power <=0 || power > 280)
if (power <=0 || power > 360)
{
return Result<bool>.Fail("功率值范围1到360");
}
if (pn != 1 && pn != 2)
{
return Result<bool>.Fail("请选择1枪或者2枪");
}
ChargerClient? chargerClient = ClientMgr.GetBySn(code);
if (chargerClient != null)
{
chargerClient.SendPileAdjustPower(pn,power);
chargerClient.SendPowerRegulation(power);
return Result<bool>.Success(true);
}
return Result<bool>.Fail("充电机未连接");
}
/// <summary>
/// 获取充电桩信息
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("GetChargerPile")]
public Result<List<ChargerPileResp>> GetChargerPile()
{
var chargerClients = ClientMgr.Dictionary;
if (chargerClients.IsEmpty)
{
return Result<List<ChargerPileResp>>.Fail("没有充电机连接");
}
var list = chargerClients.Values.Select(client => new ChargerPileResp
{
Sn = client.Sn,
GunChargedOne = client.GunCharged[1],
GunChargedTwo = client.GunCharged[2],
ChargedPileOne = client.ChargedPile[1],
ChargedPileTwo = client.ChargedPile[2],
ChargePilePowerOne = client.ChargePilePower[1],
ChargePilePowerTwo = client.ChargePilePower[2]
}).ToList();
return Result<List<ChargerPileResp>>.Success(list);
}
}

@ -175,7 +175,7 @@ public partial class Form2 : Form
private void btnStartCharge_Click(object sender, EventArgs e)
{
Result<string> chargeOrderNo = _chargerClient.SendRemoteStartCharging(100);
Result<string> chargeOrderNo = _chargerClient.SendRemoteStartCharging(1,100);
_chargerClient.ChargeOrderNo = chargeOrderNo.Data;
MessageBox.Show(@"发送成功");
DisplayData();

Loading…
Cancel
Save