diff --git a/Adaptation/FileHandlers/OpenInsightMetrologyViewer/WSRequest.cs b/Adaptation/FileHandlers/OpenInsightMetrologyViewer/WSRequest.cs index 60f2a9d..887f169 100644 --- a/Adaptation/FileHandlers/OpenInsightMetrologyViewer/WSRequest.cs +++ b/Adaptation/FileHandlers/OpenInsightMetrologyViewer/WSRequest.cs @@ -21,6 +21,7 @@ public class WSRequest public string AreaTotalMax { get; set; } public string AreaTotalMin { get; set; } public string AreaTotalStdDev { get; set; } + public string AttemptCounter { get; set; } public string Date { get; set; } public string HazeAverageAvg { get; set; } public string HazeAverageMax { get; set; } @@ -30,6 +31,7 @@ public class WSRequest public string HazeRegionMax { get; set; } public string HazeRegionMin { get; set; } public string HazeRegionStdDev { get; set; } + public string IndexOf { get; set; } public string Layer { get; set; } public string LotID { get; set; } public string LPDCM2Avg { get; set; } @@ -93,6 +95,7 @@ public class WSRequest AreaTotalMax = x.AreaTotalMax; AreaTotalMin = x.AreaTotalMin; AreaTotalStdDev = x.AreaTotalStdDev; + AttemptCounter = x.AttemptCounter; Date = x.Date; HazeAverageAvg = x.HazeAverageAvg; HazeAverageMax = x.HazeAverageMax; @@ -102,6 +105,7 @@ public class WSRequest HazeRegionMax = x.HazeRegionMax; HazeRegionMin = x.HazeRegionMin; HazeRegionStdDev = x.HazeRegionStdDev; + IndexOf = x.IndexOf; LotID = x.Lot; LPDCM2Avg = x.LPDCM2Avg; LPDCM2Max = x.LPDCM2Max; diff --git a/Adaptation/FileHandlers/pcl/Convert.cs b/Adaptation/FileHandlers/pcl/Convert.cs index 3fedd48..16892e0 100644 --- a/Adaptation/FileHandlers/pcl/Convert.cs +++ b/Adaptation/FileHandlers/pcl/Convert.cs @@ -42,7 +42,7 @@ internal class Convert RedirectStandardOutput = true, }; Process process = Process.Start(processStartInfo); - _ = process.WaitForExit(30000); + _ = process.WaitForExit(300000); string text; string checkFile; string[] pdfFiles = Directory.GetFiles(sourcePath, "*.pdf", SearchOption.TopDirectoryOnly); diff --git a/Adaptation/FileHandlers/pcl/Description.cs b/Adaptation/FileHandlers/pcl/Description.cs index b0ba8a2..04cd6a5 100644 --- a/Adaptation/FileHandlers/pcl/Description.cs +++ b/Adaptation/FileHandlers/pcl/Description.cs @@ -30,6 +30,8 @@ public class Description : IDescription, Shared.Properties.IDescription [JsonPropertyName("PSN")] public string PSN { get; set; } [JsonPropertyName("Reactor")] public string Reactor { get; set; } [JsonPropertyName("Recipe")] public string Recipe { get; set; } + [JsonPropertyName("IndexOf")] public string IndexOf { get; set; } + [JsonPropertyName("AttemptCounter")] public string AttemptCounter { get; set; } // [JsonPropertyName("Comments")] public string Comments { get; set; } [JsonPropertyName("Diameter")] public string Diameter { get; set; } @@ -307,6 +309,8 @@ public class Description : IDescription, Shared.Properties.IDescription PSN = processData.PSN, Reactor = processData.Reactor, Recipe = processData.Recipe, + IndexOf = nameof(IndexOf), + AttemptCounter = nameof(AttemptCounter), // Comments = detail.Comments, Diameter = detail.Diameter, @@ -415,6 +419,8 @@ public class Description : IDescription, Shared.Properties.IDescription PSN = nameof(PSN), Reactor = nameof(Reactor), Recipe = nameof(Recipe), + IndexOf = nameof(IndexOf), + AttemptCounter = nameof(AttemptCounter), // Comments = nameof(Comments), Diameter = nameof(Diameter), diff --git a/Adaptation/Infineon/Monitoring/MonA/MonIn.cs b/Adaptation/Infineon/Monitoring/MonA/MonIn.cs index 7a8a711..fcd16ca 100644 --- a/Adaptation/Infineon/Monitoring/MonA/MonIn.cs +++ b/Adaptation/Infineon/Monitoring/MonA/MonIn.cs @@ -226,9 +226,9 @@ public class MonIn : IMonIn, IDisposable { StringBuilder stringBuilder = new(); if (string.IsNullOrEmpty(subresource)) - _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} \n{5}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), stateName.Trim(), state.Trim(), description.Trim()); + _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} \n{5}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), stateName.Trim(), state.Trim(), description.Trim()); else - _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} \n{6}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), subresource.Trim(), stateName.Trim(), state.Trim(), description.Trim()); + _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} \n{6}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), subresource.Trim(), stateName.Trim(), state.Trim(), description.Trim()); return stringBuilder.ToString(); } @@ -247,14 +247,14 @@ public class MonIn : IMonIn, IDisposable if (string.IsNullOrEmpty(subresource)) { if (unit.Equals(string.Empty) && !interval.HasValue) - _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} \n{5}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), performanceName.Trim(), value, description.Trim()); + _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} \n{5}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), performanceName.Trim(), value, description.Trim()); else - _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} {5} {{interval={6}, unit={7}}}\n", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), performanceName.Trim(), value, description.Trim(), interval.HasValue ? interval.Value.ToString() : (object)string.Empty, unit.Trim()); + _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} {5} {{interval={6}, unit={7}}}\n", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), performanceName.Trim(), value, description.Trim(), interval.HasValue ? interval.Value.ToString() : string.Empty, unit.Trim()); } else if (unit.Equals(string.Empty) && !interval.HasValue) - _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} \n{6}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), subresource.Trim(), performanceName.Trim(), value, description.Trim()); + _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} \n{6}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), subresource.Trim(), performanceName.Trim(), value, description.Trim()); else - _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} {6} {{interval={7}, unit={8}}}\n", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), subresource.Trim(), performanceName.Trim(), value, description.Trim(), interval.HasValue ? interval.Value.ToString() : (object)string.Empty, unit.Trim()); + _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} {6} {{interval={7}, unit={8}}}\n", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), subresource.Trim(), performanceName.Trim(), value, description.Trim(), interval.HasValue ? interval.Value.ToString() : string.Empty, unit.Trim()); return stringBuilder.ToString(); } diff --git a/Adaptation/Shared/ProcessDataStandardFormat.cs b/Adaptation/Shared/ProcessDataStandardFormat.cs index 9d48a31..bc3c424 100644 --- a/Adaptation/Shared/ProcessDataStandardFormat.cs +++ b/Adaptation/Shared/ProcessDataStandardFormat.cs @@ -187,7 +187,7 @@ internal class ProcessDataStandardFormat break; } } - string? linesOne = lines.Length > 0 && body.Count == 0 && columns.Count == 0 ? lines[1] : null; + string? linesOne = lines.Length > 1 && body.Count == 0 && columns.Count == 0 ? lines[1] : null; logistics = GetLogistics(footer, linesOne: linesOne); if (logistics.Count == 0) sequence = null; @@ -235,7 +235,7 @@ internal class ProcessDataStandardFormat const int columnsLine = 6; FileInfo fileInfo = new(reportFullPath); ProcessDataStandardFormat processDataStandardFormat = GetProcessDataStandardFormat(fileInfo.LastWriteTime, columnsLine, fileInfo.FullName, lines: null); - JsonElement[]? jsonElements = processDataStandardFormatMapping.OldColumnNames.Count != processDataStandardFormatMapping.ColumnIndices.Count ? null : GetFullArray(processDataStandardFormat); + JsonElement[]? jsonElements = processDataStandardFormatMapping.OldColumnNames.Count == 0 ? null : GetFullArray(processDataStandardFormat); JsonProperty[]? jsonProperties = jsonElements is null || jsonElements.Length == 0 ? null : jsonElements[0].EnumerateObject().ToArray(); if (jsonElements is null || jsonProperties is null || jsonProperties.Length != processDataStandardFormatMapping.NewColumnNames.Count) result = processDataStandardFormat; diff --git a/Adaptation/_Tests/Static/loadLockSide.js b/Adaptation/_Tests/Static/loadLockSide.js new file mode 100644 index 0000000..40c6683 --- /dev/null +++ b/Adaptation/_Tests/Static/loadLockSide.js @@ -0,0 +1,36 @@ +// getValue(getContextData('2', 'cds.NULL_DATA', '')); + +function getValue(json) { + let result; + if (json == undefined || json.length === 0) + result = 'A) Invalid input!'; + else { + let parsed; + try { + parsed = JSON.parse(json); + } catch (error) { + parsed = null; + } + if (parsed == null) + result = 'B) Invalid input!'; + else { + let reactorType = parsed.rds == undefined ? '' : parsed.rds.reactorType == undefined ? '' : parsed.rds.reactorType; + if (parsed.rds == undefined) + result = '-'; + else if (parsed.rds.loadLockSide == undefined) + result = '_ - ' + reactorType; + else if (parsed.rds.loadLockSide === 'L') + result = 'Left - ' + reactorType; + else if (parsed.rds.loadLockSide === 'R') + result = 'Right - ' + reactorType; + else + result = parsed.rds.loadLockSide + ' - ' + reactorType; + } + } + return result; +} + +const json = '{"rds":{"prodSpec":{"recipesAndPatterns":[{"recipe":"6IN25_ROTR","pattern":"","patternSize":0,"tool":"TENCOR"}]}}}'; +const testA = getValue(json); +if (testA !== '1') + throw 'Test A failed: ' + testA; \ No newline at end of file diff --git a/Adaptation/_Tests/Static/recipes-and-patterns.js b/Adaptation/_Tests/Static/recipes-and-patterns.js new file mode 100644 index 0000000..8f5fdae --- /dev/null +++ b/Adaptation/_Tests/Static/recipes-and-patterns.js @@ -0,0 +1,115 @@ +// Recipe 1 = Matched +// recipes-and-patterns.js under IndexOf +// RecipesAndPatternsMatch +// ($('dcp.TENCOR1/csv/Index', 0) + 1) == $('dcp.TENCOR1/csv/Count', 0) +// getValue('TENCOR', $('dcp.TENCOR1/csv/Count', 0), $('dcp.TENCOR1/csv/Session', ''), 'pattern', getContextData('2', 'cds.NULL_DATA', '')); + +function getValue(tool, patternSize, recipe, pattern, json) { + let result; + if (tool == undefined || tool.length === 0 || patternSize == undefined || patternSize.length === 0 || recipe == undefined || recipe.length === 0 || pattern == undefined || pattern.length === 0 || json == undefined || json.length === 0) + result = 'A) Invalid input!'; + else { + let parsed; + try { + parsed = JSON.parse(json); + } catch (error) { + parsed = null; + } + if (parsed == null) + result = 'B) Invalid input!'; + else if (parsed.rds == undefined || parsed.rds.prodSpec == undefined || parsed.rds.prodSpec.recipesAndPatterns == undefined) + result = 'C) No Spec!'; + else { + let toolMatches = []; + for (let index = 0; index < parsed.rds.prodSpec.recipesAndPatterns.length; index++) { + if (parsed.rds.prodSpec.recipesAndPatterns[index].tool === tool) { + toolMatches.push(parsed.rds.prodSpec.recipesAndPatterns[index]); + } + } + if (toolMatches == null || toolMatches.length === 0) + result = 'Tool [' + tool + '] not found in OI API results!'; + else { + let debug = ''; + let matches = 0; + for (let index = 0; index < toolMatches.length; index++) { + debug += 'patternSize: ' + toolMatches[index].patternSize + + '; recipe: ' + toolMatches[index].recipe + + '; pattern: ' + toolMatches[index].pattern + ';~'; + if (toolMatches[index].recipe.localeCompare(recipe, ['en-US'], { sensitivity: 'base' }) === 0) { + matches++; + } + } + if (matches > 0) + result = '1'; + else + result = 'Value not matched~Run~patternSize: ' + patternSize + '; recipe: ' + recipe + '; pattern: ' + pattern + ';~API~' + debug; + } + } + } + return result; +} + +getValue('TENCOR', 0, '6IN25_ROTR', 'pattern', '{"rds":{"prodSpec":{"recipesAndPatterns":[{"recipe":"6IN25_ROTR","pattern":"","patternSize":0,"tool":"TENCOR"}]}}}'); + +let json; +let tool; +let recipe; +let pattern; +let patternSize; + +tool = 'TENCOR' +patternSize = 0; +recipe = '6IN25_ROTR'; +pattern = 'pattern'; +json = '{"rds":{"prodSpec":{"recipesAndPatterns":[{"recipe":"6IN25_ROTR","pattern":"","patternSize":0,"tool":"TENCOR"}]}}}'; +const testA = getValue(tool, patternSize, recipe, pattern, json); +if (testA !== '1') + throw 'Test A failed: ' + testA; +tool = null; +const testB = getValue(tool, patternSize, recipe, pattern, json); +if (testB !== 'A) Invalid input!') + throw 'Test L failed: ' + testB; +tool = ''; +const testC = getValue(tool, patternSize, recipe, pattern, json); +if (testC !== 'A) Invalid input!') + throw 'Test M failed: ' + testC; +patternSize = null; +const testD = getValue(tool, patternSize, recipe, pattern, json); +if (testD !== 'A) Invalid input!') + throw 'Test J failed: ' + testD; +patternSize = ''; +const testE = getValue(tool, patternSize, recipe, pattern, json); +if (testE !== 'A) Invalid input!') + throw 'Test K failed: ' + testE; +recipe = null; +const testF = getValue(tool, patternSize, recipe, pattern, json); +if (testF !== 'A) Invalid input!') + throw 'Test F failed: ' + testF; +recipe = ''; +const testG = getValue(tool, patternSize, recipe, pattern, json); +if (testG !== 'A) Invalid input!') + throw 'Test G failed: ' + testG; +pattern = null; +const testH = getValue(tool, patternSize, recipe, pattern, json); +if (testH !== 'A) Invalid input!') + throw 'Test H failed: ' + testH; +pattern = ''; +const testI = getValue(tool, patternSize, recipe, pattern, json); +if (testI !== 'A) Invalid input!') + throw 'Test I failed: ' + testI; +json = ''; +const testK = getValue(tool, patternSize, recipe, pattern, json); +if (testK !== 'A) Invalid input!') + throw 'Test B failed: ' + testK; +json = 'invalid'; +const testL = getValue(tool, patternSize, recipe, pattern, json); +if (testL !== 'B) Invalid input!') + throw 'Test C failed: ' + testL; +json = '{"rds":{}}'; +const testM = getValue(tool, patternSize, recipe, pattern, json); +if (testM !== 'C) No Spec!') + throw 'Test D failed: ' + testM; +json = '{"rds":{"prodSpec":{"recipesAndPatterns":[]}}}'; +const testN = getValue(tool, patternSize, recipe, pattern, json); +if (testN !== 'Tool [TENCOR] not found in OI API results!') + throw 'Test E failed: ' + testN;