omni still in progress
This commit is contained in:
@@ -1,86 +1,80 @@
|
||||
//using OmniPipes;
|
||||
|
||||
using OmniPlus.Connections;
|
||||
using OmniPlus.Connections;
|
||||
using OmniPlus.Features;
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using static OmniPlus.UI.Inspection.OmniPlusInspectionHeaders;
|
||||
using static OmniPlus.OmniPlusConstants;
|
||||
|
||||
namespace OmniPlus.UI.Inspection
|
||||
namespace OmniPlus
|
||||
{
|
||||
public class OmniPlusConnectionsPool : IDisposable
|
||||
{
|
||||
public event OmniPlusStateChangedEventHandler StateChanged;
|
||||
public event OmniPlusStateChanged StateChanged;
|
||||
|
||||
private readonly ConcurrentDictionary<int, OmniPlusConnection> connections;
|
||||
private readonly ConcurrentDictionary<int, OmniPlusMeter> meters;
|
||||
private readonly ConcurrentDictionary<int, Task> tasks;
|
||||
//private readonly NamedPipeClient namedPipeClient;
|
||||
private readonly OmniPlusDatabase database;
|
||||
private readonly OmniPlusType omniType;
|
||||
|
||||
private bool available;
|
||||
private int size;
|
||||
private byte size;
|
||||
|
||||
public OmniPlusConnectionsPool(string dbConnectionString)
|
||||
{
|
||||
this.connections = new ConcurrentDictionary<int, OmniPlusConnection>();
|
||||
this.meters = new ConcurrentDictionary<int, OmniPlusMeter>();
|
||||
//this.namedPipeClient = new NamedPipeClient();
|
||||
this.database = new OmniPlusDatabase(dbConnectionString);
|
||||
this.omniType = new OmniPlusType();
|
||||
this.size = 5;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Disposes all OmniPlus connections.
|
||||
foreach (var connectionKVP in this.connections)
|
||||
{
|
||||
connectionKVP.Value?.Disconnect();
|
||||
|
||||
this.StateChanged?.Invoke(connectionKVP.Key, false, CONNECTED, X);
|
||||
}
|
||||
|
||||
// Clears collected connections and their meters.
|
||||
this.connections.Clear();
|
||||
this.meters.Clear();
|
||||
|
||||
// Releases all connected event handlers to the StateChanged event.
|
||||
if (this.StateChanged != null)
|
||||
{
|
||||
foreach (var callback in this.StateChanged.GetInvocationList())
|
||||
{
|
||||
if (callback is OmniPlusStateChangedEventHandler stateChangedCallback)
|
||||
if (callback is OmniPlusStateChanged stateChangedCallback)
|
||||
{
|
||||
this.StateChanged -= stateChangedCallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var connection in this.connections.Values)
|
||||
{
|
||||
connection?.Disconnect();
|
||||
}
|
||||
|
||||
//this.namedPipeClient.Connected -= this.NamedPipeClient_Connected;
|
||||
//this.namedPipeClient.Disconnected -= this.NamedPipeClient_Disconnected;
|
||||
|
||||
//this.namedPipeClient.Disconnect();
|
||||
this.connections.Clear();
|
||||
this.meters.Clear();
|
||||
// TODO: Save state.!?
|
||||
}
|
||||
|
||||
public void InitializeInspection(params string[] portNames)
|
||||
{
|
||||
//this.namedPipeClient.Connected += this.NamedPipeClient_Connected;
|
||||
//this.namedPipeClient.Disconnected += this.NamedPipeClient_Disconnected;
|
||||
//this.namedPipeClient.Connect();
|
||||
|
||||
OmniPlusConnection connection;
|
||||
OmniPlusMeter meter;
|
||||
var connections = 0;
|
||||
var position = 1;
|
||||
var connected = true;
|
||||
|
||||
foreach (var portName in portNames)
|
||||
{
|
||||
connection = new OmniPlusConnection(portName);
|
||||
connected = connection.ConnectIrda();
|
||||
meter = new OmniPlusMeter();
|
||||
|
||||
if (connection.ConnectIrda())
|
||||
if (connected)
|
||||
{
|
||||
meter.Connected = true;
|
||||
connections++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -91,136 +85,109 @@ namespace OmniPlus.UI.Inspection
|
||||
|
||||
this.meters.TryAdd(position, meter);
|
||||
this.connections.TryAdd(position, connection);
|
||||
|
||||
this.StateChanged?.Invoke(position, true, SLOT_NR, position.ToString());
|
||||
this.StateChanged?.Invoke(position, connected ? true : default(bool?), CONNECTED, connected ? OK : null);
|
||||
|
||||
position++;
|
||||
}
|
||||
|
||||
if (this.available)
|
||||
{
|
||||
this.available = connections > 0;
|
||||
}
|
||||
this.database.LoadOmniPlusType(this.size, this.omniType);
|
||||
}
|
||||
|
||||
public void StartInspection()
|
||||
{
|
||||
this.StartOmniInitialization();
|
||||
this.StartOmniCalibration();
|
||||
this.FinishOmniInspection();
|
||||
}
|
||||
|
||||
private void StartOmniInitialization()
|
||||
{
|
||||
var factory = Task.Factory;
|
||||
var connectionsCount = this.connections.Count;
|
||||
var tasks = new Task[connectionsCount];
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
this.tasks[position] = factory.StartNew(() => this.StartOmniInitialization(position));
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.StartOmniInitialization(position));
|
||||
}
|
||||
|
||||
factory.ContinueWhenAll(this.tasks.Values.ToArray(), _ => { });
|
||||
Task.Factory
|
||||
.ContinueWhenAll(tasks, _ => { })
|
||||
.Wait();
|
||||
|
||||
foreach (var point in this.omniType.TestPoints)
|
||||
{
|
||||
// TODO: Request and wait for volume.
|
||||
|
||||
tasks = new Task[connectionsCount];
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.StartOmniCalibration(position, point));
|
||||
}
|
||||
|
||||
Task.Factory
|
||||
.ContinueWhenAll(tasks, _ => { })
|
||||
.Wait();
|
||||
|
||||
// TODO: Request reference volume.
|
||||
var volume = 0D;
|
||||
|
||||
foreach (var meter in this.meters.Values)
|
||||
{
|
||||
// TODO: meter.AddInspectionVolume(point, volume);
|
||||
}
|
||||
}
|
||||
|
||||
tasks = new Task[connectionsCount];
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.CalibrateMeter(position));
|
||||
}
|
||||
|
||||
Task.Factory
|
||||
.ContinueWhenAll(tasks, _ => { })
|
||||
.Wait();
|
||||
|
||||
//this.FinishOmniInspection();
|
||||
}
|
||||
|
||||
private void StartOmniInitialization(int position)
|
||||
{
|
||||
this.StateChanged?.Invoke(position, null, FIRMWARE, null);
|
||||
this.StateChanged?.Invoke(position, null, BUILD_INFO, null);
|
||||
|
||||
if (this.TryGetOmni(position, out var connection, out var meter))
|
||||
{
|
||||
this.StateChanged?.Invoke(position, meter.Connected, CONNECTED, meter.Connected ? OK : X);
|
||||
this.StateChanged?.Invoke(position, null, FIRMWARE, TBD);
|
||||
this.StateChanged?.Invoke(position, null, BUILD_INFO, TBD);
|
||||
|
||||
var systemParameters = connection.ViewSystemParameters();
|
||||
meter.Initialized = systemParameters.Succeeded;
|
||||
|
||||
meter.AddSystemParameters(systemParameters);
|
||||
this.database.AddOrUpdate(systemParameters);
|
||||
|
||||
this.StateChanged?.Invoke(position, meter.FirmwareInRange, FIRMWARE, meter.Firmware);
|
||||
this.StateChanged?.Invoke(position, true, BUILD_INFO, meter.BuildInfo);
|
||||
this.StateChanged?.Invoke(position, meter.ManifacturingTimeInRange, CREATED_ON, $"{meter.ManifacturingTime:yyyy-MM-dd}");
|
||||
this.StateChanged?.Invoke(position, meter.SystemTimeInRange, LAST_UPDATE, $"{meter.SystemTimeDrift} Sek.");
|
||||
this.StateChanged?.Invoke(position, meter.RebootsCount != 0xFF, REBOOTS_CNT, meter.RebootsCount.ToString());
|
||||
this.StateChanged?.Invoke(position, !meter.FactorySealed, SEALED, !meter.FactorySealed ? X : OK);
|
||||
|
||||
if (meter.Initialized)
|
||||
{
|
||||
var inputVolume = this.database.GetInputVolume(meter.Size);
|
||||
var inputVolumResponse = connection.SetInputVolume(inputVolume);
|
||||
meter.Initialized = inputVolumResponse.Succeeded;
|
||||
|
||||
if (meter.Initialized)
|
||||
{
|
||||
meter.AddInputVolume(inputVolume);
|
||||
}
|
||||
this.database.AddOrUpdate(position, systemParameters);
|
||||
}
|
||||
|
||||
this.StateChanged?.Invoke(position, meter.Initialized, ML_PER_PULSE, $"{meter.MlPerPulse:0.00000}");
|
||||
}
|
||||
else // meter or connection not in use
|
||||
{
|
||||
this.StateChanged?.Invoke(position, null, CONNECTED, null);
|
||||
this.StateChanged?.Invoke(position, null, FIRMWARE, null);
|
||||
this.StateChanged?.Invoke(position, null, BUILD_INFO, null);
|
||||
this.StateChanged?.Invoke(position, null, CREATED_ON, null);
|
||||
this.StateChanged?.Invoke(position, null, LAST_UPDATE, null);
|
||||
this.StateChanged?.Invoke(position, null, REBOOTS_CNT, null);
|
||||
this.StateChanged?.Invoke(position, null, SEALED, null);
|
||||
this.StateChanged?.Invoke(position, null, ML_PER_PULSE, null);
|
||||
connection.SetInputVolume(this.omniType.InputVolume);
|
||||
|
||||
this.StateChanged?.Invoke(position, meter.FirmwareInRange, FIRMWARE, meter.Firmware);
|
||||
this.StateChanged?.Invoke(position, !string.IsNullOrWhiteSpace(meter.BuildInfo), BUILD_INFO, meter.BuildInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartOmniCalibration()
|
||||
private void StartOmniCalibration(int position, OmniPlusTestPoint point)
|
||||
{
|
||||
var factory = Task.Factory;
|
||||
var inspectionPoints = this.database.GetInspectionPoints(this.size);
|
||||
var header = $"{point.VolumeM3H:0.0000} m³/h";
|
||||
this.StateChanged?.Invoke(position, null, header, null);
|
||||
|
||||
foreach (var point in inspectionPoints)
|
||||
if (this.TryGetOmni(position, out var connection, out var meter) && meter.Initialized)
|
||||
{
|
||||
//this.namedPipeClient.RequestFlowRate(point.FlowRate);
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
this.tasks[position] = factory.StartNew(() => this.StartOmniCalibration(position, point));
|
||||
}
|
||||
|
||||
factory.ContinueWhenAll(this.tasks.Values.ToArray(), _ => { });
|
||||
|
||||
//var volume = this.namedPipeClient.RequestReference();
|
||||
|
||||
//foreach (var meter in this.meters.Values)
|
||||
//{
|
||||
// meter.AddInspectionVolume(point, volume);
|
||||
//}
|
||||
}
|
||||
|
||||
foreach(var position in this.connections.Keys)
|
||||
{
|
||||
this.tasks[position] = factory.StartNew(() => this.CalibrateMeter(position));
|
||||
}
|
||||
|
||||
factory.ContinueWhenAll(this.tasks.Values.ToArray(), _ => { });
|
||||
}
|
||||
|
||||
private void StartOmniCalibration(int position, OmniPlusInspectionPoint point)
|
||||
{
|
||||
var header = $"{point.Rotations}/{point.Seconds}R/Sek.";
|
||||
var progress = 0;
|
||||
|
||||
this.StateChanged?.Invoke(position, null, header, $"{progress}%");
|
||||
|
||||
if (this.TryGetOmni(position, out var connection, out var meter))
|
||||
{
|
||||
if (!meter.CanCalibrate)
|
||||
{
|
||||
this.StateChanged?.Invoke(position, false, header, X);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var activationResponse = connection.StartChamberCalibration(point.Rotations, point.Seconds);
|
||||
var activationResponse = connection.StartChamberCalibration(point.Rotations, point.Duration);
|
||||
var calibrationResult = default(ChamberCalibration);
|
||||
|
||||
if (activationResponse.Succeeded)
|
||||
{
|
||||
progress += 10;
|
||||
var progress = 0;
|
||||
this.NotifyTimeProgress(position, header, point.Duration);
|
||||
|
||||
progress = 10;
|
||||
|
||||
this.StateChanged?.Invoke(position, true, header, $"{progress}%");
|
||||
|
||||
@@ -231,12 +198,12 @@ namespace OmniPlus.UI.Inspection
|
||||
this.StateChanged?.Invoke(position, true, header, $"{progress}%");
|
||||
|
||||
// waiting all the secconds to execute test
|
||||
Thread.Sleep(point.Seconds * 1000);
|
||||
Thread.Sleep(point.Duration * 1000);
|
||||
|
||||
progress += 70;
|
||||
this.StateChanged?.Invoke(position, true, header, $"{progress}%");
|
||||
|
||||
var delay = (int)(point.Seconds * 0.1) * 1000;
|
||||
var delay = (int)(point.Duration * 0.1) * 1000;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
@@ -276,17 +243,14 @@ namespace OmniPlus.UI.Inspection
|
||||
|
||||
meter.AddCalibrationResult(point, calibrationResult);
|
||||
}
|
||||
else // meter or connection not in use
|
||||
{
|
||||
this.StateChanged?.Invoke(position, null, header, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void CalibrateMeter(int position)
|
||||
{
|
||||
if (this.TryGetOmni(position, out var connection, out var meter))
|
||||
{
|
||||
var correctionFactor = meter.CalculateCorrectionFactor();
|
||||
var correctionFactor = 0D;
|
||||
// TODO: var correctionFactor = meter.CalculateCorrectionFactor();
|
||||
|
||||
this.StateChanged?.Invoke(position, meter.Calibrated, CORRECTION, $"{correctionFactor:0.00}%");
|
||||
}
|
||||
@@ -298,12 +262,14 @@ namespace OmniPlus.UI.Inspection
|
||||
|
||||
private void FinishOmniInspection()
|
||||
{
|
||||
var factory = Task.Factory;
|
||||
var tasks = new Task[this.connections.Count];
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
this.tasks[position] = factory.StartNew(() => this.FinishOmniInspection(position));
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.FinishOmniInspection(position));
|
||||
}
|
||||
|
||||
Task.Factory.ContinueWhenAll(tasks, _ => { });
|
||||
}
|
||||
|
||||
private void FinishOmniInspection(int position)
|
||||
@@ -319,10 +285,10 @@ namespace OmniPlus.UI.Inspection
|
||||
canContinue = systemTimeReset.Succeeded;
|
||||
}
|
||||
|
||||
//if (canContinue)
|
||||
//{
|
||||
// var registerSettings = connection.ViewRegisterSettings();
|
||||
//}
|
||||
if (canContinue)
|
||||
{
|
||||
// TODO: var registerSettings = connection.ViewRegisterSettings();
|
||||
}
|
||||
}
|
||||
else // meter or connection not in use
|
||||
{
|
||||
@@ -330,6 +296,13 @@ namespace OmniPlus.UI.Inspection
|
||||
}
|
||||
}
|
||||
|
||||
/// <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);
|
||||
@@ -342,10 +315,20 @@ namespace OmniPlus.UI.Inspection
|
||||
&& meter.Connected;
|
||||
}
|
||||
|
||||
private void NamedPipeClient_Connected()
|
||||
=> this.available = true;
|
||||
private void NotifyTimeProgress(int position, string header, int duration)
|
||||
{
|
||||
var progress = 0;
|
||||
var timer = new System.Timers.Timer(1000)
|
||||
{
|
||||
Enabled = true,
|
||||
AutoReset = true,
|
||||
};
|
||||
timer.Elapsed += (_, _1) => this.StateChanged?.Invoke(position, null, header, $"{progress++}/{duration}");
|
||||
timer.Start();
|
||||
|
||||
private void NamedPipeClient_Disconnected()
|
||||
=> this.available = false;
|
||||
Thread.Sleep(duration * 1000);
|
||||
|
||||
timer.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user