using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using FurnaceRT.Equipments.FIMSs; using FurnaceRT.Equipments.PMs; using FurnaceRT.Equipments.Systems; using FurnaceRT.Equipments.WaferRobots; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Jobs; using MECF.Framework.Common.SubstrateTrackings; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; using static FurnaceRT.Equipments.PMs.PMModule; namespace FurnaceRT.Devices { public class IoFIMS : BaseDevice, IDevice { private DIAccessor _diLoadComplete; private DIAccessor _diUnloadComplete; private DIAccessor _diHomeComplete; private DIAccessor _diRunning; private DIAccessor _diAutoManual; private DIAccessor _diUndock; private DIAccessor _diDock; private DIAccessor _diExist; private DIAccessor _diSeal; private DIAccessor _diRelease; private DIAccessor _diDoorOpen; private DIAccessor _diDoorClose; private DIAccessor _diLatchOn; private DIAccessor _diLatchOff; private DIAccessor _diCollisionAvoidanceDown; private DIAccessor _diCollisionAvoidanceUp; private DIAccessor _diN2PurgeValveClosed; private DIAccessor _diN2PurgeValveOpened; private DIAccessor _diFOUPVacuumSuckingOK; private DIAccessor _diFOUPVacuumSuckingAlarm; private DIAccessor _diWaferOnRobot; private DIAccessor _diWaferRobotEX1AxisHomePosition; private DIAccessor _diWaferRobotEX2AxisHomePosition; private DOAccessor _doLoad; private DOAccessor _doUnload; private DOAccessor _doHome; private DOAccessor _doAlarmReset; private DOAccessor _doAutoManual; private DOAccessor _doUndock; private DOAccessor _doDock; private DOAccessor _doSeal; private DOAccessor _doRelease; private DOAccessor _doDoorOpen; private DOAccessor _doDoorClose; private DOAccessor _doLatch1On; private DOAccessor _doLatch2On; private DOAccessor _doLatch1Off; private DOAccessor _doLatch2Off; private DOAccessor _doCollisionAvoidanceDown; private DOAccessor _doCollisionAvoidanceUp; private DOAccessor _doN2PurgeValveOpen; private DOAccessor _doN2PurgeValveClose; private DOAccessor _doVaccumValveOpen; private DOAccessor _doVaccumValveClose; private int resetTime = 500; public DeviceStatus DockUndockStatus { get { if (_diDock != null && _diUndock != null && _diDock.Value && !_diUndock.Value) return DeviceStatus.Dock; if (_diDock != null && _diUndock != null && !_diDock.Value && _diUndock.Value) return DeviceStatus.Undock; return DeviceStatus.Unknown; } } public DeviceStatus SealReleaseStatus { get { if (_diSeal != null && _diRelease != null && _diSeal.Value && !_diRelease.Value) return DeviceStatus.Seal; if (_diSeal != null && _diRelease != null && !_diSeal.Value && _diRelease.Value) return DeviceStatus.Release; return DeviceStatus.Unknown; } } public DeviceStatus DoorOpenCloseStatus { get { if (_diDoorOpen != null && _diDoorClose != null && _diDoorOpen.Value && !_diDoorClose.Value) return DeviceStatus.Open; if (_diDoorOpen != null && _diDoorClose != null && !_diDoorOpen.Value && _diDoorClose.Value) return DeviceStatus.Close; return DeviceStatus.Unknown; } } public DeviceStatus LatchOnOffStatus { get { if (_diLatchOn != null && _diLatchOff != null && _diLatchOn.Value && !_diLatchOff.Value) return DeviceStatus.On; if (_diLatchOn != null && _diLatchOff != null && !_diLatchOn.Value && _diLatchOff.Value) return DeviceStatus.Off; return DeviceStatus.Unknown; } } public DeviceStatus CollisionAvoidanceUpDownStatus { get { if (_diCollisionAvoidanceUp != null && _diCollisionAvoidanceDown != null && _diCollisionAvoidanceUp.Value && !_diCollisionAvoidanceDown.Value) return DeviceStatus.Up; if (_diCollisionAvoidanceUp != null && _diCollisionAvoidanceDown != null && !_diCollisionAvoidanceUp.Value && _diCollisionAvoidanceDown.Value) return DeviceStatus.Down; return DeviceStatus.Unknown; } } public DeviceStatus N2PurgeValveOpenCloseStatus { get { if (_diN2PurgeValveOpened != null && _diN2PurgeValveClosed != null && _diN2PurgeValveOpened.Value && !_diN2PurgeValveClosed.Value) return DeviceStatus.Open; if (_diN2PurgeValveOpened != null && _diN2PurgeValveClosed != null && !_diN2PurgeValveOpened.Value && _diN2PurgeValveClosed.Value) return DeviceStatus.Close; return DeviceStatus.Unknown; } } public DeviceStatus VaccumValveOpenCloseStatus { get { if (_doVaccumValveOpen != null && _doVaccumValveClose != null && _doVaccumValveOpen.Value && !_doVaccumValveClose.Value) return DeviceStatus.Open; if (_doVaccumValveOpen != null && _doVaccumValveClose != null && !_doVaccumValveOpen.Value && _doVaccumValveClose.Value) return DeviceStatus.Close; return DeviceStatus.Unknown; } } public bool IsPLCLoadCompleted => _diLoadComplete == null ? false : _diLoadComplete.Value; public bool IsPLCUnloadCompleted => _diUnloadComplete == null ? false : _diUnloadComplete.Value; public bool IsPLCInitCompleted => _diHomeComplete == null ? false : _diHomeComplete.Value; public bool IsRunning => _diRunning == null ? false : _diRunning.Value; public bool IsFoupExist => _diExist == null ? false : _diExist.Value; public bool IsWaferOnRobot => _diWaferOnRobot == null ? false : _diWaferOnRobot.Value; public bool IsWaferRobotEX1AxisHomePosition => _diWaferRobotEX1AxisHomePosition == null ? false : _diWaferRobotEX1AxisHomePosition.Value; public bool IsWaferRobotEX2AxisHomePosition => _diWaferRobotEX2AxisHomePosition == null ? false : _diWaferRobotEX2AxisHomePosition.Value; public bool IsLoadCompleted { get; set; } public bool IsUnloadCompleted { get; set; } public bool IsInitCompleted { get; set; } public bool IsBusy { get; set; } public bool IsPause { get; set; } public IoFIMS(string module, XmlElement node, string ioModule = "") { base.Module = string.IsNullOrEmpty(node.GetAttribute("module")) ? module : node.GetAttribute("module"); base.Name = node.GetAttribute("id"); base.Display = node.GetAttribute("display"); base.DeviceID = node.GetAttribute("schematicId"); _diLoadComplete = ParseDiNode("diLoadComplete", node, ioModule); _diUnloadComplete = ParseDiNode("diUnloadComplete", node, ioModule); _diHomeComplete = ParseDiNode("diHomeComplete", node, ioModule); _diRunning = ParseDiNode("diRunning", node, ioModule); _diAutoManual = ParseDiNode("diAutoManual", node, ioModule); _diDock = ParseDiNode("diDock", node, ioModule); _diUndock = ParseDiNode("diUndock", node, ioModule); _diExist = ParseDiNode("diExist", node, ioModule); _diSeal = ParseDiNode("diSeal", node, ioModule); _diRelease = ParseDiNode("diRelease", node, ioModule); _diDoorOpen = ParseDiNode("diDoorOpen", node, ioModule); _diDoorClose = ParseDiNode("diDoorClose", node, ioModule); _diLatchOn = ParseDiNode("diLatchOn", node, ioModule); _diLatchOff = ParseDiNode("diLatchOff", node, ioModule); _diCollisionAvoidanceDown = ParseDiNode("diCollisionAvoidanceDown", node, ioModule); _diCollisionAvoidanceUp = ParseDiNode("diCollisionAvoidanceUp", node, ioModule); _diN2PurgeValveClosed = ParseDiNode("diN2PurgeValveClosed", node, ioModule); _diN2PurgeValveOpened = ParseDiNode("diN2PurgeValveOpened", node, ioModule); _diFOUPVacuumSuckingOK = ParseDiNode("diFOUPVacuumSuckingOK", node, ioModule); _diFOUPVacuumSuckingAlarm = ParseDiNode("diFOUPVacuumSuckingAlarm", node, ioModule); _diWaferOnRobot = ParseDiNode("diWaferOnRobot", node, ioModule); _diWaferRobotEX1AxisHomePosition = ParseDiNode("diWaferRobotEX1AxisHomePosition", node, ioModule); _diWaferRobotEX2AxisHomePosition = ParseDiNode("diWaferRobotEX2AxisHomePosition", node, ioModule); _doLoad = ParseDoNode("doLoad", node, ioModule); _doUnload = ParseDoNode("doUnload", node, ioModule); _doHome = ParseDoNode("doHome", node, ioModule); _doAlarmReset = ParseDoNode("doAlarmReset", node, ioModule); _doAutoManual = ParseDoNode("doAutoManual", node, ioModule); _doDock = ParseDoNode("doDock", node, ioModule); _doUndock = ParseDoNode("doUndock", node, ioModule); _doSeal = ParseDoNode("doSeal", node, ioModule); _doRelease = ParseDoNode("doRelease", node, ioModule); _doDoorOpen = ParseDoNode("doDoorOpen", node, ioModule); _doDoorClose = ParseDoNode("doDoorClose", node, ioModule); _doLatch1On = ParseDoNode("doLatch1On", node, ioModule); _doLatch2On = ParseDoNode("doLatch2On", node, ioModule); _doLatch1Off = ParseDoNode("doLatch1Off", node, ioModule); _doLatch2Off = ParseDoNode("doLatch2Off", node, ioModule); _doCollisionAvoidanceDown = ParseDoNode("doCollisionAvoidanceDown", node, ioModule); _doCollisionAvoidanceUp = ParseDoNode("doCollisionAvoidanceUp", node, ioModule); _doN2PurgeValveOpen = ParseDoNode("doN2PurgeValveOpen", node, ioModule); _doN2PurgeValveClose = ParseDoNode("doN2PurgeValveClose", node, ioModule); _doVaccumValveOpen = ParseDoNode("doVaccumValveOpen", node, ioModule); _doVaccumValveClose = ParseDoNode("doVaccumValveClose", node, ioModule); } public bool Initialize() { DATA.Subscribe($"{Module}.{Name}.DockUndockStatus", () => DockUndockStatus.ToString()); DATA.Subscribe($"{Module}.{Name}.SealReleaseStatus", () => SealReleaseStatus.ToString()); DATA.Subscribe($"{Module}.{Name}.DoorOpenCloseStatus", () => DoorOpenCloseStatus.ToString()); DATA.Subscribe($"{Module}.{Name}.LatchOnOffStatus", () => LatchOnOffStatus.ToString()); DATA.Subscribe($"{Module}.{Name}.CollisionAvoidanceUpDownStatus", () => CollisionAvoidanceUpDownStatus.ToString()); DATA.Subscribe($"{Module}.{Name}.N2PurgeValveOpenCloseStatus", () => N2PurgeValveOpenCloseStatus.ToString()); DATA.Subscribe($"{Module}.{Name}.VaccumValveOpenCloseStatus", () => VaccumValveOpenCloseStatus.ToString()); DATA.Subscribe($"{Module}.{Name}.UIFoupSensor", () => GetUIFoupSensor(), SubscriptionAttribute.FLAG.IgnoreSaveDB); OP.Subscribe($"{Module}.{Name}.SetDockUndock", (string cmd, object[] param) => { bool.TryParse(param[0].ToString(), out bool isDock); SetDockUndock(isDock); return true; }); OP.Subscribe($"{Module}.{Name}.SetSealRelease", (string cmd, object[] param) => { bool.TryParse(param[0].ToString(), out bool isSeal); SetSealRelease(isSeal); return true; }); OP.Subscribe($"{Module}.{Name}.SetDoorOpenClose", (string cmd, object[] param) => { bool.TryParse(param[0].ToString(), out bool isOpen); SetDoorOpenClose(isOpen); return true; }); OP.Subscribe($"{Module}.{Name}.SetLatchOnOff", (string cmd, object[] param) => { bool.TryParse(param[0].ToString(), out bool isOn); SetLatchOnOff(isOn); return true; }); OP.Subscribe($"{Module}.{Name}.SetCollisionAvoidanceUpDown", (string cmd, object[] param) => { bool.TryParse(param[0].ToString(), out bool isUp); SetCollisionAvoidanceUpDown(isUp); return true; }); OP.Subscribe($"{Module}.{Name}.SetN2PurgeValveOpenClose", (string cmd, object[] param) => { bool.TryParse(param[0].ToString(), out bool isOpen); SetN2PurgeValveOpenClose(isOpen); return true; }); OP.Subscribe($"{Module}.{Name}.SetVaccumValveOpen", (string cmd, object[] param) => { bool.TryParse(param[0].ToString(), out bool isOpen); SetVaccumValveOpen(isOpen); return true; }); OP.Subscribe($"{Module}.{Name}.SetAlarmReset", (string cmd, object[] param) => { SetAlarmReset(); return true; }); return true; } public void Monitor() { var fimsFoupInfo = CarrierManager.Instance.GetCarrier(Name); if (ModuleHelper.IsFIMS(ModuleHelper.Converter(Name))) { var setValue = GetUIFoupSensor(); Singleton.Instance.SetUIWaferCount(fimsFoupInfo, ModuleHelper.Converter(Name), out var wafers); if (!Singleton.Instance.Modules.ContainsKey(ModuleHelper.Converter(Name))) { return; } var fims = Singleton.Instance.Modules[ModuleHelper.Converter(Name)] as FIMSModule; var pm = Singleton.Instance.Modules[ModuleName.PM1] as PMModule; if (pm.StringProcessFlowState == ProcessFlowState.End.ToString() && fimsFoupInfo != null && !fimsFoupInfo.IsEmpty && wafers.All(a => a.IsEmpty) && fims != null) { var activePjStatus = Singleton.Instance.GetActivePjStatus(); if (!string.IsNullOrEmpty(activePjStatus) && activePjStatus == EnumProcessingState.Discharging.ToString()) { //等待waferrobot pick fimsFoupInfo.UICarrierStatusEnum = CarrierStatus.PRCEND; } } if (setValue) { var waferRobot = Singleton.Instance.Modules[ModuleName.WaferRobot] as WaferRobotModule; if (waferRobot != null && waferRobot.IsInitialized) { if (waferRobot.FsmState == (int)WaferRobotModule.STATE.Mapping) { fimsFoupInfo.UICarrierStatusEnum = CarrierStatus.MAPPING; } } } if (fimsFoupInfo != null && fimsFoupInfo.CarrierType != CarrierType.None) { fimsFoupInfo.UICarrierType = fimsFoupInfo.CarrierType.ToString(); var pmModule = Singleton.Instance.Modules[ModuleName.PM1] as PMModule; fimsFoupInfo.UICarrierColor = pmModule.GetCarrierUIColor(fimsFoupInfo.UICarrierType, fimsFoupInfo.UICarrierStatusEnum); } SetVisibility(fimsFoupInfo, setValue); } } public void SetVisibility(CarrierInfo carrierInfo, bool setValue) { if (carrierInfo == null) { return; } carrierInfo.UIExitFoup = setValue; carrierInfo.UICarrierColorVisibility = setValue; carrierInfo.UICarrierStatusVisibility = setValue; carrierInfo.UICarrierTypeVisibility = setValue; carrierInfo.UICarrierWaferCountVisibility = setValue; } public bool GetUIFoupSensor() { var fimsFoupInfo = CarrierManager.Instance.GetCarrier(Name); if (SC.GetValue("System.IsSimulatorMode")) { if (fimsFoupInfo != null && !fimsFoupInfo.IsEmpty) { return true; } } else { if (_diExist != null && _diExist.Value && fimsFoupInfo != null && !fimsFoupInfo.IsEmpty) { return true; } return false; } return false; } public void Reset() { } public void Terminate() { } private bool SetDockUndock(bool isDock) { if (isDock) { _doUndock.SetPulseValue(false, resetTime); _doDock.SetPulseValue(true, resetTime); //_doUndock.Value = false; //_doDock.Value = true; } else { _doUndock.SetPulseValue(true, resetTime); _doDock.SetPulseValue(false, resetTime); //_doDock.Value = false; //_doUndock.Value = true; } return true; } private bool SetSealRelease(bool isSeal) { if (isSeal) { _doRelease.SetPulseValue(false, resetTime); _doSeal.SetPulseValue(true, resetTime); //_doRelease.Value = false; //_doSeal.Value = true; } else { _doSeal.SetPulseValue(false, resetTime); _doRelease.SetPulseValue(true, resetTime); //_doSeal.Value = false; //_doRelease.Value = true; } return true; } private bool SetDoorOpenClose(bool isOpen) { if (isOpen) { _doDoorClose.SetPulseValue(false, resetTime); _doDoorOpen.SetPulseValue(true, resetTime); //_doDoorClose.Value = false; //_doDoorOpen.Value = true; } else { _doDoorOpen.SetPulseValue(false, resetTime); _doDoorClose.SetPulseValue(true, resetTime); //_doDoorOpen.Value = false; //_doDoorClose.Value = true; } return true; } private bool SetLatchOnOff(bool isOn) { if (isOn) { _doLatch1Off.SetPulseValue(false, resetTime); _doLatch2Off.SetPulseValue(false, resetTime); _doLatch1On.SetPulseValue(true, resetTime); _doLatch2On.SetPulseValue(true, resetTime); //_doLatch1Off.Value = false; //_doLatch2Off.Value = false; //_doLatch1On.Value = true; //_doLatch2On.Value = true; } else { _doLatch1On.SetPulseValue(false, resetTime); _doLatch2On.SetPulseValue(false, resetTime); _doLatch1Off.SetPulseValue(true, resetTime); _doLatch2Off.SetPulseValue(true, resetTime); //_doLatch1On.Value = false; //_doLatch2On.Value = false; //_doLatch1Off.Value = true; //_doLatch2Off.Value = true; } return true; } private bool SetCollisionAvoidanceUpDown(bool isUp) { if (isUp) { _doCollisionAvoidanceDown.SetPulseValue(false, resetTime); _doCollisionAvoidanceUp.SetPulseValue(true, resetTime); //_doCollisionAvoidanceDown.Value = false; //_doCollisionAvoidanceUp.Value = true; } else { _doCollisionAvoidanceUp.SetPulseValue(false, resetTime); _doCollisionAvoidanceDown.SetPulseValue(true, resetTime); //_doCollisionAvoidanceUp.Value = false; //_doCollisionAvoidanceDown.Value = true; } return true; } private bool SetN2PurgeValveOpenClose(bool isOpen) { if (isOpen) { _doN2PurgeValveClose.SetPulseValue(false, resetTime); _doN2PurgeValveOpen.SetPulseValue(true, resetTime); //_doN2PurgeValveClose.Value = false; //_doN2PurgeValveOpen.Value = true; } else { _doN2PurgeValveOpen.SetPulseValue(false, resetTime); _doN2PurgeValveClose.SetPulseValue(true, resetTime); //_doN2PurgeValveOpen.Value = false; //_doN2PurgeValveClose.Value = true; } return true; } private bool SetVaccumValveOpen(bool isOpen) { if (isOpen) { _doVaccumValveClose.SetPulseValue(false, resetTime); _doVaccumValveOpen.SetPulseValue(true, resetTime); //_doVaccumValveClose.Value = false; //_doVaccumValveOpen.Value = true; } else { _doVaccumValveOpen.SetPulseValue(false, resetTime); _doVaccumValveClose.SetPulseValue(true, resetTime); //_doVaccumValveOpen.Value = false; //_doVaccumValveClose.Value = true; } return true; } public void SetAlarmReset() { _doAlarmReset.SetPulseValue(true, 1000); } public bool Unload(out string reason) { reason = ""; _doLoad.SetValue(false, out reason); _doHome.SetValue(false, out reason); _doUnload.SetValue(true, out reason); return true; } public bool Load(out string reason) { reason = ""; _doUnload.SetValue(false, out reason); _doHome.SetValue(false, out reason); _doLoad.SetValue(true, out reason); return true; } public bool Init(out string reason) { reason = ""; _doLoad.SetValue(false, out reason); _doUnload.SetValue(false, out reason); _doHome.SetValue(true, out reason); return true; } public bool Stop() { var reason = ""; _doLoad.SetValue(false, out reason); _doUnload.SetValue(false, out reason); _doHome.SetValue(false, out reason); return true; } public void SetPauseResume(bool isPause) { IsPause = isPause; } } }