Sic.Framework-Nanjing-Baishi/MECF.Framework.RT.Equipment.../HardwareUnits/Temps/AE/AETemp.cs

458 lines
14 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 Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.RT.IOCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Communications;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps.Omron;
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps.AE
{
public class AETemp : BaseDevice, IConnection, IDevice, ITempData
{
private AETempConnection _connection;
private bool _activeMonitorStatus;
private int _errorCode;
private R_TRIG _trigCommunicationError = new R_TRIG();
private R_TRIG _trigRetryConnect = new R_TRIG();
private R_TRIG _trigFewChannels = new R_TRIG();
private PeriodicJob _thread;
private int tempCount = 1;
private LinkedList<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();
private object _locker = new object();
private bool _enableLog = true;
private string _scRoot;
public double TempData1 { get; set; }
public double TempData2 { get; set; }
public double TempData3 { get; set; }
public double TempData4 { get; set; }
public string Address
{
get; set;
}
public bool IsConnected
{
get
{
return _connection != null && _connection.IsConnected;
}
}
public bool Connect()
{
return true;
}
public bool Disconnect()
{
return true;
}
public AETemp(string module, string name, string scRoot) : base(module, name, name, name)
{
_scRoot = scRoot;
_activeMonitorStatus = true;
}
~AETemp()
{
_connection.Disconnect();
}
public void QueryTemp()
{
_lstHandler.AddLast(new AETempReadCommandHandler(this, "OUT", "1"));
}
public void ResetDevice()
{
}
public void QueryError()
{
EV.PostInfoLog(Module, "Query error");
}
public bool Initialize(string address, bool enableLogMessage)
{
DATA.Subscribe($"PM1.{Name}.Middle", () => TempData1);
DATA.Subscribe($"PM1.{Name}.Outer", () => TempData2);
DATA.Subscribe($"PM2.{Name}.Middle", () => TempData3);
DATA.Subscribe($"PM2.{Name}.Outer", () => TempData4);
Address = address;
_enableLog = enableLogMessage;
_connection = new AETempConnection(address);
_connection.EnableLog(enableLogMessage);
_thread = new PeriodicJob(400, OnTimer, $"{Module}.{Name} MonitorHandler", true);
ConnectionManager.Instance.Subscribe($"{Name}", this);
return true;
}
private bool OnTimer()
{
try
{
_connection.MonitorTimeout();
//
if (!_connection.IsConnected || _connection.IsCommunicationError)
{
lock (_locker)
{
_lstHandler.Clear();
}
//只要断开,就进行连接
if (!_connection.Connect())
{
_trigRetryConnect.CLK = !_connection.IsConnected;
if (_trigRetryConnect.Q)
{
LOG.Write($"{Module}.PMAETemp.SetPyroCommunicationError");
EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");
//在Process模式和PreProcess模式下AE掉线直接Abort
object objStatus = DATA.Poll($"{Module}.Status");
if (objStatus != null)
{
string moduleStatus = objStatus.ToString();
if (moduleStatus == "PreProcess" || moduleStatus == "Process")
{
OP.DoOperation($"{Module}.Abort");
EV.PostAlarmLog("PM1", $"Can not connect with {_connection.Address}, {Module}.{Name}, Abort!");
EV.PostAlarmLog("PM2", $"Can not connect with {_connection.Address}, {Module}.{Name}, Abort!");
}
else
{
//EV.PostWarningLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");
LOG.Write(Module + $"Can not connect with {_connection.Address}, {Module}.{Name}");
}
}
else
{
LOG.Write(Module + $"Can not connect with {_connection.Address}, {Module}.{Name}");
}
}
_connection.ForceClear();
Thread.Sleep(1000);//重连延时
return true;
}
else
{
//连接成功后不会再进入所以也只是写入一次LOG
LOG.Write($"{Module} {Name} Connected");
EV.PostInfoLog(Module, $"{Name} Connected");
}
_trigRetryConnect.CLK = !_connection.IsConnected;
_connection.ForceClear();
return true;
}
//
HandlerBase handler = null;
lock (_locker)
{
if (_lstHandler.Count == 0)
QueryTemp();
if (_lstHandler.Count > 0 && !_connection.IsBusy)
{
handler = _lstHandler.First.Value;
_lstHandler.RemoveFirst();
if (handler != null)
{
_connection.Execute(handler);
}
}
}
}
catch (Exception ex)
{
LOG.Write(ex);
}
return true;
}
internal void NoteError()
{
}
public void ParseCommandInfo(string command, string Message)
{
try
{
switch (command)
{
case "OUT":
{
if (Message != null)
{
if (Message.Contains(" "))
{
var strs = Message.Split(' ');
if (strs.Length >= 4)
{
_trigFewChannels.CLK = false;
//
TempData1 = Convert.ToDouble(strs[0]);
TempData2 = Convert.ToDouble(strs[1]);
TempData3 = Convert.ToDouble(strs[2]);
TempData4 = Convert.ToDouble(strs[3]);
}
else
{
_trigFewChannels.CLK = true;
if (_trigFewChannels.Q)
{
EV.PostAlarmLog("PM1", "AE Error: Too few channels.");
EV.PostAlarmLog("PM2", "AE Error: Too few channels.");
}
}
}
}
}
break;
}
}
catch (Exception ex)
{
}
}
#region
//qbh 20220309
const int iQueCap = 10;
static Queue qWafInner = new Queue(iQueCap);
//static Queue qSusInner = new Queue(iQueCap);
static Queue qWafMiddle = new Queue(iQueCap);
//static Queue qSusMiddle = new Queue(iQueCap);
static Queue qWafOuter = new Queue(iQueCap);
//static Queue qSusOuter = new Queue(iQueCap);
const double dbThres = 20.0;
public static double TempFilter(string sName, double dbNewTemp)
{
//
Queue qTempData = new Queue();
switch (sName)
{
case "TempData1":
qTempData = qWafInner;
break;
case "TempData2":
qTempData = qWafMiddle;
break;
case "TempData3":
qTempData = qWafOuter;
break;
default:
break;
}
//
qTempData.Enqueue(dbNewTemp);
//
if (qTempData.Count < iQueCap)
{
return dbNewTemp;
}
else
{
//
while (qTempData.Count > iQueCap)
{
qTempData.Dequeue();
}
//
List<double> liTemp = new List<double>();
object[] objs = qTempData.ToArray();
foreach (object obj in objs)
{
liTemp.Add((double)obj);
}
liTemp.Sort();
if (liTemp.Count > 0)
{
liTemp.RemoveAt(0);
}
liTemp.Reverse();
if (liTemp.Count > 0)
{
liTemp.RemoveAt(0);
}
//
double dbAvg = 0.0;
foreach (double data in liTemp)
{
dbAvg += data;
}
dbAvg /= liTemp.Count;
//
return dbAvg;
}
//
}
/// <summary>
/// 均方根值法
/// </summary>
/// <param name="sName"></param>
/// <param name="dbNewTemp"></param>
/// <returns></returns>
public static double TempFilter2(string sName, double dbNewTemp)
{
//
Queue qTempData = new Queue();
switch (sName)
{
case "TempData1":
qTempData = qWafInner;
break;
case "TempData2":
qTempData = qWafMiddle;
break;
case "TempData3":
qTempData = qWafOuter;
break;
default:
break;
}
//
qTempData.Enqueue(dbNewTemp);
//
if (qTempData.Count < iQueCap)
{
return dbNewTemp;
}
else
{
//
while (qTempData.Count > iQueCap)
{
qTempData.Dequeue();
}
//
List<double> liTemp = new List<double>();
object[] objs = qTempData.ToArray();
foreach (object obj in objs)
{
liTemp.Add((double)obj);
}
liTemp.Sort();
if (liTemp.Count > 0)
{
liTemp.RemoveAt(0);
}
liTemp.Reverse();
if (liTemp.Count > 0)
{
liTemp.RemoveAt(0);
}
//均方根
double dbAvg = 0.0;
foreach (double data in liTemp)
{
dbAvg += data * data;
}
dbAvg /= liTemp.Count;
dbAvg = Math.Sqrt(dbAvg);
//
return dbAvg;
}
//
}
#endregion
public void Monitor()
{
try
{
_connection.EnableLog(_enableLog);
_trigCommunicationError.CLK = _connection.IsCommunicationError;
if (_trigCommunicationError.Q)
{
EV.PostAlarmLog("PM1", $"{Module}.{Name} communication error, {_connection.LastCommunicationError}");
EV.PostAlarmLog("PM2", $"{Module}.{Name} communication error, {_connection.LastCommunicationError}");
}
}
catch (Exception ex)
{
LOG.Write(ex);
}
}
public void Reset()
{
_connection.SetCommunicationError(false, "");
_enableLog = SC.GetValue<bool>($"AETemp.EnableLogMessage");
_trigCommunicationError.RST = true;
//_trigRetryConnect.RST = true;
_trigFewChannels.RST = true;
}
public void SetActiveMonitor(bool active)
{
_activeMonitorStatus = active;
}
public void SetErrorCode(int errorCode)
{
_errorCode = errorCode;
}
public void Terminate()
{
_connection.Disconnect();
}
public bool Initialize()
{
return true;
}
}
}