using Bro.Common.Base;
|
using Bro.Common.Helper;
|
using Bro.Common.Interface;
|
using Bro.Common.Model;
|
using System;
|
using System.Collections.Generic;
|
using System.Diagnostics;
|
using System.IO.Ports;
|
using System.Linq;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
using static Bro.Common.Helper.EnumHelper;
|
|
namespace Bro.Device.DAMModule
|
{
|
[Device("DAMModule", "DAM模块", EnumHelper.DeviceAttributeType.Device)]
|
public class DAMDriver : DeviceBase, IMonitor
|
{
|
#region IMonitor
|
public List<int> InputIOs { get; set; } = new List<int>();
|
public List<int> OutputIOs { get; set; } = new List<int>();
|
|
public event Action<DateTime, string, IDevice, MonitorSet> OnMonitorInvoke;
|
public event Action<DateTime, IDevice, WarningSet> OnMonitorAlarm;
|
|
public void Monitor()
|
{
|
while (CurrentState == EnumHelper.DeviceState.DSOpen)
|
{
|
if (!IConfig.IsEnableMonitor)
|
return;
|
|
_writeHandle.WaitOne();
|
|
lock (_writeLock)
|
{
|
sp.Write(byteReadAllInput, 0, byteReadAllInput.Length);
|
Thread.Sleep(IConfig.ReadWaitTime);
|
byte[] recBuffer = new byte[2048];
|
int recNum = sp.Read(recBuffer, 0, recBuffer.Length);
|
if (recNum > 0)
|
{
|
var data = AnalysisRcv(recBuffer.Take(recNum).ToArray()).ToList();
|
List<int> temp = new List<int>();
|
data.ForEach(d =>
|
{
|
for (int i = 0; i < 8; i++)
|
{
|
temp.Add((d >> i) & 1);
|
}
|
});
|
|
if (temp.Count() == InputIOs.Count())
|
{
|
MonitorCheckAndInvoke(temp, new List<int>(InputIOs));
|
}
|
|
InputIOs = new List<int>(temp);
|
}
|
|
if (IConfig.IsMonitorOutput)
|
{
|
sp.Write(byteReadAllOutput, 0, byteReadAllOutput.Length);
|
Thread.Sleep(IConfig.ReadWaitTime);
|
recBuffer = new byte[2048];
|
recNum = sp.Read(recBuffer, 0, recBuffer.Length);
|
if (recNum > 0)
|
{
|
var data = AnalysisRcv(recBuffer.Take(recNum).ToArray()).ToList();
|
List<int> temp = new List<int>();
|
data.ForEach(d =>
|
{
|
for (int i = 0; i < 8; i++)
|
{
|
temp.Add((d >> i) & 1);
|
}
|
});
|
|
OutputIOs = new List<int>(temp);
|
}
|
}
|
}
|
|
if (IConfig.MonitorInterval > 0)
|
Thread.Sleep(IConfig.MonitorInterval);
|
}
|
}
|
|
private async void MonitorCheckAndInvoke(List<int> tempNew, List<int> tempOld)
|
{
|
await Task.Run(() =>
|
{
|
Parallel.ForEach(IConfig.MonitorSetCollection, set =>
|
{
|
MonitorSet monitorSet = set as MonitorSet;
|
if (monitorSet.TriggerIndex < 0 || monitorSet.TriggerIndex >= tempNew.Count)
|
{
|
return;
|
}
|
|
int newValue = tempNew[monitorSet.TriggerIndex];
|
int oldValue = tempOld[monitorSet.TriggerIndex];
|
|
if (newValue != oldValue)
|
{
|
if (monitorSet.TriggerValue == -999 || newValue == monitorSet.TriggerValue)
|
{
|
if (monitorSet.OpConfig == null)
|
{
|
monitorSet.OpConfig = new OperationConfigBase();
|
}
|
|
monitorSet.OpConfig.InputPara = monitorSet.InputDataIndex.ConvertAll(index =>
|
{
|
return tempNew[index];
|
}).ToList();
|
|
OnMonitorInvoke?.BeginInvoke(DateTime.Now, monitorSet.InvokeDevice, this, monitorSet, OnMethodInvoked, monitorSet);
|
}
|
}
|
});
|
});
|
}
|
|
private void OnMethodInvoked(IAsyncResult ar)
|
{
|
MonitorSet monitorSet = ar.AsyncState as MonitorSet;
|
|
ProcessResponse resValues = monitorSet.Response;
|
|
if (resValues.ResultValue == (int)PLCReplyValue.IGNORE)
|
{
|
return;
|
}
|
|
Stopwatch sw = new Stopwatch();
|
sw.Start();
|
|
//if (monitorSet.ReplyDataAddress != -1 && resValues.DataList.Count > 0)
|
//{
|
// PLCItem item = new PLCItem
|
// {
|
// ItemLength = resValues.DataList.Count,
|
// Address = monitorSet.ReplyDataAddress.ToString(),
|
// ItemValues = resValues.DataList.ConvertAll(s => int.Parse(s.ToString())).ToList()
|
// };
|
// WriteItem(item, false);
|
//}
|
|
if (monitorSet.NoticeAddress != -1)
|
{
|
int repeatTime = 5;
|
|
do
|
{
|
try
|
{
|
WriteOutput(monitorSet.NoticeAddress, resValues.ResultValue == 1);
|
repeatTime = 0;
|
}
|
catch (Exception ex)
|
{
|
repeatTime--;
|
|
if (repeatTime <= 0)
|
{
|
new ProcessException($"{Name}反馈写入异常", ex, ExceptionLevel.Warning);
|
}
|
}
|
} while (repeatTime > 0);
|
}
|
|
sw.Stop();
|
LogAsync(DateTime.Now, $"{Name}反馈完成,耗时{sw.ElapsedMilliseconds}ms", $"{resValues.GetDisplayText()}");
|
}
|
|
private byte[] AnalysisRcv(byte[] src)
|
{
|
if (src.Length < 6) return null;
|
if (src[0] != Convert.ToInt16(IConfig.UnitNum)) return null;
|
|
switch (src[1])
|
{
|
case 0x01:
|
if (CMBRTU.CalculateCrc(src, src[2] + 5) == 0x00)
|
{
|
byte[] dst = new byte[src[2]];
|
for (int i = 0; i < src[2]; i++)
|
dst[i] = src[3 + i];
|
return dst;
|
}
|
break;
|
case 0x02:
|
if (CMBRTU.CalculateCrc(src, src[2] + 5) == 0x00)
|
{
|
byte[] dst = new byte[src[2]];
|
for (int i = 0; i < src[2]; i++)
|
dst[i] = src[3 + i];
|
return dst;
|
}
|
break;
|
case 0x04:
|
if (CMBRTU.CalculateCrc(src, src[2] + 5) == 0x00)
|
{
|
byte[] dst = new byte[src[2]];
|
for (int i = 0; i < src[2]; i++)
|
dst[i] = src[3 + i];
|
return dst;
|
}
|
break;
|
case 0x05:
|
if (CMBRTU.CalculateCrc(src, 8) == 0x00)
|
{
|
byte[] dst = new byte[1];
|
dst[0] = src[4];
|
return dst;
|
}
|
break;
|
case 0x0f:
|
if (CMBRTU.CalculateCrc(src, 8) == 0x00)
|
{
|
byte[] dst = new byte[1];
|
dst[0] = 1;
|
return dst;
|
}
|
break;
|
}
|
return null;
|
}
|
|
public void ResetAlarm()
|
{
|
|
}
|
|
ManualResetEvent _writeHandle = new ManualResetEvent(true);
|
object _writeLock = new object();
|
public void WriteOutput(int index, bool isOpen, bool isShortSingal = true, int elaspedTime = 0)
|
{
|
_writeHandle.Reset();
|
lock (_writeLock)
|
{
|
try
|
{
|
if (index < 0 || index > IConfig.OutputNums)
|
{
|
LogAsync(DateTime.Now, $"写入索引{index}超限,写入失败", "");
|
}
|
|
byte[] byteData = CModbusDll.WriteDO(IConfig.UnitNum, index, isOpen);
|
sp.Write(byteData, 0, byteData.Length);
|
|
if (isShortSingal)
|
{
|
if (elaspedTime == 0)
|
{
|
elaspedTime = IConfig.SignalElasped;
|
}
|
|
Thread.Sleep(elaspedTime);
|
byteData = CModbusDll.WriteDO(IConfig.UnitNum, index, !isOpen);
|
sp.Write(byteData, 0, byteData.Length);
|
}
|
|
Thread.Sleep(IConfig.ReadWaitTime);
|
sp.ReadExisting();
|
}
|
catch (Exception ex)
|
{
|
throw ex;
|
}
|
finally
|
{
|
_writeHandle.Set();
|
}
|
}
|
}
|
#endregion
|
|
#region DeviceBase
|
SerialPort sp = null;
|
byte[] byteCloseAll = null;
|
byte[] byteOpenAll = null;
|
byte[] byteReadAllOutput = null;
|
byte[] byteReadAllInput = null;
|
|
DAMInitialConfig IConfig
|
{
|
get => InitialConfig as DAMInitialConfig;
|
}
|
|
protected override void Init()
|
{
|
sp = new SerialPort(IConfig.PortName);
|
sp.BaudRate = int.Parse(IConfig.BaudRate);
|
sp.Parity = IConfig.Parity;
|
sp.DataBits = IConfig.DataBits;
|
sp.StopBits = IConfig.StopBits;
|
|
byteCloseAll = CModbusDll.WriteAllDO(IConfig.UnitNum, IConfig.OutputNums, false);
|
byteOpenAll = CModbusDll.WriteAllDO(IConfig.UnitNum, IConfig.OutputNums, true);
|
byteReadAllOutput = CModbusDll.ReadDO(IConfig.UnitNum, IConfig.OutputNums);
|
byteReadAllInput = CModbusDll.ReadDI(IConfig.UnitNum, IConfig.InputNums);
|
}
|
|
protected override void Pause()
|
{
|
}
|
|
protected override void Resume()
|
{
|
}
|
|
protected override void Start()
|
{
|
sp.Open();
|
_writeHandle = new ManualResetEvent(true);
|
}
|
|
protected override void Stop()
|
{
|
if (sp != null && sp.IsOpen)
|
{
|
sp.Close();
|
}
|
|
_writeHandle.Set();
|
_writeHandle.Dispose();
|
}
|
#endregion
|
}
|
}
|