ProductionUiCordonel: - ASBL: - meter size from order

This commit is contained in:
Thomas Wiedebusch 2025-09-22 17:11:03 +02:00
parent 0c86c58f4e
commit 5076efd960
20 changed files with 127 additions and 117 deletions

View File

@ -13,4 +13,4 @@ using System.Reflection;
//
//[assembly: AssemblyVersion("1.2.*.0")]
[assembly: AssemblyVersion("2.8.5.*")]
[assembly: AssemblyVersion("2.8.6.*")]

View File

@ -34,6 +34,9 @@ namespace Xylem.Common.CommonCore.Configuration
private static readonly String DefaultGetOrderOverviewServiceUrl =
$"{ServerDns}/MeterProcessState/api/FinalCheck/GetOrderOverview?ProductionOrderNumber=";
private static readonly String DefaultGetOrderDetailsServiceUrl =
$"{ServerDns}/MeterProcessState/api/FinalCheck/GetOrderDetails?ProductionOrderNumber=";
private static readonly String DefaultDownloadFilesPartsServiceUrl =
$"{ServerDns}/MeterProcessState/api/FileUpToDate/GetFileParts?ParentFileId=";
@ -260,6 +263,19 @@ namespace Xylem.Common.CommonCore.Configuration
DefaultGetOrderOverviewServiceUrl;
}
/// <summary>
/// Get Cordonel order details to check for order dependent requirements like
/// - MeterSize,
/// - FrequencyIndicator,
/// - PressurePresent.
/// </summary>
/// <returns></returns>
public static String GetOrderDetailsServiceUrl()
{
return ConfigurationManager.AppSettings["GetOrderDetailsServiceUrl"] ??
DefaultGetOrderDetailsServiceUrl;
}
/// <summary>
/// List all Cordonel FW packages.
/// </summary>

View File

@ -18,6 +18,7 @@ using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisStatus;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
using Xylem.Common.Logic.SoftwareAccessHelper;
using static Ui.ProductionControls.ctlPictureProgressBar;

View File

@ -225,7 +225,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
/// <inheritdoc />
public String MeterSize
{
protected set; get;
set; get;
}
/// <inheritdoc />
@ -265,7 +265,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
/// <inheritdoc />
public Boolean PressureSensorAssembled
{
protected set; get;
set; get;
}
/// <summary>

View File

@ -116,10 +116,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
/// <summary>
/// This is the meter size.
/// </summary>
String MeterSize
{
get;
}
String MeterSize { get; set; }
/// <summary>
/// Length of the meter.
@ -129,10 +126,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
/// <summary>
/// Pressure sensor assembled to meter.
/// </summary>
Boolean PressureSensorAssembled
{
get;
}
Boolean PressureSensorAssembled { get; set; }
/// <summary>
/// Region (EMEA, NA or China).

View File

@ -104,7 +104,6 @@
<Compile Include="Cordonel\CalibrationResult.cs" />
<Compile Include="Cordonel\CordonelAppVersion.cs" />
<Compile Include="Cordonel\MarriagePossibleEnum.cs" />
<Compile Include="Cordonel\PickingCompareItem.cs" />
<Compile Include="Cordonel\RegisterHistory.cs" />
<Compile Include="Cordonel\SkipProcess.cs" />
<Compile Include="Files\Fw\ClusteredFile.cs" />

View File

@ -1,10 +1,11 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Xylem.Common.CommonCore.Configuration;
using Xylem.Common.CommonCore.Consts;
using Xylem.Common.Logic.SoftwareAccessHelper;
namespace Xylem.Common.Logic.ProductionOrderCore.OrderData
{
/// <summary>
@ -90,6 +91,46 @@ namespace Xylem.Common.Logic.ProductionOrderCore.OrderData
}
}
/// <summary>
/// Get Cordonel order details for production status:
/// - MeterSize,
/// - FrequencyIndicator,
/// - PressurePresent.
/// </summary>
/// <param name="productionOrderNumber"></param>
/// <param name="pcbId"></param>
/// <param name="orderDetails"></param>
/// <returns>true if successful</returns>
/// <remarks date="2025-Sep-22" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
public static Boolean GetOrderDetails(Int64 productionOrderNumber, String pcbId,
out PickingCompareItem orderDetails)
{
try
{
var url = ServiceUrls.GetOrderOverviewServiceUrl();
url += $@"{productionOrderNumber}&CheckPcbId={pcbId}";
var requestResponse = LocalWebRequest.GetRequest(url, hugeTimeoutDbRequest);
if (string.IsNullOrEmpty(requestResponse))
{
orderDetails = new PickingCompareItem(0, 0, false, null);
return false;
}
var o = JsonConvert.DeserializeObject<OrderOverViewCordonelWithPicking>(requestResponse);
orderDetails = new PickingCompareItem(o.PickingCompareItem.MeterSize, o.PickingCompareItem.FrequencyIndicator,
o.PickingCompareItem.PressurePresent, null);
return orderDetails != null;
}
catch (Exception)
{
orderDetails = new PickingCompareItem(0, 0, false, null);
return false;
}
}
/// <summary>
/// Get Cordonel overview of production status:
/// - Order no.

View File

@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
namespace Logic.ProductionToProductMapper.Cordonel
namespace Xylem.Common.Logic.ProductionOrderCore.OrderData
{
/// <summary>
/// Picking check and process state.

View File

@ -133,6 +133,7 @@
<Compile Include="OrderData\OrderDetailsDb.cs" />
<Compile Include="OrderData\MeterSize.cs" />
<Compile Include="OrderData\MeterSizeConverter.cs" />
<Compile Include="OrderData\PickingCompareItem.cs" />
<Compile Include="OrderData\RegionConverter.cs" />
<Compile Include="OrderData\OrderOverViewCordonel.cs" />
<Compile Include="OrderData\OrderRadioParameter.cs" />

View File

@ -34,7 +34,7 @@
<appSettings>
<add key="Mode" value="1" /> <!--1 = EOL ; 2 = Picking-->
<add key="Mode" value="2" /> <!--1 = EOL ; 2 = Picking-->
<!--add key="SirtComport433" value="14" /--> <!--Thomas 14; Roland ; Stoyan ; VFM1 9; VFM4 7-->
<!--add key="SirtComport868" value="15" /--> <!--Thomas 15; Roland ; Stoyan ; VFM1 10; VFM4 8-->
<!--add key="SirtBoxNr" value="2" /--> <!--Thomas 2; Roland 2; Stoyan 2; VFM1 1; VFM4 3-->

View File

@ -1,19 +0,0 @@
using System;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolProcesses
{
public class DetectCordonel : BaseDetectCordonel
{
/// <inheritdoc />
public DetectCordonel(String name) : base(name)
{
}
/// <inheritdoc/>
protected override Boolean ValidateProcessAndPublishDataToGui()
{
return true;
}
}
}

View File

@ -123,6 +123,14 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
var stateContainer = new List<ProcessStateStruct>
{
#region ----------------------------------- GENERIC-STATES---------------------------------------------
new ProcessStateStruct(
productionProcess: new DetectCordonel(Resources.StrStateDetectCordonel),
processState: ProcessState.DetectCordonel,
processInfo: Resources.StrStateDetectCordonel,
productionProcessNo: 0,
// CheckNewMeter will exit with repeated detect or connect
nextStateOnSuccess: ProcessState.CheckNewMeter),
new ProcessStateStruct(
productionProcess: new ConnectCordonel(Resources.StrStateConnectCordonel),
processState: ProcessState.ConnectCordonel,
@ -153,14 +161,6 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.EolPr
#endregion -------------------------------- GENERIC-STATES --------------------------------------------
#region ----------------------------------- EOL-STATES ------------------------------------------------
new ProcessStateStruct(
productionProcess: new DetectCordonel(Resources.StrStateDetectCordonel),
processState: ProcessState.DetectCordonel,
processInfo: Resources.StrStateDetectCordonel,
productionProcessNo: 0,
// CheckNewMeter will exit with repeated detect or connect
nextStateOnSuccess: ProcessState.CheckNewMeter),
// Precondition: - A new meter has to be detected
// Create (hidden) EOL progress for sentinel.
new ProcessStateStruct(

View File

@ -18,7 +18,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
/// Connect initially to Cordonel.
/// Checks the ability to login as it gets the password from DB.
/// Precondition:
/// - The <see cref="BaseDetectCordonel"/> process has to be completed as the PcbId is needed.
/// - The <see cref="DetectCordonel"/> process has to be completed as the PcbId is needed.
/// </summary>
/// <returns></returns>
/// <remarks date="2023-Feb-14" author="Thomas Wiedebusch">

View File

@ -9,13 +9,13 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
/// Production process detects the serial number of the Cordonel.
/// This is the indication, that a Cordonel is connected to the hardware interface.
/// </summary>
public abstract class BaseDetectCordonel : BaseProductionProcess
public class DetectCordonel : BaseProductionProcess
{
/// <summary>
/// Ctor
/// Setup of name and single process state
/// </summary>
protected BaseDetectCordonel(String name) : base( name)
public DetectCordonel(String name) : base( name)
{
}
@ -43,17 +43,12 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
// read the PcbId to validate Cordonel is attached
var retVal = !string.IsNullOrEmpty(Meter.GetPcbId());
if (retVal && ValidateProcessAndPublishDataToGui())
if (retVal)
return StatusReturn.Okay;
ErrorMsgDispatcher(Resources.StrErrorMsgCordonelDetection);
return StatusReturn.Failed;
}
/// <summary>
/// Application differences in check result
/// </summary>
/// <returns></returns>
protected abstract Boolean ValidateProcessAndPublishDataToGui();
}
}

View File

@ -27,7 +27,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Gener
/// <summary>
/// Get programming parameters for Cordonel including VAKO and CSD
/// Precondition:
/// - The <see cref="BaseDetectCordonel"/> process has to be completed as the PcbId is needed.
/// - The <see cref="DetectCordonel"/> process has to be completed as the PcbId is needed.
/// </summary>
/// <returns></returns>
/// <remarks date="2020-Mai-15" author="Roland Drahbesh">

View File

@ -1,7 +1,6 @@
using System;
using Xylem.Common.CommonCore.Consts;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Enum;
using Xylem.Common.Production.ProductionUiCordonel.Properties;
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.PickingProcesses
{
@ -27,7 +26,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
/// Precondition: - Detection of Cordonel has to be finished.
/// </summary>
/// <returns></returns>
/// <remarks date="2025-Sep-16" author="Thomas Wiedebusch">
/// <remarks date="2025-Sep-22" author="Thomas Wiedebusch">
/// - Initial
/// </remarks>
public override StatusReturn ExecuteProcess()
@ -39,18 +38,25 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
SignalRunningState();
// TODO THW check order number and pcbid
/* Order/GetCordonelMapping?PcbId=212120036
"PcbId": "212120036",
"CordonelAssignedPicking_FertigungsAuftragsNr": 3184020,
"CordonelPressureTest_FertigungsAuftragsNr": 3184020,
"MapPcbIdToSerialNumber_SerialNumber": 22718451*/
var retVal = !string.IsNullOrEmpty(Meter.GetPcbId());
if (retVal) return StatusReturn.Okay;
// Check mapping information
if (!OrderDetailsDb.GetCordonelMapping(Meter.PcbId, out var cordonelMapping))
{
return StatusReturn.Failed;
}
// Reserve picking for this device
ErrorMsgDispatcher(Resources.StrErrorMsgCordonelDetection);
return StatusReturn.Failed;
// Get detailed order information to set e.g. the correct meter size needed for LUT
// installation
if (!OrderDetailsDb.GetOrderDetails(Meter.OrderNumber, Meter.PcbId, out var orderDetails))
{
return StatusReturn.Failed;
}
// Meter has to be connected in advance being able to overwrite the meter size
Meter.MeterSize = MeterSizeConverter.ConvertMeterSizeEnumToSizeName((MeterSize)orderDetails.MeterSize);
Meter.PressureSensorAssembled = orderDetails.PressurePresent;
return StatusReturn.Okay;
}
}
}

View File

@ -1,27 +0,0 @@
using System;
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
using Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.GenericProcesses;
namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.PickingProcesses
{
public class DetectCordonel : BaseDetectCordonel
{
/// <inheritdoc />
public DetectCordonel(String name) : base(name)
{
}
/// <inheritdoc/>
protected override Boolean ValidateProcessAndPublishDataToGui()
{
// Check mapping information
if (!OrderDetailsDb.GetCordonelMapping(Meter.PcbId, out var cordonelMapping))
{
return false;
}
// Reserve picking for this device
return true;
}
}
}

View File

@ -45,6 +45,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
try
{
var url = ServiceUrls.GetLutUrl();
// ATTENTION: Meter.MeterSize has to be preset from order.MeterSize as this is forced by order.
// If not doing so, the wrong LUT will be loaded!
url += $"?Metersize={(Int32)MeterSizeConverter.ConvertMeterSizeNameToEnum(Meter.MeterSize)}" +
$"&ForProd=true&Region={Meter.Region}";
var requestResponse = LocalWebRequest.GetRequest(url, 30000);

View File

@ -32,7 +32,7 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
/// INSTRUCTION FOR PREPARATION:
/// -----------------------------
/// STEP 1: Define some states for your processes <see cref="ProcessState"/>
/// STEP 2: Implement your processes like <see cref="BaseDetectCordonel"/>
/// STEP 2: Implement your processes like <see cref="DetectCordonel"/>
/// STEP 3: Register and chain your states here
///
///
@ -104,13 +104,22 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
var stateContainer = new List<ProcessStateStruct>
{
#region ----------------------------------- GENERIC-STATES---------------------------------------------
// Detection of Cordonel has to be completed before assigning next state, so leave to automatic
// to change the state after successfully execution. The detection is the base for all others.
new ProcessStateStruct(
productionProcess: new DetectCordonel(Resources.StrStateDetectCordonel),
processState: ProcessState.DetectCordonel,
processInfo: Resources.StrStateDetectCordonel,
productionProcessNo: 1,
nextStateOnSuccess: ProcessState.CheckNewMeter),
// Precondition: - The detection process has to be completed as the PcbId is needed.
new ProcessStateStruct(
productionProcess: new ConnectCordonel(Resources.StrStateConnectCordonel),
processState: ProcessState.ConnectCordonel,
processInfo: Resources.StrStateConnectCordonel,
productionProcessNo: 3,
nextStateOnSuccess: ProcessState.GetProgrammingParameters),
productionProcessNo: 2,
nextStateOnSuccess: ProcessState.CheckCordonelMapping),
// 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:
@ -120,9 +129,8 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
processState: ProcessState.GetProgrammingParameters,
processInfo: Resources.StrStateGetProgrammingParameters,
productionProcessNo: 4,
nextStateOnSuccess: ProcessState.InstallLut,
// Wait before starting this process until this process has been successfully completed
waitForSingleProcess: ProcessState.ConnectCordonel),
nextStateOnSuccess: ProcessState.InstallLut),
#endregion -------------------------------- GENERIC-STATES --------------------------------------------
#region ----------------------------------- PICKING-STATES --------------------------------------------
@ -134,23 +142,19 @@ namespace Xylem.Common.Production.ProductionUiCordonel.ProductionProcesses.Picki
productionProcessNo: 0,
nextStateOnSuccess: ProcessState.DetectCordonel),
// Detection of Cordonel has to be completed before assigning next state, so leave to automatic
// to change the state after successfully execution. The detection is the base for all others.
new ProcessStateStruct(
productionProcess: new DetectCordonel(Resources.StrStateDetectCordonel),
processState: ProcessState.DetectCordonel,
processInfo: Resources.StrStateDetectCordonel,
productionProcessNo: 1,
nextStateOnSuccess: ProcessState.CheckCordonelMapping),
// Detection of Cordonel has to be completed before assigning next state, so leave to automatic
// to change the state after successfully execution. The detection is the base for all others.
// Connection of Cordonel has to be completed before assigning next state, so leave to automatic
// to change the state after successfully execution. Meter has to be connected in advance being able to
// overwrite the meter size based on the order details. The initial meter size in connect Cordonel will
// be set by reading the Cordonel out. But a new meter size may be forced by the order needed to change
// it and install the correct LUT
new ProcessStateStruct(
productionProcess: new CheckCordonelMapping(Resources.StrStateCheckCordonelMapping),
processState: ProcessState.CheckCordonelMapping,
processInfo: Resources.StrStateCheckCordonelMapping,
productionProcessNo: 2,
nextStateOnSuccess: ProcessState.CheckNewMeter),
productionProcessNo: 3,
nextStateOnSuccess: ProcessState.GetProgrammingParameters,
// Wait before starting this process until this process has been successfully completed
waitForSingleProcess: ProcessState.ConnectCordonel),
// Connection of Cordonel has to be completed so leave to automatic
new ProcessStateStruct(

View File

@ -168,7 +168,6 @@
<Compile Include="Model\EOLHandler.cs" />
<Compile Include="ProductionProcesses\Enum\GuiItem.cs" />
<Compile Include="ProductionProcesses\EolProcesses\CreateEolProgress.cs" />
<Compile Include="ProductionProcesses\EolProcesses\DetectCordonel.cs" />
<Compile Include="ProductionProcesses\EolProcesses\VisualInspection.cs" />
<Compile Include="ProductionProcesses\EventArgs\GuiMessageArgs.cs" />
<Compile Include="ProductionProcesses\GenericModules\GenericChecks.cs" />
@ -178,7 +177,7 @@
<Compile Include="ProductionProcesses\GenericProcesses\ErrorHandler.cs" />
<Compile Include="ProductionProcesses\EolProcesses\ExecStoreConfiguration.cs" />
<Compile Include="ProductionProcesses\GenericProcesses\GetSerialNumberAndRadioAddress.cs" />
<Compile Include="ProductionProcesses\GenericProcesses\BaseDetectCordonel.cs" />
<Compile Include="ProductionProcesses\GenericProcesses\DetectCordonel.cs" />
<Compile Include="ProductionProcesses\EolProcesses\ExecRebootCordonel.cs" />
<Compile Include="ProductionProcesses\EolProcesses\PrepareShipping.cs" />
<Compile Include="ProductionProcesses\Enum\DialogResult.cs" />
@ -186,7 +185,6 @@
<Compile Include="ProductionProcesses\Enum\ProcessState.cs" />
<Compile Include="ProductionProcesses\EventArgs\SingleProcessStateArgs.cs" />
<Compile Include="ProductionProcesses\EolProcesses\EolProcessStatesDef.cs" />
<Compile Include="ProductionProcesses\PickingProcesses\DetectCordonel.cs" />
<Compile Include="ProductionProcesses\PickingProcesses\CheckOrderNumber.cs" />
<Compile Include="ProductionProcesses\PickingProcesses\CheckProductionState.cs" />
<Compile Include="ProductionProcesses\PickingProcesses\CheckCordonelMapping.cs" />