using System; using System.Xml; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Event; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Event; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes; namespace JetEfemLib { /// /// Future EFEM compatible with Rorze communication protocol /// public class JetEfem : RorzeEfem { public AlarmEventItem FfuAlarm { get; set; } public AlarmEventItem IonizerAlarm { get; set; } public AlarmEventItem AirErrorForRobot { get; set; } //public AlarmEventItem AirErrorForChamber { get; set; } public AlarmEventItem IsMaintain { get; set; } public AlarmEventItem DoorOpen { get; set; } public AlarmEventItem EmoAlarm { get; set; } public AlarmEventItem WaterLeakWarning { get; set; } private bool _stateFfuAlarm; private bool _stateIonizerAlarm; private bool _stateAirErrorForRobot; private bool _stateIsMaintain; private bool _stateDoorOpen; private bool _stateEmoAlarm; private bool _stateWaterLeakWarning; public JetEfem(string module, XmlElement node, string ioModule = "") : base("System", "EFEM", "") { } public JetEfem( ) : base("System", "EFEM", "") { } public override bool Initialize() { FfuAlarm = SubscribeAlarm($"{Module}.{Name}.FFUAlarm", "EFEM FFU Error", () => !_stateFfuAlarm, EventLevel.Warning); IonizerAlarm = SubscribeAlarm($"{Module}.{Name}.IonizerAlarm", "EFEM Ionizer Error", () => !_stateIonizerAlarm, EventLevel.Warning); AirErrorForRobot = SubscribeAlarm($"{Module}.{Name}.AirErrorForRobot", "EFEM Robot Air Error", () => !_stateAirErrorForRobot, EventLevel.Warning); //AirErrorForChamber = SubscribeAlarm($"{Module}.{Name}.AirErrorForChamber", "EFEM Chamber Air Error", () => !_stateAirErrorForChamber, EventLevel.Warning); IsMaintain = SubscribeAlarm($"{Module}.{Name}.IsMaintain", "EFEM in Maintenance Mode, switch to online and turn key to auto", () => !_stateIsMaintain, EventLevel.Alarm); DoorOpen = SubscribeAlarm($"{Module}.{Name}.DoorOpen", "EFEM door open", () => !_stateDoorOpen, EventLevel.Alarm); EmoAlarm = SubscribeAlarm($"{Module}.{Name}.EmoAlarm", "EFEM EMO error", () => !_stateEmoAlarm, EventLevel.Alarm); WaterLeakWarning = SubscribeAlarm($"{Module}.{Name}.WaterLeakWarning", "EFEM Water Leak Warning", () => !_stateFfuAlarm, EventLevel.Alarm); DATA.Subscribe($"{Module}.{Name}.FFUAlarm", () => _stateFfuAlarm); DATA.Subscribe($"{Module}.{Name}.IonizerAlarm", () => _stateIonizerAlarm); DATA.Subscribe($"{Module}.{Name}.AirErrorForRobot", () => _stateAirErrorForRobot); //DATA.Subscribe($"{Module}.{Name}.AirErrorForChamber", () => _stateAirErrorForChamber); DATA.Subscribe($"{Module}.{Name}.IsMaintain", () => _stateIsMaintain); DATA.Subscribe($"{Module}.{Name}.DoorOpen", () => _stateDoorOpen); DATA.Subscribe($"{Module}.{Name}.EmoAlarm", () => _stateEmoAlarm); DATA.Subscribe($"{Module}.{Name}.WaterLeakWarning", () => _stateWaterLeakWarning); OP.Subscribe("System.SetWaferSize", (string cmd, object[] args) => { string module = (string)args[0]; int slot = (int)args[1]; string size = (string)args[2]; switch (size) { case "4": WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), slot, WaferSize.WS4); break; case "6": WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), slot, WaferSize.WS6); break; case "8": WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), slot, WaferSize.WS8); break; case "12": WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), slot, WaferSize.WS12); break; default: EV.PostWarningLog("System", $"wafer size {size} not valid"); break; } return true; }); return base.Initialize(); } public override void NoteStateEvent(ModuleName module, string data1, string data2) { if (module == ModuleName.System) { uint result1 = Convert.ToUInt32(data1, 16); uint result2 = Convert.ToUInt32(data2, 16); _stateAirErrorForRobot = !((result1 & 0x00000004u) == 0x00000004u); if (_stateAirErrorForRobot) AirErrorForRobot.Set(); _stateWaterLeakWarning = !((result1 & 0x00000020u) == 0x00000020u); if (_stateWaterLeakWarning) WaterLeakWarning.Set(); _stateIonizerAlarm = !((result1 & 0x00000400u) == 0x00000400u); if (_stateIonizerAlarm) IonizerAlarm.Set(); _stateFfuAlarm = !((result1 & 0x00000800u) == 0x00000800u); if (_stateFfuAlarm) FfuAlarm.Set(); //_stateAirErrorForChamber = !((result1 & 0x00000008u) == 0x00000008u); //if (_stateAirErrorForChamber) // AirErrorForChamber.Set(); _stateIsMaintain = !((result1 & 0x00002000u) == 0x00002000u); if (_stateIsMaintain) IsMaintain.Set(); _stateDoorOpen = !((result1 & 0x000080000u) == 0x000080000u); if (_stateDoorOpen) DoorOpen.Set(); //_stateEmoAlarm = (result1 & 0x00000040u) == 0x00000040u; //if (_stateEmoAlarm) // EmoAlarm.Set(); return; } base.NoteStateEvent(module, data1, data2); } public override void NoteWaferTrack(string waferInfo) { if (waferInfo[0] == '1' && !WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1)) { WaferManager.Instance.CreateWafer(ModuleName.EfemRobot, 1, WaferStatus.Normal); } else if (waferInfo[0] == '0' && !WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1)) { WaferManager.Instance.DeleteWafer(ModuleName.EfemRobot, 1); } if (waferInfo[1] == '1' && !WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0)) { WaferManager.Instance.CreateWafer(ModuleName.EfemRobot, 0, WaferStatus.Normal); } else if (waferInfo[1] == '0' && !WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0)) { WaferManager.Instance.DeleteWafer(ModuleName.EfemRobot, 0); } if (waferInfo[2] == '1' && !WaferManager.Instance.CheckHasWafer(ModuleName.Aligner, 0)) { WaferManager.Instance.CreateWafer(ModuleName.Aligner, 0, WaferStatus.Normal); } else if (waferInfo[2] == '0' && !WaferManager.Instance.CheckNoWafer(ModuleName.Aligner, 0)) { WaferManager.Instance.DeleteWafer(ModuleName.Aligner, 0); } } public override void Monitor() { base.Monitor(); } public override void Reset() { FfuAlarm.Reset(); IonizerAlarm.Reset(); AirErrorForRobot.Reset(); //AirErrorForChamber.Reset(); IsMaintain.Reset(); DoorOpen.Reset(); EmoAlarm.Reset(); base.Reset(); } public void ResetData() { Reset(); } public bool MapCarrier(string lp, int thicknessIndex, out string slotMap, out string reason) { slotMap = string.Empty; if (!Connection.IsConnected) { reason = "not connected"; return false; } return Connection.Execute(new RorzeEfemHandlerWafsh(this, ModuleHelper.Converter(lp), true, thicknessIndex), out reason); } } }