using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Aitex.Core.RT.Device.Unit;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using Aitex.Sorter.Common;
using MECF.Framework.Common.Communications;
using TSC = Aitex.Sorter.Common;
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDK
{
///
/// 代码说明:
///
///
public class TDKLoadPort : LoadPort, IE84Provider,IConnection
{
public string Address { get; set; }
public bool IsConnected
{
get { return _port.IsOpen(); }
}
public bool UnlockKey
{
set
{
}
}
public bool Enable
{
set
{
if (_enableTrigger != null)
{
_enableTrigger.SetTrigger(value, out _);
}
}
}
public bool FFUIsOK { get; set; }
private LoadportCassetteState _cassetteState = LoadportCassetteState.None;
public override LoadportCassetteState CassetteState
{
get { return _cassetteState; }
set
{
_cassetteState = value;
}
}
public bool Processed { get; set; }
public bool Communication
{
get
{
return _port == null ? !_commErr : !_commErr && _port.IsOpen();
}
}
//
public override bool IsBusy
{
get { return _foregroundHandler != null || _handlers.Count > 0 ; }
}
public override bool IsMoving
{
get { return _foregroundHandler != null && _handlers.Count > 0; }
}
public const string delimiter = "\r";
public const int min_len = 3; //S00
private static Object _locker = new Object();
private AsyncSerial _port;
private bool _commErr = false;
private IHandler _eventHandler = null;
private IHandler _foregroundHandler = null; //moving
private Queue _handlers = new Queue();
private IoSensor _sensorEnable = null;
private IoTrigger _enableTrigger = null;
public TDKLoadPort(string module, string name, string port, IoSensor sensorEnable, IoTrigger triggerEnable,
EnumLoadPortType portType =EnumLoadPortType.LoadPort)
: base(module, name )
{
_port = new AsyncSerial(port, 9600, 8);
_port.OnDataChanged += (OnDataChanged);
_port.OnErrorHappened += (OnErrorHandler);
_eventHandler = new handler(Name);
_sensorEnable = sensorEnable;
_enableTrigger = triggerEnable;
Initalized = false;
IsMapWaferByLoadPort = portType== EnumLoadPortType.LoadPort;
PortType = portType;
IndicatiorLoad = IndicatorState.UNKNOW;
IndicatiorUnload = IndicatorState.UNKNOW;
IndicatiorPresence = IndicatorState.UNKNOW;
IndicatorAlarm = IndicatorState.UNKNOW;
IndicatiorPlacement = IndicatorState.UNKNOW;
IndicatiorOpAccess = IndicatorState.UNKNOW;
IndicatiorStatus1 = IndicatorState.UNKNOW;
IndicatiorStatus2 = IndicatorState.UNKNOW;
DoorState = FoupDoorState.Unknown;
ClampState = FoupClampState.Unknown;
CassetteState = LoadportCassetteState.Unknown;
if (!this.QueryState(out string reason))
{
EV.PostAlarmLog(module,$"Query state error.{reason}");
}
Enable = true;
Address = port;
}
public void SetCassetteState(LoadportCassetteState state)
{
_cassetteState = state;
if (state == LoadportCassetteState.Normal)
{
if (!_isPlaced)
{
OnCarrierPlaced();
}
if (!_isPresent)
{
OnCarrierPresent();
}
}
}
public override bool Initialize()
{
base.Initialize();
_commErr = true;
ConnectionManager.Instance.Subscribe($"{Name}", this);
Connect();
//if (!RetryInstance.Instance().Execute(
// ()=> _port.Open(),
// SC.GetValue("System.ComPortRetryDelayTime"),
// SC.GetValue("System.ComPortRetryCount"),
// true
//))
//{
// return false;
//}
return true;
}
public override bool Connect()
{
_commErr = false;
Task.Factory.StartNew(() =>
{
int count = SC.ContainsItem("System.ComPortRetryCount") ? SC.GetValue("System.ComPortRetryCount") : 3;
int sleep = SC.ContainsItem("System.ComPortRetryDelayTime") ? SC.GetValue("System.ComPortRetryDelayTime") : 2;
if (sleep <= 0 || sleep > 10)
sleep = 2;
int retry = 0;
do
{
if (_port.Open())
{
//LOG.Write($"Connected with {Module}.{Name} .");
EV.PostInfoLog(Module, $"Connected with {Module}.{Name} .");
break;
}
if (count > 0 && retry++ > count)
{
//LOG.Write($"Retry connect {Module}.{Name} stop retry.");
EV.PostAlarmLog(Module, $"Can't connect to {Module}.{Name}.");
break;
}
{
Thread.Sleep(sleep * 1000);
//LOG.Write($"Retry connect {Module}.{Name} for the {retry + 1} time.");
}
} while (true);
});
return true;
}
public bool Disconnect()
{
return true;
}
public override bool IsEnableMapWafer()
{
if (IsIdle
&& _isPresent
&& _isPlaced
&& DoorState == FoupDoorState.Open
&& CassetteState == LoadportCassetteState.Normal
)
return true;
return false;
}
public override bool IsEnableTransferWafer()
{
return IsEnableTransferWafer(out _);
}
public override bool IsEnableTransferWafer(out string reason)
{
reason = "";
if (_isPlaced
&& _isPresent
&& _isMapped
&& IsIdle
&& DoorState==FoupDoorState.Open
&& CassetteState==LoadportCassetteState.Normal
)
return true;
return false;
}
///
///The Indicator is for EAP/Operator
/// LOAD READY: LoadPort Ready to receive FOUP
/// UNLOAD READY: FOUP ready to remove
///
///
public void OnStateUpdated()
{
if (!SC.ContainsItem("Process.OptionLoadportMonitor") || !SC.GetValue("Process.OptionLoadportMonitor"))
return;
if (_isPresent && _isPlaced && this.ClampState == FoupClampState.Open)
{
if (IndicatiorUnload != IndicatorState.ON)
SetIndicator(Indicator.UNLOAD, IndicatorState.ON);
if (IndicatiorLoad != IndicatorState.OFF)
SetIndicator(Indicator.LOAD, IndicatorState.OFF);
return;
}
if (!_isPresent || !_isPlaced)
{
if (IndicatiorUnload != IndicatorState.OFF)
SetIndicator(Indicator.UNLOAD, IndicatorState.OFF);
if (IndicatiorLoad != IndicatorState.ON)
SetIndicator(Indicator.LOAD, IndicatorState.ON);
return;
}
if (IndicatiorUnload != IndicatorState.OFF)
SetIndicator(Indicator.UNLOAD, IndicatorState.OFF);
if (IndicatiorLoad != IndicatorState.OFF)
SetIndicator(Indicator.LOAD, IndicatorState.OFF);
}
public void OnAccessButtonPushed()
{
if (_isPresent && _isPlaced)
{
}
}
public override void Reset()
{
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
FFUIsOK = true;
_commErr = false;
Enable = true;
Error = false;
base.Reset();
}
public override bool Home(out string reason)
{
reason = string.Empty;
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
return execute(new handler(Name), out reason);
}
public override bool ForceHome(out string reason)
{
reason = string.Empty;
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
return execute(new handler(Name), out reason);
}
public override bool FOSBMode(out string reason)
{
reason = string.Empty;
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
return execute(new handler(Name), out reason);
}
public override bool FOUPMode(out string reason)
{
reason = string.Empty;
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
return execute(new handler(Name), out reason);
}
public override bool FOSBDock(out string reason)
{
reason = string.Empty;
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
return execute(new handler(Name), out reason);
}
public override bool FOSBUnDock(out string reason)
{
reason = string.Empty;
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
return execute(new handler(Name), out reason);
}
public override bool FOSBDoorOpen(out string reason)
{
reason = string.Empty;
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
return execute(new handler(Name), out reason);
}
public override bool FOSBDoorClose(out string reason)
{
reason = string.Empty;
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
return execute(new handler(Name), out reason);
}
public override bool FOSBDoorUp(out string reason)
{
reason = string.Empty;
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
return execute(new handler(Name), out reason);
}
public override bool FOSBDoorDown(out string reason)
{
reason = string.Empty;
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
return execute(new handler(Name), out reason);
}
public override bool ClearError(out string reason)
{
reason = string.Empty;
return execute(new handler(Name), out reason);
}
public override bool Stop(out string reason)
{
reason = string.Empty;
lock (_locker)
{
_foregroundHandler = null;
_handlers.Clear();
}
return execute(new handler(Name, MovType.STOP_), out reason);
}
public override bool Load(out string reason) //map and loads
{
return Move(MovType.CLDMP, out reason);
}
public override bool LoadWithoutMap(out string reason)
{
return Move(MovType.CLOAD, out reason);
}
public override bool Unload(out string reason)
{
return Move(MovType.CULOD, out reason);
}
public override bool Clamp(out string reason)
{
return Move(MovType.PODCL, out reason);
}
public override bool Unclamp(out string reason)
{
return Move(MovType.PODOP, out reason);
}
public override bool Dock(out string reason)
{
return Move(MovType.CLDDK, out reason);
}
public override bool Undock(out string reason)
{
return Move(MovType.CULFC, out reason); //????
}
public override bool OpenDoor(out string reason)
{
return Move(MovType.CLMPO, out reason);
}
public override bool OpenDoorNoMap(out string reason)
{
return Move(MovType.CLDOP, out reason);
}
public override bool CloseDoor(out string reason)
{
return Move(MovType.CULDK, out reason);
}
public override bool SetIndicator(Indicator light, IndicatorState op, out string reason)
{
reason = string.Empty;
return execute(new handler(Name, light, op), out reason);
}
public bool SetOnlineMode(out string reason)
{
reason = string.Empty;
return execute(new handler(Name, Mode.ONMGV), out reason);
}
public override bool QueryState(out string reason)
{
reason = string.Empty;
return execute(new handler(Name), out reason);
}
public override bool QueryIndicator(out string reason)
{
reason = string.Empty;
return execute(new handler(Name), out reason);
}
public override bool QueryWaferMap(out string reason)
{
reason = string.Empty;
return execute(new handler(DeviceID), out reason);
}
public override bool QueryFOSBMode(out string reason)
{
reason = string.Empty;
return execute(new handler(DeviceID), out reason);
}
public bool Move(MovType fun, out string reason)
{
reason = string.Empty;
return execute(new handler(Name, fun), out reason);
}
//public bool Query(QueryType type, out string reason)
//{
// reason = string.Empty;
// return execute(new handler(Name), out reason);
//}
public bool SetEvent(EvtType fun, out string reason)
{
reason = string.Empty;
return execute(new handler(Name, fun), out reason);
}
public bool OnEvent(out string reason)
{
reason = string.Empty;
lock (_locker)
{
if (!execute(new handler(Name), out reason))
return false;
//execute(new handler(Name), out reason);
//LoadLight();
//UnloadLight();
return execute(new handler(Name), out reason);
}
}
private bool execute(IHandler handler, out string reason)
{
reason = string.Empty;
lock (_locker)
{
if (_foregroundHandler == null)
{
if (!handler.Execute(ref _port))
{
reason = "Communication failed, please recovery it.";
return false;
}
_foregroundHandler = handler;
}
else
{
//LOG.Info(string.Format("Add command {0}", handler.ToString()));
_handlers.Enqueue(handler);
}
}
return true;
}
private bool execute(out string reason)
{
reason = string.Empty;
lock(_locker)
{
if (_handlers.Count > 0)
{
IHandler handler = _handlers.Dequeue();
if (!handler.Execute(ref _port))
{
reason = " communication failed, please recovery it.";
//LOG.Error(reason);
EV.PostMessage(Name, EventEnum.DefaultWarning, "【Reader】" + reason);
return false;
}
_foregroundHandler = handler;
}
}
return true;
}
private void OnDataChanged(string package)
{
try
{
package = package.ToUpper();
string[] msgs = Regex.Split(package, delimiter);
foreach (string msg in msgs)
{
if (msg.Length > min_len)
{
bool completed = false;
string resp = msg.Substring(3, msg.Length - min_len);
lock (_locker)
{
if (_foregroundHandler != null && _foregroundHandler.OnMessage(ref _port, resp, out completed))
{
string reason = string.Empty;
if (!_foregroundHandler.IsBackground)
{
_foregroundHandler = null;
execute(out reason);
}
else
{
if (completed)
{
_foregroundHandler = null;
QueryState(out reason);
if (_foregroundHandler is handler)
{
QueryIndicator(out reason);
}
}
}
}
else
{
_eventHandler.OnMessage(ref _port, resp, out completed); //process event
}
}
}
}
}
catch (ExcuteFailedException ex)
{
EV.PostWarningLog(Module, $"{Name} action failed, "+ex.Message);
_foregroundHandler = null;
OnError();
}
catch (InvalidPackageException ex)
{
EV.PostWarningLog(Module, $"{Name} received unprocessed message, {ex.Message}" );
OnError();
}
catch (Exception ex)
{
LOG.WriteExeption($" {Name} has exception:" , ex);
}
}
private void OnErrorHandler(ErrorEventArgs args)
{
_commErr = true;
Initalized = false;
EV.PostAlarmLog(Module, $"{Display} Communication error, {args.Reason}");
OnError();
}
public void OnCarrierNotPlaced()
{
_isPlaced = false;
ConfirmRemoveCarrier();
}
public void OnCarrierNotPresent()
{
_isPresent = false;
ConfirmRemoveCarrier();
}
public void OnCarrierPlaced()
{
_isPlaced = true;
ConfirmAddCarrier();
}
public void OnCarrierPresent()
{
_isPresent = true;
ConfirmAddCarrier();
}
public void OnSwitchKey1()
{
}
public void OnSwitchKey2()
{
}
public void SetIndicator(Indicator led, IndicatorState state)
{
SetIndicator(led, state, out string reason);
}
//impment E84 interface
public bool ReadyForLoad()
{
return CassetteState == LoadportCassetteState.Absent;
}
public bool ReadyForUnload()
{
return CassetteState == LoadportCassetteState.Normal;
}
public bool FoupArrirved()
{
return CassetteState == LoadportCassetteState.Normal;
}
public bool FoupRemoved()
{
return CassetteState == LoadportCassetteState.Absent;
}
}
}