sentinel apps versions crc and calibration checked

This commit is contained in:
Stoyan Zlatev 2024-11-20 11:20:09 +01:00
parent 9caf4671fb
commit fa4bd166a0
8 changed files with 555 additions and 191 deletions

View File

@ -0,0 +1,147 @@
namespace LaaProduction.Data.Cordonel
{
public partial class CordonelDbContext
{
/// <summary>
/// Contains placeholder for the pcbId variable name at positon: 0
/// </summary>
private const string LATEST_APPS_VERSIONS_CRC = @"
---------------------------------------------------------------------------------------------------
-- Declarations
---------------------------------------------------------------------------------------------------
DECLARE @pcbIdVarchar AS VARCHAR(20) = @{0};
DECLARE @progressId AS INT;
DECLARE @frequency AS INT;
DECLARE @meterSize AS INT;
---------------------------------------------------------------------------------------------------
-- Find and set latest progress id
---------------------------------------------------------------------------------------------------
SELECT @progressId = MAX(Id)
FROM CordonelProgress
WHERE PcbId = @pcbIdVarchar
---------------------------------------------------------------------------------------------------
-- Find and set meter size and frequency
---------------------------------------------------------------------------------------------------
SELECT @frequency = (SELECT TOP 1 CASE WHEN idn.Charcode = 'A'
THEN 868
WHEN idn.Charcode = 'B'
THEN 433
ELSE 0 END
FROM AlleIdentNrVakoMerkmale AS idn
WHERE idn.IdentNr = aap.IdentNr
AND idn.Stelle = 43
ORDER BY idn.Stelle)
, @meterSize = (SELECT TOP 1 cms.Dn_InternalId
FROM AlleIdentNrVakoMerkmale AS idn
JOIN CordonelMeterSizes AS cms
ON idn.Charcode = cms.Dn_VakoID
WHERE idn.IdentNr = aap.IdentNr
AND idn.Stelle = 4
ORDER BY idn.Stelle)
FROM MapPcbIdToSerialNumber AS map
JOIN AuftragPositionSerienNr AS aps
ON map.MapPcbIdToSerialNumber_SerialNumber = aps.SerienNr
JOIN AlleAuftragPositionen AS aap
ON aps.AuftragNr = aap.AuftragNr
AND aps.PositionNr = aap.PositionNr
WHERE map.MapPcbIdToSerialNumber_PcbId = @pcbIdVarchar
---------------------------------------------------------------------------------------------------
-- Select all apps with their versions and crc
---------------------------------------------------------------------------------------------------
SELECT DISTINCT
apps.PcbId AS AppsPcbId
, apps.AppId AS AppsAppId
, apps.Version AS AppsAppVersion
, history.PcbId AS HistoryPcbId
, history.HistoryAppVersion
, history.HistoryAppCrc
, files.FlexnetAppId
, files.FlexnetVersion
, files.MetrologyVersion
, files.CoreRevisionMin
, files.CoreRevisionMax
, files.FilesAppId
, files.FilesAppVersion
, files.FilesAppCrc
, files.ClusterFileId
, files.FileName
, files.FileContent
FROM (SELECT _progress.PcbId
, RIGHT(CONVERT(VARCHAR(10), CONVERT(BINARY(1), _apps.AppId, 2), 2), 2) AS AppId
, CASE WHEN LEN(_apps.Version) >= 4
THEN RIGHT('0' + REPLACE(_apps.Version, '.', ''), 4)
ELSE NULL END AS Version
FROM CordonelProgress AS _progress
JOIN CordonelAppVersion AS _apps
ON _progress.Id = _apps.ProgressId
WHERE _progress.Id = @progressId
AND _apps.Version IS NOT NULL)
AS apps
LEFT JOIN(SELECT _history_.PcbId
, RIGHT(_history_.HistoryAppVersion, 2) + LEFT(_history_.HistoryAppVersion, 2) AS HistoryAppVersion
, RIGHT(_history_.HistoryAppCrc, 2) + LEFT(_history_.HistoryAppCrc, 2) AS HistoryAppCrc
FROM (SELECT _history.PcbId
, LEFT(REPLACE(_history.Version, '-', ''), 4) AS HistoryAppVersion
, LEFT(REPLACE(_history.Crc, '-', ''), 4) AS HistoryAppCrc
FROM (SELECT _left.PcbId
, _left.Value AS Version
, _right.Value AS Crc
, ROW_NUMBER() OVER (PARTITION BY _left.Value ORDER BY _right.Value, _right.date DESC) AS RN
FROM GenesisMeterRegisterHistory AS _left
JOIN GenesisMeterRegisterHistory AS _right
ON _left.PcbId = _right.PcbId
AND _left.ID + 1 = _right.ID
WHERE _left.PcbId = @pcbIdVarchar
AND _left.Address = '00-01'
AND _right.Address = '00-0D')
AS _history
WHERE _history.RN = 1)
AS _history_)
AS history
ON apps.Version = history.HistoryAppVersion
LEFT JOIN(SELECT _files.FlexnetAppId
, _files.Version AS FlexnetVersion
, _files.MetrologyVersion
, _files.CoreRevisionMin
, _files.CoreRevisionMax
, _files.AppId AS FilesAppId
, RIGHT(_files.AppVersion, 2) + LEFT(_files.AppVersion, 2) AS FilesAppVersion
, RIGHT(_files.FileCrc, 2) + LEFT(_files.FileCrc, 2) AS FilesAppCrc
, _files.ClusterFileId
, _files.FileName
, _files.FileContent
FROM (SELECT DISTINCT
cluster.FileId AS ClusterFileId
, fw.FlexnetAppId
, fw.Version
, fw.CoreRevisionMin
, fw.CoreRevisionMax
, fw.MetrologyVersion
, SUBSTRING(CONVERT(VARCHAR(MAX), __files.FileContent, 2), 81, 2) AS AppId
, SUBSTRING(CONVERT(VARCHAR(MAX), __files.FileContent, 2), 13, 4) AS AppVersion
, SUBSTRING(CONVERT(VARCHAR(MAX), __files.FileContent, 2), 9, 4) AS FileCrc
, __files.FileName
, CASE WHEN __files.FileName LIKE '%.txt'
THEN CONVERT(VARCHAR(MAX), __files.FileContent, 0)
ELSE CONVERT(VARCHAR(MAX), __files.FileContent, 2)
END AS FileContent
FROM Cordonel_CurrentFw AS fw
JOIN FileClusterStore AS cluster
ON cluster.FileId = fw.FileClusterStoreId
JOIN FileMapToCluster AS filemap
ON cluster.FileId = filemap.FileMapToCluster_FileClusterId
LEFT JOIN [File] AS __files
ON filemap.FileMapToCluster_FileId = __files.FileId
WHERE fw.Metersize = @meterSize
AND fw.RadioFrequencyMhz = @frequency
AND fw.CurrentForProd = 1
AND fw.IsReleased = 1)
AS _files)
AS files
ON apps.AppId = files.FilesAppId
WHERE apps.Version IS NOT NULL
ORDER BY apps.AppId
";
}
}

View File

@ -7,12 +7,16 @@
using LaaProduction.Data.Cordonel.Repositories;
using System;
using System.Collections.Generic;
public class CordonelDbContext
public partial class CordonelDbContext
{
private readonly Action<String> errorsCallback;
public CordonelDbContext(String connectionString, Action<String> errorsCallback = null)
{
this.SqlConnection = new SqlConnection(connectionString, errorsCallback);
this.errorsCallback = errorsCallback;
this.SqlConnection = new SqlConnection(connectionString, this.OnSqlErrors);
this.EOLProgress = new EOLProgressRepository(this);
this.ProductionOrders = new ProductionOrdersRepository(this);
this.Requirements = new RequirementsRepository(this);
@ -20,6 +24,11 @@
this.StandardRequirements = new StandardRequirementsRepository(this);
}
public void OnSqlErrors(string error)
{
errorsCallback?.Invoke(error);
}
public CordonelDbContext(SqlConnection sqlConnection, Action<String> errorsCallback = null)
{
this.SqlConnection = sqlConnection;
@ -79,7 +88,32 @@
return appsDictionary;
}
public GenesisFlowModel GetLatestGenesisFlowValues(Object pcbid)
public IEnumerable<CordonelAppVeriosnCrc> GetLatestAppsWithVersions(int pcbId)
=> this.SqlConnection
.CreateCommand(string.Format(LATEST_APPS_VERSIONS_CRC, nameof(pcbId)))
.SetParameter(nameof(pcbId), pcbId)
.ExecuteReader(reader => new CordonelAppVeriosnCrc
{
AppsPcbId = reader.GetValue<int>(0),
AppsAppId = reader.GetValue<string>(1),
AppsAppVersion = reader.GetValue<string>(2),
HistoryPcbId = reader.GetValue<int>(3),
HistoryAppVersion = reader.GetValue<string>(4),
HistoryAppCrc = reader.GetValue<string>(5),
FlexnetAppId = reader.GetValue<string>(6),
FlexnetVersion = reader.GetValue<string>(7),
MetrologyVersion = reader.GetValue<int>(8),
CoreRevisionMin = reader.GetValue<int>(9),
CoreRevisionMax = reader.GetValue<int>(10),
FilesAppId = reader.GetValue<string>(11),
FilesAppVersion = reader.GetValue<string>(12),
FilesAppCrc = reader.GetValue<string>(13),
ClusterFileId = reader.GetValue<int>(14),
FileName = reader.GetValue<string>(15),
FileContent = reader.GetValue<string>(16),
});
public CordonelMetrologyValues GetLatestGenesisFlowValues(Object pcbid)
=> this.SqlConnection
.CreateCommand($@"
SELECT TOP 1
@ -106,10 +140,10 @@
WHERE PcbId = @{nameof(pcbid)}
ORDER BY date DESC")
.SetParameter(nameof(pcbid), pcbid?.ToString())
.FirstOrDefault(reader => new GenesisFlowModel
.FirstOrDefault(reader => new CordonelMetrologyValues
{
Id = reader.GetValue<Int32>(0),
PcbId = reader.GetValue<String>(1),
PcbId = reader.GetValue<Int32>(1),
CalFactor1 = reader.GetValue<Int32>(2),
CalFactor2 = reader.GetValue<Int32>(3),
CalFactor3 = reader.GetValue<Int32>(4),

View File

@ -49,6 +49,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="CordonelDbContext.cs" />
<Compile Include="CordonelDbContext.Queries.cs" />
<Compile Include="Interfaces\IEOLProgressRepository[T].cs" />
<Compile Include="Interfaces\IFilterRepository[T].cs" />
<Compile Include="Interfaces\IPORepository[T].cs" />
@ -60,6 +61,7 @@
<Compile Include="Interfaces\IRequirementsRepository[T].cs" />
<Compile Include="Interfaces\ISpecialRequirementsRepository[T].cs" />
<Compile Include="Interfaces\IStandardRequirementRepository[T].cs" />
<Compile Include="Models\CordonelAppVeriosnCrc.cs" />
<Compile Include="Models\CordonelProductionData.cs" />
<Compile Include="Models\CordonelProductionOrder.cs" />
<Compile Include="Models\CordonelRegisterHistory.cs" />
@ -73,7 +75,7 @@
<Compile Include="Models\Cordonel_POST_EOL_Progress.cs" />
<Compile Include="Models\EOLProgressModel.cs" />
<Compile Include="Models\EOLStatus.cs" />
<Compile Include="Models\GenesisFlowModel.cs" />
<Compile Include="Models\CordonelMetrologyValues.cs" />
<Compile Include="Models\JsonStatusConverter.cs" />
<Compile Include="Sentinel\Sentinel.cs" />
<Compile Include="Sentinel\SentinelHttpClient.cs" />

View File

@ -0,0 +1,39 @@
namespace LaaProduction.Data.Cordonel.Models
{
public class CordonelAppVeriosnCrc
{
public int AppsPcbId { get; set; }
public string AppsAppId { get; set; }
public string AppsAppVersion { get; set; }
public int HistoryPcbId { get; set; }
public string HistoryAppVersion { get; set; }
public string HistoryAppCrc { get; set; }
public string FlexnetAppId { get; set; }
public string FlexnetVersion { get; set; }
public int MetrologyVersion { get; set; }
public int CoreRevisionMin { get; set; }
public int CoreRevisionMax { get; set; }
public string FilesAppId { get; set; }
public string FilesAppVersion { get; set; }
public string FilesAppCrc { get; set; }
public int ClusterFileId { get; set; }
public string FileName { get; set; }
public string FileContent { get; set; }
}
}

View File

@ -0,0 +1,123 @@
namespace LaaProduction.Data.Cordonel.Models
{
using LaaPackages.Features.Cordonel;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
public class CordonelMetrologyValues
{
public Int32 Id { get; set; }
public Int32 PcbId { get; set; }
public Int32 CalFactor1 { get; set; }
public Int32 CalFactor2 { get; set; }
public Int32 CalFactor3 { get; set; }
public Int32 ZeroOffset1 { get; set; }
public Int32 ZeroOffset2 { get; set; }
public Int32 ZeroOffset3 { get; set; }
public Int32 FirstHitUpdatePeriod { get; set; }
public Int32 FirstHitShift { get; set; }
public Int32 FirstHitPercent1 { get; set; }
public Int32 FirstHitPercent2 { get; set; }
public Int32 FirstHitPercent3 { get; set; }
public Int32 ToFTempOffset1 { get; set; }
public Int32 ToFTempOffset2 { get; set; }
public Int32 ToFTempOffset3 { get; set; }
public Int32 MeterSize { get; set; }
public DateTime Date { get; set; }
public Boolean Successful { get; set; }
// TODO: is right compared
public IEnumerable<KeyValuePair<String, String>> CompareWithErrors(CordonelAppsDictionary appsDictionary, bool checkCalibration, bool checkZeroFlow)
{
if (!this.Successful)
{
yield return new KeyValuePair<String, String>(this.PcbId.ToString(), "Genesis flow is not successful.");
}
var genesisFlow = appsDictionary[Apps.GENESISFLOW];
if (checkCalibration)
{
var calFactor1 = genesisFlow[GENESISFLOW.CalFactor1].GetValue<Int32>();
var calFactor2 = genesisFlow[GENESISFLOW.CalFactor2].GetValue<Int32>();
var calFactor3 = genesisFlow[GENESISFLOW.CalFactor3].GetValue<Int32>();
var firstHitUpdatePeriod = genesisFlow[GENESISFLOW.FirstHitUpdatePeriod].GetValue<Int32>();
var firstHitShift = genesisFlow[GENESISFLOW.FirstHitShift].GetValue<Int32>();
var firstHitPercent1 = genesisFlow[GENESISFLOW.FirstHitPercent1].GetValue<Int32>();
var firstHitPercent2 = genesisFlow[GENESISFLOW.FirstHitPercent2].GetValue<Int32>();
var firstHitPercent3 = genesisFlow[GENESISFLOW.FirstHitPercent3].GetValue<Int32>();
var toFTempOffset1 = genesisFlow[GENESISFLOW.ToFTempOffset1].GetValue<Int32>();
var toFTempOffset2 = genesisFlow[GENESISFLOW.ToFTempOffset2].GetValue<Int32>();
var toFTempOffset3 = genesisFlow[GENESISFLOW.ToFTempOffset3].GetValue<Int32>();
yield return this.ErrorIf(x => x.CalFactor1 != calFactor1);
yield return this.ErrorIf(x => x.CalFactor2 != calFactor2);
yield return this.ErrorIf(x => x.CalFactor3 != calFactor3);
yield return this.ErrorIf(x => x.FirstHitUpdatePeriod != firstHitUpdatePeriod);
yield return this.ErrorIf(x => x.FirstHitShift != firstHitShift);
yield return this.ErrorIf(x => x.FirstHitPercent1 != firstHitPercent1);
yield return this.ErrorIf(x => x.FirstHitPercent2 != firstHitPercent2);
yield return this.ErrorIf(x => x.FirstHitPercent3 != firstHitPercent3);
yield return this.ErrorIf(x => x.ToFTempOffset1 != toFTempOffset1);
yield return this.ErrorIf(x => x.ToFTempOffset2 != toFTempOffset2);
yield return this.ErrorIf(x => x.ToFTempOffset3 != toFTempOffset3);
}
if (checkZeroFlow)
{
var zeroOffset1 = genesisFlow[GENESISFLOW.ZeroOffset1].GetValue<Int32>();
var zeroOffset2 = genesisFlow[GENESISFLOW.ZeroOffset2].GetValue<Int32>();
var zeroOffset3 = genesisFlow[GENESISFLOW.ZeroOffset3].GetValue<Int32>();
yield return this.ErrorIf(x => x.ZeroOffset1 != zeroOffset1);
yield return this.ErrorIf(x => x.ZeroOffset2 != zeroOffset2);
yield return this.ErrorIf(x => x.ZeroOffset3 != zeroOffset3);
}
}
private KeyValuePair<String, String> ErrorIf(Expression<Func<CordonelMetrologyValues, Boolean>> expression)
{
var succeeded = expression.Compile().Invoke(this);
if (!succeeded)
{
var binaryExpression = expression.Body as BinaryExpression;
var leftMember = binaryExpression?.Left as MemberExpression;
var leftPropertyInfo = leftMember?.Member as PropertyInfo;
var name = leftPropertyInfo.Name;
var valueL = leftPropertyInfo.GetValue(this);
var valueR = Expression
.Lambda(binaryExpression?.Right)
?.Compile()
?.DynamicInvoke();
return new KeyValuePair<String, String>(this.PcbId.ToString(), $"Calibration result compared to register value: {name} - {valueL} != {valueR}.");
}
else
{
return new KeyValuePair<String, String>();
}
}
}
}

View File

@ -9,89 +9,89 @@
/// <summary>
/// Automatically generated at first request of EOLProgress, cannot be changed.
/// </summary>
public Int32 Id { get; set; }
public Int32 Id { get; set; } // ✗
/// <summary>
/// PcbId supplied with request, cannot be changed.
/// </summary>
public Int32 PcbId { get; set; }
public Int32 PcbId { get; set; } // ✗
/// <summary>
/// DateTime at initial request, automatically generated , cannot be changed.
/// </summary>
[NotNull]
public DateTime? StartDate { get; set; }
public DateTime? StartDate { get; set; } // ✗
/// <summary>
/// Requirement ID if standard requirement should be used, else leave as is (null).
/// </summary>
[NotNull]
public Int32? StandardRequirementId { get; set; }
public Int32? StandardRequirementId { get; set; } // ✓
/// <summary>
/// Version if standard requirement should be used, else leave as is (null).
/// Version if standard requirement should be used, else leave as is (null).
/// </summary>
[NotNull]
public Int32? StandardRequirementVersion { get; set; }
public Int32? StandardRequirementVersion { get; set; } // ✓
/// <summary>
/// Requirement ID if special requirement should be used, else leave as is (null).
/// Requirement ID if special requirement should be used, else leave as is (null).
/// </summary>
public Int32? SpecialRequirementId { get; set; }
public Int32? SpecialRequirementId { get; set; } // ✓
/// <summary>
/// Version if special requirement should be used, else leave as is (null).
/// Version if special requirement should be used, else leave as is (null).
/// </summary>
public Int32? SpecialRequirementVersion { get; set; }
public Int32? SpecialRequirementVersion { get; set; } // ✓
/// <summary>
/// Requirement could be loaded for this device.
/// Requirement could be loaded for this device.
/// </summary>
[NotNull]
[NotFailed]
public EOLStatus RequirementRequestChecked { get; set; }
public EOLStatus RequirementRequestChecked { get; set; } // ✓
/// <summary>
/// Requirement PcbId equals PcbId of EOLProgress and Cordonel.
/// </summary>
[NotNull]
[NotFailed]
public EOLStatus RequirementPcbIdChecked { get; set; }
public EOLStatus RequirementPcbIdChecked { get; set; } // ✓
/// <summary>
/// Requirement order equals Cordonel order.
/// </summary>
[NotNull]
[NotFailed]
public EOLStatus RequirementOrderChecked { get; set; }
public EOLStatus RequirementOrderChecked { get; set; } // ✓
/// <summary>
/// Requirement region equals Cordonel region.
/// </summary>
[NotNull]
[NotFailed]
public EOLStatus RequirementRegionChecked { get; set; }
public EOLStatus RequirementRegionChecked { get; set; } // ✓
/// <summary>
/// Detected meter size, should never be null or empty
/// will only be set if requirement MeterSIze is equal to Cordonel MeterSize.
/// </summary>
[NotNull]
public String ProductionStatusMeterSize { get; set; }
public String ProductionStatusMeterSize { get; set; } // ✓
/// <summary>
/// Installed LUT CRC, should never be null or empty
/// will only be set if requirement LUT CRC is equal to Cordonel LUT CRC.
/// </summary>
[NotNull]
public String ProductionStatusLutCrc { get; set; }
public String ProductionStatusLutCrc { get; set; } // ✓
/// <summary>
/// Installed FW, should never be null or empty,
/// will only be set if requirement FW is equal to Cordonel FW.
/// </summary>
[NotNull]
public String ProductionStatusFwVersion { get; set; }
public String ProductionStatusFwVersion { get; set; } // ✓
/// <summary>
/// Drained battery load at EOL, should never be null
@ -124,14 +124,14 @@
/// </summary>
[NotNull]
[NotFailed]
public EOLStatus ProductionStatusZeroFlowChecked { get; set; }
public EOLStatus ProductionStatusZeroFlowChecked { get; set; } // ✓
/// <summary>
/// Calibration process executed and parameter set
/// </summary>
[NotNull]
[NotFailed]
public EOLStatus ProductionStatusCalibrationChecked { get; set; }
public EOLStatus ProductionStatusCalibrationChecked { get; set; } // ✓
/// <summary>
/// Final configuration written with Vako, CSD ... parameters.
@ -189,34 +189,34 @@
/// </summary>
[NotNull]
[NotFailed]
public EOLStatus AttachmentsChecked { get; set; }
public EOLStatus AttachmentsChecked { get; set; } // ✗
/// <summary>
/// Completion date of EOL process, should never be null
/// </summary>
[NotNull]
public DateTime? EOLCompleteDate { get; set; }
public DateTime? EOLCompleteDate { get; set; } // ✗
/// <summary>
/// Name and version of EOL process, should never be null
/// </summary>
[NotNull]
public String EOLSoftwareNameAndVersion { get; set; }
public String EOLSoftwareNameAndVersion { get; set; } // ✗
/// <summary>
/// SAP export done, added by sentinel, never set by EOL process
/// </summary>
public EOLStatus SAPExportDone { get; set; }
public EOLStatus SAPExportDone { get; set; } // ✗
/// <summary>
/// Sentinel completed check, added by sentinel, never set by EOL process
/// </summary>
public EOLStatus SentinelCompleted { get; set; }
public EOLStatus SentinelCompleted { get; set; } // ✗
/// <summary>
/// Sentinel execution and completion date, added by sentinel, never set by EOL process
/// </summary>
public DateTime? SentinelCompletedDate { get; set; }
public DateTime? SentinelCompletedDate { get; set; } // ✗
public static implicit operator EOLProgressModel(int pcbId) => new EOLProgressModel { PcbId = pcbId };
}

View File

@ -1,147 +0,0 @@
namespace LaaProduction.Data.Cordonel.Models
{
using LaaPackages.Features.Cordonel;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
public class GenesisFlowModel
{
public Int32 Id { get; set; }
public String PcbId { get; set; }
public Int32 CalFactor1 { get; set; }
public Int32 CalFactor2 { get; set; }
public Int32 CalFactor3 { get; set; }
public Int32 ZeroOffset1 { get; set; }
public Int32 ZeroOffset2 { get; set; }
public Int32 ZeroOffset3 { get; set; }
public Int32 FirstHitUpdatePeriod { get; set; }
public Int32 FirstHitShift { get; set; }
public Int32 FirstHitPercent1 { get; set; }
public Int32 FirstHitPercent2 { get; set; }
public Int32 FirstHitPercent3 { get; set; }
public Int32 ToFTempOffset1 { get; set; }
public Int32 ToFTempOffset2 { get; set; }
public Int32 ToFTempOffset3 { get; set; }
public Int32 MeterSize { get; set; }
public DateTime Date { get; set; }
public Boolean Successful { get; set; }
public IEnumerable<KeyValuePair<String, String>> IsEquals(CordonelAppsDictionary appsDictionary)
{
if (!this.Successful)
{
yield return new KeyValuePair<String, String>(this.PcbId, "Genesis flow is not successful.");
}
var genesisFlow = appsDictionary[Apps.GENESISFLOW];
var calFactor1 = genesisFlow[GENESISFLOW.CalFactor1].GetValue<Int32>();
var calFactor2 = genesisFlow[GENESISFLOW.CalFactor2].GetValue<Int32>();
var calFactor3 = genesisFlow[GENESISFLOW.CalFactor3].GetValue<Int32>();
var zeroOffset1 = genesisFlow[GENESISFLOW.ZeroOffset1].GetValue<Int32>();
var zeroOffset2 = genesisFlow[GENESISFLOW.ZeroOffset2].GetValue<Int32>();
var zeroOffset3 = genesisFlow[GENESISFLOW.ZeroOffset3].GetValue<Int32>();
var firstHitUpdatePeriod = genesisFlow[GENESISFLOW.FirstHitUpdatePeriod].GetValue<Int32>();
var firstHitShift = genesisFlow[GENESISFLOW.FirstHitShift].GetValue<Int32>();
var firstHitPercent1 = genesisFlow[GENESISFLOW.FirstHitPercent1].GetValue<Int32>();
var firstHitPercent2 = genesisFlow[GENESISFLOW.FirstHitPercent2].GetValue<Int32>();
var firstHitPercent3 = genesisFlow[GENESISFLOW.FirstHitPercent3].GetValue<Int32>();
var toFTempOffset1 = genesisFlow[GENESISFLOW.ToFTempOffset1].GetValue<Int32>();
var toFTempOffset2 = genesisFlow[GENESISFLOW.ToFTempOffset2].GetValue<Int32>();
var toFTempOffset3 = genesisFlow[GENESISFLOW.ToFTempOffset3].GetValue<Int32>();
yield return this.ErrorIf(x => x.CalFactor1 != calFactor1);
yield return this.ErrorIf(x => x.CalFactor2 != calFactor2);
yield return this.ErrorIf(x => x.CalFactor3 != calFactor3);
yield return this.ErrorIf(x => x.ZeroOffset1 != zeroOffset1);
yield return this.ErrorIf(x => x.ZeroOffset2 != zeroOffset2);
yield return this.ErrorIf(x => x.ZeroOffset3 != zeroOffset3);
yield return this.ErrorIf(x => x.FirstHitUpdatePeriod != firstHitUpdatePeriod);
yield return this.ErrorIf(x => x.FirstHitShift != firstHitShift);
yield return this.ErrorIf(x => x.FirstHitPercent1 != firstHitPercent1);
yield return this.ErrorIf(x => x.FirstHitPercent2 != firstHitPercent2);
yield return this.ErrorIf(x => x.FirstHitPercent3 != firstHitPercent3);
yield return this.ErrorIf(x => x.ToFTempOffset1 != toFTempOffset1);
yield return this.ErrorIf(x => x.ToFTempOffset2 != toFTempOffset2);
yield return this.ErrorIf(x => x.ToFTempOffset3 != toFTempOffset3);
}
public IEnumerable<KeyValuePair<String, String>> IsZeroFlowEquals(CordonelAppsDictionary appsDictionary)
{
if (!this.Successful)
{
yield return new KeyValuePair<String, String>(this.PcbId, "Genesis flow is not successful.");
}
var genesisFlow = appsDictionary[Apps.GENESISFLOW];
var zeroOffset1 = genesisFlow[GENESISFLOW.ZeroOffset1].GetValue<Int32>();
var zeroOffset2 = genesisFlow[GENESISFLOW.ZeroOffset2].GetValue<Int32>();
var zeroOffset3 = genesisFlow[GENESISFLOW.ZeroOffset3].GetValue<Int32>();
yield return this.ErrorIf(x => x.ZeroOffset1 != zeroOffset1);
yield return this.ErrorIf(x => x.ZeroOffset2 != zeroOffset2);
yield return this.ErrorIf(x => x.ZeroOffset3 != zeroOffset3);
}
public IEnumerable<KeyValuePair<String, String>> IsCalibrationEquals(CordonelAppsDictionary appsDictionary)
{
if (!this.Successful)
{
yield return new KeyValuePair<String, String>(this.PcbId, "Genesis flow is not successful.");
}
var genesisFlow = appsDictionary[Apps.GENESISFLOW];
var calFactor1 = genesisFlow[GENESISFLOW.CalFactor1].GetValue<Int32>();
var calFactor2 = genesisFlow[GENESISFLOW.CalFactor2].GetValue<Int32>();
var calFactor3 = genesisFlow[GENESISFLOW.CalFactor3].GetValue<Int32>();
yield return this.ErrorIf(x => x.CalFactor1 != calFactor1);
yield return this.ErrorIf(x => x.CalFactor2 != calFactor2);
yield return this.ErrorIf(x => x.CalFactor3 != calFactor3);
}
private KeyValuePair<String, String> ErrorIf(Expression<Func<GenesisFlowModel, Boolean>> expression)
{
var succeeded = expression.Compile().Invoke(this);
if (!succeeded)
{
var binaryExpression = expression.Body as BinaryExpression;
var leftMember = binaryExpression?.Left as MemberExpression;
var leftPropertyInfo = leftMember?.Member as PropertyInfo;
var name = leftPropertyInfo.Name;
var valueL = leftPropertyInfo.GetValue(this);
var valueR = Expression
.Lambda(binaryExpression?.Right)
?.Compile()
?.DynamicInvoke();
return new KeyValuePair<String, String>(this.PcbId, $"Calibration result compared to register value: {name} - {valueL} != {valueR}.");
}
else
{
return new KeyValuePair<String, String>();
}
}
}
}

View File

@ -32,19 +32,27 @@
try
{
// Data loading
this.TryGetUniqueProductionData(pcbId, out var productionData);
this.TryGetEOLProgressModel(pcbId, out var eolProgress);
this.TryGetCordonelRequirements(pcbId, out var requirements);
this.TryGetCordonelAppsAndRegisterValues(pcbId, out var apps);
this.TryGetCordonelAppsAndFWVersionValues(pcbId, out var appsVersionsCrcs);
this.TryGetCordonelMetrologyValues(pcbId, out var metrologyValues);
// Data comparison
this.TryCompareRequirementsIdAndVersion(eolProgress, requirements, eolProgress);
this.TryCompareAllPcbIds(pcbId, productionData, requirements, apps, eolProgress);
this.TryCompareAllPcbIds(pcbId, productionData, requirements, apps, eolProgress, metrologyValues);
this.TryCompareProductionOrderNumber(productionData, requirements, eolProgress);
this.TryCompareRegionSizeKey(productionData, requirements, eolProgress);
this.TryCompareMeterSize(productionData, requirements, eolProgress, apps);
this.TryCompareMeterSize(productionData, requirements, eolProgress, apps, metrologyValues);
this.TryCompareLUTCRCVersion(requirements, eolProgress, apps);
this.TryCompareAppsAndFWVersion(requirements, eolProgress, apps, appsVersionsCrcs);
this.TryCompareMetrologyValues(requirements, eolProgress, apps, metrologyValues);
}
catch (SentinelException e)
{
sentinelResult.Succeeded = false;
sentinelResult[e.Key] = e.Message;
sentinelResult[nameof(e.Source)] = e.Source;
sentinelResult[nameof(e.StackTrace)] = e.StackTrace;
@ -53,7 +61,7 @@
return sentinelResult;
}
internal void TryCompareAllPcbIds(int pcbId, CordonelProductionData productionData, CordonelRequirements requirements, CordonelAppsDictionary apps, EOLProgressModel eolProgress)
internal void TryCompareAllPcbIds(int pcbId, CordonelProductionData productionData, CordonelRequirements requirements, CordonelAppsDictionary apps, EOLProgressModel eolProgress, CordonelMetrologyValues metrologyValues)
{
if (eolProgress.RequirementPcbIdChecked == EOLStatus.NA)
{
@ -83,6 +91,16 @@
, nameof(SYSTEM.PCBSerialNumber)
, registerPcbId));
}
else if (pcbId != metrologyValues.PcbId)
{
throw new SentinelException(nameof(productionData.PcbId), string.Format(errorFormat
, "parameter"
, nameof(pcbId)
, pcbId
, nameof(CordonelMetrologyValues)
, nameof(CordonelMetrologyValues.PcbId)
, metrologyValues.PcbId));
}
else if (requirements.PcbId != null)
{
if (pcbId != requirements.PcbId)
@ -118,6 +136,103 @@
}
}
internal void TryCompareAppsAndFWVersion(CordonelRequirements requirements, EOLProgressModel eolProgress, CordonelAppsDictionary apps, CordonelAppVeriosnCrc[] appsVersionsCrcs)
{
var errorFormat = "{0}.{1}({2}) != {3}.{4}({5})";
if (string.IsNullOrWhiteSpace(requirements.FwVersion))
{
throw new SentinelException(nameof(requirements.FwVersion), $"{nameof(CordonelRequirements)}.{nameof(CordonelRequirements.FwVersion)} ist erforderlich");
}
else if (requirements.FwVersion != eolProgress.ProductionStatusFwVersion)
{
throw new SentinelException(nameof(requirements.FwVersion), string.Format(errorFormat
, nameof(CordonelRequirements)
, nameof(CordonelRequirements.FwVersion)
, requirements.FwVersion
, nameof(EOLProgressModel)
, nameof(EOLProgressModel.ProductionStatusFwVersion)
, eolProgress.ProductionStatusFwVersion));
}
var requirementFlexnetVersion = requirements
.FwVersion
.Replace(".", string.Empty)
.Substring(1);
var currentFlexnetVersion = default(string);
var firstIteration = true;
foreach (var appVersionCrc in appsVersionsCrcs)
{
if (firstIteration)
{
if (appVersionCrc.AppsPcbId != appVersionCrc.HistoryPcbId)
{
throw new SentinelException(nameof(appVersionCrc.AppsPcbId), string.Format(errorFormat
, nameof(CordonelAppVeriosnCrc)
, nameof(CordonelAppVeriosnCrc.AppsPcbId)
, appVersionCrc.AppsPcbId
, nameof(CordonelAppVeriosnCrc)
, nameof(CordonelAppVeriosnCrc.HistoryPcbId)
, appVersionCrc.HistoryPcbId));
}
else if (appVersionCrc.AppsAppId != appVersionCrc.FilesAppId)
{
throw new SentinelException(nameof(appVersionCrc.AppsAppId), string.Format(errorFormat
, nameof(CordonelAppVeriosnCrc)
, nameof(CordonelAppVeriosnCrc.AppsAppId)
, appVersionCrc.AppsAppId
, nameof(CordonelAppVeriosnCrc)
, nameof(CordonelAppVeriosnCrc.FilesAppId)
, appVersionCrc.FilesAppId));
}
firstIteration = !firstIteration;
}
if (appVersionCrc.AppsAppId == byte.MaxValue.ToString("X2"))
{
// TODO: compare min max and metrology
}
else if (appVersionCrc.AppsAppVersion != appVersionCrc.HistoryAppVersion)
{
throw new SentinelException(nameof(appVersionCrc.AppsAppVersion), string.Format(errorFormat
, nameof(CordonelAppVeriosnCrc)
, nameof(CordonelAppVeriosnCrc.AppsAppVersion)
, appVersionCrc.AppsAppVersion
, nameof(CordonelAppVeriosnCrc)
, nameof(CordonelAppVeriosnCrc.HistoryAppVersion)
, appVersionCrc.HistoryAppVersion));
}
else if (appVersionCrc.AppsAppVersion != appVersionCrc.FilesAppVersion)
{
throw new SentinelException(nameof(appVersionCrc.AppsAppVersion), string.Format(errorFormat
, nameof(CordonelAppVeriosnCrc)
, nameof(CordonelAppVeriosnCrc.AppsAppVersion)
, appVersionCrc.AppsAppVersion
, nameof(CordonelAppVeriosnCrc)
, nameof(CordonelAppVeriosnCrc.FilesAppVersion)
, appVersionCrc.FilesAppVersion));
}
if (appVersionCrc.AppsAppId == Apps.FLEXNETVERSION.ToString("X2"))
{
currentFlexnetVersion = appVersionCrc.HistoryAppVersion;
}
}
if (requirementFlexnetVersion != currentFlexnetVersion)
{
throw new SentinelException(nameof(Apps.FLEXNETVERSION), string.Format(errorFormat
, nameof(CordonelRequirements)
, nameof(CordonelRequirements.FwVersion)
, requirementFlexnetVersion
, nameof(CordonelAppVeriosnCrc)
, nameof(CordonelAppVeriosnCrc.HistoryAppVersion)
, currentFlexnetVersion));
}
}
internal void TryCompareLUTCRCVersion(CordonelRequirements requirements, EOLProgressModel eolProgress, CordonelAppsDictionary apps)
{
var errorFormat = "{0}.{1}({2}) != {3}.{4}({5})";
@ -146,7 +261,7 @@
}
}
internal void TryCompareMeterSize(CordonelProductionData productionData, CordonelRequirements requirements, EOLProgressModel eolProgress, CordonelAppsDictionary apps)
internal void TryCompareMeterSize(CordonelProductionData productionData, CordonelRequirements requirements, EOLProgressModel eolProgress, CordonelAppsDictionary apps, CordonelMetrologyValues metrologyValues)
{
var errorFormat = "{0}.{1}({2}) != {3}.{4}({5})";
var appMeterSizeValue = apps[Apps.GENESISFLOW][GENESISFLOW.MeterSize].GetValue<byte>();
@ -171,6 +286,26 @@
, nameof(CordonelRequirements.MeterSize)
, requirements.MeterSize));
}
else if (productionData.MeterSizeValue != appMeterSizeValue)
{
throw new SentinelException(nameof(productionData.PcbId), string.Format(errorFormat
, nameof(CordonelProductionData)
, nameof(CordonelProductionData.MeterSizeValue)
, productionData.MeterSizeValue
, nameof(Apps.GENESISFLOW)
, nameof(GENESISFLOW.MeterSize)
, appMeterSizeValue));
}
else if (productionData.MeterSizeValue != metrologyValues.MeterSize)
{
throw new SentinelException(nameof(productionData.PcbId), string.Format(errorFormat
, nameof(CordonelProductionData)
, nameof(CordonelProductionData.MeterSizeValue)
, productionData.MeterSizeValue
, nameof(CordonelMetrologyValues)
, nameof(CordonelMetrologyValues.MeterSize)
, metrologyValues.MeterSize));
}
else if (requirements.MeterSize != eolProgress.ProductionStatusMeterSize)
{
throw new SentinelException(nameof(productionData.PcbId), string.Format(errorFormat
@ -181,15 +316,24 @@
, nameof(EOLProgressModel.ProductionStatusMeterSize)
, eolProgress.ProductionStatusMeterSize));
}
else if (productionData.MeterSizeValue != appMeterSizeValue)
}
private void TryCompareMetrologyValues(CordonelRequirements requirements, EOLProgressModel eolProgress, CordonelAppsDictionary apps, CordonelMetrologyValues metrologyValues)
{
if (requirements.SkipCalibration == true)
{
throw new SentinelException(nameof(productionData.PcbId), string.Format(errorFormat
, nameof(CordonelProductionData)
, nameof(CordonelProductionData.MeterSizeValue)
, productionData.MeterSizeValue
, nameof(Apps.GENESISFLOW)
, nameof(GENESISFLOW.MeterSize)
, appMeterSizeValue));
return;
}
var checkCalibration = eolProgress.ProductionStatusCalibrationChecked == EOLStatus.OK;
var checkZeroFlow = eolProgress.ProductionStatusZeroFlowChecked == EOLStatus.OK;
foreach (var kvp in metrologyValues.CompareWithErrors(apps, checkCalibration, checkZeroFlow))
{
if (!string.IsNullOrWhiteSpace(kvp.Key))
{
throw new SentinelException(kvp.Key, kvp.Value);
}
}
}
@ -318,6 +462,28 @@
}
}
internal void TryGetCordonelAppsAndFWVersionValues(int pcbId, out CordonelAppVeriosnCrc[] appsVersionsCrc)
{
appsVersionsCrc = this.cordonelDbContext
.GetLatestAppsWithVersions(pcbId)
.ToArray();
if (appsVersionsCrc.Length <= 0)
{
throw new SentinelException(nameof(CordonelAppVeriosnCrc), "Keine ergebnisse gefunden");
}
}
internal void TryGetCordonelMetrologyValues(int pcbId, out CordonelMetrologyValues metrologyValues)
{
metrologyValues = this.cordonelDbContext.GetLatestGenesisFlowValues(pcbId);
if (metrologyValues is null)
{
throw new SentinelException(nameof(CordonelMetrologyValues), "Keine ergebnisse gefunden");
}
}
internal void TryGetCordonelRequirements(int pcbId, out CordonelRequirements requirements)
{
requirements = this.cordonelDbContext