OMNI testen on 2020
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
<add key="PSNR" value="2015"/>
|
||||
<add key="Type" value="T2" />
|
||||
<add key="COMPorts" value="COM4" />
|
||||
<!--<add key="ExchangeHubURL" value="http://sla12iis01.emea.sensus.net/LaaProductionWeb" />-->
|
||||
<add key="ExchangeHubURL" value="http://localhost:52822/LaaProductionWeb"/>
|
||||
<add key="ExchangeHubURL" value="http://sla12iis01.emea.sensus.net/LaaProductionWeb" />
|
||||
<!--<add key="ExchangeHubURL" value="http://localhost:52822/LaaProductionWeb"/>-->
|
||||
<add key="OmniDB" value="Server=SLASQL01.emea.sensus.net; Database=AuftragKopie; User ID=sa; Password=sqlserver;" />
|
||||
</appSettings>
|
||||
</configuration>
|
||||
@@ -2,7 +2,6 @@
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -10,6 +9,7 @@
|
||||
|
||||
using OmniPlus;
|
||||
using OmniPlus.Features;
|
||||
using OmniPlus.Features.Enums;
|
||||
using OmniPlus.Inspection;
|
||||
|
||||
using OMNIPruefung.ViewModels.Base;
|
||||
@@ -127,12 +127,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
public int AvailableIn { get; set; }
|
||||
|
||||
public OMNIPlusVM Meter { get; }
|
||||
|
||||
internal void CancelExecution()
|
||||
{
|
||||
this.Dispose();
|
||||
|
||||
this.State = "Prüfung abgebrochen.";
|
||||
this.Connected = false;
|
||||
this.Running = false;
|
||||
@@ -140,7 +140,7 @@
|
||||
|
||||
internal Task InitializeAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.Dispose);
|
||||
cancellationToken.Register(this.CancelExecution);
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
@@ -163,7 +163,7 @@
|
||||
|
||||
if (this.IsRunning())
|
||||
{
|
||||
this.State = "Mit IRDA verbunden";
|
||||
this.State = "Verbunden";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -181,12 +181,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
return Task.Factory.StartNew(Initialize, cancellationToken);
|
||||
return this.StartNew(Initialize, cancellationToken);
|
||||
}
|
||||
|
||||
internal Task ReadSystemParametersAsync(CancellationToken cancelationToken)
|
||||
{
|
||||
cancelationToken.Register(this.Dispose);
|
||||
cancelationToken.Register(this.CancelExecution);
|
||||
|
||||
void ReadSystemParameters()
|
||||
{
|
||||
@@ -216,12 +216,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
return Task.Factory.StartNew(ReadSystemParameters, cancelationToken);
|
||||
return this.StartNew(ReadSystemParameters, cancelationToken);
|
||||
}
|
||||
|
||||
internal Task SetInputVolumeAsync(OmniPlusType defaults, CancellationToken cancelationToken)
|
||||
{
|
||||
cancelationToken.Register(this.Dispose);
|
||||
cancelationToken.Register(this.CancelExecution);
|
||||
|
||||
void SetInputVolume()
|
||||
{
|
||||
@@ -232,6 +232,8 @@
|
||||
|
||||
if (this.Running)
|
||||
{
|
||||
this.Meter.Add(defaults.InputVolume);
|
||||
|
||||
this.State = "Flow-Eigenschaften konfiguriert";
|
||||
}
|
||||
else
|
||||
@@ -247,87 +249,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
return Task.Factory.StartNew(SetInputVolume, cancelationToken);
|
||||
}
|
||||
|
||||
internal Task SetReferenceVolumeAsync(OmniPlusTestPoint pp, double referenceV, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.Dispose);
|
||||
|
||||
void SetReferenceVolume()
|
||||
{
|
||||
if (this.results.ContainsKey(pp))
|
||||
{
|
||||
this.results[pp].VolumeMessured = referenceV;
|
||||
}
|
||||
}
|
||||
|
||||
return Task.Factory.StartNew(SetReferenceVolume, cancellationToken);
|
||||
}
|
||||
|
||||
internal Task SaveInspectionAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.Dispose);
|
||||
|
||||
void SaveInspection()
|
||||
{
|
||||
if (!this.IsRunning())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var resultsBuilder = new StringBuilder();
|
||||
|
||||
resultsBuilder.AppendLine($"GPM\t"
|
||||
+ $"m³/h\t"
|
||||
+ $"ml/R\t"
|
||||
+ $"R(soll)\t"
|
||||
+ $"R(ist)\t"
|
||||
+ $"T(soll)\t"
|
||||
+ $"T(ist)\t"
|
||||
+ $"m³(ist)\t"
|
||||
+ $"Diff %\t"
|
||||
+ $"Factor %\t"
|
||||
+ $"Min\t"
|
||||
+ $"Max\t");
|
||||
|
||||
foreach (var kvp in this.results)
|
||||
{
|
||||
var pruefpunkt = kvp.Key;
|
||||
var ergebnis = kvp.Value;
|
||||
|
||||
resultsBuilder.AppendLine($"{pruefpunkt.GalPerMin:0.00}\t"
|
||||
+ $"{pruefpunkt.VolumeM3H:0.00}\t"
|
||||
+ $"{pruefpunkt.MlPerRotation:0.00}\t"
|
||||
+ $"{pruefpunkt.Rotations}\t"
|
||||
+ $"{ergebnis.Rotations}\t"
|
||||
+ $"{pruefpunkt.Duration}\t"
|
||||
+ $"{ergebnis.Duration}\t"
|
||||
+ $"{ergebnis.VolumeMessured}\t"
|
||||
+ $"{ergebnis.DifferencePercentage:0.00}%\t"
|
||||
+ $"{this.GetCorrectionFactor():0.00}%\t"
|
||||
+ $"{pruefpunkt.MinDiff:0.00}\t"
|
||||
+ $"{pruefpunkt.MaxDiff:0.00}\t");
|
||||
}
|
||||
|
||||
this.TestResults = resultsBuilder.ToString();
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText($"{this.Header}_{DateTime.Now:yyyyMMddHHmmss}.csv", this.TestResults);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.State = e.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
return Task.Factory.StartNew(SaveInspection, cancellationToken);
|
||||
return this.StartNew(SetInputVolume, cancelationToken);
|
||||
}
|
||||
|
||||
internal Task StartPPCalibrationAsync(OmniPlusTestPoint pp, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.Dispose);
|
||||
cancellationToken.Register(this.CancelExecution);
|
||||
|
||||
void StartPPCalibration()
|
||||
{
|
||||
@@ -340,6 +267,8 @@
|
||||
var activationResponse = connection.StartChamberCalibration(pp.Rotations, pp.Duration);
|
||||
this.Running = activationResponse.Succeeded && activationResponse.Control == ChamberCalibrationResponse.TEST_ACTIVATED;
|
||||
|
||||
this.Meter.Add(pp);
|
||||
|
||||
if (this.Running)
|
||||
{
|
||||
this.State = $"PP {rotations}/{duration} (rotations/seconds) wurde gestarted.";
|
||||
@@ -353,12 +282,12 @@
|
||||
this.Progress += 10;
|
||||
}
|
||||
|
||||
return Task.Factory.StartNew(StartPPCalibration, cancellationToken);
|
||||
return this.StartNew(StartPPCalibration, cancellationToken);
|
||||
}
|
||||
|
||||
internal Task StopPPCalibrationAsync(OmniPlusTestPoint pp, CancellationToken cancellationToken)
|
||||
internal Task StopPPCalibrationAsync(OmniPlusTestPoint pp, double referenceV, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.Dispose);
|
||||
cancellationToken.Register(this.CancelExecution);
|
||||
|
||||
void StopPPCalibration()
|
||||
{
|
||||
@@ -366,11 +295,14 @@
|
||||
{
|
||||
var calibrationResult = connection.ViewChamberCalibration();
|
||||
this.results[pp].Rotations = calibrationResult.Rotations;
|
||||
this.results[pp].Duration = calibrationResult.Duration;
|
||||
this.results[pp].Duration = calibrationResult.DurationSec;
|
||||
this.results[pp].MeterVolume = pp.VolumeM3(this.results[pp]);
|
||||
this.results[pp].VolumeMessured = referenceV;
|
||||
|
||||
this.Running = calibrationResult.Succeeded && calibrationResult.Control == ChamberCalibrationResponse.TEST_COMPLETED;
|
||||
|
||||
this.Meter.Add(this.results[pp]);
|
||||
|
||||
if (this.Running)
|
||||
{
|
||||
this.State = $"PP {pp.Rotations}/{pp.Duration} (rotations/seconds) wurde durchgeführt.";
|
||||
@@ -384,7 +316,201 @@
|
||||
this.Progress += 10;
|
||||
}
|
||||
|
||||
return Task.Factory.StartNew(StopPPCalibration, cancellationToken);
|
||||
return this.StartNew(StopPPCalibration, cancellationToken);
|
||||
}
|
||||
|
||||
internal Task FinishInspectionAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.CancelExecution);
|
||||
|
||||
void FinishInspection()
|
||||
{
|
||||
if (!this.IsRunning())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var configurationParameters = this.connection.ViewConfigurationParameters();
|
||||
var canContinue = configurationParameters.Succeeded;
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
this.Meter.Add(configurationParameters);
|
||||
// TODO: Uncomment in production
|
||||
// var systemTimeReset = connection.SetSystemTime();
|
||||
//canContinue = systemTimeReset.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var registerSettings = new RegisterSettings();
|
||||
|
||||
registerSettings.IntPart = this.Meter.IntPart;
|
||||
registerSettings.Fraction = this.Meter.Fraction;
|
||||
registerSettings.Size = this.Meter.Size;
|
||||
registerSettings.Range = this.Meter.Range;
|
||||
registerSettings.VolumePerPulseUnit = 0x00;
|
||||
registerSettings.MeterUnits = (byte)MessurementUnits.USGallons;
|
||||
registerSettings.FlowUnits = (byte)MessurementUnits.USGallons;
|
||||
registerSettings.FlowRate = (byte)TimeUnits.Minutes;
|
||||
registerSettings.FactoryCorrection = this.Meter.FactoryCorrection;
|
||||
registerSettings.FieldCorrection = 0x00;
|
||||
registerSettings.PulseWeight = 0x01;
|
||||
registerSettings.PulseWidth = 0x02;
|
||||
registerSettings.PulseUpdate = 0x00;
|
||||
|
||||
var response = this.connection.Set(registerSettings);
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var configurationParametersSet = new ConfigurationParametersSet();
|
||||
configurationParametersSet.ProgrammableID = this.Meter.BuildInfo;
|
||||
configurationParametersSet.FactoryID = this.Meter.BuildInfo;
|
||||
configurationParametersSet.NumberOfReadingDigits = 8;
|
||||
configurationParametersSet.ReadingPreset = "000000000";
|
||||
configurationParametersSet.OptionalUniDirFields = 1;
|
||||
configurationParametersSet.AlarmPercistancePeriodDays = 31;
|
||||
configurationParametersSet.DataLogIntervalMinutes = 60;
|
||||
configurationParametersSet.ManifacturingTime = Epoch20000101.UTCNow - 30000;
|
||||
configurationParametersSet.SystemTime = Epoch20000101.UTCNow;
|
||||
configurationParametersSet.RebootCount = 0;
|
||||
configurationParametersSet.BuildInfo = this.Meter.BuildInfo;
|
||||
|
||||
var response = this.connection.Set(configurationParametersSet);
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.ClearDisplay();
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.Set(new LeakAlarm
|
||||
{
|
||||
FlowRateGal = 0.25F, // 0.25 gpm
|
||||
TimeLimit = 24 * 60 * 60 // 24 hours => 86400sec
|
||||
});
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.Set(new HighFlowAlarm
|
||||
{
|
||||
FlowRateGal = 25F, // 25 gpm
|
||||
TimeLimit = 1 * 60 * 60 // 1 hours => 86400sec
|
||||
});
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.Set(new ReverseFlowAlarm
|
||||
{
|
||||
FlowRateGal = -1F, // -1 gpm
|
||||
TimeLimit = 60 // 1 hours => 86400sec
|
||||
});
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.ClearAlarms();
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var alarmsState = this.connection.ViewAlarmsState();
|
||||
canContinue = alarmsState.Succeeded;
|
||||
//&& alarmsState.UsrEnabled
|
||||
//&& alarmsState.PreEnabledInactive;
|
||||
//TODO: Check alarms
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.EnableNFC();
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var registerSettingsAfter = this.connection.ViewRegisterSettings();
|
||||
//canContinue = registerSettingsAfter.Succeeded
|
||||
// && meter.Compare(registerSettingsAfter);
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var systemParametersAfter = this.connection.ViewSystemParameters();
|
||||
canContinue = systemParametersAfter.Succeeded;
|
||||
//&& meter.Compare(systemParametersAfter);
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var configurationParametersAfter = this.connection.ViewConfigurationParameters();
|
||||
canContinue = configurationParametersAfter.Succeeded;
|
||||
//&& meter.Compare(configurationParametersAfter);
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var alarmsState = this.connection.ViewAlarmsState();
|
||||
canContinue = alarmsState.Succeeded;
|
||||
//&& alarmsState.UsrEnabled
|
||||
//&& alarmsState.PreEnabledInactive;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.ViewAlarmSettings(0x01);
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.ViewAlarmSettings(0x02);
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.ViewAlarmSettings(0x04);
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
if (canContinue)
|
||||
{
|
||||
//connection.Set(new FactorySeal
|
||||
//{
|
||||
// Sealed = true,
|
||||
//});
|
||||
|
||||
//var factorySeal = connection.ViewFactorySeal();
|
||||
//canContinue = factorySeal.Succeeded && factorySeal.Sealed;
|
||||
}
|
||||
|
||||
this.Progress = 100;
|
||||
}
|
||||
|
||||
return this.StartNew(FinishInspection, cancellationToken);
|
||||
}
|
||||
|
||||
internal void SaveInspection(StringBuilder results)
|
||||
{
|
||||
if (results.Length <= 1)
|
||||
{
|
||||
results.AppendLine(string.Join(";", this.Meter.Results.Select(x => x.Key)));
|
||||
}
|
||||
|
||||
results.AppendLine(string.Join(";", this.Meter.Results.Select(x => x.Value)));
|
||||
}
|
||||
|
||||
internal double GetCorrectionFactor()
|
||||
@@ -404,23 +530,12 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
this.SaveInspectionAsync(CancellationToken.None).Wait();
|
||||
|
||||
this.connection?.Disconnect();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.State = e.Message;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.results.Clear();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.State = e.Message;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsRunning()
|
||||
@@ -434,5 +549,19 @@
|
||||
|
||||
return this.Connected;
|
||||
}
|
||||
|
||||
private Task StartNew(Action action, CancellationToken cancellationToken, int counter = 3)
|
||||
{
|
||||
return Task
|
||||
.Factory
|
||||
.StartNew(action, cancellationToken);
|
||||
//.ContinueWith(task =>
|
||||
//{
|
||||
// if (task.Status == TaskStatus.Faulted && counter > 0)
|
||||
// {
|
||||
// StartNew(action, cancellationToken, counter - 1).Wait();
|
||||
// }
|
||||
//});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
@@ -37,6 +39,7 @@
|
||||
{
|
||||
this.Header = "EOL";
|
||||
this.CanStart = true;
|
||||
this.CanCheck = true;
|
||||
this.Option = new EOLOptionVM(this);
|
||||
this.OmniDefaults = new OmniPlusType();
|
||||
|
||||
@@ -49,6 +52,7 @@
|
||||
this.LoadComPorts = new Command(this.PrepareConnections);
|
||||
this.CancelInspection = new Command(this.CancelInspectionHandler);
|
||||
this.StartInspection = new Command(this.StartInspectionHandler);
|
||||
this.CheckInspection = new Command(this.CheckInspectionHandler);
|
||||
|
||||
this.Option.OptionSelected += this.NotifyOptionSelected;
|
||||
|
||||
@@ -127,6 +131,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
private bool canCheck;
|
||||
public bool CanCheck
|
||||
{
|
||||
get => this.canCheck;
|
||||
set
|
||||
{
|
||||
this.canCheck = value;
|
||||
|
||||
this.NotifyPropertyChanged(nameof(this.CanCheck));
|
||||
}
|
||||
}
|
||||
|
||||
private bool canStop;
|
||||
public bool CanStop
|
||||
{
|
||||
@@ -171,8 +187,23 @@
|
||||
|
||||
public ICommand StartInspection { get; }
|
||||
|
||||
public ICommand CheckInspection { get; }
|
||||
|
||||
private string errorLog;
|
||||
private void PrepareConnections()
|
||||
{
|
||||
try
|
||||
{
|
||||
var directory = Directory.CreateDirectory(".\\Results");
|
||||
this.errorLog = Path.Combine(directory.FullName, $"errors.txt");
|
||||
|
||||
File.AppendAllText(this.errorLog, string.Empty);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.State = e.ToString();
|
||||
}
|
||||
|
||||
this.exchangeConnection.Disconnect();
|
||||
this.exchangeConnection.Connect(this.hubsettings.ExchangeHubURL);
|
||||
|
||||
@@ -271,14 +302,13 @@
|
||||
this.State = default(string);
|
||||
}
|
||||
|
||||
this.InvokeAsync(() =>
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
this.WaitUntil(this.AvailableIn, show: true, error: true);
|
||||
|
||||
this.CanStart = true;
|
||||
|
||||
this.Error = default(string);
|
||||
this.State = default(string);
|
||||
}, wait: false);
|
||||
});
|
||||
}
|
||||
|
||||
private void StartInspectionHandler()
|
||||
@@ -289,8 +319,11 @@
|
||||
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
this.cancellationToken = this.cancellationTokenSource.Token;
|
||||
|
||||
var metersVM = this.Nodes.Cast<COMContentVM>();
|
||||
|
||||
this.cancellationToken.Register(() => this.canceled = true);
|
||||
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
@@ -303,7 +336,7 @@
|
||||
|
||||
foreach (var pp in this.OmniDefaults.TestPoints)
|
||||
{
|
||||
if (this.cancellationTokenSource?.IsCancellationRequested == true)
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -313,6 +346,11 @@
|
||||
|
||||
this.StartFlow(pp.VolumeM3H);
|
||||
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
@@ -322,48 +360,165 @@
|
||||
});
|
||||
|
||||
this.StartReferenceMessurement(duration);
|
||||
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
this.WaitUntil((int)(duration * 1.2), true, false);
|
||||
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var referenceV = this.GetReferenceVolume();
|
||||
|
||||
if (this.cancellationTokenSource?.IsCancellationRequested == true)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.StopPPCalibrationAsync(pp, cancellationToken));
|
||||
tasks.Add(meterVM.StopPPCalibrationAsync(pp, referenceV, cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
if (this.cancellationTokenSource?.IsCancellationRequested == true)
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.exchangeConnection.SendStopFlow();
|
||||
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
meterVM.GetCorrectionFactor();
|
||||
}
|
||||
|
||||
var results = new StringBuilder();
|
||||
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
meterVM.SaveInspection(results);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var directory = Directory.CreateDirectory(".\\Results");
|
||||
var file = Path.Combine(directory.FullName, $"Results_{DateTime.Now:yyyyMMddHHmmss}.csv");
|
||||
|
||||
File.WriteAllText(file, results.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.State = e.ToString();
|
||||
}
|
||||
|
||||
if (!this.canceled)
|
||||
{
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.SetReferenceVolumeAsync(pp, referenceV, cancellationToken));
|
||||
tasks.Add(meterVM.FinishInspectionAsync(cancellationToken));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.exchangeConnection.SendStopReferenceMessurement(default(double));
|
||||
this.exchangeConnection.SendStopFlow();
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
meterVM.Dispose();
|
||||
}
|
||||
|
||||
this.WaitUntil(this.AvailableIn, show: true);
|
||||
|
||||
this.CanStart = true;
|
||||
this.Error = default(string);
|
||||
this.State = default(string);
|
||||
}, this.cancellationToken);
|
||||
}
|
||||
|
||||
private void CheckInspectionHandler()
|
||||
{
|
||||
this.canceled = false;
|
||||
this.CanStart = false;
|
||||
this.CanStop = true;
|
||||
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
this.cancellationToken = this.cancellationTokenSource.Token;
|
||||
|
||||
var metersVM = this.Nodes.Cast<COMContentVM>();
|
||||
|
||||
this.cancellationToken.Register(() => this.canceled = true);
|
||||
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.SaveInspectionAsync(cancellationToken));
|
||||
tasks.Add(meterVM.SetInputVolumeAsync(this.OmniDefaults, cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
foreach (var pp in this.OmniDefaults.TestPoints)
|
||||
{
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var rotations = pp.Rotations;
|
||||
var duration = pp.Duration;
|
||||
|
||||
this.StartFlow(pp.VolumeM3H);
|
||||
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.StartPPCalibrationAsync(pp, cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
this.StartReferenceMessurement(duration);
|
||||
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
this.WaitUntil((int)(duration * 1.2), true, false);
|
||||
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var referenceV = this.GetReferenceVolume();
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.StopPPCalibrationAsync(pp, referenceV, cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.exchangeConnection.SendStopFlow();
|
||||
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
meterVM.GetCorrectionFactor();
|
||||
@@ -374,15 +529,13 @@
|
||||
meterVM.Dispose();
|
||||
}
|
||||
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.WaitUntil(this.AvailableIn, show: true);
|
||||
this.WaitUntil(this.AvailableIn, show: true);
|
||||
|
||||
this.CanStart = true;
|
||||
this.Error = default(string);
|
||||
this.State = default(string);
|
||||
});
|
||||
}, wait: false);
|
||||
this.CanStart = true;
|
||||
this.Error = default(string);
|
||||
this.State = default(string);
|
||||
|
||||
}, this.cancellationToken);
|
||||
}
|
||||
|
||||
private void WaitUntil(int duration, bool show = false, bool error = true)
|
||||
@@ -395,6 +548,7 @@
|
||||
}
|
||||
|
||||
this.CanStart = false;
|
||||
this.AvailableIn = duration;
|
||||
this.awaiter = new ManualResetEventSlim();
|
||||
this.timer = new TimersTimer(1000)
|
||||
{
|
||||
@@ -563,12 +717,6 @@
|
||||
|
||||
private void InvokeAsync(Action<ICollection<Task>, CancellationToken> action, bool wait = true)
|
||||
{
|
||||
if (this.cancellationTokenSource?.IsCancellationRequested == true)
|
||||
{
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
this.cancellationToken = this.cancellationTokenSource.Token;
|
||||
}
|
||||
|
||||
this.tasks = new List<Task>();
|
||||
|
||||
action?.Invoke(this.tasks, this.cancellationToken);
|
||||
@@ -576,24 +724,47 @@
|
||||
if (tasks.Any())
|
||||
{
|
||||
var handle = Task.Factory
|
||||
.ContinueWhenAll(this.tasks.ToArray(), _ => { })
|
||||
.ContinueWith(_ => this.tasks.Clear());
|
||||
.ContinueWhenAll(this.tasks.ToArray(), _tasks =>
|
||||
{
|
||||
foreach (var t in _tasks)
|
||||
{
|
||||
this.LogError($"[{t.Id}]:{nameof(t.Status)} = {t.Status}{Environment.NewLine}");
|
||||
|
||||
if (t.Exception != null)
|
||||
{
|
||||
this.LogError($"[{t.Id}]:{t.Exception}{Environment.NewLine}");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (wait)
|
||||
{
|
||||
handle.Wait();
|
||||
}
|
||||
|
||||
this.tasks.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void InvokeAsync(Action action, bool wait = true)
|
||||
private Task InvokeAsync(Action action, CancellationToken cancellationToken)
|
||||
{
|
||||
var handle = Task.Factory.StartNew(action);
|
||||
return Task
|
||||
.Factory
|
||||
.StartNew(action, cancellationToken)
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
this.LogError($"[{t.Id}]:{nameof(t.Status)} = {t.Status}{Environment.NewLine}");
|
||||
|
||||
if (wait)
|
||||
{
|
||||
handle.Wait();
|
||||
}
|
||||
if (t.Exception != null)
|
||||
{
|
||||
this.LogError($"[{t.Id}]:{t.Exception}{Environment.NewLine}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void LogError(string error)
|
||||
{
|
||||
File.AppendAllText(this.errorLog, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +1,114 @@
|
||||
namespace OMNIPruefung.ViewModels.Features
|
||||
{
|
||||
using OmniPlus.Features;
|
||||
using OmniPlus.Inspection;
|
||||
using OMNIPruefung.ViewModels.Base;
|
||||
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
public class OMNIPlusVM : VM<OMNIPlusVM>
|
||||
{
|
||||
public ObservableCollection<Property> Values { get; }
|
||||
= new ObservableCollection<Property>();
|
||||
|
||||
public ObservableCollection<Result> Results { get; }
|
||||
= new ObservableCollection<Result>();
|
||||
|
||||
public ushort IntPart { get; internal set; }
|
||||
|
||||
public ushort Fraction { get; internal set; }
|
||||
|
||||
public byte Size { get; internal set; }
|
||||
|
||||
public byte Range { get; internal set; }
|
||||
|
||||
public sbyte FactoryCorrection { get; internal set; }
|
||||
|
||||
public string BuildInfo { get; internal set; }
|
||||
|
||||
internal void AddResult(string key, string value)
|
||||
{
|
||||
this.Results.Add(new Result
|
||||
{
|
||||
Key = key,
|
||||
Value = value
|
||||
});
|
||||
}
|
||||
|
||||
internal void Add(SystemParameters response)
|
||||
{
|
||||
this.AddResult("Reading System Parameters", $"{response.Status}");
|
||||
|
||||
if (response.Succeeded)
|
||||
{
|
||||
this.BuildInfo = response.BuildInfo.Value;
|
||||
|
||||
this.AddResult(nameof(response.VersionAndType), response.VersionAndType.Value);
|
||||
this.AddResult(nameof(response.BuildInfo), response.BuildInfo.Value);
|
||||
this.AddResult(nameof(response.BatteryVoltage), $"{(response.BatteryVoltage.Volts + 0.0001) / 1000:0.0000 V}");
|
||||
this.AddResult(nameof(response.ManifacturingTime), $"{response.ManifacturingTime.DateTime:dd.MM.yyyy}");
|
||||
this.AddResult(nameof(response.SystemTime), $"{response.SystemTime.DateTime:dd.MM.yyyy}");
|
||||
this.AddResult(nameof(response.RebootsCount), $"{response.RebootsCount}");
|
||||
this.AddResult(nameof(response.FactorySealed), $"{response.FactorySealed}");
|
||||
}
|
||||
}
|
||||
|
||||
internal void Add(InputVolume response)
|
||||
{
|
||||
this.IntPart = response.IntPart;
|
||||
this.Fraction = response.Fraction;
|
||||
this.Size = response.Size;
|
||||
this.Range = response.Range;
|
||||
|
||||
this.AddResult("Setting ml/r", $"{response.MlPerRotation:0.0000 ml/r}");
|
||||
}
|
||||
|
||||
internal void Add(OmniPlusTestPoint pp)
|
||||
{
|
||||
this.AddResult("Test point:", $"{pp.Rotations}/{pp.Duration:0}");
|
||||
this.AddResult("Volume", $"{pp.VolumeM3H:0.0000 m³/h}");
|
||||
this.AddResult("Duration", $"{pp.Duration:0 sec.}");
|
||||
this.AddResult("ml/rotation", $"{pp.MlPerRotation:0.0000 ml/r}");
|
||||
this.AddResult("Validation frame", $"{pp.MinDiff:0.00}% - {pp.MaxDiff:0.00}%");
|
||||
}
|
||||
|
||||
internal void Add(OmniPlusTest test)
|
||||
{
|
||||
this.AddResult("Result", $"{test.DifferencePercentage:0.00}%");
|
||||
this.AddResult("Meter volume", $"{test.MeterVolume:0.0000 m³}");
|
||||
this.AddResult("Reference volume", $"{test.VolumeMessured:0.0000 m³}");
|
||||
this.AddResult("Test result", $"{test.Rotations}/{test.Duration:0}");
|
||||
}
|
||||
|
||||
internal void Add(ConfigurationParameters response)
|
||||
{
|
||||
this.AddResult(nameof(response.ProgrammableID), response.ProgrammableID.Value);
|
||||
this.AddResult(nameof(response.FactoryID), response.FactoryID.Value);
|
||||
this.AddResult(nameof(response.ReadingDigits), $"{response.ReadingDigits.Count}");
|
||||
this.AddResult(nameof(response.Readings), response.Readings.Value);
|
||||
this.AddResult("Optional Uni-Dir-Fields", response.OptionalUniDirFields.Value);
|
||||
this.AddResult("Alarm persistence", $"{response.AlarmPersistenceDays:0 days}");
|
||||
this.AddResult("Data log interval", $"{response.DataLogIntervalMins:0 min.}");
|
||||
this.AddResult(nameof(response.DeviceID), response.DeviceID.Value);
|
||||
}
|
||||
|
||||
internal void AddFactoryCorrection(double value)
|
||||
{
|
||||
this.FactoryCorrection = (sbyte)(value * 10);
|
||||
|
||||
this.AddResult("Factory correction %", $"{value:0.00}%");
|
||||
this.AddResult("Factory correction", $"{this.FactoryCorrection:0}");
|
||||
}
|
||||
}
|
||||
|
||||
public class Result
|
||||
{
|
||||
public string Key { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
||||
public class Property
|
||||
{
|
||||
public string DbName { get; set; }
|
||||
public string Key { get; set; }
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public string BinValue { get; set; }
|
||||
|
||||
public string StrValue { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,27 +13,9 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ItemsControl Grid.Row="0" ItemsSource="{Binding Meter.Properties}" FontFamily="Consolas">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<Label Content="{Binding Path=Key}" Padding="21, 3" FontWeight="Bold"/>
|
||||
<ItemsControl ItemsSource="{Binding Path=Value}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Content="{Binding Path=Key}" Padding="42, 3, 2, 3" Width="200" FontWeight="Bold"/>
|
||||
<Label Content="{Binding Path=Value}" Padding="3"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
|
||||
<DataGrid Grid.Row="0" ItemsSource="{Binding Meter.Results}" FontFamily="Consolas" FontSize="13" HeadersVisibility="Column" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Margin="13"
|
||||
FontFamily="Consolas"
|
||||
@@ -44,7 +26,5 @@
|
||||
FontFamily="Consolas"
|
||||
TextAlignment="Left"
|
||||
Text="{Binding Error}" />
|
||||
|
||||
<DataGrid Grid.Row="3" ItemsSource="{Binding Meter.Results}" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ComboBox Grid.Column="0" Text="{Binding Size}" HorizontalAlignment="Stretch" Margin="0, 2, 2, 2">
|
||||
<ComboBoxItem IsSelected="True">5</ComboBoxItem>
|
||||
@@ -95,6 +97,11 @@
|
||||
<ComboBoxItem >R2</ComboBoxItem>
|
||||
<ComboBoxItem >T2</ComboBoxItem>
|
||||
</ComboBox>
|
||||
<Button Grid.Column="3"
|
||||
Content="Überprüfung starten"
|
||||
Style="{DynamicResource SystemBtn}"
|
||||
Visibility="{Binding CanCheck, Converter={StaticResource BooleanVisibility}}"
|
||||
Command="{Binding CheckInspection}"/>
|
||||
</Grid>
|
||||
|
||||
<!--<Label Grid.Column="0" Grid.Row="9" Content="Type eingeben: " VerticalContentAlignment="Center" VerticalAlignment="Stretch"/>
|
||||
|
||||
@@ -24,13 +24,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
protected override void BeginRead(byte[] buffer)
|
||||
protected override void BeginRead(byte[] bytes)
|
||||
{
|
||||
var start = Array.IndexOf(buffer, this.encoder.Device2PC);
|
||||
if (bytes is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var start = Array.IndexOf(bytes, this.encoder.Device2PC);
|
||||
|
||||
if (start >= 0)
|
||||
{
|
||||
if (this.encoder.TryDecode(buffer, out byte[] message))
|
||||
if (this.encoder.TryDecode(bytes, out byte[] message))
|
||||
{
|
||||
this.EnqueueMessage(message);
|
||||
this.RemoveRange(message.Length);
|
||||
@@ -38,7 +43,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
this.RemoveRange(buffer.Length);
|
||||
this.RemoveRange(bytes.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
|
||||
internal abstract class SerialDataReader : SerialDataStream
|
||||
{
|
||||
protected bool read;
|
||||
private Thread thread;
|
||||
private List<byte> stream;
|
||||
private Queue<byte[]> messages;
|
||||
protected ManualResetEventSlim awaiter;
|
||||
|
||||
protected SerialDataReader(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
@@ -29,7 +31,18 @@
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
this.StopListening();
|
||||
try
|
||||
{
|
||||
this.messages = null;
|
||||
this.stream = null;
|
||||
|
||||
this.thread?.Abort();
|
||||
this.thread = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e.ToString());
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
@@ -77,13 +90,26 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.IsOpen)
|
||||
if (!this.IsOpen)
|
||||
{
|
||||
base.Open();
|
||||
}
|
||||
|
||||
if (!this.IsAlive)
|
||||
{
|
||||
this.stream = new List<byte>();
|
||||
this.messages = new Queue<byte[]>();
|
||||
this.thread = new Thread(this.BeginRead);
|
||||
this.thread.Start();
|
||||
}
|
||||
|
||||
if (this.awaiter?.IsSet == true)
|
||||
{
|
||||
this.awaiter.Set();
|
||||
}
|
||||
|
||||
this.awaiter = new ManualResetEventSlim();
|
||||
this.read = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -95,22 +121,24 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.IsAlive)
|
||||
{
|
||||
this.thread.Abort();
|
||||
}
|
||||
this.stream.Clear();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
|
||||
this.stream?.Clear();
|
||||
this.messages?.Clear();
|
||||
|
||||
this.messages = null;
|
||||
this.stream = null;
|
||||
this.thread = null;
|
||||
try
|
||||
{
|
||||
this.messages.Clear();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
|
||||
this.read = false;
|
||||
this.awaiter.Set();
|
||||
}
|
||||
|
||||
private void BeginRead()
|
||||
@@ -119,9 +147,9 @@
|
||||
|
||||
while (this.IsAlive)
|
||||
{
|
||||
if (this.stream is null)
|
||||
if (!this.read)
|
||||
{
|
||||
continue;
|
||||
this.awaiter.Wait();
|
||||
}
|
||||
|
||||
var bytes = this.ReadBytes();
|
||||
@@ -131,7 +159,7 @@
|
||||
this.stream.AddRange(bytes);
|
||||
}
|
||||
|
||||
this.BeginRead(this.stream.ToArray());
|
||||
this.BeginRead(this.stream?.ToArray());
|
||||
}
|
||||
|
||||
this.NotifyStateChanged($"{nameof(IrdaStream)} - reading thread stoped.");
|
||||
|
||||
@@ -1,19 +1,32 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
internal class UI1236Stream : IrdaStream
|
||||
{
|
||||
private readonly string fileName;
|
||||
private readonly UI1236Encoder encoder;
|
||||
|
||||
public UI1236Stream(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
var directiry = Directory.CreateDirectory(".\\UI1236");
|
||||
this.fileName = Path.Combine(directiry.FullName, $"[{settings.PortName}].txt");
|
||||
this.encoder = new UI1236Encoder();
|
||||
|
||||
File.AppendAllText(Path.Combine(directiry.FullName, $"[{settings.PortName}].txt"), string.Empty);
|
||||
|
||||
this.StateChanged += this.UI1236Stream_StateChanged;
|
||||
}
|
||||
|
||||
public byte[] Write(params byte[] bytes)
|
||||
{
|
||||
this.LogToFile($">>> {BitConverter.ToString(bytes)}");
|
||||
this.StartListening();
|
||||
|
||||
Thread.Sleep(500);
|
||||
|
||||
this.WriteBytes(bytes);
|
||||
|
||||
var response = new byte[0];
|
||||
@@ -34,12 +47,12 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,11 +61,16 @@
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(200);
|
||||
this.LogToFile($"<<< {BitConverter.ToString(response)}");
|
||||
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
this.StopListening();
|
||||
|
||||
this.LogToFile($"<<< {BitConverter.ToString(response)}");
|
||||
this.LogToFile(string.Empty);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -63,5 +81,22 @@
|
||||
base.WriteBytes(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void LogToFile(string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.AppendAllText(this.fileName, $"{value}{Environment.NewLine}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void UI1236Stream_StateChanged(object state)
|
||||
{
|
||||
this.LogToFile($"{state}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
public class ConfigurationParametersSet : FeatureRequest
|
||||
{
|
||||
const int LENGTH = 80;
|
||||
const int LENGTH = 90;
|
||||
|
||||
public ConfigurationParametersSet() : base(LENGTH)
|
||||
{
|
||||
@@ -88,9 +88,9 @@
|
||||
get => this.programmableID;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 0, 21);
|
||||
this.SetASCIIBytes(value, 0, 20);
|
||||
|
||||
this.programmableID = this.bytes.ToASCIIString(0, 21);
|
||||
this.programmableID = this.bytes.ToASCIIString(0, 20);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,9 +139,9 @@
|
||||
get => this.readingPreset;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 38, 10);
|
||||
this.SetASCIIBytes(value, 38, 9);
|
||||
|
||||
this.readingPreset = this.bytes.ToASCIIString(38, 10);
|
||||
this.readingPreset = this.bytes.ToASCIIString(38, 9);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,9 +240,9 @@
|
||||
get => this.buildInfo;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 64, 16);
|
||||
this.SetASCIIBytes(value, 64, 14);
|
||||
|
||||
this.buildInfo = this.bytes.ToASCIIString(64, 16);
|
||||
this.buildInfo = this.bytes.ToASCIIString(64, 14);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,10 +251,17 @@
|
||||
/// Set Device ID String, string is padded and terminated with '\0'
|
||||
/// +1
|
||||
/// </summary>
|
||||
//public string DeviceID
|
||||
//{
|
||||
// set => this.SetASCIIBytes(value, 80, 10);
|
||||
//}
|
||||
private string deviceID;
|
||||
public string DeviceID
|
||||
{
|
||||
get => this.deviceID;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 80, 9);
|
||||
|
||||
this.deviceID = this.bytes.ToASCIIString(80, 9);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetASCIIBytes(string value, int start, int length)
|
||||
{
|
||||
|
||||
@@ -43,7 +43,16 @@
|
||||
public short CorrectionFactor { get; set; }
|
||||
|
||||
public double MlPerRotation
|
||||
=> OmniPlusExtensions.MlPerRotation(this.IntPart, this.Fraction, this.CorrectionFactor);
|
||||
{
|
||||
get
|
||||
{
|
||||
var mlPerRotation = OmniPlusExtensions.MlPerRotation(this.IntPart, this.Fraction, this.CorrectionFactor);
|
||||
|
||||
this.InputVolume.MlPerRotation = mlPerRotation;
|
||||
|
||||
return OmniPlusExtensions.MlPerRotation(this.IntPart, this.Fraction, this.CorrectionFactor);
|
||||
}
|
||||
}
|
||||
|
||||
public InputVolume InputVolume { get; }
|
||||
= new InputVolume();
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
<Compile Include="Features\VersionAndType.cs" />
|
||||
<Compile Include="Inspection\OmniPlusFormulas.cs" />
|
||||
<Compile Include="OmniPlusConnection.cs" />
|
||||
<Compile Include="OmniPlusConnectionsPool.cs" />
|
||||
<Compile Include="OmniPlusDatabase.cs" />
|
||||
<Compile Include="Inspection\OmniPlusExtensions.cs" />
|
||||
<Compile Include="Inspection\OmniPlusTest.cs" />
|
||||
|
||||
@@ -0,0 +1,498 @@
|
||||
using OmniPlus.Features;
|
||||
using OmniPlus.Inspection;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OmniPlus
|
||||
{
|
||||
public class OmniPlusConnectionsPool : IDisposable
|
||||
{
|
||||
public event Action Done;
|
||||
|
||||
private readonly ConcurrentDictionary<int, OmniPlusConnection> connections;
|
||||
private readonly ConcurrentDictionary<int, OmniPlusMeter> meters;
|
||||
private readonly CancellationTokenSource cancellationTokenSource;
|
||||
private readonly CancellationToken cancellationToken;
|
||||
private readonly OmniPlusExchangeSlave exchangeSlave;
|
||||
private readonly OmniPlusDatabase database;
|
||||
private readonly OmniPlusType omniType;
|
||||
|
||||
private byte size;
|
||||
private string variant;
|
||||
private BackgroundWorker background;
|
||||
|
||||
public OmniPlusConnectionsPool(string dbConnectionString, string signalRURL)
|
||||
{
|
||||
this.connections = new ConcurrentDictionary<int, OmniPlusConnection>();
|
||||
this.meters = new ConcurrentDictionary<int, OmniPlusMeter>();
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
this.exchangeSlave = new OmniPlusExchangeSlave(signalRURL);
|
||||
this.database = new OmniPlusDatabase(dbConnectionString);
|
||||
this.omniType = new OmniPlusType();
|
||||
|
||||
this.size = 5;
|
||||
this.variant = "C2";
|
||||
this.cancellationToken = this.cancellationTokenSource.Token;
|
||||
this.cancellationToken.Register(this.CancellationCallback);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.exchangeSlave.Dispose();
|
||||
|
||||
// Disposes all OmniPlus connections.
|
||||
foreach (var connectionKVP in this.connections)
|
||||
{
|
||||
connectionKVP.Value?.Disconnect();
|
||||
}
|
||||
|
||||
// Clears collected connections and their meters.
|
||||
this.connections.Clear();
|
||||
this.meters.Clear();
|
||||
}
|
||||
|
||||
public void InitializeInspection(params string[] portNames)
|
||||
{
|
||||
OmniPlusConnection connection;
|
||||
OmniPlusMeter meter;
|
||||
int position = 1;
|
||||
bool connected;
|
||||
|
||||
foreach (var portName in portNames)
|
||||
{
|
||||
connection = new OmniPlusConnection(portName);
|
||||
connected = connection.ConnectIrda();
|
||||
|
||||
if (connected)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
connection.Disconnect();
|
||||
connection = default(OmniPlusConnection);
|
||||
meter = default(OmniPlusMeter);
|
||||
}
|
||||
|
||||
this.connections.TryAdd(position, connection);
|
||||
|
||||
position++;
|
||||
}
|
||||
|
||||
this.database.LoadOmniDefaults(this.size, this.variant, this.omniType);
|
||||
}
|
||||
|
||||
public void CancelExecution()
|
||||
=> this.cancellationTokenSource.Cancel(false);
|
||||
|
||||
//public void StartInspection()
|
||||
//{
|
||||
// foreach (var position in this.connections.Keys)
|
||||
// {
|
||||
// this.StartOmniInitialization(position);
|
||||
|
||||
// //foreach (var point in this.omniType.TestPoints)
|
||||
// //{
|
||||
// // this.StartOmniInspection(position, point);
|
||||
// //}
|
||||
|
||||
// //this.CalculateCorrectionFactor(position);
|
||||
|
||||
// this.FinishOmniInspection(position);
|
||||
// }
|
||||
//}
|
||||
|
||||
public void StartInspection()
|
||||
{
|
||||
this.background = new BackgroundWorker();
|
||||
|
||||
this.background.DoWork += this.StartInspection;
|
||||
|
||||
this.background.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void StartInspection(object sender, EventArgs args)
|
||||
{
|
||||
var connectionsCount = this.connections.Count;
|
||||
var tasks = new Task[connectionsCount];
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.StartOmniInitialization(position), this.cancellationToken);
|
||||
}
|
||||
|
||||
foreach (var point in this.omniType.TestPoints)
|
||||
{
|
||||
// TODO: 600 = 10min * 60sec - change for production.
|
||||
|
||||
//if (!this.exchangeSlave.SetQAndWaitUntilReached(point.VolumeM3H))
|
||||
//{
|
||||
// this.CancelExecution();
|
||||
|
||||
// break;
|
||||
//}
|
||||
|
||||
tasks = new Task[connectionsCount];
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.StartOmniInspection(position, point), this.cancellationToken);
|
||||
}
|
||||
|
||||
//var volume = this.exchangeSlave.RequestRefV();
|
||||
|
||||
//foreach (var position in this.connections.Keys)
|
||||
//{
|
||||
// this.SetPointDifference(position, point, volume);
|
||||
//}
|
||||
}
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
this.CalculateCorrectionFactor(position);
|
||||
}
|
||||
|
||||
tasks = new Task[connectionsCount];
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.FinishOmniInspection(position), this.cancellationToken);
|
||||
}
|
||||
|
||||
this.Done?.Invoke();
|
||||
}
|
||||
|
||||
private void StartOmniInitialization(int position)
|
||||
{
|
||||
if (this.TryGetOmni(position, out var connection, out var meter))
|
||||
{
|
||||
var systemParameters = connection.ViewSystemParameters();
|
||||
|
||||
// connection.Set(this.omniType.InputVolume).Succeeded;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void StartOmniInspection(int position, OmniPlusTestPoint point)
|
||||
{
|
||||
var header = $"{point.VolumeM3H:0.0000}m³/h";
|
||||
|
||||
if (this.TryGetOmni(position, out var connection, out var meter) /*&& meter.Initialized && meter.CanCalibrate*/)
|
||||
{
|
||||
var activationResponse = connection.StartChamberCalibration(point.Rotations, point.Duration);
|
||||
|
||||
if (activationResponse.Succeeded)
|
||||
{
|
||||
var calibrationResult = new ChamberCalibrationResponse();
|
||||
var duration = point.Duration + 3;
|
||||
|
||||
this.NotifyWhileThreadSleep(position, header, point.Duration + 3);
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
calibrationResult = connection.ViewChamberCalibration();
|
||||
|
||||
if (calibrationResult.Succeeded)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
else // activation failed
|
||||
{
|
||||
}
|
||||
}
|
||||
else // not connected
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPointDifference(int position, OmniPlusTestPoint point, double volume)
|
||||
{
|
||||
//var header = $"{point.VolumeM3H:0.0000}m³/h";
|
||||
|
||||
//if (this.TryGetOmni(position, out var _, out var meter) && meter.Initialized && meter.CanCalibrate)
|
||||
//{
|
||||
// var difference = meter.AddCalibrationVolume(point, volume);
|
||||
|
||||
// this.StateChanged?.Invoke(position, 0, header, $"{difference:0.00}%");
|
||||
//}
|
||||
//else // not connected
|
||||
//{
|
||||
// this.StateChanged?.Invoke(position, 0, header, null);
|
||||
//}
|
||||
}
|
||||
|
||||
private void CalculateCorrectionFactor(int position)
|
||||
{
|
||||
//if (this.TryGetOmni(position, out var _, out var meter) && meter.Initialized && meter.CanCalibrate)
|
||||
//{
|
||||
// var correctionFactor = meter.GetCorrectionFactor();
|
||||
|
||||
// this.StateChanged?.Invoke(position, meter.CanCalibrate ? 1 : -1, CORRECTION, $"{correctionFactor:0.00}%");
|
||||
//}
|
||||
//else // not connected
|
||||
//{
|
||||
// this.StateChanged?.Invoke(position, 0, CORRECTION, null);
|
||||
//}
|
||||
}
|
||||
|
||||
private void FinishOmniInspection(int position)
|
||||
{
|
||||
//if (this.TryGetOmni(position, out var connection, out var meter)/* && meter.Calibrated*/)
|
||||
//{
|
||||
// var configurationParameters = connection.ViewConfigurationParameters();
|
||||
// var canContinue = configurationParameters.Succeeded;
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// meter.AddConfigurationParameters(configurationParameters);
|
||||
// this.database.AddOrUpdate(position, configurationParameters);
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// // TODO: Uncomment in production
|
||||
// //var systemTimeReset = connection.SetSystemTime();
|
||||
// //canContinue = systemTimeReset.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var registerSettings = new RegisterSettings();
|
||||
|
||||
// registerSettings.IntPart = this.omniType.IntPart;
|
||||
// registerSettings.Fraction = this.omniType.Fraction;
|
||||
// registerSettings.Size = this.omniType.Size;
|
||||
// registerSettings.Range = this.omniType.Range;
|
||||
// registerSettings.VolumePerPulseUnit = 0x00;
|
||||
// registerSettings.MeterUnits = (byte)MessurementUnits.USGallons;
|
||||
// registerSettings.FlowUnits = (byte)MessurementUnits.USGallons;
|
||||
// registerSettings.FlowRate = (byte)TimeUnits.Minutes;
|
||||
// registerSettings.FactoryCorrection = meter.FactoryCorrection;
|
||||
// registerSettings.FieldCorrection = 0x00;
|
||||
// registerSettings.PulseWeight = 0x01;
|
||||
// registerSettings.PulseWidth = 0x02;
|
||||
// registerSettings.PulseUpdate = 0x00;
|
||||
|
||||
// var response = connection.Set(registerSettings);
|
||||
// canContinue = response.Succeeded;
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// meter.AddRegisterSettings(registerSettings);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var configurationParametersSet = new ConfigurationParametersSet();
|
||||
// configurationParametersSet.ProgrammableID = "816232411983";
|
||||
// configurationParametersSet.FactoryID = "816232411983";
|
||||
// configurationParametersSet.NumberOfReadingDigits = 8; // meter.ReadingDigits;
|
||||
// configurationParametersSet.ReadingPreset = "000000000";
|
||||
// configurationParametersSet.OptionalUniDirFields = 1; // meter.OptionalUniDirFields;
|
||||
// configurationParametersSet.AlarmPercistancePeriodDays = 31;
|
||||
// configurationParametersSet.DataLogIntervalMinutes = 60;
|
||||
// configurationParametersSet.ManifacturingTime = Epoch20000101.UTCNow - 30000; // meter.ManifacturingTime;
|
||||
// configurationParametersSet.SystemTime = Epoch20000101.UTCNow;
|
||||
// configurationParametersSet.RebootCount = 0;
|
||||
// configurationParametersSet.BuildInfo = "816232411983"; // meter.BuildInfo;
|
||||
// // configurationParametersSet.DeviceID = "OMNI-01";
|
||||
|
||||
// var response = connection.Set(configurationParametersSet);
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.ClearDisplay();
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.Set(new LeakAlarm
|
||||
// {
|
||||
// FlowRateGal = 0.25F, // 0.25 gpm
|
||||
// TimeLimit = 24 * 60 * 60 // 24 hours => 86400sec
|
||||
// });
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.Set(new HighFlowAlarm
|
||||
// {
|
||||
// FlowRateGal = 25F, // 25 gpm
|
||||
// TimeLimit = 1 * 60 * 60 // 1 hours => 86400sec
|
||||
// });
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.Set(new ReverseFlowAlarm
|
||||
// {
|
||||
// FlowRateGal = -1F, // -1 gpm
|
||||
// TimeLimit = 60 // 1 hours => 86400sec
|
||||
// });
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.ClearAlarms();
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var alarmsState = connection.ViewAlarmsState();
|
||||
// canContinue = alarmsState.Succeeded;
|
||||
// //&& alarmsState.UsrEnabled
|
||||
// //&& alarmsState.PreEnabledInactive;
|
||||
// //TODO: Check alarms
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.EnableNFC();
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var registerSettingsAfter = connection.ViewRegisterSettings();
|
||||
// canContinue = registerSettingsAfter.Succeeded
|
||||
// && meter.Compare(registerSettingsAfter);
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var systemParametersAfter = connection.ViewSystemParameters();
|
||||
// canContinue = systemParametersAfter.Succeeded;
|
||||
// //&& meter.Compare(systemParametersAfter);
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var configurationParametersAfter = connection.ViewConfigurationParameters();
|
||||
// canContinue = configurationParametersAfter.Succeeded;
|
||||
// //&& meter.Compare(configurationParametersAfter);
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var alarmsState = connection.ViewAlarmsState();
|
||||
// canContinue = alarmsState.Succeeded;
|
||||
// //&& alarmsState.UsrEnabled
|
||||
// //&& alarmsState.PreEnabledInactive;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.ViewAlarmSettings(0x01);
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.ViewAlarmSettings(0x02);
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.ViewAlarmSettings(0x04);
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// //connection.Set(new FactorySeal
|
||||
// //{
|
||||
// // Sealed = true,
|
||||
// //});
|
||||
|
||||
// //var factorySeal = connection.ViewFactorySeal();
|
||||
// //canContinue = factorySeal.Succeeded && factorySeal.Sealed;
|
||||
// }
|
||||
//}
|
||||
//else // meter or connection not in use
|
||||
//{
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns only connected connections and meters.
|
||||
/// </summary>
|
||||
/// <param name="position">The position of connection and meter.</param>
|
||||
/// <param name="connection"><see cref="OmniPlusConnection"/></param>
|
||||
/// <param name="meter"><see cref="OmniPlusMeter"/></param>
|
||||
/// <returns>Returns true if connection and meter are found and are not null and the meter is connected, otherwise false.</returns>
|
||||
private bool TryGetOmni(int position, out OmniPlusConnection connection, out OmniPlusMeter meter)
|
||||
{
|
||||
var connectionFound = this.connections.TryGetValue(position, out connection);
|
||||
var meterFound = this.meters.TryGetValue(position, out meter);
|
||||
|
||||
return connectionFound
|
||||
&& connection != null
|
||||
&& meterFound
|
||||
&& meter != null;
|
||||
}
|
||||
|
||||
private void NotifyWhileThreadSleep(int position, string header, int duration)
|
||||
{
|
||||
//var seconds = 0;
|
||||
//var timer = new System.Timers.Timer(1000)
|
||||
//{
|
||||
// Enabled = true,
|
||||
// AutoReset = true,
|
||||
//};
|
||||
//timer.Elapsed += (_, _1) =>
|
||||
//{
|
||||
// this.StateChanged?.Invoke(position, 0, header, $"{seconds++}/{duration}");
|
||||
//};
|
||||
|
||||
//timer.Start();
|
||||
|
||||
//Thread.Sleep(duration * 1000);
|
||||
|
||||
//timer.Stop();
|
||||
}
|
||||
|
||||
private void CancellationCallback()
|
||||
{
|
||||
// TODO: Update database.
|
||||
this.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
internal class OmniPlusExchangeSlave
|
||||
{
|
||||
private String signalRURL;
|
||||
|
||||
public OmniPlusExchangeSlave(String signalRURL)
|
||||
{
|
||||
this.signalRURL = signalRURL;
|
||||
}
|
||||
|
||||
internal void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
internal class OmniPlusMeter
|
||||
{
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user