Files
laatzen/Common/OmniPlus/OmniPlusExtensions.cs
T
2023-12-14 16:18:51 +01:00

436 lines
12 KiB
C#

using OmniPlus.Options;
using System;
using System.Data.SqlClient;
using System.Threading.Tasks;
namespace OmniPlus
{
public static class OmniPlusExtensions
{
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;
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];
Array.Copy(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];
Array.Copy(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 bytesLength = bytes.Length;
if (bytesLength >= 2)
{
if (bytes[1] == IRDA_PING)
{
return payload;
}
}
var payloadLength = bytes.Length - IRDA_MIN_LENGTH;
if (payloadLength <= OxOO)
{
return payload;
}
payload = new byte[payloadLength];
Array.Copy(bytes, OxO3, payload, OxOO, payloadLength);
return payload;
}
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);
}
public static void Clear(this byte[] bytes)
{
var length = bytes.Length;
for (int i = OxOO; i < length; i++)
{
bytes[i] = OxOO;
}
}
public static string ToASCIIString(this byte[] bytes, int start, int length)
{
var asciiString = string.Empty;
while (start >= 0 && start < bytes.Length)
{
asciiString += (char)bytes[start++];
}
return asciiString;
}
public static void ContinueWhenAll(this Task[] tasks)
=> Task.Factory
.ContinueWhenAll(tasks, _ => { })
.Wait();
public static void OpenConnection(this SqlConnection sqlConnection)
{
sqlConnection.FireInfoMessageEventOnUserErrors = true;
sqlConnection.InfoMessage += SqlConnection_InfoMessage;
sqlConnection.Open();
}
private static void SqlConnection_InfoMessage(object _, SqlInfoMessageEventArgs args)
{
Console.WriteLine(args.Message);
}
public static T GetValue<T>(this SqlDataReader reader, int field)
{
if (!reader.IsDBNull(field) && reader.GetValue(field) is T value)
{
return value;
}
return default(T);
}
public static double MlPerRotation(byte intPart, ushort fraction, short correctionFactor)
=> (intPart + (double)fraction / ushort.MaxValue) * correctionFactor;
public static double GPM2M3H(double value)
=> value * 3785.411784 / 1000 / 1000 * 60;
public static double GetCorrectionFactor(this double[] points)
{
if (points?.Length != 3)
{
return double.MinValue;
}
var min = points[0];
var mid = points[1];
var max = points[2];
if (Math.Abs(mid - max) <= 3 && Math.Max(mid, max) - min <= 6.5)
{
var avgMidMax = (mid + max) / 2;
if (100 - avgMidMax + min < 95)
{
return 95 - min;
}
else
{
return 100 - avgMidMax;
}
}
return double.MaxValue;
}
public static byte[] GetBits(this byte value)
{
var bits = new byte[BYTE_BITS];
for (byte i = 0; i < BYTE_BITS; i++)
{
bits[i] = (byte)(value >> i & 1);
}
return bits;
}
public static byte[] GetBits(this byte[] bytes)
{
var bytesL = bytes.Length;
var bitsL = bytesL * BYTE_BITS;
var bits = new byte[bitsL];
for (int i = 0; i < bytesL; i++)
{
for (int b = 0; b < BYTE_BITS; b++)
{
bits[i + b] = (byte)(bytes[i] >> b & 1);
}
}
return bits;
}
public static byte ToUint8(this byte[] bits)
{
var sum = default(byte);
for (byte i = 0; i < bits.Length; i++)
{
sum ^= (byte)(bits[i] << i);
}
return sum;
}
public static byte GetUint8(this byte x, int start, int length)
{
var src = x.GetBits();
var dst = new byte[8];
Array.Copy(src, start, dst, 0, length);
return dst.ToUint8();
}
public static void SetUint8(this ref byte x, int start, int length, byte value)
{
var src = value.GetBits();
var dst = x.GetBits();
Array.Copy(src, 0, dst, start, length);
x = dst.ToUint8();
}
public static byte[] Subarray(this byte[] bytes, int start, int length)
{
var subarray = new byte[length];
Array.Copy(bytes, start, subarray, 0, length);
return subarray;
}
public static byte[] Reverse(this byte[] bytes)
{
var length = bytes.Length / 2;
for (int i = 0; i < length; i++)
{
var last = length - i - 1;
var first = bytes[i];
bytes[i] = bytes[last];
bytes[last] = first;
}
return bytes;
}
}
}