2023-03-03 15:42:13 +08:00
|
|
|
|
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 Mainframe.Buffers;
|
|
|
|
|
using Mainframe.LLs;
|
|
|
|
|
using Mainframe.TMs;
|
|
|
|
|
using SicRT.Instances;
|
|
|
|
|
using SicRT.Modules;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Aitex.Core.RT.Device.Unit;
|
|
|
|
|
using Mainframe.Aligners;
|
|
|
|
|
using Mainframe.UnLoads;
|
|
|
|
|
using Mainframe.EFEMs;
|
|
|
|
|
using Mainframe.Cassettes;
|
|
|
|
|
using Aitex.Core.RT.SCCore;
|
|
|
|
|
using SicPM1;
|
|
|
|
|
using SicPM2;
|
|
|
|
|
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.UPS;
|
|
|
|
|
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps.AE;
|
|
|
|
|
using Aitex.Core.RT.Device.Devices;
|
|
|
|
|
|
|
|
|
|
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 Mainframe.Devices.IoInterLock _tmInterLock = null;
|
|
|
|
|
private IoSlitValve _pm1SlitValve = null;
|
|
|
|
|
private IoSlitValve _pm2SlitValve = null;
|
|
|
|
|
private PeriodicJob _thread;
|
|
|
|
|
//
|
|
|
|
|
private Aitex.Core.RT.Device.Devices.IoSignalTower _st = null;
|
|
|
|
|
//
|
|
|
|
|
private IoTC _tc = null;
|
|
|
|
|
//private IoPTOffsetAndK _pm1PT1, _pm1PT2, _pm1PT3, _pm1PT4, _pm1PT9, _pm1PT10;
|
|
|
|
|
|
|
|
|
|
//private IoPTOffsetAndK _pm2PT1, _pm2PT2;
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 PM1Module(ModuleName.PM1);
|
|
|
|
|
Modules[ModuleName.PM1] = pm1;
|
|
|
|
|
//pm1.OnEnterError += OnModuleError;
|
|
|
|
|
|
|
|
|
|
var pm2 = new PM2Module(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<Mainframe.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");
|
|
|
|
|
|
|
|
|
|
_st = DEVICE.GetDevice<Aitex.Core.RT.Device.Devices.IoSignalTower>("PM1.SignalTower");
|
|
|
|
|
_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 = 2; i < 16; i++)
|
|
|
|
|
{
|
|
|
|
|
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>($"PM1.AO_AI{i}_OffsetAndK"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SC.GetValue<bool>($"System.SetUp.IsPM2Installed"))
|
|
|
|
|
{
|
|
|
|
|
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>("PM2.PT1OffsetAndK"));
|
|
|
|
|
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>("PM2.PT2OffsetAndK"));
|
|
|
|
|
for (int i = 2; i < 16; i++)
|
|
|
|
|
{
|
|
|
|
|
ioPTOffsetAndKs.Add(DEVICE.GetDevice<IoPTOffsetAndK>($"PM2.AO_AI{i}_OffsetAndK"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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());
|
2023-03-03 16:45:39 +08:00
|
|
|
|
DATA.Subscribe("System.IsEngMode", () => _isEngMode);
|
2023-03-03 15:42:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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]);
|
|
|
|
|
//});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void InitSetPSUY()
|
|
|
|
|
{
|
|
|
|
|
Task.Delay(2000).ContinueWith(x=> _tc.SetPCPSUY());
|
|
|
|
|
}
|
|
|
|
|
void InitPTOffsetAndK()
|
|
|
|
|
{
|
|
|
|
|
Task.Delay(2000).ContinueWith(x => SetPTOffsetAndK());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SetPTOffsetAndK()
|
|
|
|
|
{
|
|
|
|
|
foreach (IoPTOffsetAndK item in ioPTOffsetAndKs)
|
|
|
|
|
{
|
|
|
|
|
if (item.Name.Contains("PT"))
|
|
|
|
|
{
|
|
|
|
|
item.SetPTOffset();
|
|
|
|
|
item.SetPTK();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
item.SetTempOffset();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//EventManager触发OnAlarmEvent事件,即EV.PostAlarmLog触发
|
|
|
|
|
//具体值到 EventManager里面找
|
|
|
|
|
//private void Instance_OnAlarmEvent(EventItem obj)
|
|
|
|
|
//{
|
|
|
|
|
// if (obj.EventEnum == "ALARM_EVENT")
|
|
|
|
|
// {
|
|
|
|
|
// //这里应该触发IoSignalTower的警报动作
|
|
|
|
|
// if (_st != null)
|
|
|
|
|
// {
|
|
|
|
|
// MECF.Framework.Common.Device.Bases.SignalLightBase islL = _st.CreateLight(MECF.Framework.Common.Device.Bases.LightType.Red);
|
|
|
|
|
// if (islL != null)
|
|
|
|
|
// {
|
|
|
|
|
// islL.StateSetPoint = MECF.Framework.Common.Device.Bases.TowerLightStatus.On;
|
|
|
|
|
// }
|
|
|
|
|
// //
|
|
|
|
|
// MECF.Framework.Common.Device.Bases.SignalLightBase islB = _st.CreateLight(MECF.Framework.Common.Device.Bases.LightType.Buzzer);
|
|
|
|
|
// if (islB != null)
|
|
|
|
|
// {
|
|
|
|
|
// islB.StateSetPoint = MECF.Framework.Common.Device.Bases.TowerLightStatus.On;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (obj.Source)
|
|
|
|
|
{
|
|
|
|
|
case "PM1":
|
|
|
|
|
case "PM2":
|
|
|
|
|
case "EFEM":
|
|
|
|
|
case "TM":
|
|
|
|
|
default:
|
|
|
|
|
if (Modules.ContainsKey(ModuleHelper.Converter(obj.Source)))
|
|
|
|
|
{
|
|
|
|
|
Modules[ModuleHelper.Converter(obj.Source)]?.PostMsg(msg, obj.Id, obj.Description);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_st != null)
|
|
|
|
|
{
|
|
|
|
|
_st.SwitchOffBuzzer(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#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 PM1Module;
|
|
|
|
|
pm1.InvokeOffline();
|
|
|
|
|
|
|
|
|
|
var pm2 = Modules[ModuleName.PM2] as PM2Module;
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
var pm1 = Modules[ModuleName.PM1] as PM1Module;
|
|
|
|
|
pm1.InvokeOnline();
|
|
|
|
|
|
|
|
|
|
var pm2 = Modules[ModuleName.PM2] as PM2Module;
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-13 17:37:55 +08:00
|
|
|
|
var wafer = WaferManager.Instance.GetWafer(target, slot);
|
2023-03-03 15:42:13 +08:00
|
|
|
|
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];
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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];
|
2023-03-13 17:37:55 +08:00
|
|
|
|
var wafer = WaferManager.Instance.GetWafer(chamber, slot);
|
2023-03-03 15:42:13 +08:00
|
|
|
|
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(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();
|
2023-03-03 16:45:39 +08:00
|
|
|
|
MonitorEngMode();
|
2023-03-03 15:42:13 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-03 16:45:39 +08:00
|
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-03 15:42:13 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
}
|