MoS2/Framework/MECF.Framework.RT.EquipmentLibrary/HardwareUnits/SMIFs/Fortrend/SMIFBase.cs
2026-06-15 10:56:30 +08:00

218 lines
5.5 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.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();
}
}
}