using System; using System.Collections.Generic; using System.Data; using System.Linq; using Aitex.Core.Common; using Aitex.Core.RT.DBCore; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.Util; using MECF.Framework.Common.CommonData.EnumData; using MECF.Framework.Common.DBCore; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.Common.Utilities; namespace MECF.Framework.Common.DataCenter { public class ScheduleMaintenanceData { public ScheduleMaintenanceDataItem DataItem { get; private set; } public ScheduleMaintenanceData(string item, string display, string unit, float startValue, float limitValue, string maintenanceProcessing, string path, string additionInformationName = "", string additionInformationDisplay = "", string associationProcessRecipeName = "") { ScheduleMaintenanceDataManager.Instance.Subscribe(item, display, unit, startValue, limitValue, maintenanceProcessing, path, additionInformationName, additionInformationDisplay, associationProcessRecipeName); DataItem = ScheduleMaintenanceDataManager.Instance.GetItem(item); } public float SetLimitValue(float value) { return ScheduleMaintenanceDataManager.Instance.SetLimitValue(DataItem.Item, value); } public string SetMaintenanceProcessing(string value) { return ScheduleMaintenanceDataManager.Instance.SetMaintenanceProcessing(DataItem.Item, value); } public void SetValue(float value) { ScheduleMaintenanceDataManager.Instance.SetValue(DataItem.Item, value); } public void SetStartValue(float value) { ScheduleMaintenanceDataManager.Instance.SetStartValue(DataItem.Item, value); } public float GetValue() { return ScheduleMaintenanceDataManager.Instance.GetValue(DataItem.Item); } public float Increase(float additionValue = 1) { return ScheduleMaintenanceDataManager.Instance.Increase(DataItem.Item, additionValue); } } public class ScheduleMaintenanceDataItem { public string Unit { get; set; } public string Item { get; set; } public float CurrentValue { get; set; } public float StartValue { get; set; } public float LimitValue { get; set; } public string MaintenanceProcessing { get; set; } public string AssociationProcessRecipeName { get; set; } public string Display { get; set; } public string Path { get; set; } public string AdditionInformationName { get; set; } public string AdditionInformationDisplay { get; set; } } public class ScheduleMaintenanceDataManager : Singleton { private Dictionary _items = new Dictionary(); public Dictionary Item { get => _items; } private object _locker = new object(); public ScheduleMaintenanceDataManager() { } public void Initialize() { try { OP.Subscribe("System.ScheduleMaintenance.SetCurrentValue", (method, args) => { float.TryParse(args[1].ToString(), out float value); SetValue((string)args[0], value); return true; }); OP.Subscribe("System.ScheduleMaintenance.SetMaintenanceName", (method, args) => { SetMaintenanceName((string)args[0], args[1].ToString()); return true; }); OP.Subscribe("System.ScheduleMaintenance.SetMaintenanceProcessing", (method, args) => { SetMaintenanceProcessing((string)args[0], args[1].ToString()); return true; }); OP.Subscribe("System.ScheduleMaintenance.SetAssociationProcessRecipeName", (method, args) => { SetAssociationProcessRecipeName((string)args[0], args[1].ToString()); return true; }); OP.Subscribe("System.ScheduleMaintenance.SetLimitValue", (method, args) => { float.TryParse(args[1].ToString(), out float value); SetLimitValue((string)args[0], value); return true; }); OP.Subscribe("System.ScheduleMaintenance.SetStartValue", (method, args) => { float.TryParse(args[1].ToString(), out float value); SetStartValue((string)args[0], value); return true; }); OP.Subscribe("System.ScheduleMaintenance.SetAdditionInformationDisplayName", (method, args) => { SetMaintenanceName((string)args[0], args[1].ToString()); return true; }); DataTable dt = DataQuery.Query("select * from \"schedule_maintenance\""); for (int i = 0; i < dt.Rows.Count; i++) { ScheduleMaintenanceDataItem item = new ScheduleMaintenanceDataItem(); item.Item = dt.Rows[i]["maintenance_item"].ToString(); item.Display = dt.Rows[i]["maintenance_display"].ToString(); item.Unit = dt.Rows[i]["unit"].ToString(); item.MaintenanceProcessing = dt.Rows[i]["maintenance_processing"].ToString(); item.Path = dt.Rows[i]["path"].ToString(); item.AdditionInformationName = dt.Rows[i]["addition_information_name"].ToString(); item.AdditionInformationDisplay = dt.Rows[i]["addition_information_display"].ToString(); item.AssociationProcessRecipeName = dt.Rows[i]["association_process_recipeName"].ToString(); if (float.TryParse(dt.Rows[i]["current_value"].ToString(), out float value)) item.CurrentValue = value; if (float.TryParse(dt.Rows[i]["scheduling_start_value"].ToString(), out value)) item.StartValue = value; if (float.TryParse(dt.Rows[i]["maintenance_limit_value"].ToString(), out value)) item.LimitValue = value; _items[item.Item] = item; } InitScheduleMaintenance(); UpdateSEDWafer(); } catch (Exception ex) { LOG.Error("init stats data manager failed", ex); } } public string SetMaintenanceName(string name, string display) { lock (_locker) { if (!_items.ContainsKey(name)) { LOG.Error($"Can not set {name} maintenanceName value, not defined item"); return ""; } string preValue = _items[name].Display; _items[name].Display = display; string sql = string.Format( "UPDATE \"schedule_maintenance\" SET \"maintenance_display\"='{0}'WHERE \"maintenance_item\"='{1}';", display, name); DB.Insert(sql); EV.PostInfoLog("System", $"{name} schedule maintenance maintenanceName value changed from {preValue} to {display}"); return display; } } public string SetAdditionInformationDisplayName(string name, string display) { lock (_locker) { if (!_items.ContainsKey(name)) { LOG.Error($"Can not set {name} AdditionInformationDispla value, not defined item"); return ""; } string preValue = _items[name].AdditionInformationDisplay; _items[name].AdditionInformationDisplay = display; string sql = string.Format( "UPDATE \"schedule_maintenance\" SET \"addition_information_display\"='{0}'WHERE \"maintenance_item\"='{1}';", display, name); DB.Insert(sql); EV.PostInfoLog("System", $"{name} schedule maintenance AdditionInformationDisplay value changed from {preValue} to {display}"); return display; } } public string SetAssociationProcessRecipeName(string name, string associationProcessRecipeName) { lock (_locker) { if (!_items.ContainsKey(name)) { LOG.Error($"Can not set {name} associationProcessRecipeName value, not defined item"); return ""; } string preValue = _items[name].AssociationProcessRecipeName; _items[name].AssociationProcessRecipeName = associationProcessRecipeName; string sql = string.Format( "UPDATE \"schedule_maintenance\" SET \"association_process_recipeName\"='{0}'WHERE \"maintenance_item\"='{1}';", associationProcessRecipeName, name); DB.Insert(sql); EV.PostInfoLog("System", $"{name} schedule maintenance associationProcessRecipeName value changed from {preValue} to {associationProcessRecipeName}"); return associationProcessRecipeName; } } public string SetMaintenanceProcessing(string name, string maintenanceProcessing) { lock (_locker) { if (!_items.ContainsKey(name)) { LOG.Error($"Can not set {name} maintenanceProcessing value, not defined item"); return ""; } string preValue = _items[name].MaintenanceProcessing; _items[name].MaintenanceProcessing = maintenanceProcessing; string sql = string.Format( "UPDATE \"schedule_maintenance\" SET \"maintenance_processing\"='{0}'WHERE \"maintenance_item\"='{1}';", maintenanceProcessing, name); DB.Insert(sql); EV.PostInfoLog("System", $"{name} schedule maintenance MaintenanceProcessing value changed from {preValue} to {maintenanceProcessing}"); return maintenanceProcessing; } } public float SetLimitValue(string name, float value) { lock (_locker) { if (!_items.ContainsKey(name)) { LOG.Error($"Can not set {name} limit value, not defined item"); return -1; } float preValue = _items[name].LimitValue; _items[name].LimitValue = value; string sql = string.Format( "UPDATE \"schedule_maintenance\" SET \"maintenance_limit_value\"='{0}'WHERE \"maintenance_item\"='{1}';", _items[name].LimitValue, name); DB.Insert(sql); EV.PostInfoLog("System", $"{name} schedule maintenance limit value changed from {preValue} to {value}"); return preValue; } } public void Terminate() { } public void Subscribe(string item, string display, string unit, float startValue, float limitValue, string maintenanceProcessing, string path, string additionInformationName, string additionInformationDisplay, string associationProcessRecipeName) { lock (_locker) { if (!_items.ContainsKey(item)) { _items[item] = new ScheduleMaintenanceDataItem() { Display = display, Item = item }; string executeInsert = string.Format( @"Insert into ""schedule_maintenance""(""maintenance_item"", ""maintenance_display"", ""scheduling_start_value"", ""maintenance_limit_value"", ""maintenance_processing"", ""unit"", ""path"", ""addition_information_name"", ""addition_information_display"" ""association_process_recipeName"" ) values('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}')", item, display, startValue, limitValue, maintenanceProcessing, unit, path, additionInformationName, additionInformationDisplay, associationProcessRecipeName); DB.Insert(executeInsert); } } } public void SetValue(string name, float value) { lock (_locker) { if (!_items.ContainsKey(name)) { LOG.Error($"Can not set {name} value, not defined item"); return; } _items[name].CurrentValue = value; string sql = string.Format( "UPDATE \"schedule_maintenance\" SET \"current_value\"='{0}' WHERE \"maintenance_item\"='{1}';", _items[name].CurrentValue, name); DB.Insert(sql); } } public void SetStartValue(string name, float value) { lock (_locker) { if (!_items.ContainsKey(name)) { LOG.Error($"Can not set {name} scheduling_start_value, not defined item"); return; } _items[name].StartValue = value; string sql = string.Format( "UPDATE \"schedule_maintenance\" SET \"scheduling_start_value\"='{0}' WHERE \"maintenance_item\"='{1}';", _items[name].StartValue, name); DB.Insert(sql); } } public float GetValue(string name) { lock (_locker) { if (_items.ContainsKey(name)) { return _items[name].CurrentValue; } } LOG.Error($"Can not get {name} value, not defined item"); return 0; } public ScheduleMaintenanceDataItem GetItem(string name) { lock (_locker) { if (_items.ContainsKey(name)) { return _items[name]; } } LOG.Error($"Can not get {name} value, not defined item"); return null; } public bool CheckHasItem(string name) { if (_items.ContainsKey(name)) return true; else return false; } public float Increase(string name, float additionValue = 1) { lock (_locker) { if (!_items.ContainsKey(name)) { LOG.Error($"Can not increase {name} value, not defined item"); return -1; } _items[name].CurrentValue += additionValue; string sql = string.Format( "UPDATE \"schedule_maintenance\" SET \"current_value\"='{0}' WHERE \"maintenance_item\"='{1}';", _items[name].CurrentValue, name); DB.Insert(sql); return _items[name].CurrentValue; } } #region private Dictionary _stepThickness; private Dictionary _scheduleMaintenanceDataDictionary; private void InitScheduleMaintenance() { _scheduleMaintenanceDataDictionary = new Dictionary { { MaintenanceItemEnum.SDCarrierUseFreq, new ScheduleMaintenanceData(MaintenanceItemEnum.SDCarrierUseFreq.ToString(),"SDCarrierUseFreq", "Times", 0, 0, "None", "CarrierWafer.SieDummy", "Carrier Kind", "Side Dummy") }, { MaintenanceItemEnum.SDWaferThickness, new ScheduleMaintenanceData(MaintenanceItemEnum.SDWaferThickness.ToString(), "SDWaferThickness", "Å", 0, 0, "None", "CarrierWafer.SieDummy", "Carrier Kind", "Side Dummy") }, { MaintenanceItemEnum.SDUsableDummyWafer, new ScheduleMaintenanceData(MaintenanceItemEnum.SDUsableDummyWafer.ToString(), "SDWaferRemain", "Sheets", 0, 0, "None", "CarrierWafer.SieDummy", "Carrier Kind", "Side Dummy") }, { MaintenanceItemEnum.SDBufferRackStayTime, new ScheduleMaintenanceData(MaintenanceItemEnum.SDBufferRackStayTime.ToString(), "SDCarrierStay", "h:m", 0, 0, "None", "CarrierWafer.SieDummy", "Carrier Kind", "Side Dummy") }, { MaintenanceItemEnum.SDWaferUserTime, new ScheduleMaintenanceData(MaintenanceItemEnum.SDWaferUserTime.ToString(), "SDWaferUserTime", "h:m", 0, 0, "None", "CarrierWafer.SieDummy", "Carrier Kind", "Side Dummy") }, { MaintenanceItemEnum.FDCarrierUseFreq, new ScheduleMaintenanceData(MaintenanceItemEnum.FDCarrierUseFreq.ToString(),"FDCarrierUseFreq", "Times", 0, 0, "None", "CarrierWafer.FillDummy", "Carrier Kind", "Fill Dummy") }, { MaintenanceItemEnum.FDWaferThickness, new ScheduleMaintenanceData(MaintenanceItemEnum.FDWaferThickness.ToString(),"FDWaferThickness", "Å", 0, 0, "None", "CarrierWafer.FillDummy", "Carrier Kind", "Fill Dummy") }, { MaintenanceItemEnum.FDUsableDummyWafer, new ScheduleMaintenanceData(MaintenanceItemEnum.FDUsableDummyWafer.ToString(),"FDWaferRemain", "Sheets", 0, 0, "None", "CarrierWafer.FillDummy", "Carrier Kind", "Fill Dummy") }, { MaintenanceItemEnum.FDBufferRackStayTime, new ScheduleMaintenanceData(MaintenanceItemEnum.FDBufferRackStayTime.ToString(), "FDCarrierStay", "h:m", 0, 0, "None", "CarrierWafer.FillDummy", "Carrier Kind", "Fill Dummy") }, { MaintenanceItemEnum.FDWaferUserTime, new ScheduleMaintenanceData(MaintenanceItemEnum.FDWaferUserTime.ToString(), "FDWaferUserTime", "h:m", 0, 0, "None", "CarrierWafer.FillDummy", "Carrier Kind", "Fill Dummy") }, { MaintenanceItemEnum.OnBoatDummyWaferUse, new ScheduleMaintenanceData(MaintenanceItemEnum.OnBoatDummyWaferUse.ToString(),"OnBoatDummyWaferUse", "Times", 0, 0, "None", "Boat", "", "") }, { MaintenanceItemEnum.OnBoatDummyWaferThick, new ScheduleMaintenanceData(MaintenanceItemEnum.OnBoatDummyWaferThick.ToString(), "OnBoatDummyWaferThick", "Å", 0, 0, "None", "Boat", "", "") }, { MaintenanceItemEnum.BoatRecipeThickness1, new ScheduleMaintenanceData(MaintenanceItemEnum.BoatRecipeThickness1.ToString(), "BoatRecipeThickness1", "Å", 0, 0, "None", "Boat", "", "") }, { MaintenanceItemEnum.BoatRecipeThickness2, new ScheduleMaintenanceData(MaintenanceItemEnum.BoatRecipeThickness2.ToString(), "BoatRecipeThickness2", "Å", 0, 0, "None", "Boat", "", "") }, { MaintenanceItemEnum.BoatRecipeThickness3, new ScheduleMaintenanceData(MaintenanceItemEnum.BoatRecipeThickness3.ToString(), "BoatRecipeThickness3", "Å", 0, 0, "None", "Boat", "", "") }, { MaintenanceItemEnum.NonOperationTime1, new ScheduleMaintenanceData(MaintenanceItemEnum.NonOperationTime1.ToString(), "NonOperationTime1", "h:m", 0, 0, "None", "Conditioning", "", "") }, { MaintenanceItemEnum.NonOperationTime2, new ScheduleMaintenanceData(MaintenanceItemEnum.NonOperationTime2.ToString(), "NonOperationTime2", "h:m", 0, 0, "None", "Conditioning", "", "") }, { MaintenanceItemEnum.RecipeExecuteFreq, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeExecuteFreq.ToString(), "Recipe Run Freq", "Times", 0, 0, "None", "Reactor.Recipe", "", "") }, { MaintenanceItemEnum.RecipeThickness, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeThickness.ToString(), "Recipe Thickness", "Å", 0, 0, "None", "Reactor.Recipe", "", "") }, { MaintenanceItemEnum.RecipeStepExecuteFreq1, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeStepExecuteFreq1.ToString(), "Recipe StepRunTime1", "Times", 0, 0, "None", "Reactor.StepRunFreq", "Step ID", "") }, { MaintenanceItemEnum.RecipeStepExecuteFreq2, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeStepExecuteFreq2.ToString(), "Recipe StepRunTime2", "Times", 0, 0, "None", "Reactor.StepRunFreq", "Step ID", "") }, { MaintenanceItemEnum.RecipeStepExecuteFreq3, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeStepExecuteFreq3.ToString(), "Recipe StepRunTime3", "Times", 0, 0, "None", "Reactor.StepRunFreq", "Step ID", "") }, { MaintenanceItemEnum.RecipeStepExecuteTime1, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeStepExecuteTime1.ToString(), "Recipe StepRunTime1", "h:m", 0, 0, "None", "Reactor.StepRunTime", "Step ID", "") }, { MaintenanceItemEnum.RecipeStepExecuteTime2, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeStepExecuteTime2.ToString(), "Recipe StepRunTime2", "h:m", 0, 0, "None", "Reactor.StepRunTime", "Step ID", "") }, { MaintenanceItemEnum.RecipeStepExecuteTime3, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeStepExecuteTime3.ToString(), "Recipe StepRunTime3", "h:m", 0, 0, "None", "Reactor.StepRunTime", "Step ID", "") }, { MaintenanceItemEnum.RecipeStepExecuteTime4, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeStepExecuteTime4.ToString(), "Recipe StepRunTime4", "h:m", 0, 0, "None", "Reactor.StepRunTime", "Step ID", "") }, { MaintenanceItemEnum.RecipeStepExecuteTime5, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeStepExecuteTime5.ToString(), "Recipe StepRunTime5", "h:m", 0, 0, "None", "Reactor.StepRunTime", "Step ID", "") }, { MaintenanceItemEnum.RecipeStepExecuteTime6, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeStepExecuteTime6.ToString(), "Recipe StepRunTime6", "h:m", 0, 0, "None", "Reactor.StepRunTime", "Step ID", "") }, { MaintenanceItemEnum.RecipeStepExecuteTime7, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeStepExecuteTime7.ToString(), "Recipe StepRunTime7", "h:m", 0, 0, "None", "Reactor.StepRunTime", "Step ID", "") }, { MaintenanceItemEnum.RecipeStepExecuteTime8, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeStepExecuteTime8.ToString(), "Recipe StepRunTime8", "h:m", 0, 0, "None", "Reactor.StepRunTime", "Step ID", "") }, { MaintenanceItemEnum.RecipeThickness1_Step, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeThickness1_Step.ToString(), "Recipe StepThickness1", "Å", 0, 0, "None", "Reactor.StepThickness", "Step Group", "Group 1") }, { MaintenanceItemEnum.RecipeThickness2_Step, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeThickness2_Step.ToString(), "Recipe StepThickness2", "Å", 0, 0, "None", "Reactor.StepThickness", "Step Group", "Group 2") }, { MaintenanceItemEnum.RecipeThickness3_Step, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeThickness3_Step.ToString(), "Recipe StepThickness3", "Å", 0, 0, "None", "Reactor.StepThickness", "Step Group", "Group 3") }, { MaintenanceItemEnum.RecipeThickness4_Step, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeThickness4_Step.ToString(), "Recipe StepThickness4", "Å", 0, 0, "None", "Reactor.StepThickness", "Step Group", "Group 4") }, { MaintenanceItemEnum.RecipeThickness5_Step, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeThickness5_Step.ToString(), "Recipe StepThickness5", "Å", 0, 0, "None", "Reactor.StepThickness", "Step Group", "Group 5") }, { MaintenanceItemEnum.RecipeThickness6_Step, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeThickness6_Step.ToString(), "Recipe StepThickness6", "Å", 0, 0, "None", "Reactor.StepThickness", "Step Group", "Group 6") }, { MaintenanceItemEnum.RecipeThickness7_Step, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeThickness7_Step.ToString(), "Recipe StepThickness7", "Å", 0, 0, "None", "Reactor.StepThickness", "Step Group", "Group 7") }, { MaintenanceItemEnum.RecipeThickness8_Step, new ScheduleMaintenanceData(MaintenanceItemEnum.RecipeThickness8_Step.ToString(), "Recipe StepThickness8", "Å", 0, 0, "None", "Reactor.StepThickness", "Step Group", "Group 8") } }; _stepThickness = new Dictionary() { {"1","WAIT"}, {"2","Name"}, }; } public void UpdateRecipeTotalThickness(string recipeName, float thickness) { } public void UpdateRecipeStepThicknessAndTime(string stepName, float thickness, float timeS) { if (string.IsNullOrEmpty(stepName)) return; var checkName = stepName; var nameParas = stepName.Split(':'); if (nameParas != null && nameParas.Length > 1) checkName = nameParas[1]; } public bool CheckScheduleMaintenanceBeforeJobStart(out string reason) { reason = ""; return true; } public ScheduleMaintenanceData GetScheduleMaintenanceData(MaintenanceItemEnum MaintenanceItemEnum) { _scheduleMaintenanceDataDictionary.TryGetValue(MaintenanceItemEnum, out var data); return data; } public void MaintenanceProcessingCommandExec(string maintenanceProcessing, Action alarmReportExec, string warningMessage) { if (Enum.TryParse(maintenanceProcessing, out var command)) { switch (command) { case MaintenanceProcessingCommandEnum.None: break; case MaintenanceProcessingCommandEnum.AlarmReport: alarmReportExec(warningMessage); break; case MaintenanceProcessingCommandEnum.JobProhibition: break; case MaintenanceProcessingCommandEnum.JobManualStart: break; case MaintenanceProcessingCommandEnum.JobAutoStart: break; } } } public void UpdateSEDWafer() { var ccc = BinarySerializer>>.FromStream("WaferManager"); List waferInfos = new List(); if (ccc != null) { foreach (var moduleWafers in ccc) { waferInfos.AddRange(moduleWafers.Value.Select(a => a.Value)); } if (waferInfos.Any(a => a.WaferType == WaferType.ED)) { var maxEDUseCount = waferInfos.Where(a => a.WaferType == WaferType.ED).Max(a => a.UseCount); var maxEDUseThick = waferInfos.Where(a => a.WaferType == WaferType.ED).Max(a => a.UseThick); var maxEDUseTime = waferInfos.Where(a => a.WaferType == WaferType.ED).Max(a => a.UseTime); if (_scheduleMaintenanceDataDictionary.TryGetValue(MaintenanceItemEnum.FDCarrierUseFreq, out var FDCarrierUseFreq)) FDCarrierUseFreq.SetValue(maxEDUseCount); if (_scheduleMaintenanceDataDictionary.TryGetValue(MaintenanceItemEnum.FDWaferThickness, out var FDWaferThickness)) FDWaferThickness.SetValue(maxEDUseThick); if (_scheduleMaintenanceDataDictionary.TryGetValue(MaintenanceItemEnum.FDWaferUserTime, out var FDWaferUserTime)) FDWaferUserTime.SetValue(maxEDUseTime); } if (waferInfos.Any(a => a.WaferType == WaferType.SD)) { var maxSDUseCount = waferInfos.Where(a => a.WaferType == WaferType.SD).Max(a => a.UseCount); var maxSDUseThick = waferInfos.Where(a => a.WaferType == WaferType.SD).Max(a => a.UseThick); var maxSDUseTime = waferInfos.Where(a => a.WaferType == WaferType.SD).Max(a => a.UseTime); if (_scheduleMaintenanceDataDictionary.TryGetValue(MaintenanceItemEnum.SDCarrierUseFreq, out var SDCarrierUseFreq)) SDCarrierUseFreq.SetValue(maxSDUseCount); if (_scheduleMaintenanceDataDictionary.TryGetValue(MaintenanceItemEnum.SDWaferThickness, out var SDWaferThickness)) SDWaferThickness.SetValue(maxSDUseThick); if (_scheduleMaintenanceDataDictionary.TryGetValue(MaintenanceItemEnum.SDWaferUserTime, out var SDWaferUserTime)) SDWaferUserTime.SetValue(maxSDUseTime); } // var data = ccc.Select(a => a.Value.Select(e=>e.Value)).ToList(); } } #endregion } }