<Feat>: Add standalone Genesis preadjustment activities, fix configuration control and increase revision to 3.9.3146.101
Cause: - GenesisCommunication did not expose GCI preadjustment phases as selectable test activities. - Meter size and temperature inputs required by preadjustment could not be configured. - The configuration control incorrectly expected the iPerlCommunication configuration type. - Preadjustment results were not propagated to TBF test and meter results. Solution: 1. Added standalone preadjustment activities - Added Initialization, Detect, Preparation, Amplitude Test, Temperature Calibration, Push Temperature, Offset Test and Completion. - Each phase can be selected and executed independently. 2. Added preadjustment parameters - Added configurable meter size and temperature. - Added validation and supported meter-size selection. 3. Added batch preadjustment execution - Resolves enabled Genesis register readers and their slots. - Verifies that all readers use the same GCI Bridge instance. - Dispatches the selected activity through the corresponding GCI Bridge API. 4. Added result processing - Stores execution time and completion status. - Updates test and meter results according to the GCI response. 5. Fixed the configuration control - Corrected TestMethodCfgCtrl to accept the GenesisCommunication TestMethodCfg type. 6. Increased revision - Updated revision to 3.9.3146.101.
This commit is contained in:
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("3.9.3146.0")]
|
||||
[assembly: AssemblyFileVersion("3.9.3146.0")]
|
||||
[assembly: AssemblyVersion("3.9.3146.101")]
|
||||
[assembly: AssemblyFileVersion("3.9.3146.101")]
|
||||
|
||||
@@ -5,16 +5,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Common;
|
||||
using CordonelPreadjustmentUi;
|
||||
using CordonelPreadjustmentUi.Processes.Itinerary;
|
||||
using Config.Entities;
|
||||
using GenesisCordonelInterface.API;
|
||||
using log4net;
|
||||
using RestClient;
|
||||
using Results.Entities;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.RegisterReaders.GenesisRegReader.implementations;
|
||||
using TBF.Rig.TestMethods.iPerlCommunication;
|
||||
using TBF.UiBridge;
|
||||
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
|
||||
using Xylem.Common.Ui.CordonelPreadjustmentUi;
|
||||
using GciBridgeType = TBF.Rig.BridgeComponents.GciBridge.GciBridge;
|
||||
using GciPublicModels = GenesisCordonelInterface.API.PublicModels;
|
||||
/// Point definition
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
@@ -28,6 +39,14 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
public const string Q2correctionCheckCmd = "Q2 correction check ";
|
||||
public const string IperlCheckCmd = "iPERL_check ";
|
||||
public const string SimulateCmd = "simulate ";
|
||||
public const string PreadjustmentInitializationStr = "Preadjustment Initialization";
|
||||
public const string PreadjustmentDetectStr = "Preadjustment Detect";
|
||||
public const string PreadjustmentPreparationStr = "Preadjustment Preparation";
|
||||
public const string PreadjustmentAmplitudeTestStr = "Preadjustment Amplitude Test";
|
||||
public const string PreadjustmentTemperatureCalibrationStr = "Preadjustment Temperature Calibration";
|
||||
public const string PreadjustmentPushTemperatureStr = "Preadjustment Push Temperature";
|
||||
public const string PreadjustmentOffsetTestStr = "Preadjustment Offset Test";
|
||||
public const string PreadjustmentCompletionStr = "Preadjustment Completion";
|
||||
|
||||
|
||||
System.Windows.Forms.Form modelessDlg;
|
||||
@@ -71,6 +90,12 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
|
||||
processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, false);
|
||||
|
||||
iPerlCommunicationParams genesisTestParams = testParams as iPerlCommunicationParams;
|
||||
if (genesisTestParams != null && IsPreadjustmentActivity(genesisTestParams.Activity))
|
||||
{
|
||||
return ExecutePreadjustment(test, method, genesisTestParams);
|
||||
}
|
||||
|
||||
string cmd;
|
||||
if (testParams.Activity.ToLower().Equals(cmd = GenesisCommunicationForm.GetDefaultQ2CorrectionsStr.ToLower()))
|
||||
{
|
||||
@@ -410,6 +435,199 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
return new List<Event> { Event.Done };
|
||||
}
|
||||
|
||||
private static bool IsPreadjustmentActivity(string activity)
|
||||
{
|
||||
return string.Equals(activity, PreadjustmentInitializationStr, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(activity, PreadjustmentDetectStr, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(activity, PreadjustmentPreparationStr, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(activity, PreadjustmentAmplitudeTestStr, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(activity, PreadjustmentTemperatureCalibrationStr, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(activity, PreadjustmentPushTemperatureStr, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(activity, PreadjustmentOffsetTestStr, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(activity, PreadjustmentCompletionStr, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private IList<Event> ExecutePreadjustment(Test test, TestMethod method, iPerlCommunicationParams testParams)
|
||||
{
|
||||
DateTime startTime = DateTime.Now;
|
||||
bool success = false;
|
||||
string response = string.Empty;
|
||||
List<KeyValuePair<int, GenesisSmartReader>> readers = new List<KeyValuePair<int, GenesisSmartReader>>();
|
||||
|
||||
TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 0, 30, 0, 30, 0, 0 });
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.JustStarted));
|
||||
Bridge.OnActivity(this, testParams.Activity);
|
||||
|
||||
try
|
||||
{
|
||||
readers = GetPreadjustmentReaders(test);
|
||||
GciBridgeType bridge = GetCommonGciBridge(readers);
|
||||
success = ExecutePreadjustmentActivity(bridge, readers, testParams, out response);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
response = ex.Message;
|
||||
log.Error(string.Format("{0} failed.", testParams.Activity), ex);
|
||||
}
|
||||
|
||||
UpdatePreadjustmentResult(test, method, readers, success, startTime);
|
||||
|
||||
if (success)
|
||||
log.InfoFormat("{0} finished successfully. {1}", testParams.Activity, response);
|
||||
else
|
||||
log.ErrorFormat("{0} failed. {1}", testParams.Activity, response);
|
||||
|
||||
Bridge.OnActivity(this, string.Format("{0}: {1}", testParams.Activity, response));
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, Progress.Completed));
|
||||
Bridge.OnTestCompleted(this, new TestCompletedEventArgs(test.Name, ProcessData.BatchRslts.GetTestRslt(test.Name, test.Part)));
|
||||
allResults.Info(TestResult2CsvLine(test.Name, test.Part));
|
||||
|
||||
return new List<Event> { Event.Done };
|
||||
}
|
||||
|
||||
private static List<KeyValuePair<int, GenesisSmartReader>> GetPreadjustmentReaders(Test test)
|
||||
{
|
||||
var metersPath = StateMachine.GetMetersPath(test);
|
||||
if (metersPath == null || metersPath.RegisterReaders == null)
|
||||
throw new InvalidOperationException("No register readers are configured for the test.");
|
||||
|
||||
var readers = new List<KeyValuePair<int, GenesisSmartReader>>();
|
||||
for (int meterPosition = 0; meterPosition < metersPath.RegisterReaders.Length; meterPosition++)
|
||||
{
|
||||
GenesisSmartReader reader = metersPath.RegisterReaders[meterPosition] as GenesisSmartReader;
|
||||
if (reader == null)
|
||||
continue;
|
||||
|
||||
if (meterPosition < ProcessData.BatchRslts.Batch.WaterMeters.Count && ProcessData.BatchRslts.Batch.WaterMeters[meterPosition] != null && ProcessData.BatchRslts.Batch.WaterMeters[meterPosition].Disabled)
|
||||
continue;
|
||||
|
||||
if (reader.GetSlotNr <= 0)
|
||||
throw new InvalidOperationException(string.Format("Genesis reader '{0}' has invalid slot number {1}.", reader.Name, reader.GetSlotNr));
|
||||
|
||||
readers.Add(new KeyValuePair<int, GenesisSmartReader>(meterPosition, reader));
|
||||
}
|
||||
|
||||
if (readers.Count == 0)
|
||||
throw new InvalidOperationException("No enabled Genesis register reader with a valid slot was found.");
|
||||
|
||||
if (readers.Select(item => item.Value.GetSlotNr).Distinct().Count() != readers.Count)
|
||||
throw new InvalidOperationException("More than one Genesis register reader uses the same GCI slot.");
|
||||
|
||||
return readers;
|
||||
}
|
||||
|
||||
private static GciBridgeType GetCommonGciBridge(IEnumerable<KeyValuePair<int, GenesisSmartReader>> readers)
|
||||
{
|
||||
GciBridgeType commonBridge = null;
|
||||
|
||||
foreach (KeyValuePair<int, GenesisSmartReader> item in readers)
|
||||
{
|
||||
GciBridgeType bridge = item.Value.CommInterfaceBridge;
|
||||
if (bridge == null)
|
||||
throw new InvalidOperationException(string.Format("Genesis reader '{0}' has no valid GCI Bridge configured.", item.Value.Name));
|
||||
|
||||
if (commonBridge != null && !ReferenceEquals(commonBridge, bridge))
|
||||
throw new InvalidOperationException("Enabled Genesis readers do not use the same GCI Bridge instance.");
|
||||
|
||||
commonBridge = bridge;
|
||||
}
|
||||
|
||||
return commonBridge;
|
||||
}
|
||||
|
||||
private static bool ExecutePreadjustmentActivity(GciBridgeType bridge, IList<KeyValuePair<int, GenesisSmartReader>> readers, iPerlCommunicationParams testParams, out string response)
|
||||
{
|
||||
if (string.Equals(testParams.Activity, PreadjustmentInitializationStr, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
MeterSize meterSize;
|
||||
if (!Enum.TryParse(testParams.MeterSize, true, out meterSize) || meterSize == MeterSize.NA)
|
||||
throw new InvalidOperationException(string.Format("Meter size '{0}' is not valid.", testParams.MeterSize));
|
||||
|
||||
var progress = new ProcessProgress
|
||||
{
|
||||
Setting = new PreAdjustmentSettingsContainer
|
||||
{
|
||||
TempOnly = false,
|
||||
Culture = new CultureInfo("en-US"),
|
||||
MeterSize = meterSize,
|
||||
NumberOfPaths = 3,
|
||||
OffsetTestSettlingTime = 0
|
||||
},
|
||||
IsAutomaticMode = true
|
||||
};
|
||||
|
||||
var meterControls = new List<MeterStateControl>();
|
||||
foreach (KeyValuePair<int, GenesisSmartReader> item in readers)
|
||||
{
|
||||
var meterControl = new MeterStateControl(item.Value.GetSlotNr);
|
||||
meterControl.SetChecked(true);
|
||||
meterControl.IsEnabled = true;
|
||||
meterControls.Add(meterControl);
|
||||
}
|
||||
|
||||
PublicModels.PreAdjustmentInitializationResult result = bridge.Preadjustment_Initialization(progress, meterControls);
|
||||
response = result.ToString();
|
||||
return result.Success;
|
||||
}
|
||||
|
||||
if (string.Equals(testParams.Activity, PreadjustmentDetectStr, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var selectedSlots = readers.Select(item => new GciPublicModels.MeterBatchDebugStatus { Slot = item.Value.GetSlotNr, Selected = true }).ToList();
|
||||
PublicModels.PreadjustmentDetectResult result = bridge.PreAdjustment_DetectDirect(selectedSlots, CancellationToken.None);
|
||||
response = result.ToString();
|
||||
return result.Success;
|
||||
}
|
||||
|
||||
if (string.Equals(testParams.Activity, PreadjustmentPushTemperatureStr, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Keep temperature delivery as an explicit sibling GCI API activity. A procedure can run it simultaneously with temperature calibration.
|
||||
bool pushed = bridge.PreAdjustment_PushTemperature(testParams.Temperature);
|
||||
response = pushed ? string.Format("Temperature {0} °C was accepted.", testParams.Temperature) : "GCI preadjustment was not initialized; temperature was not accepted.";
|
||||
return pushed;
|
||||
}
|
||||
|
||||
PublicModels.PreAdjustmentProcessResult processResult;
|
||||
if (string.Equals(testParams.Activity, PreadjustmentPreparationStr, StringComparison.OrdinalIgnoreCase))
|
||||
processResult = bridge.PreAdjustment_PreparationDirect();
|
||||
else if (string.Equals(testParams.Activity, PreadjustmentAmplitudeTestStr, StringComparison.OrdinalIgnoreCase))
|
||||
processResult = bridge.PreAdjustment_AmplitudeTestDirect();
|
||||
else if (string.Equals(testParams.Activity, PreadjustmentTemperatureCalibrationStr, StringComparison.OrdinalIgnoreCase))
|
||||
processResult = bridge.PreAdjustment_TemperatureCalibrationDirect();
|
||||
else if (string.Equals(testParams.Activity, PreadjustmentOffsetTestStr, StringComparison.OrdinalIgnoreCase))
|
||||
processResult = bridge.PreAdjustment_OffsetTestDirect();
|
||||
else if (string.Equals(testParams.Activity, PreadjustmentCompletionStr, StringComparison.OrdinalIgnoreCase))
|
||||
processResult = bridge.PreAdjustment_CompletionDirect();
|
||||
else
|
||||
throw new InvalidOperationException(string.Format("Unsupported preadjustment activity '{0}'.", testParams.Activity));
|
||||
|
||||
response = processResult.ToString();
|
||||
return processResult.Success;
|
||||
}
|
||||
|
||||
private static void UpdatePreadjustmentResult(Test test, TestMethod method, IEnumerable<KeyValuePair<int, GenesisSmartReader>> readers, bool success, DateTime startTime)
|
||||
{
|
||||
TestRslt testResult = ProcessData.BatchRslts.GetTestRslt(test.Name, test.Part);
|
||||
if (testResult == null)
|
||||
return;
|
||||
|
||||
testResult.MethodClass = method.ClassName;
|
||||
testResult.StartTime = startTime;
|
||||
testResult.EndTime = DateTime.Now;
|
||||
testResult.TestTime = Math.Max(0, (int)(testResult.EndTime - startTime).TotalSeconds);
|
||||
testResult.TestDone = true;
|
||||
|
||||
foreach (KeyValuePair<int, GenesisSmartReader> item in readers)
|
||||
{
|
||||
MeterTestRslt meterResult = ProcessData.BatchRslts.GetMeterTestRslt(test.Name, item.Key, CompoundMeterId.Single);
|
||||
if (meterResult == null)
|
||||
continue;
|
||||
|
||||
meterResult.WaterMeter.SerialNr = item.Value.SerialNr;
|
||||
meterResult.Passed = success;
|
||||
meterResult.TestDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read default Q2 correction factors from a REST service (= Web service).
|
||||
/// </summary>
|
||||
|
||||
@@ -14,14 +14,14 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
{
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
iPerlCommunication.TestMethodCfg config;
|
||||
public IComponentCfg Config
|
||||
TestMethodCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as iPerlCommunication.TestMethodCfg;
|
||||
Redraw();
|
||||
config = value as TestMethodCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,12 +27,16 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
/// Communication activity
|
||||
public bool SimultWithPrevious;
|
||||
public bool SimultWithNext;
|
||||
public string MeterSize = "DN50";
|
||||
public float Temperature = 20.0f;
|
||||
|
||||
public override void InitializeAll()
|
||||
{
|
||||
Activity = GenesisCommunicationForm.SlotInitializeStr;
|
||||
SimultWithPrevious = false;
|
||||
SimultWithNext = false;
|
||||
MeterSize = "DN50";
|
||||
Temperature = 20.0f;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +45,8 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
Strings.Activity,
|
||||
Strings.Simultaneous_with_previous_step,
|
||||
Strings.Simultaneous_with_next_step,
|
||||
"Meter size",
|
||||
"Temperature [°C]",
|
||||
};
|
||||
public override string ParamName(int i) { return paramNames[i]; }
|
||||
public override int ParamsCount() { return paramNames.Length; }
|
||||
@@ -65,6 +71,14 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
retVal.Add(GenesisCommunicationForm.WriteSlotQ3CalibrationStr);
|
||||
retVal.Add(GenesisCommunicationForm.CheckMeterPrepareStr);
|
||||
retVal.Add(GenesisCommunicationForm.HoldSlotStr);
|
||||
retVal.Add(GenesisCommunicationSeq.PreadjustmentInitializationStr);
|
||||
retVal.Add(GenesisCommunicationSeq.PreadjustmentDetectStr);
|
||||
retVal.Add(GenesisCommunicationSeq.PreadjustmentPreparationStr);
|
||||
retVal.Add(GenesisCommunicationSeq.PreadjustmentAmplitudeTestStr);
|
||||
retVal.Add(GenesisCommunicationSeq.PreadjustmentTemperatureCalibrationStr);
|
||||
retVal.Add(GenesisCommunicationSeq.PreadjustmentPushTemperatureStr);
|
||||
retVal.Add(GenesisCommunicationSeq.PreadjustmentOffsetTestStr);
|
||||
retVal.Add(GenesisCommunicationSeq.PreadjustmentCompletionStr);
|
||||
|
||||
|
||||
|
||||
@@ -126,10 +140,18 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
|
||||
return retVal;
|
||||
}
|
||||
else
|
||||
else if (i == 1 || i == 2)
|
||||
{
|
||||
return new string[] { Strings.yes, Strings.no };
|
||||
}
|
||||
else if (i == 3)
|
||||
{
|
||||
var meterSizes = new List<string>(System.Enum.GetNames(typeof(Xylem.Common.Logic.ProductionOrderCore.OrderData.MeterSize)));
|
||||
meterSizes.Remove(Xylem.Common.Logic.ProductionOrderCore.OrderData.MeterSize.NA.ToString());
|
||||
return meterSizes;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override string ToString(int i)
|
||||
@@ -139,6 +161,8 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
case 0: return Activity;
|
||||
case 1: return (SimultWithPrevious ? Strings.yes : Strings.no);
|
||||
case 2: return (SimultWithNext ? Strings.yes : Strings.no);
|
||||
case 3: return MeterSize;
|
||||
case 4: return Temperature.ToString();
|
||||
default: return string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -150,6 +174,8 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
case 0: Activity = strValue; return CfgUpdateFlags.None;
|
||||
case 1: SimultWithPrevious = strValue.ToLower().Equals(Strings.yes.ToLower()); return CfgUpdateFlags.None;
|
||||
case 2: SimultWithNext = strValue.ToLower().Equals(Strings.yes.ToLower()); return CfgUpdateFlags.None;
|
||||
case 3: MeterSize = strValue; return CfgUpdateFlags.None;
|
||||
case 4: Temperature = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
default: return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
@@ -157,6 +183,7 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
public bool ValidateParam(int i, string strValue, out string message)
|
||||
{
|
||||
message = string.Empty;
|
||||
float temperature;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
@@ -166,6 +193,11 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
case 2:
|
||||
if (strValue.Equals(Strings.yes) || strValue.Equals(Strings.no)) return true;
|
||||
break;
|
||||
case 3:
|
||||
return System.Enum.TryParse(strValue, true, out Xylem.Common.Logic.ProductionOrderCore.OrderData.MeterSize meterSize) && meterSize != Xylem.Common.Logic.ProductionOrderCore.OrderData.MeterSize.NA;
|
||||
case 4:
|
||||
if (Utils.TryParseSFloat(strValue, out temperature) && temperature >= -20.0f && temperature <= 100.0f) return true;
|
||||
break;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
return false;
|
||||
@@ -180,6 +212,8 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
|
||||
prms.Activity = this.Activity;
|
||||
prms.SimultWithPrevious = this.SimultWithPrevious;
|
||||
prms.SimultWithNext = this.SimultWithNext;
|
||||
prms.MeterSize = this.MeterSize;
|
||||
prms.Temperature = this.Temperature;
|
||||
}
|
||||
|
||||
public IParamsProvider Clone()
|
||||
|
||||
Reference in New Issue
Block a user