using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.Routine;
using Aitex.Core.Utilities;
using Aitex.Sorter.Common;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Schedulers;
using MECF.Framework.RT.ModuleLibrary.LPModules;
using System;
using VirgoRT.Devices.EFEM;
namespace VirgoRT.Modules.LPs
{
///
/// LP entity
///
sealed class LoadPortModule : LoadPortModuleBase
{
public event Action OnEnterError;
private enum STATE
{
Unknown,
Idle, // 1
Init,
Error,
Homing, // 2
Mapping, // 4
Loading,
ReadingCarrierId,
Unloading,
Docking,
Undocking,
Clamping,
Unclamping,
WritingCarrierId,
ReadingTagData,
WritingTagData,
}
public enum MSG
{
Home, // 0
Map, // 1
ActionDone, // 2
Abort, // 5
Online, // 6
Error, // 7
Reset,
ReadCarrierId,
WriteCarrierID,
Load,
Unload,
Dock,
Undock,
Clamp,
Unclamp,
ToInit,
ToIdle,
ReadTagData,
WriteTagData,
}
private readonly Efem _efem;
private Loadport _lpDevice;
public Loadport LPDevice
{
get
{
return _lpDevice;
}
}
public override bool IsReady
{
get { return FsmState == (int)STATE.Idle && CheckAllMessageProcessed(); }
}
public override bool IsError
{
get { return FsmState == (int)STATE.Error; }
}
public override bool IsInit
{
get { return FsmState == (int)STATE.Init; }
}
private LoadPortHomeRoutine _home;
//private LoadPortCloseDoorRoutine _closeDoor;
private LoadPortClampRoutine _clamp;
private LoadPortReadCarrierIdRoutine _readCarrierId;
private LoadPortWriteCarrierIdRoutine _writeCarrierId;
private LoadPortReadTagDataRoutine _readTag;
private LoadPortWriteTagDataRoutine _writeTag;
private LoadPortUnclampRoutine _unclamp;
//private LoadPortUndockRoutine _undock;
private LoadPortLoadRoutine _load;
private LoadPortUnloadRoutine _unload;
private bool _isInit;
public LoadPortModule(ModuleName module, Efem efem) : base(25)
{
Name = module.ToString();
Module = module.ToString();
_efem = efem;
InitFsmMap();
OP.Subscribe($"{Module}.ReadCarrierId", (cmd, args) => { PostMsg(MSG.ReadCarrierId); return true; });
OP.Subscribe($"{Module}.WriteCarrierID", (cmd, args) => { PostMsg(MSG.WriteCarrierID, args[0]); return true; });
OP.Subscribe($"{Module}.ReadTagData", (cmd, args) => { PostMsg(MSG.ReadTagData); return true; });
OP.Subscribe($"{Module}.WriteTagData", (cmd, args) => { PostMsg(MSG.WriteTagData, args[0]); return true; });
OP.Subscribe($"{Module}.Load", (cmd, args) => { PostMsg(MSG.Load); return true; });
OP.Subscribe($"{Module}.Unload", (cmd, args) => { PostMsg(MSG.Unload); return true; });
OP.Subscribe($"{Module}.Clamp", (cmd, args) => { PostMsg(MSG.Clamp); return true; });
OP.Subscribe($"{Module}.Unclamp", (cmd, args) => { PostMsg(MSG.Unclamp); return true; });
OP.Subscribe($"{Module}.Dock", (cmd, args) => { PostMsg(MSG.Dock); return true; });
OP.Subscribe($"{Module}.Undock", (cmd, args) => { PostMsg(MSG.Undock); return true; });
OP.Subscribe($"{Module}.Reset", (cmd, args) => { PostMsg(MSG.Reset); return true; });
OP.Subscribe($"{Module}.Home", (cmd, args) => { PostMsg(MSG.Home); return true; });
OP.Subscribe($"{Module}.Abort", (cmd, args) => { PostMsg(MSG.Abort); return true; });
OP.Subscribe($"{Module}.Online", (cmd, args) => { PostMsg(MSG.Online); return true; });
DATA.Subscribe($"{Module}.Status", () => ((STATE)FsmState).ToString());
DATA.Subscribe($"{Module}.FsmState", () => ((STATE)FsmState).ToString());
DATA.Subscribe($"{Module}.FsmPrevState", () => ((STATE)FsmPreviousState).ToString());
DATA.Subscribe($"{Module}.FsmLastMessage", GetFsmLastMessage);
_lpDevice = efem[module] as Loadport;
InitRoutine();
}
internal bool CheckPlaced(ModuleName module)
{
return _lpDevice.HasCassette;
}
private void InitRoutine()
{
_home = new LoadPortHomeRoutine(this);
//_closeDoor = new LoadPortCloseDoorRoutine(this);
_clamp = new LoadPortClampRoutine(this);
//_dock = new LoadPortDockRoutine(this);
//_map = new LoadPortMapRoutine(this);
//_openDoor = new LoadPortOpenDoorRoutine(this);
_readCarrierId = new LoadPortReadCarrierIdRoutine(this);
_writeCarrierId = new LoadPortWriteCarrierIdRoutine(this);
_readTag = new LoadPortReadTagDataRoutine(this);
_writeTag = new LoadPortWriteTagDataRoutine(this);
_unclamp = new LoadPortUnclampRoutine(this);
//_undock = new LoadPortUndockRoutine(this);
//_MapDT = new LoadPortGetMapInfoRoutine(this);
_load = new LoadPortLoadRoutine(this);
_unload = new LoadPortUnloadRoutine(this);
}
private string GetFsmLastMessage()
{
int msg = FsmLastMessage;
if (msg >= (int)MSG.Home && msg <= (int)MSG.Error)
return ((MSG)msg).ToString();
if (msg == (int)FSM_MSG.TIMER)
return "Timer";
return msg.ToString();
}
private void InitFsmMap()
{
EnableFsm(50, STATE.Idle);
//online
AnyStateTransition(MSG.Online, fnOnline, FSM_STATE.SAME);
//Error
AnyStateTransition(MSG.Error, FsmOnError, STATE.Error);
AnyStateTransition(MSG.Reset, FsmReset, STATE.Idle);
EnterExitTransition(STATE.Error, FsmEnterError, FSM_MSG.NONE, FsmExitError);
//Init
Transition(STATE.Init, MSG.Home, FsmStartHome, STATE.Homing);
Transition(STATE.Error, MSG.Home, FsmStartHome, STATE.Homing);
Transition(STATE.Idle, MSG.Home, FsmStartHome, STATE.Homing);
Transition(STATE.Homing, FSM_MSG.TIMER, FsmMonitorHomeTask, STATE.Idle);
Transition(STATE.Homing, MSG.Error, null, STATE.Init);
Transition(STATE.Homing, MSG.Abort, FsmAbortTask, STATE.Init);
AnyStateTransition(MSG.ToInit, FsmToInit, STATE.Init);
//load
Transition(STATE.Idle, MSG.Load, FsmStartLoad, STATE.Loading);
Transition(STATE.Loading, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
Transition(STATE.Loading, MSG.Abort, FsmAbortTask, STATE.Idle);
//unload
Transition(STATE.Idle, MSG.Unload, FsmStartUnload, STATE.Unloading);
Transition(STATE.Unloading, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
Transition(STATE.Unloading, MSG.Abort, FsmAbortTask, STATE.Idle);
//read carrier id
Transition(STATE.Idle, MSG.ReadCarrierId, FsmStartReadCarrierId, STATE.ReadingCarrierId);
Transition(STATE.ReadingCarrierId, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
Transition(STATE.ReadingCarrierId, MSG.Abort, FsmAbortTask, STATE.Idle);
//clamp
Transition(STATE.Idle, MSG.Clamp, FsmStartClamp, STATE.Clamping);
Transition(STATE.Clamping, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
Transition(STATE.Clamping, MSG.Abort, FsmAbortTask, STATE.Idle);
//unclamp
Transition(STATE.Idle, MSG.Unclamp, FsmStartUnclamp, STATE.Unclamping);
Transition(STATE.Unclamping, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
Transition(STATE.Unclamping, MSG.Abort, FsmAbortTask, STATE.Idle);
//dock
Transition(STATE.Idle, MSG.Dock, FsmStartDock, STATE.Docking);
Transition(STATE.Docking, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
Transition(STATE.Docking, MSG.Abort, FsmAbortTask, STATE.Idle);
//undock
Transition(STATE.Idle, MSG.Undock, FsmStartUndock, STATE.Undocking);
Transition(STATE.Undocking, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
Transition(STATE.Undocking, MSG.Abort, FsmAbortTask, STATE.Idle);
//write carrier id
Transition(STATE.Idle, MSG.WriteCarrierID, FsmStartWriteCarrierId, STATE.WritingCarrierId);
Transition(STATE.WritingCarrierId, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
Transition(STATE.WritingCarrierId, MSG.Abort, FsmAbortTask, STATE.Idle);
//read tag data
Transition(STATE.Idle, MSG.ReadTagData, FsmStartReadTagData, STATE.ReadingTagData);
Transition(STATE.ReadingTagData, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
Transition(STATE.ReadingTagData, MSG.Abort, FsmAbortTask, STATE.Idle);
//write tag data
Transition(STATE.Idle, MSG.WriteTagData, FsmStartWriteTagData, STATE.WritingTagData);
Transition(STATE.WritingTagData, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
Transition(STATE.WritingTagData, MSG.Abort, FsmAbortTask, STATE.Idle);
EnumLoop.ForEach((item) =>
{
MapState((int)item, item.ToString());
});
EnumLoop.ForEach((item) =>
{
MapMessage((int)item, item.ToString());
});
}
private bool FsmAbortTask(object[] param)
{
return true;
}
private bool FsmReset(object[] param)
{
LPDevice.LPReset();
if (!_isInit)
{
PostMsg(MSG.ToInit);
return false;
}
if (_lpDevice.IsError)
{
EV.PostWarningLog(Module, $"{Module} in error, home to recover");
PostMsg(MSG.ToInit);
return false;
}
return true;
}
private bool FsmOnError(object[] param)
{
if (FsmState == (int)STATE.Error)
{
return false;
}
AbortRoutine();
if (FsmState == (int)STATE.Init)
return false;
return true;
}
private bool FsmExitError(object[] param)
{
return true;
}
private bool FsmEnterError(object[] param)
{
if (OnEnterError != null)
OnEnterError(Module);
return true;
}
private bool FsmMonitorTask(object[] param)
{
Result ret = MonitorRoutine();
if (ret == Result.FAIL)
{
PostMsg(MSG.Error);
return false;
}
return ret == Result.DONE;
}
private bool FsmStartHome(object[] param)
{
Result ret = StartRoutine(_home);
if (ret == Result.FAIL || ret == Result.DONE)
return false;
_isInit = false;
return ret == Result.RUN;
}
private bool FsmMonitorHomeTask(object[] param)
{
Result ret = MonitorRoutine();
if (ret == Result.FAIL)
{
PostMsg(MSG.Error);
return false;
}
if (ret == Result.DONE)
{
_isInit = true;
return true;
}
return false;
}
private bool FsmToInit(object[] param)
{
return true;
}
private bool FsmStartUndock(object[] param)
{
QueueRoutine.Clear();
QueueRoutine.Enqueue(_unload);
_clamp.IsUnloadClamp = true;
QueueRoutine.Enqueue(_clamp);
Result ret = StartRoutine();
if (ret == Result.FAIL || ret == Result.DONE)
return false;
return ret == Result.RUN;
}
private bool FsmStartDock(object[] param)
{
//Result ret = StartRoutine(_dock);
//if (ret == Result.FAIL || ret == Result.DONE)
return false;
//return ret == Result.RUN;
}
private bool FsmStartUnclamp(object[] param)
{
Result ret = StartRoutine(_unclamp);
if (ret == Result.FAIL || ret == Result.DONE)
return false;
return ret == Result.RUN;
}
private bool FsmStartClamp(object[] param)
{
_clamp.IsUnloadClamp = false;
Result ret = StartRoutine(_clamp);
if (ret == Result.FAIL || ret == Result.DONE)
return false;
return ret == Result.RUN;
}
private bool FsmStartReadCarrierId(object[] param)
{
Result ret = StartRoutine(_readCarrierId);
if (ret == Result.FAIL || ret == Result.DONE)
return false;
return ret == Result.RUN;
}
private bool FsmStartWriteCarrierId(object[] param)
{
_writeCarrierId.CarrierIdSetPoint = (string) param[0];
Result ret = StartRoutine(_writeCarrierId);
if (ret == Result.FAIL || ret == Result.DONE)
return false;
return ret == Result.RUN;
}
private bool FsmStartReadTagData(object[] param)
{
Result ret = StartRoutine(_readTag);
if (ret == Result.FAIL || ret == Result.DONE)
return false;
return ret == Result.RUN;
}
private bool FsmStartWriteTagData(object[] param)
{
_writeTag.TagDataSetPoint = (string)param[0];
Result ret = StartRoutine(_writeTag);
if (ret == Result.FAIL || ret == Result.DONE)
return false;
return ret == Result.RUN;
}
private bool FsmStartUnload(object[] param)
{
Result ret = StartRoutine(_unload);
if (ret == Result.FAIL || ret == Result.DONE)
return false;
return ret == Result.RUN;
}
private bool FsmStartLoad(object[] param)
{
Result ret = StartRoutine(_load);
if (ret == Result.FAIL || ret == Result.DONE)
return false;
return ret == Result.RUN;
}
private bool fnOnline(object[] param)
{
bool online = (bool)param[0];
_efem.SetOnline(ModuleHelper.Converter(Module), online);
return true;
}
public bool IsPrepareTransferReady(ModuleName module, EnumTransferType type, int slot)
{
if (type == EnumTransferType.Pick)
{
//需要补充:判断LP 放好了,而且已经map过。
return _efem[module].HasCassette && _efem[module].IsMapped && _efem[module].IsThicknessValid;
}
else if (type == EnumTransferType.Place)
{
//需要补充:判断LP 放好了,而且已经map过。
return _efem[module].HasCassette && _efem[module].IsMapped && _efem[module].IsThicknessValid;
}
return false;
}
internal bool CheckReadyRunNewJob(ModuleName module)
{
return _efem[module].HasCassette && _efem[module].IsMapped && _efem[module].IsThicknessValid;
}
internal bool CheckReadyTransfer(ModuleName module)
{
return _efem[module].HasCassette && _efem[module].IsMapped && _efem[module].IsThicknessValid;
}
public override bool Home(out string reason)
{
throw new NotImplementedException();
}
public override void NoteJobStart()
{
throw new NotImplementedException();
}
public override void NoteJobComplete()
{
throw new NotImplementedException();
}
public override bool PrepareTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason)
{
throw new NotImplementedException();
}
public override bool TransferHandoff(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason)
{
throw new NotImplementedException();
}
public override bool PostTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason)
{
throw new NotImplementedException();
}
public override bool CheckReadyForTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType,
out string reason)
{
throw new NotImplementedException();
}
public override void NoteTransferStart(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType)
{
throw new NotImplementedException();
}
public override void NoteTransferStop(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType)
{
throw new NotImplementedException();
}
public override bool CheckReadyForMap(ModuleName robot, Hand blade, out string reason)
{
throw new NotImplementedException();
}
}
}