Files
YuPu-OrpaonEMS/OrpaonEMS.App/Services/BmsDataService.cs
2025-12-25 11:13:13 +08:00

724 lines
29 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using HslCommunication;
using HslCommunication.ModBus;
using NLog;
using OrpaonEMS.App.Com;
using OrpaonEMS.App.Models;
using OrpaonEMS.Core;
using OrpaonEMS.Core.DbModel;
using OrpaonEMS.Core.Enums;
using OrpaonEMS.Core.EventHandMsg;
using OrpaonEMS.Core.Model;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
using System.Windows;
namespace OrpaonEMS.App.Services
{
/// <summary>
/// 设备实时数据服务
/// </summary>
public class BmsDataService : BindableBase
{
/// <summary>
/// ScanTask扫描Task
/// </summary>
static Task ScanTask { get; set; }
/// <summary>
/// NLog服务集合
/// </summary>
public ILogService LogService { get; }
public IFreeSql FreeSql { get; }
public ConfigDataService ConfigDataService { get; }
public BmsDataService(ILogService logService,IFreeSql freeSql,ConfigDataService configDataService)
{
//Log服务实例赋值
LogService = logService;
FreeSql = freeSql;
ConfigDataService = configDataService;
//ModbusTcpNetDrive = new ModbusTcpNet("192.168.10.253", 502);
//ModbusTcpNetDrive = new ModbusTcpNet("192.0.1.21", 502);
ModbusTcpNetDrive = new ModbusTcpNet(ConfigDataService.BMSIP, 502);
ModbusTcpNetDrive.AddressStartWithZero = true;
ModbusTcpNetDrive.ReceiveTimeOut = 2000;
ModbusTcpNetDrive.SetPersistentConnection();
var LinkResult = ModbusTcpNetDrive.ConnectServer();
if (!LinkResult.IsSuccess)
{
LogService!.Info($"时间:{DateTime.Now.ToString()}-【Info】:BMS 初始连接失败");
MessageBox.Show("BMS 连接失败");
}
//报警数据获取
ListAlarmCell = LoadAlarm.GetAlarms(ChannelInfo);
//把报警的单元注入到报警模型中,方便统计
CurAlarmModel = new BmsAlarmModel(ListAlarmCell);
CurAlarmModel.BmsAlarmResetEventHandler += CurAlarmModel_BmsAlarmResetEventHandler;
ListSoxValue = new ObservableCollection<DoughnutModel>()
{
new DoughnutModel() {Title="SOC",Value=50,States=""},
new DoughnutModel() {Title="SOH",Value=50,States=""},
new DoughnutModel() {Title="SOX",Value=50,States=""}
};
//获取只读数据
ListBmsRoCell = BmsLoadData.GetRoData();
//获取读写数据
ListBmsRwCell = BmsLoadData.GetRWData();
//从集合里找出单独关注的UI数据
BmsCur = ListBmsRoCell.Find(a => a.Name == "电池簇电流值")!;
BmsVol = ListBmsRoCell.Find(a => a.Name == "电池簇电压")!;
BmsSOC = ListBmsRoCell.Find(a => a.Name == "电池簇总SOC")!;
BmsSOH = ListBmsRoCell.Find(a => a.Name == "电池簇总SOH")!;
BmsSOE = ListBmsRoCell.Find(a => a.Name == "电池簇总SOE")!;
BmsResP = ListBmsRoCell.Find(a => a.Name == "电池簇绝缘电阻R+")!;
BmsResN = ListBmsRoCell.Find(a => a.Name == "电池簇绝缘电阻R-")!;
BmsMaxBatTemp = ListBmsRoCell.Find(a => a.Name == "电池最高温度")!;
BmsMinBatTemp = ListBmsRoCell.Find(a => a.Name == "电池最低温度")!;
BmsAccChargCount = ListBmsRoCell.Find(a => a.Name == "累计充电次数")!;
BmsAccDisChargCount = ListBmsRoCell.Find(a => a.Name == "累计放电次数")!;
BmsAccCharg = ListBmsRoCell.Find(a => a.Name == "累计充电电量")!;
BmsAccDisCharg = ListBmsRoCell.Find(a => a.Name == "累计放电电量")!;
MaxDisChargePowerCell = ListBmsRoCell.Find(a => a.Name == "最大允许放电功率")!;
MaxChargePowerCell = ListBmsRoCell.Find(a => a.Name == "最大允许充电功率")!;
ScanStart();
//报警消费
Task.Run(() => AlarmChannelAction());
}
/// <summary>
/// 报警消失后的复位操作一下
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private void CurAlarmModel_BmsAlarmResetEventHandler(object? sender, string e)
{
BmsAlarmReset();
Console.WriteLine($"时间:{DateTime.Now.ToString()}-内容:报警复位进行了复位操作");
}
/// <summary>
/// 发布BMS的一些状态信号
/// </summary>
public event EventHandler<BmsEventHandMsg> PubBmsMsgEventHandler;
/// <summary>
/// 连接状态模型
/// </summary>
public LinkStateModel LinkStateModels { get; set; } = new LinkStateModel();
/// <summary>
/// BMS IO的状态
/// </summary>
public BmsIO BmsIO { get; set; }=new BmsIO();
/// <summary>
/// BMS是否存在报警
/// 一般这个是2级和3级比较严重的报警触发的
/// 1级的报警不严重
/// </summary>
/// <returns></returns>
public bool IsBmsExistAlarm()
{
//有报警状态的情况下是报警发生了
if (BMSAlarmState == BMSAlarmStateEnum.Alarm)
{
return true;
}
return false;
}
/// <summary>
/// BMS报警复位
/// </summary>
public void BmsAlarmReset()
{
Task.Run(() =>
{
ModbusTcpNetDrive.Write("108", (ushort)1);
Thread.Sleep(1000);
ModbusTcpNetDrive.Write("108", (ushort)0);
});
}
/// <summary>
/// 实时报警数据
/// </summary>
public List<AlarmCell> ListAlarmCell { get; set; }
/// <summary>
/// BMS只读实时数据集合
/// </summary>
public List<BMSRoCell> ListBmsRoCell { get; set; }
/// <summary>
/// BMS读写实时数据集合
/// </summary>
public ObservableCollection<BmsRwCell> ListBmsRwCell { get; set; }
#region
/// <summary>
/// Bms报警模型
/// 由众多报警集合汇总而来
/// </summary>
public BmsAlarmModel CurAlarmModel { get; set; }
/// <summary>
/// 队列通道
/// 当前队列消费当前产线的报警数据
/// </summary>
public Channel<AlarmChannelData> ChannelInfo = Channel.CreateUnbounded<AlarmChannelData>(new UnboundedChannelOptions()
{
SingleWriter = false,//允许一次写入多条数据
SingleReader = true //一次只能读取一条消息
});
/// <summary>
/// 报警通道任务执行
/// </summary>
/// <returns></returns>
private async void AlarmChannelAction()
{
while (await ChannelInfo.Reader.WaitToReadAsync())
{
if (ChannelInfo.Reader.TryRead(out var msgData))
{
try
{
//FSqlContext.FDb.Select
//统一的处理报警信息
FreeSql.Insert<HistoryAlarm>(new HistoryAlarm()
{
Category = "电池",
StartTime = msgData.alarmChannel.StartTime,
EndTime = msgData.alarmChannel.EndTime,
Level = msgData.alarmChannel.Level,
StopDur = msgData.alarmChannel.AlarmDur,
Content = msgData.alarmChannel.Content,
WorkDay = DateTime.Now.ToString("yyyy-MM-dd")
}).ExecuteAffrows();
Console.WriteLine($"时间:{DateTime.Now.ToString()}-内容:{msgData.alarmChannel.Content}");
}
catch (Exception ex)
{
LogService.Info($"时间:{DateTime.Now.ToString()}-【ExitPeakValley】-{ex.Message}");
}
}
}
}
#endregion
#region
/// <summary>
/// ModbusTcp驱动
/// </summary>
private ModbusTcpNet ModbusTcpNetDrive { get; set; }
/// <summary>
/// 扫描设备线程数据
/// </summary>
public Thread ScanDeviceThread { set; get; }
/// <summary>
/// 扫描线程使能
/// </summary>
public bool ThreadEnable { get; set; } = true;
/// <summary>
/// 报警状态数据
/// </summary>
private OperateResult<bool[]> OperateResultBmsAlarm { get; set; }
/// <summary>
/// BMS只读数据-前125字节
/// </summary>
private OperateResult<byte[]> OperateResultRoRtData1 { get; set; }
/// <summary>
/// BMS只读数据 后125字节
/// </summary>
private OperateResult<byte[]> OperateResultRoRtData2 { get; set; }
/// <summary>
/// 连接失败次数
/// </summary>
private int LinkFaultCount { get; set; }
/// <summary>
/// BMS配置数据
/// </summary>
private OperateResult<byte[]> OperateResultConfigData { get; set; }
/// <summary>
///扫描BMS设备的线程
/// </summary>
private void ScanStart()
{
ScanTask = Task.Run(async () =>
{
while (ThreadEnable)
{
try
{
await Task.Delay(200);
//BmsVol.SrRtValue = (ushort)new Random().Next(0, 1000);
//报警数据
OperateResultBmsAlarm = ModbusTcpNetDrive.ReadDiscrete("1", 200);
if (OperateResultBmsAlarm.IsSuccess)
{
foreach (var itemAlarmCell in ListAlarmCell)
{
itemAlarmCell.UpdateValue(OperateResultBmsAlarm.Content[itemAlarmCell.BitIndex]);
}
}
//只读数据测试
OperateResultRoRtData1 = ModbusTcpNetDrive.Read("x=4;1", 260);
if (OperateResultRoRtData1.IsSuccess)
{
foreach (var ItembMSRoCell in ListBmsRoCell)
{
//if (ItembMSRoCell.Index <= 240)
//{
if (ItembMSRoCell.Lengh == 2)
{
ItembMSRoCell.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt32(OperateResultRoRtData1.Content, ItembMSRoCell.Index);
}
else
{
ItembMSRoCell.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultRoRtData1.Content, ItembMSRoCell.Index);
}
//}
//一些整型数据转枚举和字符串的处理
switch (ItembMSRoCell.Name)
{
case "系统告警状态":
BMSAlarmStateValue = (int)ItembMSRoCell.SrRtValue;
break;
case "电池簇电池状态":
BmsBatStateVaue = (ushort)ItembMSRoCell.SrRtValue;
break;
case "DI检测状态":
BmsIO.DIValue = (ushort)ItembMSRoCell.SrRtValue;
break;
case "DO输出状态":
BmsIO.DOValue = (ushort)ItembMSRoCell.SrRtValue;
break;
default:
break;
}
}
//BmsBatStateVaue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultRoRtData1.Content, 14);
//BmsAccCharg.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt32(OperateResultRoRtData1.Content, BmsAccCharg.Index);
//BmsAccDisCharg.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt32(OperateResultRoRtData1.Content, BmsAccDisCharg.Index);
//BmsAccChargCount.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultRoRtData1.Content, BmsAccChargCount.Index);
//BmsAccDisChargCount.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultRoRtData1.Content, BmsAccDisChargCount.Index);
App.Current.Dispatcher.Invoke(() =>
{
ListSoxValue[0].Value = BmsSOC.RtValue;
ListSoxValue[1].Value = BmsSOH.RtValue;
ListSoxValue[2].Value = BmsSOE.RtValue;
});
//MaxChargePowerCell.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultRoRtData1.Content, MaxChargePowerCell.Index);
//MaxDisChargePowerCell.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultRoRtData1.Content, MaxDisChargePowerCell.Index);
LinkStateModels.LinkState = true;
LinkFaultCount = 0;
}
else
{
LinkFaultCount = LinkFaultCount + 1;
if (LinkFaultCount > 100)
{
//连接失败 暂时退出
LinkStateModels.LinkState = false;
}
}
//读写数据测试
OperateResultConfigData = ModbusTcpNetDrive.Read("1", 260);
if (OperateResultConfigData.IsSuccess)
{
foreach (var ItembMSRoCell in ListBmsRwCell)
{
ItembMSRoCell.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransInt16(OperateResultConfigData.Content, ItembMSRoCell.Index);
}
//FireSmokeTrigVaue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 460);
//FireTempTrigVaue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 462);
//FireWorkModelVaue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 464);
//FireMainPowerStateVaue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 466);
//FireSubPowerStateVaue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 468);
//FireSolenoidValveStateVaue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 470);
//FireInjectionCountdown = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 472);
//FirePressSensorStateVaue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 474);
////xxx = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 460);
//InPress.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 452);
//OutPress.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 454);
//OutTemp.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 448);
//InTemp.SrRtValue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 450);
//CoolFaultValue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 456);
//CoolStateVaue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultConfigData.Content, 446);
}
}
catch (Exception ex)
{
var dd = 1;
}
}
});
}
/// <summary>
/// 关闭驱动连接
/// </summary>
public void CloseDrive()
{
ThreadEnable = false;
ModbusTcpNetDrive.ConnectClose();
}
public bool WriteValue(BmsRwCell data)
{
var Result = ModbusTcpNetDrive.Write(data.Address, data.GetWriteDeviceValue());
if (Result.IsSuccess)
{
return true;
}
return false;
}
#endregion
#region BMS UI关注数据
/// <summary>
/// BMS的全部状态
/// 这个暂时是统计得出的,逻辑还没有做
/// 根据其他的信号得出的总的状态结果
/// True是好的状态
/// False是差的状态
/// </summary>
public bool BmsTotalState { get; set; } = true;
private string _BmsAlarmStateMsg;
/// <summary>
/// 系统告警状态
/// 告警状态 消息内容
/// </summary>
public string BmsAlarmStateMsg
{
get { return _BmsAlarmStateMsg; }
set { _BmsAlarmStateMsg = value; RaisePropertyChanged(); }
}
/// <summary>
/// 系统告警状态
/// 告警状态
/// </summary>
public BMSAlarmStateEnum BMSAlarmState { get; set; }
private int bMSAlarmStateValue;
/// <summary>
/// BMS报警状态值
/// 系统告警状态
/// </summary>
public int BMSAlarmStateValue
{
get { return bMSAlarmStateValue; }
set
{
if (value != bMSAlarmStateValue)
{
if (ComHelper.GetBitValue(value, 0))
{
BMSAlarmState = BMSAlarmStateEnum.StopCharg;
BmsAlarmStateMsg = "禁充标志";
BmsTotalState = false;
}
else if (ComHelper.GetBitValue(value, 1))
{
BMSAlarmState = BMSAlarmStateEnum.StopDisCharg;
BmsAlarmStateMsg = "禁放标志";
BmsTotalState = false;
}
else if (ComHelper.GetBitValue(value, 2))
{
//当严重的2级和3级别的报警发生时会产生报警状态
BMSAlarmState = BMSAlarmStateEnum.Alarm;
BmsAlarmStateMsg = "告警状态";
BmsTotalState = false;
//PubBmsMsgEventHandler(this, new BmsEventHandMsg() { MsgType = "Alarm", AlarmState = true }) ;
}
else if (ComHelper.GetBitValue(value, 3))
{
BMSAlarmState = BMSAlarmStateEnum.Full;
BmsAlarmStateMsg = "充满状态";
BmsTotalState = true;
}
else if (ComHelper.GetBitValue(value, 4))
{
BMSAlarmState = BMSAlarmStateEnum.Empty;
BmsAlarmStateMsg = "放空状态";
BmsTotalState = true;
}
else
{
BMSAlarmState = BMSAlarmStateEnum.NoAlarm;
BmsAlarmStateMsg = "无报警";
BmsTotalState = true;
}
bMSAlarmStateValue = value;
}
}
}
/// <summary>
/// 电池簇电池状态
/// </summary>
public BMSStateEnum BmsState { get; set; }
private string _BmsBatStateMsg = "";
/// <summary>
/// 电池簇电池状态消息内容
/// </summary>
public string BmsBatStateMsg
{
get { return _BmsBatStateMsg; }
set { _BmsBatStateMsg = value; RaisePropertyChanged(); }
}
private ushort _BmsBatStateVaue = 100;
/// <summary>
/// 电池簇电池状态状态字
/// </summary>
public ushort BmsBatStateVaue
{
get { return _BmsBatStateVaue; }
set
{
if (value != _BmsBatStateVaue)
{
switch (value)
{
case 1:
BmsBatStateMsg = "初始化状态";
BmsState = BMSStateEnum.Initial;
break;
case 2:
BmsBatStateMsg = "自检";
BmsState = BMSStateEnum.SelfTest;
break;
case 3:
BmsBatStateMsg = "上电";
BmsState = BMSStateEnum.PowerOn;
break;
case 4:
BmsBatStateMsg = "上电完成";
BmsState = BMSStateEnum.PowerOnCom;
break;
case 5:
BmsBatStateMsg = "禁充";
BmsState = BMSStateEnum.StopCharge;
break;
case 6:
BmsBatStateMsg = "禁放";
BmsState = BMSStateEnum.StopDisCharge;
break;
case 7:
BmsBatStateMsg = "待机";
BmsState = BMSStateEnum.Standby;
break;
case 8:
BmsBatStateMsg = "故障下电";
BmsState = BMSStateEnum.FaultPoweOff;
break;
case 9:
BmsBatStateMsg = "故障下电后故障已清除";
BmsState = BMSStateEnum.FaultClear;
break;
case 10:
BmsBatStateMsg = "测试模式";
BmsState = BMSStateEnum.TestMode;
break;
case 11:
BmsBatStateMsg = "单簇维护";
BmsState = BMSStateEnum.SingleMaintenance;
break;
default:
break;
}
_BmsBatStateVaue = value;
}
}
}
private ObservableCollection<DoughnutModel> _ListSoxValue;
/// <summary>
/// Doughnut 数据 SOC/SOH等
/// </summary>
public ObservableCollection<DoughnutModel> ListSoxValue
{
get { return _ListSoxValue; }
set { _ListSoxValue = value; RaisePropertyChanged(); }
}
/// <summary>
/// 最大允许放电功率
/// </summary>
public BMSRoCell MaxDisChargePowerCell { get; set; }// = new BMSRoCell(name: "电池簇电流值", offset: -1600, ratio: 0.1, index: 2, lengh: 1, address: "2", focus: true, unit: "A");
/// <summary>
/// 最大允许充电功率
/// </summary>
public BMSRoCell MaxChargePowerCell { get; set; } //= new BMSRoCell(name: "电池簇电压", offset: 0, ratio: 0.1, index: 0, lengh: 1, address: "1", focus: true, unit: "V");
/// <summary>
/// 电池簇电流值
/// </summary>
public BMSRoCell BmsCur { get; set; }// = new BMSRoCell(name: "电池簇电流值", offset: -1600, ratio: 0.1, index: 2, lengh: 1, address: "2", focus: true, unit: "A");
/// <summary>
/// 电池簇电压
/// </summary>
public BMSRoCell BmsVol { get; set; } //= new BMSRoCell(name: "电池簇电压", offset: 0, ratio: 0.1, index: 0, lengh: 1, address: "1", focus: true, unit: "V");
/// <summary>
/// 电池簇总SOC
/// </summary>
public BMSRoCell BmsSOC { get; set; }// = new BMSRoCell(name: "电池簇总SOC", offset: 0, ratio: 0.1, index: 4, lengh: 1, address: "3", focus: true, unit: "%");
/// <summary>
/// 电池簇总SOH
/// </summary>
public BMSRoCell BmsSOH { get; set; }// = new BMSRoCell(name: "电池簇总SOH", offset: 0, ratio: 1, index: 6, lengh: 1, address: "4", focus: true, unit: "%");
/// <summary>
/// 电池簇总SOE
/// </summary>
public BMSRoCell BmsSOE { get; set; }// = new BMSRoCell(name: "电池簇总SOE", offset: 0, ratio: 0.1, index: 8, lengh: 1, address: "5", focus: true, unit: "%");
/// <summary>
/// 电池簇绝缘电阻R+
/// </summary>
public BMSRoCell BmsResP { get; set; }// = new BMSRoCell(name: "电池簇绝缘电阻R+", offset: 0, ratio: 1, index: 10, lengh: 1, address: "6", focus: true, unit: "kΩ");
/// <summary>
/// 电池簇绝缘电阻R-
/// </summary>
public BMSRoCell BmsResN { get; set; }// = new BMSRoCell(name: "电池簇绝缘电阻R-", offset: 0, ratio: 1, index: 12, lengh: 1, address: "7", focus: true, unit: "kΩ");
/// <summary>
/// 最高电池温度
/// </summary>
public BMSRoCell BmsMaxBatTemp { get; set; }// = new BMSRoCell(name: "电池最高温度", offset: -40, ratio: 0.1, index: 22, lengh: 1, address: "12", focus: true, unit: "℃");
/// <summary>
/// 最低电池温度
/// </summary>
public BMSRoCell BmsMinBatTemp { get; set; }// = new BMSRoCell(name: "电池最低温度", offset: -40, ratio: 0.1, index: 28, lengh: 1, address: "15", focus: true, unit: "℃");
/// <summary>
/// 累计充电次数
/// </summary>
public BMSRoCell BmsAccChargCount { get; set; }// = new BMSRoCell(name: "累计充电次数", offset: 0, ratio: 1, index: 128, lengh: 1, address: "65", focus: true, unit: "次");
/// <summary>
/// 累计放电次数
/// </summary>
public BMSRoCell BmsAccDisChargCount { get; set; }// = new BMSRoCell(name: "累计放电次数", offset: 0, ratio: 1, index: 130, lengh: 1, address: "66", focus: true, unit: "次");
/// <summary>
/// 累计充电电量
/// </summary>
public BMSRoCell BmsAccCharg { get; set; }// = new BMSRoCell(name: "累计充电电量", offset: 0, ratio: 0.1, index: 116, lengh: 2, address: "59", focus: true, unit: "KWh");
/// <summary>
/// 累计放电电量
/// </summary>
public BMSRoCell BmsAccDisCharg { get; set; }// = new BMSRoCell(name: "累计放电电量", offset: 0, ratio: 0.1, index: 120, lengh: 2, address: "61", focus: true, unit: "KWh");
#endregion
#region
/// <summary>
/// Bms是否可以充电
/// </summary>
/// <returns></returns>
public bool BmsIsCharg()
{
if (BMSAlarmState != BMSAlarmStateEnum.StopCharg && BMSAlarmState != BMSAlarmStateEnum.Alarm && BMSAlarmState != BMSAlarmStateEnum.Full)
{
return true;
}
return false;
}
/// <summary>
/// Bms是否可以放电
/// </summary>
/// <returns></returns>
public bool BmsIsDisCharg()
{
if (BMSAlarmState != BMSAlarmStateEnum.StopDisCharg && BMSAlarmState != BMSAlarmStateEnum.Alarm && BMSAlarmState != BMSAlarmStateEnum.Empty)
{
return true;
}
return false;
}
#endregion
}
}