diff --git a/.vscode/.UserSecrets/file-watcher.json b/.vscode/.UserSecrets/file-watcher.json index ceeda04..d3a2044 100644 --- a/.vscode/.UserSecrets/file-watcher.json +++ b/.vscode/.UserSecrets/file-watcher.json @@ -36,6 +36,40 @@ "DestinationDirectory": "D:/EAF/drssdv702.eu.infineon.com-eafdev-DeliveredPackages-IFX.EAF Kernel SEMI/v2.57.0.0", "SourceDirectory": "\\\\eafdev.drs.infineon.com\\eafdev\\DeliveredPackages\\IFX.EAF Kernel SEMI\\v2.57.0.0\\EAF v2.57.0.0 API\\complete_with_adaptations" }, + "InfinityQSConfiguration": { + "ConnectionStringX": "Data Source=messad1001\\test1,59583;Initial Catalog=LSL2SQL;Persist Security Info=True;User ID=srpadmin;Password=0okm9ijn;", + "ConnectionString": "Data Source=messqlec1.infineon.com\\PROD1,53959;Initial Catalog=Metrology;User ID=metrology_rouser;Password=Metrologyrouser2024!;", + "ConnectionStringXXX": "Data Source=messqlec1.infineon.com\\PROD1,53959;Initial Catalog=IRMNSPC;User ID=IRMNSPC;Password=dsaf;", + "DestinationDirectory": "L:/File-Watcher/Helper/InfinityQS", + "SubGroupTime": 1727177147, + "TestsFile": "L:/File-Watcher/Helper/InfinityQS/.json", + "Tests": [ + { + "Name": "Bin2", + "Value": 1655396897 + }, + { + "Name": "Thresh", + "Value": 1655396909 + }, + { + "Name": "GradeStdDev", + "Value": 1656695902 + }, + { + "Name": "HgCV Res Average", + "Value": 1228920625 + }, + { + "Name": "3mm Edge % from R/2", + "Value": 1423499546 + }, + { + "Name": "Average Sum of Defects", + "Value": 1125073605 + } + ] + }, "MetrologyConfiguration": { "DeleteOlderThanWeeks": 16, "DirectoriesBack": 2, diff --git a/File-Watcher.csproj b/File-Watcher.csproj index 17fc4d9..b185508 100644 --- a/File-Watcher.csproj +++ b/File-Watcher.csproj @@ -18,6 +18,7 @@ + diff --git a/Helpers/HelperInfinityQS.cs b/Helpers/HelperInfinityQS.cs index c9403e3..2392159 100644 --- a/Helpers/HelperInfinityQS.cs +++ b/Helpers/HelperInfinityQS.cs @@ -1,15 +1,187 @@ using File_Watcher.Models; +using System.Collections.ObjectModel; +using System.Data; +using System.Data.SqlClient; using System.Diagnostics; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; namespace File_Watcher.Helpers; internal static partial class HelperInfinityQS { - internal static bool RunMI(AppSettings appSettings, ILogger logger) + internal record Record([property: JsonPropertyName("count_se_sgtm")] int CountSeSubgroupTime, + [property: JsonPropertyName("date_time")] DateTime DateTime, + [property: JsonPropertyName("max_se_lot")] int MaxSeLot, + [property: JsonPropertyName("max_se_prcs")] int MaxSeProcess, + [property: JsonPropertyName("max_se_sgrp")] int MaxSeSubgroup, + [property: JsonPropertyName("max_se_test")] int MaxSeTest, + [property: JsonPropertyName("max_se_val")] float MaxSeValue, + [property: JsonPropertyName("min_se_sgrp")] int MinSeSubgroup, + [property: JsonPropertyName("test")] string Test); + + [JsonSourceGenerationOptions(WriteIndented = true)] + [JsonSerializable(typeof(Record[]))] + internal partial class RecordCollectionSourceGenerationContext : JsonSerializerContext + { + } + + private static string GetCommandText(InfinityQSConfiguration infinityQSConfiguration, Test test) + { // cSpell:disable + List results = []; + results.Add(" select min_se_sgrp, "); + results.Add(" max_se_sgrp, "); + results.Add(" max_se_prcs, "); + results.Add(" max_se_lot, "); + results.Add(" max_se_test, "); + results.Add(" max_se_val, "); + results.Add($" '{test.Name}' test, "); + results.Add(" dateadd(HH, -7, (dateadd(SS, convert(bigint, max_se_sgtm), '19700101'))) date_time, "); + results.Add(" count_se_sgtm "); + results.Add(" from ( "); + results.Add(" select "); + results.Add(" max(se.f_lot) max_se_lot, "); + results.Add(" max(se.f_val) max_se_val, "); + results.Add(" min(se.f_lot) min_se_lot, "); + results.Add(" min(se.f_val) min_se_val, "); + results.Add(" max(se.f_prcs) max_se_prcs, "); + results.Add(" max(se.f_sgrp) max_se_sgrp, "); + results.Add(" max(se.f_sgtm) max_se_sgtm, "); + results.Add(" max(se.f_test) max_se_test, "); + results.Add(" min(se.f_prcs) min_se_prcs, "); + results.Add(" min(se.f_sgrp) min_se_sgrp, "); + results.Add(" count(se.f_sgtm) count_se_sgtm "); + results.Add(" from [spcepiworld].[dbo].[sgrp_ext] se "); + results.Add(" where se.f_tsno = 1 "); + results.Add(" and se.f_val <> 0 "); + results.Add(" and se.f_flag = 0 "); + results.Add($" and se.f_test = {test.Value} "); + results.Add($" and se.f_sgtm > {infinityQSConfiguration.SubGroupTime} "); + results.Add(" group by se.f_sgtm, se.f_prcs, se.f_lot "); + results.Add(" ) qa "); + results.Add(" where qa.count_se_sgtm > 1 "); + results.Add(" and min_se_lot = max_se_lot "); + results.Add(" and min_se_val = max_se_val "); + results.Add(" and min_se_prcs = max_se_prcs "); + results.Add(" for json path "); + return string.Join(' ', results); + } // cSpell:enable + + private static string GetCommandText(ReadOnlyCollection subGroups) + { // cSpell:disable + List results = []; + results.Add(" update [spcepiworld].[dbo].[sgrp_ext] "); + results.Add(" set f_flag = 1 "); + results.Add(" where f_flag = 0 "); + results.Add($" and f_sgrp in ({string.Join(',', subGroups)}) "); + return string.Join(Environment.NewLine, results); + } // cSpell:enable + + private static StringBuilder GetForJsonPath(InfinityQSConfiguration infinityQSConfiguration, string commandText) + { + StringBuilder stringBuilder = new(); + using SqlConnection sqlConnection = new(infinityQSConfiguration.ConnectionString); + sqlConnection.Open(); + using SqlCommand sqlCommand = new(commandText, sqlConnection); + SqlDataReader sqlDataReader = sqlCommand.ExecuteReader(CommandBehavior.SequentialAccess); + while (sqlDataReader.Read()) + _ = stringBuilder.Append(sqlDataReader.GetString(0)); + return stringBuilder; + } + + private static int? ExecuteNonQuery(InfinityQSConfiguration infinityQSConfiguration, string commandText) + { + int? result; + if (!string.IsNullOrEmpty(infinityQSConfiguration.ConnectionString)) + result = null; + else + { + using SqlConnection sqlConnection = new(infinityQSConfiguration.ConnectionString); + sqlConnection.Open(); + using SqlCommand sqlCommand = new(commandText, sqlConnection); + result = sqlCommand.ExecuteNonQuery(); + } + return result; + } + + private static void Disable(InfinityQSConfiguration infinityQSConfiguration, string checkFile, ReadOnlyCollection collection) + { + string commandText = GetCommandText(collection); + File.WriteAllText(checkFile, commandText); + _ = ExecuteNonQuery(infinityQSConfiguration, commandText); + } + + private static ReadOnlyCollection GetTests(InfinityQSConfiguration infinityQSConfiguration) + { + List results = new(infinityQSConfiguration.Tests); + if (File.Exists(infinityQSConfiguration.TestsFile)) + { + string json = File.ReadAllText(infinityQSConfiguration.TestsFile); + List distinct = infinityQSConfiguration.Tests.Select(l => l.Value).ToList(); + Test[]? tests = JsonSerializer.Deserialize(json, TestCollectionSourceGenerationContext.Default.TestArray); + if (tests is not null) + { + foreach (Test test in tests) + { + if (distinct.Contains(test.Value)) + continue; + distinct.Add(test.Value); + results.AddRange(tests); + } + } + } + return new(results); + } + + private static void DisableMaxDuplicates(AppSettings appSettings) + { + Record[]? records; + bool added; + string json; + string commandText; + StringBuilder result; + List collection = []; + ReadOnlyCollection tests = GetTests(appSettings.InfinityQSConfiguration); + if (!Directory.Exists(appSettings.InfinityQSConfiguration.DestinationDirectory)) + _ = Directory.CreateDirectory(appSettings.InfinityQSConfiguration.DestinationDirectory); + string checkFile = Path.Combine(appSettings.InfinityQSConfiguration.DestinationDirectory, ".sql"); + foreach (Test test in tests) + { + added = false; + if (File.Exists(checkFile)) + continue; + commandText = GetCommandText(appSettings.InfinityQSConfiguration, test); + result = GetForJsonPath(appSettings.InfinityQSConfiguration, commandText); + if (result.Length == 0) + continue; + records = JsonSerializer.Deserialize(result.ToString(), RecordCollectionSourceGenerationContext.Default.RecordArray); + if (records is null || records.Length < 1) + continue; + foreach (Record record in records) + { + if (collection.Contains(record.MaxSeSubgroup)) + continue; + if (!added) + added = true; + collection.Add(record.MaxSeSubgroup); + } + if (!added) + continue; + json = JsonSerializer.Serialize(records, RecordCollectionSourceGenerationContext.Default.RecordArray); + File.WriteAllText(Path.Combine(appSettings.InfinityQSConfiguration.DestinationDirectory, $"{DateTime.Now.Ticks}.json"), json); + Thread.Sleep(500); + if (collection.Count > 1000) + break; + } + if (collection.Count > 0) + Disable(appSettings.InfinityQSConfiguration, checkFile, new(collection)); + } + + private static void RunMI() { #pragma warning disable CA1416 - logger.LogInformation(appSettings.Company); ProcessStartInfo processStartInfo = new("iispcmi.exe") { Domain = "Infineon", @@ -21,7 +193,15 @@ internal static partial class HelperInfinityQS Process process = Process.Start(processStartInfo) ?? throw new NullReferenceException(nameof(Process)); process.WaitForExit(); #pragma warning restore CA1416 - return true; } + internal static bool Select(AppSettings appSettings, ILogger logger) + { + logger.LogInformation(appSettings.Company); + if (string.IsNullOrEmpty(appSettings.InfinityQSConfiguration.ConnectionString)) + RunMI(); + else + DisableMaxDuplicates(appSettings); + return true; + } } \ No newline at end of file diff --git a/Models/AppSettings.cs b/Models/AppSettings.cs index e2c73e7..50117ae 100644 --- a/Models/AppSettings.cs +++ b/Models/AppSettings.cs @@ -7,6 +7,7 @@ public record AppSettings(CompassConfiguration CompassConfiguration, DriveConfiguration DriveConfiguration, EAFLogConfiguration EAFLogConfiguration, EDADatabaseConfiguration EDADatabaseConfiguration, + InfinityQSConfiguration InfinityQSConfiguration, IsoConfiguration IsoConfiguration, MetrologyConfiguration MetrologyConfiguration, NugetConfiguration NugetConfiguration, diff --git a/Models/Binder/AppSettings.cs b/Models/Binder/AppSettings.cs index f29a989..f504ee0 100644 --- a/Models/Binder/AppSettings.cs +++ b/Models/Binder/AppSettings.cs @@ -48,6 +48,7 @@ public class AppSettings DriveConfiguration driveConfiguration, EAFLogConfiguration eafLogConfiguration, EDADatabaseConfiguration edaDatabaseConfiguration, + InfinityQSConfiguration infinityQSConfiguration, IsoConfiguration isoConfiguration, MetrologyConfiguration metrologyConfiguration, NugetConfiguration nugetConfiguration, @@ -69,6 +70,7 @@ public class AppSettings driveConfiguration, eafLogConfiguration, edaDatabaseConfiguration, + infinityQSConfiguration, isoConfiguration, metrologyConfiguration, nugetConfiguration, @@ -114,6 +116,7 @@ public class AppSettings results.DriveConfiguration, results.EAFLogConfiguration, results.EDADatabaseConfiguration, + results.InfinityQSConfiguration, results.IsoConfiguration, results.MetrologyConfiguration, results.NugetConfiguration, diff --git a/Models/InfinityQSConfiguration.cs b/Models/InfinityQSConfiguration.cs new file mode 100644 index 0000000..d83f1b6 --- /dev/null +++ b/Models/InfinityQSConfiguration.cs @@ -0,0 +1,34 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace File_Watcher.Models; + +public record Test(string Name, + long Value); + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Test[]))] +internal partial class TestCollectionSourceGenerationContext : JsonSerializerContext +{ +} + +public record InfinityQSConfiguration(string ConnectionString, + string DestinationDirectory, + long SubGroupTime, + string TestsFile, + Test[] Tests) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, InfinityQSConfigurationSourceGenerationContext.Default.InfinityQSConfiguration); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(InfinityQSConfiguration))] +internal partial class InfinityQSConfigurationSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Worker.cs b/Worker.cs index 8bc3bee..28617b2 100644 --- a/Worker.cs +++ b/Worker.cs @@ -37,7 +37,7 @@ public partial class Worker : BackgroundService nameof(Helpers.HelperCompass) => Helpers.HelperCompass.CopyFile(_AppSettings, _Logger), nameof(Helpers.HelperStratus) => Helpers.HelperStratus.MoveFile(_AppSettings, _Logger), nameof(Helpers.HelperEAFLog) => Helpers.HelperEAFLog.DeleteFiles(_AppSettings, _Logger), - nameof(Helpers.HelperInfinityQS) => Helpers.HelperInfinityQS.RunMI(_AppSettings, _Logger), + nameof(Helpers.HelperInfinityQS) => Helpers.HelperInfinityQS.Select(_AppSettings, _Logger), nameof(Helpers.HelperEventLog) => Helpers.HelperEventLog.ClearEventLogs(_AppSettings, _Logger), nameof(Helpers.HelperWaferCounter) => Helpers.HelperWaferCounter.MoveFile(_AppSettings, _Logger), nameof(Helpers.HelperSerial) => Helpers.HelperSerial.ReadWrite(_AppSettings, _Logger, cancellationToken), @@ -61,7 +61,7 @@ public partial class Worker : BackgroundService for (int i = 0; i < int.MaxValue; i++) { BodyInner(cancellationToken); - Thread.Sleep(500); + Thread.Sleep(_AppSettings.MillisecondsDelay); } } while (_IsWindowsService && !cancellationToken.IsCancellationRequested)