einpfad
This commit is contained in:
parent
c31c863d6d
commit
97c68b8fe3
@ -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" />
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 };
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -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 haven’t 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -211,7 +211,7 @@ namespace CordonelPreadjustmentUi
|
||||
{
|
||||
if (e is CalibDataEventArgs)
|
||||
{
|
||||
|
||||
|
||||
var decodedDate = (CalibDataEventArgs)e;
|
||||
var data = decodedDate.CalibChl;
|
||||
if (Slot == 10 && data.Channel == 2)
|
||||
|
||||
44
Common/CordonelPreadjustmentUi/ZeroFlowSinglePathMeter.cs
Normal file
44
Common/CordonelPreadjustmentUi/ZeroFlowSinglePathMeter.cs
Normal 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();
|
||||
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// }
|
||||
//}
|
||||
@ -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");
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user