calculation of the correction factor
This commit is contained in:
@@ -187,8 +187,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeHub", "ExchangeHub\
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OMNIPruefung", "OMNIPruefung\OMNIPruefung.csproj", "{D766BA80-CCA1-4D05-96B9-AAE520F30595}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Abstraction", "CommonCore\Common.Abstraction\Common.Abstraction.csproj", "{1743B349-E347-4DCF-A106-15AE3F95C3A3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeUI", "ExchangeUI\ExchangeUI.csproj", "{482A8486-AE5E-4508-92AA-51B096945B18}"
|
||||
EndProject
|
||||
Global
|
||||
@@ -4385,70 +4383,6 @@ Global
|
||||
{D766BA80-CCA1-4D05-96B9-AAE520F30595}.XP32bit|x64.Build.0 = Release|Any CPU
|
||||
{D766BA80-CCA1-4D05-96B9-AAE520F30595}.XP32bit|x86.ActiveCfg = Release|Any CPU
|
||||
{D766BA80-CCA1-4D05-96B9-AAE520F30595}.XP32bit|x86.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}._MANUAL_CONTROL|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}._MANUAL_CONTROL|x64.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}._MANUAL_CONTROL|x64.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}._MANUAL_CONTROL|x86.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}._MANUAL_CONTROL|x86.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.COM|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.COM|Any CPU.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.COM|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.COM|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.COM|x64.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.COM|x64.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.COM|x86.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.COM|x86.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.GenesisDisplayTool_V01|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.GenesisDisplayTool_V01|Any CPU.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.GenesisDisplayTool_V01|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.GenesisDisplayTool_V01|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.GenesisDisplayTool_V01|x64.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.GenesisDisplayTool_V01|x64.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.GenesisDisplayTool_V01|x86.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.GenesisDisplayTool_V01|x86.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.PerformTest|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.PerformTest|Any CPU.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.PerformTest|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.PerformTest|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.PerformTest|x64.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.PerformTest|x64.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.PerformTest|x86.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.PerformTest|x86.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.ReleaseTest|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.ReleaseTest|Any CPU.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.ReleaseTest|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.ReleaseTest|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.ReleaseTest|x64.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.ReleaseTest|x64.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.ReleaseTest|x86.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.ReleaseTest|x86.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.XP32bit|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.XP32bit|Any CPU.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.XP32bit|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.XP32bit|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.XP32bit|x64.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.XP32bit|x64.Build.0 = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.XP32bit|x86.ActiveCfg = Release|Any CPU
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3}.XP32bit|x86.Build.0 = Release|Any CPU
|
||||
{482A8486-AE5E-4508-92AA-51B096945B18}._MANUAL_CONTROL|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{482A8486-AE5E-4508-92AA-51B096945B18}._MANUAL_CONTROL|Any CPU.Build.0 = Release|Any CPU
|
||||
{482A8486-AE5E-4508-92AA-51B096945B18}._MANUAL_CONTROL|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
@@ -4597,7 +4531,6 @@ Global
|
||||
{6518211A-E83F-4171-97C4-A61FCF66D6E0} = {68323534-4337-4E3A-89BC-11D8BB55343A}
|
||||
{6033FF0C-CF32-4BC5-8EFE-4774CCDC663D} = {68323534-4337-4E3A-89BC-11D8BB55343A}
|
||||
{D766BA80-CCA1-4D05-96B9-AAE520F30595} = {68323534-4337-4E3A-89BC-11D8BB55343A}
|
||||
{1743B349-E347-4DCF-A106-15AE3F95C3A3} = {C17363DF-A043-4F25-8EBA-2B3B078227DC}
|
||||
{482A8486-AE5E-4508-92AA-51B096945B18} = {68323534-4337-4E3A-89BC-11D8BB55343A}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
|
||||
+30
-233
@@ -1,255 +1,52 @@
|
||||
namespace CommonConsole
|
||||
using System;
|
||||
|
||||
namespace CommonConsole
|
||||
{
|
||||
using OmniPlus;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
var connection = new IRDAPort();
|
||||
var response = connection.Send(0x01);
|
||||
Console.WriteLine(Encoding.ASCII.GetString(response));
|
||||
var rotations = BitConverter.ToInt16(new byte[] { 0x84, 0x03 }, 0);
|
||||
Console.WriteLine($"Rotations: {rotations}");
|
||||
|
||||
response = connection.Send(0xFD, 0xC6);
|
||||
Console.WriteLine(Encoding.ASCII.GetString(response));
|
||||
var duration = BitConverter.ToUInt32(new byte[] { 0x5C, 0xCF, 0x0E, 0x00 }, 0);
|
||||
Console.WriteLine($"Duration: {duration}");
|
||||
|
||||
connection.Dispose();
|
||||
}
|
||||
}
|
||||
var seconds = duration * 1D / (short.MaxValue + 1);
|
||||
Console.WriteLine($"Seconds: {seconds}");
|
||||
|
||||
public abstract class Port : IDisposable
|
||||
{
|
||||
private readonly String name;
|
||||
private readonly Int32 bauds;
|
||||
private readonly Int32 data;
|
||||
private readonly Parity parity;
|
||||
private readonly StopBits stop;
|
||||
Console.WriteLine();
|
||||
|
||||
private SerialPort port;
|
||||
rotations = BitConverter.ToInt16(new byte[] { 0x04, 0x00 }, 0);
|
||||
Console.WriteLine($"Rotations: {rotations}");
|
||||
|
||||
protected Port(String name, Int32 bauds, Int32 data, Parity parity, StopBits stop)
|
||||
{
|
||||
this.name = name;
|
||||
this.bauds = bauds;
|
||||
this.data = data;
|
||||
this.parity = parity;
|
||||
this.stop = stop;
|
||||
}
|
||||
duration = BitConverter.ToUInt32(new byte[] { 0x6F, 0x85, 0x0D, 0x00 }, 0);
|
||||
Console.WriteLine($"Duration: {duration}");
|
||||
|
||||
protected bool IsOpen => this.port?.IsOpen ?? false;
|
||||
seconds = duration * 1D / (short.MaxValue + 1);
|
||||
Console.WriteLine($"Seconds: {seconds}");
|
||||
|
||||
protected Stream Stream => this.port.BaseStream;
|
||||
Console.WriteLine();
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.port != null)
|
||||
{
|
||||
this.port.Disposed -= this.Port_Disposed;
|
||||
this.port.ErrorReceived -= this.Port_ErrorReceived;
|
||||
rotations = BitConverter.ToInt16(new byte[] { 0x08, 0x00 }, 0);
|
||||
Console.WriteLine($"Rotations: {rotations}");
|
||||
|
||||
this.port.Close();
|
||||
this.port.Dispose();
|
||||
this.port = null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
duration = BitConverter.ToUInt32(new byte[] { 0x4F, 0xFA, 0x11, 0x00 }, 0);
|
||||
Console.WriteLine($"Duration: {duration}");
|
||||
|
||||
Console.WriteLine("... Port disposed");
|
||||
}
|
||||
seconds = duration * 1D / (short.MaxValue + 1);
|
||||
Console.WriteLine($"Seconds: {seconds}");
|
||||
|
||||
protected virtual void Open()
|
||||
{
|
||||
this.Dispose();
|
||||
Console.WriteLine();
|
||||
|
||||
try
|
||||
{
|
||||
this.port = new SerialPort
|
||||
{
|
||||
PortName = this.name,
|
||||
BaudRate = this.bauds,
|
||||
DataBits = this.data,
|
||||
Parity = this.parity,
|
||||
StopBits = this.stop,
|
||||
};
|
||||
rotations = BitConverter.ToInt16(new byte[] { 0xE8, 0x03 }, 0);
|
||||
Console.WriteLine($"Rotations: {rotations}");
|
||||
|
||||
this.port.Disposed += this.Port_Disposed;
|
||||
this.port.ErrorReceived += this.Port_ErrorReceived;
|
||||
duration = BitConverter.ToUInt32(new byte[] { 0xA1, 0xFB, 0x10, 0x00 }, 0);
|
||||
Console.WriteLine($"Duration: {duration}");
|
||||
|
||||
this.port.Open();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
|
||||
Console.WriteLine("... Port created");
|
||||
}
|
||||
|
||||
private void Port_Disposed(Object sender, EventArgs args)
|
||||
{
|
||||
this.Dispose();
|
||||
|
||||
Console.WriteLine("... Port disposed internal");
|
||||
}
|
||||
|
||||
private void Port_ErrorReceived(Object sender, SerialErrorReceivedEventArgs args)
|
||||
{
|
||||
Console.WriteLine("... Port error received");
|
||||
Console.WriteLine($"... {args.EventType}");
|
||||
|
||||
if (!this.port.IsOpen)
|
||||
{
|
||||
this.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class IRDAPort : Port
|
||||
{
|
||||
public IRDAPort() : base("COM26", 115200, 8, Parity.None, StopBits.One)
|
||||
{
|
||||
}
|
||||
|
||||
public Byte[] Send(params Byte[] request)
|
||||
{
|
||||
Console.WriteLine(">>> " + BitConverter.ToString(request));
|
||||
|
||||
if (!this.IsOpen)
|
||||
{
|
||||
this.Open();
|
||||
}
|
||||
|
||||
var response = new Byte[] { };
|
||||
|
||||
if (!this.IsOpen || !this.Stream.CanWrite || !this.Stream.CanRead)
|
||||
{
|
||||
return response;
|
||||
}
|
||||
|
||||
Console.WriteLine(">>> 1-1-1-1");
|
||||
this.Stream.Write(new byte[] { 1, 1, 1, 1 }, 0, 4);
|
||||
|
||||
request = request
|
||||
.ToUI1236Message()
|
||||
.ToIrdaMessage();
|
||||
|
||||
Console.WriteLine(">>> " + BitConverter.ToString(request));
|
||||
|
||||
var asyncState = new IRDAAsyncState
|
||||
{
|
||||
Request = request,
|
||||
Stream = this.Stream
|
||||
};
|
||||
|
||||
var lock_object = new object();
|
||||
|
||||
lock (lock_object)
|
||||
{
|
||||
Task.Factory.StartNew(asyncState.BeginReadAsync, asyncState.CancellationToken);
|
||||
|
||||
asyncState.BeginWriteAsync(request);
|
||||
}
|
||||
|
||||
return asyncState.Response;
|
||||
}
|
||||
}
|
||||
|
||||
public class IRDAAsyncState
|
||||
{
|
||||
private readonly ManualResetEventSlim manualResetEventSlim;
|
||||
private readonly CancellationTokenSource cancellationTokenSource;
|
||||
|
||||
public IRDAAsyncState()
|
||||
{
|
||||
this.manualResetEventSlim = new ManualResetEventSlim();
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
this.CancellationToken = this.cancellationTokenSource.Token;
|
||||
this.Buffer = new Byte[256];
|
||||
}
|
||||
|
||||
public Byte[] Buffer { get; private set; }
|
||||
|
||||
public Byte[] Request { get; set; }
|
||||
|
||||
public Byte[] Response { get; set; }
|
||||
|
||||
public Stream Stream { get; set; }
|
||||
|
||||
public CancellationToken CancellationToken { get; }
|
||||
|
||||
internal void BeginReadAsync()
|
||||
{
|
||||
this.Response = null;
|
||||
|
||||
var asyncResult = this.Stream.BeginRead(this.Buffer, 0, this.Buffer.Length, this.EndReadAsync, this);
|
||||
|
||||
asyncResult.AsyncWaitHandle.WaitOne();
|
||||
|
||||
if (this.Response is null)
|
||||
{
|
||||
this.BeginReadAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.manualResetEventSlim.Set();
|
||||
}
|
||||
}
|
||||
|
||||
private void EndReadAsync(IAsyncResult asyncResult)
|
||||
{
|
||||
if (asyncResult.AsyncState is IRDAAsyncState asyncState)
|
||||
{
|
||||
var bytesLength = asyncState.Stream.EndRead(asyncResult);
|
||||
|
||||
if (this.Response is null)
|
||||
{
|
||||
var response = new Byte[bytesLength];
|
||||
|
||||
Array.Copy(this.Buffer, 0, response, 0, bytesLength);
|
||||
|
||||
Console.WriteLine("<<< " + BitConverter.ToString(response));
|
||||
|
||||
response = response
|
||||
.FromIrdaMessage()
|
||||
.FromUI1236Message();
|
||||
|
||||
Console.WriteLine("<<< " + BitConverter.ToString(response));
|
||||
|
||||
if (response.Length != 0)
|
||||
{
|
||||
this.Response = response;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void BeginWriteAsync(Byte[] request)
|
||||
{
|
||||
var asyncResult = this.Stream.BeginWrite(request, 0, request.Length, this.EndWriteAsync, this);
|
||||
|
||||
asyncResult.AsyncWaitHandle.WaitOne();
|
||||
|
||||
this.manualResetEventSlim.Wait();
|
||||
}
|
||||
|
||||
private void EndWriteAsync(IAsyncResult asyncResult)
|
||||
{
|
||||
if (asyncResult.AsyncState is IRDAAsyncState asyncState)
|
||||
{
|
||||
asyncState.Stream.EndWrite(asyncResult);
|
||||
}
|
||||
seconds = duration * 1D / (short.MaxValue + 1);
|
||||
Console.WriteLine($"Seconds: {seconds}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<appSettings>
|
||||
<add key="PSNR" value="2015"/>
|
||||
<add key="Type" value="T2" />
|
||||
<add key="COMPorts" value="COM26" />
|
||||
<add key="COMPorts" value="COM4" />
|
||||
<add key="ExchangeHubURL" value="http://sla12iis01.emea.sensus.net/LaaProductionWeb" />
|
||||
<add key="OmniDB" value="Server=SLASQL01.emea.sensus.net; Database=AuftragKopie; User ID=sa; Password=sqlserver;" />
|
||||
</appSettings>
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<Compile Include="Helpers\BooleanVisibilityConverter.cs" />
|
||||
<Compile Include="Models\Appsettings.cs" />
|
||||
<Compile Include="ViewModels\Content\SettingsContentVM.cs" />
|
||||
<Compile Include="ViewModels\Features\OMNIPlus.cs" />
|
||||
<Compile Include="ViewModels\Features\OMNIPlusVM.cs" />
|
||||
<Compile Include="ViewModels\Base\Command.cs" />
|
||||
<Compile Include="ViewModels\Base\Command[T].cs" />
|
||||
<Compile Include="ViewModels\Base\VM[T].cs" />
|
||||
|
||||
@@ -136,7 +136,11 @@
|
||||
this.Running = false;
|
||||
}
|
||||
|
||||
internal void InitializeAsync()
|
||||
internal Task InitializeAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.Dispose);
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
this.results.Clear();
|
||||
|
||||
@@ -151,27 +155,13 @@
|
||||
|
||||
if (!this.Connected)
|
||||
{
|
||||
Thread.Sleep(2000);
|
||||
|
||||
this.Connected = this.connection.ConnectIrda();
|
||||
this.Running = this.Connected;
|
||||
}
|
||||
|
||||
if (this.Connected)
|
||||
if (this.IsRunning())
|
||||
{
|
||||
this.State = "Mit IRDA verbunden";
|
||||
|
||||
this.Meter.SystemParameters = this.connection.ViewSystemParameters();
|
||||
this.Header = this.Meter.SystemParameters.BuildInfo;
|
||||
this.Running = this.Meter.SystemParameters.IsValid;
|
||||
|
||||
if (this.Running)
|
||||
{
|
||||
this.State = this.Meter.SystemParameters.BuildInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.State = $"({this.PortName} - fehler!)";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -184,30 +174,28 @@
|
||||
catch (Exception e)
|
||||
{
|
||||
this.connection.Disconnect();
|
||||
this.Meter.Error = e.Message;
|
||||
this.Header = $"({this.PortName} - nicht vorhanden!)";
|
||||
this.State = this.Header;
|
||||
}
|
||||
}
|
||||
|
||||
internal Task ReadSystemParametersTask(CancellationToken cancelationToken)
|
||||
return Task.Factory.StartNew(Initialize, cancellationToken);
|
||||
}
|
||||
|
||||
internal Task ReadSystemParametersAsync(CancellationToken cancelationToken)
|
||||
{
|
||||
cancelationToken.Register(this.Dispose);
|
||||
|
||||
void ReadSystemParameters()
|
||||
{
|
||||
if (!this.Running)
|
||||
if (this.IsRunning())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var response = this.connection.ViewSystemParameters();
|
||||
|
||||
this.Connected = this.connection.Connected;
|
||||
this.Meter.Add(response);
|
||||
|
||||
if (this.Connected)
|
||||
{
|
||||
this.Meter.SystemParameters = this.connection.ViewSystemParameters();
|
||||
this.Header = this.Meter.SystemParameters.BuildInfo;
|
||||
this.Running = this.Meter.SystemParameters.IsValid;
|
||||
this.Header = response.BuildInfo.Value;
|
||||
this.Running = response.IsValid;
|
||||
|
||||
if (this.Running)
|
||||
{
|
||||
@@ -229,19 +217,12 @@
|
||||
return Task.Factory.StartNew(ReadSystemParameters, cancelationToken);
|
||||
}
|
||||
|
||||
internal Task SetInputVolumeTask(OmniPlusType defaults, CancellationToken cancelationToken)
|
||||
internal Task SetInputVolumeAsync(OmniPlusType defaults, CancellationToken cancelationToken)
|
||||
{
|
||||
cancelationToken.Register(this.Dispose);
|
||||
|
||||
void SetInputVolume()
|
||||
{
|
||||
if (!this.Running)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.Connected = this.connection.Connected;
|
||||
|
||||
if (this.Connected)
|
||||
{
|
||||
var response = this.connection.Set(defaults.InputVolume);
|
||||
@@ -267,92 +248,33 @@
|
||||
return Task.Factory.StartNew(SetInputVolume, cancelationToken);
|
||||
}
|
||||
|
||||
internal Task InspectPPTask(OmniPlusTestPoint pp, CancellationToken cancelationToken)
|
||||
internal Task SetReferenceVolumeAsync(OmniPlusTestPoint pp, double referenceV, CancellationToken cancellationToken)
|
||||
{
|
||||
cancelationToken.Register(this.Dispose);
|
||||
cancellationToken.Register(this.Dispose);
|
||||
|
||||
void InspectPP()
|
||||
void SetReferenceVolume()
|
||||
{
|
||||
if (!this.Running)
|
||||
if (this.results.ContainsKey(pp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.Connected = this.connection.Connected;
|
||||
this.results[pp] = new OmniPlusTest();
|
||||
|
||||
var rotations = pp.Rotations;
|
||||
var duration = pp.Duration;
|
||||
|
||||
if (this.Connected)
|
||||
{
|
||||
var activationResponse = connection.StartChamberCalibration(rotations, duration);
|
||||
this.Running = activationResponse.Succeeded;
|
||||
|
||||
if (this.Running)
|
||||
{
|
||||
var format = $"Prüfung für {rotations}/{duration} (rotations/seconds) Bereit in {{0}} Sekunden";
|
||||
var _duration = pp.Duration;
|
||||
|
||||
while (_duration > 0 && !cancelationToken.IsCancellationRequested)
|
||||
{
|
||||
this.State = string.Format(format, _duration--);
|
||||
|
||||
Thread.Sleep(1200);
|
||||
}
|
||||
|
||||
this.AvailableIn = _duration;
|
||||
this.State = "Das Ergebnis wird ermittelt ...";
|
||||
var calibrationResult = connection.ViewChamberCalibration();
|
||||
this.Running = calibrationResult.Succeeded;
|
||||
|
||||
if (!this.Running)
|
||||
{
|
||||
this.State = $"Prüfung für {rotations}/{duration} (rotations/seconds) fehlgeschlagen: ({calibrationResult.Status})";
|
||||
}
|
||||
else if (calibrationResult.Control != ChamberCalibrationResponse.TEST_COMPLETED)
|
||||
{
|
||||
var controlNr = calibrationResult.Control;
|
||||
var controlTxt = controlNr == ChamberCalibrationResponse.TEST_ACTIVATED
|
||||
? nameof(ChamberCalibrationResponse.TEST_ACTIVATED)
|
||||
: nameof(ChamberCalibrationResponse.TEST_FAILED);
|
||||
|
||||
this.Running = false;
|
||||
this.State = $"Prüfung für {rotations}/{duration} (rotations/seconds) fehlgeschlagen: ({controlNr} - {controlTxt})";
|
||||
}
|
||||
else // process calibration
|
||||
{
|
||||
this.State = $"Prüfung für {rotations}/{duration} (rotations/seconds) erfolgreich";
|
||||
|
||||
this.results[pp].Duration = calibrationResult.Duration;
|
||||
this.results[pp].Rotations = calibrationResult.Rotations;
|
||||
this.results[pp].VolumeMessured = referenceV;
|
||||
}
|
||||
}
|
||||
else // not activated
|
||||
{
|
||||
this.State = $"Prüfung activierung fehlgeschlagen: ({(int)activationResponse.Status} - {activationResponse.Status})";
|
||||
}
|
||||
}
|
||||
else // not connected or running
|
||||
{
|
||||
this.State = $"PP {rotations}/{duration} (rotations/seconds) wurde aufgrund ungültiger Eigenschaften abgebrochen";
|
||||
|
||||
return Task.Factory.StartNew(SetReferenceVolume, cancellationToken);
|
||||
}
|
||||
|
||||
this.Progress += 10;
|
||||
}
|
||||
|
||||
return Task.Factory.StartNew(InspectPP, cancelationToken);
|
||||
}
|
||||
|
||||
internal void SaveInspection()
|
||||
internal Task SaveInspectionAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!this.Running)
|
||||
cancellationToken.Register(this.Dispose);
|
||||
|
||||
void SaveInspection()
|
||||
{
|
||||
if (!this.IsRunning())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var resultsBuilder = new StringBuilder();
|
||||
var correctionFactor = this.GetCorrectionFactor();
|
||||
|
||||
resultsBuilder.AppendLine($"GPM\t"
|
||||
+ $"m³/h\t"
|
||||
@@ -381,36 +303,70 @@
|
||||
+ $"{ergebnis.Duration}\t"
|
||||
+ $"{ergebnis.VolumeMessured}\t"
|
||||
+ $"{ergebnis.DifferencePercentage:0.00}%\t"
|
||||
+ $"{correctionFactor:0.00}%\t"
|
||||
+ $"{this.GetCorrectionFactor():0.00}%\t"
|
||||
+ $"{pruefpunkt.MinDiff:0.00}\t"
|
||||
+ $"{pruefpunkt.MaxDiff:0.00}\t");
|
||||
}
|
||||
|
||||
this.TestResults = resultsBuilder.ToString();
|
||||
|
||||
// TODO: Log for instance in databse table.
|
||||
try
|
||||
{
|
||||
File.WriteAllText($"{this.Meter.SystemParameters.BuildInfo}_{DateTime.Now:yyyyMMddHHmmss}.csv", this.TestResults);
|
||||
File.WriteAllText($"{this.Header}_{DateTime.Now:yyyyMMddHHmmss}.csv", this.TestResults);
|
||||
}
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
this.State = e.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
internal Task StopPPCalibrationTask(OmniPlusTestPoint pp, CancellationToken cancellationToken)
|
||||
return Task.Factory.StartNew(SaveInspection, cancellationToken);
|
||||
}
|
||||
|
||||
internal Task StartPPCalibrationAsync(OmniPlusTestPoint pp, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.Dispose);
|
||||
|
||||
void StartPPCalibration()
|
||||
{
|
||||
this.results[pp] = new OmniPlusTest();
|
||||
|
||||
//if (this.IsRunning())
|
||||
//{
|
||||
// var rotations = pp.Rotations;
|
||||
// var duration = pp.Duration;
|
||||
// var activationResponse = connection.StartChamberCalibration(pp.Rotations, pp.Duration);
|
||||
// this.Running = activationResponse.Succeeded && activationResponse.Control == ChamberCalibrationResponse.TEST_ACTIVATED;
|
||||
|
||||
// if (this.Running)
|
||||
// {
|
||||
// this.State = $"PP {rotations}/{duration} (rotations/seconds) wurde gestarted.";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// this.State = $"PP {rotations}/{duration} (rotations/seconds): {(int)activationResponse.Status} - {activationResponse.Status}";
|
||||
// }
|
||||
//}
|
||||
|
||||
this.Progress += 10;
|
||||
}
|
||||
|
||||
return Task.Factory.StartNew(StartPPCalibration, cancellationToken);
|
||||
}
|
||||
|
||||
internal Task StopPPCalibrationAsync(OmniPlusTestPoint pp, byte[] response, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.Dispose);
|
||||
|
||||
void StopPPCalibration()
|
||||
{
|
||||
if (this.Running && this.Connected)
|
||||
if (this.IsRunning())
|
||||
{
|
||||
var calibrationResult = connection.ViewChamberCalibration();
|
||||
// var calibrationResult = connection.ViewChamberCalibration();
|
||||
var calibrationResult = new ChamberCalibrationResponse(response);
|
||||
this.results[pp].Rotations = calibrationResult.Rotations;
|
||||
this.results[pp].Duration = calibrationResult.Duration;
|
||||
this.results[pp].VolumeMessured = pp.VolumeM3(this.results[pp]);
|
||||
this.results[pp].MeterVolume = pp.VolumeM3(this.results[pp]);
|
||||
|
||||
this.Running = calibrationResult.Succeeded && calibrationResult.Control == ChamberCalibrationResponse.TEST_COMPLETED;
|
||||
|
||||
@@ -430,62 +386,25 @@
|
||||
return Task.Factory.StartNew(StopPPCalibration, cancellationToken);
|
||||
}
|
||||
|
||||
internal Task StartPPCalibrationTask(OmniPlusTestPoint pp, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.Dispose);
|
||||
|
||||
void StartPPCalibration()
|
||||
{
|
||||
this.results[pp] = new OmniPlusTest();
|
||||
|
||||
if (this.Running && this.Connected)
|
||||
{
|
||||
var rotations = pp.Rotations;
|
||||
var duration = pp.Duration;
|
||||
var activationResponse = connection.StartChamberCalibration(pp.Rotations, pp.Duration);
|
||||
this.Running = activationResponse.Succeeded && activationResponse.Control == ChamberCalibrationResponse.TEST_ACTIVATED;
|
||||
|
||||
if (this.Running)
|
||||
{
|
||||
this.State = $"PP {rotations}/{duration} (rotations/seconds) wurde gestarted.";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.State = $"PP {rotations}/{duration} (rotations/seconds): {(int)activationResponse.Status} - {activationResponse.Status}";
|
||||
}
|
||||
}
|
||||
|
||||
this.Progress += 10;
|
||||
}
|
||||
|
||||
return Task.Factory.StartNew(StartPPCalibration, cancellationToken);
|
||||
}
|
||||
|
||||
internal void SetReferenceVolume(OmniPlusTestPoint pp, double referenceV)
|
||||
{
|
||||
if (this.results.ContainsKey(pp))
|
||||
{
|
||||
this.results[pp].VolumeMessured = referenceV;
|
||||
}
|
||||
}
|
||||
|
||||
internal double GetCorrectionFactor()
|
||||
{
|
||||
this.Meter.CorrectionFactor = this.results
|
||||
var correction = this.results
|
||||
.OrderBy(x => x.Key.GalPerMin)
|
||||
.Select(x => x.Value.DifferencePercentage)
|
||||
.ToArray()
|
||||
.GetCorrectionFactor();
|
||||
|
||||
this.State = $"Korekturfaktor: {this.Meter.CorrectionFactor:0.00} %";
|
||||
this.State = $"Korekturfaktor: {correction:0.00} %";
|
||||
|
||||
return this.Meter.CorrectionFactor;
|
||||
return correction;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.SaveInspectionAsync(CancellationToken.None).Wait();
|
||||
|
||||
this.connection?.Disconnect();
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -493,8 +412,6 @@
|
||||
this.State = e.Message;
|
||||
}
|
||||
|
||||
// TODO: save state
|
||||
|
||||
try
|
||||
{
|
||||
this.results.Clear();
|
||||
@@ -504,5 +421,17 @@
|
||||
this.State = e.Message;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsRunning()
|
||||
{
|
||||
if (!this.Running)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this.Connected = this.connection.Connected;
|
||||
|
||||
return this.Connected;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,12 +22,13 @@
|
||||
|
||||
private readonly EOLSettings omnisettings;
|
||||
private readonly ExchangeHubSettings hubsettings;
|
||||
|
||||
private CancellationTokenSource cancellationTokenSource;
|
||||
private CancellationToken cancellationToken;
|
||||
private OmniPlusDatabase dbcontext;
|
||||
private ExchangeConnection signalR;
|
||||
private ManualResetEventSlim awaiter;
|
||||
private ICollection<Task> tasks;
|
||||
private ManualResetEventSlim manualResetEventSlim;
|
||||
private TimersTimer timer;
|
||||
private bool canceled;
|
||||
|
||||
@@ -48,11 +49,11 @@
|
||||
this.signalR.OutputDir = this.hubsettings.ExchangeHubOutputDir;
|
||||
this.signalR.Connect(this.hubsettings.ExchangeHubURL);
|
||||
|
||||
this.LoadComPorts = new Command(this.InitializeComPorts);
|
||||
this.LoadComPorts = new Command(this.PrepareConnections);
|
||||
this.CancelInspection = new Command(this.CancelInspectionHandler);
|
||||
this.StartInspection = new Command(this.StartInspectionHandler);
|
||||
|
||||
this.InitializeComPorts();
|
||||
this.PrepareConnections();
|
||||
}
|
||||
|
||||
private int size;
|
||||
@@ -171,11 +172,12 @@
|
||||
|
||||
public ICommand StartInspection { get; }
|
||||
|
||||
private void InitializeComPorts()
|
||||
private void PrepareConnections()
|
||||
{
|
||||
if (this.Size == 0 || this.Type is null)
|
||||
{
|
||||
this.Error = "Size und Type auswählen!";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -193,9 +195,12 @@
|
||||
this.Option.Clear();
|
||||
}
|
||||
|
||||
this.dbcontext.LoadOmniDefaults((byte)this.Size, this.Type, this.OmniDefaults);
|
||||
this.NotifyPropertyChanged(nameof(this.OmniDefaults));
|
||||
|
||||
this.Text = $"ME OMNI 1.5-2\" {this.Type}";
|
||||
|
||||
try
|
||||
{
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
var placeNr = 1;
|
||||
|
||||
@@ -207,19 +212,28 @@
|
||||
comVM.Nr = placeNr++;
|
||||
comVM.Header = $"{com}";
|
||||
comVM.State = $"{com}";
|
||||
comVM.InitializeAsync();
|
||||
|
||||
this.Nodes.Add(comVM);
|
||||
this.Option.Add(comVM.Option);
|
||||
}
|
||||
|
||||
this.Text = $"ME OMNI 1.5-2\" {this.Type}";
|
||||
this.Option.SetIndentation(this.Option.Indent);
|
||||
this.NotifyPropertyChanged(nameof(this.Nodes));
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in this.Nodes.Cast<COMContentVM>())
|
||||
{
|
||||
tasks.Add(meterVM.InitializeAsync(cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
this.dbcontext.LoadOmniDefaults((byte)this.Size, this.Type, this.OmniDefaults);
|
||||
this.NotifyPropertyChanged(nameof(this.OmniDefaults));
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in this.Nodes.Cast<COMContentVM>())
|
||||
{
|
||||
tasks.Add(meterVM.ReadSystemParametersAsync(cancellationToken));
|
||||
}
|
||||
}, wait: false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -242,10 +256,11 @@
|
||||
|
||||
try
|
||||
{
|
||||
this.manualResetEventSlim?.Set();
|
||||
this.signalR.NotifyStopRef();
|
||||
this.signalR.NotifyStopQ();
|
||||
this.awaiter?.Set();
|
||||
this.cancellationTokenSource?.Cancel();
|
||||
this.tasks.Clear();
|
||||
this.Dispose();
|
||||
|
||||
this.State = "Vorgang wurde abbgebrochen!";
|
||||
}
|
||||
@@ -255,135 +270,171 @@
|
||||
this.State = default(string);
|
||||
}
|
||||
|
||||
Task.Factory.StartNew(() =>
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
this.CanStart = false;
|
||||
|
||||
if (this.AvailableIn > 0)
|
||||
{
|
||||
this.WaitUntil(this.AvailableIn, true);
|
||||
}
|
||||
this.WaitUntil(this.AvailableIn, show: true, error: true);
|
||||
|
||||
this.CanStart = true;
|
||||
this.Error = default(string);
|
||||
});
|
||||
this.State = default(string);
|
||||
}, wait: false);
|
||||
}
|
||||
|
||||
private void StartInspectionHandler()
|
||||
{
|
||||
this.canceled = false;
|
||||
this.CanStop = true;
|
||||
this.CanStart = false;
|
||||
this.CanStop = true;
|
||||
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
this.cancellationToken = this.cancellationTokenSource.Token;
|
||||
var metersVM = this.Nodes.Cast<COMContentVM>();
|
||||
|
||||
Task.Factory.StartNew(() =>
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
var coms = this.Nodes.Cast<COMContentVM>();
|
||||
//this.InvokeAsync((tasks, cancellationToken) =>
|
||||
//{
|
||||
// foreach (var meterVM in metersVM)
|
||||
// {
|
||||
// tasks.Add(meterVM.SetInputVolumeAsync(this.OmniDefaults, cancellationToken));
|
||||
// }
|
||||
//});
|
||||
|
||||
foreach (var comVM in coms)
|
||||
var results = new byte[][]
|
||||
{
|
||||
this.tasks.Add(comVM.SetInputVolumeTask(this.OmniDefaults, this.cancellationToken));
|
||||
new byte[] { 0x01, 0x02, 0x04, 0x00, 0x6F, 0x85, 0x0D, 0x00, 0x01 },
|
||||
new byte[] { 0x01, 0x02, 0x08, 0x00, 0x4F, 0xFA, 0x11, 0x00, 0x01 },
|
||||
new byte[] { 0x01, 0x02, 0xE8, 0x03, 0xA1, 0xFB, 0x10, 0x00, 0x02 },
|
||||
};
|
||||
|
||||
for (int i = 0; i < this.OmniDefaults.TestPoints.Count; i++)
|
||||
{
|
||||
var pp = this.OmniDefaults.TestPoints[i];
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.StartPPCalibrationAsync(pp, cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
var result = results[i];
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.StopPPCalibrationAsync(pp, result, cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
var referenceV = pp.VolumeM3H * 1;
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.SetReferenceVolumeAsync(pp, referenceV, cancellationToken));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.ContinueWhenAll();
|
||||
//foreach (var pp in this.OmniDefaults.TestPoints)
|
||||
//{
|
||||
// if (this.cancellationTokenSource?.IsCancellationRequested == true)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
|
||||
var results = this.OmniDefaults
|
||||
.TestPoints
|
||||
.ToDictionary(x => x, x => new List<OmniPlusTest>());
|
||||
// var rotations = pp.Rotations;
|
||||
// var duration = pp.Duration;
|
||||
|
||||
foreach (var pp in this.OmniDefaults.TestPoints)
|
||||
// this.StartFlow(pp.VolumeM3H);
|
||||
|
||||
// this.InvokeAsync((tasks, cancellationToken) =>
|
||||
// {
|
||||
// foreach (var meterVM in metersVM)
|
||||
// {
|
||||
// tasks.Add(meterVM.StartPPCalibrationAsync(pp, cancellationToken));
|
||||
// }
|
||||
// });
|
||||
|
||||
// this.StartReferenceMessurement(duration);
|
||||
// this.WaitUntil((int)(duration * 1.2), true, false);
|
||||
|
||||
// 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));
|
||||
// }
|
||||
// });
|
||||
|
||||
// if (this.cancellationTokenSource?.IsCancellationRequested == true)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
|
||||
// this.InvokeAsync((tasks, cancellationToken) =>
|
||||
// {
|
||||
// foreach (var meterVM in metersVM)
|
||||
// {
|
||||
// tasks.Add(meterVM.SetReferenceVolumeAsync(pp, referenceV, cancellationToken));
|
||||
// }
|
||||
// });
|
||||
//}
|
||||
|
||||
//this.signalR.NotifyStopQ();
|
||||
//this.signalR.NotifyStopRef();
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
if (coms.All(x => !x.Running))
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
break;
|
||||
tasks.Add(meterVM.SaveInspectionAsync(cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
meterVM.GetCorrectionFactor();
|
||||
}
|
||||
|
||||
var rotations = pp.Rotations;
|
||||
var duration = pp.Duration;
|
||||
|
||||
this.SetFlow(pp.VolumeM3H);
|
||||
|
||||
foreach (var comVM in coms)
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
this.tasks.Add(comVM.StartPPCalibrationTask(pp, this.cancellationToken));
|
||||
meterVM.Dispose();
|
||||
}
|
||||
|
||||
this.ContinueWhenAll();
|
||||
|
||||
this.StartRZ(duration);
|
||||
this.WaitUntil((int)(duration * 1.2), true, false);
|
||||
|
||||
if (this.manualResetEventSlim.IsSet)
|
||||
this.InvokeAsync(() =>
|
||||
{
|
||||
break;
|
||||
}
|
||||
this.WaitUntil(this.AvailableIn, show: true);
|
||||
|
||||
var referenceV = this.GetRZVolume();
|
||||
|
||||
foreach (var comVM in coms)
|
||||
{
|
||||
this.tasks.Add(comVM.StopPPCalibrationTask(pp, this.cancellationToken));
|
||||
}
|
||||
|
||||
this.ContinueWhenAll();
|
||||
|
||||
if (coms.All(x => !x.Running))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (var comVM in coms)
|
||||
{
|
||||
comVM.SetReferenceVolume(pp, referenceV);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var comVM in coms)
|
||||
{
|
||||
comVM.SaveInspection();
|
||||
}
|
||||
|
||||
if (coms.All(x => x.Running))
|
||||
{
|
||||
foreach (var comVM in coms)
|
||||
{
|
||||
comVM.GetCorrectionFactor();
|
||||
}
|
||||
|
||||
foreach (var comVM in coms)
|
||||
{
|
||||
comVM.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
this.CancelInspectionHandler();
|
||||
this.signalR.NotifyStopRef();
|
||||
this.signalR.NotifyStopQ();
|
||||
this.signalR.Dispose();
|
||||
|
||||
}, this.cancellationToken);
|
||||
this.CanStart = true;
|
||||
this.Error = default(string);
|
||||
this.State = default(string);
|
||||
});
|
||||
}, wait: false);
|
||||
}
|
||||
|
||||
private void WaitUntil(int duration, bool show = false, bool error = true)
|
||||
{
|
||||
this.AvailableIn = duration;
|
||||
|
||||
if (this.manualResetEventSlim != null)
|
||||
if (duration <= 0)
|
||||
{
|
||||
this.manualResetEventSlim.Set();
|
||||
this.manualResetEventSlim.Dispose();
|
||||
}
|
||||
this.AvailableIn = 0;
|
||||
|
||||
this.manualResetEventSlim = new ManualResetEventSlim();
|
||||
|
||||
if (this.timer != null)
|
||||
{
|
||||
this.timer.Stop();
|
||||
this.timer.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
this.CanStart = false;
|
||||
this.awaiter = new ManualResetEventSlim();
|
||||
this.timer = new TimersTimer(1000)
|
||||
{
|
||||
AutoReset = true,
|
||||
@@ -410,27 +461,17 @@
|
||||
if (this.AvailableIn <= 0)
|
||||
{
|
||||
this.AvailableIn = 0;
|
||||
this.manualResetEventSlim.Set();
|
||||
this.awaiter.Set();
|
||||
}
|
||||
};
|
||||
|
||||
this.timer.Start();
|
||||
this.manualResetEventSlim.Wait(this.AvailableIn * 1000);
|
||||
|
||||
this.awaiter.Wait(this.AvailableIn * 1000);
|
||||
this.awaiter = null;
|
||||
|
||||
this.timer.Stop();
|
||||
}
|
||||
|
||||
private void ContinueWhenAll()
|
||||
{
|
||||
if (this.tasks.Any())
|
||||
{
|
||||
Task.Factory
|
||||
.ContinueWhenAll(this.tasks.ToArray(), _ => { })
|
||||
.Wait();
|
||||
|
||||
this.tasks.Clear();
|
||||
}
|
||||
|
||||
Thread.Sleep(1000);
|
||||
this.timer = null;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
@@ -439,9 +480,11 @@
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
|
||||
this.signalR.Dispose();
|
||||
}
|
||||
|
||||
private void SetFlow(double volumeM3H)
|
||||
private void StartFlow(double volumeM3H)
|
||||
{
|
||||
var received = false;
|
||||
var volume = volumeM3H;
|
||||
@@ -464,6 +507,8 @@
|
||||
{
|
||||
if (this.canceled)
|
||||
{
|
||||
this.AvailableIn = timeout;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -471,13 +516,16 @@
|
||||
|
||||
timeout--;
|
||||
|
||||
this.State = $"{timeout} Sekunden verbleiben ...";
|
||||
this.State = $"{timeout} Sekunden verbleiben bis Q(soll) erreicht";
|
||||
}
|
||||
|
||||
this.State = $"Durchfluss {volumeM3H:0.0000} erreicht ...";
|
||||
if (!this.canceled)
|
||||
{
|
||||
this.State = $"Durchfluss {volume:0.0000} erreicht ...";
|
||||
}
|
||||
}
|
||||
|
||||
private void StartRZ(int duration)
|
||||
private void StartReferenceMessurement(int duration)
|
||||
{
|
||||
var received = false;
|
||||
var reference = 0;
|
||||
@@ -500,6 +548,8 @@
|
||||
{
|
||||
if (this.canceled)
|
||||
{
|
||||
this.AvailableIn = timeout;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -510,10 +560,13 @@
|
||||
this.State = $"{timeout} Sekunden verbleiben ...";
|
||||
}
|
||||
|
||||
if (!this.canceled)
|
||||
{
|
||||
this.State = $"Referenzmessung gestartet ...";
|
||||
}
|
||||
}
|
||||
|
||||
private double GetRZVolume()
|
||||
private double GetReferenceVolume()
|
||||
{
|
||||
var received = false;
|
||||
var referenceV = 0D;
|
||||
@@ -536,6 +589,8 @@
|
||||
{
|
||||
if (this.canceled)
|
||||
{
|
||||
this.AvailableIn = timeout;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -546,9 +601,48 @@
|
||||
this.State = $"{timeout} Sekunden verbleiben ...";
|
||||
}
|
||||
|
||||
|
||||
if (!this.canceled)
|
||||
{
|
||||
this.State = $"Referenzmessung bereit ...";
|
||||
}
|
||||
|
||||
return referenceV;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (tasks.Any())
|
||||
{
|
||||
var handle = Task.Factory
|
||||
.ContinueWhenAll(this.tasks.ToArray(), _ => { })
|
||||
.ContinueWith(_ => this.tasks.Clear());
|
||||
|
||||
if (wait)
|
||||
{
|
||||
handle.Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InvokeAsync(Action action, bool wait = true)
|
||||
{
|
||||
var handle = Task.Factory.StartNew(action);
|
||||
|
||||
if (wait)
|
||||
{
|
||||
handle.Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
namespace OMNIPruefung.ViewModels.Features
|
||||
{
|
||||
using OmniPlus.Features;
|
||||
using OMNIPruefung.ViewModels.Base;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class OMNIPlusVM : VM<OMNIPlusVM>
|
||||
{
|
||||
private OMNISysParameters sysParameters;
|
||||
public OMNISysParameters SystemParameters
|
||||
{
|
||||
get => this.sysParameters;
|
||||
set
|
||||
{
|
||||
this.sysParameters = value;
|
||||
|
||||
this.NotifyPropertyChanged(nameof(this.SystemParameters));
|
||||
}
|
||||
}
|
||||
|
||||
public double CorrectionFactor { get; set; }
|
||||
|
||||
public ChamberCalibrationResponse CalibrationResult { get; set; }
|
||||
= new ChamberCalibrationResponse();
|
||||
|
||||
public Dictionary<string, Dictionary<string, string>> Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
var dictionary = new Dictionary<string, Dictionary<string, string>>();
|
||||
|
||||
dictionary["System parameters:"] = this.SystemParameters
|
||||
?.ToDictionary() ?? new Dictionary<string, string>();
|
||||
|
||||
dictionary["Test results:"] = new Dictionary<string, string>
|
||||
{
|
||||
{ nameof(this.CorrectionFactor), $"{this.CorrectionFactor:0.0000}" }
|
||||
};
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
}
|
||||
|
||||
private string error;
|
||||
public string Error
|
||||
{
|
||||
get => this.error;
|
||||
set
|
||||
{
|
||||
this.error = value;
|
||||
|
||||
this.NotifyPropertyChanged(nameof(this.Error));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
namespace OMNIPruefung.ViewModels.Features
|
||||
{
|
||||
using OmniPlus.Features;
|
||||
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>();
|
||||
|
||||
internal void Add(SystemParameters response)
|
||||
{
|
||||
if (response.Succeeded)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Result
|
||||
{
|
||||
}
|
||||
|
||||
public class Property
|
||||
{
|
||||
public string DbName { get; set; }
|
||||
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public string BinValue { get; set; }
|
||||
|
||||
public string StrValue { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,10 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ItemsControl ItemsSource="{Binding Meter.Properties}" FontFamily="Consolas">
|
||||
|
||||
<ItemsControl Grid.Row="0" ItemsSource="{Binding Meter.Properties}" FontFamily="Consolas">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical">
|
||||
@@ -31,6 +33,7 @@
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Margin="13"
|
||||
FontFamily="Consolas"
|
||||
@@ -41,5 +44,7 @@
|
||||
FontFamily="Consolas"
|
||||
TextAlignment="Left"
|
||||
Text="{Binding Error}" />
|
||||
|
||||
<DataGrid Grid.Row="3" ItemsSource="{Binding Meter.Results}" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
using OmniPlus.Enums;
|
||||
using OmniPlus.Hanlers;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OmniPlus
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using OmniPlus.Enums;
|
||||
using OmniPlus.Hanlers;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal class IrdaConnection : SerialPortConnection
|
||||
{
|
||||
protected event DataReceivedHandler MessageReceived;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
internal class IrdaEncoder : SerialDataEncoder
|
||||
{
|
||||
public byte Device2PC { get; } = SerialDataExtensions.IRDA_REG2PC;
|
||||
|
||||
public override bool TryDecode(byte[] encoded, out byte[] decoded)
|
||||
{
|
||||
decoded = encoded.FromIrdaMessage();
|
||||
|
||||
return decoded.Length > 0;
|
||||
}
|
||||
|
||||
public override bool TryEncode(byte[] decoded, out byte[] encoded)
|
||||
{
|
||||
encoded = decoded.ToIrdaMessage();
|
||||
|
||||
return encoded.Length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
internal class IrdaStream : SerialDataReader
|
||||
{
|
||||
private readonly IrdaEncoder encoder;
|
||||
|
||||
public IrdaStream(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
this.encoder = new IrdaEncoder();
|
||||
}
|
||||
|
||||
public override void WriteBytes(params byte[] bytes)
|
||||
{
|
||||
if (this.encoder.TryEncode(bytes, out byte[] message))
|
||||
{
|
||||
base.WriteBytes(1, 1, 1, 1);
|
||||
|
||||
Thread.Sleep(1);
|
||||
|
||||
base.WriteBytes(message);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void BeginRead(byte[] buffer)
|
||||
{
|
||||
var start = Array.IndexOf(buffer, this.encoder.Device2PC);
|
||||
|
||||
if (start >= 0)
|
||||
{
|
||||
if (this.encoder.TryDecode(buffer, out byte[] message))
|
||||
{
|
||||
this.EnqueueMessage(message);
|
||||
this.RemoveRange(message.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.RemoveRange(buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Text;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var number = "81623241198";
|
||||
var last = number.Length - 1;
|
||||
var line = string.Empty;
|
||||
|
||||
while (!string.IsNullOrEmpty(line = Console.ReadLine()))
|
||||
{
|
||||
Console.WriteLine();
|
||||
|
||||
var next = number + line[0];
|
||||
var request = new byte[] { };
|
||||
var response = new byte[] { };
|
||||
var settings = new SerialPortSettings
|
||||
{
|
||||
BaudRate = 115200,
|
||||
DataBits = 8,
|
||||
Parity = Parity.None,
|
||||
PortName = "COM1",
|
||||
StopBits = StopBits.One,
|
||||
};
|
||||
var foreground = Console.ForegroundColor;
|
||||
|
||||
using (var stream = new UI1236Stream(settings))
|
||||
{
|
||||
stream.Open();
|
||||
|
||||
request = new byte[] { 0x05 };
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[] { 0x01 };
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[14];
|
||||
request[0] = 0x02;
|
||||
Encoding.ASCII.GetBytes(next).CopyTo(request, 1);
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[] { 0x01 };
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[] { 0x03 };
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[22];
|
||||
request[0] = 0x04;
|
||||
Encoding.ASCII.GetBytes($"SEN{next}").CopyTo(request, 1);
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[] { 0x03 };
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
Console.ForegroundColor = foreground;
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
internal abstract class SerialDataEncoder
|
||||
{
|
||||
public abstract bool TryDecode(byte[] encoded, out byte[] decoded);
|
||||
|
||||
public abstract bool TryEncode(byte[] decoded, out byte[] encoded);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
|
||||
internal static class SerialDataExtensions
|
||||
{
|
||||
public const int BYTE_BITS = 8;
|
||||
|
||||
public const byte OxOO = 0x00;
|
||||
public const byte OxO1 = 0x01;
|
||||
public const byte OxO2 = 0x02;
|
||||
public const byte OxO3 = 0x03;
|
||||
|
||||
public const byte UNIPRO_START = 0x53;
|
||||
public const byte UNIPRO_PC2REG = 0x57;
|
||||
public const byte UNIPRO_REG2PC = 0x52;
|
||||
public const byte UNIPRO_STOP = 0x0D;
|
||||
public const byte UNIPRO_MIN_LENGTH = 4;
|
||||
|
||||
public const byte UI1236_START = 0x0D;
|
||||
public const byte UI1236_MIN_LENGTH = 5;
|
||||
public const byte UI1236_HED_LENGTH = 3;
|
||||
|
||||
public const byte IRDA_START = 0x9B;
|
||||
public const byte IRDA_PING = 0x82;
|
||||
public const byte IRDA_PC2REG = 0x33;
|
||||
public const byte IRDA_REG2PC = 0x43;
|
||||
public const byte IRDA_MIN_LENGTH = 5;
|
||||
public const byte IRDA_CRC_LENGTH = 2;
|
||||
|
||||
/// <summary>
|
||||
/// <para>UI1236 structure:</para>
|
||||
/// <para> 0. 0x0D - Start byte</para>
|
||||
/// <para> 1. .... - Length: max. 254</para>
|
||||
/// <para> 2. .... - Control byte</para>
|
||||
/// <para>3+n. .... - Payload</para>
|
||||
/// <para>n-2. .... - Checksum 0 </para>
|
||||
/// <para>n-1. .... - Checksum 1 </para>
|
||||
/// </summary>
|
||||
public static byte[] ToUI1236Message(this byte[] bytes)
|
||||
{
|
||||
var bytesLength = bytes.Length;
|
||||
var payloadLength = bytes.Length + UI1236_MIN_LENGTH;
|
||||
payloadLength += payloadLength % OxO2;
|
||||
|
||||
var index = OxOO;
|
||||
var message = new byte[payloadLength];
|
||||
message[index++] = UI1236_START;
|
||||
message[index++] = (byte)(bytesLength + UI1236_HED_LENGTH);
|
||||
|
||||
//OmniControlOptions control = OxOO;
|
||||
//control.ReturnResponse = true;
|
||||
//message[index++] = control;
|
||||
message[index++] = 0x08;
|
||||
|
||||
bytes.CopyTo(message, index);
|
||||
|
||||
var checksum = message.CalculateCheckSUM(message.Length - OxO2);
|
||||
var checksumIndex = bytesLength + UI1236_HED_LENGTH;
|
||||
message[checksumIndex++] = checksum[OxO1];
|
||||
message[checksumIndex++] = checksum[OxOO];
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>UI1236 structure:</para>
|
||||
/// <para> 0. 0x0D - Start byte</para>
|
||||
/// <para> 1. .... - Length: max. 254</para>
|
||||
/// <para> 2. .... - Control byte</para>
|
||||
/// <para>3+n. .... - Payload</para>
|
||||
/// <para>n-2. .... - Checksum 0 </para>
|
||||
/// <para>n-1. .... - Checksum 1 </para>
|
||||
/// </summary>
|
||||
public static byte[] FromUI1236Message(this byte[] bytes)
|
||||
{
|
||||
var payload = new byte[OxOO];
|
||||
|
||||
if (bytes is null)
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
var payloadLength = bytes.Length - UI1236_MIN_LENGTH;
|
||||
|
||||
if (payloadLength <= OxOO)
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
payload = new byte[payloadLength];
|
||||
|
||||
Buffer.BlockCopy(bytes, OxO3, payload, OxOO, payloadLength);
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>UniPro structure:</para>
|
||||
/// <para> 0. .... - Start byte</para>
|
||||
/// <para> 1. .... - Direction</para>
|
||||
/// <para> 2. .... - Length</para>
|
||||
/// <para> .. .... - Payload</para>
|
||||
/// <para>n-1. .... - Stop byte</para>
|
||||
/// </summary>
|
||||
public static byte[] ToUniProMessage(this byte[] bytes)
|
||||
{
|
||||
var messageLength = (byte)(bytes.Length + UNIPRO_MIN_LENGTH);
|
||||
var message = new byte[messageLength];
|
||||
var index = OxOO;
|
||||
|
||||
message[index++] = UNIPRO_START;
|
||||
message[index++] = UNIPRO_PC2REG;
|
||||
message[index++] = messageLength;
|
||||
message[messageLength - OxO1] = UNIPRO_STOP;
|
||||
|
||||
bytes.CopyTo(message, index);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>UniPro structure:</para>
|
||||
/// <para> 0. .... - Start byte</para>
|
||||
/// <para> 1. .... - Direction</para>
|
||||
/// <para> 2. .... - Length</para>
|
||||
/// <para> .. .... - Payload</para>
|
||||
/// <para>n-1. .... - Stop byte</para>
|
||||
/// </summary>
|
||||
public static byte[] FromUniProMessage(this byte[] bytes)
|
||||
{
|
||||
var payload = new byte[OxOO];
|
||||
|
||||
if (bytes is null)
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
var payloadLength = bytes.Length - UNIPRO_MIN_LENGTH;
|
||||
|
||||
if (payloadLength <= OxOO)
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
payload = new byte[payloadLength];
|
||||
|
||||
Buffer.BlockCopy(bytes, OxO3, payload, OxOO, payloadLength);
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Irda structure:</para>
|
||||
/// <para> 0. .... - Start byte</para>
|
||||
/// <para> 1. .... - Direction</para>
|
||||
/// <para> 2. .... - Length / 2</para>
|
||||
/// <para>3+n. .... - Payload</para>
|
||||
/// <para>n-3. .... - aligned byte</para>
|
||||
/// <para>n-2. .... - CRC16 0 </para>
|
||||
/// <para>n-1. .... - CRC16 1 </para>
|
||||
/// </summary>
|
||||
public static byte[] ToIrdaMessage(this byte[] bytes)
|
||||
{
|
||||
var payloadLength = bytes.Length;
|
||||
payloadLength += payloadLength % OxO2;
|
||||
|
||||
var index = OxOO;
|
||||
var message = new byte[payloadLength + IRDA_MIN_LENGTH];
|
||||
message[index++] = IRDA_START;
|
||||
message[index++] = IRDA_PC2REG;
|
||||
message[index++] = (byte)(payloadLength / OxO2);
|
||||
|
||||
bytes.CopyTo(message, index);
|
||||
|
||||
var messageLength = message.Length;
|
||||
var crc16 = message.CalculateCRC8408(1, messageLength - IRDA_CRC_LENGTH);
|
||||
message[messageLength - OxO2] = crc16[OxOO];
|
||||
message[messageLength - OxO1] = crc16[OxO1];
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Irda structure:</para>
|
||||
/// <para> 0. .... - Start byte</para>
|
||||
/// <para> 1. .... - Direction</para>
|
||||
/// <para> 2. .... - Length / 2</para>
|
||||
/// <para>3+n. .... - Payload</para>
|
||||
/// <para>n-3. .... - aligned byte</para>
|
||||
/// <para>n-2. .... - CRC16 0 </para>
|
||||
/// <para>n-1. .... - CRC16 1 </para>
|
||||
/// </summary>
|
||||
public static byte[] FromIrdaMessage(this byte[] bytes)
|
||||
{
|
||||
var payload = new byte[OxOO];
|
||||
|
||||
if (bytes is null)
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
var payloadLength = bytes.Length - IRDA_MIN_LENGTH;
|
||||
|
||||
if (payloadLength <= OxOO)
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
payload = new byte[payloadLength];
|
||||
|
||||
Buffer.BlockCopy(bytes, OxO3, payload, OxOO, payloadLength);
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Irda structure:</para>
|
||||
/// <para> 0. .... - Start byte</para>
|
||||
/// <para> 1. .... - Direction</para>
|
||||
/// <para> 2. .... - Length / 2</para>
|
||||
/// <para>3+n. .... - Payload</para>
|
||||
/// <para>n-3. .... - aligned byte</para>
|
||||
/// <para>n-2. .... - CRC16 0 </para>
|
||||
/// <para>n-1. .... - CRC16 1 </para>
|
||||
/// </summary>
|
||||
public static byte[] FromIrdaMessage(this byte[] bytes, int start, out int length)
|
||||
{
|
||||
length = OxOO;
|
||||
|
||||
var payload = new byte[length];
|
||||
|
||||
if (bytes is null)
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
var bytesLength = bytes.Length;
|
||||
var payloadLengthIndex = start + 2;
|
||||
|
||||
if (bytesLength <= payloadLengthIndex)
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
var payloadLength = bytes[payloadLengthIndex] * 2;
|
||||
length = payloadLength + IRDA_MIN_LENGTH;
|
||||
|
||||
if (payloadLength <= OxOO)
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
payload = new byte[payloadLength];
|
||||
var payloadStart = payloadLengthIndex + 1;
|
||||
|
||||
Buffer.BlockCopy(bytes, payloadStart, payload, 0, payloadLength);
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Irda structure:</para>
|
||||
/// <para> 0. .... - Start byte</para>
|
||||
/// <para> 1. .... - Direction</para>
|
||||
/// <para> 2. .... - Length / 2</para>
|
||||
/// <para>3+n. .... - Payload</para>
|
||||
/// <para>n-3. .... - aligned byte</para>
|
||||
/// <para>n-2. .... - CRC16 0 </para>
|
||||
/// <para>n-1. .... - CRC16 1 </para>
|
||||
/// </summary>
|
||||
public static byte[] FromIrdaMessage(this byte[] bytes, int start)
|
||||
{
|
||||
var bytesLength = bytes.Length;
|
||||
|
||||
if (bytes is null || bytesLength <= start)
|
||||
{
|
||||
return new byte[] { };
|
||||
}
|
||||
|
||||
var _length = bytes[start + 2] * 2;
|
||||
var _start = start + 3;
|
||||
|
||||
if (_start + _length >= bytesLength)
|
||||
{
|
||||
return new byte[] { };
|
||||
}
|
||||
|
||||
var data = new byte[_length];
|
||||
|
||||
Buffer.BlockCopy(bytes, _start, data, 0, _length);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public static byte[] CalculateCRC8408(this byte[] message, int start, int length)
|
||||
{
|
||||
var crc = 0xFFFF;
|
||||
|
||||
for (int x = start; x < length; x++)
|
||||
{
|
||||
crc ^= 0x00FF & message[x];
|
||||
|
||||
for (int i = 8; i > OxOO; i--)
|
||||
{
|
||||
if ((crc & 0x0001) != OxOO)
|
||||
{
|
||||
crc = (crc >> OxO1) ^ 0x8408;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc >>= OxO1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crc = ~crc;
|
||||
|
||||
return BitConverter.GetBytes(crc);
|
||||
}
|
||||
|
||||
public static byte[] CalculateCheckSUM(this byte[] bytes, int length)
|
||||
{
|
||||
ushort checksum = OxOO;
|
||||
|
||||
for (int i = OxOO; i < length; i++)
|
||||
{
|
||||
checksum += bytes[i];
|
||||
}
|
||||
|
||||
return BitConverter.GetBytes(checksum);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
internal abstract class SerialDataReader : SerialDataStream
|
||||
{
|
||||
private Thread thread;
|
||||
private List<byte> stream;
|
||||
private Queue<byte[]> messages;
|
||||
|
||||
protected SerialDataReader(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsAlive
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.thread is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.thread.IsAlive;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
this.StopListening();
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
protected virtual void BeginRead(byte[] bytes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected void ClearMessages()
|
||||
{
|
||||
if (this.messages != null)
|
||||
{
|
||||
this.messages.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] DequeueMessage()
|
||||
{
|
||||
if (this.messages != null && this.messages.Count > 0)
|
||||
{
|
||||
return this.messages.Dequeue();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void EnqueueMessage(byte[] message)
|
||||
{
|
||||
if (this.messages != null)
|
||||
{
|
||||
this.messages.Enqueue(message);
|
||||
}
|
||||
}
|
||||
|
||||
protected void RemoveRange(int length)
|
||||
{
|
||||
if (this.stream != null)
|
||||
{
|
||||
this.stream.RemoveRange(0, length);
|
||||
}
|
||||
}
|
||||
|
||||
protected void StartListening()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.IsOpen)
|
||||
{
|
||||
this.stream = new List<byte>();
|
||||
this.messages = new Queue<byte[]>();
|
||||
this.thread = new Thread(this.BeginRead);
|
||||
this.thread.Start();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void StopListening()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.IsAlive)
|
||||
{
|
||||
this.thread.Abort();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
|
||||
this.stream?.Clear();
|
||||
this.messages?.Clear();
|
||||
|
||||
this.messages = null;
|
||||
this.stream = null;
|
||||
this.thread = null;
|
||||
}
|
||||
|
||||
private void BeginRead()
|
||||
{
|
||||
this.NotifyStateChanged($"{nameof(IrdaStream)} - reading thread started.");
|
||||
|
||||
while (this.IsAlive)
|
||||
{
|
||||
var bytes = this.ReadBytes();
|
||||
|
||||
if (bytes.Length > 0)
|
||||
{
|
||||
this.stream.AddRange(bytes);
|
||||
}
|
||||
|
||||
this.BeginRead(this.stream.ToArray());
|
||||
}
|
||||
|
||||
this.NotifyStateChanged($"{nameof(IrdaStream)} - reading thread stoped.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
|
||||
internal class SerialDataStream : SerialPortStream
|
||||
{
|
||||
public SerialDataStream(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual byte[] ReadBytes()
|
||||
{
|
||||
var bytes = new byte[0];
|
||||
|
||||
try
|
||||
{
|
||||
if (this.IsOpen)
|
||||
{
|
||||
var length = this.serialPort.BytesToRead;
|
||||
|
||||
if (length > 1)
|
||||
{
|
||||
bytes = new byte[length];
|
||||
|
||||
this.serialPort.Read(bytes, 0, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public virtual void WriteBytes(params byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.IsOpen)
|
||||
{
|
||||
var _lock = new object();
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
this.serialPort.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
using OmniPlus.Enums;
|
||||
using OmniPlus.Hanlers;
|
||||
using OmniPlus.Options;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OmniPlus
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using OmniPlus.Enums;
|
||||
using OmniPlus.Hanlers;
|
||||
using OmniPlus.Options;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal abstract class SerialPortConnection : IDisposable
|
||||
{
|
||||
protected event StateChangedEventHandler StateChanged;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System.IO.Ports;
|
||||
|
||||
internal class SerialPortSettings
|
||||
{
|
||||
public int BaudRate { get; set; }
|
||||
|
||||
public int DataBits { get; set; }
|
||||
|
||||
public Parity Parity { get; set; }
|
||||
|
||||
public string PortName { get; set; }
|
||||
|
||||
public StopBits StopBits { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
|
||||
internal abstract class SerialPortStream : IDisposable
|
||||
{
|
||||
protected SerialPort serialPort;
|
||||
|
||||
private readonly SerialPortSettings settings;
|
||||
|
||||
protected SerialPortStream(SerialPortSettings settings)
|
||||
{
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public event Action Connected;
|
||||
public event Action Disconnected;
|
||||
public event Action<object> StateChanged;
|
||||
|
||||
public bool IsOpen
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.serialPort is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.serialPort.IsOpen;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.serialPort != null)
|
||||
{
|
||||
this.serialPort.Close();
|
||||
this.serialPort.Dispose();
|
||||
this.serialPort = null;
|
||||
|
||||
this.NotifyStateChanged($"{this} - disposed.");
|
||||
this.Disconnected?.Invoke();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Open()
|
||||
{
|
||||
if (this.serialPort != null)
|
||||
{
|
||||
this.Dispose();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.serialPort = new SerialPort
|
||||
{
|
||||
BaudRate = this.settings.BaudRate,
|
||||
DataBits = this.settings.DataBits,
|
||||
Parity = this.settings.Parity,
|
||||
PortName = this.settings.PortName,
|
||||
StopBits = this.settings.StopBits,
|
||||
};
|
||||
|
||||
this.serialPort.Open();
|
||||
|
||||
if (this.IsOpen)
|
||||
{
|
||||
this.NotifyStateChanged($"{this} - connected.");
|
||||
this.Connected?.Invoke();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (this.serialPort is null)
|
||||
{
|
||||
return $"{this.settings.PortName}, " +
|
||||
$"{this.settings.BaudRate}, " +
|
||||
$"{this.settings.DataBits}, " +
|
||||
$"{this.settings.Parity}, " +
|
||||
$"{this.settings.StopBits}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{this.serialPort.PortName}, " +
|
||||
$"{this.serialPort.BaudRate}, " +
|
||||
$"{this.serialPort.DataBits}, " +
|
||||
$"{this.serialPort.Parity}, " +
|
||||
$"{this.serialPort.StopBits}";
|
||||
}
|
||||
}
|
||||
|
||||
protected void NotifyStateChanged(object state)
|
||||
{
|
||||
this.StateChanged?.Invoke(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
|
||||
internal class SerialTextStream : SerialPortStream
|
||||
{
|
||||
public SerialTextStream(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
}
|
||||
|
||||
public string ReadLine()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.IsOpen)
|
||||
{
|
||||
return this.serialPort.ReadLine();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
|
||||
return default(string);
|
||||
}
|
||||
|
||||
public void WriteLine(string line)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.IsOpen)
|
||||
{
|
||||
var _lock = new object();
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
this.serialPort.WriteLine(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
internal class UI1236Encoder : SerialDataEncoder
|
||||
{
|
||||
public override bool TryDecode(byte[] encoded, out byte[] decoded)
|
||||
{
|
||||
decoded = encoded.FromUI1236Message();
|
||||
|
||||
return decoded.Length > 0;
|
||||
}
|
||||
|
||||
public override bool TryEncode(byte[] decoded, out byte[] encoded)
|
||||
{
|
||||
encoded = decoded.ToUI1236Message();
|
||||
|
||||
return encoded.Length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System.Threading;
|
||||
|
||||
internal class UI1236Stream : IrdaStream
|
||||
{
|
||||
private readonly UI1236Encoder encoder;
|
||||
|
||||
public UI1236Stream(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
this.encoder = new UI1236Encoder();
|
||||
}
|
||||
|
||||
public byte[] Write(params byte[] bytes)
|
||||
{
|
||||
this.StartListening();
|
||||
this.WriteBytes(bytes);
|
||||
|
||||
var response = new byte[0];
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
var message = this.DequeueMessage();
|
||||
|
||||
if (message != null)
|
||||
{
|
||||
if (this.encoder.TryDecode(message, out response))
|
||||
{
|
||||
this.ClearMessages();
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
}
|
||||
|
||||
if (response.Length > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
|
||||
this.StopListening();
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public override void WriteBytes(params byte[] bytes)
|
||||
{
|
||||
if (this.encoder.TryEncode(bytes, out byte[] message))
|
||||
{
|
||||
base.WriteBytes(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
using OmniPlus.Enums;
|
||||
using OmniPlus.Hanlers;
|
||||
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
|
||||
namespace OmniPlus
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using OmniPlus.Enums;
|
||||
using OmniPlus.Hanlers;
|
||||
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
|
||||
internal class UniProConnection : SerialPortConnection
|
||||
{
|
||||
protected event DataReceivedHandler MessageReceived;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
internal class UniProEncoder : SerialDataEncoder
|
||||
{
|
||||
public object Device2PC { get; } = SerialDataExtensions.UNIPRO_REG2PC;
|
||||
|
||||
public override bool TryDecode(byte[] encoded, out byte[] decoded)
|
||||
{
|
||||
decoded = encoded.FromUniProMessage();
|
||||
|
||||
return decoded.Length > 0;
|
||||
}
|
||||
|
||||
public override bool TryEncode(byte[] decoded, out byte[] encoded)
|
||||
{
|
||||
encoded = decoded.FromUniProMessage();
|
||||
|
||||
return encoded.Length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
internal class UniProStream : SerialDataReader
|
||||
{
|
||||
private readonly UniProEncoder encoder;
|
||||
|
||||
public UniProStream(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
this.encoder = new UniProEncoder();
|
||||
}
|
||||
|
||||
public byte[] Write(params byte[] bytes)
|
||||
{
|
||||
this.StartListening();
|
||||
this.WriteBytes(bytes);
|
||||
|
||||
var response = new byte[0];
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
var message = this.DequeueMessage();
|
||||
|
||||
if (message != null)
|
||||
{
|
||||
if (this.encoder.TryDecode(message, out response))
|
||||
{
|
||||
this.ClearMessages();
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
}
|
||||
|
||||
if (response.Length > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
|
||||
this.StopListening();
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public override void WriteBytes(params byte[] bytes)
|
||||
{
|
||||
if (this.encoder.TryEncode(bytes, out byte[] message))
|
||||
{
|
||||
base.WriteBytes(message);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void BeginRead(byte[] buffer)
|
||||
{
|
||||
var start = Array.IndexOf(buffer, this.encoder.Device2PC);
|
||||
|
||||
if (start >= 0)
|
||||
{
|
||||
if (this.encoder.TryDecode(buffer, out byte[] message))
|
||||
{
|
||||
this.EnqueueMessage(message);
|
||||
this.RemoveRange(message.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.RemoveRange(buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,8 +47,10 @@
|
||||
/// </summary>
|
||||
public uint Duration
|
||||
{
|
||||
get => BitConverter.ToUInt16(this.bytes, 3);
|
||||
get => BitConverter.ToUInt32(this.bytes, 3);
|
||||
set => BitConverter.GetBytes(value).CopyTo(this.bytes, 3);
|
||||
}
|
||||
|
||||
public double DurationSec => this.Duration * (1D / 32768);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,20 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Connections\IrdaConnection.cs" />
|
||||
<Compile Include="Connections\IrdaEncoder.cs" />
|
||||
<Compile Include="Connections\IrdaStream.cs" />
|
||||
<Compile Include="Connections\Program.cs" />
|
||||
<Compile Include="Connections\SerialDataEncoder.cs" />
|
||||
<Compile Include="Connections\SerialDataExtensions.cs" />
|
||||
<Compile Include="Connections\SerialDataReader.cs" />
|
||||
<Compile Include="Connections\SerialDataStream.cs" />
|
||||
<Compile Include="Connections\SerialPortSettings.cs" />
|
||||
<Compile Include="Connections\SerialPortStream.cs" />
|
||||
<Compile Include="Connections\SerialTextStream.cs" />
|
||||
<Compile Include="Connections\UI1236Encoder.cs" />
|
||||
<Compile Include="Connections\UI1236Stream.cs" />
|
||||
<Compile Include="Connections\UniProEncoder.cs" />
|
||||
<Compile Include="Connections\UniProStream.cs" />
|
||||
<Compile Include="Enums\MessurementUnits.cs" />
|
||||
<Compile Include="Enums\ReadingSettings.cs" />
|
||||
<Compile Include="Enums\Status.cs" />
|
||||
|
||||
@@ -1,21 +1,37 @@
|
||||
using System;
|
||||
using OmniPlus.Features;
|
||||
using OmniPlus.Hanlers;
|
||||
|
||||
using static OmniPlus.Features.Features;
|
||||
|
||||
namespace OmniPlus
|
||||
namespace OmniPlus
|
||||
{
|
||||
using OmniPlus.Connections;
|
||||
using OmniPlus.Features;
|
||||
using OmniPlus.Hanlers;
|
||||
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using static OmniPlus.Features.Features;
|
||||
|
||||
public sealed class OmniPlusConnection
|
||||
{
|
||||
private Func<bool> connected;
|
||||
private readonly IrdaConnection irdaConnection;
|
||||
private readonly UniProConnection uniProConnection;
|
||||
private readonly UI1236Stream ui1236;
|
||||
private readonly UniProStream unipro;
|
||||
|
||||
public OmniPlusConnection(string portName)
|
||||
{
|
||||
this.irdaConnection = new IrdaConnection(portName);
|
||||
this.uniProConnection = new UniProConnection(portName);
|
||||
this.ui1236 = new UI1236Stream(new SerialPortSettings
|
||||
{
|
||||
BaudRate = 115200,
|
||||
DataBits = 8,
|
||||
Parity = Parity.None,
|
||||
PortName = portName,
|
||||
StopBits = StopBits.One
|
||||
});
|
||||
this.unipro = new UniProStream(new SerialPortSettings
|
||||
{
|
||||
BaudRate = 2400,
|
||||
DataBits = 8,
|
||||
Parity = Parity.None,
|
||||
PortName = portName,
|
||||
StopBits = StopBits.One
|
||||
});
|
||||
}
|
||||
|
||||
internal MessageHandler MessageHandler;
|
||||
@@ -25,30 +41,30 @@ namespace OmniPlus
|
||||
|
||||
public bool ConnectIrda()
|
||||
{
|
||||
this.uniProConnection.Close();
|
||||
this.irdaConnection.Open();
|
||||
this.unipro.Dispose();
|
||||
this.ui1236.Open();
|
||||
|
||||
this.connected = () => this.irdaConnection.Connected;
|
||||
this.MessageHandler = this.irdaConnection.Send;
|
||||
this.connected = () => this.ui1236.IsOpen;
|
||||
this.MessageHandler = this.ui1236.Write;
|
||||
|
||||
return this.irdaConnection.Connected;
|
||||
return this.ui1236.IsOpen;
|
||||
}
|
||||
|
||||
public bool ConnectUniPro()
|
||||
{
|
||||
this.irdaConnection.Close();
|
||||
this.uniProConnection.Open();
|
||||
this.ui1236.Dispose();
|
||||
this.unipro.Open();
|
||||
|
||||
this.connected = () => this.uniProConnection.Connected;
|
||||
this.MessageHandler = this.uniProConnection.SendMessage;
|
||||
this.connected = () => this.unipro.IsOpen;
|
||||
this.MessageHandler = this.unipro.Write;
|
||||
|
||||
return this.irdaConnection.Connected;
|
||||
return this.unipro.IsOpen;
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
this.uniProConnection.Close();
|
||||
this.irdaConnection.Close();
|
||||
this.unipro.Dispose();
|
||||
this.ui1236.Dispose();
|
||||
}
|
||||
|
||||
public FactoryID ViewFactoryID()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
return 100 - this.MeterVolume / this.VolumeMessured * 100;
|
||||
return 100 + (this.MeterVolume - this.VolumeMessured) / this.VolumeMessured;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -31,6 +31,8 @@ namespace OmniPlus
|
||||
}
|
||||
|
||||
public double VolumeM3(OmniPlusTest test)
|
||||
=> this.VolumeM3(test.Rotations, test.Duration);
|
||||
{
|
||||
return this.VolumeM3(test.Rotations, test.Duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user