calculation of the correction factor

This commit is contained in:
Stoyan Zlatev
2024-01-03 10:38:30 +01:00
parent afd8984e9b
commit 4e07239125
31 changed files with 1623 additions and 769 deletions
+10 -10
View File
@@ -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;
}
}
}
+45
View File
@@ -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);
}
}
}
}
+110
View File
@@ -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);
}
}
+14
View File
@@ -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" />
+39 -23
View File
@@ -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()
+1 -1
View File
@@ -16,7 +16,7 @@
{
try
{
return 100 - this.MeterVolume / this.VolumeMessured * 100;
return 100 + (this.MeterVolume - this.VolumeMessured) / this.VolumeMessured;
}
catch
{
+4 -2
View File
@@ -30,7 +30,9 @@ namespace OmniPlus
return seconds * milliliter / 1000 / 1000;
}
public double VolumeM3(OmniPlusTest test)
=> this.VolumeM3(test.Rotations, test.Duration);
public double VolumeM3(OmniPlusTest test)
{
return this.VolumeM3(test.Rotations, test.Duration);
}
}
}