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

458 lines
14 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
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;
}
}
}