PMMethods.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. using Aitex.Common.Util;
  2. using Aitex.Core.Common.DeviceData;
  3. using Aitex.Core.RT.DataCenter;
  4. using Aitex.Core.RT.Device;
  5. using Aitex.Core.RT.Device.Unit;
  6. using Aitex.Core.RT.Event;
  7. using Aitex.Core.RT.IOCore;
  8. using Aitex.Core.RT.Log;
  9. using Aitex.Core.RT.OperationCenter;
  10. using Aitex.Core.RT.SCCore;
  11. using Aitex.Core.UI.Control;
  12. using Aitex.Core.Util;
  13. using FurnaceRT.Devices;
  14. using FurnaceRT.Equipments.Boats;
  15. using FurnaceRT.Equipments.Systems;
  16. using FurnaceRT.Equipments.WaferRobots;
  17. using MECF.Framework.Common.Device.Bases;
  18. using MECF.Framework.Common.Equipment;
  19. using MECF.Framework.Common.SubstrateTrackings;
  20. using MECF.Framework.Common.Utilities;
  21. using System;
  22. using System.Collections.Generic;
  23. using System.IO;
  24. using System.Linq;
  25. using System.Text;
  26. using System.Threading;
  27. using System.Threading.Tasks;
  28. using System.Xml.Linq;
  29. using static Aitex.Core.RT.Device.Unit.IoBoat;
  30. using static log4net.Appender.RollingFileAppender;
  31. namespace FurnaceRT.Equipments.PMs
  32. {
  33. /// <summary>
  34. /// 分布类 定义各种方法
  35. /// </summary>
  36. public partial class PMModule
  37. {
  38. private static Dictionary<string, Dictionary<string, string>> _allWaferTypeNode = new Dictionary<string, Dictionary<string, string>>();
  39. private void InitOtherData()
  40. {
  41. DATA.Subscribe($"System.CompareFileDataA", () => _compareADic, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  42. DATA.Subscribe($"System.CompareFileDataB", () => _compareBDic, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  43. DATA.Subscribe($"System.SCDataLastWriteTime", () => GetSCDataLastWriteTime(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
  44. DATA.Subscribe($"System.BackUpFileData", () => GetAllBackUpFiles(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
  45. }
  46. private void InitOtherOP()
  47. {
  48. }
  49. #region 备份/ZIP
  50. private Dictionary<string, string> _compareADic = new Dictionary<string, string>();
  51. private Dictionary<string, string> _compareBDic = new Dictionary<string, string>();
  52. private int _backUpFileMaxNumber = 10;
  53. private Dictionary<string, List<string>> GetAllBackUpFiles()
  54. {
  55. Dictionary<string, List<string>> result = new Dictionary<string, List<string>>();
  56. string sourcePath = $"{PathManager.GetCfgDir()}";
  57. string backUpFolderPath = Path.Combine(sourcePath, BackUpDireEnum.BackUp.ToString());
  58. var allDires = new DirectoryInfo(backUpFolderPath).GetDirectories();
  59. foreach (var item in allDires)
  60. {
  61. var direFiles = item.GetFiles().OrderByDescending(a => a.CreationTime).Select(a => a.Name).ToList();
  62. if (result.ContainsKey(item.Name))
  63. {
  64. result[item.Name] = direFiles;
  65. }
  66. else
  67. {
  68. result.Add(item.Name, direFiles);
  69. }
  70. }
  71. return result;
  72. }
  73. private bool RollBackFileDataMethod(out string reason, int time, object[] param)
  74. {
  75. reason = string.Empty;
  76. if (param == null || param.Length == 0)
  77. return true;
  78. //先备份当前数据
  79. BackUpFileDataMethod();
  80. //在进行RollBack
  81. string sourcePath = $"{PathManager.GetCfgDir()}";
  82. var scDataPath = $"{sourcePath}\\_sc.data";
  83. var rollBackScDataPath = $"{sourcePath}\\{BackUpDireEnum.BackUp}\\{BackUpDireEnum.SC}\\{param[0]}";
  84. if (!File.Exists(rollBackScDataPath))
  85. return false;
  86. if (File.Exists(scDataPath))
  87. File.Delete(scDataPath);
  88. File.Copy(rollBackScDataPath, scDataPath, true);
  89. return true;
  90. }
  91. private bool CompareFileDataMethod(out string reason, int time, object[] param)
  92. {
  93. reason = string.Empty;
  94. if (param == null || param.Count() == 0)
  95. return true;
  96. string sourcePath = $"{Directory.GetCurrentDirectory()}";
  97. var dataPara = param[0].ToString().Split(',');
  98. if (dataPara.Count() == 1)
  99. {
  100. var compareAPath = $"{PathManager.GetCfgDir()}\\{BackUpDireEnum.BackUp}\\{BackUpDireEnum.SC}\\{dataPara[0]}";
  101. var compareBPath = $"{PathManager.GetCfgDir()}\\_sc.data";
  102. _compareADic = GetScDataByFilePath(compareAPath);
  103. _compareBDic = GetScDataByFilePath(compareBPath);
  104. }
  105. else if (dataPara.Count() == 2)
  106. {
  107. var compareAPath = $"{PathManager.GetCfgDir()}\\{BackUpDireEnum.BackUp}\\{BackUpDireEnum.SC}\\{dataPara[0]}";
  108. var compareBPath = $"{PathManager.GetCfgDir()}\\{BackUpDireEnum.BackUp}\\{BackUpDireEnum.SC}\\{dataPara[1]}";
  109. _compareADic = GetScDataByFilePath(compareAPath);
  110. _compareBDic = GetScDataByFilePath(compareBPath);
  111. }
  112. return true;
  113. }
  114. private string GetSCDataLastWriteTime()
  115. {
  116. var compareBPath = $"{PathManager.GetCfgDir()}\\_sc.data";
  117. return File.GetLastWriteTime(compareBPath).ToString("yyyy-MM-dd HH-mm-ss");
  118. }
  119. private Dictionary<string, string> GetScDataByFilePath(string filePath)
  120. {
  121. Dictionary<string, string> result = new Dictionary<string, string>();
  122. try
  123. {
  124. // 加载XML文件
  125. XDocument xmlDoc = XDocument.Load(filePath);
  126. // 获取所有的scdata元素
  127. var scDataElements = xmlDoc.Descendants("scdata");
  128. // 遍历每个scdata元素并打印其属性
  129. foreach (var element in scDataElements)
  130. {
  131. string name = element.Attribute("name")?.Value ?? "N/A";
  132. string value = element.Attribute("value")?.Value ?? "N/A";
  133. if (result.ContainsKey(name))
  134. {
  135. result[name] = value;
  136. }
  137. else
  138. {
  139. result.Add(name, value);
  140. }
  141. }
  142. }
  143. catch (Exception ex)
  144. {
  145. // 如果发生异常,捕获并显示错误消息
  146. Console.WriteLine("Error reading file: " + ex.Message);
  147. }
  148. return result;
  149. }
  150. private async void BackUpFileDataMethod()
  151. {
  152. _backUpFileMaxNumber = SC.GetValue<int>("System.BackUpFileMaxNumber");
  153. var dateTime = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss");
  154. string sourcePath = $"{PathManager.GetAppDir()}";
  155. string newSourcePath = $"{PathManager.GetCfgDir()}";
  156. string backUpFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}");
  157. string scFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.SC}");
  158. string ioFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.IO}");
  159. string recipeFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.Recipes}");
  160. string gasXmlFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.GasXml}");
  161. string objectsFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.Objects}");
  162. string parametersFolderPath = Path.Combine(newSourcePath, $"{BackUpDireEnum.BackUp}\\{BackUpDireEnum.Parameters}");
  163. // 检查 SC 文件夹并复制 sc.data 文件
  164. await CheckAndCopyFile(scFolderPath, Path.Combine(newSourcePath, "_sc.data"), $"{dateTime}@", "_sc.data");
  165. // 检查 IO 文件夹并复制 IO 文件夹内容
  166. await CheckAndCopyFolder(ioFolderPath, Path.Combine(newSourcePath, $"{BackUpDireEnum.IO}"), dateTime);
  167. // 检查 Recipe 文件夹并复制 Recipe 文件夹内容
  168. await CheckAndCopyFolder(recipeFolderPath, Path.Combine(sourcePath, $"{BackUpDireEnum.Recipes}"), dateTime);
  169. // 检查 GasXml 文件夹并复制 GasXml 文件夹内容
  170. await CheckAndCopyFolder(gasXmlFolderPath, Path.Combine($"{newSourcePath}", $"{BackUpDireEnum.GasXml}"), dateTime);
  171. // 检查 Objects 文件夹并复制 Objects 文件夹内容
  172. await CheckAndCopyFolder(objectsFolderPath, Path.Combine(sourcePath, $"{BackUpDireEnum.Objects}"), dateTime);
  173. // 检查 Parameters 文件夹并复制 Parameters 文件夹内容
  174. await CheckAndCopyFolder(parametersFolderPath, Path.Combine(sourcePath, $"{BackUpDireEnum.Parameters}"), dateTime);
  175. GetAllBackUpFiles();
  176. }
  177. private async Task CheckAndCopyFile(string targetFolderPath, string sourceFilePath, string prefixFileName, string fileName)
  178. {
  179. if (!Directory.Exists(targetFolderPath))
  180. Directory.CreateDirectory(targetFolderPath);
  181. var allpath = $"{prefixFileName}{fileName}";
  182. string destinationFilePath = Path.Combine(targetFolderPath, allpath);
  183. try
  184. {
  185. var filesWithSameName = Directory.GetFiles(targetFolderPath)
  186. .Where(f => Path.GetFileName(f).Contains(fileName))
  187. .OrderBy(f => new FileInfo(f).CreationTime)
  188. .ToArray();
  189. // If there are more than 10 files, delete the oldest one
  190. if (filesWithSameName.Length >= _backUpFileMaxNumber)
  191. {
  192. File.Delete(filesWithSameName[0]);
  193. }
  194. if (File.Exists(destinationFilePath))
  195. return;
  196. await Task.Run(() => File.Copy(sourceFilePath, destinationFilePath, true));
  197. }
  198. catch (Exception ex)
  199. {
  200. Console.WriteLine($"Error copying {fileName}: {ex.Message}");
  201. }
  202. }
  203. private async Task CheckAndCopyFolder(string targetFolderPath, string sourceFolderPath, string dateTime)
  204. {
  205. if (!Directory.Exists(targetFolderPath))
  206. Directory.CreateDirectory(targetFolderPath);
  207. if (!Directory.Exists(sourceFolderPath))
  208. {
  209. return;
  210. }
  211. try
  212. {
  213. await CopyDirectory(sourceFolderPath, targetFolderPath, dateTime);
  214. }
  215. catch (Exception ex)
  216. {
  217. Console.WriteLine($"Error copying folder {sourceFolderPath}: {ex.Message}");
  218. }
  219. }
  220. private async Task CopyDirectory(string sourceDirName, string destDirName, string dateTime)
  221. {
  222. // Get the subdirectories for the specified directory.
  223. DirectoryInfo dir = new DirectoryInfo(sourceDirName);
  224. if (!dir.Exists)
  225. {
  226. throw new DirectoryNotFoundException(
  227. "Source directory does not exist or could not be found: "
  228. + sourceDirName);
  229. }
  230. DirectoryInfo[] dirs = dir.GetDirectories();
  231. // If the destination directory doesn't exist, create it.
  232. if (!Directory.Exists(destDirName))
  233. Directory.CreateDirectory(destDirName);
  234. var newFies = new DirectoryInfo(destDirName).GetFiles().OrderBy(f => f.CreationTime).Select(a => a.Name).ToList();
  235. // Get the files in the directory and copy them to the new location.
  236. FileInfo[] files = dir.GetFiles();
  237. foreach (FileInfo file in files)
  238. {
  239. var sameFiles = newFies.Where(a => a.Contains(file.Name)).ToArray();
  240. if (sameFiles.Length >= _backUpFileMaxNumber)
  241. {
  242. File.Delete(Path.Combine(destDirName, sameFiles[0]));
  243. }
  244. var newName = $"{dateTime}@{file.Name}";
  245. if (newFies.Contains(newName))
  246. {
  247. continue;
  248. }
  249. string tempPath = Path.Combine(destDirName, newName);
  250. await Task.Run(() => file.CopyTo(tempPath, true));
  251. }
  252. // Recursively call CopyDirectory on each subdirectory.
  253. foreach (DirectoryInfo subdir in dirs)
  254. {
  255. string temppath = Path.Combine(destDirName, subdir.Name);
  256. await CopyDirectory(subdir.FullName, temppath, dateTime);
  257. }
  258. }
  259. #endregion
  260. public void InitAllWaferTypeNode()
  261. {
  262. _allWaferTypeNode = SC.GetAllWaferTypeColor();
  263. }
  264. public string GetCarrierUIColor(string carrierType, CarrierStatus carrierStatus)
  265. {
  266. var defaultColor = "#ccc";
  267. if (carrierType == null || !_allWaferTypeNode.ContainsKey(carrierType))
  268. return defaultColor;
  269. if (!_allWaferTypeNode[carrierType].ContainsKey(carrierStatus.ToString()))
  270. return defaultColor;
  271. return _allWaferTypeNode[carrierType][carrierStatus.ToString()];
  272. }
  273. private void AxisDataLoad(object[] args)
  274. {
  275. var trigDataLoad = DEVICE.GetDevice<IoTrigger>($"{ModuleName.PM1.ToString()}.TrigDataLoad");
  276. var trigDataSend = DEVICE.GetDevice<IoTrigger>($"{ModuleName.PM1.ToString()}.TrigDataSend");
  277. trigDataSend.SetTrigger(false, out _);
  278. trigDataLoad.SetTrigger(true, out _);
  279. Thread.Sleep(1500);
  280. var paras = args[0].ToString().Split(',');
  281. foreach (var item in paras)
  282. {
  283. var path = $"System.AxisParameters.{item}";
  284. if (!SC.ContainsItem(path))
  285. continue;
  286. var ioName = $"{ModuleName.PM1}.{item}";
  287. var dataValue = IO.AO[ioName].FloatValue;
  288. SC.SetItemValue(path, dataValue);
  289. }
  290. trigDataLoad.SetTrigger(false, out _);
  291. }
  292. private void AxisDataSend(object[] args)
  293. {
  294. var trigDataLoad = DEVICE.GetDevice<IoTrigger>($"{ModuleName.PM1.ToString()}.TrigDataLoad");
  295. var trigDataSend = DEVICE.GetDevice<IoTrigger>($"{ModuleName.PM1.ToString()}.TrigDataSend");
  296. trigDataSend.SetTrigger(true, out _);
  297. trigDataLoad.SetTrigger(false, out _);
  298. var paras = args[0].ToString().Split(',');
  299. foreach (var item in paras)
  300. {
  301. var path = $"System.AxisParameters.{item}";
  302. if (!SC.ContainsItem(path))
  303. continue;
  304. var ioName = $"{ModuleName.PM1}.{item}";
  305. var scDataValue = SC.GetValue<double>(path);
  306. IO.AO[ioName].FloatValue = (float)scDataValue;
  307. }
  308. trigDataSend.SetTrigger(false, out _);
  309. }
  310. private Dictionary<string, string> GetHeatersData()
  311. {
  312. Dictionary<string, string> result = new Dictionary<string, string>();
  313. if (_heaters == null || _heaters.Count == 0)
  314. {
  315. return result;
  316. }
  317. foreach (var item in _heaters)
  318. {
  319. result.Add(item.Display, item.TempFeedback.ToString("f1"));
  320. }
  321. return result;
  322. }
  323. }
  324. public enum BackUpDireEnum
  325. {
  326. SC,
  327. GasXml,
  328. IO,
  329. Objects,
  330. Parameters,
  331. Recipes,
  332. BackUp,
  333. Config,
  334. }
  335. }