using Eaf.Management.ConfigurationData.CellAutomation; using Ifx.Eaf.EquipmentConnector.File.Configuration; using Infineon.Monitoring.MonA; using Shared; using Shared.Metrology; using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Text.Json; using System.Threading; namespace MET08DDUPSFS6420.Helpers { public partial class ConfigData : ConfigDataBase { internal const object NullData = null; internal const int MinFileLength = 100; public string IqsFile { get; private set; } public string OpenInsightFilePattern { get; private set; } public string IqsQueryFilter { get; private set; } public string TracePath { get; private set; } public string VillachPath { get; private set; } public string ProgressPath { get; private set; } public string MemoryPath { get; private set; } public bool IsSourceIPDSF { get; private set; } public bool IsSourceTimer { get; private set; } public bool IsDatabaseExportToIPDSF { get; private set; } public string OpenInsightSiViewer { get; private set; } public string OpenInsightMetrogyViewerAPI { get; private set; } public Level? Duplicator { get; private set; } public static Dictionary> DummyRuns { get; private set; } public FileConnectorConfiguration FileConnectorConfiguration { get; private set; } public string GhostPCLFileName { get; private set; } public string NoWaferMap { get; private set; } private Timer _Timer; private int _LastDummyRunIndex; private readonly Calendar _Calendar; private readonly string _ReportFullPath; public ConfigData(ILogic logic, string equipmentElementName, EquipmentConnection? equipmentConnection, string cellName, FileConnectorConfiguration fileConnectorConfiguration, IList configuredParameters, EventName? eventName, bool isEAFHosted) : base(equipmentElementName, equipmentConnection, cellName, eventName, isEAFHosted) { EafHosted = isEAFHosted; _LastDummyRunIndex = -1; UseCyclicalForDescription = false; EquipmentConnection = equipmentConnection; EquipmentElementName = equipmentElementName; CultureInfo cultureInfo = new CultureInfo("en-US"); _Calendar = cultureInfo.Calendar; FileConnectorConfiguration = fileConnectorConfiguration; string firstSourceFileFilter = fileConnectorConfiguration.SourceFileFilter.Split('|')[0]; IsSourceIPDSF = (fileConnectorConfiguration.SourceFileFilter == "*.ipdsf"); IsSourceTimer = (fileConnectorConfiguration.SourceFileFilter == "*Timer.txt"); IsDatabaseExportToIPDSF = (fileConnectorConfiguration.SourceFileLocation.Contains("DatabaseExport")); if (DummyRuns is null) DummyRuns = new Dictionary>(); bool isDuplicator = cellInstanceConnectionName.StartsWith(cellName); int level = (cellInstanceConnectionName.Length - cellInstanceConnectionName.Replace("-", string.Empty).Length); if (IsSourceIPDSF && isDuplicator) IsSourceIPDSF = false; if (!isDuplicator) Duplicator = null; else { CellNames.Add(cellName, cellName); MesEntities.Add(cellName, cellName); Duplicator = (Level)level; } IProcessDataDescription processDataDescription; if (isDuplicator) processDataDescription = new Duplicator.Description(); else { switch (eventName.Value) { case EventName.FileRead: processDataDescription = new ProcessData.FileRead.Description(); break; default: throw new Exception(); } } _ProcessDataDescription = processDataDescription; if (!isEAFHosted) WriteExportAliases(logic, cellName); GhostPCLFileName = string.Concat(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), @"\gpcl6win64.exe"); if (EafHosted && Duplicator.HasValue && Duplicator.Value == Level.IsXToOpenInsightMetrologyViewerAttachments && !File.Exists(GhostPCLFileName)) throw new Exception("Ghost PCL FileName doesn't Exist!"); //LincPDFCFileName = string.Concat(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), @"\LincPDFC.exe"); if (!modelObjectParameterDefinitions.Any()) { CellNames.Add(cellName, "****"); MesEntities.Add(cellName, "****"); } else { int index; string key; string variable = string.Empty; Dictionary iqsSection = new Dictionary(); Dictionary pathSection = new Dictionary(); Dictionary commonSection = new Dictionary(); Dictionary openInsightSection = new Dictionary(); foreach (ModelObjectParameterDefinition modelObjectParameterDefinition in modelObjectParameterDefinitions) { if (!modelObjectParameterDefinition.Name.Contains('.')) continue; index = modelObjectParameterDefinition.Name.IndexOf("."); if (index <= -1) continue; key = modelObjectParameterDefinition.Name.Substring(0, index); variable = modelObjectParameterDefinition.Name.Substring(index + 1); if (key == "COMMON") commonSection.Add(variable, modelObjectParameterDefinition.Value); //else if (key == "CONNECTION STRINGS") // connectionStringsSection.Add(variable, modelObjectParameterDefinition.Value); else if (key == "IQS") iqsSection.Add(variable, modelObjectParameterDefinition.Value); else if (key == "OpenInsight") openInsightSection.Add(variable, modelObjectParameterDefinition.Value); else if (key == "PATH") pathSection.Add(variable, modelObjectParameterDefinition.Value); //else if (key == "REACTOR") // reactorTuples.Add(new Tuple(variable, modelObjectParameterDefinition.Value)); //else if (key == "TIBCO") // tibcoSection.Add(variable, modelObjectParameterDefinition.Value); else throw new Exception(); } if (!iqsSection.Any()) throw new Exception("IQS section is missing from configuration"); else { key = "FILE"; if (iqsSection.ContainsKey(key)) IqsFile = iqsSection[key]; else throw new Exception(string.Concat("Missing IQS Configuration entry for ", key)); if (string.IsNullOrEmpty(IqsFile)) throw new Exception(string.Format("IQS key {0} is empty", key)); key = "QUERY"; if (iqsSection.ContainsKey(key)) IqsQueryFilter = iqsSection[key]; else throw new Exception(string.Concat("Missing IQS Configuration entry for ", key)); if (string.IsNullOrEmpty(IqsQueryFilter)) throw new Exception(string.Format("IQS key {0} is empty", key)); } if (!pathSection.Any()) throw new Exception("Path section is missing from configuration"); else { key = "TRACE"; if (pathSection.ContainsKey(key) && pathSection[key].StartsWith(@"\\")) TracePath = pathSection[key]; if (!string.IsNullOrEmpty(TracePath) && !Directory.Exists(TracePath)) Directory.CreateDirectory(TracePath); key = "VILLACH"; if (pathSection.ContainsKey(key) && pathSection[key].StartsWith(@"\\")) VillachPath = pathSection[key]; if (!string.IsNullOrEmpty(VillachPath) && !Directory.Exists(VillachPath)) Directory.CreateDirectory(VillachPath); key = "Progress"; if (pathSection.ContainsKey(key) && pathSection[key].StartsWith(@"\\")) ProgressPath = pathSection[key]; if (!string.IsNullOrEmpty(ProgressPath) && Directory.Exists(Path.GetPathRoot(ProgressPath)) && !Directory.Exists(ProgressPath)) Directory.CreateDirectory(ProgressPath); key = "Memory"; if (pathSection.ContainsKey(key) && pathSection[key].StartsWith(@"\\")) MemoryPath = pathSection[key]; if (!string.IsNullOrEmpty(MemoryPath) && !Directory.Exists(MemoryPath)) Directory.CreateDirectory(MemoryPath); } if (!commonSection.Any()) throw new Exception("Common section is missing from configuration"); else { key = "CELL_NAMES"; if (!commonSection.ContainsKey(key) || !commonSection[key].Contains(';') || !commonSection[key].Contains(':')) throw new Exception(); else { string[] segments; string[] cellNames = commonSection[key].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); foreach (string item in cellNames) { segments = item.Split(':'); CellNames.Add(segments[0].Trim(), segments[1].Trim()); } } if (!string.IsNullOrEmpty(cellName) && !CellNames.ContainsKey(cellName)) throw new Exception(); key = "MES_ENTITIES"; if (!commonSection.ContainsKey(key) || !commonSection[key].Contains(';') || !commonSection[key].Contains(':')) throw new Exception(); else { string[] segments; string[] mesEntity = commonSection[key].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); foreach (string item in mesEntity) { segments = item.Split(':'); MesEntities.Add(segments[0].Trim(), segments[1].Trim()); } } if (!string.IsNullOrEmpty(cellName) && !MesEntities.ContainsKey(cellName)) throw new Exception(); key = "NoWaferMap"; if (commonSection.ContainsKey(key)) NoWaferMap = commonSection[key]; if (string.IsNullOrEmpty(NoWaferMap)) throw new Exception(string.Format("Common key {0} is empty", key)); if (Duplicator.HasValue && Duplicator.Value == Level.IsXToOpenInsightMetrologyViewerAttachments && !File.Exists(NoWaferMap)) throw new Exception(string.Format("Common key {0} is doesn't exist!", key)); } if (!openInsightSection.Any()) throw new Exception("OpenInsight section is missing from configuration"); else { key = "MetrologyViewerAPI"; if (openInsightSection.ContainsKey(key)) OpenInsightMetrogyViewerAPI = openInsightSection[key]; if (string.IsNullOrEmpty(OpenInsightMetrogyViewerAPI)) throw new Exception(string.Format("OpenInsight key {0} is empty", key)); if (!OpenInsightMetrogyViewerAPI.Contains(":") || !OpenInsightMetrogyViewerAPI.Contains(".")) throw new Exception(string.Format("OpenInsight key {0} is invalid", key)); key = "SiViewer"; if (openInsightSection.ContainsKey(key)) OpenInsightSiViewer = openInsightSection[key]; if (string.IsNullOrEmpty(OpenInsightSiViewer)) throw new Exception(string.Format("OpenInsight key {0} is empty", key)); if (!OpenInsightSiViewer.Contains(":") || !OpenInsightSiViewer.Contains(".")) throw new Exception(string.Format("OpenInsight key {0} is invalid", key)); key = "FilePattern"; if (openInsightSection.ContainsKey(key)) OpenInsightFilePattern = openInsightSection[key]; else throw new Exception(string.Concat("Missing OpenInsight Configuration entry for ", key)); if (string.IsNullOrEmpty(OpenInsightFilePattern)) throw new Exception(string.Format("OpenInsight key {0} is empty", key)); } if (!MesEntities.Any()) throw new Exception(); if (IsSourceTimer || IsDatabaseExportToIPDSF || (Duplicator.HasValue && Duplicator.Value == Level.IsDummy)) { if (!Directory.Exists(fileConnectorConfiguration.SourceFileLocation)) Directory.CreateDirectory(fileConnectorConfiguration.SourceFileLocation); _ReportFullPath = string.Concat(fileConnectorConfiguration.SourceFileLocation, firstSourceFileFilter.Replace("*", @"\")); if (Debugger.IsAttached || fileConnectorConfiguration.PreProcessingMode == FileConnectorConfiguration.PreProcessingModeEnum.Process) Callback(null); else { int milliSeconds; milliSeconds = (fileConnectorConfiguration.FileScanningIntervalInSeconds * 1000) / 2; _Timer = new Timer(Callback, null, milliSeconds, Timeout.Infinite); milliSeconds += 2000; } } } } private void CallbackIsDummy() { DateTime dateTime = DateTime.Now; bool check = (dateTime.Hour > 7 && dateTime.Hour < 18 && dateTime.DayOfWeek != DayOfWeek.Sunday && dateTime.DayOfWeek != DayOfWeek.Saturday); if (check) { int fileCount; string[] files; string monARessource; string checkDirectory; string sourceArchiveFile; string sourceFileLocation; string targetFileLocation; string inProcessDirectory; string weekOfYear = _Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); string traceDummyDirectory = string.Concat(Path.GetPathRoot(TracePath), @"\TracesDummy\", _CellName, @"\Source\", dateTime.ToString("yyyy"), "___Week_", weekOfYear); if (!Directory.Exists(traceDummyDirectory)) Directory.CreateDirectory(traceDummyDirectory); string traceDummyFile = string.Concat(traceDummyDirectory, @"\", dateTime.Ticks, " - ", _CellName, ".txt"); File.AppendAllText(traceDummyFile, string.Empty); List> tuples = new List>(); foreach (var keyValuePair in CellNames) { monARessource = keyValuePair.Key; if (!keyValuePair.Value.Contains(@"\")) continue; foreach (string sourceFileFilter in FileConnectorConfiguration.SourceFileFilter.Split('|')) { if (sourceFileFilter.ToLower().StartsWith(keyValuePair.Value.Replace(@"\", string.Empty))) sourceFileLocation = Path.GetFullPath(FileConnectorConfiguration.SourceFileLocation); else if (FileConnectorConfiguration.SourceFileLocation.ToLower().EndsWith(keyValuePair.Value)) sourceFileLocation = Path.GetFullPath(FileConnectorConfiguration.SourceFileLocation); else sourceFileLocation = Path.GetFullPath(string.Concat(FileConnectorConfiguration.SourceFileLocation, @"\", keyValuePair.Value)); sourceArchiveFile = Path.GetFullPath(string.Concat(sourceFileLocation, @"\", sourceFileFilter)); targetFileLocation = Path.GetFullPath(string.Concat(FileConnectorConfiguration.TargetFileLocation, @"\", keyValuePair.Value)); if (!File.Exists(sourceArchiveFile)) continue; if (!DummyRuns.ContainsKey(monARessource)) DummyRuns.Add(monARessource, new List()); tuples.Add(new Tuple(monARessource, sourceFileLocation, targetFileLocation, sourceArchiveFile, 0)); } } File.AppendAllLines(traceDummyFile, from l in tuples select l.Item4); if (tuples.Any()) { _LastDummyRunIndex += 1; if (_LastDummyRunIndex >= tuples.Count) _LastDummyRunIndex = 0; monARessource = tuples[_LastDummyRunIndex].Item1; sourceFileLocation = tuples[_LastDummyRunIndex].Item2; targetFileLocation = tuples[_LastDummyRunIndex].Item3; sourceArchiveFile = tuples[_LastDummyRunIndex].Item4; //fileCount = tuples[_LastDummyRunIndex].Item5; tuples.Clear(); if (long.TryParse(Path.GetFileNameWithoutExtension(sourceArchiveFile).Replace("x", string.Empty), out long sequence)) { if (!DummyRuns[monARessource].Contains(sequence)) DummyRuns[monARessource].Add(sequence); inProcessDirectory = string.Concat(ProgressPath, @"\", monARessource, @"\Dummy_in process\", sequence); checkDirectory = inProcessDirectory; if (!Directory.Exists(checkDirectory)) Directory.CreateDirectory(checkDirectory); files = Directory.GetFiles(checkDirectory, "*", SearchOption.AllDirectories); fileCount = files.Length; if (files.Any()) { if (files.Length > 250) throw new Exception("Safety net!"); try { foreach (string file in files) File.Delete(file); } catch (Exception) { } } tuples.Add(new Tuple(monARessource, sourceArchiveFile, inProcessDirectory, checkDirectory, fileCount)); checkDirectory = targetFileLocation; files = Directory.GetFiles(checkDirectory, string.Concat("*", sequence, "*"), SearchOption.TopDirectoryOnly); fileCount = files.Length; tuples.Add(new Tuple(monARessource, sourceArchiveFile, inProcessDirectory, checkDirectory, fileCount)); } } if (tuples.Any()) { const string site = "sjc"; MonIn monIn = MonIn.GetInstance(); string stateName = string.Concat("Dummy_", _EventName); foreach (Tuple item in tuples) { monARessource = item.Item1; sourceArchiveFile = item.Item2; inProcessDirectory = item.Item3; checkDirectory = item.Item4; fileCount = item.Item5; try { if (fileCount > 0 || string.IsNullOrEmpty(checkDirectory)) { File.AppendAllLines(traceDummyFile, new string[] { site, monARessource, stateName, State.Warning.ToString() }); monIn.SendStatus(site, monARessource, stateName, State.Warning); for (int i = 1; i < 12; i++) Thread.Sleep(500); } else if (inProcessDirectory != checkDirectory) { if (!File.Exists(sourceArchiveFile)) continue; if (!long.TryParse(Path.GetFileNameWithoutExtension(sourceArchiveFile).Replace("x", string.Empty), out long sequence)) continue; ZipFile.ExtractToDirectory(sourceArchiveFile, inProcessDirectory); if (FileConnectorConfiguration.IncludeSubDirectories) files = Directory.GetFiles(inProcessDirectory, "*", SearchOption.AllDirectories); else files = Directory.GetFiles(inProcessDirectory, "*", SearchOption.TopDirectoryOnly); if (files.Length > 250) throw new Exception("Safety net!"); foreach (string file in files) File.SetLastWriteTime(file, new DateTime(sequence)); if (!FileConnectorConfiguration.IncludeSubDirectories) { foreach (string file in files) File.Move(file, string.Concat(checkDirectory, @"\", Path.GetFileName(file))); } else { string[] directories = Directory.GetDirectories(inProcessDirectory, "*", SearchOption.AllDirectories); foreach (string directory in directories) Directory.CreateDirectory(string.Concat(checkDirectory, directory.Substring(inProcessDirectory.Length))); foreach (string file in files) File.Move(file, string.Concat(checkDirectory, file.Substring(inProcessDirectory.Length))); } File.AppendAllLines(traceDummyFile, new string[] { site, monARessource, stateName, State.Ok.ToString() }); monIn.SendStatus(site, monARessource, stateName, State.Ok); } } catch (Exception exception) { File.AppendAllLines(traceDummyFile, new string[] { site, monARessource, stateName, State.Critical.ToString(), exception.Message, exception.StackTrace }); monIn.SendStatus(site, monARessource, stateName, State.Critical); try { Eaf.Core.Smtp.ISmtp smtp = Eaf.Core.Backbone.Instance.GetBackboneComponentsOfType().SingleOrDefault(); Eaf.Core.Smtp.EmailMessage emailMessage = new Eaf.Core.Smtp.EmailMessage(string.Concat("Exception:", EquipmentElementName), string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace), Eaf.Core.Smtp.MailPriority.High); smtp.Send(emailMessage); } catch (Exception) { } } } } } } private void Callback(object state) { try { if (Duplicator is null) { if (File.Exists(_ReportFullPath)) File.Delete(_ReportFullPath); File.WriteAllText(_ReportFullPath, string.Empty); } else if (Duplicator.Value == Level.IsDummy) CallbackIsDummy(); else throw new Exception(); } catch (Exception exception) { try { Eaf.Core.Smtp.ISmtp smtp = Eaf.Core.Backbone.Instance.GetBackboneComponentsOfType().SingleOrDefault(); Eaf.Core.Smtp.EmailMessage emailMessage = new Eaf.Core.Smtp.EmailMessage(string.Concat("Exception:", EquipmentElementName), string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace), Eaf.Core.Smtp.MailPriority.High); smtp.Send(emailMessage); } catch (Exception) { } } try { TimeSpan timeSpan; if (IsDatabaseExportToIPDSF) timeSpan = new TimeSpan(DateTime.Now.AddMinutes(1).Ticks - DateTime.Now.Ticks); else if (IsSourceTimer) timeSpan = new TimeSpan(DateTime.Now.AddMinutes(15).Ticks - DateTime.Now.Ticks); else if (Duplicator.HasValue && Duplicator.Value == Level.IsDummy) timeSpan = new TimeSpan(DateTime.Now.AddSeconds(FileConnectorConfiguration.FileScanningIntervalInSeconds).Ticks - DateTime.Now.Ticks); else if (Duplicator.HasValue) timeSpan = new TimeSpan(DateTime.Now.AddSeconds(30).Ticks - DateTime.Now.Ticks); else timeSpan = new TimeSpan(DateTime.Now.AddDays(.5).Ticks - DateTime.Now.Ticks); if (!(_Timer is null)) _Timer.Change((long)timeSpan.TotalMilliseconds, Timeout.Infinite); else _Timer = new Timer(Callback, null, (long)timeSpan.TotalMilliseconds, Timeout.Infinite); } catch (Exception exception) { try { Eaf.Core.Smtp.ISmtp smtp = Eaf.Core.Backbone.Instance.GetBackboneComponentsOfType().SingleOrDefault(); Eaf.Core.Smtp.EmailMessage emailMessage = new Eaf.Core.Smtp.EmailMessage(string.Concat("Exception:", EquipmentElementName), string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace), Eaf.Core.Smtp.MailPriority.High); smtp.Send(emailMessage); } catch (Exception) { } } } public string GetCurrentReactorKey(Logistics logistics) { throw new Exception(); } public Tuple> GetResults(ILogic logic, List fileInfoCollection, ProcessData processData) { Tuple> results; List tests = new List(); List descriptions; if (_EventName.Value == EventName.FileRead && processData.Details.Any()) { foreach (var item in processData.Details) tests.Add(Test.Tencor); descriptions = _ProcessDataDescription.GetDescription(logic, this, tests, processData); } else throw new Exception(); if (!EafHosted) { new ProcessData.FileRead.Description().GetDescription(logic, this, tests, processData); } if (tests.Count != descriptions.Count) throw new Exception(); for (int i = 0; i < tests.Count; i++) { if (descriptions[i].Test != (int)tests[i]) throw new Exception(); } string json; if (descriptions[0] is Duplicator.Description) { List duplicatorDescriptions = (from l in descriptions select (Duplicator.Description)l).ToList(); json = JsonSerializer.Serialize(duplicatorDescriptions, duplicatorDescriptions.GetType()); } else if (descriptions[0] is ProcessData.FileRead.Description) { List fileReadDescriptions = (from l in descriptions select (ProcessData.FileRead.Description)l).ToList(); json = JsonSerializer.Serialize(fileReadDescriptions, fileReadDescriptions.GetType()); } else throw new Exception(); object @object = JsonSerializer.Deserialize(json); if (!(@object is JsonElement jsonElement)) throw new Exception(); results = new Tuple>(logic.Logistics.Logistics1[0], jsonElement, fileInfoCollection); return results; } public Dictionary> GetKeyValuePairs(JsonElement jsonElement, List processDataDescriptions, bool extra = false) { Dictionary> results = GetKeyValuePairs(processDataDescriptions); List tests = new List(); foreach (Test test in results.Keys) { if (test == Test.Tencor) { if (!(_ProcessDataDescription is ProcessData.FileRead.Description)) _ProcessDataDescription = new ProcessData.FileRead.Description(); } else throw new Exception(); } return results; } public List GetProcessDataFileReadDescriptions(JsonElement jsonElement) { List results = new List(); List processDataDescriptions = GetIProcessDataDescriptions(jsonElement); foreach (IProcessDataDescription processDataDescription in processDataDescriptions) { if (!(processDataDescription is ProcessData.FileRead.Description description)) continue; results.Add(description); } return results; } } }