1657 lines
69 KiB
C#
1657 lines
69 KiB
C#
using HslCommunication.ModBus;
|
||
using NLog;
|
||
using OrpaonEMS.App.Models;
|
||
using OrpaonEMS.Core.DbModel;
|
||
using OrpaonEMS.Core.Enums;
|
||
using OrpaonEMS.Core;
|
||
using Stateless;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Diagnostics.Metrics;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using Prism.Mvvm;
|
||
using OrpaonEMS.Model;
|
||
using OrpaonEMS.Model.Enums;
|
||
using Prism.Events;
|
||
using OrpaonEMS.App.PrismEvent;
|
||
using OrpaonEMS.App.Com;
|
||
using NLog.Targets;
|
||
using System.Diagnostics.Eventing.Reader;
|
||
using HslCommunication.WebSocket;
|
||
using HslCommunication;
|
||
using OrpaonEMS.Model.MasterSlave;
|
||
using System.Text.Json;
|
||
using Windows.ApplicationModel.Contacts;
|
||
|
||
namespace OrpaonEMS.App.Services
|
||
{
|
||
/// <summary>
|
||
/// 储能服务
|
||
/// https://blog.csdn.net/zwcslj/article/details/136363261
|
||
/// </summary>
|
||
public class EnergyStorageService : BindableBase
|
||
{
|
||
///// <summary>
|
||
///// 负载仪表数据
|
||
/// 伊顿客户提供的仪表
|
||
///// </summary>
|
||
//public KEMeter kEMeter { get; set; } = new KEMeter();
|
||
|
||
/// <summary>
|
||
/// 安科瑞仪表数据
|
||
/// 储能本身的计量数据
|
||
/// </summary>
|
||
public AcrelMeterDataService AcrelMeters { get; set; }
|
||
public PwAnalyzeService PwAnalyzeService { get; }
|
||
|
||
///// <summary>
|
||
///// 分布式控制
|
||
///// 主从站通信
|
||
///// </summary>
|
||
//public EMSService MasterSlave { get; set; }
|
||
|
||
/// <summary>
|
||
/// NLog服务集合
|
||
/// </summary>
|
||
public ILogService LogService { get; }
|
||
|
||
/// <summary>
|
||
/// 储能统计分析
|
||
/// </summary>
|
||
public PwAnalyzeService pwAnalyze { get; set; }
|
||
|
||
/// <summary>
|
||
/// 是否为主站
|
||
/// </summary>
|
||
public bool IsMaster { get; set; }
|
||
|
||
/// <summary>
|
||
/// 实例化
|
||
/// </summary>
|
||
public EnergyStorageService(ILogService logService,
|
||
BmsDataService bmsDataService,
|
||
SolarEnergyService solarEnergyService,
|
||
InPowerPCSDataService inPowerPCSDataService,
|
||
IFreeSql freeSql,
|
||
ACService aCService,
|
||
AcrelMeterDataService acrelMeterDataService,
|
||
PwAnalyzeService pwAnalyzeService,
|
||
ConfigDataService configDataService)
|
||
{
|
||
//Log服务实例赋值
|
||
LogService = logService;
|
||
|
||
AcrelMeters = acrelMeterDataService;
|
||
|
||
//获取Bms服务实例
|
||
BmsDataService = bmsDataService;
|
||
//获取太阳储能的服务
|
||
SolarEnergyService = solarEnergyService;
|
||
|
||
//获取英博PCS服务实例
|
||
InPowerPCSDataService = inPowerPCSDataService;
|
||
|
||
//FreeSQL实例
|
||
FreeSql = freeSql;
|
||
ACService = aCService;
|
||
|
||
//ListEnergyStoragePeakValleyTimeConfig = new List<PeakValleyConfig>();
|
||
|
||
//获取配置服务实例
|
||
ConfigDataService = configDataService;
|
||
WebUrl = ConfigDataService.ServerUrl;
|
||
|
||
IsMaster = ConfigDataService.IsMaster;
|
||
|
||
if (IsMaster)
|
||
{
|
||
//作为服务时,站号是固定的
|
||
ClientStation = 0;
|
||
}
|
||
else
|
||
{
|
||
ClientStation = ConfigDataService.Station;
|
||
}
|
||
CurClientInfo.Station = ClientStation;
|
||
|
||
//PCS的追踪模型,初始值设置为0
|
||
InPowerPCSDataService.PwTranceCmdValues.CmdValue = 0;
|
||
|
||
//伊顿电表服务 特制
|
||
//PwMeters = new PwMeter();
|
||
|
||
//状态机初始化参数配置
|
||
StateMachineInitial();
|
||
|
||
//注入当前的实例
|
||
TrigModuleStartRunActions = new TrigModuleStartRunAction(this);
|
||
|
||
//云服务实例化
|
||
////服务实例化
|
||
//esModbusTcpServer = new EsModbusTcpServer();
|
||
//esModbusTcpServer.StartServer();
|
||
|
||
//ModbusTcpServerTask = Task.Run(() => ModbusTcpServerCycle());
|
||
|
||
//mqttClientDrive = new MqttClientDrive("139.224.230.213", "1883", "b1955190-d471-11ee-a961-354c6e00783a", "ter354uyQbK81JF6xWH9", "", "v1/devices/me/telemetry");
|
||
//mqttClientDrive.CurMsg = "{\r\n \"stringKey\": \"value1\",\r\n \"booleanKey\": true,\r\n \"doubleKey\": 42.0,\r\n \"longKey\": 73,\r\n \"jsonKey\": {\r\n \"someNumber\": 42,\r\n \"someArray\": [1,2,3],\r\n \"someNestedObject\": {\"key\": \"value\"}\r\n }\r\n}";
|
||
|
||
//实例化能耗统计分析模型
|
||
PwAnalyzeService = pwAnalyzeService;
|
||
//pwAnalyze = new PwAnalyze(this, LogService, FreeSql, ConfigDataService);
|
||
//MasterSlave = new EMSService(LogService, InPowerPCSDataService, BmsDataService, ConfigDataService, this);
|
||
WebSocketClientInit();
|
||
}
|
||
|
||
#region ModbusTcpServer
|
||
|
||
///// <summary>
|
||
///// ModbusTcp服务
|
||
///// </summary>
|
||
//public EsModbusTcpServer esModbusTcpServer { get; set; } = null;
|
||
|
||
//public MqttClientDrive mqttClientDrive { get; set; }
|
||
|
||
///// <summary>
|
||
///// ModbusTcp 的服务周期
|
||
///// </summary>
|
||
//public Task ModbusTcpServerTask = null;
|
||
|
||
|
||
///// <summary>
|
||
///// 循环赋值
|
||
///// </summary>
|
||
///// <returns></returns>
|
||
//private async Task ModbusTcpServerCycle()
|
||
//{
|
||
// Thread.Sleep(10000);
|
||
// while (ThreadEnable)
|
||
// {
|
||
// try
|
||
// {
|
||
// if (esModbusTcpServer.IsOpenServer())
|
||
// {
|
||
// //BMS
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;1", BmsDataService.ListBMSRoCell.Find(a => a.Name == "电池簇总SOC").SrRtValue);
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;2", BmsDataService.ListBMSRoCell.Find(a => a.Name == "电池簇总SOH").SrRtValue);
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;3", BmsDataService.ListBMSRoCell.Find(a => a.Name == "电池最高温度").SrRtValue);
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;4", BmsDataService.ListBMSRoCell.Find(a => a.Name == "电池最高温度所在模块号").SrRtValue);
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;5", BmsDataService.ListBMSRoCell.Find(a => a.Name == "电池最低温度").SrRtValue);
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;6", BmsDataService.ListBMSRoCell.Find(a => a.Name == "电池最低温度所在模块号").SrRtValue);
|
||
|
||
// //PCS
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;7", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(InPowerPCSDataService.OperateResultBytes1.Content, 0));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;8", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(InPowerPCSDataService.OperateResultBytes1.Content, 2));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;9", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(InPowerPCSDataService.OperateResultBytes1.Content, 4));
|
||
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;10", esModbusTcpServer.busTcpServer.ByteTransform.TransInt16(InPowerPCSDataService.OperateResultBytes1.Content, 6));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;11", esModbusTcpServer.busTcpServer.ByteTransform.TransInt16(InPowerPCSDataService.OperateResultBytes1.Content, 8));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;12", esModbusTcpServer.busTcpServer.ByteTransform.TransInt16(InPowerPCSDataService.OperateResultBytes1.Content, 10));
|
||
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;13", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(InPowerPCSDataService.OperateResultBytes1.Content, 12));
|
||
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;14", esModbusTcpServer.busTcpServer.ByteTransform.TransInt16(InPowerPCSDataService.OperateResultBytes1.Content, 20));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;15", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(InPowerPCSDataService.OperateResultBytes1.Content, 36));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;16", esModbusTcpServer.busTcpServer.ByteTransform.TransInt16(InPowerPCSDataService.OperateResultBytes1.Content, 28));
|
||
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;17", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(InPowerPCSDataService.OperateResultBytes1.Content, 44));
|
||
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;18", esModbusTcpServer.busTcpServer.ByteTransform.TransInt16(InPowerPCSDataService.OperateResultBytes1.Content, 52));
|
||
|
||
// //电表数据
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;20", esModbusTcpServer.busTcpServer.ByteTransform.TransSingle(AcrelMeters.OperateResultBytes1.Content, 52));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;22", esModbusTcpServer.busTcpServer.ByteTransform.TransSingle(AcrelMeters.OperateResultBytes1.Content, 68));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;24", esModbusTcpServer.busTcpServer.ByteTransform.TransSingle(AcrelMeters.OperateResultBytes1.Content, 0));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;26", esModbusTcpServer.busTcpServer.ByteTransform.TransSingle(AcrelMeters.OperateResultBytes1.Content, 4));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;28", esModbusTcpServer.busTcpServer.ByteTransform.TransSingle(AcrelMeters.OperateResultBytes1.Content, 8));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;30", esModbusTcpServer.busTcpServer.ByteTransform.TransSingle(AcrelMeters.OperateResultBytes1.Content, 24));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;32", esModbusTcpServer.busTcpServer.ByteTransform.TransSingle(AcrelMeters.OperateResultBytes1.Content, 28));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;34", esModbusTcpServer.busTcpServer.ByteTransform.TransSingle(AcrelMeters.OperateResultBytes1.Content, 32));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;36", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt32(AcrelMeters.OperateResultBytes3.Content, 0));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;38", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt32(AcrelMeters.OperateResultBytes3.Content, 72));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;40", esModbusTcpServer.busTcpServer.ByteTransform.TransSingle(AcrelMeters.OperateResultBytes1.Content, 100));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;42", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(AcrelMeters.OperateResultBytes2.Content, 0));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;43", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(AcrelMeters.OperateResultBytes2.Content, 2));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;44", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(AcrelMeters.OperateResultBytes2.Content, 4));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;45", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(AcrelMeters.OperateResultBytes2.Content, 6));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;46", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(AcrelMeters.OperateResultBytes2.Content, 8));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;47", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt16(AcrelMeters.OperateResultBytes2.Content, 10));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;50", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt32(AcrelMeters.OperateResultBytes3.Content, 8));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;52", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt32(AcrelMeters.OperateResultBytes3.Content, 16));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;54", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt32(AcrelMeters.OperateResultBytes3.Content, 24));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;56", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt32(AcrelMeters.OperateResultBytes3.Content, 32));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;58", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt32(AcrelMeters.OperateResultBytes3.Content, 0));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;60", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt32(AcrelMeters.OperateResultBytes3.Content, 88));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;62", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt32(AcrelMeters.OperateResultBytes3.Content, 96));
|
||
// esModbusTcpServer.busTcpServer.Write("x=4;64", esModbusTcpServer.busTcpServer.ByteTransform.TransUInt32(AcrelMeters.OperateResultBytes3.Content, 104));
|
||
|
||
|
||
// }
|
||
|
||
// }
|
||
// catch (Exception ex)
|
||
// {
|
||
// LogService.Info($"时间:{DateTime.Now.ToString()}-【ExitPeakValley】-{ex.Message}");
|
||
// }
|
||
|
||
// await Task.Delay(2000);
|
||
// }
|
||
|
||
|
||
//}
|
||
|
||
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 线程启用的标志位
|
||
/// 退出关闭标志位
|
||
/// </summary>
|
||
public bool ThreadEnable { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 当前系统报警消息内容
|
||
/// 不是来自设备实际报警
|
||
/// 来自软件判断
|
||
/// </summary>
|
||
public string CurSysAlarmMsg { get; set; }
|
||
|
||
#region 储能指令函数
|
||
//MasterSlave
|
||
|
||
|
||
/// <summary>
|
||
/// 储能充电指令
|
||
/// 可实时调用这个方法
|
||
/// 英博PCS 正从电网充电
|
||
/// 可实时给值
|
||
/// </summary>
|
||
/// <param name="targetpw"></param>
|
||
public void ChargPwCmd(double targetpw)
|
||
{
|
||
//指令状态
|
||
//EsSysCmdState = EnergyStoryageCmdState.ChargeValue;
|
||
if (BmsDataService.MaxChargePowerCell.RtValue * ConfigDataService.energyStorageRunConfig.MaxBatChargRatio < Math.Abs(targetpw))//超过了限值
|
||
{
|
||
//超过了限值就按照最大的限值发送
|
||
InPowerPCSDataService.PwTranceCmdValues.CmdValue = Math.Abs(BmsDataService.MaxChargePowerCell.RtValue * ConfigDataService.energyStorageRunConfig.MaxBatChargRatio) + 0;
|
||
return;
|
||
}
|
||
|
||
//实时写入到追踪模型中,变化大于阀值则发数据给PCS 让总关口电表为正不能为0
|
||
InPowerPCSDataService.PwTranceCmdValues.CmdValue = Math.Abs(targetpw) / 1.0 + ConfigDataService.energyStorageRunConfig.PcsChargOffset;
|
||
|
||
|
||
////指令状态 没有分布式之前
|
||
//EsSysCmdState = EnergyStoryageCmdState.ChargeValue;
|
||
//if (BmsDataService.MaxChargePowerCell.RtValue * ConfigDataService.energyStorageRunConfig.MaxBatChargRatio < Math.Abs(targetpw))//超过了限值
|
||
//{
|
||
// //超过了限值就按照最大的限值发送
|
||
// InPowerPCSDataService.PwTranceCmdValues.CmdValue = Math.Abs(BmsDataService.MaxChargePowerCell.RtValue * ConfigDataService.energyStorageRunConfig.MaxBatChargRatio) + 0;
|
||
// return;
|
||
//}
|
||
|
||
////实时写入到追踪模型中,变化大于阀值则发数据给PCS 让总关口电表为正不能为0
|
||
//InPowerPCSDataService.PwTranceCmdValues.CmdValue = Math.Abs(targetpw) / 1.0 + ConfigDataService.energyStorageRunConfig.PcsChargOffset;
|
||
}
|
||
|
||
///// <summary>
|
||
///// 计算或者获取Pcs的目标指令值
|
||
///// </summary>
|
||
//private double PcsTargetPw { get; set; }
|
||
|
||
/// <summary>
|
||
/// 储能放电指令
|
||
/// 英博PCS 负给电网放电
|
||
/// 可实时给值
|
||
/// </summary>
|
||
/// <param name="targetpw"></param>
|
||
public void DisChargPwCmd(double targetpw)
|
||
{
|
||
//指令状态
|
||
//EsSysCmdState = EnergyStoryageCmdState.DischargeValue;
|
||
|
||
if (BmsDataService.MaxDisChargePowerCell.RtValue * ConfigDataService.energyStorageRunConfig.MaxBatDisChargRatio < Math.Abs(targetpw))//超过了限值
|
||
{
|
||
//超过了限值就按照最大的限值发送
|
||
InPowerPCSDataService.PwTranceCmdValues.CmdValue = -(Math.Abs(BmsDataService.MaxDisChargePowerCell.RtValue * ConfigDataService.energyStorageRunConfig.MaxBatDisChargRatio) + 0);
|
||
return;
|
||
}
|
||
|
||
//实时写入到追踪模型中,变化大于阀值则发数据给PCS
|
||
InPowerPCSDataService.PwTranceCmdValues.CmdValue = -(Math.Abs(targetpw) / 1.0 + ConfigDataService.energyStorageRunConfig.PcsDisChargOffset);
|
||
|
||
////指令状态 没有分布式之前
|
||
//EsSysCmdState = EnergyStoryageCmdState.DischargeValue;
|
||
|
||
//if (BmsDataService.MaxDisChargePowerCell.RtValue * ConfigDataService.energyStorageRunConfig.MaxBatDisChargRatio < Math.Abs(targetpw))//超过了限值
|
||
//{
|
||
// //超过了限值就按照最大的限值发送
|
||
// InPowerPCSDataService.PwTranceCmdValues.CmdValue = -(Math.Abs(BmsDataService.MaxDisChargePowerCell.RtValue * ConfigDataService.energyStorageRunConfig.MaxBatDisChargRatio) + 0);
|
||
// return;
|
||
//}
|
||
|
||
////实时写入到追踪模型中,变化大于阀值则发数据给PCS
|
||
//InPowerPCSDataService.PwTranceCmdValues.CmdValue = -(Math.Abs(targetpw) / 1.0 + ConfigDataService.energyStorageRunConfig.PcsDisChargOffset);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送全功率放电
|
||
/// 可实时给值
|
||
/// </summary>
|
||
public void SendFullDisChargePwValueCmd(double cmdValue)
|
||
{
|
||
//指令状态 这里只是标记状态
|
||
//EsSysCmdState = EnergyStoryageCmdState.FullDischarge;
|
||
|
||
//发送全功率的功率值给Pcs
|
||
InPowerPCSDataService.PwTranceCmdValues.CmdValue = -Math.Abs(cmdValue) / 1.0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送全功率充电
|
||
/// 可实时给值
|
||
/// </summary>
|
||
public void SendFullChargePwCmd(double cmdValue)
|
||
{
|
||
//指令状态 这里只是标记状态
|
||
//EsSysCmdState = EnergyStoryageCmdState.FullCharge;
|
||
|
||
//发送全功率的功率值给Pcs
|
||
InPowerPCSDataService.PwTranceCmdValues.CmdValue = Math.Abs(cmdValue) / 1.0 + 0;
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 待机指令
|
||
/// 其实给PCS发送0的功率值则就是待机指令
|
||
/// 可实时给值
|
||
/// </summary>
|
||
public void SendStandby()
|
||
{
|
||
//指令状态 无指令的状态,PCS待机状态 为0的功率值
|
||
//EsSysCmdState = EnergyStoryageCmdState.Standby;
|
||
InPowerPCSDataService.PwTranceCmdValues.CmdValue = 0;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 储能的状态机
|
||
|
||
/// <summary>
|
||
/// 储能状态机初始化配置
|
||
/// </summary>
|
||
private void StateMachineInitial()
|
||
{
|
||
//初始状态是这个状态,不然同一个状态会重复进入导致状态机报错
|
||
_EsSysRunState = EnergyStorageState.Inital;
|
||
|
||
EnergyStorageStateMachine = new StateMachine<EnergyStorageState, EnergyStorageStateTrig>(EnergyStorageState.Inital);
|
||
|
||
//初始状态
|
||
EnergyStorageStateMachine.Configure(EnergyStorageState.Inital)
|
||
.Permit(EnergyStorageStateTrig.HandTrig, EnergyStorageState.Hand)
|
||
.Permit(EnergyStorageStateTrig.StandbyTrig, EnergyStorageState.Standby)
|
||
.Permit(EnergyStorageStateTrig.ReadyCmdTrig, EnergyStorageState.ReadyCmd)
|
||
.Permit(EnergyStorageStateTrig.AlarmTrig, EnergyStorageState.Alarm)
|
||
.Ignore(EnergyStorageStateTrig.InitalTrig);
|
||
|
||
//待机状态
|
||
EnergyStorageStateMachine.Configure(EnergyStorageState.Standby)
|
||
.Permit(EnergyStorageStateTrig.HandTrig, EnergyStorageState.Hand)
|
||
.Permit(EnergyStorageStateTrig.AlarmTrig, EnergyStorageState.Alarm)
|
||
.Permit(EnergyStorageStateTrig.ReadyCmdTrig, EnergyStorageState.ReadyCmd)
|
||
.Ignore(EnergyStorageStateTrig.StandbyTrig)
|
||
.OnEntry(() => EntryStandby())
|
||
.OnExit(() => ExitStandby());
|
||
|
||
//峰谷模式/命令等待 状态
|
||
EnergyStorageStateMachine.Configure(EnergyStorageState.ReadyCmd)
|
||
.Permit(EnergyStorageStateTrig.HandTrig, EnergyStorageState.Hand)
|
||
.Permit(EnergyStorageStateTrig.StandbyTrig, EnergyStorageState.Standby)
|
||
.Permit(EnergyStorageStateTrig.AlarmTrig, EnergyStorageState.Alarm)
|
||
.Ignore(EnergyStorageStateTrig.ReadyCmdTrig)
|
||
.OnEntry(() => EntryReadyCmd())
|
||
.OnExit(() => ExitReadyCmd());
|
||
|
||
//报警状态
|
||
EnergyStorageStateMachine.Configure(EnergyStorageState.Alarm)
|
||
.Permit(EnergyStorageStateTrig.HandTrig, EnergyStorageState.Hand)
|
||
.Permit(EnergyStorageStateTrig.StandbyTrig, EnergyStorageState.Standby)
|
||
.Permit(EnergyStorageStateTrig.ReadyCmdTrig, EnergyStorageState.ReadyCmd)
|
||
.Ignore(EnergyStorageStateTrig.AlarmTrig)
|
||
.OnEntry(() => EntryAlarm())
|
||
.OnExit(() => ExitAlarm());
|
||
|
||
//手动状态
|
||
EnergyStorageStateMachine.Configure(EnergyStorageState.Hand)
|
||
.Permit(EnergyStorageStateTrig.AlarmTrig, EnergyStorageState.Alarm)
|
||
.Permit(EnergyStorageStateTrig.StandbyTrig, EnergyStorageState.Standby)
|
||
.Permit(EnergyStorageStateTrig.ReadyCmdTrig, EnergyStorageState.ReadyCmd)
|
||
.Ignore(EnergyStorageStateTrig.HandTrig)
|
||
.OnEntry(() => EntryHand())
|
||
.OnExit(() => ExitHand());
|
||
|
||
//初始的储能检查
|
||
EnergyStorageCheck();
|
||
|
||
}
|
||
|
||
public TrigModuleStartRunAction TrigModuleStartRunActions { get; set; }
|
||
|
||
/// <summary>
|
||
/// 削峰填谷的线程取消操作
|
||
/// </summary>
|
||
private CancellationTokenSource ReadyCmdTokenSource { get; set; }
|
||
|
||
/// <summary>
|
||
/// 报警的线程取消操作
|
||
/// </summary>
|
||
private CancellationTokenSource AlarmTokenSource;
|
||
|
||
/// <summary>
|
||
/// 待机的线程取消操作
|
||
/// </summary>
|
||
private CancellationTokenSource StandbyTokenSource;
|
||
|
||
/// <summary>
|
||
/// 进入手动模式
|
||
/// 手动模式的优先级比较高,在当前模式下,即使报警了,也不自动跳转。其跳转由人工手动触发,
|
||
/// 手动模式和自动模式,手动模式是一个确定的模式,没有确定和具体的自动模式,自动模式是跳转到包括报警和待机和等待指令的任何一个模式(具体要看当时的情况)
|
||
/// </summary>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void EntryHand()
|
||
{
|
||
HandAutoState = "手动模式";
|
||
|
||
EsSysRunState = EnergyStorageState.Hand;
|
||
CurClientInfo.SysState = "Hand";
|
||
|
||
AutoHandValue = false;
|
||
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能进入【手动】模式 ");
|
||
}
|
||
|
||
private bool _AutoHandValue = true;
|
||
/// <summary>
|
||
/// 手自动值
|
||
/// 手动为False
|
||
/// 自动为True
|
||
/// </summary>
|
||
public bool AutoHandValue
|
||
{
|
||
get { return _AutoHandValue; }
|
||
set { _AutoHandValue = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 退出手动模式
|
||
/// </summary>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void ExitHand()
|
||
{
|
||
HandAutoState = "自动模式";
|
||
AutoHandValue = true;
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能离开【手动】模式 ");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 离开命令等待的模式
|
||
/// </summary>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void ExitReadyCmd()
|
||
{
|
||
try
|
||
{
|
||
//线程取消,防止一直运行和后面的冲突
|
||
ReadyCmdTokenSource.Cancel();
|
||
//离开命令等待,之前可能有遗漏的指令,防止其他的状态残留,那么需要发送PCS待机指令 可能退出之前还是大功率充电
|
||
|
||
SendStandby();
|
||
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能离开【命令等待】模式 ");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogService.Info($"时间:{DateTime.Now.ToString()}-【ExitPeakValley】-{ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 进入储能的等待指令的状态
|
||
/// 则此时需要接受通信的数据
|
||
/// 如果和EMS通信的状态是OK的话,直接执行EMS的指令
|
||
/// </summary>
|
||
private void EntryReadyCmd()
|
||
{
|
||
try
|
||
{
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能进入【等待指令】模式 ");
|
||
|
||
//EsSysRunStateMsg = "峰谷状态";
|
||
EsSysRunState = EnergyStorageState.ReadyCmd;
|
||
CurClientInfo.SysState = "ReadyCmd";
|
||
|
||
ReadyCmdTokenSource = new CancellationTokenSource();
|
||
|
||
//等待EMS指令的状态
|
||
Task.Run(() =>
|
||
{
|
||
//判断储能的状态是否正确
|
||
while (EsSysRunState == EnergyStorageState.ReadyCmd)
|
||
{
|
||
try
|
||
{
|
||
Thread.Sleep(200);
|
||
|
||
//检查储能的状态
|
||
if (!CheckEnergyStorageModuleLink().Result || !CheckEnergyStorageModuleAlarm().Result)//产生报警
|
||
{
|
||
//产生报警,把自动触发PCS运行关闭掉
|
||
//可能运行自动触发PCS运行的循环,先关闭循环,没触发也可以关闭
|
||
TrigModuleStartRunActions.PcsAutoTrigClose();
|
||
|
||
//EsSysRunState=EnergyStorageState.Alarm;
|
||
//产生报警
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能待机状态判断 产生报警 跳转-开始进入重新策略分配 ");
|
||
StrategyAllocate(EnergyStorageState.Alarm);
|
||
break;
|
||
}
|
||
else if (!CheckEnergyStorageModuleRunState().Result)
|
||
{
|
||
//储能的状态出现问题,跳转到待机状态
|
||
//可能运行自动触发PCS运行的循环,先关闭循环,没触发也可以关闭
|
||
TrigModuleStartRunActions.PcsAutoTrigClose();
|
||
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能的状态出现问题,-开始进入待机状态 ");
|
||
StrategyAllocate(EnergyStorageState.Standby);
|
||
break;
|
||
}
|
||
else//依旧存在未正常运行状态,维持当前状态机
|
||
{
|
||
//当处于待机状态时,主要组件没有运行,那么可以通过自动执行指令进行运行指令的操作
|
||
if (true)
|
||
{
|
||
|
||
}
|
||
}
|
||
|
||
|
||
if (ReadyCmdTokenSource.IsCancellationRequested)
|
||
{
|
||
break;
|
||
}
|
||
//先检查跟服务器的状态,服务器的状态没有跟储能本体的状态绑定,分开,方便拆分状态逻辑
|
||
if (EMSSocketClientConState.ConResult)
|
||
{
|
||
switch (CurServerCmd.CmdType)
|
||
{
|
||
case "Charg"://充电
|
||
ChargPwCmd(CurServerCmd.CmdPw);
|
||
break;
|
||
case "DisCharg"://放电
|
||
DisChargPwCmd(CurServerCmd.CmdPw);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
//液冷控制
|
||
if (CurServerCmd.CoolOnOffCmd)
|
||
{
|
||
ACService.SetCoolCtrModel(CoolState.Auto);
|
||
}
|
||
else
|
||
{
|
||
ACService.SetCoolCtrModel(CoolState.Stop);
|
||
}
|
||
|
||
}
|
||
else//和服务器的通信状态失败,那么指令就没有意义了,防止之前的指令残留,设置为0
|
||
{
|
||
switch (CurServerCmd.CmdType)
|
||
{
|
||
case "Charg"://充电
|
||
ChargPwCmd(0);
|
||
break;
|
||
case "DisCharg"://放电
|
||
DisChargPwCmd(0);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogService.Info($"时间:{DateTime.Now.ToString()}-【EntryAlarm】-{ex.Message}");
|
||
}
|
||
}
|
||
}, ReadyCmdTokenSource.Token);
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogService.Info($"时间:{DateTime.Now.ToString()}-【EntryReadyCmd】-{ex.Message}");
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 进入初始化状态
|
||
/// 开始检查各个系统的状态
|
||
/// 确保连接成功和没有报警
|
||
/// </summary>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void EnergyStorageCheck()
|
||
{
|
||
try
|
||
{
|
||
//确保通信连接正常 BMS和PCS 电表
|
||
var LinkData = CheckEnergyStorageModuleLink();
|
||
if (!LinkData.Result)
|
||
{
|
||
//触发报警
|
||
//if (EnergyStorageStateMachine.State != EnergyStorageState.Alarm)
|
||
//{
|
||
EnergyStorageStateMachine.Fire(EnergyStorageStateTrig.AlarmTrig);
|
||
//}
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能初始检查【通信连接失败】");
|
||
CurSysAlarmMsg = LinkData.Msg;
|
||
return;
|
||
}
|
||
|
||
var AlarmData = CheckEnergyStorageModuleAlarm();
|
||
if (!AlarmData.Result)
|
||
{
|
||
//if (EnergyStorageStateMachine.State != EnergyStorageState.Alarm)
|
||
//{
|
||
//触发报警
|
||
EnergyStorageStateMachine.Fire(EnergyStorageStateTrig.AlarmTrig);
|
||
//}
|
||
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能初始检查【报警发生】");
|
||
CurSysAlarmMsg = AlarmData.Msg;
|
||
}
|
||
|
||
if (ConfigDataService.IsStartAuto)
|
||
{
|
||
//如果到这里的话 没有问题的话则进入待机模式
|
||
EnergyStorageStateMachine.Fire(EnergyStorageStateTrig.StandbyTrig);
|
||
}
|
||
else
|
||
{
|
||
EnergyStorageStateMachine.Fire(EnergyStorageStateTrig.HandTrig);
|
||
}
|
||
|
||
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogService.Info($"时间:{DateTime.Now.ToString()}-【PeakValleyCycle】-{ex.Message}");
|
||
}
|
||
}
|
||
|
||
|
||
#region 储能检查
|
||
|
||
///////////////////////////////////////////////////////////////
|
||
///进入储能的削峰填谷的状态模式,需要具备
|
||
///1)模块连接正常
|
||
///2)模块没有报警
|
||
///3)模块运行状态符合要求
|
||
///////////////////////////////////////////////////////////////
|
||
|
||
|
||
/// <summary>
|
||
/// 检查模块通信状态
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private ResultInfo CheckEnergyStorageModuleLink()
|
||
{
|
||
try
|
||
{
|
||
////Test
|
||
if (ConfigDataService.IsDebug)
|
||
{
|
||
return new ResultInfo() { Result = true, Msg = "" };
|
||
}
|
||
|
||
|
||
|
||
//检查BMS通信
|
||
if (!BmsDataService.LinkStateModels.LinkState)
|
||
{
|
||
//Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能检查【BMS通信失败】");
|
||
return new ResultInfo() { Result = false, Msg = "BMS通信失败" };
|
||
}
|
||
|
||
//检查PCS通信
|
||
if (InPowerPCSDataService.PcsRunState.PcsLinkState == LinkState.LinkNG)
|
||
{
|
||
//Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能检查【PCS通信失败】");
|
||
return new ResultInfo() { Result = false, Msg = "PCS通信失败" };
|
||
}
|
||
|
||
//检查电表通信
|
||
if (!AcrelMeters.MeterLinkState)
|
||
{
|
||
//Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能检查【电表通信失败】");
|
||
return new ResultInfo() { Result = false, Msg = "电表通信失败" };
|
||
}
|
||
|
||
//通信成功
|
||
return new ResultInfo() { Result = true, Msg = null };
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
//LogService.Info($"时间:{DateTime.Now.ToString()}-【CheckEnergyStorageModuleLink】-{ex.Message}");
|
||
//通信成功
|
||
return new ResultInfo() { Result = false, Msg = null };
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 检查模块的报警状态
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private ResultInfo CheckEnergyStorageModuleAlarm()
|
||
{
|
||
try
|
||
{
|
||
////Test
|
||
if (ConfigDataService.IsDebug)
|
||
{
|
||
return new ResultInfo() { Result = true, Msg = "" };
|
||
}
|
||
//return new ResultInfo() { Result = true, Msg = "BMS通信失败" };
|
||
|
||
|
||
//检查BMS报警
|
||
if (BmsDataService.BMSAlarmState == BMSAlarmStateEnum.Alarm)
|
||
{
|
||
//Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能检查【BMS报警】");
|
||
return new ResultInfo() { Result = false, Msg = "BMS报警" };
|
||
}
|
||
|
||
//检查PCS报警
|
||
if (InPowerPCSDataService.PcsRunState.PcsSysAlarmState == PcsAlarmState.Alarm)
|
||
{
|
||
//Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能检查【PCS报警】");
|
||
return new ResultInfo() { Result = false, Msg = "PCS报警" };
|
||
}
|
||
|
||
//检查PCS故障
|
||
if (InPowerPCSDataService.PcsRunState.PcsSysFaultState == PcsFaultState.Fault)
|
||
{
|
||
//Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能检查【PCS故障】");
|
||
return new ResultInfo() { Result = false, Msg = "PCS故障" };
|
||
}
|
||
|
||
////检查液冷故障
|
||
//if (BmsDataService.CoolAlarmState)
|
||
//{
|
||
// Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能检查【液冷报警】");
|
||
// return new ResultInfo() { Result = false, Msg = "液冷报警" };
|
||
//}
|
||
|
||
//没有故障发生
|
||
return new ResultInfo() { Result = true, Msg = "" };
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogService.Info($"时间:{DateTime.Now.ToString()}-【CheckEnergyStorageModuleAlarm】-{ex.Message}");
|
||
//没有故障发生
|
||
return new ResultInfo() { Result = true, Msg = "" };
|
||
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 检查储能的运行状态
|
||
/// 报警的优先级更高
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private ResultInfo CheckEnergyStorageModuleRunState()
|
||
{
|
||
try
|
||
{
|
||
////Test
|
||
if (ConfigDataService.IsDebug)
|
||
{
|
||
return new ResultInfo() { Result = true, Msg = "" };
|
||
}
|
||
|
||
//检查BMS运行状态
|
||
if (!BmsDataService.BmsTotalState)
|
||
{
|
||
//Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能检查【BMS未正常运行】");
|
||
return new ResultInfo() { Result = false, Msg = "BMS未正常运行" };
|
||
}
|
||
|
||
//检查PCS运行状态
|
||
if (InPowerPCSDataService.PcsRunState.PcsStateInfo == PCSState.Stop)
|
||
{
|
||
//Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能检查【PCS未运行】");
|
||
return new ResultInfo() { Result = false, Msg = "PCS未运行" };
|
||
}
|
||
|
||
//检查液冷运行状态
|
||
//液冷并不总是运行,根据温度进行逻辑判断,并且液冷不直接影响削峰填谷的执行,报警状态已经能概括液冷的运行状态了
|
||
//if (xxx)
|
||
//{
|
||
// Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能检查【PCS未运行】");
|
||
// return new ResultInfo() { Result = false, Msg = "PCS未运行" };
|
||
//}
|
||
|
||
//检查消防运行状态
|
||
//消防没有运行与否负状态,并且液冷不直接影响削峰填谷的执行,报警状态已经能概括消防的运行状态了
|
||
//if (xxx)
|
||
//{
|
||
// Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能检查【PCS未运行】");
|
||
// return new ResultInfo() { Result = false, Msg = "PCS未运行" };
|
||
//}
|
||
|
||
//正常运行
|
||
return new ResultInfo() { Result = true, Msg = null };
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogService.Info($"时间:{DateTime.Now.ToString()}-【PeakValleyCycle】-{ex.Message}");
|
||
//正常运行
|
||
return new ResultInfo() { Result = true, Msg = null };
|
||
}
|
||
|
||
}
|
||
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 进入储能待机状态
|
||
/// </summary>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void EntryStandby()
|
||
{
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能进入【待机】模式 ");
|
||
|
||
//EsSysRunStateMsg = "待机状态";
|
||
EsSysRunState = EnergyStorageState.Standby;
|
||
CurClientInfo.SysState = "Standby";
|
||
|
||
StandbyTokenSource = new CancellationTokenSource();
|
||
|
||
//报警任务循环
|
||
Task.Run(() =>
|
||
{
|
||
//待机状态时,如果是PCS的停止了,那么需要自动触发PCS运行
|
||
if (InPowerPCSDataService.PcsRunState.PcsStateInfo == PCSState.Stop)
|
||
{
|
||
TrigModuleStartRunActions.PcsAutoTrigRun();
|
||
}
|
||
|
||
//判断储能的状态是否正确
|
||
while (EsSysRunState == EnergyStorageState.Standby)
|
||
{
|
||
try
|
||
{
|
||
Thread.Sleep(100);
|
||
if (StandbyTokenSource.IsCancellationRequested)
|
||
{
|
||
break;
|
||
}
|
||
|
||
//待机状态,可能转到报警,可能转到削峰填谷 报警优先判断
|
||
//循环获取系统的状态
|
||
if (!CheckEnergyStorageModuleLink().Result || !CheckEnergyStorageModuleAlarm().Result)//产生报警
|
||
{
|
||
//可能运行自动触发PCS运行的循环,先关闭循环,没触发也可以关闭
|
||
TrigModuleStartRunActions.PcsAutoTrigClose();
|
||
|
||
//EsSysRunState=EnergyStorageState.Alarm;
|
||
//产生报警
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能待机状态判断 产生报警 跳转-开始进入重新策略分配 ");
|
||
StrategyAllocate(EnergyStorageState.Alarm);
|
||
break;
|
||
}
|
||
else if (CheckEnergyStorageModuleRunState().Result)
|
||
{
|
||
//可能运行自动触发PCS运行的循环,先关闭循环,没触发也可以关闭
|
||
TrigModuleStartRunActions.PcsAutoTrigClose();
|
||
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:未正常运行状态消失-储能待机状态判断,-开始进入重新策略分配 ");
|
||
StrategyAllocate(EnergyStorageState.ReadyCmd);
|
||
break;
|
||
}
|
||
else//依旧存在未正常运行状态,维持当前状态机
|
||
{
|
||
//当处于待机状态时,主要组件没有运行,那么可以通过自动执行指令进行运行指令的操作
|
||
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogService.Info($"时间:{DateTime.Now.ToString()}-【EntryStandby】-{ex.Message}");
|
||
}
|
||
|
||
|
||
}
|
||
}, StandbyTokenSource.Token);
|
||
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 退出待机状态
|
||
/// </summary>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void ExitStandby()
|
||
{
|
||
StandbyTokenSource.Cancel();
|
||
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能离开【待机】模式 ");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 进入储能的报警状态
|
||
/// </summary>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void EntryAlarm()
|
||
{
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能进入【报警】模式 ");
|
||
|
||
//EsSysRunStateMsg = "报警状态";
|
||
|
||
EsSysRunState = EnergyStorageState.Alarm;
|
||
CurClientInfo.SysState = "Alarm";
|
||
|
||
AlarmTokenSource = new CancellationTokenSource();
|
||
|
||
//报警任务循环
|
||
var AlarmTask = Task.Run(() =>
|
||
{
|
||
//判断储能的状态是否正确
|
||
while (EsSysRunState == EnergyStorageState.Alarm)
|
||
{
|
||
try
|
||
{
|
||
Thread.Sleep(100);
|
||
if (AlarmTokenSource.IsCancellationRequested)
|
||
{
|
||
break;
|
||
}
|
||
//循环获取系统的状态
|
||
//State = CheckEnergyStorageAlarmState();
|
||
if (CheckEnergyStorageModuleLink().Result && CheckEnergyStorageModuleAlarm().Result)//没有报警状态
|
||
{
|
||
//报警消失,再判断模块的运行状态是否正常
|
||
if (CheckEnergyStorageModuleRunState().Result)
|
||
{
|
||
//报警消失
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能报警消失-判断到削峰填谷-开始进入重新策略分配 ");
|
||
StrategyAllocate(EnergyStorageState.ReadyCmd);
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
//报警消失
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能报警消失-判断到待机状态-开始进入重新策略分配 ");
|
||
StrategyAllocate(EnergyStorageState.Standby);
|
||
break;
|
||
}
|
||
|
||
}
|
||
else//依旧存在报警状态,维持状态机
|
||
{
|
||
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogService.Info($"时间:{DateTime.Now.ToString()}-【EntryAlarm】-{ex.Message}");
|
||
}
|
||
}
|
||
}, AlarmTokenSource.Token);
|
||
|
||
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 储能离开报警
|
||
/// </summary>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void ExitAlarm()
|
||
{
|
||
AlarmTokenSource.Cancel();
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能离开【报警】模式 ");
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 其他状态退出后暂时还没有状态分配
|
||
/// 这里进行状态分配一下
|
||
/// 策略分配
|
||
/// </summary>
|
||
private void StrategyAllocate(EnergyStorageState newState)
|
||
{
|
||
//如果有切换到手自动的话,则进入到待机状态,否则进入削峰填谷的模式
|
||
//当然报警的等级是最高的,报警出来后才能接受外面的最新的状态
|
||
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能开始【策略分配】 新判断:{newState.ToString()}");
|
||
try
|
||
{
|
||
// 【newState】是新的判断后的状态
|
||
switch (newState)
|
||
{
|
||
case EnergyStorageState.Inital:
|
||
break;
|
||
case EnergyStorageState.Standby:
|
||
EnergyStorageStateMachine.Fire(EnergyStorageStateTrig.StandbyTrig);
|
||
break;
|
||
case EnergyStorageState.Alarm:
|
||
EnergyStorageStateMachine.Fire(EnergyStorageStateTrig.AlarmTrig);
|
||
break;
|
||
case EnergyStorageState.ReadyCmd:
|
||
EnergyStorageStateMachine.Fire(EnergyStorageStateTrig.ReadyCmdTrig);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogService.Error($"错误信息,策略分配处的状态机出现错误 {ex.Message}");
|
||
StrategyAllocate(newState);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 光伏的开关和电能逻辑
|
||
|
||
/// <summary>
|
||
/// 是否可以充电
|
||
/// 1) 电池状态允许
|
||
/// 2) 电池Soc允许
|
||
/// 3)PCS运行状态
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool IsCanCharg()
|
||
{
|
||
//电池
|
||
if (BmsDataService.BmsAlarmStateMsg == "禁充标志")
|
||
{
|
||
IsCanChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
if (BmsDataService.BmsAlarmStateMsg == "充满状态")
|
||
{
|
||
IsCanChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
if (BmsDataService.BmsAlarmStateMsg == "告警状态")
|
||
{
|
||
IsCanChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
|
||
//模式判断 模式不是命令等待模式时,给Server状态不进行充放电
|
||
if (EsSysRunState != EnergyStorageState.ReadyCmd)
|
||
{
|
||
IsCanChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
|
||
//PCS
|
||
if (InPowerPCSDataService.PcsRunState.PcsStateMsg == "停止")
|
||
{
|
||
IsCanChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
|
||
//SOC处于运行的范围之内
|
||
if (BmsDataService.BmsSOC.RtValue <= ConfigDataService.energyStorageRunConfig.BMSSocUpSignLimitValue)
|
||
{
|
||
IsCanChargMsg = "允许";
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
IsCanChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
|
||
//IsCanChargMsg = "禁止";
|
||
//return false;
|
||
}
|
||
|
||
private string _IsCanChargMsg;
|
||
/// <summary>
|
||
/// 是否可以充电文本
|
||
/// </summary>
|
||
public string IsCanChargMsg
|
||
{
|
||
get { return _IsCanChargMsg; }
|
||
set { _IsCanChargMsg = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private string _IsCanDisChargMsg;
|
||
/// <summary>
|
||
/// 是否可以放电文本
|
||
/// </summary>
|
||
public string IsCanDisChargMsg
|
||
{
|
||
get { return _IsCanDisChargMsg; }
|
||
set { _IsCanDisChargMsg = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否可以放电
|
||
/// 1) 电池状态允许
|
||
/// 2) 电池Soc允许
|
||
/// 3)PCS运行状态
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool IsCanDisCharg()
|
||
{
|
||
//电池
|
||
if (BmsDataService.BmsAlarmStateMsg == "禁放标志")
|
||
{
|
||
IsCanDisChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
if (BmsDataService.BmsAlarmStateMsg == "放空状态")
|
||
{
|
||
IsCanDisChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
if (BmsDataService.BmsAlarmStateMsg == "告警状态")
|
||
{
|
||
IsCanDisChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
|
||
//PCS
|
||
if (InPowerPCSDataService.PcsRunState.PcsStateMsg == "停止")
|
||
{
|
||
IsCanDisChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
|
||
//模式判断 模式不是命令等待模式时,给Server状态不进行充放电
|
||
if (EsSysRunState != EnergyStorageState.ReadyCmd)
|
||
{
|
||
IsCanChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
|
||
if (BmsDataService.BmsSOC.RtValue >= ConfigDataService.energyStorageRunConfig.BMSSocDownSignLimitValue)
|
||
{
|
||
IsCanDisChargMsg = "允许";
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
IsCanDisChargMsg = "禁止";
|
||
return false;
|
||
}
|
||
|
||
//IsCanDisChargMsg = "禁止";
|
||
//return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 最大允许充电功率
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public double GetMaxChargPw()
|
||
{
|
||
return BmsDataService.MaxChargePowerCell.RtValue;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 最大允许放电电功率
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public double GetMaxDisChargPw()
|
||
{
|
||
return BmsDataService.MaxDisChargePowerCell.RtValue;
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 切换到手动模式 手动模式等于待机模式 暂时这么定义
|
||
/// 进度待机模式
|
||
/// </summary>
|
||
public string HandModel()
|
||
{
|
||
//
|
||
if (EsSysRunState == EnergyStorageState.Alarm)
|
||
{
|
||
return "当前处于报警状态,无法切换到手动模式,请报警结束后再重试";
|
||
}
|
||
else
|
||
{
|
||
EnergyStorageStateMachine.Fire(EnergyStorageStateTrig.StandbyTrig);
|
||
return "OK";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 英博PCS实例
|
||
/// </summary>
|
||
public InPowerPCSDataService InPowerPCSDataService { get; set; }
|
||
public IFreeSql FreeSql { get; }
|
||
public ACService ACService { get; }
|
||
|
||
/// <summary>
|
||
/// 系统的配置服务实例
|
||
/// </summary>
|
||
public ConfigDataService ConfigDataService { get; }
|
||
|
||
/// <summary>
|
||
/// BMS模型实例
|
||
/// </summary>
|
||
public BmsDataService BmsDataService { get; set; }
|
||
|
||
/// <summary>
|
||
/// 光伏的数据服务
|
||
/// </summary>
|
||
public SolarEnergyService SolarEnergyService { get; }
|
||
|
||
///// <summary>
|
||
///// 电表数据
|
||
///// </summary>
|
||
//public PwMeter PwMeters { get; set; }
|
||
|
||
/// <summary>
|
||
/// 储能系统的状态机
|
||
/// </summary>
|
||
public StateMachine<EnergyStorageState, EnergyStorageStateTrig> EnergyStorageStateMachine { get; set; }
|
||
|
||
private string _HandAutoState = "自动模式";
|
||
/// <summary>
|
||
/// 手自动模式
|
||
/// </summary>
|
||
public string HandAutoState
|
||
{
|
||
get { return _HandAutoState; }
|
||
set { _HandAutoState = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private string _EsSysRunStateMsg = "待机状态";
|
||
/// <summary>
|
||
/// 储能系统运行状态
|
||
/// </summary>
|
||
public string EsSysRunStateMsg
|
||
{
|
||
get { return _EsSysRunStateMsg; }
|
||
set { _EsSysRunStateMsg = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
|
||
private EnergyStorageState _EsSysRunState;
|
||
/// <summary>
|
||
/// 储能当前的状态
|
||
/// </summary>
|
||
public EnergyStorageState EsSysRunState
|
||
{
|
||
get { return _EsSysRunState; }
|
||
set
|
||
{
|
||
if (_EsSysRunState != value)//储能的状态改变了
|
||
{
|
||
switch (value)
|
||
{
|
||
case EnergyStorageState.Inital:
|
||
EsSysRunStateMsg = "初始化";
|
||
break;
|
||
case EnergyStorageState.Standby:
|
||
EsSysRunStateMsg = "待机";
|
||
break;
|
||
case EnergyStorageState.Alarm:
|
||
EsSysRunStateMsg = "报警";
|
||
break;
|
||
case EnergyStorageState.ReadyCmd:
|
||
EsSysRunStateMsg = "命令等待";
|
||
break;
|
||
case EnergyStorageState.Hand:
|
||
EsSysRunStateMsg = "手动";
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
_EsSysRunState = value;
|
||
}
|
||
}
|
||
}
|
||
|
||
///// <summary>
|
||
///// 储能系统的指令状态
|
||
///// </summary>
|
||
//public StateMachine<EnergyStoryageCmdState, EnergyStoryageCmdStateTrig> EnergyStoryageCmdStateMachine { get; set; }
|
||
|
||
/// <summary>
|
||
/// 获取储能系统的状态
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public EnergyStorageState GetEnergyStorageState()
|
||
{
|
||
//return EnergyStorageState.Charge;
|
||
return EsSysRunState;
|
||
}
|
||
|
||
|
||
#region Slave Client 本站
|
||
|
||
/// <summary>
|
||
/// 驱动扫描线程
|
||
/// </summary>
|
||
static Task mainTask = null;
|
||
|
||
/// <summary>
|
||
/// 线程使能
|
||
/// </summary>
|
||
public bool WebSocketThreadEnable { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 当前的客户端状态指令内容
|
||
/// </summary>
|
||
private ClientInfo CurClientInfo { get; set; } = new ClientInfo();
|
||
|
||
/// <summary>
|
||
/// 当前站号
|
||
/// </summary>
|
||
public ushort ClientStation { get; set; }
|
||
|
||
//客户端考虑是否可以充放电的时候,除了状态,把SOC的情况放进去
|
||
|
||
private EnergyStoryageCmdState _EsSysCmdState;
|
||
/// <summary>
|
||
/// 储能的指令状态
|
||
/// 只是监视全功率的指令的变化 这个有问题,就是全功率实时发送一次,但是全功率的功率值根据SOC是改变的,可能需要监视全功率值,然后多次触发全功率数据????
|
||
/// </summary>
|
||
public EnergyStoryageCmdState EsSysCmdState
|
||
{
|
||
get { return _EsSysCmdState; }
|
||
set
|
||
{
|
||
if (value != _EsSysCmdState)
|
||
{
|
||
switch (value)
|
||
{
|
||
case EnergyStoryageCmdState.NoCmd://指令是实时的值
|
||
EsSysCmdStateMsg = "无指令";
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:进入平衡阶段,不需要调整[维持上一个指令] ");
|
||
break;
|
||
case EnergyStoryageCmdState.Standby://指令是实时的值
|
||
EsSysCmdStateMsg = "待机指令";
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:储能PCS待机指令 ");
|
||
//InPowerPCSDataService.StandbyPwCmd();
|
||
break;
|
||
case EnergyStoryageCmdState.ChargeValue://指令是实时的值
|
||
EsSysCmdStateMsg = "充电指令";
|
||
break;
|
||
case EnergyStoryageCmdState.DischargeValue://指令是实时的值
|
||
EsSysCmdStateMsg = "放电指令";
|
||
break;
|
||
case EnergyStoryageCmdState.FullCharge://全功率充电 变化时发送一次数据
|
||
EsSysCmdStateMsg = "全功率充电指令";
|
||
//这里只是标记状态,因为最大功率是变化的,这里只能执行一次,那么在赋值的时候做一个处理
|
||
break;
|
||
case EnergyStoryageCmdState.FullDischarge://全功率放电 变化时发送一次数据
|
||
EsSysCmdStateMsg = "全功率放电指令";
|
||
//这里只是标记状态,因为最大功率是变化的,这里只能执行一次,那么在赋值的时候做一个处理
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}:全功率放电指令 ");
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
_EsSysCmdState = value;
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
private string _EsSysCmdStateMsg;
|
||
/// <summary>
|
||
/// 储能的指令状态
|
||
/// 只是监视全功率的指令的变化 这个有问题,就是全功率实时发送一次,但是全功率的功率值根据SOC是改变的,可能需要监视全功率值,然后多次触发全功率数据????
|
||
/// </summary>
|
||
public string EsSysCmdStateMsg
|
||
{
|
||
get { return _EsSysCmdStateMsg; }
|
||
set { _EsSysCmdStateMsg = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
/// <summary>
|
||
/// WebSocketClient
|
||
/// </summary>
|
||
private WebSocketClient wsClient { get; set; }
|
||
|
||
/// <summary>
|
||
/// WebSocketClient 的状态
|
||
/// </summary>
|
||
public EMSClientConState EMSSocketClientConState { get; set; } = new EMSClientConState();
|
||
|
||
/// <summary>
|
||
/// WebSocket Url
|
||
/// </summary>
|
||
public string WebUrl { get; set; } = "ws://127.0.0.1:1883";
|
||
|
||
/// <summary>
|
||
/// 当前服务侧发送给客户端的指令
|
||
/// </summary>
|
||
public ServerCmd CurServerCmd { get; set; } = new ServerCmd();
|
||
|
||
|
||
/// <summary>
|
||
/// WebSocketClient初始化函数
|
||
/// </summary>
|
||
private void WebSocketClientInit()
|
||
{
|
||
EMSSocketClientConState = new EMSClientConState();
|
||
EMSSocketClientConState.EMSClientConErrEventHandler += EMSSocketClientConState_EMSClientConErrEventHandler;
|
||
|
||
wsClient?.ConnectClose();
|
||
//ws://183.6.55.87:8036/dev-api/mesWebSocket
|
||
//wsClient = new WebSocketClient( textBox1.Text, int.Parse( textBox2.Text ), textBox5.Text );//( textBox1.Text, int.Parse(textBox2.Text), textBox5.Text );
|
||
//wsClient = new WebSocketClient("ws://183.6.55.87:8036/dev-api/mesWebSocket");//( textBox1.Text, int.Parse(textBox2.Text), textBox5.Text );
|
||
wsClient = new WebSocketClient(WebUrl);//( textBox1.Text, int.Parse(textBox2.Text), textBox5.Text );
|
||
//wsClient.LogNet = new HslCommunication.LogNet.LogNetSingle(string.Empty);
|
||
//wsClient.LogNet.BeforeSaveToFile += LogNet_BeforeSaveToFile;
|
||
wsClient.OnClientApplicationMessageReceive += WebSocket_OnWebSocketMessageReceived;
|
||
wsClient.OnNetworkError += WsClient_OnNetworkError; // 这里使用内置的处理方式,一般也就够用了。
|
||
wsClient.OnClientConnected += WsClient_OnClientConnected;
|
||
//connect = wsClient.ConnectServer();
|
||
//if (string.IsNullOrEmpty(textBox3.Text))
|
||
ConnectResult = wsClient.ConnectServer();
|
||
if (ConnectResult.IsSuccess)
|
||
{
|
||
EMSSocketClientConState.ClientSendState = true;
|
||
EMSSocketClientConState.ClientRecvState = true;
|
||
}
|
||
else
|
||
{
|
||
EMSSocketClientConState.ClientSendState = false;
|
||
EMSSocketClientConState.ClientRecvState = false;
|
||
}
|
||
|
||
//扫描开始
|
||
WebSocketScanStart();
|
||
|
||
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 判定跟EMS通信失败触发的事件
|
||
/// 因为状态机里面有实时获取状态判断了
|
||
/// 这里不需要事件触发纸执行,暂时舍弃
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void EMSSocketClientConState_EMSClientConErrEventHandler(object? sender, EMSConErrEventArgs data)
|
||
{
|
||
if (data.Result)//
|
||
{
|
||
|
||
}
|
||
else//连接失败
|
||
{
|
||
////跟EMS通信失败后,立刻进入待机状态,如果当前处于待机状态也要先给PCS指令为0
|
||
//if (EnergyStorageStateMachine.State != EnergyStorageState.Standby)
|
||
//{
|
||
// SendStandby();//防止其他的状态残留,先给0功率
|
||
// EnergyStorageStateMachine.Fire(EnergyStorageStateTrig.StandbyTrig);
|
||
//}
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 连接服务的结果
|
||
/// </summary>
|
||
private OperateResult ConnectResult { get; set; }
|
||
|
||
/// <summary>
|
||
/// 实时客户端的状态消息
|
||
/// </summary>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void WebSocketScanStart()
|
||
{
|
||
mainTask = Task.Run(async () =>
|
||
{
|
||
while (WebSocketThreadEnable)
|
||
{
|
||
await Task.Delay(100);
|
||
//定期发送数据,需要连接状态OK,否则实时主动连接Server直到成功
|
||
if (EMSSocketClientConState.ClientState)
|
||
{
|
||
CurClientInfo.MaxChargPw = BmsDataService.MaxChargePowerCell.RtValue;
|
||
CurClientInfo.MaxDisChargPw = BmsDataService.MaxDisChargePowerCell.RtValue;
|
||
CurClientInfo.SOC = BmsDataService.BmsSOC.RtValue;
|
||
CurClientInfo.CurActionCmdPw = InPowerPCSDataService.CurCmdPw;
|
||
CurClientInfo.IsCharg = IsCanCharg();
|
||
CurClientInfo.IsDisCharg = IsCanDisCharg();
|
||
|
||
CurClientInfo.CoolState=ACService.CapState== "开启"?true:false;
|
||
CurClientInfo.SOE = BmsDataService.BmsSOE.RtValue;
|
||
CurClientInfo.SOH = BmsDataService.BmsSOH.RtValue;
|
||
|
||
//开始发送数据
|
||
//发送数据成功,则代表发送状态OK
|
||
EMSSocketClientConState.ClientSendState = ClientSendMsg(CurClientInfo);
|
||
}
|
||
else
|
||
{
|
||
ConnectResult = wsClient.ConnectServer();
|
||
if (ConnectResult.IsSuccess)
|
||
{
|
||
if (ConnectResult.IsSuccess)
|
||
{
|
||
EMSSocketClientConState.ClientState = true;
|
||
}
|
||
else
|
||
{
|
||
EMSSocketClientConState.ClientState = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 客户端连接成功触发事件,重新连接也会触发
|
||
/// </summary>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void WsClient_OnClientConnected()
|
||
{
|
||
EMSSocketClientConState.ClientState = true;
|
||
LogService.Info($"时间:{DateTime.Now.ToString()}-【WebSocket客户端连接成功】");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送消息数据
|
||
/// </summary>
|
||
/// <param name="msg"></param>
|
||
/// <returns></returns>
|
||
public bool ClientSendMsg(ClientInfo msg)
|
||
{
|
||
return wsClient.SendServer(JsonSerializer.Serialize<ClientInfo>(msg)).IsSuccess;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关闭连接
|
||
/// </summary>
|
||
public void ClientCloseLink()
|
||
{
|
||
LogService.Info($"时间:{DateTime.Now.ToString()}-【WebSocket关闭连接】");
|
||
EMSSocketClientConState.ClientState = false;
|
||
wsClient?.ConnectClose();
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 网络通信失败
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void WsClient_OnNetworkError(object? sender, EventArgs e)
|
||
{
|
||
LogService.Info($"时间:{DateTime.Now.ToString()}-【WebSocket网络通信失败】");
|
||
EMSSocketClientConState.ClientState = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// WebSoketClient 接收到数据
|
||
/// </summary>
|
||
/// <param name="message"></param>
|
||
private void WebSocket_OnWebSocketMessageReceived(WebSocketMessage message)
|
||
{
|
||
try
|
||
{
|
||
//if (EsSysRunState == EnergyStorageState.ReadyCmd)
|
||
//{
|
||
EMSSocketClientConState.ClientRecvState = true;
|
||
|
||
//反序列化数据
|
||
var data = JsonSerializer.Deserialize<List<ServerCmd>>(Encoding.UTF8.GetString(message.Payload)).Find(a => a.Station == ClientStation);
|
||
|
||
//充放电的指令
|
||
CurServerCmd.CmdPw = data!.CmdPw;
|
||
CurServerCmd.CmdType = data.CmdType;
|
||
|
||
//液冷的开关
|
||
CurServerCmd.CoolOnOffCmd = data!.CoolOnOffCmd;
|
||
|
||
//Pcs的开关
|
||
CurServerCmd.PcsOnOffCmd = data!.PcsOnOffCmd;
|
||
|
||
|
||
}
|
||
catch (Exception Ex)
|
||
{
|
||
LogService.Error($"时间:{DateTime.Now.ToString()}-【WebSocket接收到数据】ErrMessage{Ex.Message}");
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
}
|
||
}
|