using System;
using System.Data.SqlClient;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace OmniFeaturesTest
{
internal 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_PC2REG = 0x33;
public const byte IRDA_REG2PC = 0x43;
public const byte IRDA_MIN_LENGTH = 5;
public const byte IRDA_CRC_LENGTH = 2;
///
/// UI1236 structure:
/// 0. 0x0D - Start byte
/// 1. .... - Length: max. 254
/// 2. .... - Control byte
/// 3+n. .... - Payload
/// n-2. .... - Checksum 0
/// n-1. .... - Checksum 1
///
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);
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;
}
///
/// UI1236 structure:
/// 0. 0x0D - Start byte
/// 1. .... - Length: max. 254
/// 2. .... - Control byte
/// 3+n. .... - Payload
/// n-2. .... - Checksum 0
/// n-1. .... - Checksum 1
///
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;
}
///
/// UniPro structure:
/// 0. .... - Start byte
/// 1. .... - Direction
/// 2. .... - Length
/// .. .... - Payload
/// n-1. .... - Stop byte
///
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;
}
///
/// UniPro structure:
/// 0. .... - Start byte
/// 1. .... - Direction
/// 2. .... - Length
/// .. .... - Payload
/// n-1. .... - Stop byte
///
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;
}
///
/// Irda structure:
/// 0. .... - Start byte
/// 1. .... - Direction
/// 2. .... - Length / 2
/// 3+n. .... - Payload
/// n-3. .... - aligned byte
/// n-2. .... - CRC16 0
/// n-1. .... - CRC16 1
///
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;
}
///
/// Irda structure:
/// 0. .... - Start byte
/// 1. .... - Direction
/// 2. .... - Length / 2
/// 3+n. .... - Payload
/// n-3. .... - aligned byte
/// n-2. .... - CRC16 0
/// n-1. .... - CRC16 1
///
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];
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(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)
{
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 bytes;
}
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;
}
}
}