1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021 |
- using Aitex.Core.RT.Device;
- using Aitex.Core.RT.Log;
- using Aitex.Core.RT.Routine;
- using Aitex.Core.RT.SCCore;
- using Aitex.Core.Util;
- using CyberX8_Core;
- using CyberX8_RT.Devices.Facilities;
- using CyberX8_RT.Devices.Metal;
- using CyberX8_RT.Devices.PowerSupplier;
- using CyberX8_RT.Devices.Reservoir;
- using CyberX8_RT.Devices.Temperature;
- using CyberX8_RT.Modules.Metal;
- using CyberX8_RT.Modules;
- using MECF.Framework.Common.Alarm;
- using MECF.Framework.Common.CommonData;
- using MECF.Framework.Common.CommonData.Metal;
- using MECF.Framework.Common.CommonData.PowerSupplier;
- using MECF.Framework.Common.Persistent.Reservoirs;
- using MECF.Framework.Common.RecipeCenter;
- using MECF.Framework.Common.Routine;
- using MECF.Framework.Common.ToolLayout;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- namespace CyberX8_RT.Modules.Metal
- {
- public class ReservoirRunRecipeRoutine : RoutineBase, IRoutine
- {
- #region 常量
- private const int LOTTRACK_TIME = 1000;
- private const string CDA_1_PRESSURE_VALUE = "CDA1Pressure";
- private const string CDA_2_PRESSURE_VALUE = "CDA2Pressure";
- private const string STRATUS = "Stratus";
- #endregion
- private enum RecipeStep
- {
- PlatingDelay,
- PlatingDelayCheck,
- HotPlating,
- WaitPlatingDelay,
- RunPowerStep,
- RunPowerStepWait,
- LoopStart,
- LoopCheckRun,
- LoopEnd,
- StopLinmot,
- StopPowerSuppliers,
- SwitchToNormal,
- WaferHolderUnclampOn,
- End
- }
- #region 常量
- private const string SIDE_A = "SideA";
- private const string SIDE_B = "SideB";
- #endregion
- #region 内部变量
- /// <summary>
- /// recipe
- /// </summary>
- private DepRecipe _recipe;
- /// <summary>
- /// Plate Delay时间
- /// </summary>
- private DateTime _platingDelayTime = DateTime.Now;
- /// <summary>
- /// 启动步骤时间
- /// </summary>
- private DateTime _startStepTime = DateTime.Now;
- /// <summary>
- /// 电量步骤计数
- /// </summary>
- private Stopwatch _stepWatch = new Stopwatch();
- /// <summary>
- /// Power 集合
- /// </summary>
- List<PowerSupplierStepPeriodData> _powerSupplierStepPeriodDatas = new List<PowerSupplierStepPeriodData>();
- /// <summary>
- /// 单面
- /// </summary>
- private string _side;
- /// <summary>
- /// 步骤索引
- /// </summary>
- private int _stepIndex = 0;
- /// <summary>
- /// 设备
- /// </summary>
- private MetalCellDevice _device;
- /// <summary>
- /// 设备Entity
- /// </summary>
- private MetalEntity _metalEntity;
- /// <summary>
- /// A面电量
- /// </summary>
- private double _anodeAUsage;
- /// <summary>
- /// B面电量
- /// </summary>
- private double _anodeBUsage;
- /// <summary>
- /// 是否启动recipe步骤
- /// </summary>
- private bool _startRecipeStep = false;
- /// <summary>
- /// lock track time
- /// </summary>
- private DateTime _lotTackTime = DateTime.Now;
- /// <summary>
- /// LotTrack数据
- /// </summary>
- private List<MetalLotTrackData> _datas = new List<MetalLotTrackData>();
- /// <summary>
- /// LotTrack文件头数据
- /// </summary>
- private LotTrackFileHeaderCommonData _header = new LotTrackFileHeaderCommonData();
- /// <summary>
- /// Facilities
- /// </summary>
- private SystemFacilities _facilities;
- /// <summary>
- /// StandardHot Reservoir Device
- /// </summary>
- private StandardHotReservoirDevice _standardHotReservoirDevice;
- /// <summary>
- /// StandardHot Metal Device
- /// </summary>
- private StandardHotMetalDevice _standardHotMetalDevice;
- /// <summary>
- /// CompactMembran Reservoir Device
- /// </summary>
- private CompactMembranReservoirDevice _compactMembranReservoirDevice;
- /// <summary>
- /// CompactMembran Reservoir Metal
- /// </summary>
- private CompactMembranMetalDevice _compactMembranMetalDevice;
- /// <summary>
- /// MetalType
- /// </summary>
- private string _metalType;
- /// <summary>
- /// TC device
- /// </summary>
- private TemperatureController _temperatureController;
- /// <summary>
- /// Persistent value
- /// </summary>
- private MetalPersistentValue _persistentValue;
- /// <summary>
- /// PlatingDelay计时
- /// </summary>
- private DateTime _hotPlatingRunTime;
- /// <summary>
- /// 是否处于warning状态
- /// </summary>
- private bool _isVotlageWarningA = false;
- private bool _isVotlageWarningB = false;
- private bool _isCurrentWarningA = false;
- private bool _isCurrentWarningB = false;
- private bool _isZeroCurrent = false;
- private int _totalMicrosecond = 0;
- private double _currentHoldoffTime;
- private double _voltageHoldoffTime;
- private double _cellFlowHoldoffTime;
- private HoldoffTimeSignalMonitor _currentHoldoffTimeSignalMonitor;
- private HoldoffTimeSignalMonitor _voltageHoldoffTimeSignalMonitor;
- private HoldoffTimeSignalMonitor _cellFlowHoldoffTimeSignalMonitor;
- #endregion
- #region 属性
- /// <summary>
- /// A面电量
- /// </summary>
- public double AnodeAUsage { get { return _anodeAUsage; } }
- /// <summary>
- /// B面电量
- /// </summary>
- public double AnodeBUsage { get { return _anodeBUsage; } }
- /// <summary>
- /// LotTrack数据
- /// </summary>
- public List<MetalLotTrackData> MetalLotTrackDatas { get { return _datas; } }
- /// <summary>
- /// LotTrack文件头数据
- /// </summary>
- public LotTrackFileHeaderCommonData MetalLotTrackHeaderDatas { get { return _header; } }
- #endregion
- /// <summary>
- /// 构造函数
- /// </summary>
- public ReservoirRunRecipeRoutine(string moduleName) : base(moduleName)
- {
- _currentHoldoffTime = SC.GetValue<double>($"Metal.CurrentAlarmHoldoffTime");
- _voltageHoldoffTime = SC.GetValue<double>($"Metal.VoltageAlarmHoldoffTime");
- _cellFlowHoldoffTime = SC.GetValue<double>($"Metal.CellFlowAlarmHoldoffTime");
- _currentHoldoffTimeSignalMonitor = new HoldoffTimeSignalMonitor(Module, "Current");
- _voltageHoldoffTimeSignalMonitor = new HoldoffTimeSignalMonitor(Module, "Voltage");
- _cellFlowHoldoffTimeSignalMonitor = new HoldoffTimeSignalMonitor(Module, "CellFlow");
- }
- /// <summary>
- /// 中止
- /// </summary>
- public void Abort()
- {
- if (_device != null)
- {
- _device.SideAPowerSupplier.DisableOperation("", null);
- _device.SideBPowerSupplier.DisableOperation("", null);
- _device.SideAPowerSupplier.SwitchPowerRunModel((int)PowerRunModelEnum.Normal);
- _device.SideBPowerSupplier.SwitchPowerRunModel((int)PowerRunModelEnum.Normal);
- if (_device.IsLinmotMotorOn)
- {
- _device.StopLinmot();
- }
- }
- Runner.Stop("Manual Abort");
- }
- /// <summary>
- /// 监控
- /// </summary>
- /// <returns></returns>
- public RState Monitor()
- {
- LottrackRecord();
- Runner.Run(RecipeStep.PlatingDelay, PlatingDelay, _delay_1ms)
- .WaitWithStopCondition(RecipeStep.PlatingDelayCheck, () => { return _device.CheckLinmotRoutineEnd(); }, () => { return _device.CheckLinmotRoutineError(); })
- .RunIf(RecipeStep.HotPlating, _recipe.HotPlatingCurrentOn, HotPlating, _delay_1ms)
- .RunIf(RecipeStep.WaitPlatingDelay, !_recipe.HotPlatingCurrentOn, NullFun, WaitPlatingDelay, _recipe.PlatingDelaySeconds * 1000 + 10000)
- .RunIf(RecipeStep.RunPowerStep, !_recipe.HotPlatingCurrentOn, StartPowerStep, _delay_1ms)
- .WaitWithStopCondition(RecipeStep.RunPowerStepWait, CheckRecipeStepEndStatus, CheckRecipeStepStopStatus, _delay_5s)
- .LoopStart(RecipeStep.LoopStart, "Loop update linmot speed", _powerSupplierStepPeriodDatas.Count, NullFun, _delay_1ms)
- .LoopRunWithStopStatus(RecipeStep.LoopCheckRun, CheckStepComplete, () => { return false; }, 24 * 60 * 60 * 1000)
- .LoopEnd(RecipeStep.LoopEnd, NullFun, _delay_1ms)
- .Run(RecipeStep.StopLinmot, StopLinmot, _delay_1ms)
- .Run(RecipeStep.StopPowerSuppliers, StopPowerSupplier, _delay_1ms)
- .Run(RecipeStep.SwitchToNormal, SwitchToNormal, _delay_1ms)
- .End(RecipeStep.End, NullFun, _delay_1ms);
- return Runner.Status;
- }
- /// <summary>
- /// 记录Lottrack
- /// </summary>
- private void LottrackRecord()
- {
- //记录Lottrack
- if (DateTime.Now.Subtract(_lotTackTime).TotalMilliseconds >= LOTTRACK_TIME)
- {
- AddLotTrackData();
- _lotTackTime = DateTime.Now;
- }
- }
- /// <summary>
- /// 获取Lot Track数据
- /// </summary>
- /// <returns></returns>
- public void AddLotTrackData()
- {
- MetalLotTrackData data = new MetalLotTrackData();
- if (_metalType == STRATUS)
- {
- data.Flow = _standardHotMetalDevice.MetalDeviceData.CellFlow;
- data.ANLevel = 0;
- data.CALevel = _standardHotReservoirDevice.ReservoirData.Level;
- data.CAPumpSpeed = 0;
- }
- else
- {
- data.Flow = _compactMembranMetalDevice.MetalDeviceData.CellFlow;
- data.ANLevel = _compactMembranReservoirDevice.ReservoirData.ANLevel;
- data.CALevel = _compactMembranReservoirDevice.ReservoirData.CALevel;
- data.CAPumpSpeed = _compactMembranReservoirDevice.ReservoirData.CAPumpSpeed;
- }
- data.RunTime = 0;
- data.ClampCycleEngaged = _recipe.CycleClampsEnable;
- data.Temperature = _temperatureController.TemperatureData.ReserviorTemperature;
- data.TimeStamp = DateTime.Now;
- data.PowerSupplyA = _device.SideAPowerSupplier.Name;
- data.PowerSupplyB = _device.SideBPowerSupplier.Name;
- data.PosVoltageA = _device.SideAPowerSupplier.PowerSupplierData.Voltage;
- data.PosCurrentA = _device.SideAPowerSupplier.PowerSupplierData.Current;
- data.PosVoltageB = _device.SideBPowerSupplier.PowerSupplierData.Voltage;
- data.PosCurrentB = _device.SideBPowerSupplier.PowerSupplierData.Current;
- data.CDA_1_Pressure = _facilities.GetCommonLimitDataByName(CDA_1_PRESSURE_VALUE).Value;
- data.CDA_2_Pressure = _facilities.GetCommonLimitDataByName(CDA_2_PRESSURE_VALUE).Value;
- int maxStep = _powerSupplierStepPeriodDatas.Count;
- if (_stepIndex < maxStep)
- {
- data.StepNum = _stepIndex + 1;
- int length = _powerSupplierStepPeriodDatas[_stepIndex].Hour * 3600 + _powerSupplierStepPeriodDatas[_stepIndex].Minute * 60 +
- _powerSupplierStepPeriodDatas[_stepIndex].Second;
- data.DurationRef = length;
- data.ShearPlateSpeed = _recipe.CurrentRampProfileSteps[_stepIndex].ShearPlateSpeed;
- data.CurrentSP = _recipe.CurrentRampProfileSteps[_stepIndex].ForwardAmps;
- }
- else
- {
- data.StepNum = maxStep;
- int length = _powerSupplierStepPeriodDatas[maxStep - 1].Hour * 3600 + _powerSupplierStepPeriodDatas[maxStep - 1].Minute * 60 +
- _powerSupplierStepPeriodDatas[maxStep - 1].Second;
- data.DurationRef = length;
- data.ShearPlateSpeed = _recipe.CurrentRampProfileSteps[maxStep - 1].ShearPlateSpeed;
- data.CurrentSP = _recipe.CurrentRampProfileSteps[maxStep - 1].ForwardAmps;
- }
- RecipeStep step = (RecipeStep)Runner.CurrentStep;
- if (step <= RecipeStep.WaitPlatingDelay)
- {
- if (!_recipe.HotPlatingCurrentOn)
- {
- data.RunTime = DateTime.Now.Subtract(_hotPlatingRunTime).TotalSeconds;
- data.DurationRef = _recipe.PlatingDelaySeconds;
- data.StepNum = 0;
- }
- else
- {
- data.RunTime = 0;
- data.DurationRef = _recipe.PlatingDelaySeconds;
- data.StepNum = 0;
- }
- }
- else
- {
- if (_recipe.HotPlatingCurrentOn)
- {
- if (DateTime.Now.Subtract(_hotPlatingRunTime).TotalSeconds <= _recipe.PlatingDelaySeconds)
- {
- data.RunTime = DateTime.Now.Subtract(_hotPlatingRunTime).TotalSeconds;
- data.DurationRef = _recipe.PlatingDelaySeconds;
- data.StepNum = 0;
- }
- else
- {
- if (data.StepNum == 1) data.DurationRef -= _recipe.PlatingDelaySeconds;
- data.RunTime = (data.StepNum == 1) ? (DateTime.Now.Subtract(_startStepTime).TotalSeconds - _recipe.PlatingDelaySeconds) : DateTime.Now.Subtract(_startStepTime).TotalSeconds;
- }
- }
- else
- {
- data.RunTime = DateTime.Now.Subtract(_startStepTime).TotalSeconds;
- }
- }
- _datas.Add(data);
- }
- /// <summary>
- /// Plate Delay
- /// </summary>
- /// <returns></returns>
- private bool PlatingDelay()
- {
- double speed = _recipe.CurrentRampProfileSteps[0].ShearPlateSpeed;
- bool result = _device.StartCurveMotion((int)speed);
- if (result)
- {
- _platingDelayTime = DateTime.Now;
- if (!_recipe.HotPlatingCurrentOn) _hotPlatingRunTime = DateTime.Now;
- }
- return result;
- }
- /// <summary>
- /// Hot Plating
- /// </summary>
- /// <returns></returns>
- private bool HotPlating()
- {
- UpdateHotPlatingStepDatas();
- return StartPowerStep();
- }
- /// <summary>
- /// 启动PowerSupplier
- /// </summary>
- /// <returns></returns>
- private bool StartPowerStep()
- {
- if (_isZeroCurrent)
- {
- _startStepTime = DateTime.Now;
- return true;
- }
- if (string.IsNullOrEmpty(_side))
- {
- bool result = StartPowerStep(_device.SideAPowerSupplier);
- if (result)
- {
- result = StartPowerStep(_device.SideBPowerSupplier);
- if (!result)
- {
- _device.SideAPowerSupplier.DisableOperation("", null);
- _device.SideBPowerSupplier.DisableOperation("", null);
- return false;
- }
- else
- {
- _startStepTime = DateTime.Now;
- _hotPlatingRunTime = DateTime.Now;
- _stepWatch.Restart();
- _startRecipeStep = true;
- return true;
- }
- }
- else
- {
- _device.SideAPowerSupplier.DisableOperation("", null);
- return false;
- }
- }
- else
- {
- CellPowerSupplier cellPowerSupplier = GetSidePowerSupplier();
- bool result = StartPowerStep(cellPowerSupplier);
- if (!result)
- {
- cellPowerSupplier.DisableOperation("", null);
- _stepWatch.Restart();
- return false;
- }
- _startStepTime = DateTime.Now;
- _hotPlatingRunTime = DateTime.Now;
- _startRecipeStep = true;
- return true;
- }
- }
- /// <summary>
- /// 检验Powerstep是否启动完成
- /// </summary>
- /// <returns></returns>
- private bool CheckRecipeStepEndStatus()
- {
- if (_isZeroCurrent)
- {
- return true;
- }
- if (_startRecipeStep)
- {
- if (string.IsNullOrEmpty(_side))
- {
- bool resultA = _device.SideAPowerSupplier.Status == RState.End;
- bool resultB = _device.SideBPowerSupplier.Status == RState.End;
- return resultA && resultB;
- }
- else
- {
- CellPowerSupplier cellPowerSupplier = GetSidePowerSupplier();
- return cellPowerSupplier.Status == RState.End;
- }
- }
- return true;
- }
- /// <summary>
- /// 检验Powerstep是否启动完成
- /// </summary>
- /// <returns></returns>
- private bool CheckRecipeStepStopStatus()
- {
- if (_isZeroCurrent)
- {
- return false;
- }
- if (_startRecipeStep)
- {
- if (string.IsNullOrEmpty(_side))
- {
- bool resultA = _device.SideAPowerSupplier.Status == RState.Failed || _device.SideAPowerSupplier.Status == RState.Timeout;
- bool resultB = _device.SideBPowerSupplier.Status == RState.Failed || _device.SideBPowerSupplier.Status == RState.Timeout;
- return resultA && resultB;
- }
- else
- {
- CellPowerSupplier cellPowerSupplier = GetSidePowerSupplier();
- return cellPowerSupplier.Status == RState.Failed || cellPowerSupplier.Status == RState.Timeout;
- }
- }
- return false;
- }
- /// <summary>
- /// 获取单面PowerSupplier
- /// </summary>
- /// <returns></returns>
- private CellPowerSupplier GetSidePowerSupplier()
- {
- if (_side == SIDE_A)
- {
- return _device.SideAPowerSupplier;
- }
- else
- {
- return _device.SideBPowerSupplier;
- }
- }
- /// <summary>
- /// 启动
- /// </summary>
- /// <returns></returns>
- private bool StartPowerStep(CellPowerSupplier cellPowerSupplier)
- {
- bool result = cellPowerSupplier.StartSetStepPeriodNoWaitEnd(_powerSupplierStepPeriodDatas);
- if (!result)
- {
- cellPowerSupplier.DisableOperation("", null);
- return false;
- }
- return true;
- }
- /// <summary>
- /// 更新HotPlating step数据
- /// </summary>
- private void UpdateHotPlatingStepDatas()
- {
- ushort second = _powerSupplierStepPeriodDatas[0].Second;
- ushort minute = _powerSupplierStepPeriodDatas[0].Minute;
- ushort hour = _powerSupplierStepPeriodDatas[0].Hour;
- if (second + _recipe.PlatingDelaySeconds >= 60)
- {
- if (minute + 1 < 60)
- {
- _powerSupplierStepPeriodDatas[0].Minute = (ushort)(minute + 1);
- }
- else
- {
- _powerSupplierStepPeriodDatas[0].Minute = 0;
- _powerSupplierStepPeriodDatas[0].Hour = (ushort)(hour + 1);
- }
- _powerSupplierStepPeriodDatas[0].Second = (ushort)(second + _recipe.PlatingDelaySeconds - 60);
- }
- else
- {
- _powerSupplierStepPeriodDatas[0].Second = (ushort)(second + _recipe.PlatingDelaySeconds);
- }
- }
- /// <summary>
- /// 更新Power step步骤
- /// </summary>
- private void UpdatePowerStepDatas()
- {
- _isZeroCurrent = false;
- double current = 0;
- _totalMicrosecond = 0;
- _powerSupplierStepPeriodDatas.Clear();
- foreach (var item in _recipe.CurrentRampProfileSteps)
- {
- PowerSupplierStepPeriodData step = new PowerSupplierStepPeriodData();
- step.Current = item.ForwardAmps;
- step.Hour = (ushort)(item.CurrentRampDurartionSeconds / 3600);
- step.Minute = (ushort)((item.CurrentRampDurartionSeconds - step.Hour * 3600) / 60);
- step.Second = (ushort)(item.CurrentRampDurartionSeconds % 60);
- step.Microsecond = 0;
- step.Voltage = _recipe.VoltageWarningLevel;
- _powerSupplierStepPeriodDatas.Add(step);
- current += step.Current;
- _totalMicrosecond += item.CurrentRampDurartionSeconds * 1000;
- }
- if (current == 0)
- {
- _isZeroCurrent = true;
- }
- }
- /// <summary>
- /// 等待Plating Delay结束
- /// </summary>
- /// <returns></returns>
- private bool WaitPlatingDelay()
- {
- if (DateTime.Now.Subtract(_platingDelayTime).TotalSeconds >= _recipe.PlatingDelaySeconds)
- {
- return true;
- }
- return false;
- }
- /// <summary>
- /// 检验步骤是否完成
- /// </summary>
- /// <returns></returns>
- private bool CheckStepComplete()
- {
- if (_stepIndex >= _powerSupplierStepPeriodDatas.Count)
- {
- _stepWatch.Stop();
- LOG.WriteLog(eEvent.INFO_METAL, Module, $"step {_stepIndex} is over step count {_powerSupplierStepPeriodDatas.Count}");
- return true;
- }
- int firstDelay = 2000;
- if (_stepIndex == 0)
- {
- firstDelay = SC.GetValue<int>("Metal.CurrentCheckDelay") * 1000;
- }
- if (DateTime.Now.Subtract(_startStepTime).TotalMilliseconds >= firstDelay)
- {
- bool abnormal = CheckMetalDisable();
- if (abnormal)
- {
- return false;
- }
- }
- int length = _powerSupplierStepPeriodDatas[_stepIndex].Hour * 3600 + _powerSupplierStepPeriodDatas[_stepIndex].Minute * 60 +
- _powerSupplierStepPeriodDatas[_stepIndex].Second;
- if (DateTime.Now.Subtract(_startStepTime).TotalSeconds >= length)
- {
- _stepIndex++;
- if (_stepIndex >= _powerSupplierStepPeriodDatas.Count)
- {
- _stepWatch.Stop();
- LOG.WriteLog(eEvent.INFO_METAL, Module, $"step {_stepIndex} is over step count {_powerSupplierStepPeriodDatas.Count}");
- return true;
- }
- bool result = _device.ChangeCurveSpeedMotion((int)_recipe.CurrentRampProfileSteps[_stepIndex].ShearPlateSpeed);
- if (result)
- {
- LOG.WriteLog(eEvent.INFO_METAL, Module, $"step {_stepIndex} complete");
- _startStepTime = DateTime.Now;
- }
- return result;
- }
- double second = (double)_stepWatch.ElapsedMilliseconds / 1000;
- if (string.IsNullOrEmpty(_side))
- {
- _anodeAUsage += _device.SideAPowerSupplier.PowerSupplierData.Current * second / 3600;
- _anodeBUsage += _device.SideBPowerSupplier.PowerSupplierData.Current * second / 3600;
- }
- else if (_side == SIDE_A)
- {
- _anodeAUsage += _device.SideAPowerSupplier.PowerSupplierData.Current * second / 3600;
- }
- else
- {
- _anodeBUsage += _device.SideBPowerSupplier.PowerSupplierData.Current * second / 3600;
- }
- _stepWatch.Restart();
- return false;
- }
- /// <summary>
- /// 检验Power是否Disable
- /// </summary>
- /// <returns></returns>
- private bool CheckMetalDisable()
- {
- if (!_device.IsLinmotMotorOn)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, "Linmot is not motor on");
- Abort();
- return true;
- }
- //CheckVotlageAndCurrent();
- if (!CheckVoltageAndCurrentValid())
- {
- Abort();
- return true;
- }
- if (!CheckMetalCellFlow()) //校验Manual 状态下run recipe的 cell flow和hold flow
- {
- Abort();
- return true;
- }
- return false;
- }
- /// <summary>
- /// 监控流量
- /// </summary>
- /// <returns></returns>
- private bool CheckMetalCellFlow()
- {
- MetalEntity metalEntity = Singleton<RouteManager>.Instance.GetModule<MetalEntity>(Module);
- if (metalEntity != null && metalEntity.IsManual)
- {
- MetalItem metalItem = MetalItemManager.Instance.GetMetalItem(Module);
- _metalType = metalItem.SubType;
- if (_metalType == STRATUS)
- {
- StandardHotMetalDevice _standardHotMetalDevice = DEVICE.GetDevice<StandardHotMetalDevice>(Module.ToString());
- //if (_standardHotMetalDevice.MetalDeviceData.CellFlow <= 0)
- //{
- // LOG.WriteLog(eEvent.ERR_METAL, Module.ToString(), $"{Module} metal cell flow is 0");
- // return false;
- //}
- bool cellFlowSignalresulte = _cellFlowHoldoffTimeSignalMonitor.IsSignalAbnormal(_cellFlowHoldoffTime, _standardHotMetalDevice.MetalDeviceData.CellFlow, null, 0);
- if (cellFlowSignalresulte)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module.ToString(), $"{Module} metal cell flow is 0");
- return false;
- }
- }
- }
- return true;
- }
- /// <summary>
- /// 检验电压电流的合理性
- /// </summary>
- /// <returns></returns>
- private bool CheckVoltageAndCurrentValid()
- {
- //零电流不检验
- if (_isZeroCurrent)
- {
- return true;
- }
- if (string.IsNullOrEmpty(_side))
- {
- if (!_device.SideAPowerSupplier.PowerSupplierData.Enabled)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, "PowerA disable");
- return false;
- }
- if (!_device.SideBPowerSupplier.PowerSupplierData.Enabled)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, "PowerB disable");
- return false;
- }
- }
- else
- {
- if (_side == SIDE_A && !_device.SideAPowerSupplier.PowerSupplierData.Enabled)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, "PowerA disable");
- return false;
- }
- if (_side == SIDE_B && !_device.SideBPowerSupplier.PowerSupplierData.Enabled)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, "PowerB disable");
- return false;
- }
- }
- double sideACurrent = _device.SideAPowerSupplier.PowerSupplierData.Current;
- double sideAVoltage = _device.SideAPowerSupplier.PowerSupplierData.Voltage;
- double sideBCurrent = _device.SideBPowerSupplier.PowerSupplierData.Current;
- double sideBVoltage = _device.SideBPowerSupplier.PowerSupplierData.Voltage;
- if (string.IsNullOrEmpty(_side))
- {
- bool sideAValid = CheckSidePowerInvalid(sideACurrent, sideAVoltage, SIDE_A);
- if (sideAValid)
- {
- return false;
- }
- bool sideBValid = CheckSidePowerInvalid(sideBCurrent, sideBVoltage, SIDE_B);
- if (sideBValid)
- {
- return false;
- }
- }
- else
- {
- if (_side == SIDE_A)
- {
- bool sideAValid = CheckSidePowerInvalid(sideACurrent, sideAVoltage, SIDE_A);
- if (sideAValid)
- {
- return false;
- }
- }
- else
- {
- bool sideBValid = CheckSidePowerInvalid(sideBCurrent, sideBVoltage, SIDE_B);
- if (sideBValid)
- {
- return false;
- }
- }
- }
- return true;
- }
- /// <summary>
- /// 检验电流和电压合理性
- /// </summary>
- /// <param name="current"></param>
- /// <param name="voltage"></param>
- /// <param name="side"></param>
- /// <returns></returns>
- private bool CheckSidePowerInvalid(double current, double voltage, string side)
- {
- double maxVoltage = _recipe.VolatageLimitMax;
- double warnVoltage = _recipe.VoltageWarningLevel;
- double minVoltage = _recipe.VolatageLimitMin;
- //if (voltage > maxVoltage)
- //{
- // LOG.WriteLog(eEvent.ERR_METAL, Module, $"{side} voltage {voltage} is large than recipe max voltage {maxVoltage}");
- // return true;
- //}
- //if (voltage < minVoltage)
- //{
- // LOG.WriteLog(eEvent.ERR_METAL, Module, $"{side} voltage {voltage} is less than recipe min voltage {minVoltage}");
- // return true;
- //}
- bool voltageSignalresulte = _voltageHoldoffTimeSignalMonitor.IsSignalAbnormal(_voltageHoldoffTime, voltage, maxVoltage, minVoltage);
- if (voltageSignalresulte)
- {
- if (voltage > maxVoltage)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"{side} voltage {voltage} is large than recipe max voltage {maxVoltage}");
- }
- if (voltage < minVoltage)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"{side} voltage {voltage} is less than recipe min voltage {minVoltage}");
- }
- return true;
- }
- if (voltage > warnVoltage)
- {
- string str = $"{side} voltage is {voltage} in warning";
- if (AlarmListManager.Instance.AddWarn(Module, $"{side} voltage", str))
- {
- LOG.WriteLog(eEvent.WARN_PREWET, Module, str);
- }
- }
- double maxErrorCurrent = _powerSupplierStepPeriodDatas[_stepIndex].Current * (double)(1 + _recipe.FaultPercent * 0.01);
- double minErrorCurrent = _powerSupplierStepPeriodDatas[_stepIndex].Current * (double)(1 - _recipe.FaultPercent * 0.01);
- double maxWarnCurrent = _powerSupplierStepPeriodDatas[_stepIndex].Current * (double)(1 + _recipe.CurrentWarningLevel * 0.01);
- double minWarnCurrent = _powerSupplierStepPeriodDatas[_stepIndex].Current * (double)(1 - _recipe.CurrentWarningLevel * 0.01);
- //if (current > maxErrorCurrent)
- //{
- // LOG.WriteLog(eEvent.ERR_METAL, Module, $"{side} current {current} is large than recipe max current {maxErrorCurrent}");
- // return true;
- //}
- //if (current < minErrorCurrent)
- //{
- // LOG.WriteLog(eEvent.ERR_METAL, Module, $"{side} current {current} is less than recipe min current {minErrorCurrent}");
- // return true;
- //}
- bool currentSignalresulte = _currentHoldoffTimeSignalMonitor.IsSignalAbnormal(_currentHoldoffTime, current, maxErrorCurrent, minErrorCurrent);
- if (currentSignalresulte)
- {
- if (current > maxErrorCurrent)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"{side} current {current} is large than recipe max current {maxErrorCurrent}");
- }
- if (current < minErrorCurrent)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"{side} current {current} is less than recipe min current {minErrorCurrent}");
- }
- return true;
- }
- if ((current <= maxErrorCurrent && current >= maxWarnCurrent) || (current >= minErrorCurrent && current <= minWarnCurrent))
- {
- string str = $"{side} current {current} is in warning";
- if (AlarmListManager.Instance.AddWarn(Module, $"{side} current", str))
- {
- LOG.WriteLog(eEvent.WARN_PREWET, Module, str);
- }
- }
- return false;
- }
- /// <summary>
- /// 停止Linmot
- /// </summary>
- /// <returns></returns>
- private bool StopLinmot()
- {
- return _device.StopLinmot();
- }
- /// <summary>
- /// 停止电源
- /// </summary>
- /// <returns></returns>
- private bool StopPowerSupplier()
- {
- if (string.IsNullOrEmpty(_side))
- {
- _device.SideAPowerSupplier.DisableOperation("", null);
- _device.SideBPowerSupplier.DisableOperation("", null);
- }
- else
- {
- CellPowerSupplier cellPowerSupplier = GetSidePowerSupplier();
- cellPowerSupplier.DisableOperation("", null);
- }
- return true;
- }
- /// <summary>
- /// 切换成正常模式
- /// </summary>
- /// <returns></returns>
- private bool SwitchToNormal()
- {
- if (string.IsNullOrEmpty(_side))
- {
- _device.SideAPowerSupplier.SwitchPowerRunModel((int)PowerRunModelEnum.Normal);
- _device.SideBPowerSupplier.SwitchPowerRunModel((int)PowerRunModelEnum.Normal);
- }
- else
- {
- CellPowerSupplier cellPowerSupplier = GetSidePowerSupplier();
- cellPowerSupplier.SwitchPowerRunModel((int)PowerRunModelEnum.Normal);
- }
- return true;
- }
- /// <summary>
- /// 启动
- /// </summary>
- /// <param name="objs"></param>
- /// <returns></returns>
- public RState Start(params object[] objs)
- {
- _isVotlageWarningA = false;
- _isVotlageWarningB = false;
- _isCurrentWarningA = false;
- _isCurrentWarningB = false;
- _recipe = objs[0] as DepRecipe;
- if (_recipe == null)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, "recipe is null");
- return RState.Failed;
- }
- if (objs.Length > 1)
- {
- _side = objs[1].ToString();
- }
- _startRecipeStep = false;
- _anodeAUsage = 0;
- _anodeBUsage = 0;
- _device = DEVICE.GetDevice<MetalCellDevice>(Module);
- _metalEntity = Singleton<RouteManager>.Instance.GetModule<MetalEntity>(Module);
- UpdatePowerStepDatas();
- _stepIndex = 0;
- _header.SoftWareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
- _header.Recipe = $"{_recipe.Ppid}.dep.rcp";
- if (SC.ContainsItem("System.ToolID")) _header.ToolID = SC.GetStringValue("System.ToolID");
- //lotTract记录SequenceRecipe
- MetalEntity metalEntity = Singleton<RouteManager>.Instance.GetModule<MetalEntity>(Module);
- if (metalEntity.WaferHolderInfo != null && metalEntity.WaferHolderInfo.SequenceRecipe != null && !String.IsNullOrEmpty(metalEntity.WaferHolderInfo.SequenceRecipe.Ppid.ToString()))
- {
- _header.SequenceRecipe = metalEntity.WaferHolderInfo.SequenceRecipe.Ppid.ToString();
- _header.ProcessTransferList = new List<string>();
- _header.ProcessTransferList.AddRange(metalEntity.WaferHolderInfo.SchedulerModules);
- metalEntity.WaferHolderInfo.SchedulerModules.Clear();
- }
- _facilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
- if (_facilities == null)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, "Facility is null");
- return RState.Failed;
- }
- string reservoirName = ReservoirItemManager.Instance.GetReservoirByMetal(Module);
- MetalItem metalItem = MetalItemManager.Instance.GetMetalItem(Module);
- _metalType = metalItem.SubType;
- if (_metalType == STRATUS)
- {
- _standardHotReservoirDevice = DEVICE.GetDevice<StandardHotReservoirDevice>(reservoirName);
- _standardHotMetalDevice = DEVICE.GetDevice<StandardHotMetalDevice>(Module);
- if (_standardHotReservoirDevice == null || _standardHotMetalDevice == null)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"metal or reservoir device is null");
- return RState.Failed;
- }
- if (_standardHotMetalDevice.MetalDeviceData.CellFlow <= 0) //检查cell flow
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"reservoir metal cell flow is 0");
- return RState.Failed;
- }
- }
- else
- {
- _compactMembranReservoirDevice = DEVICE.GetDevice<CompactMembranReservoirDevice>(reservoirName);
- _compactMembranMetalDevice = DEVICE.GetDevice<CompactMembranMetalDevice>(Module);
- if (_compactMembranMetalDevice == null || _compactMembranReservoirDevice == null)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"metal or reservoir device is null");
- return RState.Failed;
- }
- if (_compactMembranMetalDevice.MetalDeviceData.CellFlow <= 0) //检查cell flow
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"reservoir metal cell flow is 0");
- return RState.Failed;
- }
- if (_compactMembranMetalDevice.ANACellFlow.CounterValue <= 0) //检查hold flow
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"reservoir metal AnodeA flow is 0");
- return RState.Failed;
- }
- if (_compactMembranMetalDevice.ANBCellFlow.CounterValue <= 0)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"reservoir metal AnodeB flow is 0");
- return RState.Failed;
- }
- }
- ReservoirItem reservoirItem = ReservoirItemManager.Instance.GetReservoirItem(reservoirName);
- _temperatureController = DEVICE.GetDevice<TemperatureController>(reservoirItem.TCID);
- if (_temperatureController == null)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"Temperature controller is null");
- return RState.Failed;
- }
- _persistentValue = MetalPersistentManager.Instance.GetMetalPersistentValue(Module);
- if (_persistentValue == null)
- {
- LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} Persistent Value Object is not exist");
- return RState.Failed;
- }
- _lotTackTime = DateTime.Now;
- return Runner.Start(Module, "Metal run recipe");
- }
- public void clearLotTrack()
- {
- _datas.Clear();
- }
- public void resetMetalUsage()
- {
- _anodeAUsage = 0;
- _anodeBUsage = 0;
- }
- }
- }
|