diff --git a/Adaptation/FileHandlers/CellInstanceConnectionName.cs b/Adaptation/FileHandlers/CellInstanceConnectionName.cs index 81a760b..f749d89 100644 --- a/Adaptation/FileHandlers/CellInstanceConnectionName.cs +++ b/Adaptation/FileHandlers/CellInstanceConnectionName.cs @@ -22,9 +22,11 @@ public class CellInstanceConnectionName nameof(OpenInsight) => new OpenInsight.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), nameof(OpenInsightMetrologyViewer) => new OpenInsightMetrologyViewer.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), nameof(OpenInsightMetrologyViewerAttachments) => new OpenInsightMetrologyViewerAttachments.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), + nameof(pdsf) => new pdsf.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), nameof(pcl) => new pcl.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), nameof(Processed) => new Processed.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), nameof(SPaCe) => new SPaCe.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), + nameof(TransmissionControlProtocol) => new TransmissionControlProtocol.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), _ => throw new Exception($"\"{cellInstanceConnectionName}\" not mapped") }; return result; diff --git a/Adaptation/FileHandlers/OpenInsight/FileRead.cs b/Adaptation/FileHandlers/OpenInsight/FileRead.cs index e1a18da..a95e81c 100644 --- a/Adaptation/FileHandlers/OpenInsight/FileRead.cs +++ b/Adaptation/FileHandlers/OpenInsight/FileRead.cs @@ -113,19 +113,20 @@ public class FileRead : Shared.FileRead, IFileRead private Tuple> GetExtractResult(string reportFullPath, DateTime dateTime) { Tuple> results; - ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath); + string[] lines = File.ReadAllLines(reportFullPath); + ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); _Logistics = new Logistics(reportFullPath, processDataStandardFormat); SetFileParameterLotIDToLogisticsMID(); - JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat); + JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(reportFullPath, lines, processDataStandardFormat); List descriptions = pcl.ProcessData.GetDescriptions(jsonElements); Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) - SaveOpenInsightFile(reportFullPath, dateTime, processDataStandardFormat, descriptions, tests); + SaveOpenInsightFile(reportFullPath, dateTime, descriptions, tests); results = new Tuple>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List()); return results; } - private void SaveOpenInsightFile(string reportFullPath, DateTime dateTime, ProcessDataStandardFormat processDataStandardFormat, List descriptions, Test[] tests) + private void SaveOpenInsightFile(string reportFullPath, DateTime dateTime, List descriptions, Test[] tests) { string duplicateFile; bool isDummyRun = false; @@ -158,7 +159,7 @@ public class FileRead : Shared.FileRead, IFileRead else duplicateFile = Path.Combine(duplicateDirectory, $"{$"Viewer {subgroupId}".TrimEnd()} {fileName.Replace("Viewer", string.Empty)}"); string weekOfYear = _Calendar.GetWeekOfYear(_Logistics.DateTimeFromSequence, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); - FromIQS.Save(_OpenInsightApiECDirectory, _Logistics, reportFullPath, processDataStandardFormat, descriptions.First(), subgroupId, weekOfYear); + FromIQS.Save(_OpenInsightApiECDirectory, _Logistics, reportFullPath, descriptions.First(), subgroupId, weekOfYear); } if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) { diff --git a/Adaptation/FileHandlers/OpenInsight/FromIQS.cs b/Adaptation/FileHandlers/OpenInsight/FromIQS.cs index acd8bc6..9a5052c 100644 --- a/Adaptation/FileHandlers/OpenInsight/FromIQS.cs +++ b/Adaptation/FileHandlers/OpenInsight/FromIQS.cs @@ -325,74 +325,18 @@ public class FromIQS return new(result, count, commandText); } - private static string GetJson(Logistics logistics, ProcessDataStandardFormat processDataStandardFormat, pcl.Description description) + internal static void Save(string openInsightApiECDirectory, Logistics logistics, string reportFullPath, pcl.Description description, long? subGroupId, string weekOfYear) { - string result; - StringBuilder stringBuilder = new(); - var @object = new - { - description.MesEntity, - description.Employee, - description.Layer, - description.PSN, - description.RDS, - description.Reactor, - description.Recipe, - description.Zone, - logistics.DateTimeFromSequence.Ticks - }; - string[] pair; - string safeValue; - string[] segments; - string serializerValue; - foreach (string line in processDataStandardFormat.Logistics) - { - segments = line.Split('\t'); - if (segments.Length < 2) - continue; - segments = segments[1].Split(';'); - _ = stringBuilder.Append('{'); - foreach (string segment in segments) - { - pair = segment.Split('='); - if (pair.Length != 2 || pair[0].Length < 3) - continue; - serializerValue = JsonSerializer.Serialize(pair[1]); - safeValue = serializerValue.Substring(1, serializerValue.Length - 2); - _ = stringBuilder.Append('"').Append(pair[0].Substring(2)).Append('"').Append(':').Append('"').Append(safeValue).Append('"').Append(','); - } - if (stringBuilder.Length > 0) - _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); - _ = stringBuilder.Append('}').Append(','); - } - if (stringBuilder.Length > 0) - _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); - _ = stringBuilder.Append(']').Append('}'); - _ = stringBuilder.Insert(0, ",\"Logistics\":["); - string json = JsonSerializer.Serialize(@object); - _ = stringBuilder.Insert(0, json.Substring(0, json.Length - 1)); - JsonElement? jsonElement = JsonSerializer.Deserialize(stringBuilder.ToString()); - result = jsonElement is null ? "{}" : JsonSerializer.Serialize(jsonElement, new JsonSerializerOptions { WriteIndented = true }); - return result; - } - - internal static void Save(string openInsightApiECDirectory, Logistics logistics, string reportFullPath, ProcessDataStandardFormat processDataStandardFormat, pcl.Description description, long? subGroupId, string weekOfYear) - { - string checkFile; string fileName = Path.GetFileName(reportFullPath); - string json = GetJson(logistics, processDataStandardFormat, description); string? ecPathRoot = Path.GetPathRoot(openInsightApiECDirectory); bool ecExists = ecPathRoot is not null && Directory.Exists(ecPathRoot); string weekYear = $"{logistics.DateTimeFromSequence:yyyy}_Week_{weekOfYear}"; string ecDirectory = Path.Combine(openInsightApiECDirectory, weekYear, $"-{description.PSN}", $"-{description.Reactor}", $"-{description.RDS}", $"-{subGroupId}"); if (ecExists && !Directory.Exists(ecDirectory)) _ = Directory.CreateDirectory(ecDirectory); - checkFile = Path.Combine(ecDirectory, fileName); + string checkFile = Path.Combine(ecDirectory, fileName); if (ecExists && !File.Exists(checkFile)) File.Copy(reportFullPath, checkFile); - checkFile = Path.Combine(ecDirectory, $"{logistics.DateTimeFromSequence.Ticks}.json"); - if (ecExists && !File.Exists(checkFile)) - File.WriteAllText(checkFile, json); } } \ No newline at end of file diff --git a/Adaptation/FileHandlers/OpenInsightMetrologyViewer/FileRead.cs b/Adaptation/FileHandlers/OpenInsightMetrologyViewer/FileRead.cs index c8266ef..a3f798c 100644 --- a/Adaptation/FileHandlers/OpenInsightMetrologyViewer/FileRead.cs +++ b/Adaptation/FileHandlers/OpenInsightMetrologyViewer/FileRead.cs @@ -110,10 +110,10 @@ public class FileRead : Shared.FileRead, IFileRead return results; } - private void SendData(string reportFullPath, DateTime dateTime, List descriptions) + private void SendData(string reportFullPath, DateTime dateTime, JsonElement[] jsonElements, List descriptions) { string checkDirectory; - WSRequest wsRequest = new(this, _Logistics, descriptions); + WSRequest wsRequest = new(this, _Logistics, jsonElements, descriptions); int weekOfYear = _Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday); string directory = Path.Combine(_OpenInsightMetrologyViewerFileShare, dateTime.Year.ToString(), $"WW{weekOfYear:00}"); checkDirectory = Path.Combine(directory, _Logistics.Sequence.ToString()); @@ -139,14 +139,15 @@ public class FileRead : Shared.FileRead, IFileRead private Tuple> GetExtractResult(string reportFullPath, DateTime dateTime) { Tuple> results; - ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath); + string[] lines = File.ReadAllLines(reportFullPath); + ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); _Logistics = new Logistics(reportFullPath, processDataStandardFormat); SetFileParameterLotIDToLogisticsMID(); - JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat); + JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(reportFullPath, lines, processDataStandardFormat); List descriptions = pcl.ProcessData.GetDescriptions(jsonElements); Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) - SendData(reportFullPath, dateTime, descriptions); + SendData(reportFullPath, dateTime, jsonElements, descriptions); results = new Tuple>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List()); return results; } diff --git a/Adaptation/FileHandlers/OpenInsightMetrologyViewer/WSRequest.cs b/Adaptation/FileHandlers/OpenInsightMetrologyViewer/WSRequest.cs index 5c6aefc..ae29c0b 100644 --- a/Adaptation/FileHandlers/OpenInsightMetrologyViewer/WSRequest.cs +++ b/Adaptation/FileHandlers/OpenInsightMetrologyViewer/WSRequest.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Text.Json; namespace Adaptation.FileHandlers.OpenInsightMetrologyViewer; @@ -73,7 +74,7 @@ public class WSRequest [Obsolete("For json")] public WSRequest() { } #pragma warning disable IDE0060 - internal WSRequest(IFileRead fileRead, Logistics logistics, List descriptions, string processDataStandardFormat = null) + internal WSRequest(IFileRead fileRead, Logistics logistics, JsonElement[] jsonElements, List descriptions, string processDataStandardFormat = null) #pragma warning restore IDE0060 { Id = -1; @@ -94,7 +95,7 @@ public class WSRequest GradeMean = x.GradeMean; GradeRadialGradient = x.GradeRadialGradient; GradeStdDev = x.GradeStdDev; - Operator = logistics.MesEntity; + Operator = logistics.MesEntity; // different name Layer = x.Layer; Lot = x.Lot; Model = x.Model; @@ -182,14 +183,14 @@ public class WSRequest return result; } - internal static long GetHeaderId(IFileRead fileRead, Logistics logistics, string openInsightMetrologyViewerAPI, string openInsightMetrologyViewerFileShare, int weekOfYear, WS.Results results, List descriptions) + internal static long GetHeaderId(IFileRead fileRead, Logistics logistics, string openInsightMetrologyViewerAPI, string openInsightMetrologyViewerFileShare, int weekOfYear, WS.Results results, JsonElement[] jsonElements, List descriptions) { long result; if (results is not null && results.HeaderId is not null) result = results.HeaderId.Value; else { - WSRequest wsRequest = new(fileRead, logistics, descriptions); + WSRequest wsRequest = new(fileRead, logistics, jsonElements, descriptions); string directory = Path.Combine(openInsightMetrologyViewerFileShare, logistics.DateTimeFromSequence.Year.ToString(), $"WW{weekOfYear:00}"); (_, WS.Results wsResults) = WS.SendData(openInsightMetrologyViewerAPI, logistics.Sequence, directory, wsRequest); if (wsResults.Success is null || !wsResults.Success.Value) diff --git a/Adaptation/FileHandlers/OpenInsightMetrologyViewerAttachments/FileRead.cs b/Adaptation/FileHandlers/OpenInsightMetrologyViewerAttachments/FileRead.cs index 4dfdab1..67deef7 100644 --- a/Adaptation/FileHandlers/OpenInsightMetrologyViewerAttachments/FileRead.cs +++ b/Adaptation/FileHandlers/OpenInsightMetrologyViewerAttachments/FileRead.cs @@ -139,7 +139,7 @@ public class FileRead : Shared.FileRead, IFileRead return result; } - private void PostOpenInsightMetrologyViewerAttachments(List descriptions) + private void PostOpenInsightMetrologyViewerAttachments(JsonElement[] jsonElements, List descriptions) { Shared.Metrology.WS.Results? results; string jobIdDirectory = Path.Combine(Path.GetDirectoryName(_FileConnectorConfiguration.AlternateTargetFolder) ?? throw new Exception(), _Logistics.JobID); @@ -155,7 +155,7 @@ public class FileRead : Shared.FileRead, IFileRead results = wsResults[0]; } int weekOfYear = _Calendar.GetWeekOfYear(_Logistics.DateTimeFromSequence, CalendarWeekRule.FirstDay, DayOfWeek.Sunday); - long headerId = !_IsEAFHosted ? -1 : OpenInsightMetrologyViewer.WSRequest.GetHeaderId(this, _Logistics, _OpenInsightMetrologyViewerAPI, _OpenInsightMetrologyViewerFileShare, weekOfYear, results, descriptions); + long headerId = !_IsEAFHosted ? -1 : OpenInsightMetrologyViewer.WSRequest.GetHeaderId(this, _Logistics, _OpenInsightMetrologyViewerAPI, _OpenInsightMetrologyViewerFileShare, weekOfYear, results, jsonElements, descriptions); string? headerIdDirectory = GetHeaderIdDirectory(headerId); if (string.IsNullOrEmpty(headerIdDirectory)) throw new Exception($"Didn't find header id directory <{headerId}>"); @@ -167,14 +167,15 @@ public class FileRead : Shared.FileRead, IFileRead if (dateTime == DateTime.MinValue) throw new ArgumentNullException(nameof(dateTime)); Tuple> results; - ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath); + string[] lines = File.ReadAllLines(reportFullPath); + ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); _Logistics = new Logistics(reportFullPath, processDataStandardFormat); SetFileParameterLotIDToLogisticsMID(); - JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat); + JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(reportFullPath, lines, processDataStandardFormat); List descriptions = pcl.ProcessData.GetDescriptions(jsonElements); Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) - PostOpenInsightMetrologyViewerAttachments(descriptions); + PostOpenInsightMetrologyViewerAttachments(jsonElements, descriptions); results = new Tuple>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List()); return results; } diff --git a/Adaptation/FileHandlers/Processed/FileRead.cs b/Adaptation/FileHandlers/Processed/FileRead.cs index d105fce..5110055 100644 --- a/Adaptation/FileHandlers/Processed/FileRead.cs +++ b/Adaptation/FileHandlers/Processed/FileRead.cs @@ -108,7 +108,7 @@ public class FileRead : Shared.FileRead, IFileRead return results; } - private void DirectoryMove(string reportFullPath, DateTime dateTime, List descriptions) + private void DirectoryMove(string reportFullPath, DateTime dateTime, JsonElement[] jsonElements, List descriptions) { if (dateTime == DateTime.MinValue) throw new ArgumentNullException(nameof(dateTime)); @@ -122,7 +122,7 @@ public class FileRead : Shared.FileRead, IFileRead throw new Exception("Didn't find directory by logistics sequence"); if (fileInfo.Exists && fileInfo.LastWriteTime < fileInfo.CreationTime) File.SetLastWriteTime(reportFullPath, fileInfo.CreationTime); - OpenInsightMetrologyViewer.WSRequest wsRequest = new(this, _Logistics, descriptions); + OpenInsightMetrologyViewer.WSRequest wsRequest = new(this, _Logistics, jsonElements, descriptions); JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; string json = JsonSerializer.Serialize(wsRequest, wsRequest.GetType(), jsonSerializerOptions); string directoryName = $"{Path.GetFileName(matchDirectories[0]).Split(new string[] { logisticsSequence }, StringSplitOptions.None)[0]}{_Logistics.DateTimeFromSequence:yyyy-MM-dd_hh;mm_tt_}{DateTime.Now.Ticks - _Logistics.Sequence}"; @@ -166,23 +166,24 @@ public class FileRead : Shared.FileRead, IFileRead private Tuple> GetExtractResult(string reportFullPath, DateTime dateTime) { Tuple> results; - ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath); + string[] lines = File.ReadAllLines(reportFullPath); + ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); _Logistics = new Logistics(reportFullPath, processDataStandardFormat); SetFileParameterLotIDToLogisticsMID(); - JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat); + JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(reportFullPath, lines, processDataStandardFormat); List descriptions = pcl.ProcessData.GetDescriptions(jsonElements); Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); results = new Tuple>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List()); if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) - DirectoryMove(reportFullPath, dateTime, descriptions); + DirectoryMove(reportFullPath, dateTime, jsonElements, descriptions); else if (!_IsEAFHosted) { - OpenInsightMetrologyViewer.WSRequest wsRequest = new(this, _Logistics, descriptions); + OpenInsightMetrologyViewer.WSRequest wsRequest = new(this, _Logistics, jsonElements, descriptions); JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; - string json = JsonSerializer.Serialize(wsRequest, wsRequest.GetType(), jsonSerializerOptions); + string check = JsonSerializer.Serialize(wsRequest, wsRequest.GetType(), jsonSerializerOptions); string jsonFileName = Path.ChangeExtension(reportFullPath, ".json"); string historicalText = File.ReadAllText(jsonFileName); - if (json != historicalText) + if (check != historicalText) throw new Exception("File doesn't match historical!"); } return results; diff --git a/Adaptation/FileHandlers/TransmissionControlProtocol/FileRead.cs b/Adaptation/FileHandlers/TransmissionControlProtocol/FileRead.cs new file mode 100644 index 0000000..2443398 --- /dev/null +++ b/Adaptation/FileHandlers/TransmissionControlProtocol/FileRead.cs @@ -0,0 +1,250 @@ +using Adaptation.Eaf.Management.ConfigurationData.CellAutomation; +using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; +using Adaptation.Shared; +using Adaptation.Shared.Duplicator; +using Adaptation.Shared.Methods; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Sockets; +using System.Reflection; +using System.Text; +using System.Text.Json; +using System.Threading; + +namespace Adaptation.FileHandlers.TransmissionControlProtocol; + +#nullable enable + +public class FileRead : Shared.FileRead, IFileRead +{ + + private readonly int _Port; + private readonly Timer _Timer; + private static Record? _Record; + private static long _LastWrite; + private readonly string _IPAddress; + private readonly string _RawDirectory; + private readonly int _DelimiterSeconds; + private readonly string[] _DelimiterPatterns; + private static readonly object _Lock = new(); + + public FileRead(ISMTP smtp, Dictionary fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList modelObjectParameters, string equipmentDictionaryName, Dictionary> dummyRuns, Dictionary> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : + base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) + { + _MinFileLength = 10; + _NullData = string.Empty; + _Logistics = new(this); + if (_FileParameter is null) + throw new Exception(cellInstanceConnectionName); + if (_ModelObjectParameterDefinitions is null) + throw new Exception(cellInstanceConnectionName); + if (_IsDuplicator) + throw new Exception(cellInstanceConnectionName); + string sourceFileLocation = fileConnectorConfiguration.SourceFileLocation.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + string? ipAddress = Path.GetDirectoryName(sourceFileLocation); + string port = Path.GetFileName(sourceFileLocation); + _Timer = new Timer(Callback, null, Timeout.Infinite, Timeout.Infinite); + _Port = int.Parse(port, System.Globalization.CultureInfo.InvariantCulture); + _DelimiterPatterns = fileConnectorConfiguration.SourceFileFilter.Split('*'); + _IPAddress = Path.GetFileName(ipAddress) ?? throw new Exception(sourceFileLocation); + _RawDirectory = Path.GetDirectoryName(ipAddress) ?? throw new Exception(sourceFileLocation); + DateTime fileAgeThresholdTimeOnly = GetFileAgeThresholdTimeOnly(_FileConnectorConfiguration.FileAgeThreshold); + _DelimiterSeconds = fileAgeThresholdTimeOnly.Second; + if (Debugger.IsAttached || fileConnectorConfiguration.PreProcessingMode == FileConnectorConfiguration.PreProcessingModeEnum.Process || _FileConnectorConfiguration.FileScanningIntervalInSeconds is null) + Callback(null); + else + { + TimeSpan timeSpan = new(DateTime.Now.AddSeconds(_FileConnectorConfiguration.FileScanningIntervalInSeconds.Value).Ticks - DateTime.Now.Ticks); + _ = _Timer.Change((long)timeSpan.TotalMilliseconds, Timeout.Infinite); + } + } + + void IFileRead.Move(Tuple> extractResults, Exception exception) => Move(extractResults); + + void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); + + string IFileRead.GetEventDescription() + { + string result = _Description.GetEventDescription(); + return result; + } + + List IFileRead.GetHeaderNames() + { + List results = _Description.GetHeaderNames(); + return results; + } + + string[] IFileRead.Move(Tuple> extractResults, string to, string from, string resolvedFileLocation, Exception exception) + { + string[] results = Move(extractResults, to, from, resolvedFileLocation, exception); + return results; + } + + JsonProperty[] IFileRead.GetDefault() + { + JsonProperty[] results = _Description.GetDefault(this, _Logistics); + return results; + } + + Dictionary IFileRead.GetDisplayNamesJsonElement() + { + Dictionary results = _Description.GetDisplayNamesJsonElement(this); + return results; + } + + List IFileRead.GetDescriptions(IFileRead fileRead, List tests, IProcessData processData) + { + List results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData); + return results; + } + + Tuple> IFileRead.GetExtractResult(string reportFullPath, string eventName) => throw new Exception(string.Concat("See ", nameof(Callback))); + + Tuple> IFileRead.ReExtract() => throw new Exception(string.Concat("See ", nameof(Callback))); + + private static DateTime GetFileAgeThresholdTimeOnly(string fileAgeThreshold) + { + DateTime result = DateTime.MinValue; + string[] segments = fileAgeThreshold.Split(':'); + for (int i = 0; i < segments.Length; i++) + { + result = i switch + { + 0 => result.AddDays(double.Parse(segments[i])), + 1 => result.AddHours(double.Parse(segments[i])), + 2 => result.AddMinutes(double.Parse(segments[i])), + 3 => result.AddSeconds(double.Parse(segments[i])), + _ => throw new Exception(), + }; + } + return result; + } + + private static void ReadFiles(log4net.ILog log, FileConnectorConfiguration fileConnectorConfiguration, string ipAddress, string rawDirectory) + { + List bytes = new(); + string[] files = Directory.GetFiles(rawDirectory, $"{ipAddress}-*.raw", SearchOption.TopDirectoryOnly); + log.Info($"Read {files.Length} files"); + foreach (string file in files) + { + foreach (byte @byte in File.ReadAllBytes(file)) + bytes.Add(@byte); + } + if (bytes.Count > 0) + { + string bytesFile = Path.Combine(fileConnectorConfiguration.TargetFileLocation, $"{ipAddress}-{DateTime.Now.Ticks}{fileConnectorConfiguration.TargetFileName}"); + File.WriteAllBytes(bytesFile, bytes.ToArray()); + foreach (string file in files) + File.Delete(file); + } + } + + private static void CreateClient(log4net.ILog log, string ipAddress, int port) + { + log.Debug(ipAddress); + TcpClient tcpClient = new(ipAddress, port); + NetworkStream networkStream = tcpClient.GetStream(); + Type baseType = typeof(NetworkStream); + PropertyInfo? propertyInfo = baseType.GetProperty("Socket", BindingFlags.Instance | BindingFlags.NonPublic); + _Record = new(binaryReader: new(networkStream), binaryWriter: new(networkStream), networkStream: networkStream, propertyInfo: propertyInfo, readTimes: new()); + } + + private static byte[] GetBytes(NetworkStream networkStream) + { + List results = new(); + byte[] bytes = new byte[1024]; + do + { + int count = networkStream.Read(bytes, 0, bytes.Length); + if (count > 0) + results.AddRange(bytes.Take(count)); + } + while (networkStream.DataAvailable); + return results.ToArray(); + } + + private void Callback() + { + if (_Record?.NetworkStream is null || _Record.PropertyInfo is null || _Record.PropertyInfo.GetValue(_Record.NetworkStream) is not Socket socket || !socket.Connected) + CreateClient(_Log, _IPAddress, _Port); + if (_Record is not null) + { + TimeSpan timeSpan = new(DateTime.Now.Ticks - _LastWrite); + if (_LastWrite == 0 || timeSpan.TotalMinutes > 1) + { + try + { + _Record.NetworkStream.WriteByte(Convert.ToByte('\0')); + _LastWrite = DateTime.Now.Ticks; + } + catch (Exception) + { } + } + } + if (_Record?.NetworkStream is not null && _Record.NetworkStream.CanRead && _Record.NetworkStream.DataAvailable) + { + byte[] bytes = GetBytes(_Record.NetworkStream); + _Log.Info($"Read {bytes.Length} bytes"); + if (bytes.Length > 0) + { + string path = Path.Combine(_RawDirectory, $"{_IPAddress}-{DateTime.Now.Ticks}.raw"); + File.WriteAllBytes(path, bytes); + string content = Encoding.ASCII.GetString(bytes); + _Log.Debug($"Content {content}"); + foreach (string delimiterPattern in _DelimiterPatterns) + { + if (content.Contains(delimiterPattern)) + _Record.ReadTimes.Add(DateTime.Now.Ticks); + } + if (_Record.ReadTimes.Count > 0) + _Record.ReadTimes.Add(DateTime.Now.Ticks); + } + } + if (_Record is not null && _Record.ReadTimes.Count > 0 && _DelimiterSeconds > 0) + { + TimeSpan? timeSpan = new(DateTime.Now.Ticks - _Record.ReadTimes.Last()); + if (timeSpan.Value.TotalSeconds > _DelimiterSeconds) + { + ReadFiles(_Log, _FileConnectorConfiguration, _IPAddress, _RawDirectory); + _Record.ReadTimes.Clear(); + } + } + } + + private void Callback(object? state) + { + try + { + lock (_Lock) + Callback(); + } + catch (Exception exception) + { + string subject = string.Concat("Exception:", _CellInstanceConnectionName); + string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace); + try + { _SMTP.SendHighPriorityEmailMessage(subject, body); } + catch (Exception) { } + } + try + { + if (_FileConnectorConfiguration.FileScanningIntervalInSeconds is null) + throw new Exception(_CellInstanceConnectionName); + TimeSpan timeSpan = new(DateTime.Now.AddSeconds(_FileConnectorConfiguration.FileScanningIntervalInSeconds.Value).Ticks - DateTime.Now.Ticks); + _ = _Timer.Change((long)timeSpan.TotalMilliseconds, Timeout.Infinite); + } + catch (Exception exception) + { + string subject = string.Concat("Exception:", _CellInstanceConnectionName); + string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace); + try + { _SMTP.SendHighPriorityEmailMessage(subject, body); } + catch (Exception) { } + } + } + +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/TransmissionControlProtocol/Record.cs b/Adaptation/FileHandlers/TransmissionControlProtocol/Record.cs new file mode 100644 index 0000000..f041aa1 --- /dev/null +++ b/Adaptation/FileHandlers/TransmissionControlProtocol/Record.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.IO; +using System.Net.Sockets; +using System.Reflection; + +namespace Adaptation.FileHandlers.TransmissionControlProtocol; + +#nullable enable + +internal class Record +{ + + public BinaryReader BinaryReader { get; } + public BinaryWriter BinaryWriter { get; } + public NetworkStream NetworkStream { get; } + public PropertyInfo? PropertyInfo { get; } + public List ReadTimes { get; } + + public Record(BinaryReader binaryReader, BinaryWriter binaryWriter, NetworkStream networkStream, PropertyInfo? propertyInfo, List readTimes) + { + BinaryReader = binaryReader; + BinaryWriter = binaryWriter; + NetworkStream = networkStream; + PropertyInfo = propertyInfo; + ReadTimes = readTimes; + } + +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/pcl/Description.cs b/Adaptation/FileHandlers/pcl/Description.cs index 9849c64..d3fc847 100644 --- a/Adaptation/FileHandlers/pcl/Description.cs +++ b/Adaptation/FileHandlers/pcl/Description.cs @@ -4,111 +4,112 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text.Json; +using System.Text.Json.Serialization; namespace Adaptation.FileHandlers.pcl; public class Description : IDescription, Shared.Properties.IDescription { - public int Test { get; set; } - public int Count { get; set; } - public int Index { get; set; } + [JsonPropertyName("EventId")] public int Test { get; set; } + [JsonPropertyName("Count")] public int Count { get; set; } + [JsonPropertyName("Index")] public int Index { get; set; } // public string EventName { get; set; } public string NullData { get; set; } public string JobID { get; set; } public string Sequence { get; set; } - public string MesEntity { get; set; } + [JsonPropertyName("MesEntity")] public string MesEntity { get; set; } public string ReportFullPath { get; set; } public string ProcessJobID { get; set; } public string MID { get; set; } // - public string Date { get; set; } - public string Employee { get; set; } - public string Lot { get; set; } - public string PSN { get; set; } - public string Reactor { get; set; } - public string Recipe { get; set; } + [JsonPropertyName("Date")] public string Date { get; set; } + [JsonPropertyName("Employee")] public string Employee { get; set; } + [JsonPropertyName("Lot")] public string Lot { get; set; } + [JsonPropertyName("PSN")] public string PSN { get; set; } + [JsonPropertyName("Reactor")] public string Reactor { get; set; } + [JsonPropertyName("Recipe")] public string Recipe { get; set; } // - public string Area { get; set; } - public string Folder { get; set; } + [JsonPropertyName("Area")] public string Area { get; set; } + [JsonPropertyName("Folder")] public string Folder { get; set; } public string HeaderUniqueId { get; set; } public string Id { get; set; } - public string Layer { get; set; } - public string Model { get; set; } - public string Pattern { get; set; } - public string Phase { get; set; } - public string Plan { get; set; } - public string RampRate { get; set; } - public string RDS { get; set; } - public string SetupFile { get; set; } - public string StartVoltage { get; set; } - public string StopVoltage { get; set; } + [JsonPropertyName("Layer")] public string Layer { get; set; } + [JsonPropertyName("Model")] public string Model { get; set; } + [JsonPropertyName("Pattern")] public string Pattern { get; set; } + [JsonPropertyName("Phase")] public string Phase { get; set; } + [JsonPropertyName("Plan")] public string Plan { get; set; } + [JsonPropertyName("RampRate")] public string RampRate { get; set; } + [JsonPropertyName("RDS")] public string RDS { get; set; } + [JsonPropertyName("SetupFile")] public string SetupFile { get; set; } + [JsonPropertyName("StartVoltage")] public string StartVoltage { get; set; } + [JsonPropertyName("StopVoltage")] public string StopVoltage { get; set; } public string UniqueId { get; set; } - public string Wafer { get; set; } - public string WaferSize { get; set; } - public string Zone { get; set; } + [JsonPropertyName("Wafer")] public string Wafer { get; set; } + [JsonPropertyName("WaferSize")] public string WaferSize { get; set; } + [JsonPropertyName("Zone")] public string Zone { get; set; } // - public string Ccomp { get; set; } - public string CondType { get; set; } - public string FlatZ { get; set; } - public string FlatZMean { get; set; } - public string FlatZRadialGradient { get; set; } - public string FlatZStdDev { get; set; } - public string GLimit { get; set; } - public string Grade { get; set; } - public string GradeMean { get; set; } - public string GradeRadialGradient { get; set; } - public string GradeStdDev { get; set; } - public string NAvg { get; set; } - public string NAvgMean { get; set; } - public string NAvgRadialGradient { get; set; } - public string NAvgStdDev { get; set; } - public string Nsl { get; set; } - public string NslMean { get; set; } - public string NslRadialGradient { get; set; } - public string NslStdDev { get; set; } - public string PhaseMean { get; set; } - public string PhaseRadialGradient { get; set; } - public string PhaseStdDev { get; set; } - public string RhoAvg { get; set; } - public string RhoAvgMean { get; set; } - public string RhoAvgRadialGradient { get; set; } - public string RhoAvgStdDev { get; set; } - public string RhoMethod { get; set; } - public string Rhosl { get; set; } - public string RhoslMean { get; set; } - public string RhoslRadialGradient { get; set; } - public string RhoslStdDev { get; set; } - public string RsMean { get; set; } - public string RsRadialGradient { get; set; } - public string RsStdDev { get; set; } - public string Vd { get; set; } - public string VdMean { get; set; } - public string VdRadialGradient { get; set; } - public string VdStdDev { get; set; } + [JsonPropertyName("Ccomp")] public string Ccomp { get; set; } + [JsonPropertyName("CondType")] public string CondType { get; set; } + [JsonPropertyName("FlatZ")] public string FlatZ { get; set; } + [JsonPropertyName("MeanFlatZ")] public string FlatZMean { get; set; } + [JsonPropertyName("RadialGradientFlatZ")] public string FlatZRadialGradient { get; set; } + [JsonPropertyName("StandardDeviationPercentageFlatZ")] public string FlatZStdDev { get; set; } + [JsonPropertyName("GLimit")] public string GLimit { get; set; } + [JsonPropertyName("Grade")] public string Grade { get; set; } + [JsonPropertyName("MeanGrade")] public string GradeMean { get; set; } + [JsonPropertyName("RadialGradientGrade")] public string GradeRadialGradient { get; set; } + [JsonPropertyName("StandardDeviationPercentageGrade")] public string GradeStdDev { get; set; } + [JsonPropertyName("NAvg")] public string NAvg { get; set; } + [JsonPropertyName("MeanNAvg")] public string NAvgMean { get; set; } + [JsonPropertyName("RadialGradientNAvg")] public string NAvgRadialGradient { get; set; } + [JsonPropertyName("StandardDeviationPercentageNAvg")] public string NAvgStdDev { get; set; } + [JsonPropertyName("Nsl")] public string Nsl { get; set; } + [JsonPropertyName("MeanNsl")] public string NslMean { get; set; } + [JsonPropertyName("RadialGradientNsl")] public string NslRadialGradient { get; set; } + [JsonPropertyName("StandardDeviationPercentageNsl")] public string NslStdDev { get; set; } + [JsonPropertyName("MeanPhase")] public string PhaseMean { get; set; } + [JsonPropertyName("RadialGradientPhase")] public string PhaseRadialGradient { get; set; } + [JsonPropertyName("StandardDeviationPercentagePhase")] public string PhaseStdDev { get; set; } + [JsonPropertyName("RhoAvg")] public string RhoAvg { get; set; } + [JsonPropertyName("MeanRhoAvg")] public string RhoAvgMean { get; set; } + [JsonPropertyName("RadialGradientRhoAvg")] public string RhoAvgRadialGradient { get; set; } + [JsonPropertyName("StandardDeviationPercentageRhoAvg")] public string RhoAvgStdDev { get; set; } + [JsonPropertyName("RhoMethod")] public string RhoMethod { get; set; } + [JsonPropertyName("Rhosl")] public string Rhosl { get; set; } + [JsonPropertyName("MeanRhosl")] public string RhoslMean { get; set; } + [JsonPropertyName("RadialGradientRhosl")] public string RhoslRadialGradient { get; set; } + [JsonPropertyName("StandardDeviationPercentageRhosl")] public string RhoslStdDev { get; set; } + [JsonPropertyName("MeanRs")] public string RsMean { get; set; } + [JsonPropertyName("RadialGradientRs")] public string RsRadialGradient { get; set; } + [JsonPropertyName("StandardDeviationPercentageRs")] public string RsStdDev { get; set; } + [JsonPropertyName("Vd")] public string Vd { get; set; } + [JsonPropertyName("MeanVd")] public string VdMean { get; set; } + [JsonPropertyName("RadialGradientVd")] public string VdRadialGradient { get; set; } + [JsonPropertyName("StandardDeviationPercentageVd")] public string VdStdDev { get; set; } // - public string Variation { get; set; } - public string AreaDeltaFromLastRun { get; set; } + [JsonPropertyName("Variation")] public string Variation { get; set; } + [JsonPropertyName("AreaDeltaFromLastRun")] public string AreaDeltaFromLastRun { get; set; } // - public string Nine10mmEdgeMean { get; set; } - public string Nine4mmEdgeMean { get; set; } - public string NineCriticalPointsAverage { get; set; } - public string NineCriticalPointsPhaseAngleAverage { get; set; } - public string NineCriticalPointsStdDev { get; set; } - public string NineEdgeMeanDelta { get; set; } - public string NineMean { get; set; } - public string NineResRangePercent { get; set; } + [JsonPropertyName("Nine10mmEdgeMean")] public string Nine10mmEdgeMean { get; set; } + [JsonPropertyName("Nine4mmEdgeMean")] public string Nine4mmEdgeMean { get; set; } + [JsonPropertyName("NineCriticalPointsAverage")] public string NineCriticalPointsAverage { get; set; } + [JsonPropertyName("NineCriticalPointsPhaseAngleAverage")] public string NineCriticalPointsPhaseAngleAverage { get; set; } + [JsonPropertyName("NineCriticalPointsStdDev")] public string NineCriticalPointsStdDev { get; set; } + [JsonPropertyName("NineEdgeMeanDelta")] public string NineEdgeMeanDelta { get; set; } + [JsonPropertyName("NineMean")] public string NineMean { get; set; } + [JsonPropertyName("NineResRangePercent")] public string NineResRangePercent { get; set; } // - public string RhoAvg01 { get; set; } - public string RhoAvg02 { get; set; } - public string RhoAvg03 { get; set; } - public string RhoAvg04 { get; set; } - public string RhoAvg05 { get; set; } - public string RhoAvg06 { get; set; } - public string RhoAvg07 { get; set; } - public string RhoAvg08 { get; set; } - public string RhoAvg09 { get; set; } + [JsonPropertyName("RhoAvg01")] public string RhoAvg01 { get; set; } + [JsonPropertyName("RhoAvg02")] public string RhoAvg02 { get; set; } + [JsonPropertyName("RhoAvg03")] public string RhoAvg03 { get; set; } + [JsonPropertyName("RhoAvg04")] public string RhoAvg04 { get; set; } + [JsonPropertyName("RhoAvg05")] public string RhoAvg05 { get; set; } + [JsonPropertyName("RhoAvg06")] public string RhoAvg06 { get; set; } + [JsonPropertyName("RhoAvg07")] public string RhoAvg07 { get; set; } + [JsonPropertyName("RhoAvg08")] public string RhoAvg08 { get; set; } + [JsonPropertyName("RhoAvg09")] public string RhoAvg09 { get; set; } string IDescription.GetEventDescription() => "File Has been read and parsed"; @@ -511,4 +512,16 @@ public class Description : IDescription, Shared.Properties.IDescription internal static string GetDateFormat() => "MM/dd/yyyy hh:mm:ss tt"; +} + +[JsonSourceGenerationOptions(WriteIndented = true, NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] +[JsonSerializable(typeof(Description))] +internal partial class DescriptionSourceGenerationContext : JsonSerializerContext +{ +} + +[JsonSourceGenerationOptions(WriteIndented = true, NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] +[JsonSerializable(typeof(Description[]))] +internal partial class DescriptionArraySourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Adaptation/FileHandlers/pcl/Detail.cs b/Adaptation/FileHandlers/pcl/Detail.cs index aba9965..a37a3f1 100644 --- a/Adaptation/FileHandlers/pcl/Detail.cs +++ b/Adaptation/FileHandlers/pcl/Detail.cs @@ -1,19 +1,33 @@ -namespace Adaptation.FileHandlers.pcl; +using System.Text.Json.Serialization; + +namespace Adaptation.FileHandlers.pcl; public class Detail { - public string FlatZ { get; set; } - public string Grade { get; set; } + [JsonPropertyName("FlatZ")] public string FlatZ { get; set; } + [JsonPropertyName("Grade")] public string Grade { get; set; } public string HeaderUniqueId { get; set; } - public string NAvg { get; set; } - public string Nsl { get; set; } - public string Phase { get; set; } - public string RhoAvg { get; set; } - public string Rhosl { get; set; } + [JsonPropertyName("NAvg")] public string NAvg { get; set; } + [JsonPropertyName("Nsl")] public string Nsl { get; set; } + [JsonPropertyName("Phase")] public string Phase { get; set; } + [JsonPropertyName("RhoAvg")] public string RhoAvg { get; set; } + [JsonPropertyName("Rhosl")] public string Rhosl { get; set; } public string UniqueId { get; set; } - public string Vd { get; set; } + [JsonPropertyName("Vd")] public string Vd { get; set; } public override string ToString() => string.Concat(FlatZ, ";", Grade); +} + +[JsonSourceGenerationOptions(WriteIndented = true, NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] +[JsonSerializable(typeof(Detail))] +internal partial class DetailSourceGenerationContext : JsonSerializerContext +{ +} + +[JsonSourceGenerationOptions(WriteIndented = true, NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] +[JsonSerializable(typeof(Detail[]))] +internal partial class DetailArraySourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Adaptation/FileHandlers/pcl/Header.cs b/Adaptation/FileHandlers/pcl/Header.cs index 96b8b0e..a6de8e7 100644 --- a/Adaptation/FileHandlers/pcl/Header.cs +++ b/Adaptation/FileHandlers/pcl/Header.cs @@ -155,7 +155,7 @@ internal class Header else { json = JsonSerializer.Serialize(keyValuePairs); - result = JsonSerializer.Deserialize(json, HeaderSourceGenerationContext.Default.Header) ?? throw new NullReferenceException(nameof(result)); + result = JsonSerializer.Deserialize(json, PCLHeaderSourceGenerationContext.Default.Header) ?? throw new NullReferenceException(nameof(result)); } return result; } @@ -164,6 +164,6 @@ internal class Header [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Header))] -internal partial class HeaderSourceGenerationContext : JsonSerializerContext +internal partial class PCLHeaderSourceGenerationContext : JsonSerializerContext { } \ No newline at end of file diff --git a/Adaptation/FileHandlers/pcl/Point.cs b/Adaptation/FileHandlers/pcl/Point.cs index 83767b8..c58b16f 100644 --- a/Adaptation/FileHandlers/pcl/Point.cs +++ b/Adaptation/FileHandlers/pcl/Point.cs @@ -138,6 +138,6 @@ internal class Point [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Point))] -internal partial class PointSourceGenerationContext : JsonSerializerContext +internal partial class PCLPointSourceGenerationContext : JsonSerializerContext { } \ No newline at end of file diff --git a/Adaptation/FileHandlers/pcl/ProcessData.cs b/Adaptation/FileHandlers/pcl/ProcessData.cs index ec5065a..07d1661 100644 --- a/Adaptation/FileHandlers/pcl/ProcessData.cs +++ b/Adaptation/FileHandlers/pcl/ProcessData.cs @@ -615,12 +615,11 @@ internal class ProcessData : IProcessData { List results = new(); Description? description; - JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString }; foreach (JsonElement jsonElement in jsonElements) { if (jsonElement.ValueKind != JsonValueKind.Object) throw new Exception(); - description = JsonSerializer.Deserialize(jsonElement.ToString(), jsonSerializerOptions); + description = JsonSerializer.Deserialize(jsonElement.ToString(), DescriptionSourceGenerationContext.Default.Description); if (description is null) continue; results.Add(description); diff --git a/Adaptation/FileHandlers/pcl/Row.cs b/Adaptation/FileHandlers/pcl/Row.cs index 0dd4cd4..1d7e117 100644 --- a/Adaptation/FileHandlers/pcl/Row.cs +++ b/Adaptation/FileHandlers/pcl/Row.cs @@ -191,6 +191,6 @@ internal class Row [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Row))] -internal partial class RowSourceGenerationContext : JsonSerializerContext +internal partial class PCLRowSourceGenerationContext : JsonSerializerContext { } \ No newline at end of file diff --git a/Adaptation/FileHandlers/pcl/Run.cs b/Adaptation/FileHandlers/pcl/Run.cs index 89a4c20..70e264d 100644 --- a/Adaptation/FileHandlers/pcl/Run.cs +++ b/Adaptation/FileHandlers/pcl/Run.cs @@ -43,7 +43,7 @@ internal class Run private static void WriteJson(Logistics logistics, List fileInfoCollection, Run result) { FileInfo fileInfo = new($"{logistics.ReportFullPath}.run.json"); - string json = JsonSerializer.Serialize(result, RunSourceGenerationContext.Default.Run); + string json = JsonSerializer.Serialize(result, PCLRunSourceGenerationContext.Default.Run); File.WriteAllText(fileInfo.FullName, json); File.SetLastWriteTime(fileInfo.FullName, logistics.DateTimeFromSequence); fileInfoCollection.Add(fileInfo); @@ -143,6 +143,6 @@ internal class Run [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Run))] -internal partial class RunSourceGenerationContext : JsonSerializerContext +internal partial class PCLRunSourceGenerationContext : JsonSerializerContext { } \ No newline at end of file diff --git a/Adaptation/FileHandlers/pcl/Summary.cs b/Adaptation/FileHandlers/pcl/Summary.cs index 3b1e597..ff598d0 100644 --- a/Adaptation/FileHandlers/pcl/Summary.cs +++ b/Adaptation/FileHandlers/pcl/Summary.cs @@ -22,6 +22,6 @@ internal class Summary [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Summary))] -internal partial class SummarySourceGenerationContext : JsonSerializerContext +internal partial class PCLSummarySourceGenerationContext : JsonSerializerContext { } \ No newline at end of file diff --git a/Adaptation/FileHandlers/pcl/SummarySegment.cs b/Adaptation/FileHandlers/pcl/SummarySegment.cs index 525cccc..bfbd237 100644 --- a/Adaptation/FileHandlers/pcl/SummarySegment.cs +++ b/Adaptation/FileHandlers/pcl/SummarySegment.cs @@ -100,11 +100,11 @@ internal class SummarySegment else { json = JsonSerializer.Serialize(keyValuePairs); - SummarySegment? mean = JsonSerializer.Deserialize(json, SummarySegmentSourceGenerationContext.Default.SummarySegment); + SummarySegment? mean = JsonSerializer.Deserialize(json, PCLSummarySegmentSourceGenerationContext.Default.SummarySegment); json = JsonSerializer.Serialize(keyValuePairsB); - SummarySegment? standardDeviationPercentage = JsonSerializer.Deserialize(json, SummarySegmentSourceGenerationContext.Default.SummarySegment); + SummarySegment? standardDeviationPercentage = JsonSerializer.Deserialize(json, PCLSummarySegmentSourceGenerationContext.Default.SummarySegment); json = JsonSerializer.Serialize(keyValuePairsC); - SummarySegment? radialGradient = JsonSerializer.Deserialize(json, SummarySegmentSourceGenerationContext.Default.SummarySegment); + SummarySegment? radialGradient = JsonSerializer.Deserialize(json, PCLSummarySegmentSourceGenerationContext.Default.SummarySegment); result = new(mean, standardDeviationPercentage, radialGradient); } return result; @@ -114,6 +114,6 @@ internal class SummarySegment [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(SummarySegment))] -internal partial class SummarySegmentSourceGenerationContext : JsonSerializerContext +internal partial class PCLSummarySegmentSourceGenerationContext : JsonSerializerContext { } \ No newline at end of file diff --git a/Adaptation/FileHandlers/pdsf/Constant.cs b/Adaptation/FileHandlers/pdsf/Constant.cs new file mode 100644 index 0000000..5f652e1 --- /dev/null +++ b/Adaptation/FileHandlers/pdsf/Constant.cs @@ -0,0 +1,13 @@ +namespace Adaptation.FileHandlers.pdsf; + +internal class Constant +{ + + public int Take { get; } = 11; + public string Site { get; } = "Site: "; + public string Multiple { get; } = "MULTIPLE"; + public string SummaryLine { get; } = "SUMMARY A A"; + public string LastUnits { get; } = "Flat Z: Grade : % Flat Z: Grade : % Flat Z: Grade : %"; + public string LastUnitsB { get; } = "Flat Z: Grade : % Flat Z: Grade : % Flat Z: Grade : %"; + +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/pdsf/Convert.cs b/Adaptation/FileHandlers/pdsf/Convert.cs new file mode 100644 index 0000000..ed4df9b --- /dev/null +++ b/Adaptation/FileHandlers/pdsf/Convert.cs @@ -0,0 +1,89 @@ +using Adaptation.Shared; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.IO; + +namespace Adaptation.FileHandlers.pdsf; + +internal class Convert +{ + + /// + /// Convert the raw data file to parsable file format - in this case from PCL to PDF + /// + /// source file to be converted to PDF + /// + private static string ConvertSourceFileToPdf(Logistics logistics, string ghostPCLFileName) + { + string result = Path.ChangeExtension(logistics.ReportFullPath, ".pdf"); + if (!File.Exists(result)) + { + //string arguments = string.Concat("-i \"", sourceFile, "\" -o \"", result, "\""); + string arguments = string.Concat("-dSAFER -dBATCH -dNOPAUSE -dFIXEDMEDIA -dFitPage -dAutoRotatePages=/All -dDEVICEWIDTHPOINTS=792 -dDEVICEHEIGHTPOINTS=612 -sOutputFile=\"", result, "\" -sDEVICE=pdfwrite \"", logistics.ReportFullPath, "\""); + //Process process = Process.Start(configData.LincPDFCFileName, arguments); + Process process = Process.Start(ghostPCLFileName, arguments); + _ = process.WaitForExit(30000); + if (!File.Exists(result)) + throw new Exception("PDF file wasn't created"); + } + return result; + } + + private static ReadOnlyCollection GetTextFromPDF(string pdfTextStripperFileName, string sourceFileNamePdf, string altHeaderFileName) + { + string[] result; + ProcessStartInfo processStartInfo = new(pdfTextStripperFileName, $"s \"{sourceFileNamePdf}\"") + { + UseShellExecute = false, + RedirectStandardError = true, + RedirectStandardOutput = true, + }; + Process process = Process.Start(processStartInfo); + _ = process.WaitForExit(30000); + if (!File.Exists(altHeaderFileName)) + result = Array.Empty(); + else + result = File.ReadAllLines(altHeaderFileName); + return new(result); + } + + internal static ReadOnlyCollection PDF(Logistics logistics, string ghostPCLFileName, string pdfTextStripperFileName, List fileInfoCollection) + { + ReadOnlyCollection result; + string sourceFileNamePdf = ConvertSourceFileToPdf(logistics, ghostPCLFileName); + fileInfoCollection.Add(new FileInfo(sourceFileNamePdf)); + string altHeaderFileName = Path.ChangeExtension(logistics.ReportFullPath, ".txt"); + if (File.Exists(altHeaderFileName)) + { + result = new(File.ReadAllLines(altHeaderFileName)); + fileInfoCollection.Add(new FileInfo(altHeaderFileName)); + } + else + { + try + { + //Pdfbox, IKVM.AWT.WinForms + org.apache.pdfbox.pdmodel.PDDocument pdfDocument = org.apache.pdfbox.pdmodel.PDDocument.load(sourceFileNamePdf); + org.apache.pdfbox.util.PDFTextStripper stripper = new(); + string text = stripper.getText(pdfDocument); + pdfDocument.close(); + File.AppendAllText(altHeaderFileName, text); + fileInfoCollection.Add(new FileInfo(altHeaderFileName)); + result = new(text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)); + } + catch (MissingMethodException) + { + if (!File.Exists(pdfTextStripperFileName)) + throw; + result = GetTextFromPDF(pdfTextStripperFileName, sourceFileNamePdf, altHeaderFileName); + if (result.Count == 0) + throw; + fileInfoCollection.Add(new FileInfo(altHeaderFileName)); + } + } + return result; + } + +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/pdsf/FileRead.cs b/Adaptation/FileHandlers/pdsf/FileRead.cs new file mode 100644 index 0000000..3cfffff --- /dev/null +++ b/Adaptation/FileHandlers/pdsf/FileRead.cs @@ -0,0 +1,136 @@ +using Adaptation.Eaf.Management.ConfigurationData.CellAutomation; +using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; +using Adaptation.Shared; +using Adaptation.Shared.Duplicator; +using Adaptation.Shared.Methods; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Text.Json; + +namespace Adaptation.FileHandlers.pdsf; + +public class FileRead : Shared.FileRead, IFileRead +{ + + private readonly string _GhostPCLFileName; + private readonly string _PDFTextStripperFileName; + + public FileRead(ISMTP smtp, Dictionary fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList modelObjectParameters, string equipmentDictionaryName, Dictionary> dummyRuns, Dictionary> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : + base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) + { + _MinFileLength = 150; + _NullData = string.Empty; + _Logistics = new(this); + if (_FileParameter is null) + throw new Exception(cellInstanceConnectionName); + if (_ModelObjectParameterDefinitions is null) + throw new Exception(cellInstanceConnectionName); + if (_IsDuplicator) + throw new Exception(cellInstanceConnectionName); + _GhostPCLFileName = Path.Combine(AppContext.BaseDirectory, "gpcl6win64.exe"); + if (!File.Exists(_GhostPCLFileName)) + throw new Exception("Ghost PCL FileName doesn't Exist!"); + _PDFTextStripperFileName = Path.Combine(AppContext.BaseDirectory, "PDF-Text-Stripper.exe"); + if (!File.Exists(_PDFTextStripperFileName)) + throw new Exception("PDF-Text-Stripper FileName doesn't Exist!"); + if (_IsEAFHosted) + NestExistingFiles(_FileConnectorConfiguration); + } + + void IFileRead.Move(Tuple> extractResults, Exception exception) => Move(extractResults); + + void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); + + string IFileRead.GetEventDescription() + { + string result = _Description.GetEventDescription(); + return result; + } + + List IFileRead.GetHeaderNames() + { + List results = _Description.GetHeaderNames(); + return results; + } + + string[] IFileRead.Move(Tuple> extractResults, string to, string from, string resolvedFileLocation, Exception exception) + { + string[] results = Move(extractResults, to, from, resolvedFileLocation, exception); + return results; + } + + JsonProperty[] IFileRead.GetDefault() + { + JsonProperty[] results = _Description.GetDefault(this, _Logistics); + return results; + } + + Dictionary IFileRead.GetDisplayNamesJsonElement() + { + Dictionary results = _Description.GetDisplayNamesJsonElement(this); + return results; + } + + List IFileRead.GetDescriptions(IFileRead fileRead, List tests, IProcessData processData) + { + List results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData); + return results; + } + + Tuple> IFileRead.GetExtractResult(string reportFullPath, string eventName) + { + Tuple> results; + if (string.IsNullOrEmpty(eventName)) + throw new Exception(); + _ReportFullPath = reportFullPath; + DateTime dateTime = DateTime.Now; + results = GetExtractResult(reportFullPath, dateTime); + if (results.Item3 is null) + results = new Tuple>(results.Item1, Array.Empty(), JsonSerializer.Deserialize("[]"), results.Item4); + if (results.Item3.Length > 0 && _IsEAFHosted) + WritePDSF(this, results.Item3); + UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks); + return results; + } + + Tuple> IFileRead.ReExtract() + { + Tuple> results; + List headerNames = _Description.GetHeaderNames(); + Dictionary keyValuePairs = _Description.GetDisplayNamesJsonElement(this); + results = ReExtract(this, headerNames, keyValuePairs); + return results; + } + +#nullable enable + + private Tuple> GetExtractResult(string reportFullPath, DateTime dateTime) + { + Tuple> results; + string result; + JsonElement[] jsonElements; + Test[] tests = Array.Empty(); + List fileInfoCollection = new(); + ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath); + _Logistics = new Logistics(reportFullPath, processDataStandardFormat); + SetFileParameterLotIDToLogisticsMID(); + ReadOnlyCollection lines = Convert.PDF(_Logistics, _GhostPCLFileName, _PDFTextStripperFileName, fileInfoCollection); + Run? run = Run.Get(_Logistics, fileInfoCollection, lines); + if (run is null) + { + jsonElements = Array.Empty(); + result = string.Concat("A) No Data - ", dateTime.Ticks); + results = new(result, tests, jsonElements, fileInfoCollection); + } + else + { + result = string.Join(Environment.NewLine, _Logistics.Logistics1); + jsonElements = _IsEAFHosted ? Array.Empty() : ProcessDataStandardFormat.GetArray(processDataStandardFormat); + results = new(result, tests, jsonElements, fileInfoCollection); + } + return results; + } + +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/pdsf/Header.cs b/Adaptation/FileHandlers/pdsf/Header.cs new file mode 100644 index 0000000..bfbf0b2 --- /dev/null +++ b/Adaptation/FileHandlers/pdsf/Header.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Adaptation.FileHandlers.pdsf; + +#nullable enable + +internal class Header +{ + + [JsonConstructor] + public Header(string @operator, string startVoltage, string wafer, string stopVoltage, string lot, string rampRate, string plan, string gLimit, string date, string time, string setupFile, string waferSize, string folder, string ccomp, string pattern, string area, string condType, string rhoMethod, string model) + { + Operator = @operator; + StartVoltage = startVoltage; + Wafer = wafer; + StopVoltage = stopVoltage; + Lot = lot; + RampRate = rampRate; + Plan = plan; + GLimit = gLimit; + Date = date; + Time = time; + SetupFile = setupFile; + WaferSize = waferSize; + Folder = folder; + Ccomp = ccomp; + Pattern = pattern; + Area = area; + CondType = condType; + RhoMethod = rhoMethod; + Model = model; + } + + [JsonPropertyName("Operator")] public string Operator { get; } + [JsonPropertyName("Start Voltage")] public string StartVoltage { get; } + [JsonPropertyName("Wafer")] public string Wafer { get; } + [JsonPropertyName("Stop Voltage")] public string StopVoltage { get; } + [JsonPropertyName("Lot")] public string Lot { get; } + [JsonPropertyName("Ramp Rate")] public string RampRate { get; } + [JsonPropertyName("Plan")] public string Plan { get; } + [JsonPropertyName("G limit")] public string GLimit { get; } + [JsonPropertyName("Date")] public string Date { get; } + [JsonPropertyName("Time")] public string Time { get; } + [JsonPropertyName("Setup File")] public string SetupFile { get; } + [JsonPropertyName("Wafer size")] public string WaferSize { get; } + [JsonPropertyName("Folder")] public string Folder { get; } + [JsonPropertyName("Ccomp")] public string Ccomp { get; } + [JsonPropertyName("Pattern")] public string Pattern { get; } + [JsonPropertyName("Area")] public string Area { get; } + [JsonPropertyName("Cond Type")] public string CondType { get; } + [JsonPropertyName("Rho Method")] public string RhoMethod { get; } + [JsonPropertyName("Model")] public string Model { get; } + + private static string[] GetRemove() => + new string[] + { + " L L", + " O O", + " G G", + " C C", + " O O", + " N N", + " C C", + " E E", + " N N", + " T T", + " R R", + " A A", + " T T", + " I I", + " O O", + " N N" + }; + + public static Header Get() => + new(string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty); + + private static ReadOnlyCollection GetJsonProperties() + { + JsonProperty[] results; + string json; + Header header = Get(); + json = JsonSerializer.Serialize(header); + JsonElement jsonElement = JsonSerializer.Deserialize(json); + results = jsonElement.EnumerateObject().ToArray(); + return new(results); + } + + public static Header? Get(Constant constant, ReadOnlyCollection lines) + { + Header? result; + string json; + string check; + string[] segments; + string[] segmentsB; + string[] segmentsC; + bool found = false; + string[] remove = GetRemove(); + Dictionary keyValuePairs = new(); + ReadOnlyCollection jsonProperties = GetJsonProperties(); + foreach (string line in lines) + { + if (line.Contains(constant.Site)) + found = true; + if (!found) + continue; + if (line == constant.SummaryLine) + break; + foreach (JsonProperty jsonProperty in jsonProperties) + { + segments = line.Split(new string[] { $"{jsonProperty.Name}:", $"{jsonProperty.Name} :" }, StringSplitOptions.None); + if (segments.Length < 2) + continue; + check = segments[1].Trim(); + foreach (JsonProperty jsonPropertyB in jsonProperties) + { + segmentsB = check.Split(new string[] { $"{jsonPropertyB.Name}:", $"{jsonPropertyB.Name} :" }, StringSplitOptions.None); + if (segmentsB.Length > 1) + check = segmentsB[0].Trim(); + } + foreach (string r in remove) + { + segmentsC = check.Split(new string[] { r }, StringSplitOptions.None); + if (segmentsC.Length > 1) + check = segmentsC[0].Trim(); + } + keyValuePairs.Add(jsonProperty.Name, check); + } + } + if (keyValuePairs.Count != jsonProperties.Count) + result = null; + else + { + json = JsonSerializer.Serialize(keyValuePairs); + result = JsonSerializer.Deserialize(json, HeaderSourceGenerationContext.Default.Header) ?? throw new NullReferenceException(nameof(result)); + } + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Header))] +internal partial class HeaderSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/pdsf/Point.cs b/Adaptation/FileHandlers/pdsf/Point.cs new file mode 100644 index 0000000..a4ab318 --- /dev/null +++ b/Adaptation/FileHandlers/pdsf/Point.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text.Json.Serialization; + +namespace Adaptation.FileHandlers.pdsf; + +#nullable enable + +internal class Point +{ + + public Point(string site, string x, string y, string nAvg, string rhoAvg, string nsl, string rhosl, string vd, string phase, string flatZ, string grade, string xLeft, string xRight, string bottomY, string topY) + { + Site = site; + X = x; + Y = y; + NAvg = nAvg; + RhoAvg = rhoAvg; + Nsl = nsl; + Rhosl = rhosl; + Vd = vd; + Phase = phase; + FlatZ = flatZ; + Grade = grade; + XLeft = xLeft; + XRight = xRight; + BottomY = bottomY; + TopY = topY; + } + + [JsonPropertyName("Site")] public string Site { get; } + [JsonPropertyName("X")] public string X { get; } + [JsonPropertyName("Y")] public string Y { get; } + [JsonPropertyName("Navg")] public string NAvg { get; } + [JsonPropertyName("Rhoavg")] public string RhoAvg { get; } + [JsonPropertyName("Nsl")] public string Nsl { get; } + [JsonPropertyName("Rhosl")] public string Rhosl { get; } + [JsonPropertyName("Vd")] public string Vd { get; } + [JsonPropertyName("Phase")] public string Phase { get; } + [JsonPropertyName("Flat Z")] public string FlatZ { get; } + [JsonPropertyName("Grade")] public string Grade { get; } + [JsonPropertyName("X Left")] public string XLeft { get; } + [JsonPropertyName("X Right")] public string XRight { get; } + [JsonPropertyName("Bottom Y")] public string BottomY { get; } + [JsonPropertyName("Top Y")] public string TopY { get; } + + public static Point Get() => + new(string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty); + + public static ReadOnlyCollection GetCollection(Constant constant, ReadOnlyCollection lines) + { + List results = new(); + string s; + string line; + Point point; + string[] segments; + string[] segmentsB; + bool found = false; + string[] segmentsC; + bool foundB = false; + int x = constant.Take - 2; + List sites = new(); + for (int i = 0; i < lines.Count; i++) + { + line = lines[i]; + segmentsC = line.Split(new string[] { constant.Site }, StringSplitOptions.RemoveEmptyEntries); + if (segmentsC.Length > 1) + { + foreach (string segment in segmentsC) + sites.Add(segment.Trim()); + } + if (line == constant.SummaryLine) + { + sites.RemoveAt(0); + found = true; + } + if (!found) + continue; + if (!foundB && line.Contains(constant.Multiple)) + foundB = true; + if (line != constant.LastUnitsB) + continue; + if (foundB) + { + foundB = false; + continue; + } + for (int j = 0; j < sites.Count; j++) + { + s = sites[j]; + if (i + constant.Take > lines.Count) + break; + segments = s.Split(new string[] { "(", ",", ")" }, StringSplitOptions.None); + if (segments.Length < 2) + break; + segmentsB = lines[i + x].Split(' '); + if (segmentsB.Length < 2) + break; + point = new(site: segments[0].Trim(), + x: segments[1].Trim(), + y: segments[2].Trim(), + nAvg: lines[i + 1].Trim(), + nsl: lines[i + 2].Trim(), + vd: lines[i + 3].Trim(), + flatZ: lines[i + 4].Trim(), + rhoAvg: lines[i + 5].Trim(), + rhosl: lines[i + 6].Trim(), + phase: lines[i + 7].Trim(), + grade: lines[i + 8].Trim(), + xLeft: segmentsB[0], + xRight: segmentsB[1], + bottomY: lines[i + 10].Trim(), + topY: lines[i + 11].Trim()); + results.Add(point); + i += constant.Take; + } + sites.Clear(); + } + return new(results); + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Point))] +internal partial class PointSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/pdsf/Row.cs b/Adaptation/FileHandlers/pdsf/Row.cs new file mode 100644 index 0000000..7fb7cc4 --- /dev/null +++ b/Adaptation/FileHandlers/pdsf/Row.cs @@ -0,0 +1,196 @@ +using System.Text.Json.Serialization; + +namespace Adaptation.FileHandlers.pdsf; + +#nullable enable + +internal class Row +{ + + public Row(Run run, int i) + { + Index = i; + // + Operator = run.Header.Operator; + StartVoltage = run.Header.StartVoltage; + Wafer = run.Header.Wafer; + StopVoltage = run.Header.StopVoltage; + Lot = run.Header.Lot; + RampRate = run.Header.RampRate; + Plan = run.Header.Plan; + GLimit = run.Header.GLimit; + Date = run.Header.Date; + Time = run.Header.Time; + SetupFile = run.Header.SetupFile; + WaferSize = run.Header.WaferSize; + Folder = run.Header.Folder; + Ccomp = run.Header.Ccomp; + Pattern = run.Header.Pattern; + Area = run.Header.Area; + CondType = run.Header.CondType; + RhoMethod = run.Header.RhoMethod; + Model = run.Header.Model; + if (run.Summary.Mean is null) + { + MeanNAvg = string.Empty; + MeanNsl = string.Empty; + MeanVd = string.Empty; + MeanFlatZ = string.Empty; + MeanRhoAvg = string.Empty; + MeanRhosl = string.Empty; + MeanPhase = string.Empty; + MeanGrade = string.Empty; + MeanRs = string.Empty; + } + else + { + MeanNAvg = run.Summary.Mean.NAvg; + MeanNsl = run.Summary.Mean.Nsl; + MeanVd = run.Summary.Mean.Vd; + MeanFlatZ = run.Summary.Mean.FlatZ; + MeanRhoAvg = run.Summary.Mean.RhoAvg; + MeanRhosl = run.Summary.Mean.Rhosl; + MeanPhase = run.Summary.Mean.Phase; + MeanGrade = run.Summary.Mean.Grade; + MeanRs = run.Summary.Mean.Rs; + } + if (run.Summary.StandardDeviationPercentage is null) + { + StandardDeviationPercentageNAvg = string.Empty; + StandardDeviationPercentageNsl = string.Empty; + StandardDeviationPercentageVd = string.Empty; + StandardDeviationPercentageFlatZ = string.Empty; + StandardDeviationPercentageRhoAvg = string.Empty; + StandardDeviationPercentageRhosl = string.Empty; + StandardDeviationPercentagePhase = string.Empty; + StandardDeviationPercentageGrade = string.Empty; + StandardDeviationPercentageRs = string.Empty; + } + else + { + StandardDeviationPercentageNAvg = run.Summary.StandardDeviationPercentage.NAvg; + StandardDeviationPercentageNsl = run.Summary.StandardDeviationPercentage.Nsl; + StandardDeviationPercentageVd = run.Summary.StandardDeviationPercentage.Vd; + StandardDeviationPercentageFlatZ = run.Summary.StandardDeviationPercentage.FlatZ; + StandardDeviationPercentageRhoAvg = run.Summary.StandardDeviationPercentage.RhoAvg; + StandardDeviationPercentageRhosl = run.Summary.StandardDeviationPercentage.Rhosl; + StandardDeviationPercentagePhase = run.Summary.StandardDeviationPercentage.Phase; + StandardDeviationPercentageGrade = run.Summary.StandardDeviationPercentage.Grade; + StandardDeviationPercentageRs = run.Summary.StandardDeviationPercentage.Rs; + } + if (run.Summary.RadialGradient is null) + { + RadialGradientNAvg = string.Empty; + RadialGradientNsl = string.Empty; + RadialGradientVd = string.Empty; + RadialGradientFlatZ = string.Empty; + RadialGradientRhoAvg = string.Empty; + RadialGradientRhosl = string.Empty; + RadialGradientPhase = string.Empty; + RadialGradientGrade = string.Empty; + RadialGradientRs = string.Empty; + } + else + { + RadialGradientNAvg = run.Summary.RadialGradient.NAvg; + RadialGradientNsl = run.Summary.RadialGradient.Nsl; + RadialGradientVd = run.Summary.RadialGradient.Vd; + RadialGradientFlatZ = run.Summary.RadialGradient.FlatZ; + RadialGradientRhoAvg = run.Summary.RadialGradient.RhoAvg; + RadialGradientRhosl = run.Summary.RadialGradient.Rhosl; + RadialGradientPhase = run.Summary.RadialGradient.Phase; + RadialGradientGrade = run.Summary.RadialGradient.Grade; + RadialGradientRs = run.Summary.RadialGradient.Rs; + } + Site = run.Points[i].Site; + X = run.Points[i].X; + Y = run.Points[i].Y; + NAvg = run.Points[i].NAvg; + RhoAvg = run.Points[i].RhoAvg; + Nsl = run.Points[i].Nsl; + Rhosl = run.Points[i].Rhosl; + Vd = run.Points[i].Vd; + Phase = run.Points[i].Phase; + FlatZ = run.Points[i].FlatZ; + Grade = run.Points[i].Grade; + XLeft = run.Points[i].XLeft; + XRight = run.Points[i].XRight; + BottomY = run.Points[i].BottomY; + TopY = run.Points[i].TopY; + } + + public int Index { get; } + // + public string Operator { get; } + public string StartVoltage { get; } + public string Wafer { get; } + public string StopVoltage { get; } + public string Lot { get; } + public string RampRate { get; } + public string Plan { get; } + public string GLimit { get; } + public string Date { get; } + public string Time { get; } + public string SetupFile { get; } + public string WaferSize { get; } + public string Folder { get; } + public string Ccomp { get; } + public string Pattern { get; } + public string Area { get; } + public string CondType { get; } + public string RhoMethod { get; } + public string Model { get; } + // + public string MeanNAvg { get; } + public string MeanNsl { get; } + public string MeanVd { get; } + public string MeanFlatZ { get; } + public string MeanRhoAvg { get; } + public string MeanRhosl { get; } + public string MeanPhase { get; } + public string MeanGrade { get; } + public string MeanRs { get; } + // + public string StandardDeviationPercentageNAvg { get; } + public string StandardDeviationPercentageNsl { get; } + public string StandardDeviationPercentageVd { get; } + public string StandardDeviationPercentageFlatZ { get; } + public string StandardDeviationPercentageRhoAvg { get; } + public string StandardDeviationPercentageRhosl { get; } + public string StandardDeviationPercentagePhase { get; } + public string StandardDeviationPercentageGrade { get; } + public string StandardDeviationPercentageRs { get; } + // + public string RadialGradientNAvg { get; } + public string RadialGradientNsl { get; } + public string RadialGradientVd { get; } + public string RadialGradientFlatZ { get; } + public string RadialGradientRhoAvg { get; } + public string RadialGradientRhosl { get; } + public string RadialGradientPhase { get; } + public string RadialGradientGrade { get; } + public string RadialGradientRs { get; } + // + public string Site { get; } + public string X { get; } + public string Y { get; } + public string NAvg { get; } + public string RhoAvg { get; } + public string Nsl { get; } + public string Rhosl { get; } + public string Vd { get; } + public string Phase { get; } + public string FlatZ { get; } + public string Grade { get; } + public string XLeft { get; } + public string XRight { get; } + public string BottomY { get; } + public string TopY { get; } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Row))] +internal partial class RowSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/pdsf/Run.cs b/Adaptation/FileHandlers/pdsf/Run.cs new file mode 100644 index 0000000..0aca636 --- /dev/null +++ b/Adaptation/FileHandlers/pdsf/Run.cs @@ -0,0 +1,148 @@ +using Adaptation.Shared; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Adaptation.FileHandlers.pdsf; + +#nullable enable + +internal class Run +{ + + public Run(Header header, Summary summary, ReadOnlyCollection points) + { + Header = header; + Summary = summary; + Points = points; + } + + public Header Header { get; } + public Summary Summary { get; } + public ReadOnlyCollection Points { get; } + + private static ReadOnlyCollection FilterLines(ReadOnlyCollection collection) + { + List results = new(); + foreach (string line in collection) + { + if (string.IsNullOrEmpty(line) || line is "*" or "@") + continue; + if (line.Length < 3 || line[0] is not '*' and not '@' || line[1] != ' ') + results.Add(line); + else + results.Add(line.Substring(2)); + } + return new(results); + } + + private static void WriteJson(Logistics logistics, List fileInfoCollection, Run result) + { + FileInfo fileInfo = new($"{logistics.ReportFullPath}.run.json"); + string json = JsonSerializer.Serialize(result, RunSourceGenerationContext.Default.Run); + File.WriteAllText(fileInfo.FullName, json); + File.SetLastWriteTime(fileInfo.FullName, logistics.DateTimeFromSequence); + fileInfoCollection.Add(fileInfo); + } + + private static ReadOnlyCollection GetLines(Logistics logistics, JsonElement[]? jsonElements) + { + List results = new(); + int columns = 0; + StringBuilder stringBuilder = new(); + results.Add($"\"Count\",{jsonElements?.Length}"); + results.Add($"\"{nameof(logistics.Sequence)}\",\"{logistics.Sequence}\""); + results.Add($"\"{nameof(logistics.MesEntity)}\",\"{logistics.MesEntity}\""); + string dateTimeFromSequence = logistics.DateTimeFromSequence.ToString("MM/dd/yyyy hh:mm:ss tt"); + for (int i = 0; i < jsonElements?.Length;) + { + _ = stringBuilder.Append('"').Append(nameof(logistics.DateTimeFromSequence)).Append('"').Append(','); + foreach (JsonProperty jsonProperty in jsonElements[0].EnumerateObject()) + { + columns += 1; + _ = stringBuilder.Append('"').Append(jsonProperty.Name).Append('"').Append(','); + } + break; + } + if (jsonElements?.Length != 0) + _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); + results.Add(stringBuilder.ToString()); + for (int i = 0; i < jsonElements?.Length; i++) + { + _ = stringBuilder.Clear(); + _ = stringBuilder.Append('"').Append(dateTimeFromSequence).Append('"').Append(','); + foreach (JsonProperty jsonProperty in jsonElements[i].EnumerateObject()) + { + if (jsonProperty.Value.ValueKind == JsonValueKind.Object) + _ = stringBuilder.Append(','); + else if (jsonProperty.Value.ValueKind != JsonValueKind.String) + _ = stringBuilder.Append(jsonProperty.Value).Append(','); + else + _ = stringBuilder.Append('"').Append(jsonProperty.Value).Append('"').Append(','); + } + _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); + results.Add(stringBuilder.ToString()); + } + return results.AsReadOnly(); + } + + private static void WriteCommaSeparatedValues(Logistics logistics, Run run) + { + List results = new(); + Row row; + for (int i = 0; i < run.Points.Count; i++) + { + row = new(run, i); + results.Add(row); + } + string json = JsonSerializer.Serialize(results); + JsonElement[]? jsonElements = JsonSerializer.Deserialize(json); + ReadOnlyCollection lines = GetLines(logistics, jsonElements); + File.WriteAllText($"{logistics.ReportFullPath}.csv", string.Join(Environment.NewLine, lines)); + } + + public static Run? Get(Logistics logistics, List fileInfoCollection, ReadOnlyCollection collection) + { + Run? result; + Constant constant = new(); + ReadOnlyCollection lines = FilterLines(collection); + if (collection.Count <= constant.Take) + result = null; + else + { + Header? header = Header.Get(constant, lines); + if (header is null) + result = null; + else + { + Summary? summary = SummarySegment.Get(constant, lines); + if (summary is null) + result = null; + else + { + ReadOnlyCollection points = Point.GetCollection(constant, lines) ?? throw new NullReferenceException(nameof(summary)); + if (points.Count == 0) + result = null; + else + { + result = new(header, summary, points); + WriteJson(logistics, fileInfoCollection, result); + WriteCommaSeparatedValues(logistics, result); + } + } + } + } + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Run))] +internal partial class RunSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/pdsf/Summary.cs b/Adaptation/FileHandlers/pdsf/Summary.cs new file mode 100644 index 0000000..0ca4cb7 --- /dev/null +++ b/Adaptation/FileHandlers/pdsf/Summary.cs @@ -0,0 +1,27 @@ +using System.Text.Json.Serialization; + +namespace Adaptation.FileHandlers.pdsf; + +#nullable enable + +internal class Summary +{ + + public Summary(SummarySegment? mean, SummarySegment? standardDeviationPercentage, SummarySegment? radialGradient) + { + Mean = mean; + StandardDeviationPercentage = standardDeviationPercentage; + RadialGradient = radialGradient; + } + + public SummarySegment? Mean { get; } + public SummarySegment? StandardDeviationPercentage { get; } + public SummarySegment? RadialGradient { get; } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Summary))] +internal partial class SummarySourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Adaptation/FileHandlers/pdsf/SummarySegment.cs b/Adaptation/FileHandlers/pdsf/SummarySegment.cs new file mode 100644 index 0000000..8b2efaa --- /dev/null +++ b/Adaptation/FileHandlers/pdsf/SummarySegment.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Adaptation.FileHandlers.pdsf; + +#nullable enable + +internal class SummarySegment +{ + + public SummarySegment(string nAvg, string nsl, string vd, string flatZ, string rhoAvg, string rhosl, string phase, string grade, string rs) + { + NAvg = nAvg; + Nsl = nsl; + Vd = vd; + FlatZ = flatZ; + RhoAvg = rhoAvg; + Rhosl = rhosl; + Phase = phase; + Grade = grade; + Rs = rs; + } + + [JsonPropertyName("Navg")] public string NAvg { get; } + [JsonPropertyName("Nsl")] public string Nsl { get; } + [JsonPropertyName("Vd")] public string Vd { get; } + [JsonPropertyName("Flat Z")] public string FlatZ { get; } + [JsonPropertyName("Rhoavg")] public string RhoAvg { get; } + [JsonPropertyName("Rhosl")] public string Rhosl { get; } + [JsonPropertyName("Phase")] public string Phase { get; } + [JsonPropertyName("Grade")] public string Grade { get; } + [JsonPropertyName("Rs")] public string Rs { get; } + + public static SummarySegment Get() => + new(string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty); + + private static ReadOnlyCollection GetJsonProperties() + { + JsonProperty[] results; + string json; + SummarySegment summarySegment = Get(); + json = JsonSerializer.Serialize(summarySegment); + JsonElement jsonElement = JsonSerializer.Deserialize(json); + results = jsonElement.EnumerateObject().ToArray(); + return new(results); + } + + public static Summary? Get(Constant constant, ReadOnlyCollection lines) + { + Summary? result; + string json; + string[] segments; + bool found = false; + string[] segmentsB; + List names = new(); + Dictionary keyValuePairs = new(); + Dictionary keyValuePairsB = new(); + Dictionary keyValuePairsC = new(); + ReadOnlyCollection jsonProperties = GetJsonProperties(); + foreach (string line in lines) + { + if (line == constant.SummaryLine) + found = true; + if (!found) + continue; + if (line.Contains(constant.Site)) + break; + if (line.Contains(constant.LastUnits)) + break; + foreach (JsonProperty jsonProperty in jsonProperties) + { + segments = line.Split(new string[] { $"{jsonProperty.Name}:", $"{jsonProperty.Name} :" }, StringSplitOptions.None); + if (segments.Length < 2 || !line.StartsWith(jsonProperty.Name)) + continue; + segmentsB = segments[1].Trim().Split(' '); + if (segmentsB.Length < 3) + continue; + if (names.Contains(jsonProperty.Name)) + continue; + names.Add(jsonProperty.Name); + keyValuePairs.Add(jsonProperty.Name, segmentsB[0]); + keyValuePairsB.Add(jsonProperty.Name, segmentsB[1]); + keyValuePairsC.Add(jsonProperty.Name, segmentsB[2]); + } + } + if (keyValuePairs.Count != jsonProperties.Count || keyValuePairsB.Count != jsonProperties.Count || keyValuePairsC.Count != jsonProperties.Count) + result = null; + else + { + json = JsonSerializer.Serialize(keyValuePairs); + SummarySegment? mean = JsonSerializer.Deserialize(json, SummarySegmentSourceGenerationContext.Default.SummarySegment); + json = JsonSerializer.Serialize(keyValuePairsB); + SummarySegment? standardDeviationPercentage = JsonSerializer.Deserialize(json, SummarySegmentSourceGenerationContext.Default.SummarySegment); + json = JsonSerializer.Serialize(keyValuePairsC); + SummarySegment? radialGradient = JsonSerializer.Deserialize(json, SummarySegmentSourceGenerationContext.Default.SummarySegment); + result = new(mean, standardDeviationPercentage, radialGradient); + } + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(SummarySegment))] +internal partial class SummarySegmentSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Adaptation/Shared/Duplicator/Description.cs b/Adaptation/Shared/Duplicator/Description.cs index 964612e..d9bb3b8 100644 --- a/Adaptation/Shared/Duplicator/Description.cs +++ b/Adaptation/Shared/Duplicator/Description.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text.Json; +using System.Text.Json.Serialization; namespace Adaptation.Shared.Duplicator; @@ -178,4 +179,16 @@ public class Description : IDescription, Properties.IDescription internal static string GetDateFormat() => "MM/dd/yyyy hh:mm:ss tt"; +} + +[JsonSourceGenerationOptions(WriteIndented = true, NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] +[JsonSerializable(typeof(Description))] +internal partial class SharedDescriptionSourceGenerationContext : JsonSerializerContext +{ +} + +[JsonSourceGenerationOptions(WriteIndented = true, NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] +[JsonSerializable(typeof(Description[]))] +internal partial class SharedDescriptionArraySourceGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Adaptation/Shared/FileRead.cs b/Adaptation/Shared/FileRead.cs index c2d999c..129ddcd 100644 --- a/Adaptation/Shared/FileRead.cs +++ b/Adaptation/Shared/FileRead.cs @@ -9,7 +9,6 @@ using System.IO; using System.Linq; using System.Text; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading; namespace Adaptation.Shared; @@ -447,12 +446,13 @@ public class FileRead : Properties.IFileRead { List results = new(); Duplicator.Description description; - JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString }; foreach (JsonElement jsonElement in jsonElements) { if (jsonElement.ValueKind != JsonValueKind.Object) throw new Exception(); - description = JsonSerializer.Deserialize(jsonElement.ToString(), jsonSerializerOptions); + description = JsonSerializer.Deserialize(jsonElement.ToString(), Duplicator.SharedDescriptionSourceGenerationContext.Default.Description); + if (description is null) + continue; results.Add(description); } return results; diff --git a/Adaptation/Shared/ProcessDataStandardFormat.cs b/Adaptation/Shared/ProcessDataStandardFormat.cs index 1fb9e2a..9d48a31 100644 --- a/Adaptation/Shared/ProcessDataStandardFormat.cs +++ b/Adaptation/Shared/ProcessDataStandardFormat.cs @@ -654,6 +654,17 @@ internal class ProcessDataStandardFormat return results; } + internal static JsonElement[] GetArray(string reportFullPath, string[] lines, ProcessDataStandardFormat processDataStandardFormat) + { + JsonElement[] results; + string? json = GetRecordsJson(reportFullPath, lines); + if (string.IsNullOrEmpty(json)) + results = GetArray(processDataStandardFormat); + else + results = JsonSerializer.Deserialize(json, JsonElementCollectionSourceGenerationContext.Default.JsonElementArray) ?? throw new Exception(); + return results; + } + internal static string GetPDSFText(IFileRead fileRead, Logistics logistics, JsonElement[] jsonElements, string logisticsText) { string result; @@ -903,7 +914,7 @@ internal class ProcessDataStandardFormat } foreach (KeyValuePair> keyValuePair in results) { - if (body.Count < 3) + if (body.Count < 2) break; if (keyValuePair.Value.Count != body.Count) continue; @@ -956,6 +967,26 @@ internal class ProcessDataStandardFormat return result; } + private static string? GetRecordsJson(string reportFullPath, string[] lines) + { + string? result; + bool foundRecords = false; + List results = new(); + lines ??= File.ReadAllLines(reportFullPath); + foreach (string line in lines) + { + if (line.StartsWith("\"Records\"")) + foundRecords = true; + if (!foundRecords) + continue; + if (line == "],") + break; + results.Add(line); + } + result = results.Count == 0 ? null : $"{string.Join(Environment.NewLine, results.Skip(1))}{Environment.NewLine}]"; + return result; + } + } [JsonSourceGenerationOptions(WriteIndented = true)] diff --git a/Adaptation/_Tests/CreateSelfDescription/Production/v2.60.0/HGCV2.cs b/Adaptation/_Tests/CreateSelfDescription/Production/v2.60.0/HGCV2.cs index 1e0b51d..8a176e9 100644 --- a/Adaptation/_Tests/CreateSelfDescription/Production/v2.60.0/HGCV2.cs +++ b/Adaptation/_Tests/CreateSelfDescription/Production/v2.60.0/HGCV2.cs @@ -61,5 +61,16 @@ public class HGCV2 : EAFLoggingUnitTesting EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit")); } + [Ignore] + [TestMethod] + public void Production__v2_60_0__HGCV2__pdsf() + { + string check = "*EQP_*.pdsf"; + MethodBase methodBase = new StackFrame().GetMethod(); + EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration")); + _ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting); + EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit")); + } + } #endif \ No newline at end of file diff --git a/Adaptation/_Tests/Extract/Production/v2.60.0/HGCV2.cs b/Adaptation/_Tests/Extract/Production/v2.60.0/HGCV2.cs index 597f84f..e1fb335 100644 --- a/Adaptation/_Tests/Extract/Production/v2.60.0/HGCV2.cs +++ b/Adaptation/_Tests/Extract/Production/v2.60.0/HGCV2.cs @@ -55,5 +55,20 @@ public class HGCV2 NonThrowTryCatch(); } + [Ignore] + [TestMethod] + public void Production__v2_60_0__HGCV2__pdsf__Normal() + { + bool validatePDSF = false; + string check = "*EQP_*.pdsf"; + _HGCV2.Production__v2_60_0__HGCV2__pdsf(); + MethodBase methodBase = new StackFrame().GetMethod(); + string[] variables = _HGCV2.AdaptationTesting.GetVariables(methodBase, check, validatePDSF); + IFileRead fileRead = _HGCV2.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false); + Logistics logistics = new(fileRead); + _ = AdaptationTesting.ReExtractCompareUpdatePassDirectory(variables, fileRead, logistics, validatePDSF); + NonThrowTryCatch(); + } + } #endif \ No newline at end of file diff --git a/MET08RESIHGCV.csproj b/MET08RESIHGCV.csproj index e60144e..3831295 100644 --- a/MET08RESIHGCV.csproj +++ b/MET08RESIHGCV.csproj @@ -116,6 +116,15 @@ + + + + + + + + + @@ -131,6 +140,8 @@ + +