站外优化

zw
tq 5 months ago
parent 662022ecce
commit ca28c4b23b

@ -3,6 +3,9 @@ using Newtonsoft.Json;
namespace Common.Util; namespace Common.Util;
/// <summary>
/// http工具类
/// </summary>
public static class HttpUtil public static class HttpUtil
{ {
private static readonly HttpClient httpClient = new HttpClient(); private static readonly HttpClient httpClient = new HttpClient();

@ -18,9 +18,9 @@ using Service.Charger.Msg;
using Service.Charger.Msg.Charger.OutCharger.Req; using Service.Charger.Msg.Charger.OutCharger.Req;
using Service.Charger.Msg.Charger.Req; using Service.Charger.Msg.Charger.Req;
using Service.Charger.Msg.Charger.Resp; 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;
using Service.Charger.Msg.Host.Req.Bms; using Service.Charger.Msg.Host.Req.Bms;
using Service.Charger.Msg.Host.Req.OutCharger.Req;
namespace Service.Charger.Client; namespace Service.Charger.Client;
@ -545,6 +545,24 @@ public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
return Result<string>.Success(); return Result<string>.Success();
} }
/// <summary>
/// 3.7.9 监控平台发送充电桩功率调节指令
/// </summary>
/// <param name="pn"></param>
/// <param name="expectedOperatingPower"></param>
/// <returns></returns>
public Result<bool> SendPileAdjustPower(byte pn,float expectedOperatingPower)
{
if (!Connected)
{
return Result<bool>.Fail($"charger-{BinNo} disconnect");
}
PileAdjustPower powerRegulation = new PileAdjustPower(pn,expectedOperatingPower);
this.Channel.WriteAndFlushAsync(powerRegulation);
return Result<bool>.Success();
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

@ -46,5 +46,10 @@ public class ChargerPile
/// 充电枪的唯一标识码 /// 充电枪的唯一标识码
/// </summary> /// </summary>
public string? pn { get; set; } public string? pn { get; set; }
/// <summary>
/// 工作状态
/// </summary>
public byte WorkStatus { get; set; }
} }

@ -250,6 +250,7 @@ public class Decoder : ByteToMessageDecoder
12 => ModelConvert.Decode<PileUploadTelemetry>(bytes), 12 => ModelConvert.Decode<PileUploadTelemetry>(bytes),
11 => ModelConvert.Decode<PileUploadRemoteSignal>(bytes), 11 => ModelConvert.Decode<PileUploadRemoteSignal>(bytes),
14 => ModelConvert.Decode<PileUploadChargeRecord>(bytes), 14 => ModelConvert.Decode<PileUploadChargeRecord>(bytes),
10 => ModelConvert.Decode<PileAdjustPowerRes>(bytes),
_ => throw new InvalidOperationException("This should never be reached"), _ => throw new InvalidOperationException("This should never be reached"),
}, },
#endregion #endregion

@ -0,0 +1,22 @@
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}");
}
}
}

@ -11,6 +11,7 @@ using Service.Charger.Msg.Charger.OutCharger.Resp;
using Service.Charger.Msg.Http.Resp; using Service.Charger.Msg.Http.Resp;
namespace Service.Charger.Handler.OutCharger; namespace Service.Charger.Handler.OutCharger;
/// <summary> /// <summary>
/// 3.7.2 充电桩响应远程启动充电 /// 3.7.2 充电桩响应远程启动充电
/// </summary> /// </summary>
@ -20,7 +21,7 @@ public class PileStartChargeResHandler : SimpleChannelInboundHandler<PileStartCh
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(PileStartChargeResHandler)); private static readonly ILog Log = LogManager.GetLogger(typeof(PileStartChargeResHandler));
public ChargeOrderRepository ChargeOrderRepository { get; set; } public ChargeOrderRepository ChargeOrderRepository { get; set; }
protected override void ChannelRead0(IChannelHandlerContext ctx, PileStartChargeRes msg) protected override void ChannelRead0(IChannelHandlerContext ctx, PileStartChargeRes msg)
{ {

@ -38,7 +38,7 @@ public class PileStopChargeResHandler : SimpleChannelInboundHandler<PileStopChar
PileStopChargeHttpRes res = new PileStopChargeHttpRes(); PileStopChargeHttpRes res = new PileStopChargeHttpRes();
res.pn = chargeOrder.ChargerGunNo; res.pn = chargeOrder.ChargerGunNo;
res.rs = msg.rs.ToString(); res.rs = msg.rs.ToString();
HttpUtil.SendPostRequest(res, "http://127.0.0.1:5034/api/OutCharger/ResStartOutCharger"); HttpUtil.SendPostRequest(res, "http://127.0.0.1:5034/api/OutCharger/ResStopOutCharger");
} }
} }
} }

@ -102,8 +102,7 @@ public class PileUploadChargeRecordHandler : SimpleChannelInboundHandler<PileUpl
ChargeOrderRepository.Update(chargeOrder); ChargeOrderRepository.Update(chargeOrder);
PileEndChargeReq req = new PileEndChargeReq(); PileEndChargeReq req = new PileEndChargeReq();
req.sn = StaticStationInfo.StationNo; req.sn = StaticStationInfo.StationNo;
req.con = chargeOrder.CloudChargeOrder; req.con = chargeOrder.CloudChargeOrder;
req.cosn = chargeOrder.Sn; req.cosn = chargeOrder.Sn;

@ -26,7 +26,8 @@ public class PileUploadRemoteSignalHandler: SimpleChannelInboundHandler<PileUplo
client.GunCharged[msg.Pn] = msg.WorkStatus == 1 ? true : false; client.GunCharged[msg.Pn] = msg.WorkStatus == 1 ? true : false;
client.ChargedPile[msg.Pn] = msg.ChargeStationGunHolderStatus; client.ChargedPile[msg.Pn] = !msg.ChargeStationGunHolderStatus;
client.ChargerPile[msg.Pn].WorkStatus = msg.WorkStatus;

@ -0,0 +1,35 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Charger.OutCharger.Resp;
/// <summary>
/// 3.7.10 充电桩应答功率调节指令
/// </summary>
public class PileAdjustPowerRes: 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,42 @@
using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Host.Req.OutCharger.Req;
/// <summary>
/// 3.7.9 监控平台发送充电桩功率调节指令
/// </summary>
public class PileAdjustPower: 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(8, 16, PropertyReadConstant.Bit, 0.1, 1)]
public float ExpectPower { get; set; }
public PileAdjustPower(byte pn,float expectPower)
{
RecordType = 9;
FrameTypeNo = 51;
MsgBodyCount = 1;
TransReason = 3;
PublicAddr = 0;
MsgBodyAddr = new byte[] { 0, 0, 0 };
Pn = pn;
ExpectPower = expectPower;
}
}

@ -1,6 +1,6 @@
using HybirdFrameworkCore.Autofac.Attribute; using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Host.OutCharger.Req; namespace Service.Charger.Msg.Host.Req.OutCharger.Req;
/// <summary> /// <summary>
/// 3.7.1 监控平台远程启动充电桩充电 /// 3.7.1 监控平台远程启动充电桩充电

@ -1,6 +1,6 @@
using HybirdFrameworkCore.Autofac.Attribute; using HybirdFrameworkCore.Autofac.Attribute;
namespace Service.Charger.Msg.Host.OutCharger.Req; namespace Service.Charger.Msg.Host.Req.OutCharger.Req;
/// <summary> /// <summary>
/// 3.7.3 监控平台远程停止充电桩充电 /// 3.7.3 监控平台远程停止充电桩充电

@ -0,0 +1,45 @@
namespace Service.Charger.Msg.Http.Req;
/// <summary>
/// 9.2.1.5 站控上报充电枪实时数据上报
/// </summary>
public class PileRealtimeReq
{
/// <summary>
/// 换电站编码
/// </summary>
public string sn { get; set; }
/// <summary>
/// Desc:充电枪编号
/// Default:
/// Nullable:True
/// </summary>
public string? pn { get; set; }
/// <summary>
/// 充电枪状态
/// </summary>
public int ps { get; set; }
/// <summary>
/// 插枪状态
/// </summary>
public int con { get; set; }
/// <summary>
/// 单枪输出电压
/// </summary>
public float pov { get; set; }
/// <summary>
/// 单枪输出电流
/// </summary>
public float poe { get; set; }
/// <summary>
/// 单枪故障代码
/// </summary>
public int ec { get; set; }
}

@ -0,0 +1,103 @@
using System.Collections.Concurrent;
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.7 站控上报充电枪充电遥测数据
/// </summary>
[Scope]
public class PileChargeRealtimeTask : ITask
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PileChargeRealtimeTask));
private volatile bool _stop;
public string Name()
{
return "PileChargeRealtimeTask";
}
public int Interval()
{
return 1000 * 30;
}
public void Handle()
{
ConcurrentDictionary<string, ChargerClient> chargerClients = ClientMgr.Dictionary;
if (chargerClients.Values.Count <= 0)
{
return;
}
foreach (var clientPair in chargerClients)
{
ChargerClient client = clientPair.Value;
ProcessClient(client, 1);
ProcessClient(client, 2);
}
}
private void ProcessClient(ChargerClient client, byte gunNumber)
{
if (client.GunCharged[gunNumber])
{
ChargerPile chargerPile = client.ChargerPile[gunNumber];
PileUploadTelemetry telemetry = client.PileUploadTelemetry[gunNumber];
PileUploadRemoteSignal pileUploadRemoteSignal = client.PileUploadRemoteSignal[gunNumber];
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
};
HttpUtil.SendPostRequest(req, "http://127.0.0.1:5034/api/OutCharger/SendPileChargeRealtime");
}
}
public bool Stoped()
{
return _stop;
}
public void Stop()
{
_stop = true;
}
public void ResetStop()
{
_stop = false;
}
}

@ -0,0 +1,100 @@
using System.Collections.Concurrent;
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.Http.Req;
using Service.Init;
namespace Service.Charger.MyTask;
/// <summary>
/// 9.2.1.5 站控上报充电枪实时数据上报
/// </summary>
[Scope]
public class PileRealtimeTask : ITask
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PileRealtimeTask));
private volatile bool _stop;
public string Name()
{
return "PileRealtimeTask";
}
public int Interval()
{
return 1000 * 5;
}
public void Handle()
{
ConcurrentDictionary<string, ChargerClient> chargerClients = ClientMgr.Dictionary;
if (chargerClients.Values.Count <= 0)
{
return;
}
foreach (var kvp in chargerClients)
{
ChargerClient client = kvp.Value;
HandleChargerPile(client, 1);
HandleChargerPile(client, 2);
}
}
public bool Stoped()
{
return _stop;
}
public void Stop()
{
_stop = true;
}
public void ResetStop()
{
_stop = false;
}
private void HandleChargerPile(ChargerClient client, byte pileIndex)
{
if (client.ChargedPile[pileIndex])
{
ChargerPile chargerPile = client.ChargerPile[pileIndex];
PileUploadTelemetry pileUploadTelemetry = client.PileUploadTelemetry[pileIndex];
PileRealtimeReq req = new PileRealtimeReq
{
sn = StaticStationInfo.StationNo,
pn = chargerPile.pn,
ps = GetPileStatus(chargerPile.WorkStatus),
pov = pileUploadTelemetry.BmsChargingVoltage,
poe = pileUploadTelemetry.BmsChargingCurrent,
ec = 0
};
HttpUtil.SendPostRequest(req, "http://127.0.0.1:5034/api/OutCharger/SendPileRealtime");
}
}
private int GetPileStatus(int workStatus)
{
return workStatus switch
{
0 => 1,
1 => 3,
2 => 4,
3 => 5,
_ => 1
};
}
}

@ -32,6 +32,7 @@ public class OutChargerController
[Route("SendStartOutCharger")] [Route("SendStartOutCharger")]
public Result<bool> SendStartOutCharger([FromBody] PileStartChargeHttpReq httpReq) public Result<bool> SendStartOutCharger([FromBody] PileStartChargeHttpReq httpReq)
{ {
string chargerCode = ChargerUtils.GetOutChargerCode(httpReq.pn); string chargerCode = ChargerUtils.GetOutChargerCode(httpReq.pn);
byte chargerGunCode = ChargerUtils.GetTheGun(httpReq.pn); byte chargerGunCode = ChargerUtils.GetTheGun(httpReq.pn);
@ -92,4 +93,36 @@ public class OutChargerController
return Result<bool>.Success(true); return Result<bool>.Success(true);
} }
/// <summary>
/// 给充电枪发送功率调节指令
/// </summary>
/// <param name="code">充电机code</param>
/// <param name="pn">1枪 or 2枪</param>
/// <param name="power">功率</param>
/// <returns></returns>
[HttpGet]
[Route("SendPowerRegulation/{code}/{pn}/{power}")]
public Result<bool> SendPowerRegulation(string code,byte pn, float power)
{
if (power <=0 || power > 280)
{
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);
return Result<bool>.Success(true);
}
return Result<bool>.Fail("充电机未连接");
}
} }
Loading…
Cancel
Save