Merge branch 'Dev_ProdUiCord'
This commit is contained in:
-73
@@ -1,73 +0,0 @@
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// Genesis meter final test states
|
||||
/// </summary>
|
||||
public enum PickingProcessState
|
||||
{
|
||||
/// <summary>
|
||||
/// Idle (nothing to do)
|
||||
/// </summary>
|
||||
Idle,
|
||||
|
||||
/// <summary>
|
||||
/// Idle (nothing to do)
|
||||
/// </summary>
|
||||
ScanOrder,
|
||||
/// <summary>
|
||||
/// New meter detected for marker to clear all process contents like production status
|
||||
/// and programming parameters.
|
||||
/// </summary>
|
||||
CheckNewMeter,
|
||||
/// <summary>
|
||||
/// Error handling
|
||||
/// </summary>
|
||||
Error,
|
||||
/// <summary>
|
||||
/// Abort final test execution
|
||||
/// </summary>
|
||||
Abort,
|
||||
/// <summary>
|
||||
/// Repeat the entire final test
|
||||
/// </summary>
|
||||
RepeatFailedTests,
|
||||
/// <summary>
|
||||
/// Final test failed
|
||||
/// </summary>
|
||||
PickingFailed,
|
||||
/// <summary>
|
||||
/// User stopped process
|
||||
/// </summary>
|
||||
Stop,
|
||||
/// <summary>
|
||||
/// Check the actual production state if all steps are executed
|
||||
/// </summary>
|
||||
DetectCordonel,
|
||||
/// <summary>
|
||||
/// Connect to Cordonel
|
||||
/// </summary>
|
||||
ConnectCordonel,
|
||||
/// <summary>
|
||||
/// Request the serial number and radio address from DB
|
||||
/// </summary>
|
||||
GetPickingParameters,
|
||||
/// <summary>
|
||||
/// Check the radio functionality
|
||||
/// </summary>
|
||||
CompareMeterDetails,
|
||||
InstallLut,
|
||||
//todo ad excisting processstates
|
||||
|
||||
|
||||
|
||||
PrintReturnReport,
|
||||
/// <summary>
|
||||
/// Print success report
|
||||
/// </summary>
|
||||
PrintSuccessReport,
|
||||
/// <summary>
|
||||
/// Delimiter for list
|
||||
/// </summary>
|
||||
StateListDelimiter
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -4,7 +4,7 @@ using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.UserControls;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses
|
||||
{
|
||||
public class CheckOrderNumber : BaseProductionProcess
|
||||
{
|
||||
+87
-104
@@ -6,8 +6,6 @@ using System.Windows;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using Logic.ProductionToProductMapper.Files.Fw;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Applications;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Const;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus;
|
||||
@@ -16,6 +14,7 @@ using Xylem.Common.Logic.ProductionOrderCore.OrderData;
|
||||
using Xylem.Common.Logic.ProductionOrderCore.TestResults;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Model;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericModules;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
|
||||
@@ -29,7 +28,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <summary>
|
||||
/// Maximum of expected processing steps for this process to feed the GUI progress bar.
|
||||
/// </summary>
|
||||
private const Int32 MaxActualProgressSteps = 22;
|
||||
private const Int32 MaxActualProgressSteps = 23;
|
||||
|
||||
/// <summary>
|
||||
/// Successfully test on flow test bench will return this const value.
|
||||
@@ -121,13 +120,13 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
ActualProcessProgress++;
|
||||
|
||||
// Get clustered FileId of firmware package for production or on special requirement release candidates
|
||||
var isSpecialActive = ProductionRequirements.IsSpecialActive != null &&
|
||||
var isSpecialActive = ProductionRequirements.IsSpecialActive != null &&
|
||||
(Boolean)ProductionRequirements.IsSpecialActive &&
|
||||
ProductionRequirements.IsSpecialApproved != null &&
|
||||
ProductionRequirements.IsSpecialApproved != null &&
|
||||
(Boolean)ProductionRequirements.IsSpecialApproved;
|
||||
|
||||
if (string.IsNullOrEmpty(ProductionRequirements.FwVersion) ||
|
||||
!MeterFwUpdate.SearchProdFwInDb(ProductionRequirements.FwVersion, out var parentFileId, out error,
|
||||
!MeterFwUpdate.SearchProdFwInDb(ProductionRequirements.FwVersion, out var parentFileId, out error,
|
||||
!isSpecialActive) || parentFileId == null)
|
||||
{
|
||||
Meter.WriteLog(error);
|
||||
@@ -168,9 +167,22 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Exit if meanwhile cancellation is required
|
||||
if (CancellationToken.IsCancellationRequested)
|
||||
return CancellationProcedure();
|
||||
|
||||
|
||||
ActualProcessProgress++;
|
||||
|
||||
// Get the meter length from VAKO needed for radio parameter message
|
||||
if (!GenericChecks.GetMeterLengthFromDb(Meter))
|
||||
{
|
||||
// Meter size unknown
|
||||
ErrorMsgDispatcher(Resources.StrErrorMsgMeterLengthUnknown);
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
// Exit if meanwhile cancellation is required
|
||||
if (CancellationToken.IsCancellationRequested)
|
||||
return CancellationProcedure();
|
||||
|
||||
ActualProcessProgress++;
|
||||
// Check if requirement will force skipping of calibration
|
||||
if (!ProductionRequirements.SkipCalibration)
|
||||
{
|
||||
@@ -186,7 +198,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Exit if meanwhile cancellation is required
|
||||
if (CancellationToken.IsCancellationRequested)
|
||||
return CancellationProcedure();
|
||||
|
||||
|
||||
ActualProcessProgress++;
|
||||
|
||||
// Get the pre- and final flow test state.
|
||||
@@ -202,7 +214,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Exit if meanwhile cancellation is required
|
||||
if (CancellationToken.IsCancellationRequested)
|
||||
return CancellationProcedure();
|
||||
|
||||
|
||||
ActualProcessProgress++;
|
||||
|
||||
// Fill the results to calibration check register restorer which will be used to read the actual
|
||||
@@ -251,6 +263,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
CalibCheckRegisterRestorer.OnProcessUpdate -= ProcessUpdate_Handler;
|
||||
}// Not Skip calibration loop
|
||||
|
||||
ActualProcessProgress++;
|
||||
|
||||
return StatusReturn.Okay;
|
||||
}
|
||||
|
||||
@@ -315,6 +329,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// - Collect all requirement statuses before signalizing failed to summarize results starting with battery
|
||||
/// load.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Check radio signal levels in parameter list.
|
||||
/// </remarks>
|
||||
public override StatusReturn ExecuteProcess()
|
||||
{
|
||||
#region ----------------------------------- Check EOL Progress --------------------------------------------
|
||||
@@ -404,6 +421,22 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
ActualProcessProgress++;
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Kitron Radio Signal Levels ------------------------------
|
||||
|
||||
var statusReturn = CheckKitronRadioSignalLevels(out feedbackMsg);
|
||||
if (StatusReturn.Failed == statusReturn)
|
||||
{
|
||||
ErrorMsgDispatcher(feedbackMsg);
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
if (StatusReturn.Okay == statusReturn)
|
||||
{
|
||||
SuccessMsgDispatcher(feedbackMsg);
|
||||
}
|
||||
|
||||
ActualProcessProgress++;
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Firmware and Apps ---------------------------------------
|
||||
|
||||
if (string.IsNullOrEmpty(CheckFwAndApps(out feedbackMsg)))
|
||||
@@ -506,7 +539,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// This step may exit with "skipped" here if "special-requirement" forces to skip the check of calibration.
|
||||
// All following checks will be skipped as well.
|
||||
|
||||
var statusReturn = CheckCalibrationValues(out feedbackMsg);
|
||||
statusReturn = CheckCalibrationValues(out feedbackMsg);
|
||||
if (StatusReturn.Skipped == statusReturn)
|
||||
{
|
||||
WarningMsgDispatcher(feedbackMsg);
|
||||
@@ -527,17 +560,17 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
erroneousSequenceStep = true;
|
||||
}
|
||||
#endregion -------------------------------- Check Calibration Values --------------------------------------
|
||||
|
||||
|
||||
#region ----------------------------------- Summarize Check Results ---------------------------------------
|
||||
|
||||
|
||||
// One or more checks failed
|
||||
if (erroneousSequenceStep)
|
||||
return StatusReturn.Failed;
|
||||
|
||||
|
||||
// One or more checks generated a warning
|
||||
if (warningSequenceStep)
|
||||
return StatusReturn.Skipped;
|
||||
|
||||
|
||||
// Here everything went fine
|
||||
SuccessMsgDispatcher(feedbackMsg);
|
||||
|
||||
@@ -656,11 +689,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
EolProgress.SpecialRequirementId = ProductionRequirements.SpecialId;
|
||||
EolProgress.SpecialRequirementVersion = ProductionRequirements.SpecialVersion;
|
||||
|
||||
feedbackMsg = isSpecialActive &&
|
||||
ProductionRequirements.SpecialId != null &&
|
||||
ProductionRequirements.SpecialVersion != null ?
|
||||
Resources.StrWarningMsgSpecialRequirementActive +
|
||||
$" Id.Ver: {ProductionRequirements.SpecialId}.{ProductionRequirements.SpecialVersion}" :
|
||||
feedbackMsg = isSpecialActive &&
|
||||
ProductionRequirements.SpecialId != null &&
|
||||
ProductionRequirements.SpecialVersion != null ?
|
||||
Resources.StrWarningMsgSpecialRequirementActive +
|
||||
$" Id.Ver: {ProductionRequirements.SpecialId}.{ProductionRequirements.SpecialVersion}" :
|
||||
Resources.StrSuccessMsgRequirementActive +
|
||||
$" Id.Ver {ProductionRequirements.StandardId}.{ProductionRequirements.StandardVersion}";
|
||||
|
||||
@@ -855,6 +888,24 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
return EolProgress.ProductionStatusMeterSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check the measurements from Kitron for this specific Cordonel if it is an EMEA region.
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_008]_Check_Kitron_Radio_Levels
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
private StatusReturn CheckKitronRadioSignalLevels(out String feedbackMsg)
|
||||
{
|
||||
return GenericChecks.CheckKitronRadioSignalLevels(Meter, RegisterRestorer, ProductionRequirements.SkipRadioCheck,
|
||||
out feedbackMsg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check the installed firmware (FW) and all individual applications (Apps) installed to the meter:
|
||||
/// - Take the FLEXNETVERSION as base information which FW is installed in the Cordonel and compare this with
|
||||
@@ -866,7 +917,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// Cordonel operational system (Breeze).
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_008]_Check_FW_and_Apps
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_009]_Check_FW_and_Apps
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
@@ -874,91 +925,23 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <remarks date="2024-Nov-15" author="Thomas Wiedebusch">
|
||||
/// - Extracted from <see cref="ExecuteProcess"/> for better testability.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Exported to generic tests.
|
||||
/// </remarks>
|
||||
private String CheckFwAndApps(out String feedbackMsg)
|
||||
{
|
||||
feedbackMsg = "";
|
||||
// Check installed FW version with FLEXNET information
|
||||
var fwUpdate = new MeterFwUpdate(Meter);
|
||||
if (EolProgress == null ||
|
||||
Meter == null ||
|
||||
ProductionRequirements == null ||
|
||||
string.IsNullOrEmpty(ProductionRequirements.FwVersion) ||
|
||||
string.IsNullOrEmpty(Meter.FwVersion) ||
|
||||
!Meter.FwVersion.Equals(ProductionRequirements.FwVersion) ||
|
||||
// Check if FW package has been loaded and contains at least the minimal required files
|
||||
FwUpdatePackage == null ||
|
||||
FwUpdatePackage.Count < MeterFwUpdate.MinAppsRequiredForOperation)
|
||||
var fwCheckMsg = GenericChecks.CheckFwAndApps(Meter, ProductionRequirements, FwUpdatePackage,
|
||||
out feedbackMsg);
|
||||
|
||||
// Fill the EOL progress
|
||||
if (string.IsNullOrEmpty(fwCheckMsg))
|
||||
{
|
||||
if (EolProgress != null)
|
||||
EolProgress.ProductionStatusFwVersion = null;
|
||||
feedbackMsg += $"{Resources.StrErrorMsgRequirementFw}\n";
|
||||
return "";
|
||||
}
|
||||
|
||||
var fileApps = new List<FileApplications>();
|
||||
if (FwUpdatePackage != null)
|
||||
{
|
||||
foreach (var file in FwUpdatePackage)
|
||||
{
|
||||
// load the ABC (application binary container)
|
||||
if (file.FileName.Contains("binfile") &&
|
||||
file.FileName.EndsWith(".bin") &&
|
||||
// Sometimes the * complete *.bin is part of the binaries containing all app in one file.
|
||||
// As this is not part of the ADF it has to be skipped from loading!!!!
|
||||
!file.FileName.Contains("complete"))
|
||||
{
|
||||
var fileApplication = new FileApplications(file.FileName)
|
||||
{
|
||||
BinData = new List<Byte>(file.FileContent.ToList())
|
||||
};
|
||||
fileApps.Add(fileApplication);
|
||||
}
|
||||
// Load the ADF (application description file, containing the information
|
||||
// of each application)
|
||||
else if (file.FileName.Contains("product") && file.FileName.EndsWith(".txt"))
|
||||
{
|
||||
var enc = new System.Text.ASCIIEncoding();
|
||||
var adf = enc.GetString(file.FileContent.ToArray());
|
||||
fwUpdate.LoadPackageFileFromText(adf);
|
||||
}
|
||||
}
|
||||
|
||||
fwUpdate.LoadFileApps(fileApps);
|
||||
}
|
||||
|
||||
var checkSucceeded = true;
|
||||
// Compare every installed application for version and CRC with the required to be defined by the downloaded
|
||||
// ABC (application binary container)
|
||||
fwUpdate.CompareAllMeterAndFileApps();
|
||||
|
||||
if (// Validate package description file with required Apps (fileApps) and build the CORE REVISIONS MIN MAX
|
||||
!fwUpdate.ValidateFileAppsWithPackageFile() ||
|
||||
// Check if any meter Apps is outdated or does contain an un-matching CRC
|
||||
Meter.MeterAppListVersion.Any(app => app.Status != MeterAppState.MeterAppUpToDate &&
|
||||
app.Status != MeterAppState.MeterAppNotRequired))
|
||||
{
|
||||
feedbackMsg += $"{Resources.StrErrorMsgAppVersionOrCrc}\n";
|
||||
checkSucceeded = false;
|
||||
// Do not immediately return to summarize all errors following up
|
||||
}
|
||||
|
||||
// The package description file has to be parsed in advance using the fwUpdate.ValidateFileAppsWithPackageFile()!!
|
||||
if (!fwUpdate.CheckCoreRevision(Meter.CoreRevision))
|
||||
{
|
||||
feedbackMsg += $"{Resources.StrErrorMsgCoreRevision}\n";
|
||||
// Do not immediately return to summarize all errors following up
|
||||
checkSucceeded = false;
|
||||
}
|
||||
|
||||
if (!checkSucceeded)
|
||||
{
|
||||
EolProgress.ProductionStatusFwVersion = null;
|
||||
feedbackMsg += $"{Resources.StrErrorMsgRequirementFw}\n";
|
||||
return EolProgress.ProductionStatusFwVersion;
|
||||
}
|
||||
EolProgress.ProductionStatusFwVersion = Meter.FwVersion;
|
||||
feedbackMsg = $"{Resources.StrSuccessMsgRequirementFw} - Firmware: {Meter.FwVersion}";
|
||||
return EolProgress.ProductionStatusFwVersion;
|
||||
return fwCheckMsg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -974,7 +957,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// calculation is being used.
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_009]_Check_Remaining_Battery_Load
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_010]_Check_Remaining_Battery_Load
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
@@ -1075,7 +1058,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// Check the remaining lifetime
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_010]_Check_Remaining_Lifetime
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_011]_Check_Remaining_Lifetime
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
@@ -1139,7 +1122,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// Check the months between first battery activation and now
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_011]_Check_Storage_Months
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_012]_Check_Storage_Months
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
@@ -1215,7 +1198,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// don't match, the check of valid range and set to default values doesn't come in focus!
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_012]_Check_Calibration_Values
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_013]_Check_Calibration_Values
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
@@ -1354,7 +1337,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Allow overwriting of calibration successfully checked to okay
|
||||
if (EolProgress.ProductionStatusCalibrationChecked == null)
|
||||
EolProgress.ProductionStatusCalibrationChecked = EOLStatus.OK;
|
||||
|
||||
|
||||
// Stop logging
|
||||
CalibCheckRegisterRestorer.OnProcessUpdate -= ProcessUpdate_Handler;
|
||||
|
||||
@@ -1366,7 +1349,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// the according step has been successfully executed.
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_013]_Check_Preadjustment
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_014]_Check_Preadjustment
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
@@ -1428,7 +1411,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// the according step has been successfully executed.
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_014]_Check_Flow_Test_State
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_015]_Check_Flow_Test_State
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
|
||||
+30
-7
@@ -1,12 +1,13 @@
|
||||
using System;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SIRTCOM;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Windows.Threading;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SIRTCOM;
|
||||
using System.Xml.Linq;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
@@ -15,6 +16,7 @@ using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.UserControls;
|
||||
using Xylem.Common.Utils.Logging;
|
||||
using Button = System.Windows.Controls.Button;
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Local
|
||||
|
||||
@@ -652,6 +654,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
/// <remarks date="2023-07-11" author="Thomas Wiedebusch">
|
||||
/// - Optimized based on new documentations.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-06-17" author="Thomas Wiedebusch">
|
||||
/// - Logging path changed.
|
||||
/// </remarks>
|
||||
private void SendPamListenSemi(Int32 radioAddress, Int32 byteComPort, String strKey)
|
||||
{
|
||||
if (_dataContainer == null || _stateMachine == null)
|
||||
@@ -665,9 +670,27 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
_dataContainer.RadioAdress = radioAddress;
|
||||
|
||||
_stateMachine.initialise((Byte)byteComPort);
|
||||
var date = DateTime.Now.Date;
|
||||
var loggingPath = $"C:\\GenesisLog\\{date:yyyy-MM-dd}\\ProductionUiCordonel\\{Meter.PcbId}_RadioCheck.log";
|
||||
_stateMachine.StartLoggin(loggingPath);
|
||||
|
||||
try
|
||||
{
|
||||
var path = NLogHelper.GetApplicationDataPath();
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
path = NLogHelper.GetCurrentApplicationFolder();
|
||||
}
|
||||
|
||||
var a = XElement.Load(path);
|
||||
var baseLoggingPath = a.Elements().First(s => s.Name.LocalName == "variable").Attributes()
|
||||
.First(s => s.Value == "BasePath").NextAttribute.Value;
|
||||
|
||||
var loggingPath =
|
||||
$"{baseLoggingPath}\\{DateTime.Now:yyyy-MM-dd}\\ProductionUiCordonel\\{Meter.PcbId}_RadioCheck.log";
|
||||
_stateMachine.StartLoggin(loggingPath);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
LogNewStatusMsg($"{Resources.StrRadioMsgSendPam}: {radioAddress.ToString()}");
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.UserControls;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses
|
||||
{
|
||||
public class CheckSerialNumber : BaseProductionProcess
|
||||
{
|
||||
+19
-20
@@ -151,25 +151,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Kick off parallel process execution
|
||||
kickOffParallelState: ProcessState.GetProgrammingParameters),
|
||||
|
||||
// This scans the order number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new CheckOrderNumber(Resources.StrStateCheckOrderNumber),
|
||||
processState: ProcessState.CheckOrderNumber,
|
||||
processInfo: Resources.StrStateCheckOrderNumber,
|
||||
productionProcessNo: 11,
|
||||
nextStateOnSuccess: ProcessState.CheckSerialNumber),
|
||||
|
||||
// This scans the serial number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new CheckSerialNumber( Resources.StrStateCheckSerialNumber),
|
||||
processState: ProcessState.CheckSerialNumber,
|
||||
processInfo: Resources.StrStateCheckSerialNumber,
|
||||
productionProcessNo: 12,
|
||||
nextStateOnSuccess: ProcessState.CheckAttachments),
|
||||
|
||||
#endregion -------------------------------- GENERIC-STATES --------------------------------------------
|
||||
|
||||
#region ----------------------------------- EOL-STATES ------------------------------------------------
|
||||
// Precondition: - The connection process has to be completed as a readout of some register
|
||||
// values from the Cordonel are needed to check the update capability:
|
||||
// - Wait on completed connection process before starting this process.
|
||||
@@ -186,6 +167,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
// Wait until this process has been successfully completed
|
||||
waitForSingleProcess: ProcessState.ConnectCordonel),
|
||||
|
||||
#endregion -------------------------------- GENERIC-STATES --------------------------------------------
|
||||
|
||||
#region ----------------------------------- EOL-STATES ------------------------------------------------
|
||||
// Precondition: - The connection process has to be completed as a readout of some register
|
||||
// values from the Cordonel are needed to check the update capability:
|
||||
// - Wait on completed connection process before starting this process.
|
||||
@@ -201,7 +185,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
kickOffParallelState: ProcessState.ProcessPasswordFile,
|
||||
// Wait until this process has been successfully completed
|
||||
waitForSingleProcess: ProcessState.ConnectCordonel),
|
||||
|
||||
|
||||
// Precondition: - The connection process has to be completed as a password change in the DB
|
||||
// will take place: Skeleton to Password Level 8. Not waiting for completion may cause side
|
||||
@@ -265,6 +248,22 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
|
||||
productionProcessNo: 10,
|
||||
nextStateOnSuccess: ProcessState.CheckOrderNumber),
|
||||
|
||||
// This scans the order number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new CheckOrderNumber(Resources.StrStateCheckOrderNumber),
|
||||
processState: ProcessState.CheckOrderNumber,
|
||||
processInfo: Resources.StrStateCheckOrderNumber,
|
||||
productionProcessNo: 11,
|
||||
nextStateOnSuccess: ProcessState.CheckSerialNumber),
|
||||
|
||||
// This scans the serial number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new CheckSerialNumber( Resources.StrStateCheckSerialNumber),
|
||||
processState: ProcessState.CheckSerialNumber,
|
||||
processInfo: Resources.StrStateCheckSerialNumber,
|
||||
productionProcessNo: 12,
|
||||
nextStateOnSuccess: ProcessState.CheckAttachments),
|
||||
|
||||
// Precondition: - All checks have to be executed with positive result
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new CheckAttachments(Resources.StrStateCheckAttachments),
|
||||
|
||||
+1
@@ -3,6 +3,7 @@ using System.Linq;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses
|
||||
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using Logic.ProductionToProductMapper.Files.Fw;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Applications;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Const;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
|
||||
using Xylem.Common.Logic.ProductionOrderCore.Vako;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericModules
|
||||
{
|
||||
internal static class GenericChecks
|
||||
{
|
||||
/// <summary>
|
||||
/// Check the measurements from Kitron for this specific Cordonel if it is an EMEA region.
|
||||
/// </summary>
|
||||
/// <param name="registerRestorer"></param>
|
||||
/// <param name="skipRadioCheck"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <param name="meter"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Import from CheckProductionState for common use.
|
||||
/// </remarks>
|
||||
public static StatusReturn CheckKitronRadioSignalLevels(IGenesisMeter meter, RegisterRestorer registerRestorer,
|
||||
Boolean skipRadioCheck, out String feedbackMsg)
|
||||
{
|
||||
feedbackMsg = "";
|
||||
if (meter == null ||
|
||||
string.IsNullOrEmpty(meter.MeterSize) ||
|
||||
string.IsNullOrEmpty(meter.Region))
|
||||
{
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
// The NA region has no radio or radio check should be ignored
|
||||
if (meter.Region.Equals("NA") || skipRadioCheck)
|
||||
{
|
||||
return StatusReturn.Skipped;
|
||||
}
|
||||
var pressureSensorAssembled =
|
||||
meter.PressureSensorAssembled ? $", {Resources.StrLblPressureSensorAssembledTxt}" : "";
|
||||
var meterInfo = $"{Resources.StrLblRadioFrequencyTxt}: {meter.RadioFrequencyMhz} MHz," +
|
||||
$"{Resources.StrLblMeterSizeTxt}: {meter.MeterSize}, " +
|
||||
$"{Resources.StrLblMeterLengthTxt}: {meter.MeterLength} mm" +
|
||||
$"{pressureSensorAssembled}";
|
||||
// On unknown radio signal level parameters from Kitron those are not in the list of the programming parameters
|
||||
if (!registerRestorer.RecoveryRegisters.Any(x => x.RegisterIdent.Equals("SENSUSRADIO_PowerLevel")))
|
||||
{
|
||||
feedbackMsg = Resources.StrErrorMsgRadioSignalLevels + " " + meterInfo;
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
feedbackMsg = Resources.StrSuccessMsgRadioSignalLevels + ". " + meterInfo;
|
||||
return StatusReturn.Okay;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check the installed firmware (FW) and all individual applications (Apps) installed to the meter:
|
||||
/// - Take the FLEXNETVERSION as base information which FW is installed in the Cordonel and compare this with
|
||||
/// the production-requirement,
|
||||
/// - The downloaded FW package containing all Apps as application-binary-container (ABC) will be compared with
|
||||
/// the reported Apps by the Cordonel for their version and CRC using the "<see cref="MeterFwUpdate"/> class,
|
||||
/// - Crosscheck if the application-description-file (ADF) states all Apps which are installed in the Cordonel,
|
||||
/// - Check the Core-Revision of the Cordonel against the ADF to guarantee that this FW is supported by the
|
||||
/// Cordonel operational system (Breeze).
|
||||
/// </summary>
|
||||
/// <param name="meter"></param>
|
||||
/// <param name="requirements"></param>
|
||||
/// <param name="fwUpdatePackage"></param>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Import from CheckProductionState for common use.
|
||||
/// </remarks>
|
||||
public static String CheckFwAndApps(IGenesisMeter meter, CordonelRequirements requirements,
|
||||
List<FilePart> fwUpdatePackage, out String feedbackMsg)
|
||||
{
|
||||
feedbackMsg = "";
|
||||
// Check installed FW version with FLEXNET information
|
||||
var fwUpdate = new MeterFwUpdate(meter);
|
||||
if (meter == null ||
|
||||
requirements == null ||
|
||||
string.IsNullOrEmpty(requirements.FwVersion) ||
|
||||
string.IsNullOrEmpty(meter.FwVersion) ||
|
||||
!meter.FwVersion.Equals(requirements.FwVersion) ||
|
||||
// Check if FW package has been loaded and contains at least the minimal required files
|
||||
fwUpdatePackage == null ||
|
||||
fwUpdatePackage.Count < MeterFwUpdate.MinAppsRequiredForOperation)
|
||||
{
|
||||
feedbackMsg += $"{Resources.StrErrorMsgRequirementFw}\n";
|
||||
return "";
|
||||
}
|
||||
|
||||
var fileApps = new List<FileApplications>();
|
||||
foreach (var file in fwUpdatePackage)
|
||||
{
|
||||
// load the ABC (application binary container)
|
||||
if (file.FileName.Contains("binfile") &&
|
||||
file.FileName.EndsWith(".bin") &&
|
||||
// Sometimes the * complete *.bin is part of the binaries containing all app in one file.
|
||||
// As this is not part of the ADF it has to be skipped from loading!!!!
|
||||
!file.FileName.Contains("complete"))
|
||||
{
|
||||
var fileApplication = new FileApplications(file.FileName)
|
||||
{
|
||||
BinData = new List<Byte>(file.FileContent.ToList())
|
||||
};
|
||||
fileApps.Add(fileApplication);
|
||||
}
|
||||
// Load the ADF (application description file, containing the information
|
||||
// of each application)
|
||||
else if (file.FileName.Contains("product") && file.FileName.EndsWith(".txt"))
|
||||
{
|
||||
var enc = new System.Text.ASCIIEncoding();
|
||||
var adf = enc.GetString(file.FileContent.ToArray());
|
||||
fwUpdate.LoadPackageFileFromText(adf);
|
||||
}
|
||||
}
|
||||
|
||||
fwUpdate.LoadFileApps(fileApps);
|
||||
|
||||
var checkSucceeded = true;
|
||||
// Compare every installed application for version and CRC with the required to be defined by the downloaded
|
||||
// ABC (application binary container)
|
||||
fwUpdate.CompareAllMeterAndFileApps();
|
||||
|
||||
if ( // Validate package description file with required Apps (fileApps) and build the CORE REVISIONS MIN MAX
|
||||
!fwUpdate.ValidateFileAppsWithPackageFile() ||
|
||||
// Check if any meter Apps is outdated or does contain an un-matching CRC
|
||||
meter.MeterAppListVersion.Any(app => app.Status != MeterAppState.MeterAppUpToDate &&
|
||||
app.Status != MeterAppState.MeterAppNotRequired))
|
||||
{
|
||||
feedbackMsg += $"{Resources.StrErrorMsgAppVersionOrCrc}\n";
|
||||
checkSucceeded = false;
|
||||
// Do not immediately return to summarize all errors following up
|
||||
}
|
||||
|
||||
// The package description file has to be parsed in advance using the fwUpdate.ValidateFileAppsWithPackageFile()!!
|
||||
if (!fwUpdate.CheckCoreRevision(meter.CoreRevision))
|
||||
{
|
||||
feedbackMsg += $"{Resources.StrErrorMsgCoreRevision}\n";
|
||||
// Do not immediately return to summarize all errors following up
|
||||
checkSucceeded = false;
|
||||
}
|
||||
|
||||
if (!checkSucceeded)
|
||||
{
|
||||
feedbackMsg += $"{Resources.StrErrorMsgRequirementFw}\n";
|
||||
return "";
|
||||
}
|
||||
|
||||
feedbackMsg = $"{Resources.StrSuccessMsgRequirementFw} - Firmware: {meter.FwVersion}";
|
||||
return meter.FwVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the meter length form database as single VAKO parameter
|
||||
/// </summary>
|
||||
/// <param name="meter"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Jun-17" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
public static Boolean GetMeterLengthFromDb(IGenesisMeter meter)
|
||||
{
|
||||
if (meter == null)
|
||||
return false;
|
||||
try
|
||||
{
|
||||
var a = LocalWebRequest.GetRequest(
|
||||
$"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetSingleVakoKey?ProductionOrderNumber=" +
|
||||
$"{meter.OrderNumber}&KeyName=C_GEN_BAULAENGE");
|
||||
var response = JsonConvert.DeserializeObject<VakoKeyValue>(a);
|
||||
|
||||
if (response == null || string.IsNullOrEmpty(response.Value))
|
||||
{
|
||||
// Meter size unknown
|
||||
return false;
|
||||
}
|
||||
|
||||
meter.MeterLength = response.Value;
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Meter size unknown
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,10 +7,10 @@ using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses
|
||||
{
|
||||
/// <summary>
|
||||
/// Request for parameters for final programming including VAKO and CSD
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.UserControls;
|
||||
|
||||
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.PickingProcesses
|
||||
{
|
||||
public class CheckOrderNumber : BaseProductionProcess
|
||||
{
|
||||
// string from scanner with string delimiter
|
||||
private String _scan = "";
|
||||
// marker for scan input received
|
||||
private Boolean _scanInputReceived;
|
||||
/// <summary>
|
||||
/// Ctor
|
||||
/// </summary>
|
||||
public CheckOrderNumber(String name) : base( name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void InitUserControl()
|
||||
{
|
||||
UserControl = new UcBarcodeInput
|
||||
{
|
||||
lblHeadLine = { Content = Resources.StrInstructionScanOrder },
|
||||
tbxScan = { Text = "" }
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler taking the input from text box which should be scanned but also can be input manually.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2023-Jun-21" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
private void UserControlInput_Handler(Object sender, String input)
|
||||
{
|
||||
_scan = input;
|
||||
_scanInputReceived = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scanning of order number from production order sheet and comparing with DB.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2023-Jun-21" author="Thomas Wiedebusch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2023-Jul-07" author="Thomas Wiedebusch">
|
||||
/// - Removed signals for <see cref="SingleProcessState.Error"/> and <see cref="SingleProcessState.Succeeded"/> as
|
||||
/// these will be automatically set based on return value in
|
||||
/// <see cref="BaseProductionProcess.FinalizeProcess"/>.
|
||||
/// </remarks>
|
||||
public override StatusReturn ExecuteProcess()
|
||||
{
|
||||
if (Meter == null)
|
||||
{
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
SignalRunningState();
|
||||
|
||||
if (UserControl == null)
|
||||
{
|
||||
ErrorMsgDispatcher(Resources.StrErrorMsgScanOrderNumber);
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
|
||||
var ucBarCode = (UcBarcodeInput)UserControl;
|
||||
ucBarCode.OnBarcodeInput += UserControlInput_Handler;
|
||||
|
||||
// set focus to text input for scanner
|
||||
ucBarCode.FocusMe();
|
||||
_scanInputReceived = false;
|
||||
|
||||
// wait for new line
|
||||
while (!_scanInputReceived)
|
||||
{
|
||||
}
|
||||
|
||||
ucBarCode.OnBarcodeInput -= UserControlInput_Handler;
|
||||
|
||||
if (!string.IsNullOrEmpty(_scan) && _scan.Length > 5)
|
||||
{
|
||||
//TODO Roland, Do something with the scanned order
|
||||
return StatusReturn.Okay;
|
||||
}
|
||||
|
||||
ErrorMsgDispatcher(Resources.StrErrorMsgScanOrderNumber);
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
-88
@@ -1,15 +1,13 @@
|
||||
using System;
|
||||
using Logic.ProductionToProductMapper.Files.Fw;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using Logic.ProductionToProductMapper.Files.Fw;
|
||||
using Xylem.Common.CommonCore.Consts;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Applications;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Applications.Const;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus;
|
||||
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericModules;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
|
||||
using Xylem.Common.Production.ProductionUiCordonel.Properties;
|
||||
|
||||
@@ -23,7 +21,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
/// <summary>
|
||||
/// Maximum of expected processing steps for this process to feed the GUI progress bar.
|
||||
/// </summary>
|
||||
private const Int32 MaxActualProgressSteps = 13;
|
||||
private const Int32 MaxActualProgressSteps = 14;
|
||||
|
||||
/// <summary>
|
||||
/// FW update package containing the ABC and the ADF.
|
||||
@@ -124,6 +122,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
|
||||
ActualProcessProgress++;
|
||||
|
||||
// Get the meter length from VAKO needed for radio parameter message
|
||||
if (!GenericChecks.GetMeterLengthFromDb(Meter))
|
||||
{
|
||||
// Meter size unknown
|
||||
ErrorMsgDispatcher(Resources.StrErrorMsgMeterLengthUnknown);
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
ActualProcessProgress++;
|
||||
|
||||
return StatusReturn.Okay;
|
||||
}
|
||||
|
||||
@@ -229,6 +236,22 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
ActualProcessProgress++;
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Kitron Radio Signal Levels ------------------------------
|
||||
|
||||
statusReturn = CheckKitronRadioSignalLevels(out feedbackMsg);
|
||||
if (StatusReturn.Failed == statusReturn)
|
||||
{
|
||||
ErrorMsgDispatcher(feedbackMsg);
|
||||
return StatusReturn.Failed;
|
||||
}
|
||||
if (StatusReturn.Okay == statusReturn)
|
||||
{
|
||||
SuccessMsgDispatcher(feedbackMsg);
|
||||
}
|
||||
|
||||
ActualProcessProgress++;
|
||||
#endregion
|
||||
|
||||
#region ----------------------------------- Check Firmware and Apps ---------------------------------------
|
||||
|
||||
if (string.IsNullOrEmpty(CheckFwAndApps(out feedbackMsg)))
|
||||
@@ -531,6 +554,25 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
return ProductionRequirements.MeterSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check the measurements from Kitron for this specific Cordonel if it is an EMEA region.
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_EOL_PP_CHECK_PROD_STATE_007]_Check_Kitron_Radio_Levels
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
private StatusReturn CheckKitronRadioSignalLevels(out String feedbackMsg)
|
||||
{
|
||||
return GenericChecks.CheckKitronRadioSignalLevels(Meter, RegisterRestorer, ProductionRequirements.SkipRadioCheck,
|
||||
out feedbackMsg);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check the installed firmware (FW) and all individual applications (Apps) installed to the meter:
|
||||
/// - Take the FLEXNETVERSION as base information which FW is installed in the Cordonel and compare this with
|
||||
@@ -542,7 +584,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
/// Cordonel operational system (Breeze).
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_007]_Check_FW_and_Apps
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_008]_Check_FW_and_Apps
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
@@ -550,86 +592,12 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
/// <remarks date="2025-Mai-15" author="Thomas Wiedebusch">
|
||||
/// - Initial.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Mai-28" author="Thomas Wiedebusch">
|
||||
/// - Exported to generic tests.
|
||||
/// </remarks>
|
||||
private String CheckFwAndApps(out String feedbackMsg)
|
||||
{
|
||||
feedbackMsg = "";
|
||||
// Check installed FW version with FLEXNET information
|
||||
var fwUpdate = new MeterFwUpdate(Meter);
|
||||
if (Meter == null ||
|
||||
ProductionRequirements == null ||
|
||||
string.IsNullOrEmpty(ProductionRequirements.FwVersion) ||
|
||||
string.IsNullOrEmpty(Meter.FwVersion) ||
|
||||
!Meter.FwVersion.Equals(ProductionRequirements.FwVersion) ||
|
||||
// Check if FW package has been loaded and contains at least the minimal required files
|
||||
FwUpdatePackage == null ||
|
||||
FwUpdatePackage.Count < MeterFwUpdate.MinAppsRequiredForOperation)
|
||||
{
|
||||
feedbackMsg += $"{Resources.StrErrorMsgRequirementFw}\n";
|
||||
return "";
|
||||
}
|
||||
|
||||
var fileApps = new List<FileApplications>();
|
||||
if (FwUpdatePackage != null)
|
||||
{
|
||||
foreach (var file in FwUpdatePackage)
|
||||
{
|
||||
// load the ABC (application binary container)
|
||||
if (file.FileName.Contains("binfile") &&
|
||||
file.FileName.EndsWith(".bin") &&
|
||||
// Sometimes the * complete *.bin is part of the binaries containing all app in one file.
|
||||
// As this is not part of the ADF it has to be skipped from loading!!!!
|
||||
!file.FileName.Contains("complete"))
|
||||
{
|
||||
var fileApplication = new FileApplications(file.FileName)
|
||||
{
|
||||
BinData = new List<Byte>(file.FileContent.ToList())
|
||||
};
|
||||
fileApps.Add(fileApplication);
|
||||
}
|
||||
// Load the ADF (application description file, containing the information
|
||||
// of each application)
|
||||
else if (file.FileName.Contains("product") && file.FileName.EndsWith(".txt"))
|
||||
{
|
||||
var enc = new System.Text.ASCIIEncoding();
|
||||
var adf = enc.GetString(file.FileContent.ToArray());
|
||||
fwUpdate.LoadPackageFileFromText(adf);
|
||||
}
|
||||
}
|
||||
|
||||
fwUpdate.LoadFileApps(fileApps);
|
||||
}
|
||||
|
||||
var checkSucceeded = true;
|
||||
// Compare every installed application for version and CRC with the required to be defined by the downloaded
|
||||
// ABC (application binary container)
|
||||
fwUpdate.CompareAllMeterAndFileApps();
|
||||
|
||||
if (// Validate package description file with required Apps (fileApps) and build the CORE REVISIONS MIN MAX
|
||||
!fwUpdate.ValidateFileAppsWithPackageFile() ||
|
||||
// Check if any meter Apps is outdated or does contain an un-matching CRC
|
||||
Meter.MeterAppListVersion.Any(app => app.Status != MeterAppState.MeterAppUpToDate &&
|
||||
app.Status != MeterAppState.MeterAppNotRequired))
|
||||
{
|
||||
feedbackMsg += $"{Resources.StrErrorMsgAppVersionOrCrc}\n";
|
||||
checkSucceeded = false;
|
||||
// Do not immediately return to summarize all errors following up
|
||||
}
|
||||
|
||||
// The package description file has to be parsed in advance using the fwUpdate.ValidateFileAppsWithPackageFile()!!
|
||||
if (!fwUpdate.CheckCoreRevision(Meter.CoreRevision))
|
||||
{
|
||||
feedbackMsg += $"{Resources.StrErrorMsgCoreRevision}\n";
|
||||
// Do not immediately return to summarize all errors following up
|
||||
checkSucceeded = false;
|
||||
}
|
||||
|
||||
if (!checkSucceeded)
|
||||
{
|
||||
feedbackMsg += $"{Resources.StrErrorMsgRequirementFw}\n";
|
||||
return "";
|
||||
}
|
||||
feedbackMsg = $"{Resources.StrSuccessMsgRequirementFw} - Firmware: {Meter.FwVersion}";
|
||||
return Meter.FwVersion;
|
||||
return GenericChecks.CheckFwAndApps(Meter, ProductionRequirements, FwUpdatePackage, out feedbackMsg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -645,7 +613,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
/// calculation is being used.
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_008]_Check_Remaining_Battery_Load
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_009]_Check_Remaining_Battery_Load
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
@@ -734,7 +702,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
/// Check the remaining lifetime
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_009]_Check_Remaining_Lifetime
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_010]_Check_Remaining_Lifetime
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
@@ -785,7 +753,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
/// Check the months between first battery activation and now
|
||||
///
|
||||
/// Software Requirement Specification:
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_010]_Check_Storage_Months
|
||||
/// [SRS_TBF_PICK_PP_CHECK_PROD_STATE_011]_Check_Storage_Months
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="feedbackMsg"></param>
|
||||
|
||||
+21
-8
@@ -146,20 +146,33 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
processState: ProcessState.GetSerialNumberAndRadioAddress,
|
||||
processInfo: Resources.StrStateGetSerialAndRadioAddress,
|
||||
productionProcessNo: 2,
|
||||
nextStateOnSuccess: ProcessState.CheckOrderNumber,
|
||||
waitForAllProcesses: true),
|
||||
|
||||
// Avoid automatic change after completion as parallel process is active
|
||||
nextStateOnSuccess: BaseProductionProcess.DoNotChangeStateAfterCompletion,
|
||||
// Kick off parallel process execution
|
||||
kickOffParallelState: ProcessState.GetProgrammingParameters),
|
||||
|
||||
// Precondition: - The connection process has to be completed as a readout of some register
|
||||
// values from the Cordonel are needed to check the update capability:
|
||||
// - Wait on completed connection process before starting this process.
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new GetFinalParametrization(Resources.StrStateGetProgrammingParameters),
|
||||
processState: ProcessState.GetProgrammingParameters,
|
||||
processInfo: Resources.StrStateGetProgrammingParameters,
|
||||
productionProcessNo: 3,
|
||||
nextStateOnSuccess: ProcessState.CheckOrderNumber,
|
||||
// Wait until this process has been successfully completed
|
||||
waitForSingleProcess: ProcessState.ConnectCordonel),
|
||||
#endregion -------------------------------- GENERIC-STATES --------------------------------------------
|
||||
|
||||
#region ----------------------------------- PICKING-STATES --------------------------------------------
|
||||
// This scans the order number, it has to be executed exclusively with automatic
|
||||
new ProcessStateStruct(
|
||||
productionProcess: new CheckOrderNumber(Resources.StrStateCheckOrderNumber),
|
||||
processState: ProcessState.CheckOrderNumber,
|
||||
processInfo: Resources.StrStateCheckOrderNumber,
|
||||
productionProcessNo: 3,
|
||||
productionProcessNo: 4,
|
||||
nextStateOnSuccess: ProcessState.CheckProductionState),
|
||||
|
||||
#endregion -------------------------------- GENERIC-STATES --------------------------------------------
|
||||
|
||||
#region ----------------------------------- PICKING-STATES --------------------------------------------
|
||||
// Precondition: - The connection process has to be completed as a readout of some register
|
||||
// values from the Cordonel are needed to check the update capability:
|
||||
// - Wait on completed connection process before starting this process.
|
||||
@@ -167,7 +180,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
|
||||
productionProcess: new CheckProductionState(Resources.StrStateCheckProductionState),
|
||||
processState: ProcessState.CheckProductionState,
|
||||
processInfo: Resources.StrStateCheckProductionState,
|
||||
productionProcessNo: 4,
|
||||
productionProcessNo: 5,
|
||||
nextStateOnSuccess: ProcessState.Idle),
|
||||
|
||||
//TODO Roland: implement your states here
|
||||
|
||||
@@ -653,7 +653,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses
|
||||
/// <remarks date="2025-Apr-15" author="Thomas Wiedebusch">
|
||||
/// - Feed with processStateStruct.
|
||||
/// </remarks>
|
||||
protected void StartProcess(ProcessStateStruct processStateStruct)
|
||||
private void StartProcess(ProcessStateStruct processStateStruct)
|
||||
{
|
||||
// deny access if uninitialized
|
||||
if (Processes == null || processStateStruct.ProductionProcess == null)
|
||||
|
||||
@@ -259,6 +259,7 @@
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
@@ -284,8 +285,8 @@
|
||||
<DependentUpon>ctlMultiModePressure.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Model\EOLHandler.cs" />
|
||||
<Compile Include="ProductionProcesses\Enum\PickingProcessState.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\VisualInspection.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericModules\GenericChecks.cs" />
|
||||
<Compile Include="ProductionProcesses\IProcessStateDef.cs" />
|
||||
<Compile Include="ProductionProcesses\BaseProcessStatesDef.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericProcesses\ErrorHandler.cs" />
|
||||
@@ -299,6 +300,7 @@
|
||||
<Compile Include="ProductionProcesses\Enum\ProcessState.cs" />
|
||||
<Compile Include="ProductionProcesses\EventArgs\SingleProcessStateArgs.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\EolProcessStatesDef.cs" />
|
||||
<Compile Include="ProductionProcesses\PickingProcesses\CheckOrderNumber.cs" />
|
||||
<Compile Include="ProductionProcesses\PickingProcesses\CheckProductionState.cs" />
|
||||
<Compile Include="ProductionProcesses\PickingProcesses\PickingProcessStatesDef.cs" />
|
||||
<Compile Include="ProductionProcesses\ProcessStateStruct.cs" />
|
||||
@@ -312,12 +314,12 @@
|
||||
<Compile Include="Model\PickingMultiModeViewModel.cs" />
|
||||
<Compile Include="Model\PickingViewModel.cs" />
|
||||
<Compile Include="Model\IMultiModeChildViewModel.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericProcesses\CheckSerialNumber.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericProcesses\CheckOrderNumber.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\CheckSerialNumber.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\CheckOrderNumber.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\CheckAttachments.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\CheckProductionState.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\CheckFinalParametrization.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\GetFinalParametrization.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericProcesses\GetFinalParametrization.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\ExecFinalParametrization.cs" />
|
||||
<Compile Include="ProductionProcesses\EolProcesses\CheckRadio.cs" />
|
||||
<Compile Include="ProductionProcesses\GenericProcesses\ConnectCordonel.cs" />
|
||||
|
||||
@@ -112,6 +112,7 @@
|
||||
<Label Content="Firmware:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="0" Grid.Column="5"/>
|
||||
<Label x:Name="lblLutText" Content="LUT CRC:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="1" Grid.Column="5"/>
|
||||
<Label x:Name="lblMeterSizeText" Content="Meter Size:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="2" Grid.Column="5"/>
|
||||
<Label x:Name="lblMeterLengthText" Content="Meter Length:" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="3" Grid.Column="5"/>
|
||||
|
||||
<Label Content="" x:Name="lblSerialNumberValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="0" Grid.Column="3"/>
|
||||
<Label Content="" x:Name="lblOrderNumberValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="1" Grid.Column="3"/>
|
||||
@@ -120,6 +121,7 @@
|
||||
<Label Content="" x:Name="lblFwValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="0" Grid.Column="6"/>
|
||||
<Label Content="" x:Name="lblLutValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="1" Grid.Column="6"/>
|
||||
<Label Content="" x:Name="lblMeterSizeValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="2" Grid.Column="6"/>
|
||||
<Label Content="" x:Name="lblMeterLengthValue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="2,2,2,2" Grid.Row="3" Grid.Column="6"/>
|
||||
|
||||
<!--Pictures-->
|
||||
<Border Grid.Row="0" Grid.RowSpan="4" Grid.Column="0" Margin="2,2,2,2" BorderThickness="1" BorderBrush="Black" Grid.ColumnSpan="2">
|
||||
|
||||
@@ -13,6 +13,7 @@ using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using System.Xml.Linq;
|
||||
using LaaPackages.Features.Cordonel.Models;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
@@ -44,6 +45,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
private static readonly Version _version = _assemblyName.Version;
|
||||
private readonly String _strSoftwareNameVersion;
|
||||
private RegisterLDAPUser _registerForm;
|
||||
private Boolean _lockGenesisInfo;
|
||||
|
||||
private Int32 Slot
|
||||
{
|
||||
@@ -59,7 +61,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
private String _lastLoggingTextToAvoidRepetition;
|
||||
private CordonelRequirements _productionRequirements;
|
||||
private UserAccessWindow _userAccessWindow;
|
||||
private IProcessStateDef _processStateDef;
|
||||
private readonly IProcessStateDef _processStateDef;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -104,6 +106,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
UpdateContentControl(lblRadioAddressText, Properties.Resources.StrLblRadioAddressTxt + ":");
|
||||
UpdateContentControl(lblOrderNumberText, Properties.Resources.StrLblOrderNumberTxt + ":");
|
||||
UpdateContentControl(lblMeterSizeText, Properties.Resources.StrLblMeterSizeTxt + ":");
|
||||
UpdateContentControl(lblMeterLengthText, Properties.Resources.StrLblMeterLengthTxt + ":");
|
||||
UpdateContentControl(lblSingleProcessText, Properties.Resources.StrLblSingleProcessText + ":");
|
||||
UpdateContentControl(lblTotalProcessText, Properties.Resources.StrLblTotalProcessText + ":");
|
||||
optionsMenu.Header = Properties.Resources.StrMenuOptionsText;
|
||||
@@ -446,6 +449,11 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
PrintSuccessNote();
|
||||
BtnStop_Click(this, null);
|
||||
}
|
||||
// Enable display of Genesis information on new detected
|
||||
if (e.State == ProcessState.ConnectCordonel)
|
||||
{
|
||||
_lockGenesisInfo = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -694,15 +702,18 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
/// <remarks date="????" author="Roland Drabesch">
|
||||
/// - Initial
|
||||
/// </remarks>
|
||||
/// <remarks date="2024-07-15" author="Thomas Wiedebusch">
|
||||
/// <remarks date="2024-Jul-15" author="Thomas Wiedebusch">
|
||||
/// - Additional info of Cordonel.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-18" author="Thomas Wiedebusch">
|
||||
/// - Lock display of OLD Genesis after connect until the Genesis has been detected.
|
||||
/// </remarks>
|
||||
private void UpdateGuiWithProductInfos()
|
||||
{
|
||||
var genesisMeter = _processCtrl?.GetGenesisMeter();
|
||||
_productionRequirements = _processCtrl?.GetProductionRequirements();
|
||||
|
||||
if (genesisMeter == null)
|
||||
if (genesisMeter == null || _lockGenesisInfo)
|
||||
return;
|
||||
|
||||
UpdateContentControl(lblOrderNumberValue,
|
||||
@@ -719,6 +730,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
UpdateContentControl(lblMeterSizeValue,
|
||||
!string.IsNullOrEmpty(genesisMeter.MeterSize) ? genesisMeter.MeterSize : "?");
|
||||
|
||||
UpdateContentControl(lblMeterLengthValue,
|
||||
!string.IsNullOrEmpty(genesisMeter.MeterLength) ? genesisMeter.MeterLength + " mm": "?");
|
||||
|
||||
UpdateContentControl(lblLutValue,
|
||||
!string.IsNullOrEmpty(genesisMeter.LutCrc) ? genesisMeter.LutCrc : "?");
|
||||
|
||||
@@ -798,6 +812,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
|
||||
_startTime = DateTimeOffset.UtcNow;
|
||||
_timer?.Start();
|
||||
// Avoid display of genesis info before the detect new meter has been executed
|
||||
_lockGenesisInfo = true;
|
||||
|
||||
// remove last userControl
|
||||
dpSubProcess.Children.Clear();
|
||||
@@ -809,6 +825,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
UpdateContentControl(lblRadioAddressText, "");
|
||||
UpdateContentControl(lblFwValue, "?");
|
||||
UpdateContentControl(lblMeterSizeValue, "?");
|
||||
UpdateContentControl(lblMeterLengthValue, "?");
|
||||
UpdateContentControl(lblLutValue, "?");
|
||||
UpdateContentControl(lblSerialNumberValue, "?");
|
||||
UpdateContentControl(lblRegionValue, "?");
|
||||
@@ -835,6 +852,9 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
/// <remarks date="2025-Apr-10" author="Thomas Wiedebusch">
|
||||
/// - Reduced printout.
|
||||
/// </remarks>
|
||||
/// <remarks date="2025-Jun-17" author="Thomas Wiedebusch">
|
||||
/// - Base logging path taken from NLogHelper as log-path setting made in GTB.
|
||||
/// </remarks>
|
||||
private void CreateFile(String headerInfo, Boolean shortReport = false, Boolean printReport = false)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
@@ -853,50 +873,64 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
sb.AppendLine($"{Properties.Resources.StrLblOperatorNameText}: {Software.UserName}");
|
||||
sb.AppendLine("------------------------------------------------------------------------");
|
||||
|
||||
//TODO THW take the log path from setup (done with GTB)
|
||||
var loggingPath = $"C:\\GenesisLog\\{DateTime.Now:yyyy-MM-dd}\\ProductionUiCordonel\\";
|
||||
var fileName = $"{loggingPath}{DateTime.Now.ToString("yyyyMMddHHmmss")}_ExtendedReport_{genesisMeter.PcbId}.txt";
|
||||
|
||||
// Copy the header to the compressed string builder
|
||||
var compressedSb = new StringBuilder();
|
||||
if (shortReport)
|
||||
try
|
||||
{
|
||||
compressedSb.Append(sb);
|
||||
var path = NLogHelper.GetApplicationDataPath();
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
path = NLogHelper.GetCurrentApplicationFolder();
|
||||
}
|
||||
var a = XElement.Load(path);
|
||||
var baseLoggingPath = a.Elements().First(s => s.Name.LocalName == "variable").Attributes().First(s => s.Value == "BasePath").NextAttribute.Value;
|
||||
|
||||
var loggingPath = $"{baseLoggingPath}\\{DateTime.Now:yyyy-MM-dd}\\ProductionUiCordonel\\";
|
||||
var fileName = $"{loggingPath}{DateTime.Now.ToString("yyyyMMddHHmmss")}_ExtendedReport_{genesisMeter.PcbId}.txt";
|
||||
|
||||
// Copy the header to the compressed string builder
|
||||
var compressedSb = new StringBuilder();
|
||||
if (shortReport)
|
||||
{
|
||||
compressedSb.Append(sb);
|
||||
}
|
||||
|
||||
var rtbText = new TextRange(
|
||||
rtbLog.Document.ContentStart,
|
||||
rtbLog.Document.ContentEnd
|
||||
);
|
||||
sb.Append($"{rtbText.Text}");
|
||||
// Write the complete report to the file
|
||||
File.WriteAllText(fileName, sb.ToString());
|
||||
|
||||
// Reduce sb content to compress it for printout
|
||||
if (shortReport)
|
||||
{
|
||||
fileName = $"{loggingPath}{DateTime.Now.ToString("yyyyMMddHHmmss")}" +
|
||||
$"_ShortReport_{genesisMeter.PcbId}.txt";
|
||||
var sr = new StringReader(rtbText.Text);
|
||||
var srLine = sr.ReadLine();
|
||||
while (srLine != null)
|
||||
{
|
||||
if (srLine.Contains(Properties.Resources.StrProcessStateError) ||
|
||||
srLine.Contains(Properties.Resources.StrProcessStateDone) ||
|
||||
srLine.Contains(Properties.Resources.StrProcessStateWarning) ||
|
||||
srLine.Contains(Properties.Resources.StrProcessStateSkipped) ||
|
||||
srLine.Contains(Properties.Resources.StrWarningMsgSpecialRequirementActive))
|
||||
compressedSb.AppendLine(srLine);
|
||||
srLine = sr.ReadLine();
|
||||
}
|
||||
|
||||
// Returns the compressed file for error report printout
|
||||
File.WriteAllText(fileName, compressedSb.ToString());
|
||||
if (printReport)
|
||||
{
|
||||
Process.Start(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var rtbText = new TextRange(
|
||||
rtbLog.Document.ContentStart,
|
||||
rtbLog.Document.ContentEnd
|
||||
);
|
||||
sb.Append($"{rtbText.Text}");
|
||||
// Write the complete report to the file
|
||||
File.WriteAllText(fileName, sb.ToString());
|
||||
|
||||
// Reduce sb content to compress it for printout
|
||||
if (shortReport)
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
fileName = $"{loggingPath}{DateTime.Now.ToString("yyyyMMddHHmmss")}" +
|
||||
$"_ShortReport_{genesisMeter.PcbId}.txt";
|
||||
var sr = new StringReader(rtbText.Text);
|
||||
var srLine = sr.ReadLine();
|
||||
while (srLine != null)
|
||||
{
|
||||
if (srLine.Contains(Properties.Resources.StrProcessStateError) ||
|
||||
srLine.Contains(Properties.Resources.StrProcessStateDone) ||
|
||||
srLine.Contains(Properties.Resources.StrProcessStateWarning) ||
|
||||
srLine.Contains(Properties.Resources.StrProcessStateSkipped) ||
|
||||
srLine.Contains(Properties.Resources.StrWarningMsgSpecialRequirementActive))
|
||||
compressedSb.AppendLine(srLine);
|
||||
srLine = sr.ReadLine();
|
||||
}
|
||||
|
||||
// Returns the compressed file for error report printout
|
||||
File.WriteAllText(fileName, compressedSb.ToString());
|
||||
if (printReport)
|
||||
{
|
||||
Process.Start(fileName);
|
||||
}
|
||||
Console.WriteLine(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -962,7 +996,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Console.WriteLine(exception);
|
||||
Console.WriteLine(exception.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
@@ -519,6 +519,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Cordonel length is unknown.
|
||||
/// </summary>
|
||||
internal static string StrErrorMsgMeterLengthUnknown {
|
||||
get {
|
||||
return ResourceManager.GetString("StrErrorMsgMeterLengthUnknown", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Communication port is in use or not present. The software is going to exit!.
|
||||
/// </summary>
|
||||
@@ -672,6 +681,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Missing radio signal levels from Kitron!.
|
||||
/// </summary>
|
||||
internal static string StrErrorMsgRadioSignalLevels {
|
||||
get {
|
||||
return ResourceManager.GetString("StrErrorMsgRadioSignalLevels", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ERROR: Read failed.
|
||||
/// </summary>
|
||||
@@ -1050,6 +1068,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Meter Length.
|
||||
/// </summary>
|
||||
internal static string StrLblMeterLengthTxt {
|
||||
get {
|
||||
return ResourceManager.GetString("StrLblMeterLengthTxt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Meter Size.
|
||||
/// </summary>
|
||||
@@ -1095,6 +1122,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Pressure Sensor Assembled.
|
||||
/// </summary>
|
||||
internal static string StrLblPressureSensorAssembledTxt {
|
||||
get {
|
||||
return ResourceManager.GetString("StrLblPressureSensorAssembledTxt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to RadioAddress.
|
||||
/// </summary>
|
||||
@@ -1113,6 +1149,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Radio Frequency.
|
||||
/// </summary>
|
||||
internal static string StrLblRadioFrequencyTxt {
|
||||
get {
|
||||
return ResourceManager.GetString("StrLblRadioFrequencyTxt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to SerialNumber.
|
||||
/// </summary>
|
||||
@@ -1941,6 +1986,15 @@ namespace Xylem.Common.Production.ProductionUiCordonel.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Success: Cordonel radio signal levels successfully loaded.
|
||||
/// </summary>
|
||||
internal static string StrSuccessMsgRadioSignalLevels {
|
||||
get {
|
||||
return ResourceManager.GetString("StrSuccessMsgRadioSignalLevels", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Success: Successfully read.
|
||||
/// </summary>
|
||||
|
||||
@@ -366,6 +366,9 @@
|
||||
</data>
|
||||
<data name="StrErrorMsgLifeTimeCalculation" xml:space="preserve">
|
||||
<value>FEHLER: Restlaufzeitberechnung fehlgeschlagen</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgMeterLengthUnknown" xml:space="preserve">
|
||||
<value>FEHLER: Cordonel Baulänge ist unbekannt</value>
|
||||
</data>
|
||||
<data name="StrStateFinalTestFailed" xml:space="preserve">
|
||||
<value>FEHLER: Versandfertigmachen fehlgeschlagen</value>
|
||||
@@ -400,6 +403,12 @@
|
||||
<data name="StrLblMeterSizeTxt" xml:space="preserve">
|
||||
<value>Baugröße</value>
|
||||
</data>
|
||||
<data name="StrLblMeterLengthTxt" xml:space="preserve">
|
||||
<value>Baulänge</value>
|
||||
</data>
|
||||
<data name="StrLblPressureSensorAssembledTxt" xml:space="preserve">
|
||||
<value>Drucksensor eingebaut</value>
|
||||
</data>
|
||||
<data name="StrLblKitronProductionDate" xml:space="preserve">
|
||||
<value>Kitron Produktionsdatum</value>
|
||||
</data>
|
||||
@@ -412,6 +421,9 @@
|
||||
<data name="StrLblMonths" xml:space="preserve">
|
||||
<value>Monate</value>
|
||||
</data>
|
||||
<data name="StrLblRadioFrequencyTxt" xml:space="preserve">
|
||||
<value>Funkfrequenz</value>
|
||||
</data>
|
||||
<data name="StrLblRadioAddressTxt" xml:space="preserve">
|
||||
<value>Funkadresse</value>
|
||||
</data>
|
||||
@@ -619,6 +631,9 @@
|
||||
<data name="StrErrorMsgRequirementMeterSize" xml:space="preserve">
|
||||
<value>FEHLER: Falsche Nennweite</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgRadioSignalLevels" xml:space="preserve">
|
||||
<value>FEHLER: Fehlende Funksignalpegel von Kitron!</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgRequirementProductionOrder" xml:space="preserve">
|
||||
<value>FEHLER: Falsche Produktionsnummer</value>
|
||||
</data>
|
||||
@@ -679,6 +694,9 @@
|
||||
<data name="StrSuccessMsgRequirementMaximumStorageMonth" xml:space="preserve">
|
||||
<value>Erfolg: Maximale Lagerzeit eingehalten</value>
|
||||
</data>
|
||||
<data name="StrSuccessMsgRadioSignalLevels" xml:space="preserve">
|
||||
<value>Erfolg: Cordonel Funksignalpegel erfolgreich geladen</value>
|
||||
</data>
|
||||
<data name="StrSuccessMsgRequirementMeterSize" xml:space="preserve">
|
||||
<value>Erfolg: Nennweite erfolgreich validiert</value>
|
||||
</data>
|
||||
|
||||
@@ -364,9 +364,12 @@
|
||||
<data name="StrErrorMsgRemainingLifeTime" xml:space="preserve">
|
||||
<value>ERROR: Remaining lifetime too short</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgLifeTimeCalculation" xml:space="preserve">
|
||||
<data name="StrErrorMsgLifeTimeCalculation" xml:space="preserve">
|
||||
<value>ERROR: Lifetime calculation failed</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgMeterLengthUnknown" xml:space="preserve">
|
||||
<value>ERROR: Cordonel length is unknown</value>
|
||||
</data>
|
||||
<data name="StrStateFinalTestFailed" xml:space="preserve">
|
||||
<value>ERROR: Preparation for shipping failed</value>
|
||||
</data>
|
||||
@@ -400,6 +403,12 @@
|
||||
<data name="StrLblMeterSizeTxt" xml:space="preserve">
|
||||
<value>Meter Size</value>
|
||||
</data>
|
||||
<data name="StrLblMeterLengthTxt" xml:space="preserve">
|
||||
<value>Meter Length</value>
|
||||
</data>
|
||||
<data name="StrLblPressureSensorAssembledTxt" xml:space="preserve">
|
||||
<value>Pressure Sensor Assembled</value>
|
||||
</data>
|
||||
<data name="StrLblKitronProductionDate" xml:space="preserve">
|
||||
<value>Kitron production date</value>
|
||||
</data>
|
||||
@@ -412,6 +421,9 @@
|
||||
<data name="StrLblMonths" xml:space="preserve">
|
||||
<value>Months</value>
|
||||
</data>
|
||||
<data name="StrLblRadioFrequencyTxt" xml:space="preserve">
|
||||
<value>Radio Frequency</value>
|
||||
</data>
|
||||
<data name="StrLblRadioAddressTxt" xml:space="preserve">
|
||||
<value>RadioAddress</value>
|
||||
</data>
|
||||
@@ -616,9 +628,12 @@
|
||||
<data name="StrErrorMsgRequirementMaximumStorageMonthUnknown" xml:space="preserve">
|
||||
<value>ERROR: Maximum Storage Month or battery assembly date unknown</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgRequirementMeterSize" xml:space="preserve">
|
||||
<data name="StrErrorMsgRequirementMeterSize" xml:space="preserve">
|
||||
<value>ERROR: Requirement Meter Size does not match</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgRadioSignalLevels" xml:space="preserve">
|
||||
<value>ERROR: Missing radio signal levels from Kitron!</value>
|
||||
</data>
|
||||
<data name="StrErrorMsgRequirementProductionOrder" xml:space="preserve">
|
||||
<value>ERROR: Requirement Production Order does not match</value>
|
||||
</data>
|
||||
@@ -679,6 +694,9 @@
|
||||
<data name="StrSuccessMsgRequirementMaximumStorageMonth" xml:space="preserve">
|
||||
<value>Success: Requirement for maximum storage time kept</value>
|
||||
</data>
|
||||
<data name="StrSuccessMsgRadioSignalLevels" xml:space="preserve">
|
||||
<value>Success: Cordonel radio signal levels successfully loaded</value>
|
||||
</data>
|
||||
<data name="StrSuccessMsgRequirementMeterSize" xml:space="preserve">
|
||||
<value>Success: Requirement and Cordonel meter size successfully validated</value>
|
||||
</data>
|
||||
|
||||
Reference in New Issue
Block a user