This commit is contained in:
Roland Drabesch 2024-06-03 09:30:49 +02:00
parent c31c863d6d
commit 97c68b8fe3
15 changed files with 1791 additions and 159 deletions

View File

@ -155,7 +155,7 @@
</site>
<site name="MeterProcessState" id="2">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="D:\Projekte\SENSUS_GitLab\LAA_PRODUCTION\Common\Service\MeterProcessState" />
<virtualDirectory path="/" physicalPath="C:\Users\drabesch_ro\Repo\lab\la_operations\laa_production\Common\Service\MeterProcessState" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:56011:localhost" />

View File

@ -10,13 +10,15 @@
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*" />
<ColumnDefinition Width="80*"/>
<ColumnDefinition Width="40*"/>
<ColumnDefinition Width="40*"/>
<ColumnDefinition Width="10*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="21*"/>
<RowDefinition Height="398*"/>
<RowDefinition Height="200*"/>
<RowDefinition Height="200*"/>
<RowDefinition Height="21*"/>
</Grid.RowDefinitions>
<Label x:Name="FileName" >
@ -24,6 +26,9 @@
</Label><Button Click="Button_Click" Grid.Row="0" Grid.Column="2" >File</Button>
<ScottPlot:WpfPlot x:Name="WpfPlot1" Grid.Row="1" Grid.Column="1" />
<ScottPlot:WpfPlot x:Name="WpfPlot2" Grid.Row="1" Grid.Column="2" />
<ScottPlot:WpfPlot x:Name="WpfPlot3" Grid.Row="2" Grid.Column="1" />
<ScottPlot:WpfPlot x:Name="WpfPlot4" Grid.Row="2" Grid.Column="2" />
</Grid>
</Window>

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json;
using ScottPlot.WPF;
using System;
using System.Collections.Generic;
using System.IO;
@ -11,6 +12,7 @@ using Xylem.Common.Logic.ProductionOrderCore.TestResults;
using Xylem.Common.Logic.SoftwareAccessHelper;
using Xylem.Common.Metrology.Measurements;
namespace CordoPlot
{
/// <summary>
@ -149,44 +151,44 @@ namespace CordoPlot
Lines.Add(new List<double>());
List<List<ushort>> Errors = new List<List<ushort>>();
Errors.Add(new List<ushort>());
Errors.Add(new List<ushort>());
Errors.Add(new List<ushort>());
Errors.Add(new List<ushort>());
//List<List<ushort>> Errors = new List<List<ushort>>();
//Errors.Add(new List<ushort>());
//Errors.Add(new List<ushort>());
//Errors.Add(new List<ushort>());
//Errors.Add(new List<ushort>());
List<double> Syncmarks = new List<double>();
//List<double> Syncmarks = new List<double>();
List<double> Linescale = new List<double>();
foreach (var dataItem in listOfData)
{
foreach (var item in dataItem)
{
if (item is FlowTestRecord flow)
{
Lines.First().Add(flow.GetVolumeCm());
Errors.First().Add(0);
Linescale.Add(flow.GetTimeS());
if (item.GetDataSyncMark() == SyncMarkRecord.SyncStart || item.GetDataSyncMark() == SyncMarkRecord.SyncEnd)
{
Syncmarks.Add(flow.GetTimeS());
}
}
if (item is CalibrationRecord cal)
{
if (Linescale.Any())
{
Lines[cal.Channel].Add(cal.GetVolumeCm());
Errors[cal.Channel].Add(cal.Validation);
if (item.GetDataSyncMark() == SyncMarkRecord.SyncStart || item.GetDataSyncMark() == SyncMarkRecord.SyncEnd)
{
Syncmarks.Add(cal.GetTimeS());
}
}
}
}
}
//List<double> Linescale = new List<double>();
//foreach (var dataItem in listOfData)
//{
// foreach (var item in dataItem)
// {
// if (item is FlowTestRecord flow)
// {
// Lines.First().Add(flow.GetVolumeCm());
// Errors.First().Add(0);
// Linescale.Add(flow.GetTimeS());
// if (item.GetDataSyncMark() == SyncMarkRecord.SyncStart || item.GetDataSyncMark() == SyncMarkRecord.SyncEnd)
// {
// Syncmarks.Add(flow.GetTimeS());
// }
// }
// if (item is CalibrationRecord cal)
// {
// if (Linescale.Any())
// {
// Lines[cal.Channel].Add(cal.GetVolumeCm());
// Errors[cal.Channel].Add(cal.Validation);
// if (item.GetDataSyncMark() == SyncMarkRecord.SyncStart || item.GetDataSyncMark() == SyncMarkRecord.SyncEnd)
// {
// Syncmarks.Add(cal.GetTimeS());
// }
// }
// }
// }
//}
List<Tuple<ScottPlot.Color, ScottPlot.Color>> colors = new List<Tuple<ScottPlot.Color, ScottPlot.Color>>();
colors.Add(new Tuple<ScottPlot.Color, ScottPlot.Color>(ScottPlot.Colors.Blue, ScottPlot.Colors.DarkBlue));
@ -200,100 +202,60 @@ namespace CordoPlot
FinLines.Add(new List<double>());
FinLines.Add(new List<double>());
var linecounter = 0;
var counter = 0;
var intiVol = 0.0;
foreach (var lines in Lines)
var ChnlHelper = new List<Tuple<int, WpfPlot>>();
ChnlHelper.Add(new Tuple<int, WpfPlot>(0, WpfPlot1));
ChnlHelper.Add(new Tuple<int, WpfPlot>(1, WpfPlot2));
ChnlHelper.Add(new Tuple<int, WpfPlot>(2, WpfPlot3));
ChnlHelper.Add(new Tuple<int, WpfPlot>(3, WpfPlot4));
var Plotresults = new List<PlotResult>();
foreach (var item in ChnlHelper)
{
counter = 0;
foreach (var line in lines)
var volLines = testBenchresults.Plot( item.Item1, null);
volLines.Color = colors[item.Item1].Item1;
Plotresults.Add(volLines);
//foreach (var item in Errors[i])
//{
// if (item != 0)
// {
// WpfPlot1.Plot.Add.Marker(Linescale[cordHelp], FinLines[i][cordHelp], ScottPlot.MarkerShape.Cross, 10, colors[1].Item2);
// }
// cordHelp = cordHelp + 1;
//}
}
var maxScale = Plotresults.Max(p => p.ScaleLine.Count);
var AddScale = Plotresults.First(p => p.ScaleLine.Count == maxScale);
var srtExport = new System.Text.StringBuilder();
foreach (var item in ChnlHelper)
{
Plotresults[item.Item1].ScaleUp(AddScale.ScaleLine);
item.Item2.Plot.Add.Scatter(Plotresults[item.Item1].ScaleLine.ToArray(), Plotresults[item.Item1].VolumeLine.ToArray(), Plotresults[item.Item1].Color);
var exprLine = 0;
srtExport.AppendLine($"Chnl {item.Item1} ;Scale; Vol;");
foreach (var exprHelpLine in Plotresults[item.Item1].ScaleLine)
{
if (!FinLines[linecounter].Any())
{
FinLines[linecounter].Add(0);
intiVol = Lines[linecounter][counter];
}
else
{
var addVol = line - intiVol;
var dutOverflowVolumeCm = listOfData[linecounter].First().GetOverflowVolumeCm();
//an overflow is detected when absolute volume difference is higher than 1/2 of the OverflowVolumeCm
if (Math.Abs(addVol - FinLines[linecounter].Last()) > (0.5 * dutOverflowVolumeCm))
{
//if the overflow has been detected the end volume is higher than the start volume
//indicates the negative flow direction
if (addVol > FinLines[linecounter].Last())
{
//negative overflow
intiVol -= dutOverflowVolumeCm;
//LoggerMeasurement.Info($"Slot:{Slot}, Channel: {IntermediateRecord.GetChannel()} - has negative overflow. currentVolumeQm ({currentVolumeQm}) - lastVolumeQm ({lastVolumeQm}). current accuOverflowVolume is {_accuDutOverflowVolumeCm}");
}
else
{
//positive overflow
intiVol += dutOverflowVolumeCm;
//LoggerMeasurement.Info($"Slot:{Slot}, Channel: {IntermediateRecord.GetChannel()} - has positive overflow. currentVolumeQm ({currentVolumeQm}) - lastVolumeQm ({lastVolumeQm}). current accuOverflowVolume is {_accuDutOverflowVolumeCm}");
}
}
addVol = line - intiVol;
FinLines[linecounter].Add(addVol);
}
counter = counter + 1;
srtExport.AppendLine($"{exprHelpLine};{Plotresults[item.Item1].VolumeLine[exprLine]};");
exprLine = exprLine + 1;
}
linecounter = 1 + linecounter;
item.Item2.Plot.Axes.AutoScale();
item.Item2.Refresh();
}
for (int i = 0; i <= 3; i++)
{
for (int add = FinLines[i].Count; add < Linescale.Count; add++)
{
FinLines[i].Add(0);
}
//foreach (var syncm in Syncmarks)
//{
// WpfPlot1.Plot.Add.VerticalLine(syncm, 2, ScottPlot.Colors.DarkGray);
//}
for (int add = Errors[i].Count; add < Linescale.Count; add++)
{
Errors[i].Add(0);
}
}
WpfPlot1.Plot.Add.Scatter(Linescale.ToArray(), FinLines[0].ToArray(), colors[0].Item1);
WpfPlot1.Plot.Add.Scatter(Linescale.ToArray(), FinLines[1].ToArray(), colors[1].Item1);
WpfPlot1.Plot.Add.Scatter(Linescale.ToArray(), FinLines[2].ToArray(), colors[2].Item1);
WpfPlot1.Plot.Add.Scatter(Linescale.ToArray(), FinLines[3].ToArray(), colors[3].Item1);
for (int i = 0; i <= 3; i++)
{
var cordHelp = 0;
foreach (var item in Errors[i])
{
if (item != 0)
{
WpfPlot1.Plot.Add.Marker(Linescale[cordHelp], FinLines[i][cordHelp], ScottPlot.MarkerShape.Cross, 10, colors[1].Item2);
}
cordHelp = cordHelp + 1;
}
}
foreach (var syncm in Syncmarks)
{
WpfPlot1.Plot.Add.VerticalLine(syncm, 2, ScottPlot.Colors.DarkGray);
}
WpfPlot1.Plot.Axes.AutoScale();
//WpfPlot1.Plot.Axes.AutoScale();
//for (int i = 0; i <= 3; i++)
//{
@ -307,7 +269,7 @@ namespace CordoPlot
WpfPlot1.Refresh();
//WpfPlot1.Refresh();
}
}

View File

@ -1,10 +1,35 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using ScottPlot;
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords;
using Xylem.Common.Logic.ProductionOrderCore.TestResults;
using Xylem.Common.Metrology.Measurements;
namespace CordoPlot
{
public class PlotResult
{
public List<double> VolumeLine = new List<double>();
public List<double> ScaleLine = new List<double>();
public List<double> GP30Erros = new List<double>();
public List<double> TestMarks = new List<double>();
public Color Color { get; internal set; }
public void ScaleUp(List<double> MaxSacle)
{
if (VolumeLine.Count < MaxSacle.Count)
{
for (int i = VolumeLine.Count; i < MaxSacle.Count; i++)
{
VolumeLine.Add(double.NaN);
ScaleLine.Add(MaxSacle[i]);
}
}
}
}
public class TestPointResult
{
public int? Chnl { get; internal set; } = null;
@ -34,11 +59,12 @@ namespace CordoPlot
foreach (var allChnlItems in this.ListOfRecords)
{
var intiVol = 0.0;
CurrentChnl = CurrentChnl + 1;
CurrentChnl = CurrentChnl + 1;//29586
CurrentTestPoint = 0;
foreach (var item in allChnlItems)
{
if (!testPointLocked && item.GetDataSyncMark() == Xylem.Common.CommonCore.Consts.SyncMarkRecord.SyncStart)
{
@ -61,40 +87,60 @@ namespace CordoPlot
}
}
}
return true;
}
public double[] Plot(int? Chnl = null, int? TestNr = null)
public PlotResult Plot(int Chnl, int? TestNr = null)
{
//
var results = testPointResults.Where(t => t.Chnl == Chnl && (!TestNr.HasValue || t.TestNr == TestNr.Value));
List<double> VolumeLine = new List<double>();
List<double> ScaleLine = new List<double>();
List<double> GP30Erros = new List<double>();
List<double> TestMarks = new List<double>();
var linecounter = 0;
var counter = 0;
foreach (var lines in Lines)
var intiVol = 0.0;
var currentTestNr = -1;
foreach (var lines in results)
{
counter = 0;
foreach (var line in lines)
foreach (var line in lines.measurementRecords)
{
if (!FinLines[linecounter].Any())
if (lines.TestNr != currentTestNr)
{
FinLines[linecounter].Add(0);
intiVol = Lines[linecounter][counter];
TestMarks.Add(line.GetTimeS());
currentTestNr = lines.TestNr;
}
ScaleLine.Add(line.GetTimeS() + (100000 * currentTestNr));
if (line is CalibrationRecord cal)
{
GP30Erros.Add(cal.Validation);
}
else
{
var addVol = line - intiVol;
var dutOverflowVolumeCm = listOfData[linecounter].First().GetOverflowVolumeCm();
GP30Erros.Add(0);
}
if (!VolumeLine.Any())
{
VolumeLine.Add(0);
intiVol = line.GetVolumeCm();
}
else
{
var addVol = line.GetVolumeCm() - intiVol;
var dutOverflowVolumeCm = line.GetOverflowVolumeCm();
//an overflow is detected when absolute volume difference is higher than 1/2 of the OverflowVolumeCm
if (Math.Abs(addVol - FinLines[linecounter].Last()) > (0.5 * dutOverflowVolumeCm))
if (Math.Abs(addVol - VolumeLine.Last()) > (0.5 * dutOverflowVolumeCm))
{
//if the overflow has been detected the end volume is higher than the start volume
//indicates the negative flow direction
if (addVol > FinLines[linecounter].Last())
if (addVol > VolumeLine.Last())
{
//negative overflow
intiVol -= dutOverflowVolumeCm;
@ -107,9 +153,9 @@ namespace CordoPlot
//LoggerMeasurement.Info($"Slot:{Slot}, Channel: {IntermediateRecord.GetChannel()} - has positive overflow. currentVolumeQm ({currentVolumeQm}) - lastVolumeQm ({lastVolumeQm}). current accuOverflowVolume is {_accuDutOverflowVolumeCm}");
}
}
addVol = line - intiVol;
addVol = line.GetVolumeCm() - intiVol;
FinLines[linecounter].Add(addVol);
VolumeLine.Add(addVol);
}
@ -123,6 +169,8 @@ namespace CordoPlot
linecounter = 1 + linecounter;
}
return new PlotResult() { VolumeLine = VolumeLine, ScaleLine = ScaleLine, GP30Erros = GP30Erros, TestMarks = TestMarks };
}
}

View File

@ -175,6 +175,11 @@
<DependentUpon>PreAdjustmentControl.cs</DependentUpon>
</Compile>
<Compile Include="PreAdjustmentSettingsContainer.cs" />
<Compile Include="Processes\ActionsSinglePath\SPAmplitudeTestProcess.cs" />
<Compile Include="Processes\ActionsSinglePath\SPCompletionProcess.cs" />
<Compile Include="Processes\ActionsSinglePath\SPOffsetTestProcess.cs" />
<Compile Include="Processes\ActionsSinglePath\SPPreparationProcess.cs" />
<Compile Include="Processes\ActionsSinglePath\SPTemperatureCalibrationProcess.cs" />
<Compile Include="Processes\Actions\MagFluxZeroFlow.cs" />
<Compile Include="Processes\Actions\PressureTestProcess.cs" />
<Compile Include="Processes\Actions\FlushProcess.cs" />
@ -196,6 +201,7 @@
<Compile Include="Watcher\IWatcher.cs" />
<Compile Include="Watcher\IWatcherNeedCalibrationData.cs" />
<Compile Include="Watcher\TempWatcher.cs" />
<Compile Include="ZeroFlowSinglePathMeter.cs" />
<Compile Include="ZeroFlowGenesisMeter.cs" />
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>

View File

@ -1,7 +1,6 @@
using CordonelPreadjustmentUi.Processes;
using CordonelPreadjustmentUi.Processes.Actions;
using CordonelPreadjustmentUi.Processes.Itinerary;
using Logic.ProductionToProductMapper.Cordonel;
using System;
using System.Collections.Generic;
using System.Drawing;
@ -11,7 +10,6 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Consts;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
using Xylem.Common.Logic.ProductionOrderCore.OrderData;
@ -158,7 +156,7 @@ namespace CordonelPreadjustmentUi
meterStateCtl.StartTempWatch(meterStateCtl.MeterTempMode);
}
}
@ -1694,7 +1692,7 @@ namespace CordonelPreadjustmentUi
List<IProcess> listOfProgrammParts = new List<IProcess>();
listOfProgrammParts.Add(new PrepareTestProcess("PrepareTest", StatusPanelItems.Detect, string.Empty, string.Empty, 1 * 60));
@ -1704,26 +1702,59 @@ namespace CordonelPreadjustmentUi
//listOfProgrammParts.Add(new PressureTestProcess("PreussureTest", StatusPanelItems.Prepare, PredefinedMessages.WaitUntilPreparationFinished(pp.Setting.Culture), PredefinedMessages.PreparationFailed(pp.Setting.Culture), 1 * 60));
if (pp.Setting.NumberOfPaths == 1)
{
listOfProgrammParts.Add(new SPPreparationProcess("Preparation Single", StatusPanelItems.Prepare, PredefinedMessages.WaitUntilPreparationFinished(pp.Setting.Culture), PredefinedMessages.PreparationFailed(pp.Setting.Culture), 1 * 60));
}
else
{
listOfProgrammParts.Add(new PreparationProcess("Preparation", 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));
if (pp.Setting.NumberOfPaths == 1)
{
listOfProgrammParts.Add(new SPAmplitudeTestProcess("Amplitude Test Single", StatusPanelItems.Amplitude, PredefinedMessages.WaitUntilAmplitudeTestFinished(pp.Setting.Culture), PredefinedMessages.AmplitudeFailed(pp.Setting.Culture), 4 * 60));
}
else
{
listOfProgrammParts.Add(new AmplitudeTestProcess("Amplitude Test", StatusPanelItems.Amplitude, PredefinedMessages.WaitUntilAmplitudeTestFinished(pp.Setting.Culture), PredefinedMessages.AmplitudeFailed(pp.Setting.Culture), 4 * 60));
}
listOfProgrammParts.Add(new FlushProcess("Second Flush", StatusPanelItems.Amplitude, PredefinedMessages.WaitUntilFlushFinished(pp.Setting.Culture), string.Empty, 2 * 60));
}
listOfProgrammParts.Add(new TemperatureCalibrationProcess("Temperature Calibration", StatusPanelItems.TempCal, PredefinedMessages.WaitUntilTemperatureCalibrationFinished(pp.Setting.Culture), PredefinedMessages.TempCalFailed(pp.Setting.Culture), 2 * 60));
if (!pp.Setting.TempOnly)
if (pp.Setting.NumberOfPaths == 1)
{
listOfProgrammParts.Add(new OffsetTestProcess("Offset Test", StatusPanelItems.Offset, PredefinedMessages.WaitUntilZeroflowOffsetTestFinished(pp.Setting.Culture), PredefinedMessages.ZeroflowOffsetTestFailed(pp.Setting.Culture), 18 * 60));
}
listOfProgrammParts.Add(new CompletionProcess("Completion", StatusPanelItems.Completion, PredefinedMessages.WaitUntilCompletionFinished(pp.Setting.Culture), PredefinedMessages.CompletionFailed(pp.Setting.Culture), 1 * 60));
listOfProgrammParts.Add(new SPTemperatureCalibrationProcess("Temperature Calibration Single", StatusPanelItems.TempCal, PredefinedMessages.WaitUntilTemperatureCalibrationFinished(pp.Setting.Culture), PredefinedMessages.TempCalFailed(pp.Setting.Culture), 2 * 60));
if (!pp.Setting.TempOnly)
{
listOfProgrammParts.Add(new SPOffsetTestProcess("Offset Test Single", StatusPanelItems.Offset, PredefinedMessages.WaitUntilZeroflowOffsetTestFinished(pp.Setting.Culture), PredefinedMessages.ZeroflowOffsetTestFailed(pp.Setting.Culture), 18 * 60));
}
listOfProgrammParts.Add(new SPCompletionProcess("Completion Single", StatusPanelItems.Completion, PredefinedMessages.WaitUntilCompletionFinished(pp.Setting.Culture), PredefinedMessages.CompletionFailed(pp.Setting.Culture), 1 * 60));
}
else
{
listOfProgrammParts.Add(new TemperatureCalibrationProcess("Temperature Calibration", StatusPanelItems.TempCal, PredefinedMessages.WaitUntilTemperatureCalibrationFinished(pp.Setting.Culture), PredefinedMessages.TempCalFailed(pp.Setting.Culture), 2 * 60));
if (!pp.Setting.TempOnly)
{
listOfProgrammParts.Add(new OffsetTestProcess("Offset Test", StatusPanelItems.Offset, PredefinedMessages.WaitUntilZeroflowOffsetTestFinished(pp.Setting.Culture), PredefinedMessages.ZeroflowOffsetTestFailed(pp.Setting.Culture), 18 * 60));
}
listOfProgrammParts.Add(new CompletionProcess("Completion", StatusPanelItems.Completion, PredefinedMessages.WaitUntilCompletionFinished(pp.Setting.Culture), PredefinedMessages.CompletionFailed(pp.Setting.Culture), 1 * 60));
}
var t = new Task(() =>
{
try

View File

@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Text;
using CordonelPreadjustmentUi.Processes.Itinerary;
using System.Threading;
using static CordonelPreadjustmentUi.PreAdjustmentControl;
using System.Threading.Tasks;
namespace CordonelPreadjustmentUi.Processes.Actions
{
public class DemoProcess : BaseProcess
{
public DemoProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage ) : base(processName, panelState, performMessage, failedMessage )
{
}
public override List<Task> StartWork()
{
return doWorkProcess(base.CurrentProcessProgress);
}
private List<Task> doWorkProcess(ProcessProgress pp)
{
var MetersToProcess = MeterStateCtls.Where(e => e.IsEnabled).ToList();
var listOfProcessTask = new List<Task>();
foreach (var meterctl in MetersToProcess)
{
listOfProcessTask.Add(new Task<bool>(() =>
{
var Result = false;
for (int i = 0; i < 3; i++)
{
pp.DebugMessage = $"\tCOMMAND CHANNEL: \t Performing {ProcessName} procedure\n";
try
{
Result = string.IsNullOrEmpty(meterctl.OverridePassword)
? meterctl.Meter.Login()
: meterctl.Meter.Login(meterctl.OverridePassword);
if (Result)
{
break;
}
Thread.Sleep(100);
}
catch (Exception e)
{
pp.DebugMessage = $"\tCOMMAND CHANNEL: \t Error on {ProcessName} procedure\n";
}
}
var meterIndex = (meterctl.Slot).ToString(pp.Setting.Culture);
meterctl.Failed = !Result;
if (!Result)
{
pp.DebugMessage = $"\tCOMMAND CHANNEL: \t {ProcessName} procedure failed at METER{meterIndex}\n";
}
else
{
pp.DebugMessage = $"\tCOMMAND CHANNEL: \t {ProcessName} procedure successful at METER{meterIndex}\n";
pp.GenerateReturnNote($"{meterctl.Slot}", meterctl.Meter.PcbId, PredefinedMessages.LoginFailed(pp.Setting.Culture));
}
return Result;
}));
}
return listOfProcessTask;
}
}
}

View File

@ -0,0 +1,527 @@
using CordonelPreadjustmentUi.Const;
using CordonelPreadjustmentUi.Helper;
using CordonelPreadjustmentUi.Helper.Extensions;
using CordonelPreadjustmentUi.Processes.Itinerary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using static CordonelPreadjustmentUi.PreAdjustmentControl;
namespace CordonelPreadjustmentUi.Processes.Actions
{
public class SPAmplitudeTestProcess : BaseProcess
{
public SPAmplitudeTestProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS) : base(processName, panelState, performMessage, failedMessage, expectedTimeS)
{
}
public override List<Task> StartWork()
{
return doWorkProcess(base.CurrentProcessProgress);
}
private List<Task> doWorkProcess(ProcessProgress pp)
{
var MetersToProcess = MeterStateCtls.Where(e => e.IsEnabled).ToList();
var listOfProcessTask = new List<Task>();
foreach (var meterctl in MetersToProcess)
{
listOfProcessTask.Add(new Task<bool>(() =>
{
pp.DebugMessage($"Performing {ProcessName} procedure", null, "CC");
#region Definitions and initializations
const Int32 FirstHitShiftValue = 4;
const Int32 FirstHitShiftValueEnd = 4;
const Int32 FirstHitUpdatePeriodeValue = 1;
const Int32 FirstHitUpdatePeriodeValueEnd = 10;
const Int32 WaitBeforeLogging = 5;
String DebugMessage = String.Empty;
var TofAvgMean = new MultiPathDataLogContainer<Double>(pp.Setting.NumberOfPaths);
var OptimalPoint = new MultiPathDataLogContainer<Int32>(pp.Setting.NumberOfPaths);
var TofAvgMeanTotal = new MultiPathDataLogContainer<List<Double>>(pp.Setting.NumberOfPaths);
TofAvgMeanTotal.Update(null, new List<Double>());
Boolean Ok = false;
#endregion
#region StartLogging
if (pp.Setting.AmpTestGenerateLogfiles)
{
String time = System.DateTime.Now.ToString(Formats.LogFileDateTimeString);
String Header = $"Genesis ZeroFlowOffsetCalibration {meterctl.Meter.Slot}; PCB ID = {meterctl.Meter.PcbId}; Date = {time}; Operator = {Environment.UserName}\n";
meterctl.Meter.DataLog(Header);
//GenesisZeroFlow._GenesisZeroFlow.SetLoggingPathAmplitudeTest(this.MeterNumber, $"{DataLogging.DefaultPath}AmplitudeTest_RawData_{TempPcbID}_{time}.txt");
meterctl.Meter.logAmpTest = true;
pp.DebugMessage($" Start logging", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
}
#endregion
Ok = false;
Ok = WriteRegisterSafe(meterctl.Meter, "First hit update period", Register.Genesisflow.FirstHitUpdatePeriod, FirstHitUpdatePeriodeValue);
if (CheckAbort(Ok, meterctl)) { return Ok; }
pp.StatusLabel = (PredefinedMessages.WaitUntilRegisterWriteFinished(pp.Setting.Culture));
Ok = false;
Ok = WriteRegisterSafe(meterctl.Meter, "WorkAround TriggerIdle", Register.Genesisflow.TriggerIdle, 1, false);
Thread.Sleep(150);
pp.StatusLabel = (PredefinedMessages.WaitUntilRegisterWriteFinished(pp.Setting.Culture));
Ok = false;
Ok = WriteRegisterSafe(meterctl.Meter, "first hit shift", Register.Genesisflow.FirstHitShift, FirstHitShiftValueEnd);
Thread.Sleep(150);
pp.StatusLabel = (PredefinedMessages.WaitUntilRegisterWriteFinished(pp.Setting.Culture));
Ok = false;
Ok = WriteRegisterSafe(meterctl.Meter, "WorkAround TriggerActive", Register.Genesisflow.TriggerActive, 1, false);
Thread.Sleep(150);
#region Set first hit level percentage from 5 to 35
pp.DebugMessage($"Start first hit level percentage sweep ", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
for (Int32 FirstHitLevelPercentage = pp.Setting.AmpTestPercentageStart; FirstHitLevelPercentage <= pp.Setting.AmpTestPercentageStop; FirstHitLevelPercentage++)
{
if (CheckAbort(Ok, meterctl)) { return Ok; }
pp.StatusLabel = $"{PredefinedMessages.WaitUntilPercentageSweepFinished(pp.Setting.Culture)} {FirstHitLevelPercentage.ToString(pp.Setting.Culture)}/{pp.Setting.AmpTestPercentageStop.ToString(pp.Setting.Culture)}";
#region Write to percentage register PATH0
Ok = false;
Ok = WriteRegisterSafe(meterctl.Meter, "Percentage", Register.Genesisflow.FirstHitPercent2, FirstHitLevelPercentage);
if (CheckAbort(Ok, meterctl)) { return Ok; }
#endregion
#region Wait for 1 second
for (Int32 i = 0; i < WaitBeforeLogging; i++)
{
Thread.Sleep(200);
}
#endregion
#region Record TOF
Ok = RecordData(pp, meterctl, Ok, FirstHitLevelPercentage);
bool retryRecord = false;
if (true)
{
if (!meterctl.Meter.listOfTotalTimeOfFlightSPerPath.Get(1).Any())
{
pp.StatusLabel = $"No Data for Path {1}. Start one recollect";
retryRecord = true;
}
}
else
{
//for (UInt16 Path = 0; Path < meterctl.Meter.listOfTotalTimeOfFlightSPerPath.GetPathCount(); Path++)
//{
// if (!meterctl.Meter.listOfTotalTimeOfFlightSPerPath.Get(Path).Any())
// {
// pp.StatusLabel = $"No Data for Path {Path}. Start one recollect";
// retryRecord = true;
// }
//}
}
if (retryRecord)
{
Ok = RecordData(pp, meterctl, Ok, FirstHitLevelPercentage);
}
pp.StatusLabel = $"{PredefinedMessages.WaitUntilPercentageSweepFinished(pp.Setting.Culture)} {FirstHitLevelPercentage.ToString(pp.Setting.Culture)}/{ pp.Setting.AmpTestPercentageStop.ToString(pp.Setting.Culture)}; 0s";
Ok = true;
#endregion
#region Calculate mean value
UInt16 Path = 1;
var meanVal = meterctl.Meter.listOfTotalTimeOfFlightSPerPath.Get(Path).ToList().Mean();
pp.DebugMessage($"Calculate mean value {meanVal} at {meterctl.Meter.Slot}; PATH{(Path + 1).ToString(pp.Setting.Culture)}", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
//earlier TofAvgMeanTotal
//TofAvgMean.Update(Path, meanVal);
if (meanVal == 0)
{
pp.DebugMessage($"Mean value is zero at {meterctl.Meter.Slot}; PATH{(Path + 1).ToString(pp.Setting.Culture)}; Value = {Math.Round(meanVal, 4).ToString("000.0000", pp.Setting.Culture)}", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
meterctl.Meter.calibrationResult.AddAdditionalLog($"" +
$"PATH {Path + 1}", Math.Round(meanVal, 4).ToString("000.0000", pp.Setting.Culture));
if (CheckAbort(false, meterctl)) { return false; }
}
pp.DebugMessage($"Mean value at {meterctl.Meter.Slot}; PATH{(Path + 1).ToString(pp.Setting.Culture)}; Value = {Math.Round(meanVal, 4).ToString("000.0000", pp.Setting.Culture)}", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
meterctl.Meter.calibrationResult.AddAdditionalLog($"Amp. Test Mean value PATH {Path + 1}", $"at {FirstHitLevelPercentage}={Math.Round(meanVal, 4).ToString("000.0000", pp.Setting.Culture)}");
var cTofAvgMeanTotal = TofAvgMeanTotal.Get(0).ToList();
cTofAvgMeanTotal.Add(meanVal);
TofAvgMeanTotal.Update(0, cTofAvgMeanTotal);
//meterctl.Meter.listOfTotalTimeOfFlightSPerPath.Update(Path,new List<Double>());
#endregion
}
#endregion
#region Write raw data to files
//if (this.GenerateLogFiles)
//{
// GenesisZeroFlow._GenesisZeroFlow.SetLoggingIndicatorAmpTest(this.MeterNumber, false);
// String temp = GenesisZeroFlow._GenesisZeroFlow.GetDataToLog()[this.MeterNumber];
// pp.DebugMessage =$"{meterctl.Meter.PcbId}\tAPPLICATION:\t\t Write data to files at {meterctl.Meter.Slot}\n";
// Logging.WriteToFile(temp, GenesisZeroFlow._GenesisZeroFlow.GetLoggingPathAmplitudeTest()[this.MeterNumber]);
//}
#endregion
#region Write mean values to file
//String DateTime = System.DateTime.Now.ToString(Formats.LogFileDateTimeString;
//if (this.GenerateMeanFiles)
//{
// for (UInt16 Path = Constants.PATH0; Path < Constants.NumberOfPaths; Path++)
// Logging.WriteToFile(GenesisZeroFlow._GenesisZeroFlow.GetAmpValuesToLog()[this.MeterNumber][Constants.PATH0], $@"..\ZeroflowCalibrationTool_MeanAmplitude_{meterctl.Meter.Slot}_PATH{Path + 1}_{TempPcbID}_{DateTime}.csv");
//}
//this.ClearData();
//#endregion
#region Calculate optimal point
var DistanceLeft = new MultiPathDataLogContainer<double>(pp.Setting.NumberOfPaths);
var DistanceRight = new MultiPathDataLogContainer<double>(pp.Setting.NumberOfPaths);
var CalculationFailed = new MultiPathDataLogContainer<bool>(pp.Setting.NumberOfPaths);
pp.DebugMessage($"Start calculating optimal points", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
for (UInt16 Path = 0; Path < TofAvgMeanTotal.GetPathCount(); Path++)
{
var tmpOptimalPoint = 0;
var tmpDistanceLeft = 0.0;
var tmpDistanceRight = 0.0;
var r = CalculateOptimalPoint(pp, meterctl.Meter.Slot, TofAvgMeanTotal.Get(Path).ToList(), out tmpDistanceLeft, out tmpDistanceRight, out tmpOptimalPoint);
OptimalPoint.Update(Path, tmpOptimalPoint);
DistanceLeft.Update(Path, tmpDistanceLeft);
DistanceRight.Update(Path, tmpDistanceRight);
CalculationFailed.Update(Path, r);
if (!r)
{
meterctl.Meter.calibrationResult.AddAdditionalLog($"Amp. Test OptimalPoint PATH {Path + 1}", OptimalPoint.Get(Path).ToString(pp.Setting.Culture));
pp.DebugMessage($"Optimal point calculation successful PATH{Path + 1}; Value = {OptimalPoint.Get(Path).ToString(pp.Setting.Culture)}", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
}
else
{
meterctl.Meter.calibrationResult.AddAdditionalLog($"Amp. Test OptimalPoint PATH {Path + 1}", "NaN");
pp.DebugMessage($"Optimal point calculation failed, PATH{Path + 1}", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
if (CheckAbort(!r, meterctl)) { return !r; }
}
}
#endregion
#region Check value
pp.DebugMessage($"Start optimal point values check", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
Boolean OptimalPointOK = true;
for (UInt16 Path = 0; Path < OptimalPoint.GetPathCount(); Path++)
{
if (!this.CheckOptimalPoint(pp, OptimalPoint.Get(Path), out DebugMessage, meterctl.Meter.Slot))
{
OptimalPointOK = false;
}
pp.DebugMessage($"{DebugMessage}, PATH{Path + 1}", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
}
if (CheckAbort(OptimalPointOK, meterctl)) { return OptimalPointOK; }
#endregion
#region Check distance
Boolean CheckDistOK = true;
for (UInt16 Path = 0; Path < DistanceLeft.GetPathCount(); Path++)
{
if (!this.CheckDistance(pp, DistanceLeft.Get(Path), DistanceRight.Get(Path), out DebugMessage, meterctl.Meter.Slot))
{
CheckDistOK = false;
}
pp.DebugMessage($"{DebugMessage}, PATH{Path + 1}", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
}
if (CheckAbort(CheckDistOK, meterctl)) { return CheckDistOK; }
#endregion
#region Set first hit level percentage registers
pp.DebugMessage($"Start writing to percentage registers", meterctl.Meter.Slot, "CC", meterctl.Meter.PcbId);
pp.StatusLabel = ($"{PredefinedMessages.WaitUntilRegisterWriteFinished(pp.Setting.Culture)}");
Ok = false;
String RegValue = Register.Genesisflow.FirstHitPercent2;
Ok = WriteRegisterSafe(meterctl.Meter, "Percentage", RegValue, OptimalPoint.Get(0));
if (CheckAbort(Ok, meterctl)) { return Ok; }
#endregion
//here
#region Set first hit update period to 10
pp.StatusLabel = (PredefinedMessages.WaitUntilRegisterWriteFinished(pp.Setting.Culture));
Ok = false;
Ok = WriteRegisterSafe(meterctl.Meter, "first hit update period", Register.Genesisflow.FirstHitUpdatePeriod, FirstHitUpdatePeriodeValueEnd);
if (CheckAbort(Ok, meterctl)) { return Ok; }
#endregion
#region Wait for 1 second
for (Int32 i = 0; i < WaitBeforeLogging; i++)
{
Thread.Sleep(300);
}
#endregion
#region Set first hit shift to 4
//Frost, Alex <AFrost@sentec.co.uk> Do 02.07.2020 17:12
//RE: Writing 4 to 'First hit shift'-register failed
//I think a workaround would be to go into idle mode before changing this register then back to active mode after.I havent tried this out yet
pp.StatusLabel = (PredefinedMessages.WaitUntilRegisterWriteFinished(pp.Setting.Culture));
Ok = false;
Ok = WriteRegisterSafe(meterctl.Meter, "WorkAround TriggerIdle", Register.Genesisflow.TriggerIdle, 1, false);
Thread.Sleep(150);
pp.StatusLabel = (PredefinedMessages.WaitUntilRegisterWriteFinished(pp.Setting.Culture));
Ok = false;
Ok = WriteRegisterSafe(meterctl.Meter, "first hit shift", Register.Genesisflow.FirstHitShift, FirstHitShiftValueEnd);
Thread.Sleep(150);
pp.StatusLabel = (PredefinedMessages.WaitUntilRegisterWriteFinished(pp.Setting.Culture));
Ok = false;
Ok = WriteRegisterSafe(meterctl.Meter, "WorkAround TriggerActive", Register.Genesisflow.TriggerActive, 1, false);
Thread.Sleep(150);
if (CheckAbort(Ok, meterctl)) { return Ok; }
#endregion
#endregion
return Ok;
}));
}
return listOfProcessTask;
}
private bool RecordData(ProcessProgress pp, MeterStateControl meterctl, bool Ok, int FirstHitLevelPercentage)
{
meterctl.Meter.listOfTotalTimeOfFlightSPerPath.Update(null, new List<Double>());
meterctl.Meter.logAmpTest = true;
pp.DebugMessage($"Start collecting data", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
var LinecounterFollowing = new MultiPathDataLogContainer<Int32>(pp.Setting.NumberOfPaths);
for (Int32 Seconds = 0; Seconds < pp.Setting.AmpTestTofRecordingTime; Seconds++) // eight seconds remove /2
{
if (Int32.Equals((Seconds % pp.Setting.AmpTestActivityCheckInverval), 0))
{
pp.StatusLabel = $"{PredefinedMessages.WaitUntilPercentageSweepFinished(pp.Setting.Culture)} {FirstHitLevelPercentage.ToString(pp.Setting.Culture)}/{ pp.Setting.AmpTestPercentageStop.ToString(pp.Setting.Culture)}; {(pp.Setting.AmpTestTofRecordingTime - Seconds).ToString(pp.Setting.Culture)}s";
Thread.Sleep(1000);
Ok = ActivityCheck(pp, meterctl.Meter.listOfTotalTimeOfFlightSPerPath, pp.Setting.AmpTestTofRecordingTime);
if (!Ok)
{
pp.DebugMessage($"Activity check failed", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
// if (CheckAbort(Ok, meterctl)) { return Ok; }
}
}
}
return Ok;
}
private Boolean CalculateOptimalPoint(ProcessProgress pp, int Slot, List<Double> TofAvg, out Double left, out Double right, out Int32 xAtOptimalPoint)
{
List<Double> ValuesLeft = new List<Double>();
List<Double> ValuesRight = new List<Double>();
List<Double> MinDistance = new List<Double>();
xAtOptimalPoint = 0;
Boolean SubError = true;
left = 0;
right = 0;
ValuesLeft = this.CalculateNearestDistanceLeft(pp, TofAvg, out left);
ValuesRight = this.CalculateNearestDistanceRight(pp, TofAvg, out right);
for (UInt16 i = 0; i < ValuesLeft.Count(); i++)
{
Double temp1 = ValuesLeft.ElementAt(i);
Double temp2 = ValuesRight.ElementAt(i);
Thread.Sleep(10);
MinDistance.Add(Math.Min(temp1, temp2));
}
//String mindistance = $"mindistance: PATH{path.ToString(GlobalCulture)}\n";
//for (Int16 i = 0; i < MinDistance.Count(); i++)
//{
// Double temp = MinDistance.ElementAt(i);
// Misc.WaitNMilliseconds(10);
// mindistance = $"{mindistance}{temp.ToString(GlobalCulture)}\n";
//}
//Logging.WriteToFile(mindistance, @"..\mindistance_PATH"+ path.ToString() + ".txt");
Double Maximum = 0;
for (Int16 i = 0; i < MinDistance.Count(); i++)
{
if ((!Int16.Equals(i, 0)) && (!Int16.Equals(i, (Int16)(TofAvg.Count() - 1))))
{
if (MinDistance.ElementAt(i) > Maximum)
{
Maximum = MinDistance.ElementAt(i);
xAtOptimalPoint = (Int32)i + pp.Setting.AmpTestPercentageStart;
;
SubError = false;
}
}
}
return SubError;
}
private List<Double> CalculateNearestDistanceLeft(ProcessProgress pp, List<Double> TofAvg, out Double left)
{
List<Double> Distance = new List<Double>();
Double NearestDistance = 0;
Boolean Detected = false;
left = 0;
for (Int32 Percentage = pp.Setting.AmpTestFirstHitLevelPropMin; Percentage <= pp.Setting.AmpTestFirstHitLevelPropMax; Percentage++)
{
Detected = false;
for (Int32 PercentageFollowing = Percentage; PercentageFollowing <= pp.Setting.AmpTestFirstHitLevelPropMax; PercentageFollowing++)
{
if ((TofAvg.ElementAt(PercentageFollowing - pp.Setting.AmpTestFirstHitLevelPropMin) - TofAvg.ElementAt(Percentage - pp.Setting.AmpTestFirstHitLevelPropMin)) > pp.Setting.AmpTestTriggerValue)
{
NearestDistance = PercentageFollowing - Percentage;
Detected = true;
break;
}
}
if (!Detected)
{
NearestDistance = pp.Setting.AmpTestFirstHitLevelPropMax - Percentage;
}
Distance.Add(NearestDistance);
}
for (Int16 i = 0; i < (Int16)Distance.Count(); i++)
{
if (Distance.ElementAt(i) >= left)
{
left = Distance.ElementAt(i);
}
}
return Distance;
}
private List<Double> CalculateNearestDistanceRight(ProcessProgress pp, List<Double> TofAvg, out Double right)
{
List<Double> Distance = new List<Double>();
Double NearestDistance = 0;
Boolean Detected = false;
right = 0;
for (Int32 Percentage = pp.Setting.AmpTestFirstHitLevelPropMax; Percentage >= (pp.Setting.AmpTestFirstHitLevelPropMin); Percentage--)
{
Detected = false;
for (Int32 ProportionFollowing = Percentage; ProportionFollowing >= pp.Setting.AmpTestFirstHitLevelPropMin; ProportionFollowing--)
{
if ((TofAvg.ElementAt(ProportionFollowing - pp.Setting.AmpTestFirstHitLevelPropMin)) - (TofAvg.ElementAt(Percentage - pp.Setting.AmpTestFirstHitLevelPropMin)) < -pp.Setting.AmpTestTriggerValue)
{
NearestDistance = Percentage - ProportionFollowing;
Detected = true;
break;
}
}
if (!Detected)
{
NearestDistance = Percentage - pp.Setting.AmpTestFirstHitLevelPropMin;
}
Distance.Add(NearestDistance);
}
Distance.Reverse();
for (Int16 i = 0; i < Distance.Count(); i++)
{
if (Distance.ElementAt(i) >= right)
{
right = Distance.ElementAt(i);
}
}
return Distance;
}
private Boolean CheckOptimalPoint(ProcessProgress pp, Int32 optimalPoint, out String debugMessage, int Slot)
{
Boolean Ok = true;
debugMessage = $"Optimal point check successful at {Slot}";
// ampTestLowerLimit, ampTestUpperLimit, ampTestDistance
if (optimalPoint > pp.Setting.AmpTestFirstHitLevelPropMax)
{
debugMessage = $"Optimal point maximum check failed at {Slot}";
Ok = false;
return Ok;
}
if (optimalPoint < pp.Setting.AmpTestFirstHitLevelPropMin)
{
debugMessage = $"Optimal point minimum check failed at {Slot}";
Ok = false;
return Ok;
}
return Ok;
}
private Boolean CheckDistance(ProcessProgress pp, Double left, Double right, out String debugMessage, int Slot)
{
Boolean Ok = true;
debugMessage = $"Distance check successful at {Slot}";
if (left < pp.Setting.AmpTestFirstHitLevelPropMin)
{
Ok = false;
debugMessage = $"Distance check failed at {Slot}";
return Ok;
}
if (right < pp.Setting.AmpTestFirstHitLevelPropMin)
{
Ok = false;
debugMessage = $"Distance check failed at {Slot}";
return Ok;
}
return Ok;
}
}
}

View File

@ -0,0 +1,189 @@
using CordonelPreadjustmentUi.Processes.Itinerary;
using Logic.ProductionToProductMapper.Cordonel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Xylem.Common.CommonCore.Configuration;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Consts;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts;
using Xylem.Common.Logic.SoftwareAccessHelper;
using static CordonelPreadjustmentUi.PreAdjustmentControl;
namespace CordonelPreadjustmentUi.Processes.Actions
{
public class SPCompletionProcess : BaseProcess
{
public SPCompletionProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS) : base(processName, panelState, performMessage, failedMessage, expectedTimeS)
{
}
public override List<Task> StartWork()
{
return doWorkProcess(base.CurrentProcessProgress);
}
private List<Task> doWorkProcess(ProcessProgress pp)
{
var MetersToProcess = MeterStateCtls.Where(e => e.IsEnabled).ToList();
var listOfProcessTask = new List<Task>();
foreach (var meterctl in MetersToProcess)
{
listOfProcessTask.Add(new Task<bool>(() =>
{
var Result = true;
pp.DebugMessage($"Performing {ProcessName} procedure", null, "APP");
try
{
var Ok = false;
Ok = WriteRegisterSafe(meterctl.Meter, $"Samplerate", Register.Genesisflow.SampleRate, 10);
if (CheckAbort(Ok, meterctl)) { return Ok; }
Ok = WriteRegisterSafe(meterctl.Meter, $"LED mode", Register.Genesisflow.LedMode, (Byte)6);
if (CheckAbort(Ok, meterctl)) { return Ok; }
Ok = WriteRegisterSafe(meterctl.Meter, $"Store calibration", Register.Genesisflow.StoreCalibration, 1, false);
if (CheckAbort(Ok, meterctl)) { return Ok; }
pp.DebugMessage($"Read out", meterctl.Slot, "CC");
var readsOk = new List<bool>();
byte[] retByte;
readsOk.Add(ReadRegister(meterctl.Meter, "MeterSize", Register.Genesisflow.MeterSize, out retByte));
meterctl.Meter.calibrationResult.MeterSize = RegisterConverter.ByteArrayToValue<ushort>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "CalFactor1", Register.Genesisflow.CalFactor1, out retByte));
meterctl.Meter.calibrationResult.CalFactor1 = RegisterConverter.ByteArrayToValue<uint>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "CalFactor2", Register.Genesisflow.CalFactor2, out retByte));
meterctl.Meter.calibrationResult.CalFactor2 = RegisterConverter.ByteArrayToValue<uint>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "CalFactor3", Register.Genesisflow.CalFactor3, out retByte));
meterctl.Meter.calibrationResult.CalFactor3 = RegisterConverter.ByteArrayToValue<uint>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "ZeroOffset1", Register.Genesisflow.ZeroOffset1, out retByte));
meterctl.Meter.calibrationResult.ZeroOffset1 = RegisterConverter.ByteArrayToValue<int>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "ZeroOffset2", Register.Genesisflow.ZeroOffset2, out retByte));
meterctl.Meter.calibrationResult.ZeroOffset2 = RegisterConverter.ByteArrayToValue<int>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "ZeroOffset3", Register.Genesisflow.ZeroOffset3, out retByte));
meterctl.Meter.calibrationResult.ZeroOffset3 = RegisterConverter.ByteArrayToValue<int>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "FirstHitUpdatePeriod", Register.Genesisflow.FirstHitUpdatePeriod, out retByte));
meterctl.Meter.calibrationResult.FirstHitUpdatePeriod = RegisterConverter.ByteArrayToValue<ushort>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "FirstHitShift", Register.Genesisflow.FirstHitShift, out retByte));
meterctl.Meter.calibrationResult.FirstHitShift = RegisterConverter.ByteArrayToValue<ushort>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "FirstHitPercent1", Register.Genesisflow.FirstHitPercent1, out retByte));
meterctl.Meter.calibrationResult.FirstHitPercent1 = RegisterConverter.ByteArrayToValue<ushort>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "FirstHitPercent2", Register.Genesisflow.FirstHitPercent2, out retByte));
meterctl.Meter.calibrationResult.FirstHitPercent2 = RegisterConverter.ByteArrayToValue<ushort>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "FirstHitPercent3", Register.Genesisflow.FirstHitPercent3, out retByte));
meterctl.Meter.calibrationResult.FirstHitPercent3 = RegisterConverter.ByteArrayToValue<ushort>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "ToFTempOffset1", Register.Genesisflow.ToFTempOffset1, out retByte));
meterctl.Meter.calibrationResult.ToFTempOffset1 = RegisterConverter.ByteArrayToValue<int>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "ToFTempOffset2", Register.Genesisflow.ToFTempOffset2, out retByte));
meterctl.Meter.calibrationResult.ToFTempOffset2 = RegisterConverter.ByteArrayToValue<int>(retByte);
readsOk.Add(ReadRegister(meterctl.Meter, "ToFTempOffset3", Register.Genesisflow.ToFTempOffset3, out retByte));
meterctl.Meter.calibrationResult.ToFTempOffset3 = RegisterConverter.ByteArrayToValue<int>(retByte);
if (readsOk.Any(a => !a))
{
Ok = false;
}
if (CheckAbort(Ok, meterctl)) { return Ok; }
Exception exPost = new Exception();
int code = 0;
var tempP = "";
if (meterctl.Meter.calibrationResult.AdditionalLogInfos.TryGetValue("Amp. Test Mean value PATH 1", out tempP))
{
tempP = tempP.Replace(" at ", "").Replace("at ", "");
tempP = tempP.Replace(System.Environment.NewLine, ";");
meterctl.Meter.calibrationResult.AdditionalLogInfos["Amp. Test Mean value PATH 1"] = tempP;
}
if (meterctl.Meter.calibrationResult.AdditionalLogInfos.TryGetValue("Amp. Test Mean value PATH 2", out tempP))
{
tempP = tempP.Replace(" at ", "").Replace("at ", ""); ;
tempP = tempP.Replace(System.Environment.NewLine, ";");
meterctl.Meter.calibrationResult.AdditionalLogInfos["Amp. Test Mean value PATH 2"] = tempP;
}
if (meterctl.Meter.calibrationResult.AdditionalLogInfos.TryGetValue("Amp. Test Mean value PATH 3", out tempP))
{
tempP = tempP.Replace(" at ", "").Replace("at ", ""); ;
tempP = tempP.Replace(System.Environment.NewLine, ";");
meterctl.Meter.calibrationResult.AdditionalLogInfos["Amp. Test Mean value PATH 3"] = tempP.Trim();
}
var r = LocalWebRequest.PostRequestAsync($"{ServiceUrls.PostGenesisCalibrationResultUrl()}?PcbId={meterctl.Meter.PcbId}", ref code, ref exPost, 8000, meterctl.Meter.calibrationResult);
if (!r)
{
meterctl.Meter.WriteLog($"Could not store CalibrationResults on server CODE {code}EX:{exPost} ");
foreach (var item in meterctl.Meter.calibrationResult.AdditionalLogInfos)
{
meterctl.Meter.WriteLog($"AdditionalLogInfos {item.Key} -> {item.Value} ");
}
throw new Exception("Could not store CalibrationResults on server");
}
if (pp.IsAutomaticMode)
{
// meterctl.Meter.SetProcessState(Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts.DisplayCodes.ZeroFlow);
}
}
catch (Exception e)
{
pp.DebugMessage($"Error on {ProcessName} procedure", null, "APP");
pp.DebugMessage($"{e.Message}", null, "APP");
}
var meterIndex = (meterctl.Slot).ToString(pp.Setting.Culture);
meterctl.Failed = !Result;
if (!Result)
{
if (pp.IsAutomaticMode)
{
meterctl.Meter.SetProcessState(DisplayCodes.ZeroFlowFailed);
}
pp.DebugMessage($"{ProcessName} procedure failed", meterctl.Slot, "APP", meterctl.Meter.PcbId);
pp.GenerateReturnNote(PredefinedMessages.CompletionFailed(pp.Setting.Culture), meterctl);
}
else
{
pp.DebugMessage($"{ProcessName} procedure successful", meterctl.Slot, "APP", meterctl.Meter.PcbId);
if (pp.IsAutomaticMode)
{
//meterctl.Meter.SetProcessState(Xylem.Common.Hardware.WaterMeter.WaterMeterCore.Consts.DisplayCodes.ZeroFlow);
}
}
meterctl.Meter.PushProgress("CordonelPreadjustmentUi", Assembly.GetExecutingAssembly().GetName().Version.ToString());
return Result;
}));
}
return listOfProcessTask;
}
}
}

View File

@ -0,0 +1,290 @@
using CordonelPreadjustmentUi.Helper;
using CordonelPreadjustmentUi.Processes.Itinerary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Ui.CordonelPreadjustmentUi.Helper.Extensions;
using static CordonelPreadjustmentUi.PreAdjustmentControl;
namespace CordonelPreadjustmentUi.Processes.Actions
{
public class SPOffsetTestProcess : BaseProcess
{
public SPOffsetTestProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS) : base(processName, panelState, performMessage, failedMessage, expectedTimeS)
{
}
public override List<Task> StartWork()
{
return doWorkProcess(base.CurrentProcessProgress);
}
private List<Task> doWorkProcess(ProcessProgress pp)
{
var MetersToProcess = MeterStateCtls.Where(e => e.IsEnabled).ToList();
var listOfProcessTask = new List<Task>();
listOfProcessTask.Add(new Task<bool>(() =>
{
#region Wait for settling time (60s)
for (Int32 Time = pp.Setting.OffsetTestSettlingTime; Time >= 0; Time--)
{
if (CheckAbort(true)) { return false; }
pp.StatusLabel = $"{PredefinedMessages.ZeroflowOffsetWaitForSettling(pp.Setting.Culture)}{Time.ToString(pp.Setting.Culture)}";
Thread.Sleep(1000);
}
#endregion
var listOfSubTask = new List<Task>();
foreach (var meterctl in MetersToProcess)
{
meterctl.Meter.CurrentRecords.Clear();
listOfSubTask.Add(new Task<bool>(() =>
{
var Ok = true;
Boolean PerformCheck = true;
//Timeout calculation for offset test
//(pp.Setting.OffsetTestNumberOfLines * number of path) / 1000
//((9000 * 3) / 1000 ) = 27 min
var pataDataActivitCheck = new MultiPathDataLogContainer<int>(pp.Setting.NumberOfPaths);
var MaxTimeoutWarnings = 300;
pataDataActivitCheck.Update(null, -1);
Thread.Sleep(1800);
var Path = 1;
while (PerformCheck)
{
var offsetRecords = new List<CalibrationRecord>();
try
{
offsetRecords = meterctl.Meter.CurrentRecords.ToList();
}
catch (Exception ex)
{
try
{
offsetRecords = meterctl.Meter.CurrentRecords.ToList();
}
catch (Exception)
{
Ok = false;
PerformCheck = false;
}
}
pp.StatusLabel = ($"{PredefinedMessages.ZeroflowOffsetAqqFinished(pp.Setting.Culture)} {offsetRecords.Count}/{(pp.Setting.OffsetTestNumberOfLines * 3)}"); // "Wait until data aquisition has finished:"
Thread.Sleep(1800);//
var PathSum = 1;
var currentCount = offsetRecords.Count(c => c.Channel == PathSum + 1);// immer 2
var oldCound = pataDataActivitCheck.Get(0);// immer 0
if (currentCount <= oldCound + 1)
{
pp.DebugMessage($"Warn! Receive no new lines on path {PathSum}", meterctl.Slot, "DC", meterctl.Meter.PcbId);
MaxTimeoutWarnings = MaxTimeoutWarnings - 1;
}
pataDataActivitCheck.Update(0, currentCount);
//todo:enable timeout and canneclation token
if (MaxTimeoutWarnings <= 0)
{
pp.DebugMessage($"Fatal timeout while collecting data. Please check LED singnal. Has {offsetRecords.Count} from {pp.Setting.OffsetTestNumberOfLines * 3}", meterctl.Slot, "DC", meterctl.Meter.PcbId);
// Ok = false;
}
if (CheckAbort(Ok, meterctl)) { return Ok; }
bool testDone = true;
var lstPathRecords = offsetRecords.Where(c => c.Channel == Path + 1).ToList();
if (lstPathRecords.Count(v => !v.IsValid) > pp.Setting.OffsetTestNumberOfLines * 0.1)
{
pp.DebugMessage($" To many bad data Packages {meterctl.Meter.Slot}; PATH {Path + 1}; Linecounter = {lstPathRecords.Count}", null, "DC");
Ok = false;
break;
}
if (lstPathRecords.Count < pp.Setting.OffsetTestNumberOfLines)
{
testDone = false;
}
if (testDone)
{
Ok = true;
PerformCheck = false;
}
if (CheckAbort(Ok, meterctl)) { return Ok; }
}
var PathDataContainerBaddata = new MultiPathDataLogContainer<List<CalibrationRecord>>(pp.Setting.NumberOfPaths);
var PathDataContainer = new MultiPathDataLogContainer<List<CalibrationRecord>>(pp.Setting.NumberOfPaths);
var offsetRecordsB = meterctl.Meter.CurrentRecords.ToList().Where(c => (c.Channel == (Path + 1)) && c.IsValid).ToList();
PathDataContainer.Update(Path, offsetRecordsB);
offsetRecordsB = meterctl.Meter.CurrentRecords.ToList().Where(c => (c.Channel == (Path + 1)) && !c.IsValid).ToList();
PathDataContainerBaddata.Update(Path, offsetRecordsB);
#region Calculating mean values
pp.DebugMessage($"Calculating mean values", meterctl.Meter.Slot, "APP", meterctl.Meter.PcbId);
var amplitudeValuesMeanUp = new MultiPathDataLogContainer<double>(pp.Setting.NumberOfPaths);
var amplitudeValuesMeanDown = new MultiPathDataLogContainer<double>(pp.Setting.NumberOfPaths);
var DeltaTimeOfFlightAverage = new MultiPathDataLogContainer<double>(pp.Setting.NumberOfPaths);
var meanAmplitudeUpV = PathDataContainer.Get(Path).Sum(ad => ad.AmplitudeUpV) / PathDataContainer.Get(Path).Count;
var meanAmplitudeDownV = PathDataContainer.Get(Path).Sum(ad => ad.AmplitudeDownV) / PathDataContainer.Get(Path).Count;
var avgDeltaTimeOfFlight = PathDataContainer.Get(Path).Sum(ad => ad.DeltaTimeOfFlightS) / PathDataContainer.Get(Path).Count;
if (meanAmplitudeUpV == 0 || meanAmplitudeDownV == 0 || avgDeltaTimeOfFlight == 0)
{
pp.DebugMessage($"Mean value is zero at {meterctl.Meter.Slot}; PATH{Path + 1}", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
if (pp.Setting.NumberOfPaths != 1)
{
Ok = false;
}
}
if (CheckAbort(Ok, meterctl)) { return Ok; }
amplitudeValuesMeanUp.Update(Path, meanAmplitudeUpV);
amplitudeValuesMeanDown.Update(Path, meanAmplitudeDownV);
DeltaTimeOfFlightAverage.Update(Path, avgDeltaTimeOfFlight);
#endregion
var BadDataCheckOK = true;
var AmplitudeCheckOK = true;
var OffsetCheckOK = true;
pp.DebugMessage($"Bad data at PATH{Path + 1}:{PathDataContainerBaddata.Get(Path).Count()}", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
if (PathDataContainerBaddata.Get(Path).Count() > pp.Setting.OffsetTestBadDataLimit)
{
BadDataCheckOK = false;
pp.DebugMessage($"Bad datacheck failed!", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
}
pp.DebugMessage($"Average positive amplitude, PATH{(Path + 1)}: {Math.Round(amplitudeValuesMeanUp.Get(Path), 2).ToString("000.00")}mV", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
pp.DebugMessage($"Average negative amplitude, PATH{(Path + 1)}: {Math.Round(amplitudeValuesMeanDown.Get(Path), 2).ToString("000.00")}mV", meterctl.Meter.Slot, "DC", meterctl.Meter.PcbId);
meterctl.Meter.calibrationResult.AddAdditionalLog($"Offset Average positive amplitude PATH { (Path + 1)}", $"{ Math.Round(amplitudeValuesMeanUp.Get(Path), 2).ToString("000.00")}mV");
meterctl.Meter.calibrationResult.AddAdditionalLog($"Offset Average negative amplitude PATH { (Path + 1)}", $"{ Math.Round(amplitudeValuesMeanDown.Get(Path), 2).ToString("000.00")}mV");
if ((amplitudeValuesMeanUp.Get(Path) > pp.Setting.OffsetTestUpperVoltageLimitMV) ||
(amplitudeValuesMeanUp.Get(Path) < pp.Setting.OffsetTestLowerVoltageLimitMV) ||
(amplitudeValuesMeanDown.Get(Path) < pp.Setting.OffsetTestLowerVoltageLimitMV) ||
(amplitudeValuesMeanDown.Get(Path) > pp.Setting.OffsetTestUpperVoltageLimitMV))
{
AmplitudeCheckOK = false;
pp.DebugMessage($"Amplitude check failed!", meterctl.Meter.Slot, "APP", meterctl.Meter.PcbId);
}
pp.DebugMessage($"Average delta time of flight valuePATH{(Path + 1)}: Raw{DeltaTimeOfFlightAverage.Get(Path)} -> in picoseconds= { Math.Round((DeltaTimeOfFlightAverage.Get(Path) / (Math.Pow(2, 38) * Math.Pow(10, 12))), 2).ToString("000.00")}", meterctl.Meter.Slot, "APP", meterctl.Meter.PcbId);
meterctl.Meter.calibrationResult.AddAdditionalLog($"Offset Average delta time of flight value PATH { (Path + 1)} RAW ", $"{DeltaTimeOfFlightAverage.Get(Path)}");
meterctl.Meter.calibrationResult.AddAdditionalLog($"Offset Average delta time of flight value PATH { (Path + 1)} picoseconds ", $"{Math.Round((DeltaTimeOfFlightAverage.Get(Path) / (Math.Pow(2, 38) * Math.Pow(10, 12))), 2).ToString("000.00")}");
if ((DeltaTimeOfFlightAverage.Get(Path) > pp.Setting.OffsetTestOffsetLimitPS) ||
(DeltaTimeOfFlightAverage.Get(Path) < -pp.Setting.OffsetTestOffsetLimitPS))
{
pp.DebugMessage($"Delta time of flight check failed", meterctl.Meter.Slot, "APP", meterctl.Meter.PcbId);
OffsetCheckOK = false;
}
if (!BadDataCheckOK
|| !AmplitudeCheckOK
|| !OffsetCheckOK)
{
pp.DebugMessage($"Skip offset test at least one test is failed", meterctl.Meter.Slot, "APP", meterctl.Meter.PcbId);
if (pp.Setting.NumberOfPaths != 1)
{
if (CheckAbort(false, meterctl)) { return false; }
}
}
Ok = meterctl.Meter.ReLogin();
if (CheckAbort(Ok, meterctl)) { return Ok; }
var OffsetValue = (Int32)((DeltaTimeOfFlightAverage.Get(Path) * Math.Pow(2, 40)));
pp.StatusLabel = ($"{PredefinedMessages.WaitUntilRegisterWriteFinished(pp.Setting.Culture)}");
String RegValue = String.Empty;
switch (Path)
{
case 0:
RegValue = Register.Genesisflow.ZeroOffset1;
break;
case 1:
RegValue = Register.Genesisflow.ZeroOffset2;
break;
case 2:
RegValue = Register.Genesisflow.ZeroOffset3;
break;
default:
RegValue = Register.Genesisflow.ZeroOffset1;
break;
};
if (pp.Setting.NumberOfPaths != 1)
{
Ok = WriteRegisterSafe(meterctl.Meter, $"Zero flow offset Path {Path + 1}", RegValue, OffsetValue);
if (CheckAbort(Ok, meterctl)) { return Ok; }
}
else
{
Ok = WriteRegisterSafe(meterctl.Meter, $"Zero flow offset Path {Path + 1}", RegValue, OffsetValue);
Ok = true;
}
return Ok;
}));
}
listOfSubTask.ForEach(t => t.Start());
while (listOfSubTask.Any(t => !t.IsCompleted))
{
Thread.Sleep(1000);
}
return true;
}));
return listOfProcessTask;
}
}
}

View File

@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Text;
using CordonelPreadjustmentUi.Processes.Itinerary;
using System.Threading;
using static CordonelPreadjustmentUi.PreAdjustmentControl;
using System.Threading.Tasks;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Logic.SoftwareAccessHelper;
using Xylem.Common.CommonCore.Configuration;
using Newtonsoft.Json;
namespace CordonelPreadjustmentUi.Processes.Actions
{
public class SPPreparationProcess : BaseProcess
{
public SPPreparationProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS) : base(processName, panelState, performMessage, failedMessage, expectedTimeS)
{
}
public override List<Task> StartWork()
{
return doWorkProcess(base.CurrentProcessProgress);
}
private List<Task> doWorkProcess(ProcessProgress pp)
{
var MetersToProcess = MeterStateCtls.Where(e => e.IsEnabled).ToList();
//MetersToProcess.AddRange(TempMeterStateCtls.Where(e => e.IsEnabled));
var listOfProcessTask = new List<Task>();
foreach (var item in TempMeterStateCtls.Where(e => e.IsEnabled))
{
listOfProcessTask.Add(new Task<bool>(() =>
{
item.Meter.StartRecordData();
return true;
}));
}
foreach (var meterctl in MetersToProcess)
{
listOfProcessTask.Add(new Task<bool>(() =>
{
meterctl.Id = string.IsNullOrEmpty(meterctl.Meter.PcbId) ? "Unknown" : $"Pcb:{meterctl.Meter.PcbId}";
meterctl.Meter.StartRecordData();
Boolean Ok = false;
if (pp.Setting.NumberOfPaths > 0)
{
Ok = WriteRegisterSafe(meterctl.Meter, "Calibration factor1", Register.Genesisflow.CalFactor1, pp.Setting.CalFactor1);
if (CheckAbort(Ok, meterctl)) { return Ok; }
}
if (pp.Setting.NumberOfPaths > 1)
{
Ok = WriteRegisterSafe(meterctl.Meter, "Calibration factor2", Register.Genesisflow.CalFactor2, pp.Setting.CalFactor2);
if (CheckAbort(Ok, meterctl)) { return Ok; }
}
if (pp.Setting.NumberOfPaths > 2)
{
Ok = WriteRegisterSafe(meterctl.Meter, "Calibration factor3", Register.Genesisflow.CalFactor3, pp.Setting.CalFactor3);
if (CheckAbort(Ok, meterctl)) { return Ok; }
}
if (pp.Setting.doOffsetTest)
{
if (pp.Setting.NumberOfPaths > 0)
{
Ok = WriteRegisterSafe(meterctl.Meter, "Zeroflow offset1", Register.Genesisflow.ZeroOffset1, pp.Setting.ZeroOffset1);
if (CheckAbort(Ok, meterctl)) { return Ok; }
}
if (pp.Setting.NumberOfPaths > 1)
{
Ok = WriteRegisterSafe(meterctl.Meter, "Zeroflow offset2", Register.Genesisflow.ZeroOffset2, pp.Setting.ZeroOffset2);
if (CheckAbort(Ok, meterctl)) { return Ok; }
}
if (pp.Setting.NumberOfPaths > 2)
{
Ok = WriteRegisterSafe(meterctl.Meter, "Zeroflow offset3", Register.Genesisflow.ZeroOffset3, pp.Setting.ZeroOffset3);
if (CheckAbort(Ok, meterctl)) { return Ok; }
}
}
meterctl.Meter.calibrationResult.AddAdditionalLog($"OffsetTestNumberOfLines", pp.Setting.OffsetTestNumberOfLines.ToString());
meterctl.Meter.calibrationResult.AddAdditionalLog($"Samplerate", pp.Setting.Samplerate.ToString());
Ok = WriteRegisterSafe(meterctl.Meter, "Samplerate", Register.Genesisflow.SampleRate, pp.Setting.Samplerate);
if (CheckAbort(Ok, meterctl)) { return Ok; }
if (pp.Setting.Production)
{
Ok = WriteRegisterSafe(meterctl.Meter, "Metersize", Register.Genesisflow.MeterSize, pp.Setting.MeterSize.GetHashCode(), false);
if (CheckAbort(Ok, meterctl)) { return Ok; }
}
else
{
WriteRegisterSafe(meterctl.Meter, "Metersize", Register.Genesisflow.MeterSize, pp.Setting.MeterSize.GetHashCode(), false);
if (CheckAbort(Ok, meterctl)) { return Ok; }
}
Ok = WriteRegisterSafe(meterctl.Meter, "LED mode", Register.Genesisflow.LedMode, pp.Setting.LedMode.GetHashCode());
if (CheckAbort(Ok, meterctl)) { return Ok; }
Ok = WriteRegisterSafe(meterctl.Meter, "TriggerActive", Register.Genesisflow.TriggerActive, 1, false);
if (CheckAbort(Ok, meterctl)) { return Ok; }
if (CheckAbort(Ok, meterctl)) { return Ok; }
var r = LocalWebRequest.GetRequest($"{ ServiceUrls.GenesisFinalCheckServiceUrl()}GetMetersizeProgrammingData?MeterSize={pp.Setting.MeterSize.GetHashCode()}", 2000);
var dt = JsonConvert.DeserializeObject<Dictionary<string, UInt32>>(r);
foreach (var item in dt)
{
Ok = meterctl.Meter.WriteRegisterUnsafe(item.Key, item.Value);
if (CheckAbort(Ok, meterctl)) { return Ok; }
}
return Ok;
}));
}
return listOfProcessTask;
}
private static byte[] ReservandFill(byte[] b)
{
return b.Reverse().ToArray();
}
}
}

View File

@ -0,0 +1,290 @@
using CordonelPreadjustmentUi.Processes.Itinerary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Ui.CordonelPreadjustmentUi.Helper.Extensions;
using static CordonelPreadjustmentUi.PreAdjustmentControl;
namespace CordonelPreadjustmentUi.Processes.Actions
{
public class SPTemperatureCalibrationProcess : BaseProcess
{
public SPTemperatureCalibrationProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS) : base(processName, panelState, performMessage, failedMessage, expectedTimeS)
{
}
public override List<Task> StartWork()
{
return doWorkProcess(base.CurrentProcessProgress);
}
private List<Task> doWorkProcess(ProcessProgress pp)
{
#region Wait for settling time (60s)
for (Int32 Time = pp.Setting.OffsetTestSettlingTime; Time >= 0; Time--)
{
pp.StatusLabel = $"{PredefinedMessages.ZeroflowOffsetWaitForSettling(pp.Setting.Culture)}{Time.ToString(pp.Setting.Culture)}";
Thread.Sleep(1000);
}
#endregion
var MetersToProcess = MeterStateCtls.Where(e => e.IsEnabled).ToList();
var listOfProcessTask = new List<Task>();
pp.StatusLabel = (PredefinedMessages.WaitUntilTemperatureAcquisitionFinished(pp.Setting.Culture));
bool skipMan = false;
if (pp.Setting.GetTempUseTempFlansh() || TempMeterStateCtls.Any(a => a.IsEnabled))
{
skipMan = false;
//aoutmatic
decimal avgTemp = 0;
int TempFlanshCount = 0;
var listOFEnabledTempMeters = TempMeterStateCtls.Where(a => a.IsEnabled).ToList();
foreach (var avgTempCtls in listOFEnabledTempMeters)
{
var check = avgTempCtls.GetTemperature();
if (check > 5 && (double)check != 25.0d )
{
avgTemp = avgTemp + avgTempCtls.GetTemperature();
TempFlanshCount = TempFlanshCount + 1;
skipMan = true;
}
}
if (TempFlanshCount == 0)
{
System.Windows.Forms.MessageBox.Show("Fehler beim auslesen der TemperaturFlansche. Bitte per Hand eingeben");
skipMan = false;
pp.RequestTempretureSelection();
}
else
{
avgTemp = avgTemp / TempFlanshCount;
foreach (var meterctl in MetersToProcess)
{
meterctl.SetTemperature(avgTemp);
}
}
}
if (!skipMan)
{
//manual input
foreach (var meterctl in MetersToProcess)
{
meterctl.SetTemperature((decimal)0);
}
pp.RequestTemperatur();
foreach (var meterctl in TempMeterStateCtls)
{
meterctl.SetTemperature((decimal)0);
meterctl.OnTempretureChangedHandler += delegate (Object sender, EventArgsDecimal d)
{
decimal avgTemp = 0;
foreach (var tempMeter in TempMeterStateCtls)
{
avgTemp = avgTemp + tempMeter.GetTemperature();
}
avgTemp = avgTemp / TempMeterStateCtls.Count;
foreach (var updateMeter in MetersToProcess)
{
updateMeter.SetTemperature(avgTemp);
}
};
}
}
pp.DebugMessage($"Performing {ProcessName} procedure");
listOfProcessTask.Add(new Task<bool>(() =>
{
pp.RequestTempretureSelection();
while (!pp.TempretureSelected)
{
Thread.Sleep(100);
}
if (pp.Setting.GetTempUsePtOverSps() && pp.PushedTestBenchTemp.HasValue)
{
foreach (var updateMeter in MetersToProcess)
{
updateMeter.SetTemperature(Convert.ToDecimal(pp.PushedTestBenchTemp.Value));
}
}
var listOfSubTasks = new List<Task<bool>>();
foreach (var disableTempInputMeter in MetersToProcess)
{
disableTempInputMeter.DisableTemperatureinput(true);
}
foreach (var disableTempInputMeter in TempMeterStateCtls)
{
disableTempInputMeter.DisableTemperatureinput(true);
}
foreach (var putTempIntoMeter in MetersToProcess)
{
listOfSubTasks.Add(new Task<bool>(() =>
{
var originTemp = putTempIntoMeter.GetTemperature();
if (originTemp == (decimal)25.0 || originTemp == (decimal)1 || originTemp == (decimal)0)
{
pp.DebugMessage($"Temperature check failed - default", putTempIntoMeter.Meter.Slot, "APP", putTempIntoMeter.Meter.PcbId);
return false;
}
UInt32 TempToRegister = (UInt32)(originTemp * 4096);
#region Set temperature calibration register
var Ok = false;
pp.StatusLabel = PredefinedMessages.WaitUntilRegisterWriteFinished(pp.Setting.Culture);
Ok = WriteRegisterSafe(putTempIntoMeter.Meter, "Temperature calibration", Register.Genesisflow.ToFTempCalibrate, TempToRegister, false);
if (CheckAbort(Ok, putTempIntoMeter)) { return Ok; }
putTempIntoMeter.Meter.calibrationResult.AddAdditionalLog($"Temperature calibration Register", TempToRegister.ToString());
putTempIntoMeter.Meter.calibrationResult.AddAdditionalLog($"Temperature calibration Origin", originTemp.ToString());
#endregion
#region Wait for some seconds
const UInt16 WaitingTime = 10;
putTempIntoMeter.Meter.listOfTotalTimeOfFlightSPerPath.Update(null, new List<Double>());
putTempIntoMeter.Meter.CurrentRecords.Clear();
putTempIntoMeter.Meter.logAmpTest = true;
for (Int32 Seconds = 0; Seconds < WaitingTime; Seconds++) // eight seconds remove /2
{
Ok = ActivityCheck(pp, putTempIntoMeter.Meter.listOfTotalTimeOfFlightSPerPath, Seconds);
if (CheckAbort(Ok, putTempIntoMeter))
{
pp.DebugMessage($"Activity check failed", putTempIntoMeter.Meter.Slot, "DC", putTempIntoMeter.Meter.PcbId);
return Ok;
}
pp.StatusLabel = $"{PredefinedMessages.WaitSeconds(Seconds, pp.Setting.Culture)}";
Thread.Sleep(1000);
}
#endregion
#region Check temperature
putTempIntoMeter.Meter.CurrentRecords.Clear();
putTempIntoMeter.Meter.logAmpTest = true;
Thread.Sleep(1000);
var tmpTempCheckRecords = putTempIntoMeter.Meter.CurrentRecords.ToList();
if (tmpTempCheckRecords.Any())
{
var checkTempMeter = (decimal)tmpTempCheckRecords.Average(a => a.TemperatureDegC);
var sbTemp = new StringBuilder();
sbTemp.AppendLine(
$"Ref. temp = {Math.Round(originTemp, 2).ToString("00.00", pp.Setting.Culture)}°C vs. Meter temp = {checkTempMeter}°C at {putTempIntoMeter.Meter.Slot}");
if (Math.Abs(originTemp - checkTempMeter) > (decimal)pp.Setting.TempDeviationLimit)
{
pp.DebugMessage($"Temperature check failed", putTempIntoMeter.Meter.Slot, "APP", putTempIntoMeter.Meter.PcbId);
Ok = false;
}
if (CheckAbort(Ok, putTempIntoMeter)) { return Ok; }
pp.DebugMessage($"Temperature check OK", putTempIntoMeter.Meter.Slot, "APP", putTempIntoMeter.Meter.PcbId);
#endregion
#region Get 'TOF offset' registers
if (pp.Setting.NumberOfPaths > 0)
{
byte[] rawResult;
Ok = ReadRegister(putTempIntoMeter.Meter, "TOF offset1", Register.Genesisflow.ToFTempOffset1, out rawResult);
if (CheckAbort(Ok, putTempIntoMeter)) { return Ok; }
if (rawResult != null)
{
var tmp = BitConverter.ToInt32(rawResult, 0);
}
}
if (pp.Setting.NumberOfPaths > 1)
{
byte[] rawResult;
Ok = ReadRegister(putTempIntoMeter.Meter, "TOF offset2", Register.Genesisflow.ToFTempOffset2, out rawResult);
if (CheckAbort(Ok, putTempIntoMeter)) { return Ok; }
if (rawResult != null)
{
var tmp = BitConverter.ToInt32(rawResult, 0);
}
}
if (pp.Setting.NumberOfPaths > 2)
{
byte[] rawResult;
Ok = ReadRegister(putTempIntoMeter.Meter, "TOF offset3", Register.Genesisflow.ToFTempOffset3, out rawResult);
if (CheckAbort(Ok, putTempIntoMeter)) { return Ok; }
if (rawResult != null)
{
var tmp = BitConverter.ToInt32(rawResult, 0);
}
}
#endregion
putTempIntoMeter.SetWatcher((decimal)pp.Setting.LowerTempLimit, (decimal)pp.Setting.UpperTempLimit, (decimal)pp.Setting.TempDeviationLimit);
putTempIntoMeter.StartTempWatch();
return true;
}
else
{
pp.DebugMessage($"Temperature check failed - No Records", putTempIntoMeter.Meter.Slot, "APP", putTempIntoMeter.Meter.PcbId);
return false;
}
}));
}
listOfSubTasks.ForEach(t => t.Start());
while (!listOfSubTasks.All(t => t.IsCompleted))
{
Thread.Sleep(5);
}
return true;
}));
return listOfProcessTask;
}
}
}

View File

@ -211,7 +211,7 @@ namespace CordonelPreadjustmentUi
{
if (e is CalibDataEventArgs)
{
var decodedDate = (CalibDataEventArgs)e;
var data = decodedDate.CalibChl;
if (Slot == 10 && data.Channel == 2)

View File

@ -0,0 +1,44 @@
//using CordonelPreadjustmentUi.Const;
//using CordonelPreadjustmentUi.Helper;
//using Logic.ProductionToProductMapper.Cordonel;
//using System;
//using System.Collections.Concurrent;
//using System.Collections.Generic;
//using System.Globalization;
//using System.Linq;
//using System.Threading;
//using Logic.ProductionToProductMapper.Cordonel;
//using Xylem.Common.CommonCore.Consts;
//using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
//using Xylem.Common.Hardware.Interfaces.Protocols.ProtocolCore.EventArguments;
//using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.EventArguments;
//using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords;
//using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig;
//using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
//using Xylem.Common.Ui.CordonelPreadjustmentUi.Helper.Extensions;
//namespace CordonelPreadjustmentUi
//{
// public class ZeroFlowSinglePathMeter : ZeroFlowGenesisMeter
// {
// public ZeroFlowSinglePathMeter(int Slot, int PathsCount = 3, bool ignorCurruptdata = true) : base()
// {
// //base.SetupFromConfigFile(Slot, ignorCurruptdata);
// ////base.EnableAutoLogon();
// //base.Setup(PathsCount);
// ////on zeroflow every param has to be stored
// //Configuration.UseRegisterWatchService = true;
// //Configuration.RegisterWatchServiceUrl = Xylem.Common.CommonCore.Configuration.ServiceUrls.RegisterWatchServiceUrl();
// }
// }
//}

View File

@ -21,6 +21,7 @@ namespace Xylem.Common.Logic.ProductionOrderCore.OrderData
{
customerSr = scan.Substring(0, scan.IndexOf(",", StringComparison.Ordinal));
}
if (scan.StartsWith(prefix))
{
@ -71,6 +72,11 @@ namespace Xylem.Common.Logic.ProductionOrderCore.OrderData
internalSerialNr = retCustom;
return true;
}
if (scan.Replace(" ", "").Length == 12)
{
customerSr = scan.Replace(" ", "");
}
throw new ApplicationException("Could not parse serial number");
}