1482 lines
49 KiB
C#
1482 lines
49 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using Aitex.Core.Common;
|
||
using Aitex.Core.RT.DataCenter;
|
||
using Aitex.Core.RT.Device;
|
||
using Aitex.Core.RT.Event;
|
||
using Aitex.Core.RT.Fsm;
|
||
using Aitex.Core.RT.OperationCenter;
|
||
using Aitex.Core.RT.Routine;
|
||
using Aitex.Core.Util;
|
||
using Aitex.Core.Utilities;
|
||
using MECF.Framework.Common.Equipment;
|
||
using MECF.Framework.Common.Fsm;
|
||
using MECF.Framework.Common.SubstrateTrackings;
|
||
using MECF.Framework.RT.Core.IoProviders;
|
||
using SicRT.Instances;
|
||
using SicRT.Modules;
|
||
using System.Linq;
|
||
using System.Threading.Tasks;
|
||
using Aitex.Core.RT.Device.Unit;
|
||
using Aitex.Core.RT.SCCore;
|
||
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.UPS;
|
||
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps.AE;
|
||
using Aitex.Core.RT.Device.Devices;
|
||
using SicModules.Aligners;
|
||
using SicModules.Buffers;
|
||
using SicModules.Cassettes;
|
||
using SicModules.EFEMs;
|
||
using SicModules.LLs;
|
||
using SicModules.PMs;
|
||
using SicModules.TMs;
|
||
using SicModules.UnLoads;
|
||
using Aitex.Core.RT.DBCore;
|
||
using MECF.Framework.UI.Core.TrayCoating;
|
||
using System.Data;
|
||
using Aitex.Core.RT.Log;
|
||
|
||
namespace SicRT.Equipments.Systems
|
||
{
|
||
public enum RtState
|
||
{
|
||
Init,
|
||
|
||
Initializing,
|
||
Idle,
|
||
|
||
Transfer,
|
||
AutoRunning,
|
||
AutoIdle,
|
||
|
||
Cycle,
|
||
|
||
PlatformCycle,
|
||
|
||
ReturnAllWafer,
|
||
|
||
Error,
|
||
ShutDown = 999
|
||
}
|
||
|
||
public class EquipmentManager : FsmDevice
|
||
{
|
||
public enum MSG
|
||
{
|
||
HOME,
|
||
RESET,
|
||
ABORT,
|
||
ERROR,
|
||
|
||
MoveWafer,
|
||
ReturnAllWafer,
|
||
PlatformCycle,
|
||
|
||
HomeUnit,
|
||
|
||
PauseAuto,
|
||
ResumeAuto,
|
||
|
||
Stop,
|
||
StopPlatformCycle,
|
||
|
||
StartCycle,
|
||
|
||
SetAutoMode,
|
||
SetManualMode,
|
||
|
||
CreateJob,
|
||
PauseJob,
|
||
ResumeJob,
|
||
StartJob,
|
||
StopJob,
|
||
AbortJob,
|
||
|
||
JobDone,
|
||
|
||
FAJobCommand,
|
||
|
||
SetOnline,
|
||
SetOffline,
|
||
|
||
ModuleError,
|
||
ShutDown = 999,
|
||
}
|
||
|
||
public Dictionary<ModuleName, ModuleFsmDevice> Modules { get; set; }
|
||
|
||
public bool IsAutoMode
|
||
{
|
||
get
|
||
{
|
||
return FsmState == (int)RtState.AutoRunning;
|
||
}
|
||
}
|
||
|
||
public bool IsInit
|
||
{
|
||
get { return FsmState == (int)RtState.Init; }
|
||
}
|
||
|
||
public bool IsOnline
|
||
{
|
||
get;
|
||
set;
|
||
}
|
||
|
||
public bool IsIdle
|
||
{
|
||
get { return FsmState == (int)RtState.Idle; }
|
||
}
|
||
public bool IsAlarm
|
||
{
|
||
get { return FsmState == (int)RtState.Error; }
|
||
}
|
||
|
||
public bool IsRunning
|
||
{
|
||
get
|
||
{
|
||
return FsmState == (int)RtState.Initializing
|
||
|| FsmState == (int)RtState.Transfer
|
||
|| FsmState == (int)RtState.Cycle
|
||
|| FsmState == (int)RtState.AutoRunning;
|
||
}
|
||
}
|
||
|
||
private ManualTransfer _manualTransfer;
|
||
private AutoTransfer _auto = null;
|
||
private HomeAll _homeAll;
|
||
|
||
private ReturnAllWafer _returnAll;
|
||
private List<string> _modules = new List<string>();
|
||
//readonly IEnumerable<PropertyInfo> IEntityModules;
|
||
|
||
private ITAUPS _upsPM1A = null;
|
||
private ITAUPS _upsPM1B = null;
|
||
|
||
private ITAUPS _upsPM2A = null;
|
||
private ITAUPS _upsPM2B = null;
|
||
|
||
private IoUPS _pm1UPS = null;
|
||
private IoUPS _pm2UPS = null;
|
||
//AETEmp
|
||
private AETemp _aeTemp = null;
|
||
private SicAETemp _pmAETemp1 = null;
|
||
private SicAETemp _pmAETemp2 = null;
|
||
//
|
||
private IoInterLock _pm1InterLock = null;
|
||
private IoInterLock _pm2InterLock = null;
|
||
|
||
private SicModules.Devices.IoInterLock _tmInterLock = null;
|
||
private IoSlitValve _pm1SlitValve = null;
|
||
private IoSlitValve _pm2SlitValve = null;
|
||
private PeriodicJob _thread;
|
||
|
||
private IoTC _tc = null;
|
||
|
||
private List<IoPTOffsetAndK> ioPTOffsetAndKs = new List<IoPTOffsetAndK>();
|
||
public EquipmentManager()
|
||
{
|
||
Module = "System";
|
||
Name = "System";
|
||
|
||
Modules = new Dictionary<ModuleName, ModuleFsmDevice>();
|
||
}
|
||
|
||
public override bool Initialize()
|
||
{
|
||
InitModules();
|
||
|
||
EnumLoop<RtState>.ForEach((item) =>
|
||
{
|
||
MapState((int)item, item.ToString());
|
||
});
|
||
|
||
EnumLoop<MSG>.ForEach((item) =>
|
||
{
|
||
MapMessage((int)item, item.ToString());
|
||
});
|
||
EnableFsm(100, RtState.Init);
|
||
|
||
BuildTransitionTable();
|
||
|
||
SubscribeDataVariable();
|
||
|
||
SubscribeOperation();
|
||
|
||
//InitSetPSUY();
|
||
InitPTOffsetAndK();
|
||
|
||
Singleton<EventManager>.Instance.OnAlarmEvent += Instance_OnAlarmEvent;
|
||
|
||
_manualTransfer = new ManualTransfer();
|
||
_homeAll = new HomeAll();
|
||
_auto = new AutoTransfer();
|
||
_returnAll = new ReturnAllWafer();
|
||
|
||
SC.RegisterValueChangedCallback("TM.ProcessPressure", SetTansferPressure);
|
||
|
||
return true;
|
||
}
|
||
|
||
private void SetTansferPressure(object value)
|
||
{
|
||
try
|
||
{
|
||
double.TryParse(value.ToString(), out double dbValue);
|
||
|
||
double offset = SC.GetValue<double>("TM.VacuumPressureBaseOffset");
|
||
|
||
double basePressure = offset + dbValue;
|
||
|
||
SC.SetItemValue("TM.PressureBalance.BalancePressure", dbValue);
|
||
|
||
SC.SetItemValue("TM.VacuumPressureBase", basePressure);
|
||
|
||
SC.SetItemValue("TM.Purge.VentBasePressure", dbValue);
|
||
|
||
SC.SetItemValue("PM.VacuumPressureBase", basePressure);
|
||
|
||
SC.SetItemValue("PM.PM1.ProcessIdle.FinalPressure", value);
|
||
|
||
SC.SetItemValue("PM.PM1.PreProcess.ChamberPressure", value);
|
||
|
||
SC.SetItemValue("PM.PM2.ProcessIdle.FinalPressure", value);
|
||
|
||
SC.SetItemValue("PM.PM2.PreProcess.ChamberPressure", value);
|
||
|
||
SC.SetItemValue("LoadLock.VacuumPressureBase", basePressure);
|
||
|
||
SC.SetItemValue("LoadLock.Purge.VentBasePressure", value);
|
||
|
||
SC.SetItemValue("UnLoad.VacuumPressureBase", basePressure);
|
||
|
||
SC.SetItemValue("UnLoad.Purge.VentBasePressure", value);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
EV.PostWarningLog("System", ex.Message);
|
||
}
|
||
}
|
||
|
||
private void InitModules()
|
||
{
|
||
var tm = new TMModule(ModuleName.TM);
|
||
Modules[ModuleName.TM] = tm;
|
||
tm.OnEnterError += OnModuleError;
|
||
|
||
var ll = new LoadLockModule(ModuleName.LoadLock);
|
||
Modules[ModuleName.LoadLock] = ll;
|
||
ll.OnEnterError += OnModuleError;
|
||
|
||
var unlaod = new UnLoadModule(ModuleName.UnLoad);
|
||
Modules[ModuleName.UnLoad] = unlaod;
|
||
unlaod.OnEnterError += OnModuleError;
|
||
|
||
var buffer = new BufferModule(ModuleName.Buffer);
|
||
Modules[ModuleName.Buffer] = buffer;
|
||
buffer.OnEnterError += OnModuleError;
|
||
|
||
var pm1 = new PMModule(ModuleName.PM1);
|
||
Modules[ModuleName.PM1] = pm1;
|
||
pm1.OnEnterError += OnModuleError;
|
||
|
||
var pm2 = new PMModule(ModuleName.PM2);
|
||
Modules[ModuleName.PM2] = pm2;
|
||
pm2.OnEnterError += OnModuleError;
|
||
|
||
//}
|
||
|
||
var aligner = new AlignerModule(ModuleName.Aligner);
|
||
Modules[ModuleName.Aligner] = aligner;
|
||
aligner.OnEnterError += OnModuleError;
|
||
|
||
var waferRobot = new WaferRobotModule(ModuleName.WaferRobot);
|
||
Modules[ModuleName.WaferRobot] = waferRobot;
|
||
waferRobot.OnEnterError += OnModuleError;
|
||
|
||
var trayRobot = new TrayRobotModule(ModuleName.TrayRobot);
|
||
Modules[ModuleName.TrayRobot] = trayRobot;
|
||
trayRobot.OnEnterError += OnModuleError;
|
||
|
||
var efem = new EFEMModule(ModuleName.EFEM);
|
||
Modules[ModuleName.EFEM] = efem;
|
||
efem.OnEnterError += OnModuleError;
|
||
|
||
var cassAL = new CassetteModule(ModuleName.CassAL, 25);
|
||
Modules[ModuleName.CassAL] = cassAL;
|
||
cassAL.OnEnterError += OnModuleError;
|
||
|
||
var cassAR = new CassetteModule(ModuleName.CassAR, 25);
|
||
Modules[ModuleName.CassAR] = cassAR;
|
||
cassAR.OnEnterError += OnModuleError;
|
||
|
||
var cassBL = new CassetteModule(ModuleName.CassBL, 8);
|
||
Modules[ModuleName.CassBL] = cassBL;
|
||
cassBL.OnEnterError += OnModuleError;
|
||
|
||
_modules = new List<string>() { "System" };
|
||
foreach (var modulesKey in Modules.Keys)
|
||
{
|
||
_modules.Add(modulesKey.ToString());
|
||
}
|
||
|
||
foreach (var modulesValue in Modules.Values)
|
||
{
|
||
modulesValue.Initialize();
|
||
}
|
||
|
||
_pm1SlitValve = DEVICE.GetDevice<IoSlitValve>("TM.PM1Door");
|
||
_pm2SlitValve = DEVICE.GetDevice<IoSlitValve>("TM.PM2Door");
|
||
_pm1InterLock = DEVICE.GetDevice<IoInterLock>("PM1.PMInterLock");
|
||
_pm2InterLock = DEVICE.GetDevice<IoInterLock>("PM2.PMInterLock");
|
||
|
||
_tmInterLock = DEVICE.GetDevice<SicModules.Devices.IoInterLock>("TM.IoInterLock");
|
||
|
||
_upsPM1A = DEVICE.GetDevice<ITAUPS>("PM1.ITAUPSA");
|
||
_upsPM1B = DEVICE.GetDevice<ITAUPS>("PM1.ITAUPSB");
|
||
_pm1UPS = DEVICE.GetDevice<IoUPS>("PM1.UPS");
|
||
|
||
_upsPM2A = DEVICE.GetDevice<ITAUPS>("PM2.ITAUPSA");
|
||
_upsPM2B = DEVICE.GetDevice<ITAUPS>("PM2.ITAUPSB");
|
||
_pm2UPS = DEVICE.GetDevice<IoUPS>("PM2.UPS");
|
||
|
||
//AETemp
|
||
_aeTemp = DEVICE.GetDevice<AETemp>("PM.AETemp");
|
||
_pmAETemp1 = DEVICE.GetDevice<SicAETemp>("PM1.PMAETemp");
|
||
_pmAETemp2 = DEVICE.GetDevice<SicAETemp>("PM2.PMAETemp");
|
||
|
||
_tc = DEVICE.GetDevice<IoTC>("PM1.TC1");
|
||
|
||
IniioPTOffsetAndKs();
|
||
//
|
||
_thread = new PeriodicJob(200, OnTimer, "PmSlitDoor", false, true);
|
||
Task.Delay(15000).ContinueWith((a) => _thread.Start());
|
||
|
||
//IEntityModules = this.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)
|
||
// .Where(t => t.PropertyType.GetInterfaces().Contains(typeof(IEntity)) && t.PropertyType.GetInterfaces().Contains(typeof(IModuleEntity)));
|
||
}
|
||
private void IniioPTOffsetAndKs()
|
||
{
|
||
if (SC.GetValue<bool>($"System.SetUp.IsPM1Installed"))
|
||
{
|
||
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>("PM1.PT1OffsetAndK"));
|
||
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>("PM1.PT2OffsetAndK"));
|
||
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>("PM1.PT3OffsetAndK"));
|
||
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>("PM1.PT4OffsetAndK"));
|
||
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>("PM1.PT9OffsetAndK"));
|
||
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>("PM1.PT10OffsetAndK"));
|
||
for (int i = 1; i < 15; i++)
|
||
{
|
||
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>($"PM1.U{i}_Water"));
|
||
}
|
||
}
|
||
|
||
if (SC.GetValue<bool>($"System.SetUp.IsPM2Installed"))
|
||
{
|
||
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>("PM2.PT1OffsetAndK"));
|
||
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>("PM2.PT2OffsetAndK"));
|
||
for (int i = 1; i < 15; i++)
|
||
{
|
||
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>($"PM2.U{i}_Water"));
|
||
}
|
||
}
|
||
}
|
||
private void BuildTransitionTable()
|
||
{
|
||
//ShutDown
|
||
Transition(RtState.Init, MSG.ShutDown, FsmStartShutDown, RtState.ShutDown);
|
||
Transition(RtState.Idle, MSG.ShutDown, FsmStartShutDown, RtState.ShutDown);
|
||
Transition(RtState.AutoIdle, MSG.ShutDown, FsmStartShutDown, RtState.ShutDown);
|
||
EnterExitTransition<RtState, FSM_MSG>(RtState.ShutDown, FsmShutDown, null, null);
|
||
|
||
//Init sequence
|
||
Transition(RtState.Init, MSG.HOME, FsmStartHome, RtState.Initializing);
|
||
Transition(RtState.Idle, MSG.HOME, FsmStartHome, RtState.Initializing);
|
||
Transition(RtState.Error, MSG.HOME, FsmStartHome, RtState.Initializing);
|
||
|
||
// EnterExitTransition<RtState, FSM_MSG>(RtState.Initializing, fStartInit, FSM_MSG.NONE, null);
|
||
|
||
Transition(RtState.Initializing, FSM_MSG.TIMER, FsmMonitorHome, RtState.Idle);
|
||
Transition(RtState.Initializing, MSG.ERROR, fError, RtState.Error);
|
||
Transition(RtState.Initializing, MSG.ABORT, FsmAbort, RtState.Init);
|
||
|
||
//Online
|
||
Transition(RtState.Idle, MSG.SetOnline, FsmStartSetOnline, RtState.Idle);
|
||
Transition(RtState.Idle, MSG.SetOffline, FsmStartSetOffline, RtState.Idle);
|
||
|
||
//Reset
|
||
AnyStateTransition(MSG.RESET, fStartReset, RtState.Idle);
|
||
|
||
AnyStateTransition(MSG.ERROR, fError, RtState.Error);
|
||
AnyStateTransition((int)FSM_MSG.ALARM, fError, (int)RtState.Error);
|
||
|
||
//Auto/manual sequence
|
||
Transition(RtState.Idle, MSG.SetAutoMode, fStartAutoTransfer, RtState.AutoIdle);
|
||
|
||
Transition(RtState.AutoRunning, FSM_MSG.TIMER, fAutoTransfer, RtState.AutoRunning);
|
||
|
||
Transition(RtState.AutoRunning, MSG.ABORT, fAbortAutoTransfer, RtState.AutoIdle);
|
||
Transition(RtState.AutoRunning, MSG.JobDone, null, RtState.AutoIdle);
|
||
|
||
Transition(RtState.AutoRunning, MSG.FAJobCommand, FsmFAJobCommand, RtState.AutoRunning);
|
||
Transition(RtState.AutoRunning, MSG.CreateJob, FsmCreateJob, RtState.AutoRunning);
|
||
Transition(RtState.AutoRunning, MSG.StartJob, FsmStartJob, RtState.AutoRunning);
|
||
Transition(RtState.AutoRunning, MSG.PauseJob, FsmPauseJob, RtState.AutoRunning);
|
||
Transition(RtState.AutoRunning, MSG.ResumeJob, FsmResumeJob, RtState.AutoRunning);
|
||
Transition(RtState.AutoRunning, MSG.StopJob, FsmStopJob, RtState.AutoRunning);
|
||
Transition(RtState.AutoRunning, MSG.AbortJob, FsmAbortJob, RtState.AutoRunning);
|
||
|
||
Transition(RtState.AutoIdle, FSM_MSG.TIMER, FsmMonitorAutoIdle, RtState.AutoIdle);
|
||
Transition(RtState.AutoIdle, MSG.SetManualMode, FsmStartSetManualMode, RtState.Idle);
|
||
Transition(RtState.AutoIdle, MSG.FAJobCommand, FsmFAJobCommand, RtState.AutoIdle);
|
||
Transition(RtState.AutoIdle, MSG.CreateJob, FsmCreateJob, RtState.AutoIdle);
|
||
Transition(RtState.AutoIdle, MSG.StartJob, FsmStartJob, RtState.AutoRunning);
|
||
Transition(RtState.AutoIdle, MSG.ABORT, FsmAbort, RtState.AutoIdle);
|
||
Transition(RtState.AutoIdle, MSG.AbortJob, FsmAbortJob, RtState.AutoIdle);
|
||
|
||
EnterExitTransition<RtState, FSM_MSG>(RtState.AutoRunning, null, FSM_MSG.NONE, fExitAutoTransfer);
|
||
|
||
//return all wafer
|
||
Transition(RtState.Idle, MSG.ReturnAllWafer, FsmStartReturnAllWafer, RtState.ReturnAllWafer);
|
||
Transition(RtState.ReturnAllWafer, FSM_MSG.TIMER, FsmMonitorReturnAllWafer, RtState.Idle);
|
||
Transition(RtState.ReturnAllWafer, MSG.ABORT, FsmAbortReturnAllWafer, RtState.Idle);
|
||
|
||
|
||
//Transfer sequence
|
||
Transition(RtState.Idle, MSG.MoveWafer, fStartTransfer, RtState.Transfer);
|
||
Transition(RtState.Transfer, FSM_MSG.TIMER, fTransfer, RtState.Idle);
|
||
|
||
EnterExitTransition<RtState, FSM_MSG>(RtState.Transfer, null, FSM_MSG.NONE, fExitTransfer);
|
||
|
||
Transition(RtState.Transfer, MSG.ABORT, FsmAbort, RtState.Idle);
|
||
}
|
||
|
||
void SubscribeDataVariable()
|
||
{
|
||
DATA.Subscribe("Rt.Status", () => StringFsmStatus);
|
||
DATA.Subscribe("System.IsOnline", () => IsOnline);
|
||
DATA.Subscribe("System.IsIdle", () => IsIdle || IsInit);
|
||
DATA.Subscribe("System.IsAlarm", () => IsAlarm);
|
||
DATA.Subscribe("System.IsBusy", () => IsRunning);
|
||
DATA.Subscribe("System.IsAutoRunning", () => IsRunning);
|
||
DATA.Subscribe("System.Modules", () => _modules);
|
||
DATA.Subscribe("System.LiveAlarmEvent", () => EV.GetAlarmEvent());
|
||
DATA.Subscribe("System.IsEngMode", () => _isEngMode);
|
||
}
|
||
|
||
void SubscribeOperation()
|
||
{
|
||
OP.Subscribe("CreateWafer", InvokeCreateWafer);
|
||
|
||
OP.Subscribe("DeleteWafer", InvokeDeleteWafer);
|
||
|
||
OP.Subscribe("ReturnWafer", InvokeReturnWafer);
|
||
|
||
OP.Subscribe("DeleteTray", InvokeDeleteTray);
|
||
|
||
OP.Subscribe("AlterWaferInfo", InvokeAlterWaferInfo);
|
||
|
||
|
||
OP.Subscribe("System.ReturnAllWafer", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.ReturnAllWafer);
|
||
});
|
||
|
||
OP.Subscribe("System.MoveWafer", (string cmd, object[] args) =>
|
||
{
|
||
if (!Enum.TryParse((string)args[0], out ModuleName source))
|
||
{
|
||
EV.PostWarningLog(Name, $"Parameter source {(string)args[0]} not valid");
|
||
return false;
|
||
}
|
||
|
||
if (!Enum.TryParse((string)args[2], out ModuleName destination))
|
||
{
|
||
EV.PostWarningLog(Name, $"Parameter destination {(string)args[1]} not valid");
|
||
return false;
|
||
}
|
||
if (args.Length > 9 )
|
||
{
|
||
if ((bool)args[9])
|
||
{
|
||
WaferManager.Instance.WaferMoved(source, (int)args[1], destination, (int)args[3]);
|
||
return true;
|
||
}
|
||
if ((bool)args[10])
|
||
{
|
||
WaferManager.Instance.TrayMoved(source, (int)args[1], destination, (int)args[3]);
|
||
return true;
|
||
}
|
||
|
||
}
|
||
if (args.Length >= 8)
|
||
{
|
||
return CheckToPostMessage((int)MSG.MoveWafer, source, (int)args[1], destination, (int)args[3],
|
||
(bool)args[4], (int)args[5], (bool)args[6], (int)args[7]);
|
||
}
|
||
if (args.Length == 5)
|
||
{
|
||
return CheckToPostMessage((int)MSG.MoveWafer, source, (int)args[1], destination, (int)args[3], (bool)args[4]);
|
||
}
|
||
|
||
return CheckToPostMessage((int)MSG.MoveWafer, source, (int)args[1], destination, (int)args[3]);
|
||
});
|
||
|
||
OP.Subscribe("System.HomeAll", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.HOME);
|
||
});
|
||
OP.Subscribe("System.Abort", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.ABORT);
|
||
});
|
||
|
||
OP.Subscribe("System.Reset", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.RESET);
|
||
});
|
||
|
||
OP.Subscribe("System.SetAutoMode", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.SetAutoMode);
|
||
});
|
||
OP.Subscribe("System.SetManualMode", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.SetManualMode);
|
||
});
|
||
|
||
OP.Subscribe("System.CreateJob", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.CreateJob, args[0]);
|
||
});
|
||
|
||
OP.Subscribe("System.StartJob", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.StartJob, args[0]);
|
||
});
|
||
|
||
OP.Subscribe("System.PauseJob", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.PauseJob, args[0]);
|
||
});
|
||
|
||
OP.Subscribe("System.ResumeJob", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.ResumeJob, args[0]);
|
||
});
|
||
|
||
OP.Subscribe("System.StopJob", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.StopJob, args[0]);
|
||
});
|
||
|
||
OP.Subscribe("System.AbortJob", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.AbortJob, args[0]);
|
||
});
|
||
|
||
OP.Subscribe("System.SetOnline", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.SetOnline);
|
||
});
|
||
|
||
OP.Subscribe("System.SetOffline", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.SetOffline);
|
||
});
|
||
OP.Subscribe("System.ShutDown", (string cmd, object[] args) =>
|
||
{
|
||
return CheckToPostMessage((int)MSG.ShutDown, null);
|
||
});
|
||
//OP.Subscribe("System.StartAutoRun", (string cmd, object[] args) =>
|
||
//{
|
||
// return CheckToPostMessage((int)MSG.StartJob, args[0]);
|
||
//});
|
||
|
||
#region Recipe Editor Lock Password Management
|
||
|
||
const string SC_PATH_REQ_RESET_PASS = "System.Recipe.ResetEditorPassword";
|
||
const string SC_PATH_PASSWORD = "System.Recipe.EditorPassword";
|
||
|
||
OP.Subscribe("System.SetNewRecipeEditorPassword", (string cmd, object[] args) =>
|
||
{
|
||
if (args.Length == 2 && args[0] is string oldPass
|
||
&& args[1] is string newPass)
|
||
{
|
||
var oldPassInSc = SC.GetStringValue(SC_PATH_PASSWORD);
|
||
if (oldPass != oldPassInSc)
|
||
{
|
||
EV.PostWarningLog(Module, "Incorrect old password");
|
||
return false;
|
||
}
|
||
|
||
SC.SetItemValue(SC_PATH_REQ_RESET_PASS, false);
|
||
SC.SetItemValue(SC_PATH_PASSWORD, newPass);
|
||
EV.PostInfoLog(Module, "Recipe Editor Password has been changed");
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
EV.PostWarningLog(Module, "Incorrect args of setting new Recipe Editor password");
|
||
return false;
|
||
}
|
||
});
|
||
|
||
// 程序启动时禁用复位密码选项,写在这里方便移植
|
||
SC.SetItemValue(SC_PATH_REQ_RESET_PASS, false);
|
||
|
||
#endregion
|
||
|
||
}
|
||
|
||
void InitSetPSUY()
|
||
{
|
||
Task.Delay(2000).ContinueWith(x=> _tc.SetPCPSUY());
|
||
}
|
||
void InitPTOffsetAndK()
|
||
{
|
||
Task.Delay(6000).ContinueWith(x => SetPTOffsetAndK());
|
||
}
|
||
|
||
void SetPTOffsetAndK()
|
||
{
|
||
foreach (IoPTOffsetAndK item in ioPTOffsetAndKs)
|
||
{
|
||
if (item.Name.Contains("PT"))
|
||
{
|
||
item.SetPTOffset();
|
||
item.SetPTK();
|
||
}
|
||
else
|
||
item.SetTempOffset();
|
||
}
|
||
}
|
||
|
||
private void Instance_OnAlarmEvent(EventItem obj)
|
||
{
|
||
FSM_MSG msg = FSM_MSG.NONE;
|
||
if (obj.Level == EventLevel.Warning)
|
||
msg = FSM_MSG.WARNING;
|
||
else if (obj.Level == EventLevel.Alarm)
|
||
{
|
||
msg = FSM_MSG.ALARM;
|
||
|
||
if(obj.Source == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (Modules.ContainsKey(ModuleHelper.Converter(obj.Source)))
|
||
{
|
||
Modules[ModuleHelper.Converter(obj.Source)]?.PostMsg(msg, obj.Id, obj.Description);
|
||
}
|
||
}
|
||
}
|
||
|
||
#region Init
|
||
private bool FsmStartHome(object[] objs)
|
||
{
|
||
return _homeAll.Start() == Result.RUN;
|
||
}
|
||
|
||
private bool FsmMonitorHome(object[] objs)
|
||
{
|
||
Result ret = _homeAll.Monitor();
|
||
if (ret == Result.DONE)
|
||
{
|
||
_homeAll.Clear();
|
||
return true;
|
||
}
|
||
if (ret == Result.FAIL)
|
||
{
|
||
_homeAll.Clear();
|
||
PostMsg(MSG.ERROR);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
private bool fError(object[] objs)
|
||
{
|
||
IsOnline = false;
|
||
|
||
if (FsmState == (int)RtState.Transfer)
|
||
{
|
||
_manualTransfer.Clear();
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
#region AutoTransfer
|
||
|
||
private bool FsmMonitorAutoIdle(object[] param)
|
||
{
|
||
//fMonitorFAJob(param);
|
||
|
||
Result ret = _auto.Monitor();
|
||
|
||
//if (!_auto.CheckAllJobDone())
|
||
//{
|
||
// return false;
|
||
//}
|
||
|
||
return ret == Result.DONE;
|
||
}
|
||
|
||
private bool FsmStartSetManualMode(object[] objs)
|
||
{
|
||
if (_auto.HasJobRunning)
|
||
{
|
||
EV.PostWarningLog("System", "Can not change to manual mode, abort running job first");
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
private bool fStartAutoTransfer(object[] objs)
|
||
{
|
||
|
||
Result ret = _auto.Start(objs);
|
||
|
||
return ret == Result.RUN;
|
||
}
|
||
|
||
private bool fAutoTransfer(object[] objs)
|
||
{
|
||
Result ret = _auto.Monitor();
|
||
|
||
if (_auto.CheckAllJobDone())
|
||
{
|
||
if (!CheckToPostMessage((int)MSG.JobDone))
|
||
return false;
|
||
}
|
||
|
||
return ret == Result.DONE;
|
||
}
|
||
|
||
private bool fExitAutoTransfer(object[] objs)
|
||
{
|
||
_auto.Clear();
|
||
return true;
|
||
}
|
||
|
||
private bool fAbortAutoTransfer(object[] objs)
|
||
{
|
||
if (FsmState == (int)RtState.Transfer)
|
||
{
|
||
_manualTransfer.Clear();
|
||
}
|
||
|
||
if (FsmState == (int)RtState.AutoRunning)
|
||
{
|
||
_auto.Clear();
|
||
}
|
||
foreach (var modulesValue in Modules.Values)
|
||
{
|
||
if (!modulesValue.Module.Contains("PM"))
|
||
{
|
||
modulesValue.PostMsg(MSG.ABORT);
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region cycle
|
||
|
||
private bool FsmAbortCycle(object[] param)
|
||
{
|
||
return true;
|
||
}
|
||
|
||
private bool FsmMonitorCycle(object[] param)
|
||
{
|
||
return _auto.Monitor() == Result.DONE;
|
||
}
|
||
|
||
private bool FsmStartCycle(object[] param)
|
||
{
|
||
return _auto.Start() == Result.RUN;
|
||
}
|
||
#endregion
|
||
|
||
#region return all wafer
|
||
|
||
private bool FsmAbortReturnAllWafer(object[] param)
|
||
{
|
||
//_returnAll.Clear();
|
||
return true;
|
||
}
|
||
|
||
private bool FsmMonitorReturnAllWafer(object[] param)
|
||
{
|
||
return _returnAll.Monitor() == Result.DONE;
|
||
}
|
||
|
||
private bool FsmStartReturnAllWafer(object[] param)
|
||
{
|
||
return _returnAll.Start() == Result.RUN;
|
||
}
|
||
#endregion
|
||
|
||
#region Transfer
|
||
private bool fStartTransfer(object[] objs)
|
||
{
|
||
Result ret = _manualTransfer.Start(objs);
|
||
if (ret == Result.FAIL || ret == Result.DONE)
|
||
return false;
|
||
return ret == Result.RUN;
|
||
}
|
||
|
||
|
||
private bool fTransfer(object[] objs)
|
||
{
|
||
Result ret = _manualTransfer.Monitor(objs);
|
||
if (ret == Result.FAIL)
|
||
{
|
||
PostMsg(MSG.ERROR);
|
||
return false;
|
||
}
|
||
return ret == Result.DONE;
|
||
}
|
||
|
||
private bool fExitTransfer(object[] objs)
|
||
{
|
||
_manualTransfer.Clear();
|
||
|
||
return true;
|
||
}
|
||
|
||
private bool fAbortTransfer(object[] objs)
|
||
{
|
||
return true;
|
||
}
|
||
#endregion
|
||
|
||
#region reset
|
||
|
||
private bool fStartReset(object[] objs)
|
||
{
|
||
EV.ClearAlarmEvent();
|
||
|
||
if (FsmState == (int)RtState.AutoRunning)
|
||
{
|
||
_auto.ResetTask();
|
||
}
|
||
|
||
Singleton<DeviceEntity>.Instance.PostMsg(DeviceEntity.MSG.RESET);
|
||
|
||
foreach (var modulesValue in Modules.Values)
|
||
{
|
||
modulesValue.PostMsg(MSG.RESET);
|
||
}
|
||
|
||
|
||
IoProviderManager.Instance.Reset();
|
||
|
||
if (FsmState == (int)RtState.Error)
|
||
return true;
|
||
|
||
|
||
return false;
|
||
}
|
||
|
||
#endregion
|
||
|
||
private bool FsmFAJobCommand(object[] param)
|
||
{
|
||
switch ((string)param[0])
|
||
{
|
||
case "CreateProcessJob":
|
||
//_auto.CreateProcessJob((string)param[1], (string)param[2], (List<int>)param[3], (bool)param[4]);
|
||
break;
|
||
case "CreateControlJob":
|
||
//_auto.CreateControlJob((string)param[1], (string)param[2], (List<string>)param[3], (bool)param[4]);
|
||
CheckToPostMessage((int)MSG.StartJob, (string)param[1]);
|
||
break;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
private bool FsmCreateJob(object[] param)
|
||
{
|
||
_auto.CreateJob((Dictionary<string, object>)param[0]);
|
||
|
||
return true;
|
||
}
|
||
|
||
private bool FsmAbortJob(object[] param)
|
||
{
|
||
_auto.AbortJob((string)param[0]);
|
||
return true;
|
||
}
|
||
|
||
private bool FsmStopJob(object[] param)
|
||
{
|
||
_auto.StopJob((string)param[0]);
|
||
return true;
|
||
}
|
||
|
||
private bool FsmResumeJob(object[] param)
|
||
{
|
||
_auto.ResumeJob((string)param[0]);
|
||
return true;
|
||
}
|
||
|
||
private bool FsmPauseJob(object[] param)
|
||
{
|
||
_auto.PauseJob((string)param[0]);
|
||
return true;
|
||
}
|
||
|
||
private bool FsmStartJob(object[] param)
|
||
{
|
||
_auto.StartJob((string)param[0]);
|
||
return true;
|
||
}
|
||
|
||
private bool FsmAbort(object[] param)
|
||
{
|
||
if (FsmState == (int)RtState.Transfer)
|
||
{
|
||
_manualTransfer.Clear();
|
||
}
|
||
|
||
if (FsmState == (int)RtState.AutoRunning)
|
||
{
|
||
_auto.Clear();
|
||
}
|
||
|
||
foreach (var modulesValue in Modules.Values)
|
||
{
|
||
if (!modulesValue.Module.Contains("PM"))
|
||
{
|
||
modulesValue.PostMsg(MSG.ABORT);
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
private bool FsmStartSetOffline(object[] param)
|
||
{
|
||
IsOnline = false;
|
||
|
||
var tm = Modules[ModuleName.TM] as TMModule;
|
||
tm.InvokeOffline();
|
||
|
||
var ll = Modules[ModuleName.LoadLock] as LoadLockModule;
|
||
ll.InvokeOffline();
|
||
|
||
var buffer = Modules[ModuleName.Buffer] as BufferModule;
|
||
buffer.InvokeOffline();
|
||
|
||
var unLoad = Modules[ModuleName.UnLoad] as UnLoadModule;
|
||
unLoad.InvokeOffline();
|
||
|
||
var efem = Modules[ModuleName.EFEM] as EFEMModule;
|
||
efem.InvokeOffline();
|
||
|
||
var aligner = Modules[ModuleName.Aligner] as AlignerModule;
|
||
aligner.InvokeOffline();
|
||
|
||
var pm1 = Modules[ModuleName.PM1] as PMModule;
|
||
pm1.InvokeOffline();
|
||
|
||
var pm2 = Modules[ModuleName.PM2] as PMModule;
|
||
pm2.InvokeOffline();
|
||
|
||
var cassAL = Modules[ModuleName.CassAL] as CassetteModule;
|
||
cassAL.InvokeOffline();
|
||
|
||
var cassAR = Modules[ModuleName.CassAR] as CassetteModule;
|
||
cassAR.InvokeOffline();
|
||
|
||
var cassBL = Modules[ModuleName.CassBL] as CassetteModule;
|
||
cassBL.InvokeOffline();
|
||
|
||
var waferRobot = Modules[ModuleName.WaferRobot] as WaferRobotModule;
|
||
waferRobot.InvokeOffline();
|
||
|
||
var trayRobot = Modules[ModuleName.TrayRobot] as TrayRobotModule;
|
||
trayRobot.InvokeOffline();
|
||
|
||
return true;
|
||
}
|
||
|
||
private bool FsmStartSetOnline(object[] param)
|
||
{
|
||
IsOnline = true;
|
||
|
||
var tm = Modules[ModuleName.TM] as TMModule;
|
||
tm.InvokeOnline();
|
||
|
||
var ll = Modules[ModuleName.LoadLock] as LoadLockModule;
|
||
ll.InvokeOnline();
|
||
|
||
var buffer = Modules[ModuleName.Buffer] as BufferModule;
|
||
buffer.InvokeOnline();
|
||
|
||
var unLoad = Modules[ModuleName.UnLoad] as UnLoadModule;
|
||
unLoad.InvokeOnline();
|
||
|
||
var efem = Modules[ModuleName.EFEM] as EFEMModule;
|
||
efem.InvokeOnline();
|
||
|
||
var aligner = Modules[ModuleName.Aligner] as AlignerModule;
|
||
aligner.InvokeOnline();
|
||
if (SC.GetValue<bool>($"System.SetUp.IsPM1Installed"))
|
||
{
|
||
var pm1 = Modules[ModuleName.PM1] as PMModule;
|
||
pm1.InvokeOnline();
|
||
}
|
||
if (SC.GetValue<bool>($"System.SetUp.IsPM2Installed"))
|
||
{
|
||
var pm2 = Modules[ModuleName.PM2] as PMModule;
|
||
pm2.InvokeOnline();
|
||
}
|
||
|
||
|
||
|
||
var cassAL = Modules[ModuleName.CassAL] as CassetteModule;
|
||
cassAL.InvokeOnline();
|
||
|
||
var cassAR = Modules[ModuleName.CassAR] as CassetteModule;
|
||
cassAR.InvokeOnline();
|
||
|
||
var cassBL = Modules[ModuleName.CassBL] as CassetteModule;
|
||
cassBL.InvokeOnline();
|
||
|
||
var waferRobot = Modules[ModuleName.WaferRobot] as WaferRobotModule;
|
||
waferRobot.InvokeOnline();
|
||
|
||
var trayRobot = Modules[ModuleName.TrayRobot] as TrayRobotModule;
|
||
trayRobot.InvokeOnline();
|
||
|
||
return true;
|
||
}
|
||
#region cassette popup menu
|
||
private bool InvokeReturnWafer(string arg1, object[] args)
|
||
{
|
||
ModuleName target = ModuleHelper.Converter(args[0].ToString());
|
||
int slot = (int)args[1];
|
||
|
||
if (ModuleHelper.IsLoadPort(target))
|
||
{
|
||
EV.PostInfoLog("System", string.Format("Wafer already at LoadPort {0} {1}, return operation is not valid", target.ToString(), slot + 1));
|
||
return false;
|
||
}
|
||
|
||
if (!WaferManager.Instance.IsWaferSlotLocationValid(target, slot))
|
||
{
|
||
EV.PostWarningLog("System", string.Format("Invalid position,{0},{1}", target.ToString(), slot.ToString()));
|
||
return false;
|
||
}
|
||
|
||
var wafer = WaferManager.Instance.GetWafer(target, slot);
|
||
if (wafer.IsEmpty)
|
||
{
|
||
EV.PostInfoLog("System", string.Format("No wafer at {0} {1}, return operation is not valid", target.ToString(), slot + 1));
|
||
return false;
|
||
}
|
||
|
||
return CheckToPostMessage((int)MSG.MoveWafer,
|
||
target, slot,
|
||
(ModuleName)wafer.OriginStation, wafer.OriginSlot,
|
||
false, 0, false, 0);
|
||
}
|
||
|
||
|
||
private bool InvokeDeleteWafer(string arg1, object[] args)
|
||
{
|
||
ModuleName chamber = ModuleHelper.Converter(args[0].ToString());
|
||
int slot = (int)args[1];
|
||
|
||
if (chamber == ModuleName.TrayRobot || chamber == ModuleName.CassBL)
|
||
{
|
||
if (WaferManager.Instance.CheckHasTray(chamber, slot))
|
||
{
|
||
WaferManager.Instance.DeleteWafer(chamber, slot);
|
||
EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDelete, chamber.ToString(), slot + 1);
|
||
}
|
||
else
|
||
{
|
||
EV.PostInfoLog("System", string.Format("No wafer at {0} {1}, delete not valid", chamber.ToString(), slot + 1));
|
||
}
|
||
}
|
||
else if (WaferManager.Instance.CheckHasWafer(chamber, slot))
|
||
{
|
||
if (chamber == ModuleName.TMRobot || chamber == ModuleName.LoadLock || chamber == ModuleName.UnLoad
|
||
|| chamber == ModuleName.Buffer || chamber == ModuleName.PM1 || chamber == ModuleName.PM2)
|
||
{
|
||
if (WaferManager.Instance.CheckHasTray(chamber, slot))
|
||
{
|
||
WaferManager.Instance.DeleteWaferOnly(chamber, slot);
|
||
}
|
||
else
|
||
{
|
||
WaferManager.Instance.DeleteWafer(chamber, slot);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
WaferManager.Instance.DeleteWafer(chamber, slot);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
EV.PostWarningLog("System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString()));
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
private bool InvokeCreateWafer(string arg1, object[] args)
|
||
{
|
||
ModuleName chamber = ModuleHelper.Converter(args[0].ToString());
|
||
int slot = (int)args[1];
|
||
WaferStatus state = WaferStatus.Normal;
|
||
|
||
if (chamber == ModuleName.TrayRobot || chamber == ModuleName.CassBL)
|
||
{
|
||
if (WaferManager.Instance.IsWaferSlotLocationValid(chamber, slot))
|
||
{
|
||
if (WaferManager.Instance.CheckHasTray(chamber, slot))
|
||
{
|
||
EV.PostInfoLog("System", string.Format("{0} slot {1} already has tray.create wafer is not valid", chamber, slot));
|
||
}
|
||
else if (WaferManager.Instance.CreateWafer(chamber, slot, state) != null)
|
||
{
|
||
EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferCreate, chamber.ToString(), slot + 1, state.ToString());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
EV.PostWarningLog("System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString()));
|
||
return false;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
if (WaferManager.Instance.IsWaferSlotLocationValid(chamber, slot))
|
||
{
|
||
if (WaferManager.Instance.CheckHasWafer(chamber, slot))
|
||
{
|
||
EV.PostInfoLog("System", string.Format("{0} slot {1} already has wafer.create wafer is not valid", chamber, slot));
|
||
}
|
||
else if (WaferManager.Instance.CreateWafer(chamber, slot, state) != null)
|
||
{
|
||
EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferCreate, chamber.ToString(), slot + 1, state.ToString());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
EV.PostWarningLog("System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString()));
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
private bool InvokeDeleteTray(string arg1, object[] args)
|
||
{
|
||
ModuleName chamber = ModuleHelper.Converter(args[0].ToString());
|
||
int slot = (int)args[1];
|
||
|
||
//获取TrayID
|
||
var wi = WaferManager.Instance.GetWafer(ModuleHelper.Converter(chamber.ToString()), Convert.ToInt16(args[1]));
|
||
int _trayOriginSlot = wi.TrayOriginSlot;
|
||
|
||
if (WaferManager.Instance.CheckHasTray(chamber, slot))
|
||
{
|
||
if (chamber == ModuleName.Buffer)
|
||
{
|
||
WaferManager.Instance.DeleteWafer(chamber, slot);
|
||
}
|
||
else if (WaferManager.Instance.CheckHasWafer(chamber, slot))
|
||
{
|
||
if(chamber == ModuleName.PM1 || chamber == ModuleName.PM2)
|
||
{
|
||
WaferManager.Instance.DeleteWafer(chamber, slot);
|
||
}
|
||
else
|
||
{
|
||
WaferManager.Instance.GetWafer(chamber, slot).TrayState = WaferTrayStatus.Empty;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
WaferManager.Instance.DeleteWafer(chamber, slot);
|
||
}
|
||
}
|
||
//从数据库中删除Tray,更新界面
|
||
string cmd_DeleteWafer = $"delete from tray_thickness_data where wafer_guid = '{_trayOriginSlot + 1}'";
|
||
DataSet dataSet = DB.ExecuteDataset(cmd_DeleteWafer);
|
||
EV.PostInfoLog(chamber.ToString(), cmd_DeleteWafer);
|
||
CoatingManager.QueryUpdate();
|
||
|
||
return true;
|
||
}
|
||
|
||
private bool InvokeAlterWaferInfo(string arg1, object[] args)
|
||
{
|
||
ModuleName chamber = ModuleHelper.Converter(args[0].ToString());
|
||
int slot = (int)args[1];
|
||
string recipeName = args[2].ToString();
|
||
int trayProcessCount = (int)args[3];
|
||
var wafer = WaferManager.Instance.GetWafer(chamber, slot);
|
||
if (WaferManager.Instance.CheckHasWafer(chamber, slot))
|
||
{
|
||
if(!String.IsNullOrEmpty(recipeName) && wafer != null && wafer.ProcessJob != null && wafer.ProcessJob.Sequence != null && wafer.ProcessState == EnumWaferProcessStatus.Idle)
|
||
{
|
||
for (int i = 0; i < wafer.ProcessJob.Sequence.Steps.Count; i++)
|
||
{
|
||
if (!String.IsNullOrEmpty(wafer.ProcessJob.Sequence.Steps[i].RecipeName))
|
||
{
|
||
wafer.ProcessJob.Sequence.Steps[i].RecipeName = recipeName;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (WaferManager.Instance.CheckHasTray(chamber, slot))
|
||
{
|
||
if (wafer != null)
|
||
{
|
||
wafer.TrayProcessCount = trayProcessCount;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
#endregion
|
||
|
||
private void OnModuleError(object sender, string module)
|
||
{
|
||
if (FsmState == (int)RtState.AutoRunning)
|
||
{
|
||
ModuleName mod = ModuleHelper.Converter(module);
|
||
|
||
PostMsg(MSG.ModuleError, module);
|
||
}
|
||
}
|
||
|
||
#region ShutDown
|
||
private bool FsmStartShutDown(object[] objs)
|
||
{
|
||
var InBusyModuleNames = this.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)
|
||
.Where(t => t.PropertyType.GetInterfaces().Contains(typeof(IModuleEntity)) && ((IModuleEntity)t.GetValue(this, null)).IsBusy)
|
||
.Select(n => n.Name).ToArray();
|
||
|
||
if (InBusyModuleNames.Length > 0)
|
||
{
|
||
EV.PostWarningLog("System", $"Shut down fail , {string.Join(" , ", InBusyModuleNames)} is in busy");
|
||
return false;
|
||
}
|
||
|
||
Term();
|
||
EV.PostKickoutMessage("ShutDown");
|
||
return true;
|
||
}
|
||
|
||
private bool FsmShutDown(object[] objs)
|
||
{
|
||
Task.Delay(3000).ContinueWith(a =>
|
||
{
|
||
Environment.Exit(0);
|
||
});
|
||
return true;
|
||
}
|
||
|
||
protected void Term()
|
||
{
|
||
foreach (var modulesValue in Modules.Values)
|
||
{
|
||
modulesValue.Terminate();
|
||
}
|
||
}
|
||
|
||
|
||
public bool OnTimer()
|
||
{
|
||
//MonitorModuleAlarm();
|
||
MonitorPmTmInfo();
|
||
MonitorUPSAlarm();
|
||
//MonitorAETemp();
|
||
MonitorEngMode();
|
||
return true;
|
||
}
|
||
|
||
private bool _isEngMode;
|
||
private readonly DeviceTimer _timEngModeTimeout = new DeviceTimer();
|
||
private readonly R_TRIG _trigEngModeEntered = new R_TRIG();
|
||
private readonly R_TRIG _trigEngModeLeft = new R_TRIG();
|
||
|
||
private void MonitorEngMode()
|
||
{
|
||
var isBypassInterlock = SC.GetValue<bool>("System.BypassInterlock");
|
||
|
||
_trigEngModeEntered.CLK = isBypassInterlock;
|
||
_trigEngModeLeft.CLK = isBypassInterlock == false;
|
||
|
||
// InterlockBypass 变为 true
|
||
if (_trigEngModeEntered.Q)
|
||
{
|
||
// 获取互锁旁路超时,最小值限定5s
|
||
var timeout = SC.GetValue<int>("System.BypassInterlockTimeout");
|
||
if (timeout <= 5)
|
||
timeout = 5;
|
||
|
||
_isEngMode = true;
|
||
_timEngModeTimeout.Restart(timeout * 1000);
|
||
EV.PostInfoLog(Name, "Interlock is bypassed");
|
||
}
|
||
|
||
// InterlockBypass 变为 false
|
||
if (_trigEngModeLeft.Q)
|
||
{
|
||
_isEngMode = false;
|
||
EV.PostInfoLog(Name, "Interlock is resumed");
|
||
}
|
||
|
||
// Eng Mode 超时
|
||
if (_timEngModeTimeout.IsTimeout())
|
||
{
|
||
_timEngModeTimeout.Stop();
|
||
SC.SetItemValue("System.BypassInterlock", false);
|
||
EV.PostInfoLog(Name, "Interlock bypass timeout");
|
||
}
|
||
}
|
||
|
||
|
||
private void MonitorPmTmInfo()
|
||
{
|
||
if (_pm1SlitValve != null)
|
||
{
|
||
if (_pm1InterLock != null && _pm1InterLock.DoPMASlitDoorClosed != _pm1SlitValve.IsClose)
|
||
{
|
||
_pm1InterLock.DoPMASlitDoorClosed = _pm1SlitValve.IsClose;
|
||
}
|
||
|
||
if (_tmInterLock != null && _pm1InterLock != null)
|
||
{
|
||
if (_tmInterLock.DoPm1LidClosed != _pm1InterLock.DiChamLidClosed)
|
||
{
|
||
_tmInterLock.DoPm1LidClosed = _pm1InterLock.DiChamLidClosed;
|
||
}
|
||
|
||
if (_tmInterLock.DoRectorAATMTransferReady != _pm1InterLock.DoReactorATMTransferReady)
|
||
{
|
||
_tmInterLock.DoRectorAATMTransferReady = _pm1InterLock.DoReactorATMTransferReady;
|
||
}
|
||
if (_tmInterLock.DoRectorAProcessTransferReady != _pm1InterLock.DoReactorVACTransferReady)
|
||
{
|
||
_tmInterLock.DoRectorAProcessTransferReady = _pm1InterLock.DoReactorVACTransferReady;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (_pm2SlitValve != null)
|
||
{
|
||
if (_pm2InterLock != null && _pm2InterLock.DoPMASlitDoorClosed != _pm2SlitValve.IsClose)
|
||
{
|
||
_pm2InterLock.DoPMASlitDoorClosed = _pm2SlitValve.IsClose;
|
||
}
|
||
|
||
if (_tmInterLock != null && _pm2InterLock != null)
|
||
{
|
||
if (_tmInterLock.DoPm2LidClosed != _pm2InterLock.DiChamLidClosed)
|
||
{
|
||
_tmInterLock.DoPm2LidClosed = _pm2InterLock.DiChamLidClosed;
|
||
}
|
||
|
||
if (_tmInterLock.DoRectorBATMTransferReady != _pm2InterLock.DoReactorATMTransferReady)
|
||
{
|
||
_tmInterLock.DoRectorBATMTransferReady = _pm2InterLock.DoReactorATMTransferReady;
|
||
}
|
||
if (_tmInterLock.DoRectorBProcessTransferReady != _pm2InterLock.DoReactorVACTransferReady)
|
||
{
|
||
_tmInterLock.DoRectorBProcessTransferReady = _pm2InterLock.DoReactorVACTransferReady;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
private void MonitorUPSAlarm()
|
||
{
|
||
string sReason;
|
||
|
||
if (_upsPM1A != null && _upsPM1B != null && _pm1UPS != null)
|
||
{
|
||
bool _power1 = !(_upsPM1A.UPSPowerAlarm || _upsPM1B.UPSPowerAlarm);
|
||
bool _lowerBattery1 = !(_upsPM1A.UPSLowerBatteryAlarm || _upsPM1B.UPSLowerBatteryAlarm);
|
||
|
||
if (_pm1UPS.UPSEnable == _power1)
|
||
{
|
||
_pm1UPS.SetUPSEnable(_power1, out sReason);
|
||
}
|
||
if (_pm1UPS.UPSLowBattery == _lowerBattery1)
|
||
{
|
||
_pm1UPS.SetUPSLowBattery(_lowerBattery1, out sReason);
|
||
}
|
||
}
|
||
|
||
if (_upsPM2A != null && _upsPM2B != null && _pm2UPS != null)
|
||
{
|
||
bool _power2 = !(_upsPM2A.UPSPowerAlarm || _upsPM2B.UPSPowerAlarm);
|
||
bool _lowerBattery2 = !(_upsPM2A.UPSLowerBatteryAlarm || _upsPM2B.UPSLowerBatteryAlarm);
|
||
|
||
if (_pm2UPS.UPSEnable == _power2)
|
||
{
|
||
_pm2UPS.SetUPSEnable(_power2, out sReason);
|
||
}
|
||
if (_pm2UPS.UPSLowBattery == _lowerBattery2)
|
||
{
|
||
_pm2UPS.SetUPSLowBattery(_lowerBattery2, out sReason);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
private void MonitorAETemp()
|
||
{
|
||
if (_aeTemp != null && _pmAETemp1 != null)
|
||
{
|
||
string sReason;
|
||
if (!_aeTemp.IsConnected)
|
||
{
|
||
_pmAETemp1.SetPyroCommunicationError(true, out sReason);
|
||
}
|
||
else
|
||
{
|
||
_pmAETemp1.SetPyroCommunicationError(false, out sReason);
|
||
}
|
||
}
|
||
|
||
if (_aeTemp != null && _pmAETemp2 != null)
|
||
{
|
||
string sReason;
|
||
if (!_aeTemp.IsConnected)
|
||
{
|
||
_pmAETemp2.SetPyroCommunicationError(true, out sReason);
|
||
}
|
||
else
|
||
{
|
||
_pmAETemp2.SetPyroCommunicationError(false, out sReason);
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
}
|
||
}
|