830 lines
27 KiB
C#
830 lines
27 KiB
C#
using HslCommunication;
|
||
using HslCommunication.ModBus;
|
||
using OrpaonEMS.App.Models;
|
||
using OrpaonEMS.Core.DbModel;
|
||
using OrpaonEMS.Core.Enums;
|
||
using OrpaonEMS.Core.Model;
|
||
using Prism.Mvvm;
|
||
using System;
|
||
using System.Collections.ObjectModel;
|
||
using System.Linq;
|
||
using System.Threading;
|
||
using System.Threading.Channels;
|
||
using System.Threading.Tasks;
|
||
using System.Windows;
|
||
|
||
namespace OrpaonEMS.App.Services
|
||
{
|
||
/// <summary>
|
||
/// PCS数据服务
|
||
/// </summary>
|
||
public class InPowerPCSDataService : BindableBase
|
||
{
|
||
/// <summary>
|
||
/// PCS运行状态模型
|
||
/// </summary>
|
||
public PCSStateModel PcsRunState { get; set; }
|
||
|
||
/// <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>
|
||
public OperateResult<byte[]>? OperateResultBytes1 { get; set; }
|
||
|
||
/// <summary>
|
||
/// 读取的字节数据集合
|
||
/// </summary>
|
||
public OperateResult<byte[]>? OperateResultBytes2 { get; set; }
|
||
|
||
/// <summary>
|
||
/// 读取的布尔数据集合
|
||
/// </summary>
|
||
public OperateResult<bool[]>? OperateResultBool3 { get; set; }
|
||
|
||
private string _Charg_DisChargInfo = string.Empty;
|
||
/// <summary>
|
||
/// 充放电信息
|
||
/// </summary>
|
||
public string Charg_DisChargInfo
|
||
{
|
||
get { return _Charg_DisChargInfo; }
|
||
set { _Charg_DisChargInfo = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 定时器
|
||
/// </summary>
|
||
static System.Timers.Timer CurTimer { get; set; }
|
||
|
||
public InPowerPCSDataService(ILogService logService,
|
||
IFreeSql freeSql,
|
||
BmsDataService bmsDataService,
|
||
ConfigDataService configDataService)
|
||
{
|
||
LogService = logService;
|
||
FreeSql = freeSql;
|
||
BmsDataService = bmsDataService;
|
||
ConfigDataService = configDataService;
|
||
|
||
//ModbusTcpNetDrive = new ModbusTcpNet("192.168.0.20", 502);
|
||
ModbusTcpNetDrive = new ModbusTcpNet(ConfigDataService.PCSIP, 502);
|
||
ModbusTcpNetDrive.AddressStartWithZero = true;
|
||
ModbusTcpNetDrive.SetPersistentConnection();
|
||
var DATA = ModbusTcpNetDrive.ConnectServer();
|
||
if (!DATA.IsSuccess)
|
||
{
|
||
MessageBox.Show("PCS 连接失败");
|
||
}
|
||
|
||
PwTranceCmdValues = new TranceCmdValue(2);
|
||
PwTranceCmdValues.CmdValueChanged += PwTranceCmdValues_CmdValueChanged;
|
||
|
||
//CurPcsAlarmModel = new PcsAlarmModel();
|
||
|
||
//BMS目前通信来自于PCS,所以封装在英博PCS中
|
||
//bMSRtCtrCell = bMSRtCtrCellInfo;
|
||
|
||
//PCS运行状态模型实例化
|
||
PcsRunState = new PCSStateModel(this);
|
||
|
||
ScanDeviceThread = new Thread(new ThreadStart(ScanDeviceThreadMethond));
|
||
ScanDeviceThread.Start();
|
||
|
||
CurPcsAlarmModel = new PcsAlarmModel(ChannelInfo);
|
||
|
||
CurTimer = new System.Timers.Timer();
|
||
CurTimer.Elapsed += CurTimer_Elapsed;//到达时间的时候执行事件;
|
||
CurTimer.AutoReset = true;//设置是执行一次(false)还是一直执行(true);
|
||
CurTimer.Interval = 600;//设置是时钟
|
||
CurTimer.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件;
|
||
CurTimer.Start(); //启动定时器
|
||
|
||
//报警消费
|
||
Task.Run(() => AlarmChannelAction());
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// PCS报警模型
|
||
/// </summary>
|
||
public PcsAlarmModel CurPcsAlarmModel { get; set; }
|
||
|
||
/// <summary>
|
||
/// 扫描方法
|
||
/// x=4;201 寄存器信息 只读
|
||
/// x=3;301 PCS 读取保持寄存器信息
|
||
/// </summary>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void ScanDeviceThreadMethond()
|
||
{
|
||
Thread.Sleep(500);
|
||
while (ThreadEnable)
|
||
{
|
||
Thread.Sleep(100);
|
||
//地址和手册错位1个字,那么转为Byte后就是2个字节,请参考地址
|
||
OperateResultBytes1 = ModbusTcpNetDrive.Read("x=4;201", 100);
|
||
if (OperateResultBytes1.IsSuccess)
|
||
{
|
||
Power = ModbusTcpNetDrive.ByteTransform.TransInt16(OperateResultBytes1.Content, 20) * 0.1;
|
||
|
||
AVol = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 0) * 0.1;
|
||
BVol = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 2) * 0.1;
|
||
CVol = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 4) * 0.1;
|
||
|
||
ACur = ModbusTcpNetDrive.ByteTransform.TransInt16(OperateResultBytes1.Content, 6) * 0.1;
|
||
BCur = ModbusTcpNetDrive.ByteTransform.TransInt16(OperateResultBytes1.Content, 8) * 0.1;
|
||
CCur = ModbusTcpNetDrive.ByteTransform.TransInt16(OperateResultBytes1.Content, 10) * 0.1;
|
||
|
||
NetFreq = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 12) * 0.01;
|
||
|
||
TotalReactivePw = ModbusTcpNetDrive.ByteTransform.TransInt16(OperateResultBytes1.Content, 28) * 0.1;
|
||
TotalApparentPw = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 36) * 0.1;
|
||
|
||
InputVol = ModbusTcpNetDrive.ByteTransform.TransInt16(OperateResultBytes1.Content, 48) * 0.1;
|
||
InputCur = ModbusTcpNetDrive.ByteTransform.TransInt16(OperateResultBytes1.Content, 50) * 0.1;
|
||
InputPw = ModbusTcpNetDrive.ByteTransform.TransInt16(OperateResultBytes1.Content, 46) * 0.1;
|
||
|
||
PwNetFactor = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 44) * 0.001;
|
||
|
||
FinTemp = ModbusTcpNetDrive.ByteTransform.TransInt16(OperateResultBytes1.Content, 52);
|
||
|
||
CurPcsAlarmModel.AlarmWord1 = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 142);
|
||
CurPcsAlarmModel.AlarmWord2 = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 144);
|
||
CurPcsAlarmModel.AlarmWord3 = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 146);
|
||
CurPcsAlarmModel.AlarmWord4 = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 148);
|
||
CurPcsAlarmModel.AlarmWord5 = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 110);
|
||
//var dd= ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 50);
|
||
//var dd2= ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 52);
|
||
//var dd3= ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 54);
|
||
//var dd4= ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 56);
|
||
|
||
//MaxChargePower = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 186) * 0.1;
|
||
//MaxDisChargePower = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 188) * 0.1;
|
||
//bMSRtCtrCell.BMSStateValue = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 158);
|
||
|
||
//bMSRtCtrCell.SOC = ModbusTcpNetDrive.ByteTransform.TransUInt16(OperateResultBytes1.Content, 164) * 0.1;
|
||
|
||
AccChargPw = ModbusTcpNetDrive.ByteTransform.TransUInt32(OperateResultBytes1.Content, 58) * 0.001;
|
||
AccDisChargPw = ModbusTcpNetDrive.ByteTransform.TransUInt32(OperateResultBytes1.Content, 62) * 0.001;
|
||
|
||
//通过PCS交流侧的电压判断交流主断是否闭合
|
||
BmsDataService.BmsIO.PcsAcCircuitBreaker = PcsAcCircuitBreaker;
|
||
|
||
PcsRunState.LinkBitValue = 1;
|
||
//PCSLinkState = true;
|
||
}
|
||
else
|
||
{
|
||
PcsRunState.LinkBitValue = 2;
|
||
//通信失败
|
||
//PCSLinkState = false;
|
||
}
|
||
|
||
OperateResultBool3 = ModbusTcpNetDrive.ReadDiscrete("81", 20);
|
||
if (OperateResultBool3.IsSuccess)
|
||
{
|
||
PcsRunState.PCSStateValue = OperateResultBool3.Content.Skip(0).Take(3).ToArray();
|
||
PcsRunState.PcsSysFaultStateVaue = OperateResultBool3.Content[3];
|
||
PcsRunState.PcsSysAlarmVaue = OperateResultBool3.Content[4];
|
||
PcsRunState.PcsRemoteLocationStateValue = OperateResultBool3.Content[5];
|
||
PcsRunState.PcsOffLineStateValue = OperateResultBool3.Content[7];
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 指令追踪模型
|
||
/// </summary>
|
||
public TranceCmdValue PwTranceCmdValues { get; set; }
|
||
|
||
/// <summary>
|
||
/// 功率指令的值超过变化的阀值
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void PwTranceCmdValues_CmdValueChanged(object sender, double targetpw)
|
||
{
|
||
//Console.WriteLine($"datetime:{DateTime.Now.ToString()} 指令变化 发送储能功率:{targetpw}");
|
||
if (targetpw == 0)
|
||
{
|
||
//Charg_DisChargInfo = "";
|
||
StandbyPwCmd();
|
||
}
|
||
else if (targetpw > 0)
|
||
{
|
||
//Charg_DisChargInfo = "充电中";
|
||
SendPcsChargCmd(targetpw);
|
||
}
|
||
else
|
||
{
|
||
//Charg_DisChargInfo = "放电中";
|
||
SendPcsDisChargCmd(targetpw);
|
||
}
|
||
}
|
||
|
||
#region Pcs的数据
|
||
|
||
/// <summary>
|
||
/// PCS 交流侧的主断路器
|
||
/// 通过PCS交流侧的电压判断交流主断是否闭合
|
||
/// </summary>
|
||
public bool PcsAcCircuitBreaker { get; set; }
|
||
|
||
private double power;
|
||
/// <summary>
|
||
/// 储能PCS的实时功率
|
||
/// 正:代表放电
|
||
/// 负:代表充电
|
||
/// </summary>
|
||
public double Power
|
||
{
|
||
get { return power; }
|
||
set
|
||
{
|
||
power = value;
|
||
if (value > 0)
|
||
{
|
||
Charg_DisChargInfo = "放电";
|
||
}
|
||
else if (value < 0)
|
||
{
|
||
Charg_DisChargInfo = "充电";
|
||
}
|
||
else
|
||
{
|
||
Charg_DisChargInfo = "";
|
||
}
|
||
RaisePropertyChanged();
|
||
}
|
||
}
|
||
|
||
private double accChargPw;
|
||
/// <summary>
|
||
/// 交流累计充电
|
||
/// </summary>
|
||
public double AccChargPw
|
||
{
|
||
get { return accChargPw; }
|
||
set { accChargPw = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double accDisChargPw;
|
||
/// <summary>
|
||
/// 交流累计放电
|
||
/// </summary>
|
||
public double AccDisChargPw
|
||
{
|
||
get { return accDisChargPw; }
|
||
set { accDisChargPw = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double aVol;
|
||
/// <summary>
|
||
/// A相电压
|
||
/// </summary>
|
||
public double AVol
|
||
{
|
||
get { return aVol; }
|
||
set
|
||
{
|
||
aVol = value;
|
||
if (value<5)
|
||
{
|
||
PcsAcCircuitBreaker = false;
|
||
}
|
||
else
|
||
{
|
||
PcsAcCircuitBreaker = true;
|
||
}
|
||
RaisePropertyChanged();
|
||
}
|
||
}
|
||
|
||
private double bVol;
|
||
/// <summary>
|
||
/// B相电压
|
||
/// </summary>
|
||
public double BVol
|
||
{
|
||
get { return bVol; }
|
||
set { bVol = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double cVol;
|
||
/// <summary>
|
||
/// C相电压
|
||
/// </summary>
|
||
public double CVol
|
||
{
|
||
get { return cVol; }
|
||
set { cVol = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double aCur;
|
||
/// <summary>
|
||
/// A相电流
|
||
/// </summary>
|
||
public double ACur
|
||
{
|
||
get { return aCur; }
|
||
set { aCur = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double bCur;
|
||
/// <summary>
|
||
/// B相电流
|
||
/// </summary>
|
||
public double BCur
|
||
{
|
||
get { return bCur; }
|
||
set { bCur = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double cCur;
|
||
/// <summary>
|
||
/// C相电流
|
||
/// </summary>
|
||
public double CCur
|
||
{
|
||
get { return cCur; }
|
||
set { cCur = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double netFreq;
|
||
/// <summary>
|
||
/// 电网频率
|
||
/// </summary>
|
||
public double NetFreq
|
||
{
|
||
get { return netFreq; }
|
||
set { netFreq = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
|
||
private double totalReactivePw;
|
||
/// <summary>
|
||
/// 电网无功功率
|
||
/// </summary>
|
||
public double TotalReactivePw
|
||
{
|
||
get { return totalReactivePw; }
|
||
set { totalReactivePw = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double totalApparentPw;
|
||
/// <summary>
|
||
/// 电网视在功率
|
||
/// </summary>
|
||
public double TotalApparentPw
|
||
{
|
||
get { return totalApparentPw; }
|
||
set { totalApparentPw = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double inputVol;
|
||
/// <summary>
|
||
/// 输入电压
|
||
/// </summary>
|
||
public double InputVol
|
||
{
|
||
get { return inputVol; }
|
||
set { inputVol = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double inputCur;
|
||
/// <summary>
|
||
/// 输入电流
|
||
/// </summary>
|
||
public double InputCur
|
||
{
|
||
get { return inputCur; }
|
||
set { inputCur = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
|
||
private double inputPw;
|
||
/// <summary>
|
||
/// 输入功率
|
||
/// </summary>
|
||
public double InputPw
|
||
{
|
||
get { return inputPw; }
|
||
set { inputPw = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double pwNetFactor;
|
||
/// <summary>
|
||
/// 功率因数
|
||
/// </summary>
|
||
public double PwNetFactor
|
||
{
|
||
get { return pwNetFactor; }
|
||
set { pwNetFactor = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
private double finTemp;
|
||
/// <summary>
|
||
/// 散热器温度
|
||
/// </summary>
|
||
public double FinTemp
|
||
{
|
||
get { return finTemp; }
|
||
set { finTemp = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
|
||
private double curCmdPw;
|
||
/// <summary>
|
||
/// 当前的指令Pw
|
||
/// 正为充电
|
||
/// 负为放电
|
||
/// </summary>
|
||
public double CurCmdPw
|
||
{
|
||
get { return curCmdPw; }
|
||
set { curCmdPw = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region PCS实时曲线
|
||
|
||
public Random rand = new Random();
|
||
|
||
/// <summary>
|
||
/// 定时器执行方法
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
private void CurTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
|
||
{
|
||
//如果Execute执行的是一个很耗时的方法,会导致方法未执行完毕,定时器又启动了一个线程来执行Execute方法
|
||
CurTimer.Stop(); //先关闭定时器
|
||
|
||
Application.Current.Dispatcher.Invoke(() =>
|
||
{
|
||
if (RtTrend.Count < 100)//2分钟
|
||
{
|
||
RtTrend.Add(new RtPcsPwChartModel() { QPw = Power, CmdPw = CurCmdPw, CurTime = DateTime.Now });//Power
|
||
}
|
||
else if (RtTrend.Count >= 100)
|
||
{
|
||
RtTrend.RemoveAt(0);
|
||
RtTrend.Add(new RtPcsPwChartModel() { QPw = Power, CmdPw = CurCmdPw, CurTime = DateTime.Now });//Power
|
||
}
|
||
});
|
||
|
||
CurTimer.Start(); //执行完毕后再开启器
|
||
}
|
||
|
||
|
||
private ObservableCollection<RtPcsPwChartModel> _RtTrend = new ObservableCollection<RtPcsPwChartModel>();
|
||
/// <summary>
|
||
/// 实时曲线 数据集合
|
||
/// </summary>
|
||
public ObservableCollection<RtPcsPwChartModel> RtTrend
|
||
{
|
||
get { return _RtTrend; }
|
||
set { _RtTrend = value; RaisePropertyChanged(); }
|
||
}
|
||
|
||
public ILogService LogService { get; }
|
||
public IFreeSql FreeSql { get; }
|
||
public BmsDataService BmsDataService { get; }
|
||
public ConfigDataService ConfigDataService { get; }
|
||
|
||
|
||
#endregion
|
||
|
||
#region PCS封装功能
|
||
|
||
/// <summary>
|
||
/// 发送PCS充电功率
|
||
/// 正是充电
|
||
/// </summary>
|
||
/// <param name="targetpw"></param>
|
||
public void SendPcsChargCmd(double targetpw)
|
||
{
|
||
CurCmdPw = targetpw;
|
||
//Console.WriteLine($"datetime:{DateTime.Now.ToString()} 发送储能功率【充电】:{targetpw}");
|
||
var result1 = ModbusTcpNetDrive.Write("309", (short)(targetpw / 3.0 * 10));
|
||
if (!result1.IsSuccess)
|
||
{
|
||
Console.WriteLine($"datetime:{DateTime.Now.ToString()} 发送【充电】储能功率【失败】:{targetpw}");
|
||
}
|
||
ModbusTcpNetDrive.Write("310", (short)(targetpw / 3.0 * 10));
|
||
ModbusTcpNetDrive.Write("311", (short)(targetpw / 3.0 * 10));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送PCS充电功率
|
||
/// 正是充电
|
||
/// </summary>
|
||
/// <param name="targetpw"></param>
|
||
public async Task SendPcsChargCmdAsync(double targetpw)
|
||
{
|
||
CurCmdPw = targetpw;
|
||
Console.WriteLine($"datetime:{DateTime.Now.ToString()} 发送储能功率【充电】:{targetpw}");
|
||
var result1 = await ModbusTcpNetDrive.WriteAsync("309", (short)(targetpw / 3.0 * 10));
|
||
if (!result1.IsSuccess)
|
||
{
|
||
Console.WriteLine($"datetime:{DateTime.Now.ToString()} 发送【充电】储能功率【失败】:{targetpw}");
|
||
}
|
||
await ModbusTcpNetDrive.WriteAsync("310", (short)(targetpw / 3.0 * 10));
|
||
await ModbusTcpNetDrive.WriteAsync("311", (short)(targetpw / 3.0 * 10));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送PCS放电功率
|
||
/// 负是放电
|
||
/// </summary>
|
||
/// <param name="targetpw"></param>
|
||
public void SendPcsDisChargCmd(double targetpw)
|
||
{
|
||
CurCmdPw = targetpw;
|
||
//Console.WriteLine($"datetime:{DateTime.Now.ToString()} 发送储能功率【放电】:{targetpw}");
|
||
var result1 = ModbusTcpNetDrive.Write("309", (short)(targetpw / 3.0 * 10));
|
||
if (!result1.IsSuccess)
|
||
{
|
||
Console.WriteLine($"datetime:{DateTime.Now.ToString()} 发送【放电】储能功率【失败】:{targetpw}");
|
||
}
|
||
ModbusTcpNetDrive.Write("310", (short)(targetpw / 3.0 * 10));
|
||
ModbusTcpNetDrive.Write("311", (short)(targetpw / 3.0 * 10));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送PCS放电功率
|
||
/// 负是放电
|
||
/// </summary>
|
||
/// <param name="targetpw"></param>
|
||
public async Task SendPcsDisChargCmdAsync(double targetpw)
|
||
{
|
||
CurCmdPw = targetpw;
|
||
Console.WriteLine($"datetime:{DateTime.Now.ToString()} 发送储能功率【放电】:{targetpw}");
|
||
var result1 = await ModbusTcpNetDrive.WriteAsync("309", (short)(targetpw / 3.0 * 10));
|
||
if (!result1.IsSuccess)
|
||
{
|
||
Console.WriteLine($"datetime:{DateTime.Now.ToString()} 发送【放电】储能功率【失败】:{targetpw}");
|
||
}
|
||
await ModbusTcpNetDrive.WriteAsync("310", (short)(targetpw / 3.0 * 10));
|
||
await ModbusTcpNetDrive.WriteAsync("311", (short)(targetpw / 3.0 * 10));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送PCS待机指令
|
||
/// 就是给0的数据值
|
||
/// </summary>
|
||
public void StandbyPwCmd()
|
||
{
|
||
CurCmdPw = 0;
|
||
//Console.WriteLine($"时间:{DateTime.Now.ToString()}:发送0功率值,PCS待机数据 ");
|
||
|
||
ModbusTcpNetDrive.Write("309", (short)(0 / 3.0 * 10));
|
||
|
||
ModbusTcpNetDrive.Write("310", (short)(0 / 3.0 * 10));
|
||
|
||
ModbusTcpNetDrive.Write("311", (short)(0 / 3.0 * 10));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送PCS待机指令
|
||
/// 就是给0的数据值
|
||
/// </summary>
|
||
public async Task StandbyPwCmdAsync()
|
||
{
|
||
CurCmdPw = 0;
|
||
Console.WriteLine($"时间:{DateTime.Now.ToString()}:发送0功率值,PCS待机数据 ");
|
||
|
||
await ModbusTcpNetDrive.WriteAsync("309", (short)(0 / 3.0 * 10));
|
||
|
||
await ModbusTcpNetDrive.WriteAsync("310", (short)(0 / 3.0 * 10));
|
||
|
||
await ModbusTcpNetDrive.WriteAsync("311", (short)(0 / 3.0 * 10));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 并离网的配置
|
||
/// </summary>
|
||
public void PcsOffLineCmd(PCSOffLineInfo pCSOffLineInfo)
|
||
{
|
||
switch (pCSOffLineInfo)
|
||
{
|
||
case PCSOffLineInfo.OnLine:
|
||
ModbusTcpNetDrive.Write("306", (short)1);
|
||
break;
|
||
case PCSOffLineInfo.OffLine:
|
||
ModbusTcpNetDrive.Write("306", (short)0);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 并离网的配置
|
||
/// </summary>
|
||
public async Task PcsOffLineCmdAsync(PCSOffLineInfo pCSOffLineInfo)
|
||
{
|
||
switch (pCSOffLineInfo)
|
||
{
|
||
case PCSOffLineInfo.OnLine:
|
||
await ModbusTcpNetDrive.WriteAsync("306", (short)1);
|
||
break;
|
||
case PCSOffLineInfo.OffLine:
|
||
await ModbusTcpNetDrive.WriteAsync("306", (short)0);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// PCS启动 异步
|
||
/// </summary>
|
||
public async Task<bool> PCSStartAsync()
|
||
{
|
||
var Result = await ModbusTcpNetDrive.WriteAsync("2", true);
|
||
if (Result.IsSuccess)
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// PCS启动
|
||
/// </summary>
|
||
public bool PCSStart()
|
||
{
|
||
var Result = ModbusTcpNetDrive.Write("2", true);
|
||
if (Result.IsSuccess)
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// PCS停止
|
||
/// </summary>
|
||
public bool PCSStop()
|
||
{
|
||
var Result = ModbusTcpNetDrive.Write("3", true);
|
||
if (Result.IsSuccess)
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// PCS停止 异步
|
||
/// </summary>
|
||
public async Task<bool> PCSStopAsync()
|
||
{
|
||
var Result = await ModbusTcpNetDrive.WriteAsync("3", true);
|
||
if (Result.IsSuccess)
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// PCS故障复位
|
||
/// </summary>
|
||
public bool PCSFaultReset()
|
||
{
|
||
var Result = ModbusTcpNetDrive.Write("1", true);
|
||
if (Result.IsSuccess)
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// PCS故障复位
|
||
/// </summary>
|
||
public async Task<bool> PCSFaultResetAsync()
|
||
{
|
||
var Result = await ModbusTcpNetDrive.WriteAsync("1", true);
|
||
if (Result.IsSuccess)
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// PCS远程和本地切换
|
||
/// </summary>
|
||
public async Task<bool> PCSRemoteLocation(bool value)
|
||
{
|
||
var Result = await ModbusTcpNetDrive.WriteAsync("7", value);
|
||
if (Result.IsSuccess)
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// PCS远程和本地切换
|
||
/// </summary>
|
||
public async Task<bool> PCSRemoteLocationAsync(bool value)
|
||
{
|
||
var Result = await ModbusTcpNetDrive.WriteAsync("7", value);
|
||
if (Result.IsSuccess)
|
||
{
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
///关闭驱动链接
|
||
/// </summary>
|
||
public void CloseModbusRtu()
|
||
{
|
||
ThreadEnable = false;
|
||
CurTimer.Stop();
|
||
ModbusTcpNetDrive.ConnectClose();
|
||
}
|
||
|
||
/// <summary>
|
||
///关闭驱动链接
|
||
/// </summary>
|
||
public async Task CloseModbusRtuAsync()
|
||
{
|
||
ThreadEnable = false;
|
||
await ModbusTcpNetDrive.ConnectCloseAsync();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 报警
|
||
|
||
/// <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))
|
||
{
|
||
//FSqlContext.FDb.Select
|
||
//统一的处理报警信息
|
||
FreeSql.Insert<HistoryAlarm>(new HistoryAlarm()
|
||
{
|
||
Category = "PCS",
|
||
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}");
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
}
|
||
}
|