omni still in progress
This commit is contained in:
@@ -29,12 +29,8 @@
|
||||
{
|
||||
this.bytes.Clear();
|
||||
|
||||
var factoryID = value
|
||||
?.Substring(0, this.length)
|
||||
?? string.Empty;
|
||||
|
||||
Encoding.ASCII
|
||||
.GetBytes(factoryID)
|
||||
.GetBytes(value?.Trim('\0', ' ') ?? string.Empty)
|
||||
.CopyTo(this.bytes, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
namespace OmniPlus.Features
|
||||
{
|
||||
using static System.Collections.Specialized.BitVector32;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Policy;
|
||||
using System;
|
||||
|
||||
internal class Features
|
||||
{
|
||||
/// <summary>
|
||||
@@ -320,5 +314,16 @@
|
||||
/// current volume reading and alarm counts can be recovered if Set System Time is followed by a reboot.
|
||||
/// </summary>
|
||||
public const byte SET_SYSTEM_TIME = 0x11;
|
||||
|
||||
/// <summary>
|
||||
/// Get manufacturing date and time which is programmed into the register at time of manufacture.
|
||||
/// </summary>
|
||||
public const byte VIEW_MANIFACTURING_TIME = 0x39;
|
||||
/// <summary>
|
||||
/// Set manufacturing date and time.
|
||||
/// If manufacturing date/time specified in the command payload is newer than the system time of the register,
|
||||
/// the register will update system time to the time specified in this command in addition to setting manufacturing time.
|
||||
/// </summary>
|
||||
public const byte SET_MANIFACTURING_TIME = 0x3A;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,16 @@ namespace OmniPlus.Features
|
||||
{
|
||||
}
|
||||
|
||||
public ushort IntPart
|
||||
public byte Direction
|
||||
{
|
||||
get => BitConverter.ToUInt16(this.bytes, 0);
|
||||
set => BitConverter.GetBytes(value).CopyTo(this.bytes, 0);
|
||||
get => this.bytes[0];
|
||||
set => this.bytes[0] = value;
|
||||
}
|
||||
|
||||
public byte IntPart
|
||||
{
|
||||
get => this.bytes[1];
|
||||
set => this.bytes[1] = value;
|
||||
}
|
||||
|
||||
public ushort Fraction
|
||||
@@ -38,6 +44,6 @@ namespace OmniPlus.Features
|
||||
set => this.bytes[5] = value;
|
||||
}
|
||||
|
||||
public int Factor { get; set; } = 100;
|
||||
public double MlPerRotation { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
/// </summary>
|
||||
public class VersionAndType : ASCIIString
|
||||
{
|
||||
const int LENGTH = 12;
|
||||
const int LENGTH = 27;
|
||||
|
||||
public VersionAndType() : base(LENGTH)
|
||||
{
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>OmniPlus</RootNamespace>
|
||||
<AssemblyName>OmniPlus</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8.1</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -87,10 +88,11 @@
|
||||
<Compile Include="OmniPlusConnectionsPool.cs" />
|
||||
<Compile Include="OmniPlusDatabase.cs" />
|
||||
<Compile Include="OmniPlusExtensions.cs" />
|
||||
<Compile Include="OmniPlusInspectionHeaders.cs" />
|
||||
<Compile Include="OmniPlusInspectionPoint.cs" />
|
||||
<Compile Include="OmniPlusConstants.cs" />
|
||||
<Compile Include="OmniPlusTestPoint.cs" />
|
||||
<Compile Include="OmniPlusMeter.cs" />
|
||||
<Compile Include="OmniPlusStateChangedEventHandler.cs" />
|
||||
<Compile Include="OmniPlusStateChanged.cs" />
|
||||
<Compile Include="OmniPlusType.cs" />
|
||||
<Compile Include="Options\OmniControlOptions.cs" />
|
||||
<Compile Include="Options\SerialPortOptions.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
||||
@@ -151,6 +151,13 @@ namespace OmniPlus.Connections
|
||||
return new FeatureResponse(response);
|
||||
}
|
||||
|
||||
public FeatureResponse SetManifacturingTime(ManifacturingTime manifacturingTime)
|
||||
{
|
||||
var response = this.MessageHandler.Invoke(manifacturingTime[DEVICE_SPECIFIC, SET_MANIFACTURING_TIME]);
|
||||
|
||||
return new FeatureResponse(response);
|
||||
}
|
||||
|
||||
public RateResolution ViewRateResolution()
|
||||
{
|
||||
var response = this.MessageHandler.Invoke(VIEW_RATE_RESOLUTION);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace OmniPlus.UI.Inspection
|
||||
namespace OmniPlus
|
||||
{
|
||||
internal class OmniPlusInspectionHeaders
|
||||
internal class OmniPlusConstants
|
||||
{
|
||||
public const string COMS_CONFIG = "COMS";
|
||||
|
||||
@@ -12,12 +12,11 @@
|
||||
public const string REBOOTS_CNT = "Neustarts";
|
||||
public const string SEALED = "Versiegelt";
|
||||
public const string BUILD_INFO = "Build-Info";
|
||||
public const string ML_PER_PULSE = "ml/Puls";
|
||||
public const string ML_PER_ROTATION = "Ml/Rotation";
|
||||
public const string CORRECTION = "Korrekturfaktor";
|
||||
//public const string REBOOTS_CNT = "Neustarts";
|
||||
//public const string REBOOTS_CNT = "Neustarts";
|
||||
|
||||
public const string OK = "✓";
|
||||
public const string X = "✘";
|
||||
public const string TBD = "wird ermittelt";
|
||||
public const string OK = "OK";
|
||||
public const string X = "x";
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
using OmniPlus.Features;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace OmniPlus.UI.Inspection
|
||||
namespace OmniPlus
|
||||
{
|
||||
internal class OmniPlusDatabase
|
||||
{
|
||||
@@ -12,19 +11,135 @@ namespace OmniPlus.UI.Inspection
|
||||
public OmniPlusDatabase(string omniDatabase)
|
||||
=> this.connectionString = omniDatabase;
|
||||
|
||||
internal void AddOrUpdate(SystemParameters systemParameters)
|
||||
internal void AddOrUpdate(int position, SystemParameters systemParameters)
|
||||
{
|
||||
using (var sqlConnection = new SqlConnection(this.connectionString))
|
||||
{
|
||||
sqlConnection.OpenConnection();
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
INSERT
|
||||
INTO [OmniTestStates] ([Position])
|
||||
VALUES (@{nameof(position)})";
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(position), position));
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
sqlCommand.Parameters.Clear();
|
||||
}
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
UPDATE [OmniTestStates]
|
||||
SET [BuildInfo] = @{nameof(systemParameters.BuildInfo)}
|
||||
, [ManifacturingTime] = @{nameof(systemParameters.ManifacturingTime)}
|
||||
, [RebootsCount] = @{nameof(systemParameters.RebootsCount)}
|
||||
, [VersionAndType] = @{nameof(systemParameters.VersionAndType)}
|
||||
WHERE [Position] = @{nameof(position)}";
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(position), position));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(systemParameters.VersionAndType), systemParameters.VersionAndType.Value));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(systemParameters.RebootsCount), systemParameters.RebootsCount));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(systemParameters.ManifacturingTime), systemParameters.ManifacturingTime.DateTime));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(systemParameters.BuildInfo), systemParameters.BuildInfo.Value));
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
sqlCommand.Parameters.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal InputVolume GetInputVolume(object size)
|
||||
internal void LoadOmniPlusType(byte size, OmniPlusType omniType)
|
||||
{
|
||||
return new InputVolume();
|
||||
using (var sqlConnection = new SqlConnection(this.connectionString))
|
||||
{
|
||||
sqlConnection.OpenConnection();
|
||||
|
||||
var field = 0;
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
SELECT [Id]
|
||||
, [Size]
|
||||
, [Range]
|
||||
, [Direction]
|
||||
, [IntPart]
|
||||
, [Fraction]
|
||||
, [MlPerPulse] * [PulsePerRotation]
|
||||
FROM [OmniTestTypes]
|
||||
WHERE [Size] = @{nameof(size)}";
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(size), size));
|
||||
|
||||
using (var sqlDataReader = sqlCommand.ExecuteReader())
|
||||
{
|
||||
if (sqlDataReader.Read())
|
||||
{
|
||||
field = 0;
|
||||
|
||||
omniType.OmniId = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.Size = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.Range = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.Direction = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.IntPart = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.Fraction = (ushort)sqlDataReader.GetValue<int>(field++);
|
||||
omniType.MlPerRotation = sqlDataReader.GetValue<double>(field++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
SELECT [M3PerHour]
|
||||
, [Rotations]
|
||||
, [Duration]
|
||||
FROM [OmniTestPoints]
|
||||
WHERE [OmniTypeId] = @{nameof(omniType.OmniId)}
|
||||
AND [Enabled] = 1
|
||||
ORDER BY [GalPerMin] ASC";
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(omniType.OmniId), omniType.OmniId));
|
||||
|
||||
using (var sqlDataReader = sqlCommand.ExecuteReader())
|
||||
{
|
||||
while (sqlDataReader.Read())
|
||||
{
|
||||
field = 0;
|
||||
|
||||
omniType.TestPoints.Add(new OmniPlusTestPoint
|
||||
{
|
||||
VolumeM3H = sqlDataReader.GetValue<double>(field++),
|
||||
Rotations = (ushort)sqlDataReader.GetValue<short>(field++),
|
||||
Duration = (ushort)sqlDataReader.GetValue<short>(field++),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class OmniPlusDatabaseExtensions
|
||||
{
|
||||
public static void OpenConnection(this SqlConnection sqlConnection)
|
||||
{
|
||||
sqlConnection.FireInfoMessageEventOnUserErrors = true;
|
||||
sqlConnection.InfoMessage += SqlConnection_InfoMessage;
|
||||
sqlConnection.Open();
|
||||
}
|
||||
|
||||
internal IEnumerable<OmniPlusInspectionPoint> GetInspectionPoints(int size)
|
||||
private static void SqlConnection_InfoMessage(object _1, SqlInfoMessageEventArgs args)
|
||||
{
|
||||
return new OmniPlusInspectionPoint[] { };
|
||||
System.Console.WriteLine(args.Message);
|
||||
}
|
||||
|
||||
public static T GetValue<T>(this SqlDataReader reader, int field)
|
||||
{
|
||||
if (!reader.IsDBNull(field) && reader.GetValue(field) is T value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
USE [AuftragKopie];
|
||||
|
||||
IF OBJECT_ID(N'OmniTestStates') IS NOT NULL BEGIN DROP TABLE [OmniTestStates] END
|
||||
IF OBJECT_ID(N'OmniTestPoints') IS NOT NULL BEGIN DROP TABLE [OmniTestPoints] END
|
||||
IF OBJECT_ID(N'OmniTypes') IS NOT NULL BEGIN DROP TABLE [OmniTypes] END
|
||||
IF OBJECT_ID(N'OmniTestTypes') IS NOT NULL BEGIN DROP TABLE [OmniTestTypes] END
|
||||
|
||||
CREATE TABLE [OmniTypes] (
|
||||
CREATE TABLE [OmniTestTypes] (
|
||||
[Id] TINYINT NOT NULL IDENTITY(1, 1),
|
||||
[Type] VARCHAR(5) NOT NULL,
|
||||
[Size] TINYINT NOT NULL,
|
||||
@@ -11,39 +12,34 @@ CREATE TABLE [OmniTypes] (
|
||||
[Direction] TINYINT NOT NULL,
|
||||
[IntPart] TINYINT NOT NULL,
|
||||
[Fraction] INT NOT NULL,
|
||||
[FractionLSB] TINYINT NOT NULL,
|
||||
[FractionMSB] TINYINT NOT NULL,
|
||||
[CorrectionFactor] SMALLINT NOT NULL,
|
||||
[PulsePerRotation] TINYINT NOT NULL,
|
||||
[MlPerPulse] FLOAT NULL
|
||||
CONSTRAINT [PK_OmniTypes_Id] PRIMARY KEY ([Id])
|
||||
[MlPerPulse] FLOAT NULL
|
||||
CONSTRAINT [PK_OmniTestTypes_Id] PRIMARY KEY ([Id])
|
||||
);
|
||||
|
||||
SET IDENTITY_INSERT [OmniTypes] ON
|
||||
INSERT INTO [OmniTestTypes]
|
||||
([Type], [Size], [Range], [Direction], [IntPart], [Fraction], [CorrectionFactor], [PulsePerRotation])
|
||||
VALUES ( '1½"', 0x05, 0x00, 0x00, 0x00, 34017, 100, 8)
|
||||
, ( '2"', 0x06, 0x00, 0x00, 0x00, 34017, 100, 8)
|
||||
, ( '3"', 0x07, 0x01, 0x00, 0x01, 50827, 100, 8)
|
||||
, ( '4"', 0x08, 0x01, 0x00, 0x01, 50827, 100, 8)
|
||||
, ( '6"', 0x09, 0x02, 0x00, 0x06, 16754, 100, 8)
|
||||
, ( '8"', 0x0A, 0x03, 0x80, 0x01, 36814, 1000, 8)
|
||||
, ( '10"', 0x0B, 0x04, 0x80, 0x02, 21667, 1000, 8);
|
||||
|
||||
INSERT INTO [OmniTypes]
|
||||
([Id], [Type], [Size], [Range], [Direction], [IntPart], [Fraction], [FractionLSB], [FractionMSB], [CorrectionFactor], [PulsePerRotation])
|
||||
VALUES ( 1, '1½"', 0x05, 0x00, 0x00, 0x00, 34017, 0xE1, 0x84, 100, 8)
|
||||
, ( 2, '2"', 0x06, 0x00, 0x00, 0x00, 34017, 0xE1, 0x84, 100, 8)
|
||||
, ( 3, '3"', 0x07, 0x01, 0x00, 0x01, 50827, 0x8B, 0xC6, 100, 8)
|
||||
, ( 4, '4"', 0x08, 0x01, 0x00, 0x01, 50827, 0x8B, 0xC6, 100, 8)
|
||||
, ( 5, '6"', 0x09, 0x02, 0x00, 0x06, 16754, 0x72, 0x41, 100, 8)
|
||||
, ( 6, '8"', 0x0A, 0x03, 0x80, 0x01, 36814, 0xCE, 0x8F, 1000, 8)
|
||||
, ( 7, '10"', 0x0B, 0x04, 0x80, 0x02, 21667, 0xA3, 0x54, 1000, 8);
|
||||
|
||||
SET IDENTITY_INSERT [OmniTypes] OFF
|
||||
|
||||
UPDATE [OmniTypes] SET [MlPerPulse] = ([IntPart] + [Fraction] / 65535) * [CorrectionFactor];
|
||||
UPDATE [OmniTestTypes] SET [MlPerPulse] = ([IntPart] + [Fraction] / 65535.0) * [CorrectionFactor];
|
||||
|
||||
CREATE TABLE [OmniTestPoints] (
|
||||
[Id] SMALLINT NOT NULL IDENTITY(1, 1),
|
||||
[OmniTypeId] TINYINT NOT NULL,
|
||||
[GalPerMin] FLOAT NOT NULL,
|
||||
[M3PerHour] FLOAT NULL,
|
||||
[Rotations] SMALLINT NOT NULL,
|
||||
[Duration] SMALLINT NOT NULL,
|
||||
[Enabled] BIT NOT NULL DEFAULT(0)
|
||||
CONSTRAINT [PK_OmniTestPoints_Id] PRIMARY KEY ([Id]),
|
||||
CONSTRAINT [FK_OmniTestPoints_OmniTypeId_OmniPlus_Id] FOREIGN KEY ([OmniTypeId]) REFERENCES [OmniTypes]([Id]),
|
||||
CONSTRAINT [FK_OmniTestPoints_OmniTypeId_OmniPlus_Id] FOREIGN KEY ([OmniTypeId]) REFERENCES [OmniTestTypes]([Id]),
|
||||
CONSTRAINT [CHK_OmniTestPoints_Rotations] CHECK ([Rotations] BETWEEN 1 AND 5000),
|
||||
CONSTRAINT [CHK_OmniTestPoints_Duration] CHECK ([Duration] BETWEEN 1 AND 3600)
|
||||
);
|
||||
@@ -111,7 +107,9 @@ VALUES ( 1, 200.00, 900, 36)
|
||||
, ( 7, 3.50, 4, 406);
|
||||
|
||||
UPDATE [OmniTestPoints]
|
||||
SET [Enabled] = 1
|
||||
SET [Enabled] = 1
|
||||
--------------------------------ml. in Gal--------l-----m³---min. in hour
|
||||
, [M3PerHour] = ([GalPerMin] * 3785.411784) / 1000 / 1000 * 60 --------
|
||||
FROM [OmniTestPoints] AS [Current]
|
||||
JOIN (SELECT [OmniTypeId] AS [TypeId]
|
||||
, MIN([GalPerMin]) AS [Min]
|
||||
@@ -121,4 +119,14 @@ UPDATE [OmniTestPoints]
|
||||
AS [Aggregated]
|
||||
ON [Aggregated].[TypeId] = [Current].[OmniTypeId]
|
||||
AND ([Aggregated].[Min] = [Current].[GalPerMin]
|
||||
OR [Aggregated].[Max] = [Current].[GalPerMin])
|
||||
OR [Aggregated].[Max] = [Current].[GalPerMin]);
|
||||
|
||||
CREATE TABLE [OmniTestStates] (
|
||||
[Position] INT NOT NULL,
|
||||
[BuildInfo] VARCHAR(50) NULL,
|
||||
[ManifacturingTime] DATETIME NULL,
|
||||
[RebootsCount] TINYINT NULL,
|
||||
[VersionAndType] VARCHAR(50) NULL,
|
||||
CONSTRAINT [PK_OmniTestStates_Position] PRIMARY KEY ([Position]),
|
||||
CONSTRAINT [CHK_OmniTestStates_Position] CHECK ([Position] BETWEEN 1 AND 10)
|
||||
);
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace OmniPlus.UI.Inspection
|
||||
{
|
||||
using System;
|
||||
|
||||
internal struct OmniPlusInspectionPoint : IComparable<OmniPlusInspectionPoint>
|
||||
{
|
||||
public double FlowRate { get; set; }
|
||||
|
||||
public ushort Rotations { get; set; }
|
||||
|
||||
public ushort Seconds { get; set; }
|
||||
|
||||
public int CompareTo(OmniPlusInspectionPoint other)
|
||||
=> this.Rotations.CompareTo(other.Rotations);
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OmniPlus.UI.Inspection
|
||||
namespace OmniPlus
|
||||
{
|
||||
internal class OmniPlusMeter
|
||||
{
|
||||
private readonly IDictionary<OmniPlusInspectionPoint, double> inspectionPoints;
|
||||
private readonly IDictionary<OmniPlusInspectionPoint, ChamberCalibration> calibrationResults;
|
||||
private readonly IDictionary<OmniPlusTestPoint, double> inspectionPoints;
|
||||
private readonly IDictionary<OmniPlusTestPoint, ChamberCalibration> calibrationResults;
|
||||
|
||||
private InputVolume inputVolume;
|
||||
private SystemParameters systemParameters;
|
||||
@@ -18,42 +18,24 @@ namespace OmniPlus.UI.Inspection
|
||||
this.Connected = connected;
|
||||
this.inputVolume = new InputVolume();
|
||||
this.systemParameters = new SystemParameters();
|
||||
this.inspectionPoints = new Dictionary<OmniPlusInspectionPoint, double>();
|
||||
this.calibrationResults = new Dictionary<OmniPlusInspectionPoint, ChamberCalibration>();
|
||||
this.inspectionPoints = new Dictionary<OmniPlusTestPoint, double>();
|
||||
this.calibrationResults = new Dictionary<OmniPlusTestPoint, ChamberCalibration>();
|
||||
}
|
||||
|
||||
public bool Connected { get; set; }
|
||||
|
||||
public bool Initialized { get; set; }
|
||||
public bool Initialized
|
||||
=> this.RebootsCount != 0xFF
|
||||
&& this.FirmwareInRange
|
||||
&& this.ManifacturingTimeInRange
|
||||
&& this.SystemTimeInRange
|
||||
&& this.VoltsInRange
|
||||
&& !this.FactorySealed;
|
||||
|
||||
public bool CanCalibrate { get; set; } = true;
|
||||
|
||||
public bool Calibrated { get; private set; }
|
||||
|
||||
public byte Size
|
||||
{
|
||||
get => this.inputVolume.Size;
|
||||
set => this.inputVolume.Size = value;
|
||||
}
|
||||
|
||||
public byte Range
|
||||
{
|
||||
get => this.inputVolume.Range;
|
||||
set => this.inputVolume.Range = value;
|
||||
}
|
||||
|
||||
public ushort IntPart
|
||||
{
|
||||
get => this.inputVolume.IntPart;
|
||||
set => this.inputVolume.IntPart = value;
|
||||
}
|
||||
|
||||
public ushort Fraction
|
||||
{
|
||||
get => this.inputVolume.Fraction;
|
||||
set => this.inputVolume.Fraction = value;
|
||||
}
|
||||
|
||||
public string BuildInfo
|
||||
{
|
||||
get => this.systemParameters.BuildInfo.Value.Trim('\0');
|
||||
@@ -98,13 +80,7 @@ namespace OmniPlus.UI.Inspection
|
||||
set => this.systemParameters.BatteryVoltage.Volts = (ushort)(value * 1000);
|
||||
}
|
||||
|
||||
public bool VoltsInRange => 3.19 <= this.Volts && this.Volts <= 3.75;
|
||||
|
||||
public uint ADCCounts
|
||||
{
|
||||
get => this.systemParameters.BatteryVoltage.ADCCount;
|
||||
set => this.systemParameters.BatteryVoltage.ADCCount = value;
|
||||
}
|
||||
public bool VoltsInRange => 3.19 <= this.Volts && this.Volts <= 3.75;
|
||||
|
||||
public bool FactorySealed
|
||||
{
|
||||
@@ -112,21 +88,6 @@ namespace OmniPlus.UI.Inspection
|
||||
set => this.systemParameters.FactorySealed = value;
|
||||
}
|
||||
|
||||
public double MlPerPulse { get; private set; }
|
||||
|
||||
internal void AddInputVolume(InputVolume inputVolume)
|
||||
{
|
||||
if (inputVolume != null)
|
||||
{
|
||||
this.inputVolume = inputVolume;
|
||||
|
||||
if (this.inputVolume.Fraction > 0)
|
||||
{
|
||||
this.MlPerPulse = this.inputVolume.Fraction / ushort.MaxValue * this.inputVolume.Factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddSystemParameters(SystemParameters systemParameters)
|
||||
{
|
||||
if (systemParameters != null)
|
||||
@@ -143,13 +104,13 @@ namespace OmniPlus.UI.Inspection
|
||||
var versionString = firmwareTokens[0]?.Substring(1) ?? string.Empty;
|
||||
var versionParsed = double.TryParse(versionString, out var version);
|
||||
var typeString = firmwareTokens[1]?.ToUpper() ?? string.Empty;
|
||||
var isOmni = typeString == "OMNI-1" || typeString == "OMNI-2";
|
||||
var isOmni = typeString == "OMNI-01" || typeString == "OMNI-02";
|
||||
|
||||
this.FirmwareInRange = versionParsed && version >= 1.23 && isOmni;
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddCalibrationResult(OmniPlusInspectionPoint point, ChamberCalibration result)
|
||||
internal void AddCalibrationResult(OmniPlusTestPoint point, ChamberCalibration result)
|
||||
{
|
||||
this.calibrationResults[point] = result;
|
||||
|
||||
@@ -161,14 +122,5 @@ namespace OmniPlus.UI.Inspection
|
||||
&& result.Control == ChamberCalibration.TEST_COMPLETED;
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddInspectionVolume(OmniPlusInspectionPoint point, double volume)
|
||||
=> this.inspectionPoints[point] = volume;
|
||||
|
||||
internal double CalculateCorrectionFactor()
|
||||
{
|
||||
// TODO: calculate correction factor.
|
||||
return double.MinValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
public delegate void OmniPlusStateChanged(int column, bool? succeeded, string header, string value);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
namespace OmniPlus.UI.Inspection
|
||||
{
|
||||
public delegate void OmniPlusStateChangedEventHandler(int column, bool? succeeded, string header, string value);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
using System;
|
||||
|
||||
public struct OmniPlusTestPoint : IComparable<OmniPlusTestPoint>
|
||||
{
|
||||
public double VolumeM3H { get; set; }
|
||||
|
||||
public ushort Rotations { get; set; }
|
||||
|
||||
public ushort Duration { get; set; }
|
||||
|
||||
public int CompareTo(OmniPlusTestPoint other)
|
||||
=> this.Rotations.CompareTo(other.Rotations);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using OmniPlus.Features;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OmniPlus
|
||||
{
|
||||
public class OmniPlusType
|
||||
{
|
||||
public byte OmniId { get; set; }
|
||||
|
||||
public byte Size
|
||||
{
|
||||
get => this.InputVolume.Size;
|
||||
set => this.InputVolume.Size = value;
|
||||
}
|
||||
|
||||
public byte Range
|
||||
{
|
||||
get => this.InputVolume.Range;
|
||||
set => this.InputVolume.Range = value;
|
||||
}
|
||||
|
||||
public byte Direction
|
||||
{
|
||||
get => this.InputVolume.Direction;
|
||||
set => this.InputVolume.Direction = value;
|
||||
}
|
||||
|
||||
public byte IntPart
|
||||
{
|
||||
get => this.InputVolume.IntPart;
|
||||
set => this.InputVolume.IntPart = value;
|
||||
}
|
||||
|
||||
public ushort Fraction
|
||||
{
|
||||
get => this.InputVolume.Fraction;
|
||||
set => this.InputVolume.Fraction = value;
|
||||
}
|
||||
|
||||
public double MlPerRotation { get; set; }
|
||||
|
||||
public InputVolume InputVolume { get; }
|
||||
= new InputVolume();
|
||||
|
||||
public ICollection<OmniPlusTestPoint> TestPoints { get; }
|
||||
= new List<OmniPlusTestPoint>();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user