diff --git a/Common/CommonCore.Configuration/ServiceUrls.cs b/Common/CommonCore.Configuration/ServiceUrls.cs
index 469eb12c..2d5bb901 100644
--- a/Common/CommonCore.Configuration/ServiceUrls.cs
+++ b/Common/CommonCore.Configuration/ServiceUrls.cs
@@ -187,8 +187,54 @@ namespace Xylem.Common.CommonCore.Configuration
// "http://localhost:56011/api/SoftwareAccess/GetVersionIsValid";
+ private const String PressureSensorTestURL_GetTestSpec
+ = "http://sla12iis01.emea.sensus.net/MeterProcessState/api/CordonelPressureSensorTest/GetTestSpec";
-
+ private const String PressureSensorTestURL_PostTestResults
+ = "http://sla12iis01.emea.sensus.net/MeterProcessState/api/CordonelPressureSensorTest/PostTestResults";
+
+ ///
+ /// usage: string.Format(CordonelPressureSensorTestURL_GetTestResults, pcbId);
+ ///
+ private const String PressureSensorTestURL_GetTestResults
+ = "http://sla12iis01.emea.sensus.net/MeterProcessState/api/CordonelPressureSensorTest/GetTestResults/{0}";
+
+
+ ///
+ /// GET: test specification for water meter with pressure sensor.
+ ///
+ public static string GetPressureSensorSpecificationURL
+#if DEBUG
+ => "http://localhost:56011/api/CordonelPressureSensorTest/GetTestSpec";
+#else
+ => ConfigurationManager.AppSettings[nameof(GetPressureSensorSpecificationURL)]
+ ?? PressureSensorTestURL_GetTestSpec;
+#endif
+
+ ///
+ /// POST: test result for water meter with pressure sensor.
+ ///
+ public static string PostPressureSensorResultURL
+#if DEBUG
+ => "http://localhost:56011/api/CordonelPressureSensorTest/PostTestResults";
+#else
+ => ConfigurationManager.AppSettings[nameof(PostPressureSensorResultURL)]
+ ?? PressureSensorTestURL_PostTestResults;
+#endif
+
+ ///
+ /// GET: a list of test results for the water meter with specified pcbId.
+ ///
+ public static string PressureSensorResultsURL(this T pcbId)
+ {
+#if DEBUG
+ var url = "http://localhost:56011/api/CordonelPressureSensorTest/GetTestResults/{0}";
+#else
+ var url = ConfigurationManager.AppSettings[nameof(PressureSensorResultsURL)] ?? PressureSensorTestURL_GetTestResults;
+#endif
+
+ return string.Format(url, pcbId);
+ }
///
/// List all Cordonel FW packages.
diff --git a/Common/CordonelPreadjustmentUi/CordonelPreadjustmentUi.csproj b/Common/CordonelPreadjustmentUi/CordonelPreadjustmentUi.csproj
index 0dca42ea..b3996ca0 100644
--- a/Common/CordonelPreadjustmentUi/CordonelPreadjustmentUi.csproj
+++ b/Common/CordonelPreadjustmentUi/CordonelPreadjustmentUi.csproj
@@ -5,7 +5,7 @@
Debug
AnyCPU
{D0C8D887-ED52-40AB-A069-90BCE0E801E2}
- Library
+ WinExe
Properties
Xylem.Common.Ui.CordonelPreadjustmentUi
Xylem.Common.Ui.CordonelPreadjustmentUi
@@ -103,6 +103,9 @@
+
+ true
+
..\packages\Newtonsoft.Json.12.0.3\lib\net40\Newtonsoft.Json.dll
@@ -116,6 +119,9 @@
+
+ ..\..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Net.Http.dll
+
@@ -153,6 +159,7 @@
PreAdjustmentControl.cs
+
diff --git a/Common/CordonelPreadjustmentUi/PreAdjustmentControl.cs b/Common/CordonelPreadjustmentUi/PreAdjustmentControl.cs
index c190ab64..7805f8ed 100644
--- a/Common/CordonelPreadjustmentUi/PreAdjustmentControl.cs
+++ b/Common/CordonelPreadjustmentUi/PreAdjustmentControl.cs
@@ -393,6 +393,7 @@ namespace CordonelPreadjustmentUi
{
this.l_ZeroFlowCal_TempCal.ForeColor = color;
}
+
public enum StatusPanelItems
{
None = 0,
@@ -1681,9 +1682,13 @@ namespace CordonelPreadjustmentUi
listOfProgrammParts.Add(new FlushProcess("First Flush", StatusPanelItems.Detect, PredefinedMessages.WaitUntilFlushFinished(pp.Setting.Culture), string.Empty, 2 * 60));
+ listOfProgrammParts.Add(new PressureTestProcess("PreussureTest", StatusPanelItems.Prepare, PredefinedMessages.WaitUntilPreparationFinished(pp.Setting.Culture), PredefinedMessages.PreparationFailed(pp.Setting.Culture), 1 * 60));
listOfProgrammParts.Add(new PreparationProcess("Preparation", StatusPanelItems.Prepare, PredefinedMessages.WaitUntilPreparationFinished(pp.Setting.Culture), PredefinedMessages.PreparationFailed(pp.Setting.Culture), 1 * 60));
+
+
+
if (!pp.Setting.TempOnly)
{
listOfProgrammParts.Add(new AmplitudeTestProcess("Amplitude Test", StatusPanelItems.Amplitude, PredefinedMessages.WaitUntilAmplitudeTestFinished(pp.Setting.Culture), PredefinedMessages.AmplitudeFailed(pp.Setting.Culture), 4 * 60));
diff --git a/Common/CordonelPreadjustmentUi/Processes/Actions/PreparationProcess.cs b/Common/CordonelPreadjustmentUi/Processes/Actions/PreparationProcess.cs
index a153d05a..53f6e3ba 100644
--- a/Common/CordonelPreadjustmentUi/Processes/Actions/PreparationProcess.cs
+++ b/Common/CordonelPreadjustmentUi/Processes/Actions/PreparationProcess.cs
@@ -16,8 +16,6 @@ namespace CordonelPreadjustmentUi.Processes.Actions
{
public class PreparationProcess : BaseProcess
{
-
-
public PreparationProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS) : base(processName, panelState, performMessage, failedMessage, expectedTimeS)
{
}
diff --git a/Common/CordonelPreadjustmentUi/Processes/Actions/PressureTestProcess.cs b/Common/CordonelPreadjustmentUi/Processes/Actions/PressureTestProcess.cs
new file mode 100644
index 00000000..c9bf190d
--- /dev/null
+++ b/Common/CordonelPreadjustmentUi/Processes/Actions/PressureTestProcess.cs
@@ -0,0 +1,256 @@
+namespace CordonelPreadjustmentUi.Processes.Actions
+{
+ using Newtonsoft.Json;
+
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading;
+ using System.Threading.Tasks;
+
+ using Xylem.Common.CommonCore.Configuration;
+ using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
+ using Xylem.Common.Logic.SoftwareAccessHelper;
+
+ using static CordonelPreadjustmentUi.PreAdjustmentControl;
+
+ ///
+ /// Process for cordonel water meters with pressure sensor.
+ ///
+ ///
+ /// Just started implementing pressure test for water meters with pressure sensor.
+ ///
+ public class PressureTestProcess : BaseProcess
+ {
+ ///
+ /// Read / Write is pressure present for the water meter.
+ ///
+ ///
+ /// Just started implementing pressure test for water meters with pressure sensor.
+ ///
+ private const string PRESSURE_PRESENT = "METROLOGYASST_PressurePresent";
+ ///
+ /// Read / Write pressure measurements for the water meter.
+ ///
+ ///
+ /// Just started implementing pressure test for water meters with pressure sensor.
+ ///
+ private const string PRESSURE_MEASURE = "METROLOGYASST_PressureMeasure";
+
+ ///
+ /// Constructor for passing parameters to the base constructor of the derived class.
+ ///
+ /// The name used to show into the GUI.
+ /// TODO: Get the right description. Probably the state for the box into the GUI. ???
+ /// TODO: Get the right description. Probably the success message to show into the GUI. ???
+ /// TODO: Get the right description. Probably the error message to show into the GUI. ???
+ /// TODO: Get the right description. Probably the expected time for process the pressure tests. ???
+ ///
+ /// Just started implementing pressure test for water meters with pressure sensor.
+ ///
+ public PressureTestProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS)
+ : base(processName, panelState, performMessage, failedMessage, expectedTimeS)
+ {
+ }
+
+ ///
+ /// Determinates and initializes a list of pressure measure tests processes on the logedin cordonels with pressure sensor.
+ /// Programm workflow for Cordonels with pressure sensor.
+ /// When any of the water meters has presure sensor - load the test specification.
+ /// Acording to the test specification process all meters, also the referenz on workplaces 11 and 12.
+ ///
+ /// Measurement as follow.
+ /// - Measure starts with = 1
+ /// - Then registry is readeded and comaired to the referenz meters acording to the specification.
+ ///
+ ///
+ /// Returns a for processing the pressure tests on the goggedin cordonels.
+ ///
+ /// Just started implementing pressure test for water meters with pressure sensor.
+ ///
+ public override List StartWork()
+ {
+ /// List of the processes to start.
+ var listOfPresureTestTasks = new List();
+ var pressureTestSpecification = default(PressureTestSpecification);
+ var pressureTestSpecificationLoaded = false;
+ /// Just to not lose from focus the process progrss object.
+ var processProgress = base.CurrentProcessProgress;
+ var minPressureReferenzValue = default(int?);
+ var maxPressureReferenzValue = default(int?);
+
+ /// Looping trough all s to determinate whitch are with pressure sensor.
+ foreach (var meterStateControl in base.MeterStateCtls)
+ {
+ /// If the meter is enabled and pressure sensor is present a new pressure mesure task should be initialized and added to the processes list.
+ if (meterStateControl.IsEnabled)
+ {
+ /// Getting the meter object from the state control.
+ var meter = meterStateControl.Meter;
+ /// Reads the buffer for determinating if the pressure sensor is present.
+ var isPressurePresentBuffer = meter.ReadRegister(PRESSURE_PRESENT);
+ /// Converted value for determinating if the pressure sensor is present.
+ var isPressurePresent = RegisterConverter.ConvertTo(isPressurePresentBuffer);
+
+ if (!isPressurePresent)
+ {
+ processProgress.DebugMessage($"Watermeter has no pressure sensor!", meterStateControl.Slot, "DC", meter.PcbId);
+
+ continue;
+ }
+
+ /// Loads the pressure test specification from the defined web service if not yet loaded.
+ if (pressureTestSpecification is null && !pressureTestSpecificationLoaded)
+ {
+ pressureTestSpecificationLoaded = true;
+ pressureTestSpecification = this.LoadPressureTestSpecification();
+
+ /// if loading fails
+ if (pressureTestSpecification is null)
+ {
+ processProgress.DebugMessage($"Test specification could not be loaded properly!", meterStateControl.Slot, "DC", meter.PcbId);
+
+ // TODO: Handle possible exceptions by making http request.
+ continue;
+ }
+ }
+
+ /// Initialize min and max referenz values ones for all meters
+ if (minPressureReferenzValue is null)
+ {
+ /// setting the min and max values on their oposit values.
+ /// checking the equality later will set up a value by 1 or more referenz meters.
+ minPressureReferenzValue = int.MaxValue;
+ maxPressureReferenzValue = int.MinValue;
+
+ if (processProgress.Setting.GetTempUseTempFlansh() || TempMeterStateCtls.Any(a => a.IsEnabled))
+ {
+ /// Determinates the min and max values aus temperatur meters list.
+ foreach (var referenzMeterState in base.TempMeterStateCtls)
+ {
+ if (referenzMeterState.IsEnabled)
+ {
+ var referenzMeter = referenzMeterState.Meter;
+ /// Reset meter pressure
+ referenzMeter.WriteRegister(PRESSURE_MEASURE, 1);
+
+ if (!referenzMeter.IsLoggedOn)
+ {
+ referenzMeter.Login();
+ }
+
+ var referenzPressureBuffer = referenzMeter.ReadRegister(PRESSURE_MEASURE);
+ var referenzPressure = RegisterConverter.ConvertTo(referenzPressureBuffer);
+
+ if (referenzPressure < minPressureReferenzValue)
+ {
+ minPressureReferenzValue = referenzPressure;
+ }
+
+ if (referenzPressure > maxPressureReferenzValue)
+ {
+ maxPressureReferenzValue = referenzPressure;
+ }
+ }
+ }
+ }
+
+ /// Continue if min pressure value is still its oposit for the type. There was no referenz zehler found.
+ if (minPressureReferenzValue == int.MaxValue)
+ {
+ processProgress.DebugMessage($"No referenz watermeter found!", meterStateControl.Slot, "DC", meter.PcbId);
+
+ continue;
+ }
+
+ listOfPresureTestTasks.Add(new Task(() =>
+ {
+ var measuredTestValues = new int[pressureTestSpecification.NumberOfMeasurements];
+ var measurementDelyInS = pressureTestSpecification.TimeMeasurementsInS * 1000;
+ var numberOfMeasurements = pressureTestSpecification.NumberOfMeasurements;
+ var testDate = DateTime.Now;
+
+ for (int measurement = 0; measurement < numberOfMeasurements; measurement++)
+ {
+ /// Reset meter pressure
+ meter.WriteRegister(PRESSURE_MEASURE, 1);
+
+ /// Read the new meter pressure
+ var pressureMeasureBuffer = meter.ReadRegister(PRESSURE_MEASURE);
+ var pressureInPascals = RegisterConverter.ConvertTo(pressureMeasureBuffer);
+
+ measuredTestValues[measurement] = pressureInPascals;
+ processProgress.DebugMessage($"Measure {measurement + 1}: {pressureInPascals}Pa", meterStateControl.Slot, "DC", meter.PcbId);
+
+ /// Dely only for first n - 1 measurements
+ if (measurement < numberOfMeasurements - 1)
+ {
+ Thread.Sleep(measurementDelyInS);
+ }
+ }
+
+ var avgPressure = (int)measuredTestValues.Average();
+ var testPassed = minPressureReferenzValue <= avgPressure && avgPressure <= maxPressureReferenzValue;
+ var avgPressureInBars = avgPressure / 100_000F;
+
+ processProgress.DebugMessage($"Average pressure: {avgPressure}Pa", meterStateControl.Slot, "DC", meter.PcbId);
+ processProgress.DebugMessage($"Average pressure: {avgPressureInBars}Bar", meterStateControl.Slot, "DC", meter.PcbId);
+
+ if (!this.PostPressureTestResult(meter.PcbId, avgPressureInBars, testPassed, testDate))
+ {
+ processProgress.DebugMessage($"Test result was not posted!", meterStateControl.Slot, "DC", meter.PcbId);
+
+ return false;
+ }
+
+ return testPassed;
+ }));
+ }
+ }
+ }
+
+ return listOfPresureTestTasks;
+ }
+
+ private PressureTestSpecification LoadPressureTestSpecification()
+ {
+ try
+ {
+ var responseContent = LocalWebRequest.GetRequest(ServiceUrls.GetPressureSensorSpecificationURL);
+
+ return JsonConvert.DeserializeObject(responseContent);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ private bool PostPressureTestResult(string pcbIdText, float avgPressure, bool passed, DateTime testDate)
+ {
+ try
+ {
+ return LocalWebRequest.PostRequestAsync(ServiceUrls.PostPressureSensorResultURL, json: new
+ {
+ PcbId = int.TryParse(pcbIdText, out int pcbId) ? pcbId : default(int?),
+ AvgPressureInBar = avgPressure,
+ TestPassed = passed,
+ TestDate = testDate,
+ });
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ }
+ }
+
+ internal class PressureTestSpecification
+ {
+ public int NumberOfMeasurements { get; set; }
+
+ public int TimeMeasurementsInS { get; set; }
+
+ public float MaxDeviationInBar { get; set; }
+ }
+}
diff --git a/Common/CordonelPreadjustmentUi/Processes/BaseProcess.cs b/Common/CordonelPreadjustmentUi/Processes/BaseProcess.cs
index d2c6d2a4..24cbcb81 100644
--- a/Common/CordonelPreadjustmentUi/Processes/BaseProcess.cs
+++ b/Common/CordonelPreadjustmentUi/Processes/BaseProcess.cs
@@ -20,6 +20,7 @@ namespace CordonelPreadjustmentUi.Processes
public readonly string PerformMessage;
public readonly int ExpectedTimeS;
public DateTimeOffset StartTime;
+
public BaseProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS = null)
{
ProcessName = processName;
@@ -30,6 +31,7 @@ namespace CordonelPreadjustmentUi.Processes
ExpectedTimeS = expectedTimeS.HasValue ? expectedTimeS.Value : 0;
}
+
internal List AllMeterStateCtrls()
{
var r = new List();
@@ -75,29 +77,29 @@ namespace CordonelPreadjustmentUi.Processes
var completTasks = new Task(() =>
+ {
+ try
+ {
+ while (!listOfProcessTasks.All(t => t.IsCompleted))
{
- try
+ if (pp.CancellationSource != null && pp.CancellationSource.IsCancellationRequested)
{
- while (!listOfProcessTasks.All(t => t.IsCompleted))
- {
- if (pp.CancellationSource != null && pp.CancellationSource.IsCancellationRequested)
- {
- return;
- }
- Thread.Sleep(5);
- }
-
- GetSequenceResult($"{ProcessName} sequence");
- pp.IsBusy = false;
+ return;
}
- catch (Exception ex)
- {
+ Thread.Sleep(5);
+ }
- throw new ApplicationException("Error on waiting for completition", ex);
- }
+ GetSequenceResult($"{ProcessName} sequence");
+ pp.IsBusy = false;
+ }
+ catch (Exception ex)
+ {
+
+ throw new ApplicationException("Error on waiting for completition", ex);
+ }
- });
+ });
completTasks.Start();
diff --git a/Common/CordonelPreadjustmentUi/app.config b/Common/CordonelPreadjustmentUi/app.config
index e936cc13..67c9d49a 100644
--- a/Common/CordonelPreadjustmentUi/app.config
+++ b/Common/CordonelPreadjustmentUi/app.config
@@ -1,5 +1,10 @@
+
+
+
+
+
diff --git a/Common/Service/MeterProcessState/Controllers/CordonelPressureSensorTestController.cs b/Common/Service/MeterProcessState/Controllers/CordonelPressureSensorTestController.cs
index 1e9ee000..a7fd2351 100644
--- a/Common/Service/MeterProcessState/Controllers/CordonelPressureSensorTestController.cs
+++ b/Common/Service/MeterProcessState/Controllers/CordonelPressureSensorTestController.cs
@@ -14,6 +14,9 @@
using Xylem.Common.Service.MeterProcessState.Extensions;
using Xylem.Common.Service.MeterProcessState.Models;
+ ///
+ /// Controller for tests on cordonel pressure sensor.
+ ///
[RoutePrefix("api/CordonelPressureSensorTest")]
public class CordonelPressureSensorTestController : ApiController
{
@@ -106,11 +109,7 @@
return httpActionResult;
}
-
- ///
- /// Nach dem Test wird für jede PcbID diese Funktion aufgerufen und die daten in die Datenbank übermittelt
- ///
- /// TODO: return value
+
[HttpGet]
[Route(nameof(GetTestResults) + "/{pcbId}")]
public async Task GetTestResults(int pcbId)
@@ -152,7 +151,7 @@
{
testResults.Add(new CordonelTestResult
{
- Id = await sqlDataReader.GetLongAsync(0),
+ Id = await sqlDataReader.GetIntAsync(0),
PcbId = await sqlDataReader.GetIntAsync(1),
AvgPressureInBar = await sqlDataReader.GetFloatAsync(2),
TestPassed = await sqlDataReader.GetBoolAsync(3),
diff --git a/Common/Service/MeterProcessState/Models/Cordonel.cs b/Common/Service/MeterProcessState/Models/Cordonel.cs
index a1995366..0d27946a 100644
--- a/Common/Service/MeterProcessState/Models/Cordonel.cs
+++ b/Common/Service/MeterProcessState/Models/Cordonel.cs
@@ -1,6 +1,7 @@
namespace Xylem.Common.Service.MeterProcessState.Models
{
using System;
+ using System.ComponentModel.DataAnnotations;
public class CordonelTestSpec
{
@@ -13,14 +14,18 @@
public class CordonelTestResult
{
- public long Id { get; set; }
+ public int? Id { get; set; }
- public int PcbId { get; set; }
+ [Required]
+ public int? PcbId { get; set; }
- public DateTime TestDate { get; set; }
+ [Required]
+ public DateTime? TestDate { get; set; }
- public float AvgPressureInBar { get; set; }
+ [Required]
+ public float? AvgPressureInBar { get; set; }
- public bool TestPassed { get; set; }
+ [Required]
+ public bool? TestPassed { get; set; }
}
}
\ No newline at end of file
diff --git a/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache b/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache
index f98f081f..1edd49e3 100644
--- a/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache
+++ b/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache
@@ -1 +1 @@
-57a46bdf07e306281dc4ae72a3747ed460385fe7
+ac0776a643239630cd5909e36516a0bfa05cb113