using Aitex.Common.Util; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Event; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.UI.Control; using Aitex.Core.Util; using FurnaceRT.Devices; using FurnaceRT.Equipments.Boats; using FurnaceRT.Equipments.Systems; using FurnaceRT.Equipments.WaferRobots; using MECF.Framework.Common.Device.Bases; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.Common.Utilities; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; using static Aitex.Core.RT.Device.Unit.IoBoat; using static log4net.Appender.RollingFileAppender; namespace FurnaceRT.Equipments.PMs { /// /// 分布类 定义各种方法 /// public partial class PMModule { private static Dictionary> _allWaferTypeNode = new Dictionary>(); private void InitOtherData() { DATA.Subscribe($"System.CompareFileDataA", () => _compareADic, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"System.CompareFileDataB", () => _compareBDic, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"System.SCDataLastWriteTime", () => GetSCDataLastWriteTime(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"System.BackUpFileData", () => GetAllBackUpFiles(), SubscriptionAttribute.FLAG.IgnoreSaveDB); } private void InitOtherOP() { } #region 备份/ZIP private Dictionary _compareADic = new Dictionary(); private Dictionary _compareBDic = new Dictionary(); private int _backUpFileMaxNumber = 10; private Dictionary> GetAllBackUpFiles() { Dictionary> result = new Dictionary>(); string sourcePath = $"{PathManager.GetCfgDir()}"; string backUpFolderPath = Path.Combine(sourcePath, BackUpDireEnum.BackUp.ToString()); var allDires = new DirectoryInfo(backUpFolderPath).GetDirectories(); foreach (var item in allDires) { var direFiles = item.GetFiles().OrderByDescending(a => a.CreationTime).Select(a => a.Name).ToList(); if (result.ContainsKey(item.Name)) { result[item.Name] = direFiles; } else { result.Add(item.Name, direFiles); } } return result; } private bool RollBackFileDataMethod(out string reason, int time, object[] param) { reason = string.Empty; if (param == null || param.Length == 0) return true; //先备份当前数据 BackUpFileDataMethod(); //在进行RollBack string sourcePath = $"{PathManager.GetCfgDir()}"; var scDataPath = $"{sourcePath}\\_sc.data"; var rollBackScDataPath = $"{sourcePath}\\{BackUpDireEnum.BackUp}\\{BackUpDireEnum.SC}\\{param[0]}"; if (!File.Exists(rollBackScDataPath)) return false; if (File.Exists(scDataPath)) File.Delete(scDataPath); File.Copy(rollBackScDataPath, scDataPath, true); return true; } private bool CompareFileDataMethod(out string reason, int time, object[] param) { reason = string.Empty; if (param == null || param.Count() == 0) return true; string sourcePath = $"{Directory.GetCurrentDirectory()}"; var dataPara = param[0].ToString().Split(','); if (dataPara.Count() == 1) { var compareAPath = $"{PathManager.GetCfgDir()}\\{BackUpDireEnum.BackUp}\\{BackUpDireEnum.SC}\\{dataPara[0]}"; var compareBPath = $"{PathManager.GetCfgDir()}\\_sc.data"; _compareADic = GetScDataByFilePath(compareAPath); _compareBDic = GetScDataByFilePath(compareBPath); } else if (dataPara.Count() == 2) { var compareAPath = $"{PathManager.GetCfgDir()}\\{BackUpDireEnum.BackUp}\\{BackUpDireEnum.SC}\\{dataPara[0]}"; var compareBPath = $"{PathManager.GetCfgDir()}\\{BackUpDireEnum.BackUp}\\{BackUpDireEnum.SC}\\{dataPara[1]}"; _compareADic = GetScDataByFilePath(compareAPath); _compareBDic = GetScDataByFilePath(compareBPath); } return true; } private string GetSCDataLastWriteTime() { var compareBPath = $"{PathManager.GetCfgDir()}\\_sc.data"; return File.GetLastWriteTime(compareBPath).ToString("yyyy-MM-dd HH-mm-ss"); } private Dictionary GetScDataByFilePath(string filePath) { Dictionary result = new Dictionary(); try { // 加载XML文件 XDocument xmlDoc = XDocument.Load(filePath); // 获取所有的scdata元素 var scDataElements = xmlDoc.Descendants("scdata"); // 遍历每个scdata元素并打印其属性 foreach (var element in scDataElements) { string name = element.Attribute("name")?.Value ?? "N/A"; string value = element.Attribute("value")?.Value ?? "N/A"; if (result.ContainsKey(name)) { result[name] = value; } else { result.Add(name, value); } } } catch (Exception ex) { // 如果发生异常,捕获并显示错误消息 Console.WriteLine("Error reading file: " + ex.Message); } return result; } private async void BackUpFileDataMethod() { _backUpFileMaxNumber = SC.GetValue("System.BackUpFileMaxNumber"); var dateTime = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"); string sourcePath = $"{PathManager.GetAppDir()}"; string newSourcePath = $"{PathManager.GetCfgDir()}"; string backUpFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}"); string scFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.SC}"); string ioFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.IO}"); string recipeFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.Recipes}"); string gasXmlFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.GasXml}"); string objectsFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.Objects}"); string parametersFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.Parameters}"); // 检查 SC 文件夹并复制 sc.data 文件 await CheckAndCopyFile(scFolderPath, Path.Combine(newSourcePath, "_sc.data"), $"{dateTime}@", "_sc.data"); // 检查 IO 文件夹并复制 IO 文件夹内容 await CheckAndCopyFolder(ioFolderPath, Path.Combine(newSourcePath, $"{BackUpDireEnum.IO}"), dateTime); // 检查 Recipe 文件夹并复制 Recipe 文件夹内容 await CheckAndCopyFolder(recipeFolderPath, Path.Combine(sourcePath, $"{BackUpDireEnum.Recipes}"), dateTime); // 检查 GasXml 文件夹并复制 GasXml 文件夹内容 await CheckAndCopyFolder(gasXmlFolderPath, Path.Combine($"{newSourcePath}", $"{BackUpDireEnum.GasXml}"), dateTime); // 检查 Objects 文件夹并复制 Objects 文件夹内容 await CheckAndCopyFolder(objectsFolderPath, Path.Combine(sourcePath, $"{BackUpDireEnum.Objects}"), dateTime); // 检查 Parameters 文件夹并复制 Parameters 文件夹内容 await CheckAndCopyFolder(parametersFolderPath, Path.Combine(sourcePath, $"{BackUpDireEnum.Parameters}"), dateTime); GetAllBackUpFiles(); } private async Task CheckAndCopyFile(string targetFolderPath, string sourceFilePath, string prefixFileName, string fileName) { if (!Directory.Exists(targetFolderPath)) Directory.CreateDirectory(targetFolderPath); var allpath = $"{prefixFileName}{fileName}"; string destinationFilePath = Path.Combine(targetFolderPath, allpath); try { var filesWithSameName = Directory.GetFiles(targetFolderPath) .Where(f => Path.GetFileName(f).Contains(fileName)) .OrderBy(f => new FileInfo(f).CreationTime) .ToArray(); // If there are more than 10 files, delete the oldest one if (filesWithSameName.Length >= _backUpFileMaxNumber) { File.Delete(filesWithSameName[0]); } if (File.Exists(destinationFilePath)) return; await Task.Run(() => File.Copy(sourceFilePath, destinationFilePath, true)); } catch (Exception ex) { Console.WriteLine($"Error copying {fileName}: {ex.Message}"); } } private async Task CheckAndCopyFolder(string targetFolderPath, string sourceFolderPath, string dateTime) { if (!Directory.Exists(targetFolderPath)) Directory.CreateDirectory(targetFolderPath); if (!Directory.Exists(sourceFolderPath)) { return; } try { await CopyDirectory(sourceFolderPath, targetFolderPath, dateTime); } catch (Exception ex) { Console.WriteLine($"Error copying folder {sourceFolderPath}: {ex.Message}"); } } private async Task CopyDirectory(string sourceDirName, string destDirName, string dateTime) { // Get the subdirectories for the specified directory. DirectoryInfo dir = new DirectoryInfo(sourceDirName); if (!dir.Exists) { throw new DirectoryNotFoundException( "Source directory does not exist or could not be found: " + sourceDirName); } DirectoryInfo[] dirs = dir.GetDirectories(); // If the destination directory doesn't exist, create it. if (!Directory.Exists(destDirName)) Directory.CreateDirectory(destDirName); var newFies = new DirectoryInfo(destDirName).GetFiles().OrderBy(f => f.CreationTime).Select(a => a.Name).ToList(); // Get the files in the directory and copy them to the new location. FileInfo[] files = dir.GetFiles(); foreach (FileInfo file in files) { var sameFiles = newFies.Where(a => a.Contains(file.Name)).ToArray(); if (sameFiles.Length >= _backUpFileMaxNumber) { File.Delete(Path.Combine(destDirName, sameFiles[0])); } var newName = $"{dateTime}@{file.Name}"; if (newFies.Contains(newName)) { continue; } string tempPath = Path.Combine(destDirName, newName); await Task.Run(() => file.CopyTo(tempPath, true)); } // Recursively call CopyDirectory on each subdirectory. foreach (DirectoryInfo subdir in dirs) { string temppath = Path.Combine(destDirName, subdir.Name); await CopyDirectory(subdir.FullName, temppath, dateTime); } } #endregion public void InitAllWaferTypeNode() { _allWaferTypeNode = SC.GetAllWaferTypeColor(); } public string GetCarrierUIColor(string carrierType, CarrierStatus carrierStatus) { var defaultColor = "#ccc"; if (carrierType == null || !_allWaferTypeNode.ContainsKey(carrierType)) return defaultColor; if (!_allWaferTypeNode[carrierType].ContainsKey(carrierStatus.ToString())) return defaultColor; return _allWaferTypeNode[carrierType][carrierStatus.ToString()]; } private void AxisDataLoad(object[] args) { var trigDataLoad = DEVICE.GetDevice($"{ModuleName.PM1.ToString()}.TrigDataLoad"); var trigDataSend = DEVICE.GetDevice($"{ModuleName.PM1.ToString()}.TrigDataSend"); trigDataSend.SetTrigger(false, out _); trigDataLoad.SetTrigger(true, out _); Thread.Sleep(1500); var paras = args[0].ToString().Split(','); foreach (var item in paras) { var path = $"System.AxisParameters.{item}"; if (!SC.ContainsItem(path)) continue; var ioName = $"{ModuleName.PM1}.{item}"; var dataValue = IO.AO[ioName].FloatValue; SC.SetItemValue(path, dataValue); } trigDataLoad.SetTrigger(false, out _); } private void AxisDataSend(object[] args) { var trigDataLoad = DEVICE.GetDevice($"{ModuleName.PM1.ToString()}.TrigDataLoad"); var trigDataSend = DEVICE.GetDevice($"{ModuleName.PM1.ToString()}.TrigDataSend"); trigDataSend.SetTrigger(true, out _); trigDataLoad.SetTrigger(false, out _); var paras = args[0].ToString().Split(','); foreach (var item in paras) { var path = $"System.AxisParameters.{item}"; if (!SC.ContainsItem(path)) continue; var ioName = $"{ModuleName.PM1}.{item}"; var scDataValue = SC.GetValue(path); IO.AO[ioName].FloatValue = (float)scDataValue; } trigDataSend.SetTrigger(false, out _); } private Dictionary GetHeatersData() { Dictionary result = new Dictionary(); if (_heaters == null || _heaters.Count == 0) { return result; } foreach (var item in _heaters) { result.Add(item.Display, item.TempFeedback.ToString("f1")); } return result; } } public enum BackUpDireEnum { SC, GasXml, IO, Objects, Parameters, Recipes, BackUp, Config, } }