MoS2/Framework/MECF.Framework.RT.EquipmentLibrary/HardwareUnits/SMIFs/Fortrend/SMIFBase.cs

218 lines
5.5 KiB
C#
Raw Permalink Normal View History

2026-06-15 10:56:30 +08:00
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using System;
using System.Collections.Concurrent;
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.SMIFs.Fortrend
{
public abstract class SMIFBase : BaseDevice, IDevice
{
protected bool IsInstalled;
private string _scRoot;
private bool _enableLog;
//完成标志
public bool IsDone = true;
public bool IsHomeDone;
public bool IsLoadDone;
public bool IsUnloadDone;
public bool IsLockDone;
public bool IsUnLockDone;
public bool IsSwitchDone;
public bool IsCassetteExist => _diCassetteExist != null ? _diCassetteExist.Value : false;
public string Mode;
public string PortStatus;
public bool IsPodPresent => _diPodInPlace != null ? _diPodInPlace.Value : false;
public bool IsSMIFReady => _diReady != null ? _diReady.Value : false;
public bool IsSMIFAlarm => _diAlarm != null ? _diAlarm.Value : true;
public bool IsHomed;
//当前错误码
public int CurErrorCode;
protected DIAccessor _diReady = null;
protected DIAccessor _diAlarm = null;
protected DIAccessor _diPodInPlace = null;
protected DIAccessor _diReadyToUnload = null;
protected DIAccessor _diCassetteExist = null;
public DOAccessor DoUnloadEnable = null;
public DOAccessor DoStartRun = null;
public DOAccessor DoPortLock = null;
public DOAccessor DoLoadEnable = null;
public DOAccessor DoHomeEnable = null;
private SerialPortEx _serialPort;
public bool IsConnected => _serialPort != null ? _serialPort.IsOpen : false;
private R_TRIG _trigger = new R_TRIG();
public string Delimiter => _serialPort?.Delimiter;
private readonly object _locker = new object();
private ConcurrentQueue<string> _actionQueue = new ConcurrentQueue<string>();
public SMIFBase()
{
}
public SMIFBase(string module, string name)
{
Module = module;
Name = name;
}
public virtual bool Initialize()
{
IsInstalled = SC.GetValue<bool>($"System.SetUp.Is{Module}Installed");
if(IsInstalled )
{
InitSerialPort();
}
return true;
}
private void InitSerialPort()
{
try
{
string portName = string.Empty;
if (string.IsNullOrEmpty(_scRoot))
{
portName = SC.GetStringValue($"{Name}.PortName");
_enableLog = SC.GetValue<bool>($"{Name}.EnableLogMessage");
}
else
{
portName = SC.GetStringValue($"{_scRoot}.{Module}.{Name}.PortName");
_enableLog = SC.GetValue<bool>($"{_scRoot}.{Module}.{Name}.EnableLogMessage");
}
_serialPort = new SerialPortEx(portName);
_serialPort.Delimiter = "\r\n";
_serialPort.OnReceivedEvent += OnReceived;
_serialPort.Connect();
}
catch (Exception ex)
{
EV.PostAlarmLog(Module, $"{Module} connect IP:{_serialPort.PortName} failed");
LOG.Error(ex.Message, ex);
}
}
public virtual void OnReceived(string msg)
{
}
protected void AddActionToQueue(string msg)
{
if (IsConnected)
_actionQueue.Enqueue(msg);
}
protected void ClearCmdQueue()
{
lock (_locker)
{
//ConcurrentQueue<T>是线程安全的所以它不会暴露或提供Clear方法清空
while (_actionQueue.TryDequeue(out _))
{
}
}
}
protected override void HandleMonitor()
{
if(!IsInstalled)
{
return;
}
//断连后将指令队列清空
_trigger.CLK = !_serialPort.IsOpen;
if (_trigger.Q)
{
ClearCmdQueue();
EV.PostAlarmLog(Module, $"{_serialPort.PortName} Disconnected!");
}
lock (_locker)
{
//连接成功 && SMIF不是Alarm && SMIF 空闲状态
if (_serialPort != null && _serialPort.IsOpen /*&& IsSMIFReady*/ && IsDone)
{
if (_actionQueue.Count > 0 && _actionQueue.TryDequeue(out string msg))
{
IsDone = false;
SendMessage(msg);
}
}
}
}
private void SendMessage(string msg)
{
try
{
if (IsConnected)
{
_serialPort.Send(msg);
if (!msg.StartsWith("FSR"))
EV.PostInfoLog(Module, $"向{Name}发送指令:{msg.Replace("\r", "").Replace("\n", "")}");
}
}
catch (Exception ex)
{
LOG.Error(ex.Message);
}
}
public virtual void Reset()
{
_serialPort?.Reset();
}
public virtual void Terminate()
{
_serialPort?.Close();
}
}
}