diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3be5b4ea..1bbb4e86 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - dotnet-version: [ '7.0', '8.0', '9.0'] + dotnet-version: [ '8.0', '9.0', '10.0'] fail-fast: false runs-on: ${{ matrix.os }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f2fb810d..9c115874 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,9 +14,9 @@ jobs: uses: actions/setup-dotnet@v4.2.0 with: dotnet-version: | - 7.0 8.0 9.0 + 10.0 - name: Install dependencies run: dotnet restore - name: Build diff --git a/RDMSharp/EManufacturer.cs b/RDMSharp/EManufacturer.cs index 9c7c4e06..cba5a351 100644 --- a/RDMSharp/EManufacturer.cs +++ b/RDMSharp/EManufacturer.cs @@ -1,26 +1,33 @@ using System.ComponentModel; -namespace RDMSharp +namespace RDMSharp; + +public enum EManufacturer : ushort { - public enum EManufacturer : ushort - { - [Description("ESTA")] - ESTA = 0x0000, - [Description("DMXControl-Projects e.V.")] - DMXControlProjects_eV = 0x02b0, - [Description("Martin Professional A/S")] - Martin_Professional_AS = 0x4D50, - [Description("SGM Technology For Lighting SPA")] - SGM_Technology_For_Lighting_SPA = 0x5347, - [Description("Wireless Solution Sweden AB")] - Wireless_Solution_Sweden_AB = 0x5753, - [Description("Robe Show Lighting s.r.o.")] - Robe_Show_Lighting_sro = 0x5253, - [Description("Swisson AG")] - Swisson_AG = 0x5777, - [Description("GLP German Light Products GmbH")] - GLP_German_Light_Products_GmbH = 0x676C, - [Description("Steinigke Showtechnic GmbH")] - Steinigke_Showtechnic_GmbH = 0x29aa, - } + [Description("ESTA")] + ESTA = 0x0000, + [Description("DMXControl-Projects e.V.")] + DMXControlProjects_eV = 0x02b0, + [Description("Magic FX B.V.")] + Magic_FX_bv = 0x4658, + [Description("Luminex")] + LUMINEX_Lighting_Control_Equipment_bvba = 0x4C4C, + [Description("LumenRadio AB")] + LumenRadio_AB = 0x4C55, + [Description("Martin Professional A/S")] + Martin_Professional_AS = 0x4D50, + [Description("SGM Technology For Lighting SPA")] + SGM_Technology_For_Lighting_SPA = 0x5347, + [Description("Wireless Solution Sweden AB")] + Wireless_Solution_Sweden_AB = 0x5753, + [Description("Robe Show Lighting s.r.o.")] + Robe_Show_Lighting_sro = 0x5253, + [Description("Swisson AG")] + Swisson_AG = 0x5377, + [Description("GLP German Light Products GmbH")] + GLP_German_Light_Products_GmbH = 0x676C, + [Description("Electronic Theatre Controls Inc.")] + Electronic_Theatre_Controls_Inc = 0x6574, + [Description("Steinigke Showtechnic GmbH")] + Steinigke_Showtechnic_GmbH = 0x29aa, } \ No newline at end of file diff --git a/RDMSharp/Extensions/BytesParser/DoubleBytesParser.cs b/RDMSharp/Extensions/BytesParser/DoubleBytesParser.cs new file mode 100644 index 00000000..adc9716b --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/DoubleBytesParser.cs @@ -0,0 +1,32 @@ +using RDMSharp.RDM; +using System; +using System.Linq; + +namespace RDMSharp.Extensions.BytesParser; + +public class DoubleBytesParser : IBytesParser +{ + private static readonly byte _bytesLength = 8; + private static readonly string _formatIdentifyer = "double"; + private static readonly PDL _payloadDataLength = new PDL(_bytesLength); + public string FormatIdentifyer => _formatIdentifyer; + public PDL? PayloadDataLength => _payloadDataLength; + + public object ParseToObject(ref byte[] data) + { + if (data.Length < _bytesLength) + throw new ArgumentException("Data length is less than required for Double parsing.", nameof(data)); + + double _double = BitConverter.ToDouble(data.Take(_bytesLength).ToArray(), 0); + data = data.Skip(_bytesLength).ToArray(); + + return _double; + } + + public byte[] ParseToData(object obj) + { + if (obj is double _double) + return BitConverter.GetBytes(_double); + throw new ArgumentException($"Object is not of type Double", nameof(obj)); + } +} diff --git a/RDMSharp/Extensions/BytesParser/FloatBytesParser.cs b/RDMSharp/Extensions/BytesParser/FloatBytesParser.cs new file mode 100644 index 00000000..cebd9449 --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/FloatBytesParser.cs @@ -0,0 +1,32 @@ +using RDMSharp.RDM; +using System; +using System.Linq; + +namespace RDMSharp.Extensions.BytesParser; + +public class FloatBytesParser : IBytesParser +{ + private static readonly byte _bytesLength = 4; + private static readonly string _formatIdentifyer = "float"; + private static readonly PDL _payloadDataLength = new PDL(_bytesLength); + public string FormatIdentifyer => _formatIdentifyer; + public PDL? PayloadDataLength => _payloadDataLength; + + public object ParseToObject(ref byte[] data) + { + if (data.Length < _bytesLength) + throw new ArgumentException("Data length is less than required for Float parsing.", nameof(data)); + + float _float = BitConverter.ToSingle(data.Take(_bytesLength).ToArray(), 0); + data = data.Skip(_bytesLength).ToArray(); + + return _float; + } + + public byte[] ParseToData(object obj) + { + if (obj is float _float) + return BitConverter.GetBytes(_float); + throw new ArgumentException($"Object is not of type Float", nameof(obj)); + } +} diff --git a/RDMSharp/Extensions/BytesParser/GuidBytesParser.cs b/RDMSharp/Extensions/BytesParser/GuidBytesParser.cs new file mode 100644 index 00000000..e999a6e8 --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/GuidBytesParser.cs @@ -0,0 +1,32 @@ +using RDMSharp.RDM; +using System; +using System.Linq; + +namespace RDMSharp.Extensions.BytesParser; + +public class GuidBytesParser : IBytesParser +{ + private static readonly byte _bytesLength = 16; + private static readonly string _formatIdentifyer = "guid"; + private static readonly PDL _payloadDataLength = new PDL(_bytesLength); + public string FormatIdentifyer => _formatIdentifyer; + public PDL? PayloadDataLength => _payloadDataLength; + + public object ParseToObject(ref byte[] data) + { + if (data.Length < _bytesLength) + throw new ArgumentException("Data length is less than required for Guid parsing.", nameof(data)); + + Guid guid = new Guid(data.Take(_bytesLength).ToArray()); + data = data.Skip(_bytesLength).ToArray(); + + return guid; + } + + public byte[] ParseToData(object obj) + { + if (obj is Guid guid) + return guid.ToByteArray(); + throw new ArgumentException($"Object is not of type {nameof(Guid)}", nameof(obj)); + } +} diff --git a/RDMSharp/Extensions/BytesParser/IPv4AddressBytesParser.cs b/RDMSharp/Extensions/BytesParser/IPv4AddressBytesParser.cs new file mode 100644 index 00000000..ef3a534a --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/IPv4AddressBytesParser.cs @@ -0,0 +1,32 @@ +using RDMSharp.RDM; +using System; +using System.Linq; + +namespace RDMSharp.Extensions.BytesParser; + +public class IPv4AddressBytesParser : IBytesParser +{ + private static readonly byte _bytesLength = 4; + private static readonly string _formatIdentifyer = "ipv4"; + private static readonly PDL _payloadDataLength = new PDL(_bytesLength); + public string FormatIdentifyer => _formatIdentifyer; + public PDL? PayloadDataLength => _payloadDataLength; + + public object ParseToObject(ref byte[] data) + { + if (data.Length < _bytesLength) + throw new ArgumentException("Data length is less than required for IPv4 parsing.", nameof(data)); + + IPv4Address ipv4Address = new IPv4Address(data.Take(_bytesLength)); + data = data.Skip(_bytesLength).ToArray(); + + return ipv4Address; + } + + public byte[] ParseToData(object obj) + { + if (obj is IPv4Address ipv4Address) + return ipv4Address; + throw new ArgumentException($"Object is not of type {nameof(IPv4Address)}", nameof(obj)); + } +} diff --git a/RDMSharp/Extensions/BytesParser/IPv6AddressBytesParser.cs b/RDMSharp/Extensions/BytesParser/IPv6AddressBytesParser.cs new file mode 100644 index 00000000..0a021bbb --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/IPv6AddressBytesParser.cs @@ -0,0 +1,32 @@ +using RDMSharp.RDM; +using System; +using System.Linq; + +namespace RDMSharp.Extensions.BytesParser; + +public class IPv6AddressBytesParser : IBytesParser +{ + private static readonly byte _bytesLength = 16; + private static readonly string _formatIdentifyer = "ipv6"; + private static readonly PDL _payloadDataLength = new PDL(_bytesLength); + public string FormatIdentifyer => _formatIdentifyer; + public PDL? PayloadDataLength => _payloadDataLength; + + public object ParseToObject(ref byte[] data) + { + if (data.Length < _bytesLength) + throw new ArgumentException("Data length is less than required for IPv6 parsing.", nameof(data)); + + IPv6Address ipv6Address = new IPv6Address(data.Take(_bytesLength)); + data = data.Skip(_bytesLength).ToArray(); + + return ipv6Address; + } + + public byte[] ParseToData(object obj) + { + if (obj is IPv6Address ipv6Address) + return ipv6Address; + throw new ArgumentException($"Object is not of type {nameof(IPv6Address)}", nameof(obj)); + } +} diff --git a/RDMSharp/Extensions/BytesParser/MACAddressBytesParser.cs b/RDMSharp/Extensions/BytesParser/MACAddressBytesParser.cs new file mode 100644 index 00000000..4663c977 --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/MACAddressBytesParser.cs @@ -0,0 +1,32 @@ +using RDMSharp.RDM; +using System; +using System.Linq; + +namespace RDMSharp.Extensions.BytesParser; + +public class MACAddressBytesParser : IBytesParser +{ + private static readonly byte _bytesLength = 6; + private static readonly string _formatIdentifyer = "mac-address"; + private static readonly PDL _payloadDataLength = new PDL(_bytesLength); + public string FormatIdentifyer => _formatIdentifyer; + public PDL? PayloadDataLength => _payloadDataLength; + + public object ParseToObject(ref byte[] data) + { + if (data.Length < _bytesLength) + throw new ArgumentException("Data length is less than required for MAC-Address parsing.", nameof(data)); + + MACAddress macAddress = new MACAddress(data.Take(_bytesLength)); + data = data.Skip(_bytesLength).ToArray(); + + return macAddress; + } + + public byte[] ParseToData(object obj) + { + if (obj is MACAddress macAddress) + return macAddress; + throw new ArgumentException($"Object is not of type {nameof(MACAddress)}", nameof(obj)); + } +} diff --git a/RDMSharp/Extensions/BytesParser/PIDBytesParser.cs b/RDMSharp/Extensions/BytesParser/PIDBytesParser.cs new file mode 100644 index 00000000..3807005f --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/PIDBytesParser.cs @@ -0,0 +1,29 @@ +using RDMSharp.RDM; +using System; + +namespace RDMSharp.Extensions.BytesParser; + +public class PIDBytesParser : IBytesParser +{ + private static readonly byte _bytesLength = 2; + private static readonly string _formatIdentifyer = "pid"; + private static readonly PDL _payloadDataLength = new PDL(_bytesLength); + public string FormatIdentifyer => _formatIdentifyer; + public PDL? PayloadDataLength => _payloadDataLength; + + public object ParseToObject(ref byte[] data) + { + if (data.Length < _bytesLength) + throw new ArgumentException("Data length is less than required for PID parsing.", nameof(data)); + + ERDM_Parameter pid = Tools.DataToEnum(ref data); + return pid; + } + + public byte[] ParseToData(object obj) + { + if (obj is ERDM_Parameter pid) + return Tools.ValueToData(pid); + throw new ArgumentException($"Object is not of type {nameof(ERDM_Parameter)}", nameof(obj)); + } +} diff --git a/RDMSharp/Extensions/BytesParser/StringFormats/ASCIIBytesParser.cs b/RDMSharp/Extensions/BytesParser/StringFormats/ASCIIBytesParser.cs new file mode 100644 index 00000000..cee22988 --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/StringFormats/ASCIIBytesParser.cs @@ -0,0 +1,12 @@ +using System.Text; + +namespace RDMSharp.Extensions.BytesParser.StringFormats; + +public sealed class ASCIIBytesParser : AbstractStringFormatBytesParser +{ + private static readonly string _formatIdentifyer = "ascii"; + private static readonly int _nullDelimiterBytesLength = 1; + public override sealed string FormatIdentifyer => _formatIdentifyer; + public override sealed Encoding Encoding => Encoding.ASCII; + public override int NullDelimiterBytesLength => _nullDelimiterBytesLength; +} \ No newline at end of file diff --git a/RDMSharp/Extensions/BytesParser/StringFormats/AbstractStringFormatBytesParser.cs b/RDMSharp/Extensions/BytesParser/StringFormats/AbstractStringFormatBytesParser.cs new file mode 100644 index 00000000..5ff7ba46 --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/StringFormats/AbstractStringFormatBytesParser.cs @@ -0,0 +1,55 @@ +using RDMSharp.RDM; +using System; +using System.Linq; +using System.Text; + +namespace RDMSharp.Extensions.BytesParser.StringFormats; + +public abstract class AbstractStringFormatBytesParser : IBytesParser +{ + public abstract string FormatIdentifyer { get; } + public abstract Encoding Encoding { get; } + public abstract int NullDelimiterBytesLength { get; } + public PDL? PayloadDataLength => null; + + + public object ParseToObject(ref byte[] data) + { + return getNullDelimitetData(ref data); + } + + public byte[] ParseToData(object obj) + { + if (obj is string _string) + return Encoding.GetBytes(_string); + throw new ArgumentException($"Object is not of type {nameof(String)}", nameof(obj)); + } + string getNullDelimitetData(ref byte[] data) + { + int charSize = NullDelimiterBytesLength; + int length = 0; + + while (length + charSize - 1 < data.Length) + { + bool isNull = true; + + for (int i = 0; i < charSize; i++) + { + if (data[length + i] != 0x00) + { + isNull = false; + break; + } + } + + if (isNull) + break; + + length += charSize; + } + + var res = Encoding.GetString(data, 0, length); + data = data.Skip(Math.Min(data.Length, length + charSize)).ToArray(); + return res; + } +} diff --git a/RDMSharp/Extensions/BytesParser/StringFormats/BigEndianUnicodeBytesParser.cs b/RDMSharp/Extensions/BytesParser/StringFormats/BigEndianUnicodeBytesParser.cs new file mode 100644 index 00000000..c2f556de --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/StringFormats/BigEndianUnicodeBytesParser.cs @@ -0,0 +1,12 @@ +using System.Text; + +namespace RDMSharp.Extensions.BytesParser.StringFormats; + +public sealed class BigEndianUnicodeBytesParser : AbstractStringFormatBytesParser +{ + private static readonly string _formatIdentifyer = "big_edian_unicode"; + private static readonly int _nullDelimiterBytesLength = 2; + public override sealed string FormatIdentifyer => _formatIdentifyer; + public override sealed Encoding Encoding => Encoding.BigEndianUnicode; + public override int NullDelimiterBytesLength => _nullDelimiterBytesLength; +} \ No newline at end of file diff --git a/RDMSharp/Extensions/BytesParser/StringFormats/Latin1BytesParser.cs b/RDMSharp/Extensions/BytesParser/StringFormats/Latin1BytesParser.cs new file mode 100644 index 00000000..34d9c684 --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/StringFormats/Latin1BytesParser.cs @@ -0,0 +1,12 @@ +using System.Text; + +namespace RDMSharp.Extensions.BytesParser.StringFormats; + +public sealed class Latin1BytesParser : AbstractStringFormatBytesParser +{ + private static readonly string _formatIdentifyer = "latin1"; + private static readonly int _nullDelimiterBytesLength = 1; + public override sealed string FormatIdentifyer => _formatIdentifyer; + public override sealed Encoding Encoding => Encoding.Latin1; + public override int NullDelimiterBytesLength => _nullDelimiterBytesLength; +} \ No newline at end of file diff --git a/RDMSharp/Extensions/BytesParser/StringFormats/UTF32BytesParser.cs b/RDMSharp/Extensions/BytesParser/StringFormats/UTF32BytesParser.cs new file mode 100644 index 00000000..93f6999c --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/StringFormats/UTF32BytesParser.cs @@ -0,0 +1,12 @@ +using System.Text; + +namespace RDMSharp.Extensions.BytesParser.StringFormats; + +public sealed class UTF32BytesParser : AbstractStringFormatBytesParser +{ + private static readonly string _formatIdentifyer = "utf32"; + private static readonly int _nullDelimiterBytesLength = 4; + public override sealed string FormatIdentifyer => _formatIdentifyer; + public override sealed Encoding Encoding => Encoding.UTF32; + public override int NullDelimiterBytesLength => _nullDelimiterBytesLength; +} \ No newline at end of file diff --git a/RDMSharp/Extensions/BytesParser/StringFormats/UTF8BytesParser.cs b/RDMSharp/Extensions/BytesParser/StringFormats/UTF8BytesParser.cs new file mode 100644 index 00000000..8135f736 --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/StringFormats/UTF8BytesParser.cs @@ -0,0 +1,12 @@ +using System.Text; + +namespace RDMSharp.Extensions.BytesParser.StringFormats; + +public sealed class UTF8BytesParser : AbstractStringFormatBytesParser +{ + private static readonly string _formatIdentifyer = "utf8"; + private static readonly int _nullDelimiterBytesLength = 1; + public override sealed string FormatIdentifyer => _formatIdentifyer; + public override sealed Encoding Encoding => Encoding.UTF8; + public override int NullDelimiterBytesLength => _nullDelimiterBytesLength; +} \ No newline at end of file diff --git a/RDMSharp/Extensions/BytesParser/StringFormats/UnicodeBytesParser.cs b/RDMSharp/Extensions/BytesParser/StringFormats/UnicodeBytesParser.cs new file mode 100644 index 00000000..6e32039f --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/StringFormats/UnicodeBytesParser.cs @@ -0,0 +1,12 @@ +using System.Text; + +namespace RDMSharp.Extensions.BytesParser.StringFormats; + +public sealed class UnicodeBytesParser : AbstractStringFormatBytesParser +{ + private static readonly string _formatIdentifyer = "unicode"; + private static readonly int _nullDelimiterBytesLength = 2; + public override sealed string FormatIdentifyer => _formatIdentifyer; + public override sealed Encoding Encoding => Encoding.Unicode; + public override int NullDelimiterBytesLength => _nullDelimiterBytesLength; +} \ No newline at end of file diff --git a/RDMSharp/Extensions/BytesParser/UIDBytesParser.cs b/RDMSharp/Extensions/BytesParser/UIDBytesParser.cs new file mode 100644 index 00000000..90ba6b9e --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/UIDBytesParser.cs @@ -0,0 +1,30 @@ +using RDMSharp.RDM; +using System; +using System.Linq; + +namespace RDMSharp.Extensions.BytesParser; + +public class UIDBytesParser : IBytesParser +{ + private static readonly byte _bytesLength = 6; + private static readonly string _formatIdentifyer = "uid"; + private static readonly PDL _payloadDataLength = new PDL(_bytesLength); + public string FormatIdentifyer => _formatIdentifyer; + public PDL? PayloadDataLength => _payloadDataLength; + + public object ParseToObject(ref byte[] data) + { + if (data.Length < _bytesLength) + throw new ArgumentException("Data length is less than required for UID parsing.", nameof(data)); + + UID uid = new UID(Tools.DataToUShort(ref data), Tools.DataToUInt(ref data)); + return uid; + } + + public byte[] ParseToData(object obj) + { + if (obj is UID uid) + return uid.ToBytes().ToArray(); + throw new ArgumentException($"Object is not of type {nameof(UID)}", nameof(obj)); + } +} diff --git a/RDMSharp/Extensions/BytesParser/UuidBytesParser.cs b/RDMSharp/Extensions/BytesParser/UuidBytesParser.cs new file mode 100644 index 00000000..8942ed36 --- /dev/null +++ b/RDMSharp/Extensions/BytesParser/UuidBytesParser.cs @@ -0,0 +1,32 @@ +using RDMSharp.RDM; +using System; +using System.Linq; + +namespace RDMSharp.Extensions.BytesParser; + +public class UuidBytesParser : IBytesParser +{ + private static readonly byte _bytesLength = 16; + private static readonly string _formatIdentifyer = "uuid"; + private static readonly PDL _payloadDataLength = new PDL(_bytesLength); + public string FormatIdentifyer => _formatIdentifyer; + public PDL? PayloadDataLength => _payloadDataLength; + + public object ParseToObject(ref byte[] data) + { + if (data.Length < _bytesLength) + throw new ArgumentException("Data length is less than required for Uuid parsing.", nameof(data)); + + Guid uuid = new Guid(data.Take(_bytesLength).ToArray()); + data = data.Skip(_bytesLength).ToArray(); + + return uuid; + } + + public byte[] ParseToData(object obj) + { + if (obj is Guid uuid) + return uuid.ToByteArray(); + throw new ArgumentException($"Object is not of type {nameof(Guid)}", nameof(obj)); + } +} diff --git a/RDMSharp/Extensions/ExtensionsManager.cs b/RDMSharp/Extensions/ExtensionsManager.cs new file mode 100644 index 00000000..9848c605 --- /dev/null +++ b/RDMSharp/Extensions/ExtensionsManager.cs @@ -0,0 +1,223 @@ +using Microsoft.Extensions.Logging; +using RDMSharp.RDM.Device; +using RDMSharp.RDM.Device.Module; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; + +namespace RDMSharp.Extensions; + +internal class ExtensionsManager +{ + private readonly ILogger Logger; + private static ExtensionsManager _instance; + public static ExtensionsManager Instance + { + get + { + if (_instance == null) + _instance = new ExtensionsManager(); + return _instance; + } + } + + private readonly ConcurrentDictionary bytesParsers = new(); + private readonly ConcurrentDictionary supportedParametersExtensions = new(); + private readonly ConcurrentDictionary modulesExtensions = new(); + + private ExtensionsManager() + { + Logger = Logging.CreateLogger(); + } + + private void LoadBytesParsersFromAssemblies() + { + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (var assembly in assemblies) + { + try + { + var types = assembly.GetTypes(); + foreach (var type in types) + if (typeof(IBytesParser).IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract) + if (Activator.CreateInstance(type) is IBytesParser parser) + RegisterBytesParser(parser); + } + catch + { + // Ignore assemblies that can't be loaded + } + } + } + + public void RegisterBytesParser(IBytesParser bytesParser) + { + if (!bytesParsers.ContainsKey(bytesParser.FormatIdentifyer)) + if (bytesParsers.TryAdd(bytesParser.FormatIdentifyer, bytesParser)) + Logger?.LogInformation($"Registered BytesParser for format '{bytesParser.FormatIdentifyer}'"); + } + + public bool TryGetBytesParser(string formatIdentifyer, out IBytesParser? bytesParser) + { + if (string.IsNullOrWhiteSpace(formatIdentifyer)) + { + bytesParser = null; + return false; + } + + if (bytesParsers.IsEmpty) + LoadBytesParsersFromAssemblies(); + + return bytesParsers.TryGetValue(formatIdentifyer, out bytesParser); + } + + private void LoadSupportedParametersExtension() + { + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (var assembly in assemblies) + { + try + { + var types = assembly.GetTypes(); + foreach (var type in types) + if (typeof(ISupportedParametersExtension).IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract) + if (Activator.CreateInstance(type) is ISupportedParametersExtension supportedParametersExtension) + RegisterSupportedParametersExtension(supportedParametersExtension); + } + catch + { + // Ignore assemblies that can't be loaded + } + } + } + + public void RegisterSupportedParametersExtension(ISupportedParametersExtension supportedParametersExtension) + { + if (!supportedParametersExtensions.ContainsKey(supportedParametersExtension.Key)) + if (supportedParametersExtensions.TryAdd(supportedParametersExtension.Key, supportedParametersExtension)) + Logger?.LogInformation($"Registered SupportedParametersExtension with key '{supportedParametersExtension.Key}'"); + } + + public bool TryGetSupportedParametersExtensions(EManufacturer manufacturer, out IReadOnlyCollection supportedParametersExtensionsResult) + { + if (supportedParametersExtensions.IsEmpty) + LoadSupportedParametersExtension(); + + List result = new(); + + foreach (var spe in supportedParametersExtensions.Values) + if (spe.Manufacturer == EManufacturer.ESTA || spe.Manufacturer == manufacturer) + result.Add(spe); + + supportedParametersExtensionsResult = result; + return true; + } + public bool TryGetSupportedParameterMetadata(EManufacturer manufacturer, ERDM_Parameter parameter, out SupportedParameterMetadata? supportedParameterMetadata) + { + try + { + if (supportedParametersExtensions.IsEmpty) + LoadSupportedParametersExtension(); + + bool isBlueprintModelParameter = false; + bool isBlueprintModelPersonalityParameter = false; + bool isManufacturerInternalParameter = false; + string name = null; + int updateTimeMilliseconds = -1; + foreach (var spe in supportedParametersExtensions.Values) + { + if (spe.Manufacturer != EManufacturer.ESTA && spe.Manufacturer != manufacturer) + continue; + + isBlueprintModelParameter |= spe.BlueprintModelParameters.Contains(parameter); + isBlueprintModelPersonalityParameter |= spe.BlueprintModelPersonalityParameters.Contains(parameter); + isManufacturerInternalParameter |= spe.ManufacturerInternalParameters.Contains(parameter); + + if (name == null && spe.TryGetParameterName(parameter, out var paramName)) + name = paramName; + if (updateTimeMilliseconds < 0 && spe.TryGetParameterUpdateTimeMilliseconds(parameter, out var paramUpdateTime)) + updateTimeMilliseconds = paramUpdateTime; + } + + if (isBlueprintModelParameter) + supportedParameterMetadata = SupportedParameterMetadata.CreateBlueprintModel(parameter, isManufacturerInternalParameter); + else if (isBlueprintModelPersonalityParameter) + supportedParameterMetadata = SupportedParameterMetadata.CreateBlueprintModelPersonality(parameter, isManufacturerInternalParameter); + else + supportedParameterMetadata = SupportedParameterMetadata.Create(parameter, isManufacturerInternalParameter); + + + supportedParameterMetadata.SetName(name); + supportedParameterMetadata.SetParameterUpdateTime(updateTimeMilliseconds); + + return true; + } + catch (Exception e) + { + Logger?.LogError(e, "Error while getting SupportedParametersExtensions"); + supportedParameterMetadata = null; + return false; + } + } + + private void LoadModulesExtension() + { + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (var assembly in assemblies) + { + try + { + var types = assembly.GetTypes(); + foreach (var type in types) + if (typeof(IModulesExtension).IsAssignableFrom(type) && !type.IsInterface && !type.IsAbstract) + if (Activator.CreateInstance(type) is IModulesExtension modulesExtension) + RegisterModulesExtension(modulesExtension); + } + catch + { + // Ignore assemblies that can't be loaded + } + } + } + public void RegisterModulesExtension(IModulesExtension modulesExtension) + { + if (!modulesExtensions.ContainsKey(modulesExtension.Key)) + if (modulesExtensions.TryAdd(modulesExtension.Key, modulesExtension)) + Logger?.LogInformation($"Registered ModulesExtension with key '{modulesExtension.Key}'"); + } + public bool TryGetModulesExtensions(EManufacturer manufacturer, out IReadOnlyCollection modulesExtensionsResult) + { + if (modulesExtensions.IsEmpty) + LoadModulesExtension(); + + List result = new(); + + foreach (var spe in modulesExtensions.Values) + if (spe.Manufacturer == EManufacturer.ESTA || spe.Manufacturer == manufacturer) + result.Add(spe); + + modulesExtensionsResult = result; + return true; + } + + public bool TryGetMatchingModules(AbstractRemoteRDMDevice device, out IReadOnlyCollection modulesResult) + { + List result = new(); + try + { + if (this.TryGetModulesExtensions((EManufacturer)device.UID.ManufacturerID, out IReadOnlyCollection modulesExtensionsResult)) + foreach (var modulesExtension in modulesExtensionsResult) + if (modulesExtension.TryGetModules(device.DeviceModel.GetSupportedParameters().Select(spm => spm.Parameter).ToArray(), out IReadOnlyCollection modulTypes)) + foreach (var modulType in modulTypes) + if (modulesExtension.TryCreateModuleInstance(modulType, device, out IModule moduleInstance)) + result.Add(moduleInstance); + } + catch (Exception e) + { + Logger?.LogError(e); + } + modulesResult = result.AsReadOnly(); + return result.Count != 0; + } +} \ No newline at end of file diff --git a/RDMSharp/Extensions/IBytesParser.cs b/RDMSharp/Extensions/IBytesParser.cs new file mode 100644 index 00000000..4359aff1 --- /dev/null +++ b/RDMSharp/Extensions/IBytesParser.cs @@ -0,0 +1,12 @@ +using RDMSharp.RDM; + +namespace RDMSharp.Extensions; + +public interface IBytesParser +{ + string FormatIdentifyer { get; } + PDL? PayloadDataLength { get; } + + object ParseToObject(ref byte[] data); + byte[] ParseToData(object obj); +} \ No newline at end of file diff --git a/RDMSharp/Extensions/IModulesExtension.cs b/RDMSharp/Extensions/IModulesExtension.cs new file mode 100644 index 00000000..eec4c7d3 --- /dev/null +++ b/RDMSharp/Extensions/IModulesExtension.cs @@ -0,0 +1,14 @@ +using RDMSharp.RDM.Device.Module; +using System; +using System.Collections.Generic; + +namespace RDMSharp.Extensions; + +public interface IModulesExtension +{ + string Key { get; } + EManufacturer Manufacturer { get; } + + bool TryGetModules(ERDM_Parameter[] parameters, out IReadOnlyCollection modules); + bool TryCreateModuleInstance(Type moduleType, IRDMRemoteDevice remoteDevice, out IModule moduleInstance); +} \ No newline at end of file diff --git a/RDMSharp/Extensions/ISupportedParametersExtension.cs b/RDMSharp/Extensions/ISupportedParametersExtension.cs new file mode 100644 index 00000000..4cfa3cd5 --- /dev/null +++ b/RDMSharp/Extensions/ISupportedParametersExtension.cs @@ -0,0 +1,19 @@ +using System; +using System.Threading.Tasks; + +namespace RDMSharp.Extensions; + +public interface ISupportedParametersExtension +{ + string Key { get; } + EManufacturer Manufacturer { get; } + + ERDM_Parameter[] BlueprintModelParameters { get; } + ERDM_Parameter[] BlueprintModelPersonalityParameters { get; } + ERDM_Parameter[] ManufacturerInternalParameters { get; } + + Task RegisterAddSupportedParametersHandler(IRDMDeviceModel deviceModel, Func handler); + + bool TryGetParameterName(ERDM_Parameter parameter, out string name); + bool TryGetParameterUpdateTimeMilliseconds(ERDM_Parameter parameter, out int milliseconds); +} \ No newline at end of file diff --git a/RDMSharp/Extensions/ModulesExtension/AbstractModulesExtension.cs b/RDMSharp/Extensions/ModulesExtension/AbstractModulesExtension.cs new file mode 100644 index 00000000..12fd1ba9 --- /dev/null +++ b/RDMSharp/Extensions/ModulesExtension/AbstractModulesExtension.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.Logging; +using RDMSharp.RDM.Device.Module; +using System; +using System.Collections.Generic; + +namespace RDMSharp.Extensions.ModulesExtension; + +public abstract class AbstractModulesExtension : IModulesExtension +{ + protected ILogger Logger; + public abstract string Key { get; } + public abstract EManufacturer Manufacturer { get; } + + public AbstractModulesExtension() + { + Logger = Logging.CreateLogger(this.Key); + } + + public abstract bool TryGetModules(ERDM_Parameter[] parameters, out IReadOnlyCollection modules); + + public virtual bool TryCreateModuleInstance(Type moduleType, IRDMRemoteDevice remoteDevice, out IModule moduleInstance) + { + try + { + moduleInstance = Activator.CreateInstance(moduleType, remoteDevice) as IModule + ?? throw new InvalidOperationException($"Could not create instance of module type '{moduleType.FullName}'"); + return true; + } + catch (Exception ex) + { + Logger.LogError(ex, "Error creating module instance of type '{ModuleType}'", moduleType.FullName); + moduleInstance = null; + return false; + } + } +} \ No newline at end of file diff --git a/RDMSharp/Extensions/ModulesExtension/ModulesExtension.cs b/RDMSharp/Extensions/ModulesExtension/ModulesExtension.cs new file mode 100644 index 00000000..fb8fbd90 --- /dev/null +++ b/RDMSharp/Extensions/ModulesExtension/ModulesExtension.cs @@ -0,0 +1,92 @@ +using RDMSharp.RDM.Device.Module; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace RDMSharp.Extensions.ModulesExtension; + +public sealed class ModulesExtension : AbstractModulesExtension +{ + private static readonly string _key = "BasicModulesExtension"; + private const EManufacturer _manufacturer = EManufacturer.ESTA; + public sealed override string Key => _key; + public sealed override EManufacturer Manufacturer => _manufacturer; + + public sealed override bool TryGetModules(ERDM_Parameter[] parameters, out IReadOnlyCollection modules) + { + var _modules = new List(); + + if (parameters.Contains(ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID) && + parameters.Contains(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL)) + _modules.Add(typeof(BootSoftwareVersionModule)); + + if (parameters.Contains(ERDM_Parameter.DEVICE_INFO)) + _modules.Add(typeof(DeviceInfoModule)); + + if (parameters.Contains(ERDM_Parameter.DEVICE_LABEL)) + _modules.Add(typeof(DeviceLabelModule)); + + if (parameters.Contains(ERDM_Parameter.DEVICE_MODEL_DESCRIPTION)) + _modules.Add(typeof(DeviceModelDescriptionModule)); + + if (parameters.Contains(ERDM_Parameter.DMX_PERSONALITY) && + parameters.Contains(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION)) + _modules.Add(typeof(DMX_PersonalityModule)); + + if (parameters.Contains(ERDM_Parameter.DMX_START_ADDRESS)) + _modules.Add(typeof(DMX_StartAddressModule)); + + if (parameters.Contains(ERDM_Parameter.IDENTIFY_DEVICE)) + _modules.Add(typeof(IdentifyDeviceModule)); + + if (parameters.Contains(ERDM_Parameter.LIST_INTERFACES)) + _modules.Add(typeof(InterfaceModule)); + + if (parameters.Contains(ERDM_Parameter.MANUFACTURER_LABEL)) + _modules.Add(typeof(ManufacturerLabelModule)); + + if (parameters.Contains(ERDM_Parameter.PRESET_PLAYBACK)) + _modules.Add(typeof(PresetsModule)); + + if (parameters.Contains(ERDM_Parameter.PROXIED_DEVICES)) + _modules.Add(typeof(ProxiedDevicesModule)); + + if (parameters.Contains(ERDM_Parameter.REAL_TIME_CLOCK)) + _modules.Add(typeof(RealTimeClockModule)); + + if (parameters.Contains(ERDM_Parameter.CURVE)) + _modules.Add(typeof(CurveModule)); + + if (parameters.Contains(ERDM_Parameter.OUTPUT_RESPONSE_TIME)) + _modules.Add(typeof(OutputResponseTimeModule)); + + if (parameters.Contains(ERDM_Parameter.MODULATION_FREQUENCY)) + _modules.Add(typeof(ModulationFrequencyModule)); + + if (parameters.Contains(ERDM_Parameter.PERFORM_SELFTEST)) + _modules.Add(typeof(SelfTestsModule)); + + if (parameters.Contains(ERDM_Parameter.SENSOR_DEFINITION)) + _modules.Add(typeof(SensorsModule)); + + if (parameters.Contains(ERDM_Parameter.SLOT_DESCRIPTION)) + _modules.Add(typeof(SlotsModule)); + + if (parameters.Contains(ERDM_Parameter.SOFTWARE_VERSION_LABEL)) + _modules.Add(typeof(SoftwareVersionModule)); + + if (parameters.Contains(ERDM_Parameter.STATUS_MESSAGES)) + _modules.Add(typeof(ProxiedDevicesModule)); + + if (parameters.Contains(ERDM_Parameter.LIST_TAGS)) + _modules.Add(typeof(TagsModule)); + + #region E1.31-7 2019 + if (parameters.Contains(ERDM_Parameter.ENDPOINT_LIST)) + _modules.Add(typeof(EndpointsModule)); + #endregion + + modules = _modules; + return true; + } +} \ No newline at end of file diff --git a/RDMSharp/Extensions/SupportedParametersExtension/AbstractSupportedParametersExtension.cs b/RDMSharp/Extensions/SupportedParametersExtension/AbstractSupportedParametersExtension.cs new file mode 100644 index 00000000..3c2c2ec2 --- /dev/null +++ b/RDMSharp/Extensions/SupportedParametersExtension/AbstractSupportedParametersExtension.cs @@ -0,0 +1,51 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Concurrent; +using System.Threading.Tasks; + +namespace RDMSharp.Extensions.SupportedParametersExtension; + +public abstract class AbstractSupportedParametersExtension : ISupportedParametersExtension +{ + protected ILogger Logger; + public abstract string Key { get; } + public abstract EManufacturer Manufacturer { get; } + public abstract ERDM_Parameter[] BlueprintModelParameters { get; } + public abstract ERDM_Parameter[] BlueprintModelPersonalityParameters { get; } + public abstract ERDM_Parameter[] ManufacturerInternalParameters { get; } + + private ConcurrentDictionary> _handlers = new(); + + protected AbstractSupportedParametersExtension() + { + Logger = Logging.CreateLogger(Key); + } + + protected void registerHandler(IRDMDeviceModel deviceModel, Func handler) + { + _handlers.TryAdd(deviceModel, handler); + } + protected void unregisterHandler(IRDMDeviceModel deviceModel) + { + _handlers.TryRemove(deviceModel, out _); + } + protected Func getHandler(IRDMDeviceModel deviceModel) + { + _handlers.TryGetValue(deviceModel, out var handler); + return handler; + } + + public async Task RegisterAddSupportedParametersHandler(IRDMDeviceModel deviceModel, Func handler) + { + registerHandler(deviceModel, handler); + await registerAddSupportedParametersHandler(deviceModel, handler); + } + protected virtual async Task registerAddSupportedParametersHandler(IRDMDeviceModel deviceModel, Func handler) + { + await Task.CompletedTask; + } + + public abstract bool TryGetParameterName(ERDM_Parameter parameter, out string name); + + public abstract bool TryGetParameterUpdateTimeMilliseconds(ERDM_Parameter parameter, out int milliseconds); +} \ No newline at end of file diff --git a/RDMSharp/Extensions/SupportedParametersExtension/SupportedParametersExtension.cs b/RDMSharp/Extensions/SupportedParametersExtension/SupportedParametersExtension.cs new file mode 100644 index 00000000..596b6f2b --- /dev/null +++ b/RDMSharp/Extensions/SupportedParametersExtension/SupportedParametersExtension.cs @@ -0,0 +1,235 @@ +using Microsoft.Extensions.Logging; +using RDMSharp.Metadata; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace RDMSharp.Extensions.SupportedParametersExtension; + +public sealed class SupportedParametersExtension : AbstractSupportedParametersExtension +{ + private const string _key = "BasicSupportedParametersExtension"; + private const EManufacturer _manufacturer = EManufacturer.ESTA; + private static readonly ERDM_Parameter[] _manufacturerInternalParameters = new ERDM_Parameter[0]; + public sealed override string Key => _key; + public sealed override EManufacturer Manufacturer => _manufacturer; + + public sealed override ERDM_Parameter[] BlueprintModelParameters => Constants.BLUEPRINT_MODEL_PARAMETERS; + + public sealed override ERDM_Parameter[] BlueprintModelPersonalityParameters => Constants.BLUEPRINT_MODEL_PERSONALITY_PARAMETERS; + + public sealed override ERDM_Parameter[] ManufacturerInternalParameters => _manufacturerInternalParameters; + + public sealed override bool TryGetParameterName(ERDM_Parameter parameter, out string name) + { + if (((ushort)parameter) >= 0x8000 && ((ushort)parameter) <= 0xFFDF) + { + name = null; + return false; + } + + var define = MetadataFactory.GetDefine(new ParameterBag(parameter)); + if (define is not MetadataJSONObjectDefine parameterDefine) + { + name = parameter.ToString(); + return true; + } + + name = define.DisplayName ?? define.Name ?? parameter.ToString(); + return true; + } + + public sealed override bool TryGetParameterUpdateTimeMilliseconds(ERDM_Parameter parameter, out int milliseconds) + { + if (((ushort)parameter) >= 0x8000 && ((ushort)parameter) <= 0xFFDF) + { + milliseconds = -1; + return false; + } + if (parameter.GetAttribute() is not ParameterUpdateTimeAttribute attribute) + { + milliseconds = -1; + return false; + } + milliseconds = attribute.Milliseconds; + return true; + } + + protected override async Task registerAddSupportedParametersHandler(IRDMDeviceModel deviceModel, Func handler) + { + var parameters = deviceModel.GetSupportedParameters().Select(spm => spm.Parameter).ToArray(); + List supportedParameters = new List(); + var deviceInfo = deviceModel.DeviceInfo; + + if (!parameters.Contains(ERDM_Parameter.QUEUED_MESSAGE)) + { + supportedParameters.Add(ERDM_Parameter.QUEUED_MESSAGE); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for QUEUED_MESSAGE Parameter."); + } + + // Remote Device not send DMX_START_ADDRESS Parameter but uses it! + if (deviceInfo.Dmx512StartAddress.HasValue && + deviceInfo.Dmx512StartAddress >= 1 && + deviceInfo.Dmx512StartAddress.Value <= 512 && + !parameters.Contains(ERDM_Parameter.DMX_START_ADDRESS)) + { + supportedParameters.Add(ERDM_Parameter.DMX_START_ADDRESS); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for DMX_START_ADDRESS Parameter based on Start Address value {deviceInfo.Dmx512StartAddress.Value}."); + } + + // Remote Device not send DMX_PERSONALITY Parameter but uses it! + if (deviceInfo.Dmx512CurrentPersonality.HasValue && + !parameters.Contains(ERDM_Parameter.DMX_PERSONALITY)) + { + supportedParameters.Add(ERDM_Parameter.DMX_PERSONALITY); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for DMX_PERSONALITY Parameter based on Current Personality value {deviceInfo.Dmx512CurrentPersonality.Value}."); + } + + // Remote Device not send DMX_PERSONALITY Parameter but uses it! + if (deviceInfo.Dmx512NumberOfPersonalities != 0 && + !parameters.Contains(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION)) + { + supportedParameters.Add(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for DMX_PERSONALITY_DESCRIPTION Parameter based on Number of Personalities value {deviceInfo.Dmx512NumberOfPersonalities}."); + } + + if (parameters.Any(p => ((ushort)p) >= 0x8000 && + ((ushort)p) <= 0xFFDF)) + { + // Remote Device not send PARAMETER_DESCRIPTION Parameter but has Manufacture speific Parameters it! + if (!parameters.Contains(ERDM_Parameter.PARAMETER_DESCRIPTION)) + { + supportedParameters.Add(ERDM_Parameter.PARAMETER_DESCRIPTION); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for PARAMETER_DESCRIPTION Parameter based on presence of Manufacturer Specific Parameters."); + } + + // Remote Device not send METADATA_PARAMETER_VERSION Parameter but has Manufacture speific Parameters it! + if (!parameters.Contains(ERDM_Parameter.METADATA_PARAMETER_VERSION)) + { + supportedParameters.Add(ERDM_Parameter.METADATA_PARAMETER_VERSION); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for METADATA_PARAMETER_VERSION Parameter based on presence of Manufacturer Specific Parameters."); + } + // Remote Device not send METADATA_JSON Parameter but has Manufacture speific Parameters it! + if (!parameters.Contains(ERDM_Parameter.METADATA_JSON)) + { + supportedParameters.Add(ERDM_Parameter.METADATA_JSON); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for METADATA_JSON Parameter based on presence of Manufacturer Specific Parameters."); + } + } + + #region Assuming support for DESCRIPTION Parameters based on presence of related Parameters + //Test it if the device supports CURVE Parameter, if not it will be labled as not supported later on + if (parameters.Contains(ERDM_Parameter.CURVE) && !parameters.Contains(ERDM_Parameter.CURVE_DESCRIPTION)) + { + supportedParameters.Add(ERDM_Parameter.CURVE_DESCRIPTION); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for CURVE_DESCRIPTION Parameter."); + } + + //Test it if the device supports OUTPUT_RESPONSE_TIME Parameter, if not it will be labled as not supported later on + if (parameters.Contains(ERDM_Parameter.OUTPUT_RESPONSE_TIME) && !parameters.Contains(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION)) + { + supportedParameters.Add(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for OUTPUT_RESPONSE_TIME_DESCRIPTION Parameter."); + } + + //Test it if the device supports MODULATION_FREQUENCY Parameter, if not it will be labled as not supported later on + if (parameters.Contains(ERDM_Parameter.MODULATION_FREQUENCY) && !parameters.Contains(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION)) + { + supportedParameters.Add(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for MODULATION_FREQUENCY_DESCRIPTION Parameter."); + } + + //Test it if the device supports LOCK_STATE Parameter, if not it will be labled as not supported later on + if (parameters.Contains(ERDM_Parameter.LOCK_STATE) && !parameters.Contains(ERDM_Parameter.LOCK_STATE_DESCRIPTION)) + { + supportedParameters.Add(ERDM_Parameter.LOCK_STATE_DESCRIPTION); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for LOCK_STATE_DESCRIPTION Parameter."); + } + #endregion + + + //Test it if the device supports Identify Device Parameter, if not it will be labled as not supported later on + if (!parameters.Contains(ERDM_Parameter.IDENTIFY_DEVICE)) + { + supportedParameters.Add(ERDM_Parameter.IDENTIFY_DEVICE); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for IDENTIFY_DEVICE Parameter."); + } + + //Test it if the device supports Software Version Lable Device Parameter, if not it will be labled as not supported later on + if (!parameters.Contains(ERDM_Parameter.SOFTWARE_VERSION_LABEL)) + { + supportedParameters.Add(ERDM_Parameter.SOFTWARE_VERSION_LABEL); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for SOFTWARE_VERSION_LABEL Parameter."); + } + + //Test it if the device supports Factory Defaults Device Parameter, if not it will be labled as not supported later on + if (!parameters.Contains(ERDM_Parameter.FACTORY_DEFAULTS)) + { + supportedParameters.Add(ERDM_Parameter.FACTORY_DEFAULTS); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for FACTORY_DEFAULTS Parameter."); + } + + // Remote Device not send Required Tag Parameters but has at least one Tag Parameter! + if (parameters.Any(p => ((ushort)p) >= 0x0651 && + ((ushort)p) <= 0x0655)) + { + if (!parameters.Contains(ERDM_Parameter.LIST_TAGS)) + { + supportedParameters.Add(ERDM_Parameter.LIST_TAGS); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for LIST_TAGS Parameter based on presence of Tag Parameters."); + } + if (!parameters.Contains(ERDM_Parameter.ADD_TAG)) + { + supportedParameters.Add(ERDM_Parameter.ADD_TAG); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for ADD_TAG Parameter based on presence of Tag Parameters."); + } + if (!parameters.Contains(ERDM_Parameter.REMOVE_TAG)) + { + supportedParameters.Add(ERDM_Parameter.REMOVE_TAG); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for REMOVE_TAG Parameter based on presence of Tag Parameters."); + } + if (!parameters.Contains(ERDM_Parameter.CHECK_TAG)) + { + supportedParameters.Add(ERDM_Parameter.CHECK_TAG); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for CHECK_TAG Parameter based on presence of Tag Parameters."); + } + if (!parameters.Contains(ERDM_Parameter.CLEAR_TAGS)) + { + supportedParameters.Add(ERDM_Parameter.CLEAR_TAGS); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for CLEAR_TAGS Parameter based on presence of Tag Parameters."); + } + } + + // Remote Device not send LIST_INTERFACES Parameter but has Interface Parameters it! + if (parameters.Any(p => ((ushort)p) > 0x7000 && + ((ushort)p) <= 0x700D)) + { + if (!parameters.Contains(ERDM_Parameter.LIST_INTERFACES)) + { + supportedParameters.Add(ERDM_Parameter.LIST_INTERFACES); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for LIST_INTERFACES Parameter based on presence of Interface Parameters."); + } + } + + // Remote Device not send ENDPOINT_LIST Parameter but has Endpoint Parameters it! + if (parameters.Any(p => ((ushort)p) > 0x9000 && + ((ushort)p) <= 0x900D)) + { + if (!parameters.Contains(ERDM_Parameter.ENDPOINT_LIST)) + { + supportedParameters.Add(ERDM_Parameter.ENDPOINT_LIST); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for ENDPOINT_LIST Parameter based on presence of Endpoint Parameters."); + } + } + + if (parameters.Contains(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY) && + !parameters.Contains(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION)) + { + supportedParameters.Add(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION); + Logger?.LogInformation($"Remote Device Model ID 0x{deviceInfo.DeviceModelId:X4} - Assuming support for BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION Parameter based on presence of BACKGROUND_QUEUED_STATUS_POLICY Parameter."); + } + + await handler.Invoke(supportedParameters.ToArray()); + } +} \ No newline at end of file diff --git a/RDMSharp/Metadata/DataTree.cs b/RDMSharp/Metadata/DataTree.cs index a8d2f25c..fd3d0f05 100644 --- a/RDMSharp/Metadata/DataTree.cs +++ b/RDMSharp/Metadata/DataTree.cs @@ -2,101 +2,102 @@ using System.Collections.Generic; using System.Linq; -namespace RDMSharp.Metadata -{ +namespace RDMSharp.Metadata; + #pragma warning disable CS8632 - public readonly struct DataTree : IEquatable +public readonly struct DataTree : IEquatable +{ + public readonly string Name; + public readonly uint Index; + public readonly object? Value; + public readonly string? Unit; + public readonly bool IsCompound; + public readonly bool IsList; + public readonly DataTreeValueLabel[]? Labels; + public readonly DataTree[]? Children; + public readonly DataTreeIssue[]? Issues; + + private DataTree(string name, uint index, DataTreeIssue[]? issues = null, bool isCompound = false, bool isList = false) + { + Name = name; + Index = index; + Issues = issues; + IsCompound = isCompound; + IsList = isList; + } + public DataTree(DataTree dataTree, uint index) : this(dataTree.Name, index, dataTree.Issues, dataTree.IsCompound, dataTree.IsList) { - public readonly string Name; - public readonly uint Index; - public readonly object? Value; - public readonly string? Unit; - public readonly bool IsCompound; - public readonly DataTreeValueLabel[]? Labels; - public readonly DataTree[]? Children; - public readonly DataTreeIssue[]? Issues; + Value = dataTree.Value; + Unit = dataTree.Unit; + Labels = dataTree.Labels; + Children = dataTree.Children; + } + public DataTree(string name, uint index, object value, DataTreeIssue[]? issues = null, string unit = null, DataTreeValueLabel[] labels = null, bool isCompound = false, bool isList = false) : this(name, index, issues, isCompound, isList) + { + if (value is IEnumerable || value is DataTree[] children) + throw new ArgumentException($"Use other Constructor if you use {nameof(Children)}"); - private DataTree(string name, uint index, DataTreeIssue[]? issues = null, bool isCompound = false) - { - Name = name; - Index = index; - Issues = issues; - IsCompound = isCompound; - } - public DataTree(DataTree dataTree, uint index) : this(dataTree.Name, index, dataTree.Issues, dataTree.IsCompound) - { - Value = dataTree.Value; - Unit = dataTree.Unit; - Labels = dataTree.Labels; - Children = dataTree.Children; - } - public DataTree(string name, uint index, object value, DataTreeIssue[]? issues = null, string unit = null, DataTreeValueLabel[] labels = null, bool isCompound = false) : this(name, index, issues, isCompound) - { - if (value is IEnumerable || value is DataTree[] children) - throw new ArgumentException($"Use other Constructor if you use {nameof(Children)}"); + Value = value; + Unit = unit; + Labels = labels; + } - Value = value; - Unit = unit; - Labels = labels; - } + public DataTree(string name, uint index, DataTree[] children, DataTreeIssue[]? issues = null, bool isCompound = false, bool isList = false) : this(name, index, issues, isCompound, isList) + { + Children = children; + } - public DataTree(string name, uint index, DataTree[] children, DataTreeIssue[]? issues = null, bool isCompound = false) : this(name, index, issues, isCompound) - { - Children = children; - } + public override string ToString() + { + return $"[{Index}] {Name}: {Value}"; + } - public override string ToString() - { - return $"[{Index}] {Name}: {Value}"; - } + public override bool Equals(object obj) + { + return obj is DataTree tree && Equals(tree); + } - public override bool Equals(object obj) - { - return obj is DataTree tree && Equals(tree); - } + public bool Equals(DataTree other) + { + return Name == other.Name && + Index == other.Index && + EqualityComparer.Default.Equals(Value, other.Value) && + compairArrays(this, other); - public bool Equals(DataTree other) + bool compairArrays(DataTree _this, DataTree other) { - return Name == other.Name && - Index == other.Index && - EqualityComparer.Default.Equals(Value, other.Value) && - compairArrays(this, other); - - bool compairArrays(DataTree _this, DataTree other) + if (_this.Children != null) { - if (_this.Children != null) - { - if (!_this.Children.SequenceEqual(other.Children)) - return false; - } - else if (other.Children != null) + if (!_this.Children.SequenceEqual(other.Children)) return false; - if (_this.Issues != null) - { - if (!_this.Issues.SequenceEqual(other.Issues)) - return false; - } - else if (other.Issues != null) + } + else if (other.Children != null) + return false; + if (_this.Issues != null) + { + if (!_this.Issues.SequenceEqual(other.Issues)) return false; - - return true; } - } + else if (other.Issues != null) + return false; - public override int GetHashCode() - { - return HashCode.Combine(Name, Index, Value, Children, Issues); + return true; } + } - public static bool operator ==(DataTree left, DataTree right) - { - return left.Equals(right); - } + public override int GetHashCode() + { + return HashCode.Combine(Name, Index, Value, Children, Issues); + } - public static bool operator !=(DataTree left, DataTree right) - { - return !(left == right); - } + public static bool operator ==(DataTree left, DataTree right) + { + return left.Equals(right); + } + + public static bool operator !=(DataTree left, DataTree right) + { + return !(left == right); } } #pragma warning restore CS8632 \ No newline at end of file diff --git a/RDMSharp/Metadata/DataTreeBranch.cs b/RDMSharp/Metadata/DataTreeBranch.cs index 16407400..cef474c4 100644 --- a/RDMSharp/Metadata/DataTreeBranch.cs +++ b/RDMSharp/Metadata/DataTreeBranch.cs @@ -10,368 +10,507 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("RDMSharpTests")] -namespace RDMSharp.Metadata +namespace RDMSharp.Metadata; + +public readonly struct DataTreeBranch : IEquatable { - public readonly struct DataTreeBranch : IEquatable - { - private static ILogger Logger = Logging.CreateLogger(); - public static readonly DataTreeBranch Empty = new DataTreeBranch(); - public static readonly DataTreeBranch Unset = new DataTreeBranch(true); + private static ILogger Logger = Logging.CreateLogger(); + public static readonly DataTreeBranch Empty = new DataTreeBranch(); + public static readonly DataTreeBranch Unset = new DataTreeBranch(true); - public readonly DataTree[] Children; - public readonly bool IsEmpty; - public readonly bool IsUnset; + public readonly DataTree[] Children; + public readonly bool IsEmpty; + public readonly bool IsUnset; - public readonly object ParsedObject; - public DataTreeBranch() - { + public readonly object ParsedObject; + public DataTreeBranch() + { + IsEmpty = true; + } + private DataTreeBranch(bool isUnset) + { + IsUnset = true; + } + public DataTreeBranch(params DataTree[] children) + { + if (children.Length == 0) IsEmpty = true; - } - private DataTreeBranch(bool isUnset) - { - IsUnset = true; - } - public DataTreeBranch(params DataTree[] children) - { - if (children.Length == 0) - IsEmpty = true; - Children = children; - if (Children.Count(c => c.Index == 0) > 1) - for (uint i = 0; i < Children.Length; i++) - Children[i] = new DataTree(Children[i], i); - } - private DataTreeBranch(object parsedObject, params DataTree[] children) : this(children) - { - ParsedObject = parsedObject; - } - public DataTreeBranch(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType, params DataTree[] children) : this(children) - { - if (define == null) - throw new ArgumentNullException(); + Children = children; + if (Children.Count(c => c.Index == 0) > 1) + for (uint i = 0; i < Children.Length; i++) + Children[i] = new DataTree(Children[i], i); + } + private DataTreeBranch(object parsedObject, params DataTree[] children) : this(children) + { + ParsedObject = parsedObject; + } + public DataTreeBranch(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType, params DataTree[] children) : this(children) + { + if (define == null) + throw new ArgumentNullException(); + try + { ParsedObject = this.getParsedObject(define, commandType); } - - private object getParsedObject(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType) + catch (Exception e) { - ushort pid = define.PID; - var definedDataTreeObjectType = MetadataFactory.GetDefinedDataTreeObjectType(define, commandType); - return getParsedObject(pid, definedDataTreeObjectType, commandType); + Logger?.LogWarning($"Can't get a Parsed Object for {define.Name} (0x{define.PID:X4})", e); } - private object getParsedObject(ushort pid, Type definedDataTreeObjectType, Command.ECommandDublicate commandType) - { - if (IsEmpty || IsUnset) - return null; - try + } + + private object getParsedObject(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType) + { + ushort pid = define.PID; + var definedDataTreeObjectType = MetadataFactory.GetDefinedDataTreeObjectType(define, commandType); + return getParsedObject(define.ManufacturerID, pid, definedDataTreeObjectType, commandType); + } + private object getParsedObject(ushort manufacturerID, ushort pid, Type definedDataTreeObjectType, Command.ECommandDublicate commandType) + { + if (IsEmpty || IsUnset) + return null; + try + { + bool checkManufacturer(ushort attrManuId) + { + if (attrManuId == (ushort)EManufacturer.ESTA) + return true; + + return attrManuId == manufacturerID; + } + + if (definedDataTreeObjectType != null) { - if (definedDataTreeObjectType != null) + if (definedDataTreeObjectType.IsEnum) { - if (definedDataTreeObjectType.IsEnum) - { - var enumAttribute = definedDataTreeObjectType.GetCustomAttributes().FirstOrDefault(a => (ushort)a.Parameter == pid && a.Command == commandType); + var enumAttribute = definedDataTreeObjectType.GetCustomAttributes().FirstOrDefault(a => (ushort)a.Parameter == pid && a.Command == commandType && checkManufacturer((ushort)a.Manufacturer)); - var eChildren = getChildrenUsingPath(enumAttribute, Children); - if (enumAttribute.IsArray) - { - var array = Array.CreateInstance(definedDataTreeObjectType, eChildren.Length); - var aa = eChildren.Select(eC => Enum.ToObject(definedDataTreeObjectType, eC.Value)).ToArray(); - Array.Copy(aa, array, eChildren.Length); - return array; - } - else - return Enum.ToObject(definedDataTreeObjectType, eChildren.Single().Value); + var eChildren = getChildrenUsingPath(enumAttribute, Children); + if (enumAttribute.IsArray) + { + var array = Array.CreateInstance(definedDataTreeObjectType, eChildren.Length); + var aa = eChildren.Select(eC => Enum.ToObject(definedDataTreeObjectType, eC.Value)).ToArray(); + Array.Copy(aa, array, eChildren.Length); + return array; } + else + return Enum.ToObject(definedDataTreeObjectType, eChildren.Single().Value); + } - ConstructorInfo[] constructors = definedDataTreeObjectType.GetConstructors(); - var objectAttribute = definedDataTreeObjectType.GetCustomAttributes().FirstOrDefault(a => (ushort)a.Parameter == pid && a.Command == commandType); + ConstructorInfo[] constructors = definedDataTreeObjectType.GetConstructors(); + var objectAttribute = definedDataTreeObjectType.GetCustomAttributes().FirstOrDefault(a => (ushort)a.Parameter == pid && a.Command == commandType && checkManufacturer((ushort)a.Manufacturer)); - var children = getChildrenUsingPath(objectAttribute, Children); - DataTree[] getChildrenUsingPath(DataTreeObjectAttribute objectAttribute, DataTree[] children) + var flatDataTree = flateningDateTree(Children); + //var children = getChildrenUsingPath(objectAttribute, Children); + DataTree[] getChildrenUsingPath(DataTreeObjectAttribute objectAttribute, DataTree[] children) + { + if (!string.IsNullOrWhiteSpace(objectAttribute.Path)) { - if (!string.IsNullOrWhiteSpace(objectAttribute.Path)) + string[] path = objectAttribute.Path.Split('/'); + while (path.Length >= 1) { - string[] path = objectAttribute.Path.Split('/'); - while (path.Length >= 1) - { - children = children.FirstOrDefault(c => string.Equals(c.Name, path[0])).Children; - path = path.Skip(1).ToArray(); - } + children = children.FirstOrDefault(c => string.Equals(c.Name, path[0])).Children; + path = path.Skip(1).ToArray(); } - return children; } + return children; + } - foreach (var constructor in constructors) - { + foreach (var constructor in constructors) + { - if (constructor.GetCustomAttribute() is DataTreeObjectConstructorAttribute cAttribute) + if (constructor.GetCustomAttribute() is DataTreeObjectConstructorAttribute cAttribute) + { + DataTreeObjectParameterAttribute getOPA(ParameterInfo parameterInfo) { - if (!children.All(c => c.IsCompound)) - return createObjectFromDataTree(children); - else - { - var array = Array.CreateInstance(definedDataTreeObjectType, children.Length); - foreach (var comp in children) - array.SetValue(createObjectFromDataTree(comp.Children), comp.Index); - return array; - } + var attributes = parameterInfo.GetCustomAttributes(); + if (attributes.Count() == 1) + return attributes.Single(); + return attributes.Single(a => (ushort)a.Parameter == pid); + } + #region Fast path for non-compound objects with matching parameter attributes + var cParameters = constructor.GetParameters(); + var pAttributes = cParameters.Select(p => getOPA(p)).ToArray(); - object createObjectFromDataTree(DataTree[] children) + if (pAttributes.Select(p => p.Name).SequenceEqual(flatDataTree.Keys)) + { + List parameters = new List(); + bool _break = false; + for (int i = 0; i < cParameters.Length; i++) { - var parameters = new List(); - foreach (var param in constructor.GetParameters()) - if (param.GetCustomAttribute() is DataTreeObjectParameterAttribute pAttribute) + var constructorParameter = cParameters[i]; + var parameterAttribute = pAttributes[i]; + if (flatDataTree.TryGetValue(parameterAttribute.Name, out object value)) + { + Type expectedType = Nullable.GetUnderlyingType(constructorParameter.ParameterType) ?? constructorParameter.ParameterType; + + if (value is null) + if (expectedType.IsValueType) + value = Activator.CreateInstance(expectedType); // set to default value if null so it can be assigned to value types, if the parameter is nullable this will be overwritten to null in the constructor invoke and if not it will be set to default value which is the best we can do in this case + + if (expectedType == value?.GetType() || value is null) + parameters.Add(value); + else if (value is object[] compoundObjectArray) { - var children2 = children; - - string name = pAttribute.Name; - string[] path = name.Split('/'); - while (path.Length > 1) - { - children2 = children2.FirstOrDefault(c => string.Equals(c.Name, path[0])).Children; - path = path.Skip(1).ToArray(); - if (path.Length == 1) - name = path[0]; - } - if (!pAttribute.IsArray && children2.FirstOrDefault(c => string.Equals(c.Name, name)) is DataTree child) - parameters.Add(child.Value); - else if (pAttribute.IsArray && children2.Where(c => string.Equals(c.Name, pAttribute.Name)).OfType() is IEnumerable childenum) - { - Type targetType = children2.First().Value.GetType(); - var array = Array.CreateInstance(targetType, children2.Length); - Array.Copy(children2.Select(c => c.Value).ToArray(), array, children2.Length); - parameters.Add(array); - } - else - throw new ArgumentException($"No matching Value found for '{pAttribute.Name}'"); + ConstructorInfo constructorCompound = constructorParameter.ParameterType.GetElementType().GetConstructors().FirstOrDefault(c => c.GetCustomAttribute() is DataTreeObjectConstructorAttribute); + DataTreeObjectConstructorAttribute cAttributeCompound = constructorCompound.GetCustomAttribute(); + var pAttributesCompound = constructorCompound.GetParameters().Select(p => p.GetCustomAttribute()).ToArray(); + value = getCompoundObject(compoundObjectArray, pAttributesCompound, constructorCompound); + parameters.Add(value); } - - var instance = constructor.Invoke(parameters.ToArray()); - return instance; + else + { + Logger?.LogInformation($"Can't find propperty for {parameterAttribute.Name}, Expected Type: {constructorParameter.ParameterType}, Actual Type: {value?.GetType()}"); + _break = true; + } + } } + if (!_break && cParameters.Count() == parameters.Count) + return constructor.Invoke(parameters.ToArray()); } + //If the Command is only a List with one compound object, the Path can be the root key + else if (flatDataTree.Count == 1 && + flatDataTree.TryGetValue(objectAttribute.Path, out object compoundObjects)) + if (compoundObjects is object[] compoundObjectArray) + return getCompoundObject(compoundObjectArray, pAttributes, constructor); + else if (compoundObjects is null) + return Array.CreateInstance(definedDataTreeObjectType, 0); + #endregion + static object getCompoundObject(object[] compoundObjectArray, DataTreeObjectParameterAttribute[] pAttributes, ConstructorInfo constructor) + { + List parameters = new List(); + List results = new List(); + foreach (IReadOnlyDictionary compoundDict in compoundObjectArray) + { + foreach (var parameterAttribute in pAttributes) + { + if (compoundDict.TryGetValue(parameterAttribute.Name, out object value)) + parameters.Add(value); + } + results.Add(constructor.Invoke(parameters.ToArray())); + parameters.Clear(); + } + Type targetType = results.First().GetType(); + var array = Array.CreateInstance(targetType, results.Count); + Array.Copy(results.ToArray(), array, results.Count); + return array; + } + #region Replaced by code above - keeping in case i need to revert + //if (!children.All(c => c.IsCompound)) + // return createObjectFromDataTree(objectAttribute, children); + //else + //{ + // var array = Array.CreateInstance(definedDataTreeObjectType, children.Length); + // foreach (var comp in children) + // array.SetValue(createObjectFromDataTree(objectAttribute, comp.Children), comp.Index); + // return array; + //} + + + //object createObjectFromDataTree(DataTreeObjectAttribute objectAttribute, DataTree[] children) + //{ + // var parameters = new List(); + // foreach (var param in constructor.GetParameters()) + // if (param.GetCustomAttribute() is DataTreeObjectParameterAttribute pAttribute) + // { + // var children2 = children; + + // string name = pAttribute.Name; + // string[] path = name.Split('/'); + // while (path.Length > 1) + // { + // children2 = children2.FirstOrDefault(c => string.Equals(c.Name, path[0])).Children; + // path = path.Skip(1).ToArray(); + // if (path.Length == 1) + // name = path[0]; + // } + // if (!pAttribute.IsArray && children2.FirstOrDefault(c => string.Equals(c.Name, name)) is DataTree child) + // parameters.Add(child.Value); + // else if (pAttribute.IsArray && children2.Where(c => string.Equals(c.Name, pAttribute.Name)).OfType() is IEnumerable childenum) + // { + // Type targetType = children2.First().Value.GetType(); + // var array = Array.CreateInstance(targetType, children2.Length); + // Array.Copy(children2.Select(c => c.Value).ToArray(), array, children2.Length); + // parameters.Add(array); + // } + // else + // throw new ArgumentException($"No matching Value found for '{pAttribute.Name}'"); + // } + + // var instance = constructor.Invoke(parameters.ToArray()); + // return instance; + //} + #endregion } } + } - if (Children.Length == 1) - { - DataTree dataTree = Children[0]; - - if (dataTree.Value != null) - return dataTree.Value; + #region Replaced by code above - keeping in case i need to revert + if (Children.Length == 1) + { + var flatDataTree = flateningDateTree(Children); + DataTree dataTree = Children[0]; - if (dataTree.Children.GroupBy(c => c.Name).Count() == 1) - { - var list = dataTree.Children.Select(c => c.Value).ToList(); - Type targetType = list.First().GetType(); - var array = Array.CreateInstance(targetType, list.Count); - Array.Copy(list.ToArray(), array, list.Count); - //for (int i = 0; i < list.Count; i++) - // array.SetValue(Convert.ChangeType(list[i], targetType), i); + if (flatDataTree.Count == 1 && flatDataTree.Values.FirstOrDefault() is object value) + return value; - return array; - } + if (dataTree.Children.GroupBy(c => c.Name).Count() == 1) + { + var list = dataTree.Children.Select(c => c.Value).ToList(); + Type targetType = list.First().GetType(); + var array = Array.CreateInstance(targetType, list.Count); + Array.Copy(list.ToArray(), array, list.Count); + //for (int i = 0; i < list.Count; i++) + // array.SetValue(Convert.ChangeType(list[i], targetType), i); + + return array; } } - catch (Exception e) - { - Logger?.LogError(e); + #endregion + } + catch (Exception e) + { + Logger?.LogError(e); #pragma warning disable CA2200 - throw e; + throw e; #pragma warning restore CA2200 - } - - throw new NotImplementedException(); } - - public static DataTreeBranch FromObject(object obj, object key, ParameterBag parameterBag, ERDM_Command command) + throw new NotImplementedException(); + } + private Dictionary flateningDateTree(DataTree[] children) + { + Dictionary result = new Dictionary(); + foreach (var child in children) { - var result = FromObject(obj, key, command, parameterBag.PID); - if (result.IsUnset) + if (child.Value != null) + result.TryAdd(child.Name, child.Value); + else if (child.Children?.Length == 0) + result.TryAdd(child.Name, null); + else if (child.Children != null) { - var define = MetadataFactory.GetDefine(parameterBag); - if (define == null) - return result; - Command? cmd = null; - switch (command) + if (child.IsCompound) + result.TryAdd(child.Name, flateningDateTree(child.Children)); + else if (child.IsList) { - case ERDM_Command.GET_COMMAND: - if (define.GetRequest.HasValue) - cmd = define.GetRequest; - break; - case ERDM_Command.GET_COMMAND_RESPONSE: - if (define.GetResponse.HasValue) - cmd = define.GetResponse; - break; - case ERDM_Command.SET_COMMAND: - if (define.SetRequest.HasValue) - cmd = define.SetRequest; - break; - case ERDM_Command.SET_COMMAND_RESPONSE: - if (define.SetResponse.HasValue) - cmd = define.SetResponse; - break; + List list = new List(); + foreach (var grandChild in child.Children) + { + if (grandChild.Value != null) + list.Add(grandChild.Value); + else if (grandChild.Children != null) + list.Add(flateningDateTree(grandChild.Children)); + } + Type targetType = list.First().GetType(); + var array = Array.CreateInstance(targetType, list.Count); + Array.Copy(list.ToArray(), array, list.Count); + result.Add(child.Name, array); } - if (!cmd.HasValue) - return result; - List children = new List(); - - switch (cmd.Value.EnumValue) + else //Is BitField { - case Command.ECommandDublicate.GetRequest: + foreach (var grandChild in child.Children) + { + if (grandChild.Value != null) + result.TryAdd(string.Join('/', child.Name, grandChild.Name), grandChild.Value); + } + } + } + } + return result; + } + + public static DataTreeBranch FromObject(object obj, object key, ParameterBag parameterBag, ERDM_Command command) + { + var result = FromObject(obj, key, command, parameterBag.PID); + if (result.IsUnset) + { + var define = MetadataFactory.GetDefine(parameterBag); + if (define == null) + return result; + Command? cmd = null; + switch (command) + { + case ERDM_Command.GET_COMMAND: + if (define.GetRequest.HasValue) cmd = define.GetRequest; - break; - case Command.ECommandDublicate.GetResponse: + break; + case ERDM_Command.GET_COMMAND_RESPONSE: + if (define.GetResponse.HasValue) cmd = define.GetResponse; - break; - case Command.ECommandDublicate.SetRequest: + break; + case ERDM_Command.SET_COMMAND: + if (define.SetRequest.HasValue) cmd = define.SetRequest; - break; - case Command.ECommandDublicate.SetResponse: + break; + case ERDM_Command.SET_COMMAND_RESPONSE: + if (define.SetResponse.HasValue) cmd = define.SetResponse; - break; - } - if (cmd.Value.SingleField.HasValue) - children.Add(getChildren(cmd.Value.SingleField.Value, obj)); - if ((cmd.Value.ListOfFields?.Length ?? 0) > 0) - { - if (cmd.Value.ListOfFields.Length > 1) - throw new NotImplementedException(); + break; + } + if (!cmd.HasValue) + return result; + List children = new List(); + + switch (cmd.Value.EnumValue) + { + case Command.ECommandDublicate.GetRequest: + cmd = define.GetRequest; + break; + case Command.ECommandDublicate.GetResponse: + cmd = define.GetResponse; + break; + case Command.ECommandDublicate.SetRequest: + cmd = define.SetRequest; + break; + case Command.ECommandDublicate.SetResponse: + cmd = define.SetResponse; + break; + } + if (cmd.Value.SingleField.HasValue) + children.Add(getChildren(cmd.Value.SingleField.Value, obj)); + if ((cmd.Value.ListOfFields?.Length ?? 0) > 0) + { + if (cmd.Value.ListOfFields.Length > 1) + throw new NotImplementedException(); - children.Add(getChildren(cmd.Value.ListOfFields[0], obj)); + children.Add(getChildren(cmd.Value.ListOfFields[0], obj)); - } - DataTree getChildren(OneOfTypes oneOf, object o) - { - var oneofOt = oneOf.ObjectType; - if (oneofOt == null && oneOf.ReferenceType.HasValue) - oneofOt = oneOf.ReferenceType.Value.ReferencedObject; + } + DataTree getChildren(OneOfTypes oneOf, object o) + { + var oneofOt = oneOf.ObjectType; + if (oneofOt == null && oneOf.ReferenceType.HasValue) + oneofOt = oneOf.ReferenceType.Value.ReferencedObject; - if (oneofOt != null) - return new DataTree(oneofOt.Name, 0, o); + if (oneofOt != null) + return new DataTree(oneofOt.Name, 0, o); - throw new NotImplementedException(); - } - if (children.Count != 0) - return new DataTreeBranch(obj, children: children.ToArray()); - if (cmd.Value.GetIsEmpty()) - return DataTreeBranch.Empty; + throw new NotImplementedException(); } - return result; + if (children.Count != 0) + return new DataTreeBranch(obj, children: children.ToArray()); + if (cmd.Value.GetIsEmpty()) + return DataTreeBranch.Empty; } + return result; + } - public static DataTreeBranch FromObject(object obj, object key, ERDM_Command command, ERDM_Parameter parameter) - { - if (obj == null) - return DataTreeBranch.Empty; + internal static DataTreeBranch FromObject(object obj, object key, ERDM_Command command, ERDM_Parameter parameter) + { + if (obj == null) + return DataTreeBranch.Empty; - Type type = obj.GetType(); + Type type = obj.GetType(); - if (type.IsGenericType && typeof(IDictionary).IsAssignableFrom(type.GetGenericTypeDefinition())) + if (type.IsGenericType && typeof(IDictionary).IsAssignableFrom(type.GetGenericTypeDefinition())) + { + Type[] genericArguments = type.GetGenericArguments(); + Type keyType = genericArguments[0]; + Type valueType = genericArguments[1]; + + var tryGetValueMethod = type.GetMethod("TryGetValue"); + object[] parameters = { key, null }; + bool found = false; + try { - Type[] genericArguments = type.GetGenericArguments(); - Type keyType = genericArguments[0]; - Type valueType = genericArguments[1]; - - var tryGetValueMethod = type.GetMethod("TryGetValue"); - object[] parameters = { key, null }; - bool found = false; - try - { - found = (bool)tryGetValueMethod.Invoke(obj, parameters); - } - catch(Exception e) - { - Logger?.LogError(e); - } + found = (bool)tryGetValueMethod.Invoke(obj, parameters); + } + catch (Exception e) + { + Logger?.LogError(e); + } - if (found) - { - // Der Wert wird im zweiten Parameter (Index 1) gespeichert - object value = parameters[1]; - obj = value; - type = value.GetType(); - } + if (found) + { + // Der Wert wird im zweiten Parameter (Index 1) gespeichert + object value = parameters[1]; + obj = value; + type = value.GetType(); } + } - bool isArray = type.IsArray; + bool isArray = type.IsArray; - if (isArray) - type = type.GetElementType(); + if (isArray) + type = type.GetElementType(); - if (type.GetCustomAttributes().FirstOrDefault(a => a.Parameter == parameter && a.Command == Tools.ConvertCommandDublicateToCommand(command) && a.IsArray == isArray) is not DataTreeObjectAttribute dataTreeObjectAttribute) - return DataTreeBranch.Unset; + var dataTreeObjectAttributes = type.GetCustomAttributes(); + if (dataTreeObjectAttributes.FirstOrDefault(a => a.Parameter == parameter && a.Command == Tools.ConvertCommandDublicateToCommand(command)) is not DataTreeObjectAttribute dataTreeObjectAttribute) + return DataTreeBranch.Unset; - List children = new List(); - bool isCompound = false; - if (!type.IsEnum) - { - var properties = type.GetProperties().Where(p => p.GetCustomAttributes().Count() != 0).ToArray(); - isCompound = properties.Length > 1; - if (isArray) - { - Array array = (Array)obj; - for (uint i = 0; i < array.Length; i++) - children.Add(new DataTree(null, i, convertToDataTree(array.GetValue(i), properties, parameter), isCompound: isCompound)); - } - else - children.AddRange(convertToDataTree(obj, properties, parameter)); + List children = new List(); + bool isCompound = false; + if (!type.IsEnum) + { + var properties = type.GetProperties().Where(p => p.GetCustomAttributes().Count() != 0).ToArray(); + isCompound = properties.Length > 1; + + if (isArray) + { + Array array = (Array)obj; + for (uint i = 0; i < array.Length; i++) + children.Add(new DataTree(null, i, convertToDataTree(array.GetValue(i), properties, parameter), isCompound: isCompound)); } else + children.AddRange(convertToDataTree(obj, properties, parameter)); + } + else + { + DataTreeEnumAttribute enumAttribute = dataTreeObjectAttribute as DataTreeEnumAttribute; + if (isArray) { - DataTreeEnumAttribute enumAttribute = dataTreeObjectAttribute as DataTreeEnumAttribute; - if (isArray) - { - Array array = (Array)obj; - for (uint i = 0; i < array.Length; i++) - children.Add(new DataTree(enumAttribute.Name, i, getUnderlyingValue(array.GetValue(i)))); - } - else - children.Add(new DataTree(enumAttribute.Name, 0, getUnderlyingValue(obj))); + Array array = (Array)obj; + for (uint i = 0; i < array.Length; i++) + children.Add(new DataTree(enumAttribute.Name, i, getUnderlyingValue(array.GetValue(i)))); } + else + children.Add(new DataTree(enumAttribute.Name, 0, getUnderlyingValue(obj))); + } - if (!string.IsNullOrWhiteSpace(dataTreeObjectAttribute.Path)) + if (!string.IsNullOrWhiteSpace(dataTreeObjectAttribute.Path)) + { + string[] path = dataTreeObjectAttribute.Path.Split('/'); + DataTree? route = null; + for (int i = path.Length; i != 0; i--) { - string[] path = dataTreeObjectAttribute.Path.Split('/'); - DataTree? route = null; - for (int i = path.Length; i != 0; i--) - { - if (route.HasValue) - route = new DataTree(path[i - 1], 0, route); - else - route = new DataTree(path[i - 1], 0, children.ToArray()); - } - - return new DataTreeBranch(obj, route.Value); + if (route.HasValue) + route = new DataTree(path[i - 1], 0, route); + else + route = new DataTree(path[i - 1], 0, children.ToArray()); } - return new DataTreeBranch(obj, children.ToArray()); + return new DataTreeBranch(obj, route.Value); + } + + return new DataTreeBranch(obj, children.ToArray()); - static DataTree[] convertToDataTree(object value, PropertyInfo[] properties, ERDM_Parameter parameter) + static DataTree[] convertToDataTree(object value, PropertyInfo[] properties, ERDM_Parameter parameter) + { + List innerChildren = new List(); + Dictionary> deeperChildren = new Dictionary>(); + foreach (var property in properties) { - List innerChildren = new List(); - Dictionary> deeperChildren = new Dictionary>(); - foreach (var property in properties) - { - var attributes = property.GetCustomAttributes(); - DataTreeObjectPropertyAttribute attribute = attributes.FirstOrDefault(); - if (attributes.Count() != 1) - attribute = attributes.FirstOrDefault(a => a.Parameter == parameter); + var attributes = property.GetCustomAttributes(); + DataTreeObjectPropertyAttribute attribute = attributes.FirstOrDefault(); + if (attributes.Count() != 1) + attribute = attributes.FirstOrDefault(a => a.Parameter == parameter); - if (attribute != null) + if (attribute != null) + { + var val = property.GetValue(value); + if (val is Enum) + val = getUnderlyingValue(val); + if (attribute.Name.Contains("/")) { - var val = property.GetValue(value); - if (val is Enum) - val = getUnderlyingValue(val); - if (attribute.Name.Contains("/")) + string[] path = attribute.Name.Split('/'); + if (!val.GetType().IsArray) { - string[] path = attribute.Name.Split('/'); if (!deeperChildren.TryGetValue(path[0], out List ddc)) { ddc = new List(); @@ -380,81 +519,114 @@ static DataTree[] convertToDataTree(object value, PropertyInfo[] properties, ERD ddc.Add(new DataTree(path[1], attribute.Index, val)); } else - innerChildren.Add(new DataTree(attribute.Name, attribute.Index, val)); + { + List _children = new List(); + uint _index = 0; + foreach (var cv in (Array)val) + { + string _name = path[1]; + if (string.IsNullOrWhiteSpace(_name)) + _name = null; + if (!cv.GetType().GetConstructors().Any(c => c.GetCustomAttribute() is not null)) + _children.Add(new DataTree(_name, _index, cv)); + else + { + var _props = cv.GetType().GetProperties().Where(p => p.GetCustomAttributes() is not null); + _children.Add(new DataTree(_name, _index, convertToDataTree(cv, _props.ToArray(), parameter))); + } + _index++; + } + + innerChildren.Add(new DataTree(path[0], attribute.Index, _children.ToArray())); + } } + else + innerChildren.Add(new DataTree(attribute.Name, attribute.Index, val ?? attribute.NullValue)); } - foreach (var dC in deeperChildren) - { - var index = FindMissingNumbers(innerChildren.Select(ic => (int)ic.Index)).FirstOrDefault(); - innerChildren.Add(new DataTree(dC.Key, (uint)index, children: dC.Value.OrderBy(c => c.Index).ToArray())); - } - return innerChildren.OrderBy(iC => iC.Index).ToArray(); - - static IEnumerable FindMissingNumbers(IEnumerable numbers) - { - // Liste sortieren - var sortedNumbers = numbers.OrderBy(n => n).ToList(); + } + foreach (var dC in deeperChildren) + { + var index = FindMissingNumbers(innerChildren.Select(ic => (int)ic.Index)).FirstOrDefault(); + innerChildren.Add(new DataTree(dC.Key, (uint)index, children: dC.Value.OrderBy(c => c.Index).ToArray())); + } + return innerChildren.OrderBy(iC => iC.Index).ToArray(); - // Bereich (Range) bestimmen - int min = sortedNumbers.First(); - int max = sortedNumbers.Last(); + static IEnumerable FindMissingNumbers(IEnumerable numbers) + { + // Liste sortieren + var sortedNumbers = numbers.OrderBy(n => n).ToList(); - // Alle erwarteten Zahlen im Bereich erstellen - var fullRange = Enumerable.Range(min, max - min + 1); + // Bereich (Range) bestimmen + int min = sortedNumbers.First(); + int max = sortedNumbers.Last(); - // Fehlende Zahlen durch Differenz finden - return fullRange.Except(sortedNumbers); - } - } - static object getUnderlyingValue(object enumValue) - { - // Ermitteln des zugrunde liegenden Typs - Type underlyingType = Enum.GetUnderlyingType(enumValue.GetType()); + // Alle erwarteten Zahlen im Bereich erstellen + var fullRange = Enumerable.Range(min, max - min + 1); - // Konvertierung des Enum-Werts in den zugrunde liegenden Typ - return Convert.ChangeType(enumValue, underlyingType); + // Fehlende Zahlen durch Differenz finden + return fullRange.Except(sortedNumbers); } } - - public override bool Equals(object obj) + static object getUnderlyingValue(object enumValue) { - return obj is DataTreeBranch branch && Equals(branch); + // Ermitteln des zugrunde liegenden Typs + Type underlyingType = Enum.GetUnderlyingType(enumValue.GetType()); + + // Konvertierung des Enum-Werts in den zugrunde liegenden Typ + return Convert.ChangeType(enumValue, underlyingType); } + } - public bool Equals(DataTreeBranch other) - { - if ((this.Children is null) && (other.Children is null)) - return true; + public override bool Equals(object obj) + { + return obj is DataTreeBranch branch && Equals(branch); + } - if ((this.Children is null) || (other.Children is null)) - return false; + public bool Equals(DataTreeBranch other) + { + if (this.IsUnset != other.IsUnset || this.IsEmpty != other.IsEmpty) + return false; - for (int i = 0; i < Children.Length; i++) - { - DataTree me = Children[i]; - if ((other.Children?.Length ?? 0) <= i) - return false; - DataTree ot = other.Children[i]; - if (!me.Equals(ot)) - return false; - } + if ((this.Children is null) && (other.Children is null)) return true; - // return EqualityComparer.Default.Equals(Children, other.Children); // is not dooing its job - } - public override int GetHashCode() - { - return HashCode.Combine(Children); - } + if ((this.Children is null) || (other.Children is null)) + return false; - public static bool operator ==(DataTreeBranch left, DataTreeBranch right) + for (int i = 0; i < Children.Length; i++) { - return left.Equals(right); + DataTree me = Children[i]; + if ((other.Children?.Length ?? 0) <= i) + return false; + DataTree ot = other.Children[i]; + if (!me.Equals(ot)) + return false; } + return true; + // return EqualityComparer.Default.Equals(Children, other.Children); // is not dooing its job + } + + public override int GetHashCode() + { + return HashCode.Combine(Children); + } + + public static bool operator ==(DataTreeBranch left, DataTreeBranch right) + { + return left.Equals(right); + } + + public static bool operator !=(DataTreeBranch left, DataTreeBranch right) + { + return !(left == right); + } - public static bool operator !=(DataTreeBranch left, DataTreeBranch right) + public override string ToString() + { + if (Children is not null) { - return !(left == right); + return "DTB:" + Environment.NewLine + String.Join(Environment.NewLine, Children.Select(c => $"{c.Name} = {c.Value}")); } + return base.ToString(); } } \ No newline at end of file diff --git a/RDMSharp/Metadata/DataTreeObjectAttribute.cs b/RDMSharp/Metadata/DataTreeObjectAttribute.cs index 892bbd1d..e207f548 100644 --- a/RDMSharp/Metadata/DataTreeObjectAttribute.cs +++ b/RDMSharp/Metadata/DataTreeObjectAttribute.cs @@ -13,7 +13,7 @@ public class DataTreeObjectAttribute : Attribute public readonly bool IsArray; public readonly string Path; - public DataTreeObjectAttribute(ERDM_Parameter parameter, Command.ECommandDublicate command, bool isArray = false, string path = null) + internal DataTreeObjectAttribute(ERDM_Parameter parameter, Command.ECommandDublicate command, bool isArray = false, string path = null) { Parameter = parameter; Command = command; @@ -23,6 +23,8 @@ public DataTreeObjectAttribute(ERDM_Parameter parameter, Command.ECommandDublica public DataTreeObjectAttribute(EManufacturer manufacturer, ERDM_Parameter parameter, Command.ECommandDublicate command, bool isArray = false, string path = null) : this(parameter, command, isArray, path) { + if (manufacturer == EManufacturer.ESTA) + throw new NotSupportedException(); Manufacturer = manufacturer; } } diff --git a/RDMSharp/Metadata/DataTreeObjectParameterAttribute.cs b/RDMSharp/Metadata/DataTreeObjectParameterAttribute.cs index 972a01c8..f056d466 100644 --- a/RDMSharp/Metadata/DataTreeObjectParameterAttribute.cs +++ b/RDMSharp/Metadata/DataTreeObjectParameterAttribute.cs @@ -19,6 +19,10 @@ public DataTreeObjectParameterAttribute(ERDM_Parameter parameter, string name) : { Parameter = parameter; } + public DataTreeObjectParameterAttribute(ERDM_Parameter parameter, string name, bool isArray) : this(parameter, name) + { + IsArray = isArray; + } public override string ToString() { return $"{Parameter} -> {Name}"; diff --git a/RDMSharp/Metadata/DataTreeObjectPropertyAttribute.cs b/RDMSharp/Metadata/DataTreeObjectPropertyAttribute.cs index 25ec16a9..7eff0651 100644 --- a/RDMSharp/Metadata/DataTreeObjectPropertyAttribute.cs +++ b/RDMSharp/Metadata/DataTreeObjectPropertyAttribute.cs @@ -7,15 +7,17 @@ public class DataTreeObjectPropertyAttribute : Attribute { public readonly string Name; public readonly uint Index; + public readonly object NullValue; public readonly ERDM_Parameter? Parameter; - public DataTreeObjectPropertyAttribute(string name, uint index) + public DataTreeObjectPropertyAttribute(string name, uint index, object nullValue = null) { Name = name; Index = index; + NullValue = nullValue; } - public DataTreeObjectPropertyAttribute(ERDM_Parameter parameter, string name, uint index) : this(name, index) + public DataTreeObjectPropertyAttribute(ERDM_Parameter parameter, string name, uint index, object nullValue = null) : this(name, index, nullValue) { Parameter = parameter; } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs index be4253de..a39ada1c 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs @@ -5,347 +5,221 @@ using System.Text; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.JSON.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes; + +public class BytesType : CommonPropertiesForNamed { - public class BytesType : CommonPropertiesForNamed + [JsonPropertyName("name")] + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[] Resources { get; } + + [JsonPropertyName("type")] + [JsonPropertyOrder(3)] + public string Type { get; } + [JsonPropertyName("format")] + [JsonPropertyOrder(11)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string Format { get; } + [JsonPropertyName("minLength")] + [JsonPropertyOrder(12)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public uint? MinLength { get; } + [JsonPropertyName("maxLength")] + [JsonPropertyOrder(13)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public uint? MaxLength { get; } + + private readonly bool formatIsArray; + private readonly string baseFormat; + + + [JsonConstructor] + public BytesType(string name, + string displayName, + string notes, + string[] resources, + string type, + string format, + uint? minLength, + uint? maxLength) : base() { - [JsonPropertyName("name")] - [JsonPropertyOrder(1)] - [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - public override string Name { get; } - [JsonPropertyName("displayName")] - [JsonPropertyOrder(2)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string DisplayName { get; } - [JsonPropertyName("notes")] - [JsonPropertyOrder(4)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string Notes { get; } - [JsonPropertyName("resources")] - [JsonPropertyOrder(5)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[] Resources { get; } - - [JsonPropertyName("type")] - [JsonPropertyOrder(3)] - public string Type { get; } - [JsonPropertyName("format")] - [JsonPropertyOrder(11)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string Format { get; } - [JsonPropertyName("minLength")] - [JsonPropertyOrder(12)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public uint? MinLength { get; } - [JsonPropertyName("maxLength")] - [JsonPropertyOrder(13)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public uint? MaxLength { get; } + if (!"bytes".Equals(type)) + throw new ArgumentException($"Argument {nameof(type)} has to be \"bytes\""); + if (minLength.HasValue && maxLength.HasValue) + if (minLength > maxLength) + throw new ArgumentOutOfRangeException($"Argument {nameof(minLength)} has to be <= {nameof(maxLength)}"); + if (minLength.HasValue) + if (minLength > PDL.MAX_LENGTH) + throw new ArgumentOutOfRangeException($"Argument {nameof(minLength)} has to be <= {PDL.MAX_LENGTH}"); + if (maxLength.HasValue) + if (maxLength > PDL.MAX_LENGTH) + throw new ArgumentOutOfRangeException($"Argument {nameof(maxLength)} has to be <= {PDL.MAX_LENGTH}"); + + Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; + Type = type; + Format = format; + MinLength = minLength; + MaxLength = maxLength; + + formatIsArray = Format?.EndsWith("[]") ?? false; + if (formatIsArray) + baseFormat = Format.Replace("[]", ""); + else + baseFormat = Format; + } + public override string ToString() + { + return Name; + } - [JsonConstructor] - public BytesType(string name, - string displayName, - string notes, - string[] resources, - string type, - string format, - uint? minLength, - uint? maxLength) : base() + public override PDL GetDataLength() + { + uint length = 0; + bool noFixedSize = false; + if (Extensions.ExtensionsManager.Instance.TryGetBytesParser(baseFormat, out Extensions.IBytesParser bytesParser)) { - if (!"bytes".Equals(type)) - throw new ArgumentException($"Argument {nameof(type)} has to be \"bytes\""); - if (minLength.HasValue && maxLength.HasValue) - if (minLength > maxLength) - throw new ArgumentOutOfRangeException($"Argument {nameof(minLength)} has to be <= {nameof(maxLength)}"); - if (minLength.HasValue) - if (minLength > PDL.MAX_LENGTH) - throw new ArgumentOutOfRangeException($"Argument {nameof(minLength)} has to be <= {PDL.MAX_LENGTH}"); - if (maxLength.HasValue) - if (maxLength > PDL.MAX_LENGTH) - throw new ArgumentOutOfRangeException($"Argument {nameof(maxLength)} has to be <= {PDL.MAX_LENGTH}"); + if (!bytesParser.PayloadDataLength.HasValue) + { + noFixedSize = true; + goto END; + } + var pdl = bytesParser.PayloadDataLength.Value; - Name = name; - DisplayName = displayName; - Notes = notes; - Resources = resources; - Type = type; - Format = format; - MinLength = minLength; - MaxLength = maxLength; + if (pdl.Value.HasValue && formatIsArray) + { + length = pdl.Value.Value; + goto END; + } + return pdl; } + noFixedSize = true; + END: + if (formatIsArray && length != 0) + return new PDL(0, (uint)(Math.Truncate((double)PDL.MAX_LENGTH / length) * length)); - public override string ToString() - { - return Name; - } + return new PDL((uint)(MinLength ?? 1), (uint)(MaxLength ?? PDL.MAX_LENGTH)); + } + public override IEnumerable ParsePayloadToData(DataTree dataTree) + { + if (!string.Equals(dataTree.Name, this.Name)) + throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); - public override PDL GetDataLength() + if (formatIsArray && dataTree.Value is Array typedArray) { - uint length = 0; - string format = Format; - bool noFixedSize = false; - if (!string.IsNullOrWhiteSpace(Format) && Format.EndsWith("[]")) - format = Format.Replace("[]", ""); - switch (format) + List bytes = new List(); + for (int i = 0; i < typedArray.Length; i++) { - case "mac-address": - case "uid": - length = 6; - break; - case "ipv4": - case "float": - length = 4; - break; - case "ipv6": - case "uuid": - case "guid": - length = 16; - break; - case "double": - length = 8; - break; - case "pid": - length = 2; - break; - default: - noFixedSize = true; - break; + object value = typedArray.GetValue(i); + bytes.AddRange(parseData(baseFormat, value)); + if (value is string) + bytes.Add(0); //Null-Delimiter } - if (!string.IsNullOrWhiteSpace(Format) && Format.EndsWith("[]")) - return new PDL(0, (uint)(Math.Truncate((double)PDL.MAX_LENGTH / length) * length)); - else if (!noFixedSize) - return new PDL(length); - - return new PDL((uint)(MinLength ?? 1), (uint)(MaxLength ?? PDL.MAX_LENGTH)); + return Tools.EncaseData(bytes.ToArray()); } - public override IEnumerable ParsePayloadToData(DataTree dataTree) - { - if (!string.Equals(dataTree.Name, this.Name)) - throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + else + return Tools.EncaseData(parseData(baseFormat, dataTree.Value)); - if (!string.IsNullOrWhiteSpace(Format) && Format.EndsWith("[]") && dataTree.Value is Array typedArray) + byte[] parseData(string format, object value) + { + Exception e = null; + try { - List bytes = new List(); - string format = Format.Replace("[]", ""); - for (int i = 0; i < typedArray.Length; i++) - { - object value = typedArray.GetValue(i); - bytes.AddRange(parseData(format, value)); - if (value is string) - bytes.Add(0); //Null-Delimiter - } - return Tools.EncaseData(bytes.ToArray()); - } - else - return Tools.EncaseData(parseData(Format, dataTree.Value)); + if (Extensions.ExtensionsManager.Instance.TryGetBytesParser(format, out Extensions.IBytesParser bytesParser)) + return bytesParser.ParseToData(value); - byte[] parseData(string format, object value) - { - Exception e = null; - try + if (value is string str) + return Encoding.ASCII.GetBytes(str); + if (value is IReadOnlyCollection strings) { - switch (format) + List bytes = new List(); + foreach (string _str in strings) { - //Known from E1.37-5 (2024) - case "uid" when value is UID uid: - return uid.ToBytes().ToArray(); - case "ipv4" when value is IPv4Address ipv4: - return (byte[])ipv4; - case "ipv6" when value is IPv6Address ipv6: - return (byte[])ipv6; - case "mac-address" when value is MACAddress macAddress: - return (byte[])macAddress; - - //Known from E1.37-5 (2024) as uuid - case "uuid" when value is Guid uuid: - return uuid.ToByteArray(); - case "guid" when value is Guid guid: - return guid.ToByteArray(); - - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "pid" when value is ERDM_Parameter pid: - return Tools.ValueToData(pid); - - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "double" when value is double _double: - return BitConverter.GetBytes(_double); - case "float" when value is float _float: - return BitConverter.GetBytes(_float); - - - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "ascii" when value is string ascii: - return Encoding.ASCII.GetBytes(ascii); - case "utf8" when value is string utf8: - return Encoding.UTF8.GetBytes(utf8); - case "utf32" when value is string utf32: - return Encoding.UTF32.GetBytes(utf32); - case "unicode" when value is string unicode: - return Encoding.Unicode.GetBytes(unicode); - case "big_edian_unicode" when value is string big_edian_unicode: - return Encoding.BigEndianUnicode.GetBytes(big_edian_unicode); - case "latin1" when value is string latin1: - return Encoding.Latin1.GetBytes(latin1); - - //Fallback - default: - if (value is string str) - return Encoding.UTF8.GetBytes(str); - if (value is byte[] byteArray) - return byteArray; - throw new NotImplementedException($"There is no implementation for {nameof(Format)}: {Format} and Value: {value}"); + bytes.AddRange(Encoding.ASCII.GetBytes(_str)); + bytes.Add(0x00); } + return bytes.ToArray(); } - catch (Exception ex) - { - e = ex; - } - throw new ArithmeticException($"The given Object of {nameof(Format)}: \"{Format}\" can't be parsed from {nameof(value)}: {value}", e); + if (value is byte[] byteArray) + return byteArray; + throw new NotImplementedException($"There is no implementation for {nameof(format)}: {format} and Value: {value}"); + } + catch (Exception ex) + { + e = ex; } + throw new ArithmeticException($"The given Object of {nameof(format)}: \"{format}\" can't be parsed from {nameof(value)}: {value}", e); } - public override DataTree ParseDataToPayload(ref byte[] data) + } + public override DataTree ParseDataToPayload(ref byte[] data) + { + List issueList = new List(); + object value = null; + if (formatIsArray) { - List issueList = new List(); - object value = null; - if (!string.IsNullOrWhiteSpace(Format) && Format.EndsWith("[]")) + List list = new List(); + while (data.Length > 0) { - List list = new List(); - while (data.Length > 0) + try { - try - { - string format = Format.Replace("[]", ""); - list.Add(parseData(format, ref data)); - } - catch (Exception e) - { - issueList.Add(new DataTreeIssue(e.Message)); - break; - } + list.Add(parseData(baseFormat, ref data)); } - if (data.Length > 0) - issueList.Add(new DataTreeIssue("Data Length is not 0")); - - if (list.Count == 0) - value = null; - else + catch (Exception e) { - Type targetType = list.First().GetType(); - var array = Array.CreateInstance(targetType, list.Count); - for (int i = 0; i < list.Count; i++) - array.SetValue(Convert.ChangeType(list[i], targetType), i); - - value = array; + issueList.Add(new DataTreeIssue(e.Message)); + break; } } - else - value = parseData(Format, ref data); + if (data.Length > 0) + issueList.Add(new DataTreeIssue("Data Length is not 0")); - - return new DataTree(this.Name, 0, value, issueList.Count != 0 ? issueList.ToArray() : null); - - object parseData(string format, ref byte[] data) + if (list.Count == 0) + value = null; + else { - void validateDataLength(int length, ref byte[] data) - { - if (data.Length < length) - throw new ArithmeticException("Data to short"); - } - object value = null; - switch (format) - { - //Known from E1.37-5 (2024) - case "uid": - validateDataLength(6, ref data); - value = new UID(Tools.DataToUShort(ref data), Tools.DataToUInt(ref data)); - break; - case "ipv4": - validateDataLength(4, ref data); - value = new IPv4Address(data.Take(4)); - data = data.Skip(4).ToArray(); - break; - case "ipv6": - validateDataLength(16, ref data); - value = new IPv6Address(data.Take(16)); - data = data.Skip(16).ToArray(); - break; - case "mac-address": - validateDataLength(6, ref data); - value = new MACAddress(data.Take(6)); - data = data.Skip(6).ToArray(); - break; - - //Known from E1.37-5 (2024) as uuid - case "uuid": - case "guid": - validateDataLength(16, ref data); - value = new Guid(data.Take(16).ToArray()); - data = data.Skip(16).ToArray(); - break; + Type targetType = list.First().GetType(); + var array = Array.CreateInstance(targetType, list.Count); + for (int i = 0; i < list.Count; i++) + array.SetValue(Convert.ChangeType(list[i], targetType), i); - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "pid": - validateDataLength(2, ref data); - value = Tools.DataToEnum(ref data); - break; + value = array; + } + } + else + value = parseData(baseFormat, ref data); - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "double": - validateDataLength(8, ref data); - value = BitConverter.ToDouble(data.Take(8).ToArray(), 0); - data = data.Skip(8).ToArray(); - break; - case "float": - validateDataLength(4, ref data); - value = BitConverter.ToSingle(data.Take(4).ToArray(), 0); - data = data.Skip(4).ToArray(); - break; + return new DataTree(this.Name, 0, value, issueList.Count != 0 ? issueList.ToArray() : null); - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "ascii": - value = getNullDelimitetData(Encoding.ASCII, ref data); - break; - case "utf8": - value = getNullDelimitetData(Encoding.UTF8, ref data); - break; - case "utf32": - value = getNullDelimitetData(Encoding.UTF32, ref data); - break; - case "unicode": - value = getNullDelimitetData(Encoding.Unicode, ref data); - break; - case "big_edian_unicode": - value = getNullDelimitetData(Encoding.BigEndianUnicode, ref data); - break; - case "latin1": - value = getNullDelimitetData(Encoding.Latin1, ref data); - break; + object parseData(string format, ref byte[] data) + { + if ("string".Equals(format)) //Todo make this dependant on ControllerFlags + format = "ascii"; - //Fallback - default: - value = data; - data = data.Skip(data.Length).ToArray(); - issueList.Add(new DataTreeIssue($"No Parser found for {nameof(Format)}: \"{Format}\"")); - break; - } - return value; + if (Extensions.ExtensionsManager.Instance.TryGetBytesParser(format, out Extensions.IBytesParser bytesParser)) + return bytesParser.ParseToObject(ref data); - string getNullDelimitetData(Encoding encoding, ref byte[] data) - { - string res = encoding.GetString(data); - if (res.Contains('\0')) - { - res = res.Split('\0')[0]; - int count = encoding.GetByteCount(res + "\0"); - data = data.Skip(count).ToArray(); - } - else - data = new byte[0]; - return res; - } - } + object value = null; + value = data; + data = data.Skip(data.Length).ToArray(); + issueList.Add(new DataTreeIssue($"No Parser found for {nameof(format)}: \"{format}\"")); + return value; } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs index 12915bfb..9501cd45 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs @@ -7,114 +7,113 @@ [assembly: InternalsVisibleTo("RDMSharpTests")] -namespace RDMSharp.Metadata.JSON.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes; + +public class CompoundType : CommonPropertiesForNamed { - public class CompoundType : CommonPropertiesForNamed + [JsonPropertyName("name")] + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[] Resources { get; } + + [JsonPropertyName("type")] + [JsonPropertyOrder(3)] + public string Type { get; } + [JsonPropertyName("subtypes")] + [JsonPropertyOrder(11)] + public OneOfTypes[] Subtypes { get; } + + + [JsonConstructor] + public CompoundType(string name, + string displayName, + string notes, + string[] resources, + string type, + OneOfTypes[] subtypes) { - [JsonPropertyName("name")] - [JsonPropertyOrder(1)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string Name { get; } - [JsonPropertyName("displayName")] - [JsonPropertyOrder(2)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string DisplayName { get; } - [JsonPropertyName("notes")] - [JsonPropertyOrder(4)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string Notes { get; } - [JsonPropertyName("resources")] - [JsonPropertyOrder(5)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[] Resources { get; } - - [JsonPropertyName("type")] - [JsonPropertyOrder(3)] - public string Type { get; } - [JsonPropertyName("subtypes")] - [JsonPropertyOrder(11)] - public OneOfTypes[] Subtypes { get; } - - - [JsonConstructor] - public CompoundType(string name, - string displayName, - string notes, - string[] resources, - string type, - OneOfTypes[] subtypes) - { - if (!"compound".Equals(type)) - throw new ArgumentException($"Argument {nameof(type)} has to be \"compound\""); - - if (((subtypes?.Length) ?? 0) < 1) - throw new ArgumentException($"Argument {nameof(subtypes)} has to be at least a size of 1"); - - Name = name; - DisplayName = displayName; - Notes = notes; - Resources = resources; - Type = type; - Subtypes = subtypes; - } + if (!"compound".Equals(type)) + throw new ArgumentException($"Argument {nameof(type)} has to be \"compound\""); + + if (((subtypes?.Length) ?? 0) < 1) + throw new ArgumentException($"Argument {nameof(subtypes)} has to be at least a size of 1"); + + Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; + Type = type; + Subtypes = subtypes; + } - public override PDL GetDataLength() + public override PDL GetDataLength() + { + return new PDL(Subtypes.Select(s => s.GetDataLength()).ToArray()); + } + public override IEnumerable ParsePayloadToData(DataTree dataTree) + { + if (!string.Equals(dataTree.Name, this.Name)) + throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + + if (dataTree.Children.Length != Subtypes.Length) + throw new ArithmeticException($"The given {nameof(dataTree)} and {nameof(Subtypes)} has different length "); + + List data = new List(); + for (int i = 0; i < dataTree.Children.Length; i++) { - return new PDL(Subtypes.Select(s => s.GetDataLength()).ToArray()); + if (Subtypes[i].IsEmpty()) + throw new ArithmeticException($"The given Object from {nameof(Subtypes)}[{i}] is Empty"); + + data.AddRange(Subtypes[i].ParsePayloadToData(dataTree.Children[i]).SelectMany(en => en)); } - public override IEnumerable ParsePayloadToData(DataTree dataTree) - { - if (!string.Equals(dataTree.Name, this.Name)) - throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); - if (dataTree.Children.Length != Subtypes.Length) - throw new ArithmeticException($"The given {nameof(dataTree)} and {nameof(Subtypes)} has different length "); + validateDataLength(data.Count); - List data = new List(); - for (int i = 0; i < dataTree.Children.Length; i++) - { - if (Subtypes[i].IsEmpty()) - throw new ArithmeticException($"The given Object from {nameof(Subtypes)}[{i}] is Empty"); + return Tools.EncaseData(data.ToArray()); + } + public override DataTree ParseDataToPayload(ref byte[] data) + { + List subTypeDataTree = new List(); + List issueList = new List(); - data.AddRange(Subtypes[i].ParsePayloadToData(dataTree.Children[i]).SelectMany(en=>en)); - } + int dataLength = data.Length; - validateDataLength(data.Count); + for (int i = 0; i < Subtypes.Length; i++) + { + OneOfTypes subType = Subtypes[i]; + subTypeDataTree.Add(new DataTree(subType.ParseDataToPayload(ref data), (uint)i)); + } + dataLength -= data.Length; - return Tools.EncaseData(data.ToArray()); + try + { + validateDataLength(dataLength); } - public override DataTree ParseDataToPayload(ref byte[] data) + catch (Exception e) { - List subTypeDataTree = new List(); - List issueList = new List(); - - int dataLength = data.Length; - - for (int i = 0; i < Subtypes.Length; i++) - { - OneOfTypes subType = Subtypes[i]; - subTypeDataTree.Add(new DataTree(subType.ParseDataToPayload(ref data), (uint)i)); - } - dataLength -= data.Length; - - try - { - validateDataLength(dataLength); - } - catch (Exception e) - { - issueList.Add(new DataTreeIssue(e.Message)); - } - - return new DataTree(this.Name, 0, children: subTypeDataTree.OrderBy(b => b.Index).ToArray(), issueList.Count != 0 ? issueList.ToArray() : null, true); + issueList.Add(new DataTreeIssue(e.Message)); } - internal bool validateDataLength(int dataLength) - { - if (!GetDataLength().IsValid(dataLength)) - throw new ArithmeticException($"Parsed DataLength not fits Calculated DataLength"); + return new DataTree(this.Name, 0, children: subTypeDataTree.OrderBy(b => b.Index).ToArray(), issueList.Count != 0 ? issueList.ToArray() : null, isCompound: true); + } - return true; - } + internal bool validateDataLength(int dataLength) + { + if (!GetDataLength().IsValid(dataLength)) + throw new ArithmeticException($"Parsed DataLength not fits Calculated DataLength"); + + return true; } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index b3f2ffff..44c6c17c 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -4,453 +4,452 @@ using System.Linq; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.JSON.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes; + +public class IntegerType : CommonPropertiesForNamed, IIntegerType { - public class IntegerType : CommonPropertiesForNamed, IIntegerType + [JsonPropertyName("name")] + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[] Resources { get; } + + [JsonPropertyName("type")] + [JsonPropertyOrder(3)] + public EIntegerType Type { get; } + [JsonPropertyName("labels")] + [JsonPropertyOrder(31)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public LabeledIntegerType[] Labels { get; } + [JsonPropertyName("restrictToLabeled")] + [JsonPropertyOrder(32)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RestrictToLabeled { get; } + [JsonPropertyName("ranges")] + [JsonPropertyOrder(11)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Range[] Ranges { get; } + [JsonPropertyName("units")] + [JsonPropertyOrder(21)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ERDM_SensorUnit? Units { get; } + [JsonPropertyName("prefixPower")] + [JsonPropertyOrder(22)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? PrefixPower { get; } = 0; + [JsonPropertyName("prefixBase")] + [JsonPropertyOrder(23)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? PrefixBase { get; } = 10; + + [JsonIgnore(Condition = JsonIgnoreCondition.Always)] + public double PrefixMultiplyer { get; } + + [JsonConstructor] + public IntegerType(string name, + string displayName, + string notes, + string[] resources, + EIntegerType type, + LabeledIntegerType[] labels, + bool? restrictToLabeled, + Range[] ranges, + ERDM_SensorUnit? units, + int? prefixPower, + int? prefixBase) : base() { - [JsonPropertyName("name")] - [JsonPropertyOrder(1)] - [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - public override string Name { get; } - [JsonPropertyName("displayName")] - [JsonPropertyOrder(2)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string DisplayName { get; } - [JsonPropertyName("notes")] - [JsonPropertyOrder(4)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string Notes { get; } - [JsonPropertyName("resources")] - [JsonPropertyOrder(5)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[] Resources { get; } - - [JsonPropertyName("type")] - [JsonPropertyOrder(3)] - public EIntegerType Type { get; } - [JsonPropertyName("labels")] - [JsonPropertyOrder(31)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public LabeledIntegerType[] Labels { get; } - [JsonPropertyName("restrictToLabeled")] - [JsonPropertyOrder(32)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public bool? RestrictToLabeled { get; } - [JsonPropertyName("ranges")] - [JsonPropertyOrder(11)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public Range[] Ranges { get; } - [JsonPropertyName("units")] - [JsonPropertyOrder(21)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public ERDM_SensorUnit? Units { get; } - [JsonPropertyName("prefixPower")] - [JsonPropertyOrder(22)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public int? PrefixPower { get; } = 0; - [JsonPropertyName("prefixBase")] - [JsonPropertyOrder(23)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public int? PrefixBase { get; } = 10; - - [JsonIgnore(Condition = JsonIgnoreCondition.Always)] - public double PrefixMultiplyer { get; } - - [JsonConstructor] - public IntegerType(string name, - string displayName, - string notes, - string[] resources, - EIntegerType type, - LabeledIntegerType[] labels, - bool? restrictToLabeled, - Range[] ranges, - ERDM_SensorUnit? units, - int? prefixPower, - int? prefixBase) : base() - { - validateType(type); - Name = name; - DisplayName = displayName; - Notes = notes; - Resources = resources; - Type = type; - Labels = labels; - RestrictToLabeled = restrictToLabeled; - Ranges = ranges; - Units = units; - PrefixPower = prefixPower; - PrefixBase = prefixBase; - - PrefixMultiplyer = Math.Pow(PrefixBase ?? 10, PrefixPower ?? 0); - } + validateType(type); + Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; + Type = type; + Labels = labels; + RestrictToLabeled = restrictToLabeled; + Ranges = ranges; + Units = units; + PrefixPower = prefixPower; + PrefixBase = prefixBase; + + PrefixMultiplyer = Math.Pow(PrefixBase ?? 10, PrefixPower ?? 0); + } - private static void validateType(EIntegerType type, T_In dummy = default) + private static void validateType(EIntegerType type, T_In dummy = default) + { + switch (dummy) { - switch (dummy) - { - case sbyte when type is not EIntegerType.Int8: - throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int8}\""); + case sbyte when type is not EIntegerType.Int8: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int8}\""); - case byte when type is not EIntegerType.UInt8: - throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt8}\""); + case byte when type is not EIntegerType.UInt8: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt8}\""); - case short when type is not EIntegerType.Int16: - throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int16}\""); + case short when type is not EIntegerType.Int16: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int16}\""); - case ushort when type is not EIntegerType.UInt16: - throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt16}\""); + case ushort when type is not EIntegerType.UInt16: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt16}\""); - case int when type is not EIntegerType.Int32: - throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int32}\""); + case int when type is not EIntegerType.Int32: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int32}\""); - case uint when type is not EIntegerType.UInt32: - throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt32}\""); + case uint when type is not EIntegerType.UInt32: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt32}\""); - case long when type is not EIntegerType.Int64: - throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int64}\""); + case long when type is not EIntegerType.Int64: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int64}\""); - case ulong when type is not EIntegerType.UInt64: - throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt64}\""); + case ulong when type is not EIntegerType.UInt64: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt64}\""); #if NET7_0_OR_GREATER - case Int128 when type is not EIntegerType.Int128: - throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int128}\""); + case Int128 when type is not EIntegerType.Int128: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int128}\""); - case UInt128 when type is not EIntegerType.UInt128: - throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt128}\""); + case UInt128 when type is not EIntegerType.UInt128: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt128}\""); #endif - } } + } - public override string ToString() - { - if (Labels != null) - return $"{Name} {Type} -> [ {string.Join("; ", Labels.Select(l => l.ToString()))} ]"; + public override string ToString() + { + if (Labels != null) + return $"{Name} {Type} -> [ {string.Join("; ", Labels.Select(l => l.ToString()))} ]"; - return $"{Name} {Type}"; - } + return $"{Name} {Type}"; + } - public override PDL GetDataLength() + public override PDL GetDataLength() + { + switch (Type) { - switch (Type) - { - case EIntegerType.Int8: - case EIntegerType.UInt8: - return new PDL(1); - - case EIntegerType.Int16: - case EIntegerType.UInt16: - return new PDL(2); - - case EIntegerType.Int32: - case EIntegerType.UInt32: - return new PDL(4); - - case EIntegerType.Int64: - case EIntegerType.UInt64: - return new PDL(8); - } - return new PDL(16); + case EIntegerType.Int8: + case EIntegerType.UInt8: + return new PDL(1); + + case EIntegerType.Int16: + case EIntegerType.UInt16: + return new PDL(2); + + case EIntegerType.Int32: + case EIntegerType.UInt32: + return new PDL(4); + + case EIntegerType.Int64: + case EIntegerType.UInt64: + return new PDL(8); } + return new PDL(16); + } + + private TOutput convertFormatedValueToRaw(object formated) where TOutput : T + { + if (PrefixMultiplyer == 1) + return (TOutput)formated; - private TOutput convertFormatedValueToRaw(object formated) where TOutput: T + object rawValue = null; + switch (formated) { - if (PrefixMultiplyer == 1) + case double _double: + rawValue = _double / PrefixMultiplyer; + break; + case long _long: + rawValue = _long / PrefixMultiplyer; + break; + case ulong _ulong: + rawValue = _ulong / PrefixMultiplyer; + break; + + default: return (TOutput)formated; - - object rawValue = null; - switch (formated) - { - case double _double: - rawValue = _double / PrefixMultiplyer; - break; - case long _long: - rawValue = _long / PrefixMultiplyer; - break; - case ulong _ulong: - rawValue = _ulong / PrefixMultiplyer; - break; - - default: - return (TOutput)formated; - } - - if (rawValue is not null) - return (TOutput)Convert.ChangeType(rawValue, typeof(T)); - - throw new NotImplementedException(); } - private object convertRawValueToFormated(T raw) + if (rawValue is not null) + return (TOutput)Convert.ChangeType(rawValue, typeof(T)); + + throw new NotImplementedException(); + } + + private object convertRawValueToFormated(T raw) + { + if (PrefixMultiplyer == 1) + return raw; + + bool isNegativ = Math.Sign(PrefixMultiplyer) == -1; + bool isDezimal = PrefixPower < 0; + + switch (raw) { - if (PrefixMultiplyer == 1) + case sbyte int8: + if (isDezimal) + return (double)(PrefixMultiplyer * int8); + if (isNegativ) + return (long)(PrefixMultiplyer * int8); + return (ulong)(PrefixMultiplyer * int8); + + case byte uint8: + if (isDezimal) + return (double)(PrefixMultiplyer * uint8); + if (isNegativ) + return (long)(PrefixMultiplyer * uint8); + return (ulong)(PrefixMultiplyer * uint8); + + case short int16: + if (isDezimal) + return (double)(PrefixMultiplyer * int16); + if (isNegativ) + return (long)(PrefixMultiplyer * int16); + return (ulong)(PrefixMultiplyer * int16); + + case ushort uint16: + if (isDezimal) + return (double)(PrefixMultiplyer * uint16); + if (isNegativ) + return (long)(PrefixMultiplyer * uint16); + return (ulong)(PrefixMultiplyer * uint16); + + case int int32: + if (isDezimal) + return (double)(PrefixMultiplyer * int32); + if (isNegativ) + return (long)(PrefixMultiplyer * int32); + return (ulong)(PrefixMultiplyer * int32); + + case uint uint32: + if (isDezimal) + return (double)(PrefixMultiplyer * uint32); + if (isNegativ) + return (long)(PrefixMultiplyer * uint32); + return (ulong)(PrefixMultiplyer * uint32); + + case long int64: + if (isDezimal) + return (double)(PrefixMultiplyer * int64); + if (isNegativ) + return (long)(PrefixMultiplyer * int64); + return (ulong)(PrefixMultiplyer * int64); + + case ulong uint64: + if (isDezimal) + return (double)(PrefixMultiplyer * uint64); + if (isNegativ) + return (long)(PrefixMultiplyer * uint64); + return (ulong)(PrefixMultiplyer * uint64); + + default: return raw; - - bool isNegativ = Math.Sign(PrefixMultiplyer) == -1; - bool isDezimal = PrefixPower < 0; - - switch (raw) - { - case sbyte int8: - if (isDezimal) - return (double)(PrefixMultiplyer * int8); - if (isNegativ) - return (long)(PrefixMultiplyer * int8); - return (ulong)(PrefixMultiplyer * int8); - - case byte uint8: - if (isDezimal) - return (double)(PrefixMultiplyer * uint8); - if (isNegativ) - return (long)(PrefixMultiplyer * uint8); - return (ulong)(PrefixMultiplyer * uint8); - - case short int16: - if (isDezimal) - return (double)(PrefixMultiplyer * int16); - if (isNegativ) - return (long)(PrefixMultiplyer * int16); - return (ulong)(PrefixMultiplyer * int16); - - case ushort uint16: - if (isDezimal) - return (double)(PrefixMultiplyer * uint16); - if (isNegativ) - return (long)(PrefixMultiplyer * uint16); - return (ulong)(PrefixMultiplyer * uint16); - - case int int32: - if (isDezimal) - return (double)(PrefixMultiplyer * int32); - if (isNegativ) - return (long)(PrefixMultiplyer * int32); - return (ulong)(PrefixMultiplyer * int32); - - case uint uint32: - if (isDezimal) - return (double)(PrefixMultiplyer * uint32); - if (isNegativ) - return (long)(PrefixMultiplyer * uint32); - return (ulong)(PrefixMultiplyer * uint32); - - case long int64: - if (isDezimal) - return (double)(PrefixMultiplyer * int64); - if (isNegativ) - return (long)(PrefixMultiplyer * int64); - return (ulong)(PrefixMultiplyer * int64); - - case ulong uint64: - if (isDezimal) - return (double)(PrefixMultiplyer * uint64); - if (isNegativ) - return (long)(PrefixMultiplyer * uint64); - return (ulong)(PrefixMultiplyer * uint64); - - default: - return raw; - } - throw new NotImplementedException(); } + throw new NotImplementedException(); + } - public override IEnumerable ParsePayloadToData(DataTree dataTree) - { - if (!string.Equals(dataTree.Name, this.Name)) - throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + public override IEnumerable ParsePayloadToData(DataTree dataTree) + { + if (!string.Equals(dataTree.Name, this.Name)) + throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); - if(dataTree.Value is null) - throw new ArithmeticException("Value can't be Null"); + if (dataTree.Value is null) + throw new ArithmeticException("Value can't be Null"); - var rawValue = convertFormatedValueToRaw(dataTree.Value); - if (Ranges != null) - { - if (!Ranges.Any(r => r.IsInRange(rawValue))) - throw new ArithmeticException("The Value is not in range of any Range"); - } - var data = Tools.ValueToData(rawValue); + var rawValue = convertFormatedValueToRaw(dataTree.Value); + if (Ranges != null) + { + if (!Ranges.Any(r => r.IsInRange(rawValue))) + throw new ArithmeticException($"The Value is not in range of any Range {Environment.NewLine}Value: {rawValue}, Ranges: {string.Join("; ", Ranges)}"); + } + var data = Tools.ValueToData(rawValue); - return Tools.EncaseData(data); + return Tools.EncaseData(data); + } + public override DataTree ParseDataToPayload(ref byte[] data) + { + List issueList = new List(); + uint pdl = GetDataLength().Value.Value; + + if (data.Length < pdl) + { + issueList.Add(new DataTreeIssue("Given Data not fits PDL")); + byte[] cloneData = new byte[pdl]; + Array.Copy(data, cloneData, data.Length); + data = cloneData; } - public override DataTree ParseDataToPayload(ref byte[] data) + + object value = null; + + switch (this.Type) { - List issueList = new List(); - uint pdl = GetDataLength().Value.Value; - - if (data.Length < pdl) - { - issueList.Add(new DataTreeIssue("Given Data not fits PDL")); - byte[] cloneData = new byte[pdl]; - Array.Copy(data, cloneData, data.Length); - data = cloneData; - } - - object value = null; - - switch (this.Type) - { - case EIntegerType.Int8: - value = Tools.DataToSByte(ref data); - break; - case EIntegerType.UInt8: - value = Tools.DataToByte(ref data); - break; - case EIntegerType.Int16: - value = Tools.DataToShort(ref data); - break; - case EIntegerType.UInt16: - value = Tools.DataToUShort(ref data); - break; - case EIntegerType.Int32: - value = Tools.DataToInt(ref data); - break; - case EIntegerType.UInt32: - value = Tools.DataToUInt(ref data); - break; - case EIntegerType.Int64: - value = Tools.DataToLong(ref data); - break; - case EIntegerType.UInt64: - value = Tools.DataToULong(ref data); - break; + case EIntegerType.Int8: + value = Tools.DataToSByte(ref data); + break; + case EIntegerType.UInt8: + value = Tools.DataToByte(ref data); + break; + case EIntegerType.Int16: + value = Tools.DataToShort(ref data); + break; + case EIntegerType.UInt16: + value = Tools.DataToUShort(ref data); + break; + case EIntegerType.Int32: + value = Tools.DataToInt(ref data); + break; + case EIntegerType.UInt32: + value = Tools.DataToUInt(ref data); + break; + case EIntegerType.Int64: + value = Tools.DataToLong(ref data); + break; + case EIntegerType.UInt64: + value = Tools.DataToULong(ref data); + break; #if NET7_0_OR_GREATER - case EIntegerType.Int128: - value = Tools.DataToInt128(ref data); - break; - case EIntegerType.UInt128: - value = Tools.DataToUInt128(ref data); - break; + case EIntegerType.Int128: + value = Tools.DataToInt128(ref data); + break; + case EIntegerType.UInt128: + value = Tools.DataToUInt128(ref data); + break; #endif - } - if (Ranges != null) - { - if (!Ranges.Any(r => r.IsInRange((T)value))) - issueList.Add(new DataTreeIssue("The Value is not in range of any Range")); - } - - string unit = null; - if (Units.HasValue) - unit = Tools.GetUnitSymbol(Units.Value); - DataTreeValueLabel[] labels = null; - if ((Labels?.Length ?? 0) != 0) - labels = Labels.Select(lb => new DataTreeValueLabel(lb.Value, (lb.DisplayName ?? lb.Name))).ToArray(); - - return new DataTree(this.Name, 0, convertRawValueToFormated((T)value), issueList.Count != 0 ? issueList.ToArray() : null, unit, labels); } - - public bool IsInRange(object number) + if (Ranges != null) { - if (Ranges != null) - return Ranges.Any(r => r.IsInRange((T)number)); - - return new Range((T)GetMinimum(), (T)GetMaximum()).IsInRange((T)number); + if (!Ranges.Any(r => r.IsInRange((T)value))) + issueList.Add(new DataTreeIssue("The Value is not in range of any Range")); } - public object GetMaximum() + string unit = null; + if (Units.HasValue) + unit = Tools.GetUnitSymbol(Units.Value); + DataTreeValueLabel[] labels = null; + if ((Labels?.Length ?? 0) != 0) + labels = Labels.Select(lb => new DataTreeValueLabel(lb.Value, (lb.DisplayName ?? lb.Name))).ToArray(); + + return new DataTree(this.Name, 0, convertRawValueToFormated((T)value), issueList.Count != 0 ? issueList.ToArray() : null, unit, labels); + } + + public bool IsInRange(object number) + { + if (Ranges != null) + return Ranges.Any(r => r.IsInRange((T)number)); + + return new Range((T)GetMinimum(), (T)GetMaximum()).IsInRange((T)number); + } + + public object GetMaximum() + { + if (Ranges != null) + return Ranges.Max(r => r.Maximum); + + switch (this.Type) { - if (Ranges != null) - return Ranges.Max(r => r.Maximum); - - switch (this.Type) - { - case EIntegerType.Int8: - return sbyte.MaxValue; - case EIntegerType.UInt8: - return byte.MaxValue; - case EIntegerType.Int16: - return short.MaxValue; - case EIntegerType.UInt16: - return ushort.MaxValue; - case EIntegerType.Int32: - return int.MaxValue; - case EIntegerType.UInt32: - return uint.MaxValue; - case EIntegerType.Int64: - return long.MaxValue; - case EIntegerType.UInt64: - return ulong.MaxValue; + case EIntegerType.Int8: + return sbyte.MaxValue; + case EIntegerType.UInt8: + return byte.MaxValue; + case EIntegerType.Int16: + return short.MaxValue; + case EIntegerType.UInt16: + return ushort.MaxValue; + case EIntegerType.Int32: + return int.MaxValue; + case EIntegerType.UInt32: + return uint.MaxValue; + case EIntegerType.Int64: + return long.MaxValue; + case EIntegerType.UInt64: + return ulong.MaxValue; #if NET7_0_OR_GREATER - case EIntegerType.Int128: - return Int128.MaxValue; - case EIntegerType.UInt128: - return UInt128.MaxValue; + case EIntegerType.Int128: + return Int128.MaxValue; + case EIntegerType.UInt128: + return UInt128.MaxValue; #endif - } - throw new NotImplementedException(); } + throw new NotImplementedException(); + } + + public object GetMinimum() + { + if (Ranges != null) + return Ranges.Min(r => r.Minimum); - public object GetMinimum() + switch (this.Type) { - if (Ranges != null) - return Ranges.Min(r => r.Minimum); - - switch (this.Type) - { - case EIntegerType.Int8: - return sbyte.MinValue; - case EIntegerType.UInt8: - return byte.MinValue; - case EIntegerType.Int16: - return short.MinValue; - case EIntegerType.UInt16: - return ushort.MinValue; - case EIntegerType.Int32: - return int.MinValue; - case EIntegerType.UInt32: - return uint.MinValue; - case EIntegerType.Int64: - return long.MinValue; - case EIntegerType.UInt64: - return ulong.MinValue; + case EIntegerType.Int8: + return sbyte.MinValue; + case EIntegerType.UInt8: + return byte.MinValue; + case EIntegerType.Int16: + return short.MinValue; + case EIntegerType.UInt16: + return ushort.MinValue; + case EIntegerType.Int32: + return int.MinValue; + case EIntegerType.UInt32: + return uint.MinValue; + case EIntegerType.Int64: + return long.MinValue; + case EIntegerType.UInt64: + return ulong.MinValue; #if NET7_0_OR_GREATER - case EIntegerType.Int128: - return Int128.MinValue; - case EIntegerType.UInt128: - return UInt128.MinValue; + case EIntegerType.Int128: + return Int128.MinValue; + case EIntegerType.UInt128: + return UInt128.MinValue; #endif - } - throw new NotImplementedException(); } + throw new NotImplementedException(); + } - public object Increment(object number) + public object Increment(object number) + { + switch (this.Type) { - switch (this.Type) - { - case EIntegerType.Int8: - return (sbyte)((sbyte)number + 1); - case EIntegerType.UInt8: - return (byte)((byte)number + 1); - case EIntegerType.Int16: - return (short)((short)number + 1); - case EIntegerType.UInt16: - return (ushort)((ushort)number + 1); - case EIntegerType.Int32: - return (int)((int)number + 1); - case EIntegerType.UInt32: - return (uint)((uint)number + 1); - case EIntegerType.Int64: - return (long)((long)number + 1); - case EIntegerType.UInt64: - return (ulong)((ulong)number + 1); + case EIntegerType.Int8: + return (sbyte)((sbyte)number + 1); + case EIntegerType.UInt8: + return (byte)((byte)number + 1); + case EIntegerType.Int16: + return (short)((short)number + 1); + case EIntegerType.UInt16: + return (ushort)((ushort)number + 1); + case EIntegerType.Int32: + return (int)((int)number + 1); + case EIntegerType.UInt32: + return (uint)((uint)number + 1); + case EIntegerType.Int64: + return (long)((long)number + 1); + case EIntegerType.UInt64: + return (ulong)((ulong)number + 1); #if NET7_0_OR_GREATER - case EIntegerType.Int128: - return (Int128)((Int128)number + 1); - case EIntegerType.UInt128: - return (UInt128)((UInt128)number + 1); + case EIntegerType.Int128: + return (Int128)((Int128)number + 1); + case EIntegerType.UInt128: + return (UInt128)((UInt128)number + 1); #endif - } - return number; } + return number; + } - public object IncrementJumpRange(object number) - { - object incremented = Increment(number); - if (IsInRange(incremented)) - return incremented; + public object IncrementJumpRange(object number) + { + object incremented = Increment(number); + if (IsInRange(incremented)) + return incremented; - if (Ranges != null) - return Ranges.Where(r => r.IsBelow((T)incremented)).Min(r => r.Minimum); + if (Ranges != null) + return Ranges.Where(r => r.IsBelow((T)incremented)).Min(r => r.Minimum); - return false; - } + return false; } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs index 8015e499..4b1207eb 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs @@ -1,178 +1,177 @@ using RDMSharp.RDM; using System; -using System.Linq; using System.Collections.Generic; +using System.Linq; using System.Runtime.CompilerServices; using System.Text.Json.Serialization; [assembly: InternalsVisibleTo("RDMSharpTests")] -namespace RDMSharp.Metadata.JSON.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes; + +public class ListType : CommonPropertiesForNamed { - public class ListType : CommonPropertiesForNamed + [JsonPropertyName("name")] + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[] Resources { get; } + + [JsonPropertyName("type")] + [JsonPropertyOrder(3)] + public string Type { get; } + [JsonPropertyName("itemType")] + [JsonPropertyOrder(21)] + public OneOfTypes ItemType { get; } + [JsonPropertyName("minItems")] + [JsonPropertyOrder(31)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public uint? MinItems { get; } + [JsonPropertyName("maxItems")] + [JsonPropertyOrder(32)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public uint? MaxItems { get; } + + + [JsonConstructor] + public ListType(string name, + string displayName, + string notes, + string[] resources, + string type, + OneOfTypes itemType, + uint? minItems, + uint? maxItems) : base() { - [JsonPropertyName("name")] - [JsonPropertyOrder(1)] - [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - public override string Name { get; } - [JsonPropertyName("displayName")] - [JsonPropertyOrder(2)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string DisplayName { get; } - [JsonPropertyName("notes")] - [JsonPropertyOrder(4)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string Notes { get; } - [JsonPropertyName("resources")] - [JsonPropertyOrder(5)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[] Resources { get; } - - [JsonPropertyName("type")] - [JsonPropertyOrder(3)] - public string Type { get; } - [JsonPropertyName("itemType")] - [JsonPropertyOrder(21)] - public OneOfTypes ItemType { get; } - [JsonPropertyName("minItems")] - [JsonPropertyOrder(31)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public uint? MinItems { get; } - [JsonPropertyName("maxItems")] - [JsonPropertyOrder(32)] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public uint? MaxItems { get; } - - - [JsonConstructor] - public ListType(string name, - string displayName, - string notes, - string[] resources, - string type, - OneOfTypes itemType, - uint? minItems, - uint? maxItems) : base() - { - if (!"list".Equals(type)) - throw new ArgumentException($"Argument {nameof(type)} has to be \"list\""); - - if (itemType.IsEmpty()) - throw new ArgumentException($"Argument {nameof(itemType)} is Empty, this is not allowed"); - - Name = name; - DisplayName = displayName; - Notes = notes; - Resources = resources; - Type = type; - ItemType = itemType; - MinItems = minItems; - MaxItems = maxItems; - } + if (!"list".Equals(type)) + throw new ArgumentException($"Argument {nameof(type)} has to be \"list\""); + + if (itemType.IsEmpty()) + throw new ArgumentException($"Argument {nameof(itemType)} is Empty, this is not allowed"); + + Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; + Type = type; + ItemType = itemType; + MinItems = minItems; + MaxItems = maxItems; + } + + public override string ToString() + { + return DisplayName ?? Name; + } + + public override PDL GetDataLength() + { + uint min = 0; + uint max = 0; + + if (MinItems.HasValue) + min = MinItems.Value; + if (MaxItems.HasValue) + max = MaxItems.Value; - public override string ToString() + PDL itemPDL = ItemType.GetDataLength(); + if (itemPDL.Value.HasValue) { - return DisplayName ?? Name; + min *= itemPDL.Value.Value; + max *= itemPDL.Value.Value; } - - public override PDL GetDataLength() + else { - uint min = 0; - uint max = 0; + if (itemPDL.MinLength.HasValue) + min *= itemPDL.MinLength.Value; + if (itemPDL.MaxLength.HasValue) + max *= itemPDL.MaxLength.Value; + } - if (MinItems.HasValue) - min = MinItems.Value; - if (MaxItems.HasValue) - max = MaxItems.Value; + if (max == 0) + if (!MaxItems.HasValue) + max = PDL.MAX_LENGTH; - PDL itemPDL = ItemType.GetDataLength(); - if (itemPDL.Value.HasValue) - { - min *= itemPDL.Value.Value; - max *= itemPDL.Value.Value; - } - else - { - if (itemPDL.MinLength.HasValue) - min *= itemPDL.MinLength.Value; - if (itemPDL.MaxLength.HasValue) - max *= itemPDL.MaxLength.Value; - } + if (min == max) + return new PDL(min); - if (max == 0) - if (!MaxItems.HasValue) - max = PDL.MAX_LENGTH; + return new PDL(min, max); + } + public override IEnumerable ParsePayloadToData(DataTree dataTree) + { + if (!string.Equals(dataTree.Name, this.Name)) + throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); - if (min == max) - return new PDL(min); + List data = new List(); + for (int i = 0; i < dataTree.Children.Length; i++) + data.AddRange(ItemType.ParsePayloadToData(dataTree.Children[i])); - return new PDL(min, max); - } - public override IEnumerable ParsePayloadToData(DataTree dataTree) - { - if (!string.Equals(dataTree.Name, this.Name)) - throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + validateDataLength(data.SelectMany(en => en).Count()); - List data = new List(); - for (int i = 0; i < dataTree.Children.Length; i++) - data.AddRange(ItemType.ParsePayloadToData(dataTree.Children[i])); + return data.ToArray(); + } - validateDataLength(data.SelectMany(en=>en).Count()); + public override DataTree ParseDataToPayload(ref byte[] data) + { + List dataTrees = new List(); + List issueList = new List(); - return data.ToArray(); + uint index = 0; + int dataLength = data.Length; + while (_continue(ref data)) + { + dataTrees.Add(new DataTree(ItemType.ParseDataToPayload(ref data), index)); + index++; } + dataLength -= data.Length; - public override DataTree ParseDataToPayload(ref byte[] data) + try { - List dataTrees = new List(); - List issueList = new List(); - - uint index = 0; - int dataLength = data.Length; - while (_continue(ref data)) - { - dataTrees.Add(new DataTree(ItemType.ParseDataToPayload(ref data), index)); - index++; - } - dataLength -= data.Length; - - try - { - validateDataLength(dataLength); - } - catch (Exception e) - { - issueList.Add(new DataTreeIssue(e.Message)); - } + validateDataLength(dataLength); + } + catch (Exception e) + { + issueList.Add(new DataTreeIssue(e.Message)); + } - return new DataTree(Name, 0, children: dataTrees.ToArray(), issueList.Count != 0 ? issueList.ToArray() : null); + return new DataTree(Name, 0, children: dataTrees.ToArray(), issueList.Count != 0 ? issueList.ToArray() : null, isList: true); - bool _continue(ref byte[] data) - { - if (MaxItems.HasValue) - if (dataTrees.Count > MaxItems.Value) - { - if (dataTrees.Count > 0) - issueList.Add(new DataTreeIssue($"Given data exceeds {nameof(MaxItems)}")); - return false; - } - if (data.Length == 0) + bool _continue(ref byte[] data) + { + if (MaxItems.HasValue) + if (dataTrees.Count > MaxItems.Value) { - if (MinItems.HasValue) - if (dataTrees.Count < MinItems.Value) - issueList.Add(new DataTreeIssue($"Given data falls shorts of {nameof(MinItems)}")); + if (dataTrees.Count > 0) + issueList.Add(new DataTreeIssue($"Given data exceeds {nameof(MaxItems)}")); return false; } - - return true; + if (data.Length == 0) + { + if (MinItems.HasValue) + if (dataTrees.Count < MinItems.Value) + issueList.Add(new DataTreeIssue($"Given data falls shorts of {nameof(MinItems)}")); + return false; } - } - internal bool validateDataLength(int dataLength) - { - if (!GetDataLength().IsValid(dataLength)) - throw new ArithmeticException($"Parsed DataLength not fits Calculated DataLength"); return true; } } + internal bool validateDataLength(int dataLength) + { + if (!GetDataLength().IsValid(dataLength)) + throw new ArithmeticException($"Parsed DataLength not fits Calculated DataLength"); + + return true; + } } \ No newline at end of file diff --git a/RDMSharp/Metadata/MetadataFactory.cs b/RDMSharp/Metadata/MetadataFactory.cs index 85efa83f..34246118 100644 --- a/RDMSharp/Metadata/MetadataFactory.cs +++ b/RDMSharp/Metadata/MetadataFactory.cs @@ -2,471 +2,498 @@ using Microsoft.Extensions.Logging; using RDMSharp.Metadata.JSON; using RDMSharp.Metadata.JSON.OneOfTypes; +using RDMSharp.PayloadObject; using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text.Json; -using System.Text.Json.Nodes; +using System.Threading; using System.Threading.Tasks; [assembly: InternalsVisibleTo("RDMSharpTests")] -namespace RDMSharp.Metadata +namespace RDMSharp.Metadata; + +public static class MetadataFactory { - public static class MetadataFactory + private static readonly ILogger Logger = Logging.CreateLogger(typeof(MetadataFactory)); + private const string SCHEMA_FILE_NAME = "schema.json"; + private const string JSON_ENDING = ".json"; + private static ConcurrentDictionary metadataVersionList; + private static ConcurrentDictionary> metadataVersionDefinesBagDictionary; + private static ConcurrentDictionary parameterBagDefineCache; + private static List resourceProvider = new List() { typeof(MetadataFactory).Assembly }; + public static bool IsInitialized = false; + private static readonly SemaphoreSlim fillDefaultMetadataVersionListSemaphoreSlim = new SemaphoreSlim(1, 1); + + public static void AddResourceProvider(Assembly assembly) { - private static readonly ILogger Logger = Logging.CreateLogger(typeof(MetadataFactory)); - private const string SCHEMA_FILE_NAME = "schema.json"; - private const string JSON_ENDING = ".json"; - private static ConcurrentDictionary metadataVersionList; - private static ConcurrentDictionary> metadataVersionDefinesBagDictionary; - private static ConcurrentDictionary parameterBagDefineCache; - private static List resourceProvider = new List() { typeof(MetadataFactory).Assembly }; - - public static void AddResourceProvider(Assembly assembly) - { + if (!resourceProvider.Contains(assembly)) resourceProvider.Add(assembly); - } - public static IReadOnlyDictionary MetadataVersionList + } + public static IReadOnlyDictionary MetadataVersionList + { + get { - get + if (metadataVersionList == null) { - if (metadataVersionList == null) + metadataVersionList = new ConcurrentDictionary(); + foreach (Assembly assembly in resourceProvider) { - metadataVersionList = new ConcurrentDictionary(); - foreach (Assembly assembly in resourceProvider) + try { - try - { - var resoures = GetResources(assembly); - var metaDataVersions = resoures.Select(r => new MetadataVersion(r, assembly)); - foreach (var mv in metaDataVersions) - metadataVersionList.TryAdd(mv.Path, mv); - } - catch (Exception e) - { - Logger?.LogError(e); - } + var resoures = GetResources(assembly); + var metaDataVersions = resoures.Select(r => new MetadataVersion(r, assembly)); + foreach (var mv in metaDataVersions) + metadataVersionList.TryAdd(mv.Path, mv); + } + catch (Exception e) + { + Logger?.LogError(e); } } - return metadataVersionList.AsReadOnly(); } + return metadataVersionList.AsReadOnly(); } - public static IReadOnlyCollection GetResources(Assembly assembly) - { - return assembly.GetManifestResourceNames().Where(p => p.EndsWith(JSON_ENDING)).ToList().AsReadOnly(); - } - private static void fillDefaultMetadataVersionList() + } + public static IReadOnlyCollection GetResources(Assembly assembly) + { + return assembly.GetManifestResourceNames().Where(p => p.EndsWith(JSON_ENDING)).ToList().AsReadOnly(); + } + private static async Task fillDefaultMetadataVersionList() + { + if (fillDefaultMetadataVersionListSemaphoreSlim.CurrentCount == 0) + return; + await fillDefaultMetadataVersionListSemaphoreSlim.WaitAsync(); + if (metadataVersionDefinesBagDictionary != null) + return; + + metadataVersionDefinesBagDictionary = new ConcurrentDictionary>(); + foreach (Assembly assembly in resourceProvider) { - if (metadataVersionDefinesBagDictionary != null) - return; - - metadataVersionDefinesBagDictionary = new ConcurrentDictionary>(); - foreach (Assembly assembly in resourceProvider) + try { - try - { - var metaDataVersions = GetResources(assembly).Select(r => new MetadataVersion(r, assembly)); - foreach (var mv in metaDataVersions) - metadataVersionList.TryAdd(mv.Path, mv); - } - catch (Exception e) - { - Logger?.LogError(e); - } + var metaDataVersions = GetResources(assembly).Select(r => new MetadataVersion(r, assembly)); + foreach (var mv in metaDataVersions) + metadataVersionList.TryAdd(mv.Path, mv); } + catch (Exception e) + { + Logger?.LogError(e); + } + } - var schemaList = GetMetadataSchemaVersions(); - ConcurrentDictionary versionSchemas = new ConcurrentDictionary(); + var schemaList = GetMetadataSchemaVersions(); + ConcurrentDictionary versionSchemas = new ConcurrentDictionary(); - var nonSchemaVersions = metadataVersionList.Values.Where(_mv => !_mv.IsSchema).ToList(); + var nonSchemaVersions = metadataVersionList.Values.Where(_mv => !_mv.IsSchema).ToList(); - ParallelOptions parallelOptions = new ParallelOptions - { - MaxDegreeOfParallelism = Environment.ProcessorCount, // Optional: Set the maximum degree of parallelism - }; - Parallel.ForEach(nonSchemaVersions, parallelOptions, mv => + ParallelOptions parallelOptions = new ParallelOptions + { + MaxDegreeOfParallelism = Environment.ProcessorCount, // Optional: Set the maximum degree of parallelism + }; + await Parallel.ForEachAsync(nonSchemaVersions, parallelOptions, async (mv, token) => + { + try { - try + var schema = schemaList.First(s => s.Version.Equals(mv.Version)); + if (!versionSchemas.TryGetValue(schema.Version, out JsonSchema jsonSchema)) { - var schema = schemaList.First(s => s.Version.Equals(mv.Version)); - if (!versionSchemas.TryGetValue(schema.Version, out JsonSchema jsonSchema)) - { - jsonSchema = JsonSchema.FromText(new MetadataBag(schema).Content); - versionSchemas.TryAdd(schema.Version, jsonSchema); - } - MetadataBag metadataBag = new MetadataBag(mv); - var result = jsonSchema.Evaluate(JsonNode.Parse(metadataBag.Content)); - if (result.IsValid) - { - MetadataJSONObjectDefine jsonDefine = JsonSerializer.Deserialize(metadataBag.Content); - metadataVersionDefinesBagDictionary.AddOrUpdate(schema, - _ => new List { jsonDefine }, - (_, list) => - { - lock (list) - { - list.Add(jsonDefine); - return list; - } - }); - } - else - throw new Exception($"Schema Invalid for {mv.Name}"); + jsonSchema = JsonSchema.FromText(new MetadataBag(schema).Content); + versionSchemas.TryAdd(schema.Version, jsonSchema); } - catch (Exception e) + MetadataBag metadataBag = new MetadataBag(mv); + var doc = JsonDocument.Parse(metadataBag.Content); + var result = jsonSchema.Evaluate(doc.RootElement); + if (result.IsValid) { - Logger?.LogError($"Exception while Deserialize {mv.Name}", e); + MetadataJSONObjectDefine jsonDefine = JsonSerializer.Deserialize(metadataBag.Content); + metadataVersionDefinesBagDictionary.AddOrUpdate(schema, + _ => new List { jsonDefine }, + (_, list) => + { + lock (list) + { + list.Add(jsonDefine); + return list; + } + }); } - }); - } + else + throw new Exception($"Schema Invalid for {mv.Name}"); + } + catch (Exception e) + { + Logger?.LogError($"Exception while Deserialize {mv.Name}", e); + } + }); + GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true, compacting: true); + GC.WaitForPendingFinalizers(); + GC.Collect(); + IsInitialized = true; + fillDefaultMetadataVersionListSemaphoreSlim.Release(); + } - public static IReadOnlyCollection GetMetadataSchemaVersions() + public static IReadOnlyCollection GetMetadataSchemaVersions() + { + return MetadataVersionList.Values.Where(r => r.IsSchema).ToList().AsReadOnly(); + } + public static IReadOnlyCollection GetMetadataDefineVersions() + { + try { - return MetadataVersionList.Values.Where(r => r.IsSchema).ToList().AsReadOnly(); + return MetadataVersionList.Values.Where(r => !r.IsSchema).ToList().AsReadOnly(); } - public static IReadOnlyCollection GetMetadataDefineVersions() + finally { - try - { - return MetadataVersionList.Values.Where(r => !r.IsSchema).ToList().AsReadOnly(); - } - finally + fillDefaultMetadataVersionList(); + } + } + public static MetadataJSONObjectDefine GetDefine(ParameterBag parameter) + { + try + { + if (parameterBagDefineCache == null) + parameterBagDefineCache = new ConcurrentDictionary(); + + if (parameterBagDefineCache.TryGetValue(parameter, out var define)) + return define; + + define = getDefine(parameter); + if (define != null) { - fillDefaultMetadataVersionList(); + parameterBagDefineCache.TryAdd(parameter, define); + return define; } } - public static MetadataJSONObjectDefine GetDefine(ParameterBag parameter) + catch (Exception ex) { - try - { - if (parameterBagDefineCache == null) - parameterBagDefineCache = new ConcurrentDictionary(); - - if (parameterBagDefineCache.TryGetValue(parameter, out var define)) - return define; + Logger?.LogError(ex); + } + if ((ushort)parameter.PID < 0x8000 || (ushort)parameter.PID > 0xFFDF) + throw new DefineNotFoundException($"{parameter}"); - define = getDefine(parameter); - if (define != null) - { - parameterBagDefineCache.TryAdd(parameter, define); - return define; - } + return null; + } + public static void AddDefineFromParameterDescription(UID uid, SubDevice subDevice, RDMDeviceInfo deviceInfo, RDMParameterDescription parameterDescription) + { + SubdevicesForRequests[] getRequestSubdeviceRange = null; + SubdevicesForResponses[] getResponseSubdeviceRange = null; + SubdevicesForRequests[] setRequestSubdeviceRange = null; + SubdevicesForResponses[] setResponseSubdeviceRange = null; + Command? getCommandRequest = null; + Command? getCommandResponse = null; + Command? setCommandRequest = null; + Command? setCommandResponse = null; + if (deviceInfo.SubDeviceCount == 0) + { + if (parameterDescription.CommandClass.HasFlag(ERDM_CommandClass.GET)) + { + getRequestSubdeviceRange = new SubdevicesForRequests[] { new SubdevicesForRequests(SubdevicesForRequests.ESubdevicesForRequests.Root) }; + getResponseSubdeviceRange = new SubdevicesForResponses[] { new SubdevicesForResponses(SubdevicesForResponses.ESubdevicesForResponses.Root) }; } - catch (Exception ex) + if (parameterDescription.CommandClass.HasFlag(ERDM_CommandClass.SET)) { - Logger?.LogError(ex); + setRequestSubdeviceRange = new SubdevicesForRequests[] { new SubdevicesForRequests(SubdevicesForRequests.ESubdevicesForRequests.Root) }; + setResponseSubdeviceRange = new SubdevicesForResponses[] { new SubdevicesForResponses(SubdevicesForResponses.ESubdevicesForResponses.Root) }; } - if ((ushort)parameter.PID < 0x8000 || (ushort)parameter.PID > 0xFFDF) - throw new DefineNotFoundException($"{parameter}"); + } - return null; + string name = parameterDescription.Description; + string displayName = getDisplayName(parameterDescription); + + if (parameterDescription.CommandClass == ERDM_CommandClass.SET) + { + setCommandRequest = new Command(); + setCommandResponse = new Command(); } - public static void AddDefineFromParameterDescription(UID uid,SubDevice subDevice, RDMDeviceInfo deviceInfo, RDMParameterDescription parameterDescription) + else { - SubdevicesForRequests[] getRequestSubdeviceRange = null; - SubdevicesForResponses[] getResponseSubdeviceRange = null; - SubdevicesForRequests[] setRequestSubdeviceRange = null; - SubdevicesForResponses[] setResponseSubdeviceRange = null; - Command? getCommandRequest = null; - Command? getCommandResponse = null; - Command? setCommandRequest = null; - Command? setCommandResponse = null; - if (deviceInfo.SubDeviceCount == 0) + if (parameterDescription.CommandClass.HasFlag(ERDM_CommandClass.GET)) { - if (parameterDescription.CommandClass.HasFlag(ERDM_CommandClass.GET)) + getCommandRequest = new Command(); + OneOfTypes? oneOfType = null; + LabeledIntegerType[] labeledIntegerTypes = getLabeledIntegerTypes(parameterDescription); + switch (parameterDescription.DataType) { - getRequestSubdeviceRange = new SubdevicesForRequests[] { new SubdevicesForRequests(SubdevicesForRequests.ESubdevicesForRequests.Root) }; - getResponseSubdeviceRange = new SubdevicesForResponses[] { new SubdevicesForResponses(SubdevicesForResponses.ESubdevicesForResponses.Root) }; - } - if (parameterDescription.CommandClass.HasFlag(ERDM_CommandClass.SET)) - { - setRequestSubdeviceRange = new SubdevicesForRequests[] { new SubdevicesForRequests(SubdevicesForRequests.ESubdevicesForRequests.Root) }; - setResponseSubdeviceRange = new SubdevicesForResponses[] { new SubdevicesForResponses(SubdevicesForResponses.ESubdevicesForResponses.Root) }; + case ERDM_DataType.STRING: + oneOfType = new OneOfTypes(new StringType(name, displayName, null, null, "string", null, null, 0, parameterDescription.PDLSize, null, null, true)); + break; + case ERDM_DataType.UINT8: + oneOfType = new OneOfTypes(new IntegerType(name, displayName, null, null, EIntegerType.UInt8, labeledIntegerTypes, labeledIntegerTypes != null, new Range[] { new Range((byte)parameterDescription.MinValidValue, (byte)parameterDescription.MaxValidValue) }, parameterDescription.Unit, (int)Tools.GetNormalizedValue(parameterDescription.Prefix, 1), 1)); + break; + case ERDM_DataType.INT8: + oneOfType = new OneOfTypes(new IntegerType(name, displayName, null, null, EIntegerType.Int8, labeledIntegerTypes, labeledIntegerTypes != null, new Range[] { new Range((sbyte)parameterDescription.MinValidValue, (sbyte)parameterDescription.MaxValidValue) }, parameterDescription.Unit, (int)Tools.GetNormalizedValue(parameterDescription.Prefix, 1), 1)); + break; + + case ERDM_DataType.UINT16: + oneOfType = new OneOfTypes(new IntegerType(name, displayName, null, null, EIntegerType.UInt16, labeledIntegerTypes, labeledIntegerTypes != null, new Range[] { new Range((ushort)parameterDescription.MinValidValue, (ushort)parameterDescription.MaxValidValue) }, parameterDescription.Unit, (int)Tools.GetNormalizedValue(parameterDescription.Prefix, 1), 1)); + break; + case ERDM_DataType.INT16: + oneOfType = new OneOfTypes(new IntegerType(name, displayName, null, null, EIntegerType.Int16, labeledIntegerTypes, labeledIntegerTypes != null, new Range[] { new Range((short)parameterDescription.MinValidValue, (short)parameterDescription.MaxValidValue) }, parameterDescription.Unit, (int)Tools.GetNormalizedValue(parameterDescription.Prefix, 1), 1)); + break; + default: + break; } + if (oneOfType.HasValue) + getCommandResponse = new Command(oneOfType.Value); + else + getCommandResponse = new Command(); } - - string name = parameterDescription.Description; - string displayName = getDisplayName(parameterDescription); - - if (parameterDescription.CommandClass == ERDM_CommandClass.SET) + if (parameterDescription.CommandClass.HasFlag(ERDM_CommandClass.SET)) { - setCommandRequest = new Command(); + setCommandRequest = new Command(Command.ECommandDublicate.GetResponse); setCommandResponse = new Command(); } - else - { - if (parameterDescription.CommandClass.HasFlag(ERDM_CommandClass.GET)) - { - getCommandRequest = new Command(); - OneOfTypes? oneOfType = null; - LabeledIntegerType[] labeledIntegerTypes = getLabeledIntegerTypes(parameterDescription); - switch (parameterDescription.DataType) - { - case ERDM_DataType.STRING: - oneOfType = new OneOfTypes(new StringType(name, displayName, null, null, "string", null, null, 0, parameterDescription.PDLSize, null, null, true)); - break; - case ERDM_DataType.UINT8: - oneOfType = new OneOfTypes(new IntegerType(name, displayName, null, null, EIntegerType.UInt8, labeledIntegerTypes, labeledIntegerTypes != null, new Range[] { new Range((byte)parameterDescription.MinValidValue, (byte)parameterDescription.MaxValidValue) }, parameterDescription.Unit, (int)Tools.GetNormalizedValue(parameterDescription.Prefix, 1), 1)); - break; - case ERDM_DataType.INT8: - oneOfType = new OneOfTypes(new IntegerType(name, displayName, null, null, EIntegerType.Int8, labeledIntegerTypes, labeledIntegerTypes != null, new Range[] { new Range((sbyte)parameterDescription.MinValidValue, (sbyte)parameterDescription.MaxValidValue) }, parameterDescription.Unit, (int)Tools.GetNormalizedValue(parameterDescription.Prefix, 1), 1)); - break; - - case ERDM_DataType.UINT16: - oneOfType = new OneOfTypes(new IntegerType(name, displayName, null, null, EIntegerType.UInt16, labeledIntegerTypes, labeledIntegerTypes != null, new Range[] { new Range((ushort)parameterDescription.MinValidValue, (ushort)parameterDescription.MaxValidValue) }, parameterDescription.Unit, (int)Tools.GetNormalizedValue(parameterDescription.Prefix, 1), 1)); - break; - case ERDM_DataType.INT16: - oneOfType = new OneOfTypes(new IntegerType(name, displayName, null, null, EIntegerType.Int16, labeledIntegerTypes, labeledIntegerTypes != null, new Range[] { new Range((short)parameterDescription.MinValidValue, (short)parameterDescription.MaxValidValue) }, parameterDescription.Unit, (int)Tools.GetNormalizedValue(parameterDescription.Prefix, 1), 1)); - break; - default: - break; - } - if (oneOfType.HasValue) - getCommandResponse = new Command(oneOfType.Value); - else - getCommandResponse = new Command(); - } - if (parameterDescription.CommandClass.HasFlag(ERDM_CommandClass.SET)) - { - setCommandRequest = new Command(Command.ECommandDublicate.GetResponse); - setCommandResponse = new Command(); - } - } - MetadataJSONObjectDefine define = new MetadataJSONObjectDefine( - parameterDescription.Description, - displayName, - null, - uid.ManufacturerID, - deviceInfo.DeviceModelId, - deviceInfo.SoftwareVersionId, - parameterDescription.ParameterId, - 0, - getRequestSubdeviceRange, - getResponseSubdeviceRange, - setRequestSubdeviceRange, - setResponseSubdeviceRange, - getCommandRequest, - getCommandResponse, - setCommandRequest, - setCommandResponse); - - parameterBagDefineCache.TryAdd(new ParameterBag((ERDM_Parameter)define.PID, define.ManufacturerID, define.DeviceModelID, define.SoftwareVersionID), define); } - private static string getDisplayName(RDMParameterDescription parameterDescription) + MetadataJSONObjectDefine define = new MetadataJSONObjectDefine( + parameterDescription.Description, + displayName, + null, + uid.ManufacturerID, + deviceInfo.DeviceModelId, + deviceInfo.SoftwareVersionId, + parameterDescription.ParameterId, + 0, + getRequestSubdeviceRange, + getResponseSubdeviceRange, + setRequestSubdeviceRange, + setResponseSubdeviceRange, + getCommandRequest, + getCommandResponse, + setCommandRequest, + setCommandResponse); + + parameterBagDefineCache.TryAdd(new ParameterBag((ERDM_Parameter)define.PID, define.ManufacturerID, define.DeviceModelID, define.SoftwareVersionID), define); + } + private static string getDisplayName(RDMParameterDescription parameterDescription) + { + if (parameterDescription.Description.Contains(' ') && parameterDescription.Description.Contains('=')) { - if(parameterDescription.Description.Contains(' ') && parameterDescription.Description.Contains('=')) - { - string[] parts = parameterDescription.Description.Split(' '); - string result = string.Join(' ', parts.TakeWhile(p => !p.Contains('='))); - return result; - } - return null; + string[] parts = parameterDescription.Description.Split(' '); + string result = string.Join(' ', parts.TakeWhile(p => !p.Contains('='))); + return result; } - private static LabeledIntegerType[] getLabeledIntegerTypes(RDMParameterDescription parameterDescription) + return null; + } + private static LabeledIntegerType[] getLabeledIntegerTypes(RDMParameterDescription parameterDescription) + { + List labeledIntegerTypes = new List(); + if (parameterDescription.Description.Contains(' ') && parameterDescription.Description.Contains('=')) { - List labeledIntegerTypes = new List(); - if (parameterDescription.Description.Contains(' ') && parameterDescription.Description.Contains('=')) + var parts = parameterDescription.Description.Split(' ').Where(p => p.Contains('=')); + foreach (var part in parts) { - var parts = parameterDescription.Description.Split(' ').Where(p => p.Contains('=')); - foreach (var part in parts) + string[] labelAndValue = part.Split('='); + int value = 0; + if (labelAndValue.Length == 2) { - string[] labelAndValue = part.Split('='); - int value = 0; - if (labelAndValue.Length == 2) - { - if (int.TryParse(labelAndValue[0], out value)) - labeledIntegerTypes.Add(new LabeledIntegerType(labelAndValue[1], value)); - else if (int.TryParse(labelAndValue[1], out value)) - labeledIntegerTypes.Add(new LabeledIntegerType(labelAndValue[0], value)); - } + if (int.TryParse(labelAndValue[0], out value)) + labeledIntegerTypes.Add(new LabeledIntegerType(labelAndValue[1], value)); + else if (int.TryParse(labelAndValue[1], out value)) + labeledIntegerTypes.Add(new LabeledIntegerType(labelAndValue[0], value)); } } - if (labeledIntegerTypes.Count == 0) - return null; - return labeledIntegerTypes.ToArray(); } - private static MetadataJSONObjectDefine getDefine(ParameterBag parameter) - { - var version = GetMetadataSchemaVersions().First(); - if (parameter.PID == ERDM_Parameter.QUEUED_MESSAGE) - return metadataVersionDefinesBagDictionary[version].FirstOrDefault(d => d.PID == (ushort)parameter.PID); + if (labeledIntegerTypes.Count == 0) + return null; + return labeledIntegerTypes.ToArray(); + } + private static MetadataJSONObjectDefine getDefine(ParameterBag parameter) + { + var version = GetMetadataSchemaVersions().First(); + if (parameter.PID == ERDM_Parameter.QUEUED_MESSAGE && metadataVersionDefinesBagDictionary is not null) + return metadataVersionDefinesBagDictionary[version].FirstOrDefault(d => d.PID == (ushort)parameter.PID); - fillDefaultMetadataVersionList(); - var possibleDefines = metadataVersionDefinesBagDictionary[version].FindAll(d => d.PID == (ushort)parameter.PID && d.ManufacturerID == parameter.ManufacturerID); - if (possibleDefines.Count == 1) - return possibleDefines[0]; + fillDefaultMetadataVersionList(); + var possibleDefines = metadataVersionDefinesBagDictionary[version].FindAll(d => d.PID == (ushort)parameter.PID && d.ManufacturerID == parameter.ManufacturerID); + if (possibleDefines.Count == 1) + return possibleDefines[0]; - if (possibleDefines.Count > 1) + if (possibleDefines.Count > 1) + { + MetadataJSONObjectDefine define = possibleDefines.FirstOrDefault(d => d.DeviceModelID == null && d.SoftwareVersionID == null); + if (parameter.DeviceModelID != null) { - MetadataJSONObjectDefine define = possibleDefines.FirstOrDefault(d => d.DeviceModelID == null && d.SoftwareVersionID == null); - if (parameter.DeviceModelID != null) + possibleDefines = possibleDefines.Where(d => d.DeviceModelID == parameter.DeviceModelID).ToList(); + if (possibleDefines.Count == 0) + return define; + if (possibleDefines.Count == 1) + define = possibleDefines[0]; + else if (possibleDefines.Count > 1) { - possibleDefines = possibleDefines.Where(d => d.DeviceModelID == parameter.DeviceModelID).ToList(); - if (possibleDefines.Count == 0) - return define; - if (possibleDefines.Count == 1) - define = possibleDefines[0]; - else if (possibleDefines.Count > 1) + define = possibleDefines.FirstOrDefault(d => d.SoftwareVersionID == null) ?? define; + if (parameter.SoftwareVersionID != null) { - define = possibleDefines.FirstOrDefault(d => d.SoftwareVersionID == null) ?? define; - if (parameter.SoftwareVersionID != null) - { - define = possibleDefines.FirstOrDefault(d => d.SoftwareVersionID == parameter.SoftwareVersionID) ?? define; + define = possibleDefines.FirstOrDefault(d => d.SoftwareVersionID == parameter.SoftwareVersionID) ?? define; - if (define == null) - define = possibleDefines.MinBy(d => parameter.SoftwareVersionID - d.SoftwareVersionID); - } + if (define == null) + define = possibleDefines.MinBy(d => parameter.SoftwareVersionID - d.SoftwareVersionID); } } - return possibleDefines.MaxBy(d => d.Version); } - if (parameter.ManufacturerID == 0) - throw new InvalidOperationException($"{parameter.ManufacturerID} of 0 should lead to exact 1 Define"); + return possibleDefines.MaxBy(d => d.Version); + } + if (parameter.ManufacturerID == 0) + throw new InvalidOperationException($"Parameter: {parameter}, {parameter.ManufacturerID} of 0 should lead to exact 1 Define"); - if ((ushort)parameter.PID < 0x8000 || (ushort)parameter.PID > 0xFFDF) - throw new DefineNotFoundException($"{parameter}"); - return null; + if ((ushort)parameter.PID < 0x8000 || (ushort)parameter.PID > 0xFFDF) + throw new DefineNotFoundException($"{parameter}"); + return null; + } + + internal static IEnumerable ParsePayloadToData(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType, DataTreeBranch payload) + { + define.GetCommand(commandType, out Command? _command); + if (_command is not Command command) + throw new InvalidOperationException(); + List result = new List(); + if (command.GetIsEmpty()) + { + result.Add(new byte[0]); + return result.AsReadOnly(); } - internal static IEnumerable ParsePayloadToData(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType, DataTreeBranch payload) + if (command.SingleField.HasValue && payload.Children.SingleOrDefault() is DataTree dataTree) { - define.GetCommand(commandType, out Command? _command); - if (_command is not Command command) - throw new InvalidOperationException(); - List result = new List(); - if (command.GetIsEmpty()) - { - result.Add(new byte[0]); - return result.AsReadOnly(); - } + result.AddRange(command.SingleField.Value.ParsePayloadToData(dataTree)); + return result.AsReadOnly(); + } + if (command.ListOfFields.Length != 0 && payload.Children is DataTree[] dataTreeArray) + { + if (dataTreeArray.Length != command.ListOfFields.Length) + throw new IndexOutOfRangeException(); - if (command.SingleField.HasValue && payload.Children.SingleOrDefault() is DataTree dataTree) + List data = new List(); + for (int i = 0; i < command.ListOfFields.Length; i++) { - result.AddRange(command.SingleField.Value.ParsePayloadToData(dataTree)); - return result.AsReadOnly(); - } - if (command.ListOfFields.Length != 0 && payload.Children is DataTree[] dataTreeArray) - { - if (dataTreeArray.Length != command.ListOfFields.Length) - throw new IndexOutOfRangeException(); - - List data = new List(); - for (int i = 0; i < command.ListOfFields.Length; i++) + var newData = command.ListOfFields[i].ParsePayloadToData(dataTreeArray[i]); + foreach (var nData in newData) { - var newData = command.ListOfFields[i].ParsePayloadToData(dataTreeArray[i]); - foreach(var nData in newData) + if (data.Count + nData.Length > 231) { - if (data.Count + nData.Length > 231) - { - result.Add(data.ToArray()); - data.Clear(); - } - data.AddRange(nData); + result.Add(data.ToArray()); + data.Clear(); } - //data.AddRange(newData.SelectMany(en=>en).ToArray()); + data.AddRange(nData); } - - if (data.Count != 0) - result.Add(data.ToArray()); - return result.AsReadOnly(); + //data.AddRange(newData.SelectMany(en=>en).ToArray()); } - throw new ArithmeticException(); + if (data.Count != 0) + result.Add(data.ToArray()); + return result.AsReadOnly(); } - internal static DataTreeBranch ParseDataToPayload(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType, byte[] data) - { - define.GetCommand(commandType, out Command? _command); - if (_command is not Command command) - throw new InvalidOperationException(); - try - { - if (command.GetIsEmpty()) - return DataTreeBranch.Empty; - } - catch (Exception e) - { - Logger?.LogError(e); - } - - if (command.SingleField.HasValue) - return new DataTreeBranch(define, commandType, command.SingleField.Value.ParseDataToPayload(ref data)); - - if (command.ListOfFields.Length != 0) - { - List tree = new List(); - for (int i = 0; i < command.ListOfFields.Length; i++) - tree.Add(command.ListOfFields[i].ParseDataToPayload(ref data)); - return new DataTreeBranch(define, commandType, tree.ToArray()); - } - throw new ArithmeticException(); - } - internal static IEnumerable GetRequestMessageData(ParameterBag parameter, DataTreeBranch payloadData) - { - return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.GetRequest, payloadData); - } - internal static IEnumerable GetResponseMessageData(ParameterBag parameter, DataTreeBranch payloadData) + throw new ArithmeticException(); + } + internal static DataTreeBranch ParseDataToPayload(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType, byte[] data) + { + define.GetCommand(commandType, out Command? _command); + if (_command is not Command command) + throw new InvalidOperationException(); + try { - return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.GetResponse, payloadData); + if (command.GetIsEmpty()) + return DataTreeBranch.Empty; } - internal static IEnumerable SetRequestMessageData(ParameterBag parameter, DataTreeBranch payloadData) + catch (Exception e) { - return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.SetRequest, payloadData); + Logger?.LogError(e); } - internal static IEnumerable SetResponseMessageData(ParameterBag parameter, DataTreeBranch payloadData) + + if (command.SingleField.HasValue) + return new DataTreeBranch(define, commandType, command.SingleField.Value.ParseDataToPayload(ref data)); + + if (command.ListOfFields.Length != 0) { - return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.SetResponse, payloadData); + List tree = new List(); + for (int i = 0; i < command.ListOfFields.Length; i++) + tree.Add(command.ListOfFields[i].ParseDataToPayload(ref data)); + return new DataTreeBranch(define, commandType, tree.ToArray()); } - private static List definedDataTreeObjects; - public static IReadOnlyCollection DefinedDataTreeObjects + throw new ArithmeticException(); + } + internal static IEnumerable GetRequestMessageData(ParameterBag parameter, DataTreeBranch payloadData) + { + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.GetRequest, payloadData); + } + internal static IEnumerable GetResponseMessageData(ParameterBag parameter, DataTreeBranch payloadData) + { + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.GetResponse, payloadData); + } + internal static IEnumerable SetRequestMessageData(ParameterBag parameter, DataTreeBranch payloadData) + { + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.SetRequest, payloadData); + } + internal static IEnumerable SetResponseMessageData(ParameterBag parameter, DataTreeBranch payloadData) + { + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.SetResponse, payloadData); + } + + private static List definedDataTreeObjects; + public static IReadOnlyCollection DefinedDataTreeObjects + { + get { - get - { - fillDefinedDataTreeObjects(); - return definedDataTreeObjects; - } + fillDefinedDataTreeObjects(); + return definedDataTreeObjects; } + } - private static void fillDefinedDataTreeObjects() - { - if (definedDataTreeObjects != null) - return; + private static void fillDefinedDataTreeObjects() + { + if (definedDataTreeObjects != null) + return; - definedDataTreeObjects = new List(); + definedDataTreeObjects = new List(); - definedDataTreeObjects.AddRange(Tools.FindClassesWithAttribute()); - } + definedDataTreeObjects.AddRange(Tools.FindClassesWithAttribute()); + } - public static Type GetDefinedDataTreeObjectType(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType) - { - return GetDefinedDataTreeObjectType((ERDM_Parameter)define.PID, commandType); - } - public static Type GetDefinedDataTreeObjectType(MetadataJSONObjectDefine define, ERDM_Command command) - { - Command.ECommandDublicate commandType = Tools.ConvertCommandDublicateToCommand(command); - return GetDefinedDataTreeObjectType((ERDM_Parameter)define.PID, commandType); + public static Type GetDefinedDataTreeObjectType(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType) + { + return GetDefinedDataTreeObjectType((EManufacturer)define.ManufacturerID, (ERDM_Parameter)define.PID, commandType); + } + public static Type GetDefinedDataTreeObjectType(MetadataJSONObjectDefine define, ERDM_Command command) + { + Command.ECommandDublicate commandType = Tools.ConvertCommandDublicateToCommand(command); + return GetDefinedDataTreeObjectType((EManufacturer)define.ManufacturerID, (ERDM_Parameter)define.PID, commandType); + } + public static Type GetDefinedDataTreeObjectType(EManufacturer manufacturer, ERDM_Parameter parameter, ERDM_Command command) + { + Command.ECommandDublicate commandType = Tools.ConvertCommandDublicateToCommand(command); + return GetDefinedDataTreeObjectType(manufacturer, parameter, commandType); + } + public static Type GetDefinedDataTreeObjectType(EManufacturer manufacturer, ERDM_Parameter parameter, Command.ECommandDublicate commandType) + { + bool checkManufacturer(EManufacturer attrManu) + { + if (attrManu == EManufacturer.ESTA) + return true; + + return attrManu == manufacturer; } - public static Type GetDefinedDataTreeObjectType(ERDM_Parameter parameter, ERDM_Command command) + return DefinedDataTreeObjects.Where(t => { - Command.ECommandDublicate commandType = Tools.ConvertCommandDublicateToCommand(command); - return GetDefinedDataTreeObjectType(parameter, commandType); - } - public static Type GetDefinedDataTreeObjectType(ERDM_Parameter parameter, Command.ECommandDublicate commandType) + if (t.GetCustomAttributes().Any(attribute => attribute.Parameter == parameter && attribute.Command == commandType && checkManufacturer(attribute.Manufacturer))) + return true; + return false; + }).FirstOrDefault(); + } + + public static async Task AwaitInitialize() + { + while (!IsInitialized) { - return DefinedDataTreeObjects.Where(t => - { - if (t.GetCustomAttributes().Any(attribute => attribute.Parameter == parameter && attribute.Command == commandType)) - return true; - return false; - }).FirstOrDefault(); + GetMetadataDefineVersions(); + await Task.Delay(100); } } } diff --git a/RDMSharp/RDM/AsyncRDMRequestHelper.cs b/RDMSharp/RDM/AsyncRDMRequestHelper.cs index b73e7456..7d2bf7b1 100644 --- a/RDMSharp/RDM/AsyncRDMRequestHelper.cs +++ b/RDMSharp/RDM/AsyncRDMRequestHelper.cs @@ -1,244 +1,245 @@ using Microsoft.Extensions.Logging; using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -namespace RDMSharp -{ - public class AsyncRDMRequestHelper : IDisposable +namespace RDMSharp; + +public class AsyncRDMRequestHelper : IDisposable +{ + private static readonly ILogger Logger = Logging.CreateLogger(); + private static readonly Random random = new Random(); + private readonly ConcurrentDictionary buffer = new ConcurrentDictionary(); + private readonly Func _sendMethode; + private CancellationTokenSource _cts; + public bool IsDisposing, IsDisposed; + public AsyncRDMRequestHelper(Func sendMethode) { - private static readonly ILogger Logger = Logging.CreateLogger(); - private static readonly Random random = new Random(); - private readonly ConcurrentDictionary buffer = new ConcurrentDictionary(); - private readonly Func _sendMethode; - private CancellationTokenSource _cts; - public bool IsDisposing, IsDisposed; - public AsyncRDMRequestHelper(Func sendMethode) - { - _cts = new CancellationTokenSource(); - _sendMethode = sendMethode; - } + _cts = new CancellationTokenSource(); + _sendMethode = sendMethode; + } - public void Dispose() - { - if (this.IsDisposing || this.IsDisposed) - return; - this.IsDisposing = true; - _cts.Cancel(); - buffer.Clear(); - _cts.Dispose(); - this.IsDisposed = true; - this.IsDisposing = false; - } + public void Dispose() + { + if (this.IsDisposing || this.IsDisposed) + return; + this.IsDisposing = true; + _cts.Cancel(); + buffer.Clear(); + _cts.Dispose(); + this.IsDisposed = true; + this.IsDisposing = false; + } - public bool ReceiveMessage(RDMMessage rdmMessage) + public bool ReceiveMessage(RDMMessage rdmMessage) + { + if (this.IsDisposing || this.IsDisposed) + return false; + + if (rdmMessage.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE) { - if (this.IsDisposing || this.IsDisposed) + var o = buffer.FirstOrDefault(b => b.Value.Request.Parameter == rdmMessage.Parameter); + if (o.Value == null) return false; - if (rdmMessage.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE) + updateBag(o.Value, rdmMessage); + return true; + } + //By Key + var key = generateKey(rdmMessage); + if (buffer.TryGetValue(key, out AsyncBufferBag bag)) + if (checkNonQueued(bag.Request, rdmMessage)) { - var o = buffer.FirstOrDefault(b => b.Value.Request.Parameter == rdmMessage.Parameter); - if (o.Value == null) - return false; - - updateBag(o.Value, rdmMessage); + updateBag(bag, rdmMessage); return true; } - //By Key - var key = generateKey(rdmMessage); - if (buffer.TryGetValue(key, out AsyncBufferBag bag)) - if (checkNonQueued(bag.Request, rdmMessage)) - { - updateBag(bag, rdmMessage); - return true; - } - //None Queued Parameters - var obj = buffer.Where(b => b.Value.Request.Parameter != ERDM_Parameter.QUEUED_MESSAGE).FirstOrDefault(b => b.Value.Response == null && checkNonQueued(b.Value.Request, rdmMessage)); - if (obj.Value != null) - { - updateBag(obj.Value, rdmMessage); - return true; - } - //Queued Parameters - obj = buffer.Where(b => b.Value.Request.Parameter == ERDM_Parameter.QUEUED_MESSAGE).FirstOrDefault(b => b.Value.Response == null && checkQueued(b.Value.Request, rdmMessage)); - if (obj.Value != null) - { - updateBag(obj.Value, rdmMessage); - return true; - } + //None Queued Parameters + var obj = buffer.Where(b => b.Value.Request.Parameter != ERDM_Parameter.QUEUED_MESSAGE).FirstOrDefault(b => b.Value.Response == null && checkNonQueued(b.Value.Request, rdmMessage)); + if (obj.Value != null) + { + updateBag(obj.Value, rdmMessage); + return true; + } + //Queued Parameters + obj = buffer.Where(b => b.Value.Request.Parameter == ERDM_Parameter.QUEUED_MESSAGE).FirstOrDefault(b => b.Value.Response == null && checkQueued(b.Value.Request, rdmMessage)); + if (obj.Value != null) + { + updateBag(obj.Value, rdmMessage); + return true; + } - void updateBag(AsyncBufferBag bag, RDMMessage response) - { - bag.SetResponse(response); - buffer.AddOrUpdate(bag.Key, bag, (key, oldValue) => bag); - } - return false; + void updateBag(AsyncBufferBag bag, RDMMessage response) + { + bag.SetResponse(response); + buffer.AddOrUpdate(bag.Key, bag, (key, oldValue) => bag); + } + return false; - bool checkNonQueued(RDMMessage request, RDMMessage response) - { - if (request.Parameter != response.Parameter) - return false; - if (request.TransactionCounter != response.TransactionCounter) - return false; - if (request.SubDevice != response.SubDevice) - return false; - if (request.SourceUID != response.DestUID) - return false; - if (request.DestUID != response.SourceUID) - return false; - if ((request.Command | ERDM_Command.RESPONSE) != response.Command) - return false; + bool checkNonQueued(RDMMessage request, RDMMessage response) + { + if (request.Parameter != response.Parameter) + return false; + if (request.TransactionCounter != response.TransactionCounter) + return false; + if (request.SubDevice != response.SubDevice) + return false; + if (request.SourceUID != response.DestUID) + return false; + if (request.DestUID != response.SourceUID) + return false; + if ((request.Command | ERDM_Command.RESPONSE) != response.Command) + return false; - return true; - } - bool checkQueued(RDMMessage request, RDMMessage response) - { - if (request.TransactionCounter != response.TransactionCounter) - return false; - if (request.SubDevice != response.SubDevice) - return false; - if (request.SourceUID != response.DestUID) - return false; - if (request.DestUID != response.SourceUID) - return false; - if ((request.Command | ERDM_Command.RESPONSE) != response.Command) - return false; + return true; + } + bool checkQueued(RDMMessage request, RDMMessage response) + { + if (request.TransactionCounter != response.TransactionCounter) + return false; + if (request.SubDevice != response.SubDevice) + return false; + if (request.SourceUID != response.DestUID) + return false; + if (request.DestUID != response.SourceUID) + return false; - return true; - } + return true; } + } - public async Task RequestMessage(RDMMessage request, bool setTransactionCounter=true) + public async Task RequestMessage(RDMMessage request, bool setTransactionCounter = true) + { + try { - try + if (setTransactionCounter) + request.TransactionCounter = RDMSharp.Instance.getTransactionCounter(request.DestUID); + int key = generateKey(request); + if (request.SubDevice.IsBroadcast) { - if (setTransactionCounter) - request.TransactionCounter = RDMSharp.Instance.getTransactionCounter(request.DestUID); - int key = generateKey(request); - if (request.SubDevice.IsBroadcast) + Logger?.LogTrace($"Send Subdevice-Broadcast Request: {request?.ToString()}"); + await _sendMethode.Invoke(request); + return new RequestResult(request, null, TimeSpan.Zero); // Broadcasts are not expected to return a response. + } + if (!buffer.TryAdd(key, new AsyncBufferBag(key, request))) + { + key += random.Next(); + buffer.TryAdd(key, new AsyncBufferBag(key, request)); + } + RDMMessage response = null; + Logger?.LogTrace($"Send Request: {request?.ToString()}"); + await _sendMethode.Invoke(request); + int count = 0; + do + { + if (this.IsDisposing || this.IsDisposed) + return new RequestResult(request, disposing: true); + + buffer.TryGetValue(key, out AsyncBufferBag bag); + response = bag?.Response; + if (response != null) + break; + if (request.Command != ERDM_Command.DISCOVERY_COMMAND) + await Task.Delay(5, _cts.Token); + else + await Task.Delay(GlobalTimers.Instance.DiscoveryTimeout, _cts.Token); + if (request.Command == ERDM_Command.NONE) { - Logger?.LogTrace($"Send Subdevice-Broadcast Request: {request?.ToString()}"); - await _sendMethode.Invoke(request); - return new RequestResult(request, null, TimeSpan.Zero); // Broadcasts are not expected to return a response. + throw new Exception("Command is not set"); } - if (!buffer.TryAdd(key, new AsyncBufferBag(key, request))) + count++; + if (count % 300 == 299) { - key += random.Next(); - buffer.TryAdd(key, new AsyncBufferBag(key, request)); + await Task.Delay(TimeSpan.FromTicks(random.Next(33, 777)), _cts.Token); + Logger?.LogTrace($"Retry Request: {request?.ToString()} ElapsedTime: {bag?.ElapsedTime}"); + await _sendMethode.Invoke(request); + await Task.Delay(TimeSpan.FromTicks(random.Next(33, 777)), _cts.Token); } - RDMMessage response = null; - Logger?.LogTrace($"Send Request: {request?.ToString()}"); - await _sendMethode.Invoke(request); - int count = 0; - do + if (count > 3 && request.Command == ERDM_Command.DISCOVERY_COMMAND) { - if (this.IsDisposing || this.IsDisposed) - return new RequestResult(request); - - buffer.TryGetValue(key, out AsyncBufferBag bag); - response = bag?.Response; - if (response != null) - break; - if (request.Command != ERDM_Command.DISCOVERY_COMMAND) - await Task.Delay(5, _cts.Token); - else - await Task.Delay(GlobalTimers.Instance.DiscoveryTimeout, _cts.Token); - if (request.Command == ERDM_Command.NONE) - { - throw new Exception("Command is not set"); - } - count++; - if (count % 300 == 299) - { - await Task.Delay(TimeSpan.FromTicks(random.Next(33, 777)), _cts.Token); - Logger?.LogTrace($"Retry Request: {request?.ToString()} ElapsedTime: {bag?.ElapsedTime}"); - await _sendMethode.Invoke(request); - await Task.Delay(TimeSpan.FromTicks(random.Next(33, 777)), _cts.Token); - } - if (count > 3 && request.Command == ERDM_Command.DISCOVERY_COMMAND) - { - Logger?.LogTrace($"Discovery request exceeded timeout"); - break; - } + Logger?.LogTrace($"Discovery request exceeded timeout"); + break; + } - if (count >= 900) - { - Logger?.LogTrace($"Timeout Request: {request?.ToString()} ElapsedTime: {bag?.ElapsedTime}"); - return new RequestResult(request); - } + if (count >= 900) + { + Logger?.LogTrace($"Timeout Request: {request?.ToString()} ElapsedTime: {bag?.ElapsedTime}"); + return new RequestResult(request, timeout: true); } - while (response == null); - buffer.TryRemove(key, out AsyncBufferBag bag2); - response = bag2.Response; - var result = new RequestResult(request, response, bag2.ElapsedTime); - Logger?.LogTrace($"Successful Request: {request?.ToString()} Response: {response?.ToString()} ElapsedTime: {bag2?.ElapsedTime}"); - return result; } - catch (Exception ex) - { - Logger?.LogError(ex); - } - return new RequestResult(request); + while (response == null); + buffer.TryRemove(key, out AsyncBufferBag bag2); + response = bag2.Response; + var result = new RequestResult(request, response, bag2.ElapsedTime); + Logger?.LogTrace($"Successful Request: {request?.ToString()} Response: {response?.ToString()} ElapsedTime: {bag2?.ElapsedTime}"); + return result; } - private int generateKey(RDMMessage request) - { - var command = (ERDM_Command)((byte)request.Command & ~(byte)ERDM_Command.RESPONSE); - if (command == ERDM_Command.DISCOVERY_COMMAND) - return random.Next(); + catch (TimeoutException) + { + Logger?.LogInformation($"Timeout Exception Request: {request}"); + return new RequestResult(request, timeout: true); + } + catch (Exception ex) + { + Logger?.LogError(ex); + } + return new RequestResult(request); + } + private int generateKey(RDMMessage request) + { + var command = (ERDM_Command)((byte)request.Command & ~(byte)ERDM_Command.RESPONSE); + if (command == ERDM_Command.DISCOVERY_COMMAND) + return random.Next(); - int key = (request.SourceUID.GetHashCode() + request.DestUID.GetHashCode())*111111111 - + (9 + request.SubDevice.GetHashCode()) * 45123 - + (123 + request.TransactionCounter.GetHashCode()) * 931 - + request.Parameter.GetHashCode()*67 - + command.GetHashCode()*7; - return key; - } + int key = (request.SourceUID.GetHashCode() + request.DestUID.GetHashCode()) * 111111111 + + (9 + request.SubDevice.GetHashCode()) * 45123 + + (123 + request.TransactionCounter.GetHashCode()) * 931 + + request.Parameter.GetHashCode() * 67 + + command.GetHashCode() * 7; + return key; + } - private class AsyncBufferBag - { - public readonly int Key; - - public readonly RDMMessage Request; - public readonly DateTime RequestTimestamp; + private class AsyncBufferBag + { + public readonly int Key; - public RDMMessage Response { get; private set; } - public DateTime? ResponseTimestamp { get; private set; } + public readonly RDMMessage Request; + public readonly DateTime RequestTimestamp; - private TimeSpan? elapsedTime; - public TimeSpan ElapsedTime - { - get - { - if (elapsedTime.HasValue) - return elapsedTime.Value; + public RDMMessage Response { get; private set; } + public DateTime? ResponseTimestamp { get; private set; } - return DateTime.UtcNow - RequestTimestamp; ; - } - private set - { - elapsedTime = value; - } - } - - public AsyncBufferBag(int key, RDMMessage request) - { - Request = request; - Response = null; - Key = key; - RequestTimestamp = DateTime.UtcNow; - } - public void SetResponse(RDMMessage response) + private TimeSpan? elapsedTime; + public TimeSpan ElapsedTime + { + get { - Response = response; - ResponseTimestamp = DateTime.UtcNow; - ElapsedTime = ResponseTimestamp.Value - RequestTimestamp; + if (elapsedTime.HasValue) + return elapsedTime.Value; + + return DateTime.UtcNow - RequestTimestamp; ; } + private set + { + elapsedTime = value; + } + } + + public AsyncBufferBag(int key, RDMMessage request) + { + Request = request; + Response = null; + Key = key; + RequestTimestamp = DateTime.UtcNow; + } + public void SetResponse(RDMMessage response) + { + Response = response; + ResponseTimestamp = DateTime.UtcNow; + ElapsedTime = ResponseTimestamp.Value - RequestTimestamp; } - } + } } \ No newline at end of file diff --git a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs index 282532e0..ccf32f10 100644 --- a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs @@ -1,5 +1,7 @@ using Microsoft.Extensions.Logging; using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -10,824 +12,531 @@ using static RDMSharp.RDMSharp; [assembly: InternalsVisibleTo("RDMSharpTests")] -namespace RDMSharp +namespace RDMSharp; + +public abstract class AbstractGeneratedRDMDevice : AbstractRDMDevice { - public abstract class AbstractGeneratedRDMDevice : AbstractRDMDevice + public sealed override bool IsGenerated => true; + public abstract bool SupportQueued { get; } + + private HashSet _parameters; + public IReadOnlySet Parameters { - public sealed override bool IsGenerated => true; - public abstract bool SupportQueued { get; } - public abstract bool SupportStatus { get; } - public virtual bool SupportRealTimeClock { get; } - #region DeviceInfoStuff - private HashSet _parameters; - public IReadOnlySet Parameters { get => _parameters; } - public abstract EManufacturer ManufacturerID { get; } - public abstract ushort DeviceModelID { get; } - public abstract ERDM_ProductCategoryCoarse ProductCategoryCoarse { get; } - public abstract ERDM_ProductCategoryFine ProductCategoryFine { get; } - public abstract uint SoftwareVersionID { get; } - #endregion - public abstract string DeviceModelDescription { get; } - public abstract GeneratedPersonality[] Personalities { get; } - - private readonly ConcurrentDictionary sensors = new ConcurrentDictionary(); - public sealed override IReadOnlyDictionary Sensors { get { return sensors.AsReadOnly(); } } - private ConcurrentDictionary sensorDef; - private ConcurrentDictionary sensorValue; - - public sealed override IReadOnlyDictionary Slots { get { return CurrentPersonality.HasValue ? Personalities?.FirstOrDefault(p => p.ID.Equals(CurrentPersonality.Value))?.Slots : null; } } - - private ConcurrentDictionary statusMessages = new ConcurrentDictionary(); - public sealed override IReadOnlyDictionary StatusMessages { get { return statusMessages.AsReadOnly(); } } - private ConcurrentDictionary controllerCommunicationCache = new ConcurrentDictionary(); - public abstract bool SupportDMXAddress { get; } - - private RDMDeviceInfo deviceInfo; - public sealed override RDMDeviceInfo DeviceInfo { get { return deviceInfo; } } - - private ConcurrentDictionary overflowCacheBags = new ConcurrentDictionary(); - - private ushort dmxAddress { get; set; } - public ushort? DMXAddress + get => _parameters; + private set { - get - { - if (!this.Parameters.Contains(ERDM_Parameter.DMX_START_ADDRESS)) - return null; - - return dmxAddress; - } - set - { - if (!this.Parameters.Contains(ERDM_Parameter.DMX_START_ADDRESS)) - { - dmxAddress = 0; - return; - } - if (!value.HasValue) - throw new NullReferenceException($"{DMXAddress} can't be null if {ERDM_Parameter.DMX_START_ADDRESS} is Supported"); - if (value.Value == 0) - throw new ArgumentOutOfRangeException($"{DMXAddress} can't 0 if {ERDM_Parameter.DMX_START_ADDRESS} is Supported"); + if (_parameters == value) + return; + _parameters = value.ToHashSet(); + this.OnPropertyChanged(); + } + } - if (dmxAddress == value.Value) - return; + #region DeviceInfoStuff + public abstract EManufacturer ManufacturerID { get; } + public abstract ushort DeviceModelID { get; } + public abstract ERDM_ProductCategoryCoarse ProductCategoryCoarse { get; } + public abstract ERDM_ProductCategoryFine ProductCategoryFine { get; } - dmxAddress = value.Value; - this.OnPropertyChanged(nameof(this.DMXAddress)); - this.updateDeviceInfo(); - } + public uint SoftwareVersionID + { + get + { + var softwareVersionModule = this.Modules.OfType().FirstOrDefault(); + return softwareVersionModule?.SoftwareVersionId ?? 0; } - public readonly string ManufacturerLabel; + } + public IReadOnlyCollection Personalities { get { return dmxPersonalityModule?.Personalities.OfType().ToList().AsReadOnly() ?? Array.Empty().AsReadOnly(); } } + public sealed override IReadOnlyDictionary Sensors { get { return sensorsModule?.Sensors; } } + public sealed override IReadOnlyDictionary Slots { get { return slotsModule?.Slots; } } + public sealed override RDMDeviceInfo DeviceInfo { get { return deviceInfoModule?.DeviceInfo; } } - private string deviceLabel; - public string DeviceLabel + public ushort? DMXAddress + { + get { - get - { - return deviceLabel; - } - set - { - if (string.Equals(deviceLabel, value)) - return; + if (dmxStartAddressModule is null) + return null; - deviceLabel = value; - this.OnPropertyChanged(nameof(this.DeviceLabel)); - } + return dmxStartAddressModule.DMXAddress; } - - private byte currentPersonality; - public byte? CurrentPersonality + set { - get - { - if (!this.Parameters.Contains(ERDM_Parameter.DMX_PERSONALITY)) - return null; - - return currentPersonality; - } - set - { - if (!this.Parameters.Contains(ERDM_Parameter.DMX_PERSONALITY)) - { - currentPersonality = 0; - return; - } - if (!value.HasValue) - throw new NullReferenceException($"{CurrentPersonality} can't be null if {ERDM_Parameter.DMX_PERSONALITY} is Supported"); - if (value.Value == 0) - throw new ArgumentOutOfRangeException($"{CurrentPersonality} can't 0 if {ERDM_Parameter.DMX_PERSONALITY} is Supported"); - - if (!this.Personalities.Any(p => p.ID == value.Value)) - throw new ArgumentOutOfRangeException($"No Personality found with ID: {value.Value}"); - - if (currentPersonality == value) - return; + if (dmxStartAddressModule is null) + return; + if (dmxStartAddressModule.DMXAddress == value) + return; - currentPersonality = value.Value; - this.OnPropertyChanged(nameof(this.CurrentPersonality)); - this.updateDeviceInfo(); - } + dmxStartAddressModule.DMXAddress = value; + this.OnPropertyChanged(nameof(this.DMXAddress)); } - private bool discoveryMuted; - public bool DiscoveryMuted + } + + public byte? CurrentPersonalityId + { + get { - get - { - return discoveryMuted; - } - private set - { - if (discoveryMuted == value) - return; - discoveryMuted = value; - OnPropertyChanged(nameof(DiscoveryMuted)); - } + return dmxPersonalityModule.CurrentPersonality.ID; } - - private bool identify; - public bool Identify + set { - get - { - return identify; - } - set - { - if (string.Equals(identify, value)) - return; + if (dmxPersonalityModule is null) + return; + if (dmxPersonalityModule.CurrentPersonality.ID == value) + return; - identify = value; - this.OnPropertyChanged(nameof(this.Identify)); - } + Task.Run(async () => + { + await dmxPersonalityModule.SetPersonality(value.Value); + this.OnPropertyChanged(nameof(this.CurrentPersonalityId)); + }).GetAwaiter().GetResult(); } + } + #endregion + public sealed override IReadOnlyDictionary StatusMessages { get { return statusMessageModule?.StatusMessages; } } - private string softwareVersionLabel; - public string SoftwareVersionLabel - { - get - { - return softwareVersionLabel; - } - protected set - { - if (string.Equals(softwareVersionLabel, value)) - return; - - softwareVersionLabel = value; - this.OnPropertyChanged(nameof(this.SoftwareVersionLabel)); - } - } + private ConcurrentDictionary controllerCommunicationCache = new ConcurrentDictionary(); + private ConcurrentDictionary overflowCacheBags = new ConcurrentDictionary(); - private string bootSoftwareVersionLabel; - public string BootSoftwareVersionLabel - { - get - { - return bootSoftwareVersionLabel; - } - protected set - { - if (string.Equals(bootSoftwareVersionLabel, value)) - return; + private readonly IReadOnlyCollection _modules; + public IReadOnlyCollection Modules { get => _modules; } - bootSoftwareVersionLabel = value; - this.OnPropertyChanged(nameof(this.BootSoftwareVersionLabel)); - } - } + protected readonly DeviceInfoModule deviceInfoModule; + protected readonly IdentifyDeviceModule identifyDeviceModule; + protected readonly DMX_StartAddressModule? dmxStartAddressModule; + protected readonly DMX_PersonalityModule? dmxPersonalityModule; + protected readonly SlotsModule? slotsModule; + protected readonly SensorsModule? sensorsModule; + protected readonly StatusMessagesModule? statusMessageModule; - public DateTime realTimeClock; - public DateTime RealTimeClock + private bool discoveryMuted; + public bool DiscoveryMuted + { + get { - get - { - return realTimeClock; - } - private set - { - if (DateTime.Equals(realTimeClock, value)) - return; - - realTimeClock = value; - this.OnPropertyChanged(nameof(this.RealTimeClock)); - } + return discoveryMuted; } - - private bool _initialized = false; - - protected AbstractGeneratedRDMDevice(UID uid, ERDM_Parameter[] parameters, string manufacturer = null, Sensor[] sensors = null, IRDMDevice[] subDevices = null) : this(uid, SubDevice.Root, parameters, manufacturer, sensors, subDevices) + private set { + if (discoveryMuted == value) + return; + discoveryMuted = value; + OnPropertyChanged(nameof(DiscoveryMuted)); } - protected AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[] parameters, string manufacturer = null, Sensor[] sensors = null) : this(uid, subDevice, parameters, manufacturer, sensors, null) + } + + public bool Identify + { + get { + return identifyDeviceModule.Identify; } - private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[] parameters, string manufacturer = null, Sensor[] sensors = null, IRDMDevice[] subDevices = null) : base(uid, subDevice, subDevices) + set { - if (!((ushort)ManufacturerID).Equals(uid.ManufacturerID)) - throw new Exception($"{uid.ManufacturerID} not match the {ManufacturerID}"); - - RDMSharp.Instance.RequestReceivedEvent += Instance_RequestReceivedEvent; - - #region Parameters - var _params = new HashSet(); - if (parameters != null && parameters.Length != 0) - foreach (var p in parameters) - _params.Add(p); + if (string.Equals(identifyDeviceModule.Identify, value)) + return; - if (SupportQueued) - _params.Add(ERDM_Parameter.QUEUED_MESSAGE); - if (SupportStatus) - { - _params.Add(ERDM_Parameter.STATUS_MESSAGES); - _params.Add(ERDM_Parameter.CLEAR_STATUS_ID); - } + identifyDeviceModule.Identify = value; + this.OnPropertyChanged(); + } + } - _params.Add(ERDM_Parameter.DEVICE_INFO); - _params.Add(ERDM_Parameter.SUPPORTED_PARAMETERS); - _params.Add(ERDM_Parameter.SOFTWARE_VERSION_LABEL); - _params.Add(ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID); - _params.Add(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL); - _params.Add(ERDM_Parameter.DEVICE_LABEL); - _params.Add(ERDM_Parameter.DEVICE_MODEL_DESCRIPTION); - _params.Add(ERDM_Parameter.MANUFACTURER_LABEL); - _params.Add(ERDM_Parameter.IDENTIFY_DEVICE); - if (SupportRealTimeClock) - _params.Add(ERDM_Parameter.REAL_TIME_CLOCK); - if (SupportDMXAddress) - _params.Add(ERDM_Parameter.DMX_START_ADDRESS); - if ((Personalities?.Length ?? 0) != 0) - { - _params.Add(ERDM_Parameter.DMX_PERSONALITY); - _params.Add(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION); - _params.Add(ERDM_Parameter.SLOT_INFO); - _params.Add(ERDM_Parameter.SLOT_DESCRIPTION); - _params.Add(ERDM_Parameter.DEFAULT_SLOT_VALUE); - } + private bool _initialized = false; - _parameters = _params; - if (SupportRealTimeClock) - trySetParameter(ERDM_Parameter.REAL_TIME_CLOCK, new RDMRealTimeClock(DateTime.Now)); - trySetParameter(ERDM_Parameter.SUPPORTED_PARAMETERS, Parameters.ToArray()); - trySetParameter(ERDM_Parameter.IDENTIFY_DEVICE, Identify); - #endregion + protected AbstractGeneratedRDMDevice(UID uid, IRDMDevice[] subDevices = null, IReadOnlyCollection modules = null) : this(uid, SubDevice.Root, subDevices, modules) + { + } + protected AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, IReadOnlyCollection modules = null) : this(uid, subDevice, null, modules) + { + } + private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, IRDMDevice[] subDevices = null, IReadOnlyCollection modules = null) : base(uid, subDevice, subDevices) + { + if (!((ushort)ManufacturerID).Equals(uid.ManufacturerID)) + throw new Exception($"{uid.ManufacturerID} not match the {ManufacturerID}"); - #region ManufacturerLabel - string _manufacturer = Enum.GetName(typeof(EManufacturer), (EManufacturer)uid.ManufacturerID); + RDMSharp.Instance.RequestReceivedEvent += Instance_RequestReceivedEvent; - if (string.IsNullOrWhiteSpace(_manufacturer)) - _manufacturer = manufacturer; - if (string.IsNullOrWhiteSpace(_manufacturer)) - throw new ArgumentNullException($"{manufacturer} not set, needed in case the Manufacturer is not Part of {typeof(EManufacturer).Name}"); + List moduleList = new List(); + identifyDeviceModule = new IdentifyDeviceModule(); + moduleList.Add(identifyDeviceModule); - ManufacturerLabel = _manufacturer; - this.OnPropertyChanged(nameof(this.ManufacturerLabel)); - #endregion + if (modules is not null) + moduleList.AddRange(modules); - #region DeviceModelDescription - this.OnPropertyChanged(nameof(this.DeviceModelDescription)); - #endregion + deviceInfoModule = new DeviceInfoModule(); + moduleList.Add(deviceInfoModule); + _modules = moduleList.AsReadOnly(); + dmxStartAddressModule = _modules.OfType().FirstOrDefault(); + dmxPersonalityModule = _modules.OfType().FirstOrDefault(); + slotsModule = _modules.OfType().FirstOrDefault(); + sensorsModule = _modules.OfType().FirstOrDefault(); + statusMessageModule = _modules.OfType().FirstOrDefault(); + if (dmxPersonalityModule is not null)//Remove after Refactoring to Modules + dmxPersonalityModule.PropertyChanged += DmxPersonalityModule_PropertyChanged; - #region DeviceLabel - this.DeviceLabel = this.DeviceModelDescription; - #endregion + var _params = new HashSet(); - #region Personalities - if (Personalities != null) - { - if (Personalities.Length >= byte.MaxValue) - throw new ArgumentOutOfRangeException($"There to many {Personalities}! Maximum is {byte.MaxValue - 1}"); + if (SupportQueued) + _params.Add(ERDM_Parameter.QUEUED_MESSAGE); - if (Personalities.Length != 0) - { - var persDesc = new ConcurrentDictionary(); - foreach (var gPers in Personalities) - if (!persDesc.TryAdd(gPers.ID, (RDMDMXPersonalityDescription)gPers)) - throw new Exception($"{gPers.ID} already used as {nameof(gPers.ID)}"); + _params.Add(ERDM_Parameter.SUPPORTED_PARAMETERS); - trySetParameter(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, persDesc); - } - CurrentPersonality = 1; - } - #endregion + foreach (IModule module in _modules) + foreach (var parameter in module.SupportedParameters) + _params.Add(parameter); - #region Sensors + Parameters = _params; - if (sensors != null) - this.AddSensors(sensors); + foreach (IModule module in _modules) + if (module is AbstractModule aModule) + aModule.SetGeneratedParentDevice(this); - #endregion + trySetParameter(ERDM_Parameter.SUPPORTED_PARAMETERS, Parameters.ToArray()); - #region StatusMessage - if (SupportStatus) - trySetParameter(ERDM_Parameter.STATUS_MESSAGES, new RDMStatusMessage[0]); - #endregion + _initialized = true; + } - #region DMX-Address - if (Parameters.Contains(ERDM_Parameter.DMX_START_ADDRESS)) - DMXAddress = 1; - #endregion + private void DmxPersonalityModule_PropertyChanged(object sender, PropertyChangedEventArgs e)//Remove after Refactoring to Modules + { + OnPropertyChanged(e.PropertyName); + } - #region RealTimeClock - if (Parameters.Contains(ERDM_Parameter.REAL_TIME_CLOCK)) - Task.Run(async () => - { - - while (true) - { - double last = 0; - await Task.Delay(100); - var dateTime = DateTime.UtcNow.TimeOfDay.TotalSeconds; - if (Math.Abs(dateTime - last) > 1) - { - last = dateTime; - RealTimeClock = DateTime.Now; - } - } - }); - #endregion + protected bool trySetParameter(ERDM_Parameter parameter, object value) + { + if (!this.Parameters.Contains(parameter)) + throw new NotSupportedException($"The Parameter: {parameter}, is not Supported"); - updateDeviceInfo(); - _initialized = true; - } + setParameterValue(parameter, value); + return true; + } + public bool TrySetParameter(ERDM_Parameter parameter, object value, bool throwException = true) + { - private void updateDeviceInfo() + if (!this.Parameters.Contains(parameter)) { - var info = new RDMDeviceInfo(1, - 0, - DeviceModelID, - ProductCategoryCoarse, - ProductCategoryFine, - SoftwareVersionID, - dmx512Footprint: Personalities.FirstOrDefault(p => p.ID == currentPersonality)?.SlotCount ?? 0, - dmx512CurrentPersonality: currentPersonality, - dmx512NumberOfPersonalities: (byte)(Personalities?.Length ?? 0), - dmx512StartAddress: dmxAddress, - subDeviceCount: (ushort)(SubDevices?.Where(sd=>!sd.Subdevice.IsRoot).Count() ?? 0), - sensorCount: (byte)(Sensors?.Count ?? 0)); - updateDeviceInfo(info); + if (throwException) + throw new NotSupportedException($"The Device not support the Parameter: {parameter}"); + return false; } - private void updateDeviceInfo(RDMDeviceInfo value) + switch (parameter) { - if (RDMDeviceInfo.Equals(deviceInfo, value)) - return; + case ERDM_Parameter.DMX_START_ADDRESS: + case ERDM_Parameter.DEVICE_LABEL: + if (throwException) + throw new NotSupportedException($"You have no permission to set the Parameter: {parameter}, use the public Propertys to set them"); + return false; - deviceInfo = value; - this.OnPropertyChanged(nameof(this.DeviceInfo)); + case ERDM_Parameter.DEVICE_INFO: + case ERDM_Parameter.DEVICE_MODEL_DESCRIPTION: + case ERDM_Parameter.MANUFACTURER_LABEL: + case ERDM_Parameter.QUEUED_MESSAGE: + case ERDM_Parameter.SUPPORTED_PARAMETERS: + case ERDM_Parameter.SLOT_DESCRIPTION: + case ERDM_Parameter.SLOT_INFO: + case ERDM_Parameter.DEFAULT_SLOT_VALUE: + case ERDM_Parameter.SENSOR_DEFINITION: + case ERDM_Parameter.SENSOR_VALUE: + if (throwException) + throw new NotSupportedException($"The Protocoll not allow to set the Parameter: {parameter}"); + return false; } - protected void AddSensors(params Sensor[] @sensors) + var parameterBag = new ParameterBag(parameter, UID.ManufacturerID, DeviceInfo?.DeviceModelId, DeviceInfo?.SoftwareVersionId); + var define = MetadataFactory.GetDefine(parameterBag); + if (define != null) { - if (sensors == null) - throw new ArgumentNullException(); - - if (sensorDef is null) - sensorDef = new ConcurrentDictionary(); - if (sensorValue is null) - sensorValue = new ConcurrentDictionary(); - foreach (var sensor in @sensors) + if (!define.SetRequest.HasValue) { - if (sensor == null) - throw new ArgumentNullException(nameof(sensor)); - if (this.sensors.ContainsKey(sensor.SensorId)) - throw new ArgumentOutOfRangeException($"The Sensor with the ID: {sensor.SensorId} already exists"); + if (throwException) + throw new NotSupportedException($"The Protocoll not allow to set the Parameter: {parameter}"); + return false; + } - if (this.sensors.TryAdd(sensor.SensorId, sensor)) + try + { + if (!define.SetRequest.HasValue) + throw new NotSupportedException($"The Protocoll not allow to set the Parameter: {parameter}"); + else { - if (!sensorDef.TryAdd(sensor.SensorId, (RDMSensorDefinition)sensor)) - throw new Exception($"{sensor.SensorId} already used as {nameof(RDMSensorDefinition)}"); - - if (!sensorValue.TryAdd(sensor.SensorId, (RDMSensorValue)sensor)) - throw new Exception($"{sensor.SensorId} already used as {nameof(RDMSensorValue)}"); - - sensor.PropertyChanged += Sensor_PropertyChanged; + byte[] data = MetadataFactory.ParsePayloadToData(define, Metadata.JSON.Command.ECommandDublicate.SetRequest, DataTreeBranch.FromObject(value, null, parameterBag, ERDM_Command.SET_COMMAND)).First(); + var obj = MetadataFactory.ParseDataToPayload(define, Metadata.JSON.Command.ECommandDublicate.SetRequest, data); + if (!object.Equals(value, obj)) + return false; } } - - var _sensors = Sensors.Values.ToArray(); - if (_sensors.Length >= byte.MaxValue) - throw new ArgumentOutOfRangeException($"There to many {Sensors}! Maximum is {byte.MaxValue - 1}"); - if (_sensors.Length > 0) + catch (Exception e) { - if (_sensors.Min(s => s.SensorId) != 0) - throw new ArgumentOutOfRangeException($"The first Sensor should have the ID: 0, but is({_sensors.Min(s => s.SensorId)})"); - if (_sensors.Max(s => s.SensorId) + 1 != _sensors.Length) - throw new ArgumentOutOfRangeException($"The last Sensor should have the ID: {_sensors.Max(s => s.SensorId) + 1}, but is({_sensors.Max(s => s.SensorId)})"); - - if (_sensors.Select(s => s.SensorId).Distinct().Count() != _sensors.Length) - throw new ArgumentOutOfRangeException($"Some Sensor-IDs are used more then onse"); - - setParameterValue(ERDM_Parameter.SENSOR_DEFINITION, sensorDef); - setParameterValue(ERDM_Parameter.SENSOR_VALUE, sensorValue); + Logger?.LogError(e, string.Empty); + return false; } - - updateSupportedParametersOnAddRemoveSensors(); - updateDeviceInfo(); } - protected void RemoveSensors(params Sensor[] @sensors) - { - foreach (var sensor in @sensors) - { - if (sensor == null) - throw new ArgumentNullException(nameof(sensor)); - if (!this.sensors.ContainsKey(sensor.SensorId)) - throw new ArgumentOutOfRangeException($"The Sensor with the ID: {sensor.SensorId} not exists"); - if (this.sensors.TryRemove(sensor.SensorId, out _)) - { - sensor.PropertyChanged -= Sensor_PropertyChanged; - if (parameterValues.TryGetValue(ERDM_Parameter.SENSOR_DEFINITION, out object value_d) && value_d is ConcurrentDictionary sensorDef) - { - if (sensorDef.TryRemove(sensor.SensorId, out _)) - setParameterValue(ERDM_Parameter.SENSOR_DEFINITION, sensorDef); - } - if (parameterValues.TryGetValue(ERDM_Parameter.SENSOR_VALUE, out object value_v) && value_v is ConcurrentDictionary sensorValue) - { - if (sensorValue.TryRemove(sensor.SensorId, out _)) - setParameterValue(ERDM_Parameter.SENSOR_VALUE, sensorValue); - } - } - } - if (sensorDef?.IsEmpty ?? false) - sensorDef = null; - if (sensorValue?.IsEmpty ?? false) - sensorValue = null; + return this.trySetParameter(parameter, value); + } + protected sealed override void OnPropertyChanged([CallerMemberName] string property = null) + { + switch (property) + { + case nameof(DeviceInfo): + trySetParameter(ERDM_Parameter.DEVICE_INFO, this.DeviceInfo); + trySetParameter(ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID, this.DeviceInfo.SoftwareVersionId); + break; + //case nameof(CurrentPersonality): + // var slots = Personalities.First(p => p.ID == this.CurrentPersonality).Slots.Count; + // var slotInfos = new RDMSlotInfo[slots]; + // var slotDesc = new ConcurrentDictionary(); + // var slotDefault = new RDMDefaultSlotValue[slots]; + // foreach (var s in Personalities.First(p => p.ID == this.CurrentPersonality).Slots) + // { + // Slot slot = s.Value; + // slotInfos[slot.SlotId] = new RDMSlotInfo(slot.SlotId, slot.Type, slot.Category); + // slotDesc.TryAdd(slot.SlotId, new RDMSlotDescription(slot.SlotId, slot.Description)); + // slotDefault[slot.SlotId] = new RDMDefaultSlotValue(slot.SlotId, slot.DefaultValue); + // } + // trySetParameter(ERDM_Parameter.SLOT_INFO, slotInfos); + // trySetParameter(ERDM_Parameter.SLOT_DESCRIPTION, slotDesc); + // trySetParameter(ERDM_Parameter.DEFAULT_SLOT_VALUE, slotDefault); + // break; + } + base.OnPropertyChanged(property); + } - setParameterValue(ERDM_Parameter.SENSOR_DEFINITION, sensorDef); - setParameterValue(ERDM_Parameter.SENSOR_VALUE, sensorValue); - updateSupportedParametersOnAddRemoveSensors(); - updateDeviceInfo(); + public bool SetParameter(ERDM_Parameter parameter, object value = null) + { + setParameterValue(parameter, value); + return true; + } + internal void setParameterValue(ERDM_Parameter parameter, object value, object index = null) + { + bool notNew = false; + if (value is null) + { + parameterValues.TryRemove(parameter, out object oldValue); + return; } - - private void updateSupportedParametersOnAddRemoveSensors() + bool raiseAddedEvent = false; + bool raiseUpdatedEvent = false; + object? ov = null; + parameterValues.AddOrUpdate(parameter, (_) => { - var oldParameters = Parameters; - if (!this.sensors.IsEmpty) + try { - HashSet _params = Parameters.ToHashSet(); - _params.Add(ERDM_Parameter.SENSOR_DEFINITION); - _params.Add(ERDM_Parameter.SENSOR_VALUE); - _parameters = _params; + return value; } - else if ( - Parameters.Contains(ERDM_Parameter.SENSOR_DEFINITION) || - Parameters.Contains(ERDM_Parameter.SENSOR_VALUE) || - Parameters.Contains(ERDM_Parameter.RECORD_SENSORS) || - Parameters.Contains(ERDM_Parameter.SENSOR_TYPE_CUSTOM) || - Parameters.Contains(ERDM_Parameter.SENSOR_UNIT_CUSTOM)) + finally { - HashSet _params = Parameters.ToHashSet(); - _params.RemoveWhere(p => - p == ERDM_Parameter.SENSOR_DEFINITION || - p == ERDM_Parameter.SENSOR_VALUE || - p == ERDM_Parameter.RECORD_SENSORS || - p == ERDM_Parameter.SENSOR_TYPE_CUSTOM || - p == ERDM_Parameter.SENSOR_UNIT_CUSTOM); - _parameters = _params; + raiseAddedEvent = true; } - - if (sensors.Values.Any(s => s.RecordedValueSupported) && !Parameters.Contains(ERDM_Parameter.RECORD_SENSORS)) + }, (o, p) => + { + try { - HashSet _params = Parameters.ToHashSet(); - _params.Add(ERDM_Parameter.RECORD_SENSORS); - _parameters = _params; + ov = p; + if (object.Equals(ov, value) && value is not ConcurrentDictionary) + notNew = true; + return value; } - else if (!sensors.Values.Any(s => s.RecordedValueSupported) && Parameters.Contains(ERDM_Parameter.RECORD_SENSORS)) + finally { - HashSet _params = Parameters.ToHashSet(); - _params.RemoveWhere(sensors => sensors == ERDM_Parameter.RECORD_SENSORS); - _parameters = _params; + raiseUpdatedEvent = true; } + }); - if (!Parameters.SequenceEqual(oldParameters)) - trySetParameter(ERDM_Parameter.SUPPORTED_PARAMETERS, Parameters.ToArray()); - } - - private void Sensor_PropertyChanged(object sender, PropertyChangedEventArgs e) + try { - if (sender is not Sensor sensor) + if (notNew) return; - - switch (e.PropertyName) + if (parameter != ERDM_Parameter.SLOT_DESCRIPTION) { - case nameof(Sensor.Type): - case nameof(Sensor.Unit): - case nameof(Sensor.Prefix): - case nameof(Sensor.RangeMaximum): - case nameof(Sensor.RangeMinimum): - case nameof(Sensor.NormalMaximum): - case nameof(Sensor.NormalMinimum): - case nameof(Sensor.LowestHighestValueSupported): - case nameof(Sensor.RecordedValueSupported): - sensorDef.AddOrUpdate(sensor.SensorId, (RDMSensorDefinition)sensor, (o1, o2) => (RDMSensorDefinition)sensor); - setParameterValue(ERDM_Parameter.SENSOR_DEFINITION, sensorDef, sensor.SensorId); - break; - case nameof(Sensor.PresentValue): - case nameof(Sensor.LowestValue): - case nameof(Sensor.HighestValue): - case nameof(Sensor.RecordedValue): - sensorValue.AddOrUpdate(sensor.SensorId, (RDMSensorValue)sensor, (o1, o2) => (RDMSensorValue)sensor); - setParameterValue(ERDM_Parameter.SENSOR_VALUE, sensorValue, sensor.SensorId); - break; - } - } - - protected bool trySetParameter(ERDM_Parameter parameter, object value) - { - if (!this.Parameters.Contains(parameter)) - throw new NotSupportedException($"The Parameter: {parameter}, is not Supported"); - - setParameterValue(parameter, value); - return true; - } - public bool TrySetParameter(ERDM_Parameter parameter, object value, bool throwException = true) - { - - if (!this.Parameters.Contains(parameter)) - { - if (throwException) - throw new NotSupportedException($"The Device not support the Parameter: {parameter}"); - return false; + updateParameterBag(parameter, index); + return; } - - switch (parameter) + if (value is ConcurrentDictionary dict) { - case ERDM_Parameter.DMX_START_ADDRESS: - case ERDM_Parameter.DEVICE_LABEL: - if (throwException) - throw new NotSupportedException($"You have no permission to set the Parameter: {parameter}, use the public Propertys to set them"); - return false; - - case ERDM_Parameter.DEVICE_INFO: - case ERDM_Parameter.DEVICE_MODEL_DESCRIPTION: - case ERDM_Parameter.MANUFACTURER_LABEL: - case ERDM_Parameter.QUEUED_MESSAGE: - case ERDM_Parameter.SUPPORTED_PARAMETERS: - case ERDM_Parameter.SLOT_DESCRIPTION: - case ERDM_Parameter.SLOT_INFO: - case ERDM_Parameter.DEFAULT_SLOT_VALUE: - case ERDM_Parameter.SENSOR_DEFINITION: - case ERDM_Parameter.SENSOR_VALUE: - if (throwException) - throw new NotSupportedException($"The Protocoll not allow to set the Parameter: {parameter}"); - return false; + foreach (var p in dict) + updateParameterBag(parameter, p.Key); } - - var parameterBag = new ParameterBag(parameter, UID.ManufacturerID, DeviceInfo?.DeviceModelId, DeviceInfo?.SoftwareVersionId); - var define = MetadataFactory.GetDefine(parameterBag); - if (define != null) - { - if (!define.SetRequest.HasValue) - { - if (throwException) - throw new NotSupportedException($"The Protocoll not allow to set the Parameter: {parameter}"); - return false; - } - - try - { - if (!define.SetRequest.HasValue) - throw new NotSupportedException($"The Protocoll not allow to set the Parameter: {parameter}"); - else - { - byte[] data = MetadataFactory.ParsePayloadToData(define, Metadata.JSON.Command.ECommandDublicate.SetRequest, DataTreeBranch.FromObject(value, null, parameterBag, ERDM_Command.SET_COMMAND)).First(); - var obj = MetadataFactory.ParseDataToPayload(define, Metadata.JSON.Command.ECommandDublicate.SetRequest, data); - if (!object.Equals(value, obj)) - return false; - } - } - catch (Exception e) - { - Logger?.LogError(e, string.Empty); - return false; - } - } - - return this.trySetParameter(parameter, value); + return; } - protected sealed override void OnPropertyChanged(string property) + finally { - switch (property) - { - case nameof(DeviceInfo): - trySetParameter(ERDM_Parameter.DEVICE_INFO, this.DeviceInfo); - trySetParameter(ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID, this.DeviceInfo.SoftwareVersionId); - break; - case nameof(DeviceModelDescription): - trySetParameter(ERDM_Parameter.DEVICE_MODEL_DESCRIPTION, this.DeviceModelDescription); - break; - case nameof(DMXAddress): - trySetParameter(ERDM_Parameter.DMX_START_ADDRESS, this.DMXAddress); - break; - case nameof(Identify): - trySetParameter(ERDM_Parameter.IDENTIFY_DEVICE, this.Identify); - break; - case nameof(CurrentPersonality): - trySetParameter(ERDM_Parameter.DMX_PERSONALITY, new RDMDMXPersonality(this.currentPersonality, (byte)(Personalities?.Length ?? 0))); - - var slots = Personalities.First(p => p.ID == this.currentPersonality).Slots.Count; - var slotInfos = new RDMSlotInfo[slots]; - var slotDesc = new ConcurrentDictionary(); - var slotDefault = new RDMDefaultSlotValue[slots]; - foreach (var s in Personalities.First(p => p.ID == this.currentPersonality).Slots) - { - Slot slot = s.Value; - slotInfos[slot.SlotId] = new RDMSlotInfo(slot.SlotId, slot.Type, slot.Category); - slotDesc.TryAdd(slot.SlotId, new RDMSlotDescription(slot.SlotId, slot.Description)); - slotDefault[slot.SlotId] = new RDMDefaultSlotValue(slot.SlotId, slot.DefaultValue); - } - trySetParameter(ERDM_Parameter.SLOT_INFO, slotInfos); - trySetParameter(ERDM_Parameter.SLOT_DESCRIPTION, slotDesc); - trySetParameter(ERDM_Parameter.DEFAULT_SLOT_VALUE, slotDefault); - break; - case nameof(DeviceLabel): - trySetParameter(ERDM_Parameter.DEVICE_LABEL, this.DeviceLabel); - break; - case nameof(ManufacturerLabel): - trySetParameter(ERDM_Parameter.MANUFACTURER_LABEL, this.ManufacturerLabel); - break; - case nameof(SoftwareVersionLabel): - trySetParameter(ERDM_Parameter.SOFTWARE_VERSION_LABEL, this.SoftwareVersionLabel); - break; - case nameof(BootSoftwareVersionLabel): - trySetParameter(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL, this.BootSoftwareVersionLabel); - break; - case nameof(RealTimeClock): - trySetParameter(ERDM_Parameter.REAL_TIME_CLOCK, new RDMRealTimeClock(this.RealTimeClock)); - break; - } - base.OnPropertyChanged(property); + if (raiseAddedEvent) + InvokeParameterValueAdded(new ParameterValueAddedEventArgs(parameter, value, index)); + if (raiseUpdatedEvent) + InvokeParameterValueChanged(new ParameterValueChangedEventArgs(parameter, value, ov, index)); } + } - - public bool SetParameter(ERDM_Parameter parameter, object value = null) - { - setParameterValue(parameter, value); - return true; - } - private void setParameterValue(ERDM_Parameter parameter, object value, object index=null) + private void Instance_RequestReceivedEvent(object sender, RequestReceivedEventArgs e) + { + RDMMessage response = null; + if ((e.Request.DestUID.IsBroadcast || e.Request.DestUID == UID) && !e.Request.Command.HasFlag(ERDM_Command.RESPONSE)) { - switch (parameter) + if (e.Request.SubDevice.IsBroadcast) { - case ERDM_Parameter.DEVICE_INFO when value is RDMDeviceInfo _deviceInfo: - deviceInfo = _deviceInfo; - goto default; - - default: - bool notNew = false; - if (value is null) - { - parameterValues.TryRemove(parameter, out object oldValue); - return; - } - parameterValues.AddOrUpdate(parameter, value, (o, p) => - { - if (object.Equals(p, value)&& value is not ConcurrentDictionary) - notNew = true; - return value; - }); - if (notNew) - return; - if (parameter != ERDM_Parameter.SLOT_DESCRIPTION) - { - updateParameterBag(parameter, index); - return; - } - if(value is ConcurrentDictionary dict) - { - foreach (var p in dict) - updateParameterBag(parameter, p.Key); - } - return; + foreach (var sd in this.SubDevices) + _ = processRequestMessage(e.Request); //Drop response on Broadcast + return; } - } + AbstractGeneratedRDMDevice sds = null; + if (e.Request.SubDevice == this.Subdevice) + sds = this; + else + sds = this.SubDevices?.OfType().FirstOrDefault(sd => sd.Subdevice == e.Request.SubDevice); - #region SendReceive Pipeline - private void Instance_RequestReceivedEvent(object sender, RequestReceivedEventArgs e) - { - RDMMessage response = null; - if ((e.Request.DestUID.IsBroadcast || e.Request.DestUID == UID) && !e.Request.Command.HasFlag(ERDM_Command.RESPONSE)) - { - if (e.Request.SubDevice.IsBroadcast) - { - foreach (var sd in this.SubDevices) - _ = processRequestMessage(e.Request); //Drop response on Broadcast - return; - } - - AbstractGeneratedRDMDevice sds = null; - if (e.Request.SubDevice == this.Subdevice) - sds = this; - else - sds = this.SubDevices?.OfType().FirstOrDefault(sd => sd.Subdevice == e.Request.SubDevice); - - if (sds != null) - response = sds.processRequestMessage(e.Request); - } - if (e.Request.Command != ERDM_Command.DISCOVERY_COMMAND) - e.Response = response; - else if (response != null && response.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE) - RDMSharp.Instance.SendMessage(response); + if (sds != null) + response = sds.processRequestMessage(e.Request); } -#endregion - protected async Task OnReceiveRDMMessage(RDMMessage rdmMessage) - { - if ((rdmMessage.DestUID.IsBroadcast || rdmMessage.DestUID == UID) && !rdmMessage.Command.HasFlag(ERDM_Command.RESPONSE)) - { - if (rdmMessage.SubDevice.IsBroadcast || rdmMessage.SubDevice == this.Subdevice) - await RDMSharp.Instance.SendMessage(processRequestMessage(rdmMessage)); - } - } - protected sealed override async Task OnResponseMessage(RDMMessage rdmMessage) + if (e.Request.Command != ERDM_Command.DISCOVERY_COMMAND) + e.Response = response; + else if (response != null && response.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE) + RDMSharp.Instance.SendMessage(response); + } + + protected async Task OnReceiveRDMMessage(RDMMessage rdmMessage) + { + if ((rdmMessage.DestUID.IsBroadcast || rdmMessage.DestUID == UID) && !rdmMessage.Command.HasFlag(ERDM_Command.RESPONSE)) { - await OnReceiveRDMMessage(rdmMessage); - await base.OnResponseMessage(rdmMessage); + if (rdmMessage.SubDevice.IsBroadcast || rdmMessage.SubDevice == this.Subdevice) + await RDMSharp.Instance.SendMessage(processRequestMessage(rdmMessage)); } + } + protected sealed override async Task OnResponseMessage(RDMMessage rdmMessage) + { + await OnReceiveRDMMessage(rdmMessage); + await base.OnResponseMessage(rdmMessage); + } - protected RDMMessage processRequestMessage(RDMMessage rdmMessage) + protected RDMMessage processRequestMessage(RDMMessage rdmMessage) + { + RDMMessage response = null; + try { - RDMMessage response = null; - try + var controllerCache = getControllerCommunicationCache(rdmMessage.SourceUID); + controllerCache.Seen(); + if (rdmMessage.Command == ERDM_Command.DISCOVERY_COMMAND) { - var controllerCache = getControllerCommunicationCache(rdmMessage.SourceUID); - controllerCache.Seen(); - if (rdmMessage.Command == ERDM_Command.DISCOVERY_COMMAND) + switch (rdmMessage.Parameter) { - switch (rdmMessage.Parameter) - { - case ERDM_Parameter.DISC_MUTE: - DiscoveryMuted = true; - response = new RDMMessage - { - Parameter = ERDM_Parameter.DISC_MUTE, - Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, - SourceUID = UID, - DestUID = rdmMessage.SourceUID, - ParameterData = new DiscMuteUnmuteResponse().ToPayloadData() - }; - return rdmMessage.DestUID != UID.Broadcast ? response : null; - case ERDM_Parameter.DISC_UN_MUTE: - DiscoveryMuted = false; + case ERDM_Parameter.DISC_MUTE: + DiscoveryMuted = true; + response = new RDMMessage + { + Parameter = ERDM_Parameter.DISC_MUTE, + Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, + SourceUID = UID, + DestUID = rdmMessage.SourceUID, + ParameterData = new DiscMuteUnmuteResponse().ToPayloadData() + }; + return rdmMessage.DestUID != UID.Broadcast ? response : null; + case ERDM_Parameter.DISC_UN_MUTE: + DiscoveryMuted = false; + response = new RDMMessage + { + Parameter = ERDM_Parameter.DISC_UN_MUTE, + Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, + SourceUID = UID, + DestUID = rdmMessage.SourceUID, + ParameterData = new DiscMuteUnmuteResponse().ToPayloadData() + }; + return rdmMessage.DestUID != UID.Broadcast ? response : null; + case ERDM_Parameter.DISC_UNIQUE_BRANCH when rdmMessage.Value is DiscUniqueBranchRequest discUniqueBranchRequest: + if (UID >= discUniqueBranchRequest.StartUid && UID <= discUniqueBranchRequest.EndUid) + { + if (DiscoveryMuted) + return null; response = new RDMMessage { - Parameter = ERDM_Parameter.DISC_UN_MUTE, + Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH, Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, SourceUID = UID, DestUID = rdmMessage.SourceUID, - ParameterData = new DiscMuteUnmuteResponse().ToPayloadData() }; - return rdmMessage.DestUID != UID.Broadcast ? response : null; - case ERDM_Parameter.DISC_UNIQUE_BRANCH when rdmMessage.Value is DiscUniqueBranchRequest discUniqueBranchRequest: - if (UID >= discUniqueBranchRequest.StartUid && UID <= discUniqueBranchRequest.EndUid) - { - if (DiscoveryMuted) - return null; - response = new RDMMessage - { - Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH, - Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, - SourceUID = UID, - DestUID = rdmMessage.SourceUID, - }; - return response; - } - return null; - } + return response; + } + return null; } + } + + var module = this.Modules.FirstOrDefault(m => m.IsHandlingParameter(rdmMessage.Parameter, rdmMessage.Command)); + if (module is not null) + { + response = module.HandleRequest(rdmMessage); + if (response != null) + goto FAIL; + } - if (rdmMessage.SubDevice != SubDevice.Broadcast && !(this.SubDevices?.Any(sd => sd.Subdevice == rdmMessage.SubDevice) ?? true)) + if (rdmMessage.SubDevice != SubDevice.Broadcast && !(this.SubDevices?.Any(sd => sd.Subdevice == rdmMessage.SubDevice) ?? true)) + { + response = new RDMMessage(ERDM_NackReason.SUB_DEVICE_OUT_OF_RANGE) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + goto FAIL; + } + if (rdmMessage.Command == ERDM_Command.GET_COMMAND) + { + ERDM_Parameter parameter = rdmMessage.Parameter; + object requestValue = rdmMessage.Value; + byte messageCounter = 0; + if (rdmMessage.SubDevice == SubDevice.Broadcast) // no Response on Broadcast Subdevice, because this can't work on a if there are more then one Device responding on a single line. { - response = new RDMMessage(ERDM_NackReason.SUB_DEVICE_OUT_OF_RANGE) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + response = new RDMMessage(ERDM_NackReason.SUB_DEVICE_OUT_OF_RANGE) { Parameter = parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; goto FAIL; } - if (rdmMessage.Command == ERDM_Command.GET_COMMAND) + if (parameter == ERDM_Parameter.QUEUED_MESSAGE) { - ERDM_Parameter parameter = rdmMessage.Parameter; - object requestValue = rdmMessage.Value; - byte messageCounter = 0; - if (rdmMessage.SubDevice == SubDevice.Broadcast) // no Response on Broadcast Subdevice, because this can't work on a if there are more then one Device responding on a single line. + if (!SupportQueued) + goto FAIL; + + ERDM_Status statusCode = ERDM_Status.NONE; + if (requestValue is ERDM_Status status) + statusCode = status; + + if (statusCode == ERDM_Status.NONE) + { + response = new RDMMessage(ERDM_NackReason.FORMAT_ERROR) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + goto FAIL; + } + else if (statusCode == ERDM_Status.GET_LAST_MESSAGE) + { + response = controllerCache.GetLastSendQueuedOrStatusRDMMessageResponse(); + if (response != null) + goto FAIL; + + response = new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + goto FAIL; + } + + if (controllerCache.ParameterUpdatedBag.IsEmpty) { - response = new RDMMessage(ERDM_NackReason.SUB_DEVICE_OUT_OF_RANGE) { Parameter = parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + response = new RDMMessage + { + Parameter = ERDM_Parameter.STATUS_MESSAGES, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + ControllerFlags_or_MessageCounter = 0 + }; + if (statusMessageModule is not null) + fillRDMMessageWithStatusMessageData(controllerCache, statusCode, ref response); + goto FAIL; } - if (parameter == ERDM_Parameter.QUEUED_MESSAGE) + else if (controllerCache.ParameterUpdatedBag.TryDequeue(out var item)) { - if (!SupportQueued) - goto FAIL; - - ERDM_Status statusCode = ERDM_Status.NONE; - if (requestValue is ERDM_Status status) - statusCode = status; - - if (statusCode == ERDM_Status.NONE) - { - response = new RDMMessage(ERDM_NackReason.FORMAT_ERROR) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; - goto FAIL; - } - else if (statusCode == ERDM_Status.GET_LAST_MESSAGE) + parameter = item.Parameter; + requestValue = item.Index; + messageCounter = (byte)Math.Min(controllerCache.ParameterUpdatedBag.Count, byte.MaxValue); + } + } + if (parameter == ERDM_Parameter.STATUS_MESSAGES) + { + ERDM_Status statusCode = ERDM_Status.NONE; + if (requestValue is ERDM_Status status) + statusCode = status; + if (statusMessageModule is not null) + { + if (statusCode == ERDM_Status.GET_LAST_MESSAGE) { response = controllerCache.GetLastSendQueuedOrStatusRDMMessageResponse(); if (response != null) @@ -836,522 +545,452 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) response = new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; goto FAIL; } - - if (controllerCache.ParameterUpdatedBag.IsEmpty) + else { response = new RDMMessage { Parameter = ERDM_Parameter.STATUS_MESSAGES, Command = ERDM_Command.GET_COMMAND_RESPONSE, - MessageCounter = 0 + ControllerFlags_or_MessageCounter = 0, + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK }; - if (SupportStatus) - fillRDMMessageWithStatusMessageData(controllerCache, statusCode, ref response); + fillRDMMessageWithStatusMessageData(controllerCache, statusCode, ref response); + controllerCache.SetLastSendQueuedOrStatusRDMMessageResponse(response); + controllerCache.SetLastSendRDMMessageResponse(response); goto FAIL; } - else if (controllerCache.ParameterUpdatedBag.TryDequeue(out var item)) - { - parameter = item.Parameter; - requestValue = item.Index; - messageCounter = (byte)Math.Min(controllerCache.ParameterUpdatedBag.Count, byte.MaxValue); - } - } - if(parameter == ERDM_Parameter.STATUS_MESSAGES) - { - ERDM_Status statusCode = ERDM_Status.NONE; - if (requestValue is ERDM_Status status) - statusCode = status; - if (SupportStatus) - { - if (statusCode == ERDM_Status.GET_LAST_MESSAGE) - { - response = controllerCache.GetLastSendQueuedOrStatusRDMMessageResponse(); - if (response != null) - goto FAIL; - - response = new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; - goto FAIL; - } - else - { - response = new RDMMessage - { - Parameter = ERDM_Parameter.STATUS_MESSAGES, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - MessageCounter = 0 - }; - - fillRDMMessageWithStatusMessageData(controllerCache, statusCode, ref response); - controllerCache.SetLastSendQueuedOrStatusRDMMessageResponse(response); - controllerCache.SetLastSendRDMMessageResponse(response); - goto FAIL; - } - } - else goto FAIL; } - else - removeParameterFromParameterUpdateBag(parameter); + else goto FAIL; + } + else + removeParameterFromParameterUpdateBag(parameter); - parameterValues.TryGetValue(parameter, out object responseValue); + parameterValues.TryGetValue(parameter, out object responseValue); - if(responseValue is ConcurrentDictionary dict) - { - var val = dict[requestValue]; - if (val == null) - throw new ArgumentOutOfRangeException("No matching id found"); - } + if (responseValue is ConcurrentDictionary dict) + { + var val = dict[requestValue]; + if (val == null) + throw new ArgumentOutOfRangeException("No matching id found"); + } - var parameterBag = new ParameterBag(parameter, UID.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); - var define = MetadataFactory.GetDefine(parameterBag); - if (define.GetRequest is null) + var parameterBag = new ParameterBag(parameter, UID.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); + var define = MetadataFactory.GetDefine(parameterBag); + if (define.GetRequest is null) + { + response = new RDMMessage(ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + goto FAIL; + } + //response = this.Modules.FirstOrDefault(m=>m.IsHandlingParameter(parameter))?.HandleRequest(rdmMessage); + if (overflowCacheBags.TryGetValue(rdmMessage.SourceUID, out OverflowCacheBag overflowCache)) + { + if (!overflowCache.Timeouted && overflowCache.Cache.TryDequeue(out byte[] data)) { - response = new RDMMessage(ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + response = new RDMMessage + { + Parameter = parameter, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + ControllerFlags_or_MessageCounter = messageCounter, + ParameterData = data, + }; + if (!overflowCache.Cache.TryPeek(out _)) + overflowCacheBags.Remove(rdmMessage.SourceUID, out _); + else + response.PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK_OVERFLOW; goto FAIL; } - if(overflowCacheBags.TryGetValue(rdmMessage.SourceUID, out OverflowCacheBag overflowCache)) + } + var dataTreeBranch = DataTreeBranch.FromObject(responseValue, requestValue, parameterBag, ERDM_Command.GET_COMMAND_RESPONSE); + try + { + if (!dataTreeBranch.IsUnset) { - if (!overflowCache.Timeouted && overflowCache.Cache.TryDequeue(out byte[] data)) + var data = MetadataFactory.GetResponseMessageData(parameterBag, dataTreeBranch); + if (data != null) { + byte[] pData = null; + if (data.Count() != 1) + { + overflowCacheBags.AddOrUpdate(rdmMessage.SourceUID, (uid) => new OverflowCacheBag(rdmMessage.Parameter, data.ToList()), (uid, o) => new OverflowCacheBag(rdmMessage.Parameter, data.ToList())); + overflowCacheBags[rdmMessage.SourceUID].Cache.TryDequeue(out pData); + } response = new RDMMessage { Parameter = parameter, Command = ERDM_Command.GET_COMMAND_RESPONSE, - MessageCounter = messageCounter, - ParameterData = data, + ControllerFlags_or_MessageCounter = messageCounter, + ParameterData = pData ?? data.FirstOrDefault() ?? new byte[0], + PortID_or_Responsetype = pData is null ? (byte)ERDM_ResponseType.ACK : (byte)ERDM_ResponseType.ACK_OVERFLOW }; - if (!overflowCache.Cache.TryPeek(out _)) - overflowCacheBags.Remove(rdmMessage.SourceUID, out _); - else - response.PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK_OVERFLOW; - goto FAIL; - } - } - var dataTreeBranch = DataTreeBranch.FromObject(responseValue, requestValue, parameterBag, ERDM_Command.GET_COMMAND_RESPONSE); - try - { - if (!dataTreeBranch.IsUnset) - { - var data = MetadataFactory.GetResponseMessageData(parameterBag, dataTreeBranch); - if (data != null) - { - byte[] pData = null; - if (data.Count() !=1) - { - overflowCacheBags.AddOrUpdate(rdmMessage.SourceUID, (uid) => new OverflowCacheBag(rdmMessage.Parameter, data.ToList()), (uid, o) => new OverflowCacheBag(rdmMessage.Parameter, data.ToList())); - pData = overflowCacheBags[rdmMessage.SourceUID].Cache.Dequeue(); - } - response = new RDMMessage - { - Parameter = parameter, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - MessageCounter = messageCounter, - ParameterData = pData ?? data.First(), - PortID_or_Responsetype = pData is null ? (byte)ERDM_ResponseType.ACK : (byte)ERDM_ResponseType.ACK_OVERFLOW - }; - } - if (rdmMessage.Parameter == ERDM_Parameter.QUEUED_MESSAGE) - controllerCache.SetLastSendQueuedOrStatusRDMMessageResponse(response); - controllerCache.SetLastSendRDMMessageResponse(response); } - else - goto FAIL; + if (rdmMessage.Parameter == ERDM_Parameter.QUEUED_MESSAGE) + controllerCache.SetLastSendQueuedOrStatusRDMMessageResponse(response); + controllerCache.SetLastSendRDMMessageResponse(response); } - catch (Exception e) - { - Logger?.LogError(e, $"ParameterBag:{parameterBag}{Environment.NewLine}Command: {rdmMessage.Command}{Environment.NewLine}RequestValue: {requestValue ?? ""}{Environment.NewLine}ResponseValue: {responseValue ?? ""}"); + else goto FAIL; - } } - else if (rdmMessage.Command == ERDM_Command.SET_COMMAND) + catch (Exception e) + { + Logger?.LogError(e, $"ParameterBag:{parameterBag}{Environment.NewLine}Command: {rdmMessage.Command}{Environment.NewLine}RequestValue: {requestValue ?? ""}{Environment.NewLine}ResponseValue: {responseValue ?? ""}"); + goto FAIL; + } + } + else if (rdmMessage.Command == ERDM_Command.SET_COMMAND) + { + bool success = false; + //Handle set Request + if (parameterValues.TryGetValue(rdmMessage.Parameter, out object comparisonValue)) { - bool success = false; - //Handle set Request - if (parameterValues.TryGetValue(rdmMessage.Parameter, out object comparisonValue)) + parameterValues.AddOrUpdate(rdmMessage.Parameter, (_) => { - parameterValues.AddOrUpdate(rdmMessage.Parameter, (_) => rdmMessage.Value, (_,_) => rdmMessage.Value); - success = true; - object responseValue = rdmMessage.Value; - if (comparisonValue is ConcurrentDictionary dict) + try { - switch (rdmMessage.Parameter) - { - case ERDM_Parameter.SENSOR_VALUE: - if (!object.Equals(rdmMessage.Value, byte.MaxValue)) - { - this.Sensors[(byte)rdmMessage.Value].ResetValues(); - responseValue = dict[rdmMessage.Value]; - } - else //Broadcast - { - foreach (var sensor in this.Sensors.Values) - sensor.ResetValues(); - responseValue = new RDMSensorValue(0xff); - } - break; - default: - responseValue = dict[rdmMessage.Value]; - break; - } + return rdmMessage.Value; } - + finally + { + InvokeParameterValueAdded(new ParameterValueAddedEventArgs(rdmMessage.Parameter, rdmMessage.Value)); + } + }, (_, old) => + { try { - updateParameterFromRemote(rdmMessage.Parameter, responseValue); - var parameterBag = new ParameterBag(rdmMessage.Parameter, UID.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); - var dataTreeBranch = DataTreeBranch.FromObject(responseValue, rdmMessage.Value, parameterBag, ERDM_Command.SET_COMMAND_RESPONSE); - if (!dataTreeBranch.IsUnset) - { - var data = MetadataFactory.SetResponseMessageData(parameterBag, dataTreeBranch); - if (data != null) - response = new RDMMessage - { - Parameter = rdmMessage.Parameter, - Command = ERDM_Command.SET_COMMAND_RESPONSE, - ParameterData = data.First(), - }; - } - else - goto FAIL; + return rdmMessage.Value; } - catch (Exception e) + finally { - Logger?.LogError(e); - if (e is ArgumentOutOfRangeException || e is KeyNotFoundException) - response = new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; - else - response = new RDMMessage(ERDM_NackReason.FORMAT_ERROR) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; - - goto FAIL; + InvokeParameterValueChanged(new ParameterValueChangedEventArgs(rdmMessage.Parameter, rdmMessage.Value, old)); } - } - else if (Parameters.Contains(rdmMessage.Parameter))//Parameter is not in parameterValues + }); + success = true; + object responseValue = rdmMessage.Value; + if (comparisonValue is ConcurrentDictionary dict) { - var parameterBag = new ParameterBag(rdmMessage.Parameter, UID.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); - var define = MetadataFactory.GetDefine(parameterBag); switch (rdmMessage.Parameter) { - case ERDM_Parameter.RECORD_SENSORS when rdmMessage.Value is byte sensorID: - success = true; - if (sensorID == 0xFF)//Broadcast - foreach (var sensor in Sensors.Values) - sensor.RecordValue(); - else - Sensors[sensorID].RecordValue(); - response = new RDMMessage + case ERDM_Parameter.SENSOR_VALUE: + if (!object.Equals(rdmMessage.Value, byte.MaxValue)) { - Parameter = rdmMessage.Parameter, - Command = ERDM_Command.SET_COMMAND_RESPONSE - }; - goto FAIL; - case ERDM_Parameter.CLEAR_STATUS_ID: - this.statusMessages.Clear(); - setParameterValue(ERDM_Parameter.STATUS_MESSAGES, this.statusMessages.Select(sm => sm.Value).ToArray()); + this.Sensors[(byte)rdmMessage.Value].ResetValues(); + responseValue = dict[rdmMessage.Value]; + } + else //Broadcast + { + foreach (var sensor in this.Sensors.Values) + sensor.ResetValues(); + responseValue = new RDMSensorValue(0xff); + } + break; + default: + responseValue = dict[rdmMessage.Value]; + break; + } + } + + try + { + var parameterBag = new ParameterBag(rdmMessage.Parameter, UID.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); + var dataTreeBranch = DataTreeBranch.FromObject(responseValue, rdmMessage.Value, parameterBag, ERDM_Command.SET_COMMAND_RESPONSE); + if (!dataTreeBranch.IsUnset) + { + var data = MetadataFactory.SetResponseMessageData(parameterBag, dataTreeBranch); + if (data != null) response = new RDMMessage { Parameter = rdmMessage.Parameter, - Command = ERDM_Command.SET_COMMAND_RESPONSE + Command = ERDM_Command.SET_COMMAND_RESPONSE, + ParameterData = data.First(), }; - goto FAIL; - - default: - response = new RDMMessage(ERDM_NackReason.ACTION_NOT_SUPPORTED) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; - goto FAIL; } + else + goto FAIL; } - else - goto FAIL; - - //Do set Response - if (!success) + catch (Exception e) { - response = new RDMMessage(ERDM_NackReason.FORMAT_ERROR) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + Logger?.LogError(e); + if (e is ArgumentOutOfRangeException || e is KeyNotFoundException) + response = new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + else + response = new RDMMessage(ERDM_NackReason.FORMAT_ERROR) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + goto FAIL; } } - } - catch (Exception e) - { - Logger?.LogError(e, string.Empty); - - if (e is ArgumentOutOfRangeException || e is KeyNotFoundException) - response = new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; - else + else if (Parameters.Contains(rdmMessage.Parameter))//Parameter is not in parameterValues { - var define = MetadataFactory.GetDefine(new ParameterBag(rdmMessage.Parameter, (ushort)ManufacturerID, DeviceModelID, SoftwareVersionID)); - if ( - (rdmMessage.Command == ERDM_Command.GET_COMMAND && !define.GetRequest.HasValue) || - (rdmMessage.Command == ERDM_Command.SET_COMMAND && !define.SetRequest.HasValue)) - response = new RDMMessage(ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; - else - response = new RDMMessage(ERDM_NackReason.ACTION_NOT_SUPPORTED) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + var parameterBag = new ParameterBag(rdmMessage.Parameter, UID.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); + var define = MetadataFactory.GetDefine(parameterBag); + switch (rdmMessage.Parameter) + { + //case ERDM_Parameter.RECORD_SENSORS when rdmMessage.Value is byte sensorID: + // success = true; + // if (sensorID == 0xFF)//Broadcast + // foreach (var sensor in Sensors.Values) + // sensor.RecordValue(); + // else + // Sensors[sensorID].RecordValue(); + // response = new RDMMessage + // { + // Parameter = rdmMessage.Parameter, + // Command = ERDM_Command.SET_COMMAND_RESPONSE + // }; + // goto FAIL; + //case ERDM_Parameter.CLEAR_STATUS_ID: + // this.statusMessages.Clear(); + // setParameterValue(ERDM_Parameter.STATUS_MESSAGES, this.statusMessages.Select(sm => sm.Value).ToArray()); + // response = new RDMMessage + // { + // Parameter = rdmMessage.Parameter, + // Command = ERDM_Command.SET_COMMAND_RESPONSE + // }; + // goto FAIL; + + default: + response = new RDMMessage(ERDM_NackReason.FORMAT_ERROR) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + goto FAIL; + } } - goto FAIL; - } - FAIL: - if (rdmMessage.SubDevice == SubDevice.Broadcast) // no Response on Broadcast Subdevice, because this can't work on a if there are more then one Device responding on a singel line. - return null; - if (rdmMessage.DestUID.IsBroadcast) // no Response on Broadcast - return null; - if(response == null) - { + else + goto FAIL; + //Do set Response + if (!success) + { + response = new RDMMessage(ERDM_NackReason.FORMAT_ERROR) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + goto FAIL; + } } + } + catch (Exception e) + { + Logger?.LogError(e, string.Empty); - response ??= new RDMMessage(ERDM_NackReason.UNKNOWN_PID) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; - - response.TransactionCounter = rdmMessage.TransactionCounter; - response.SourceUID = rdmMessage.DestUID; - response.DestUID = rdmMessage.SourceUID; - response.SubDevice = rdmMessage.SubDevice; - if(response.ResponseType == ERDM_ResponseType.NACK_REASON) + if (e is ArgumentOutOfRangeException || e is KeyNotFoundException) + response = new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + else { - Logger?.LogTrace($"RDM NACK: {response.NackReason} for Parameter: {response.Parameter} on Device: {this.UID} with Subdevice: {response.SubDevice}"); + var define = MetadataFactory.GetDefine(new ParameterBag(rdmMessage.Parameter, (ushort)ManufacturerID, DeviceModelID, SoftwareVersionID)); + if ( + (rdmMessage.Command == ERDM_Command.GET_COMMAND && !define.GetRequest.HasValue) || + (rdmMessage.Command == ERDM_Command.SET_COMMAND && !define.SetRequest.HasValue)) + response = new RDMMessage(ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + else + response = new RDMMessage(ERDM_NackReason.FORMAT_ERROR) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; } - return response; + goto FAIL; } - public sealed override IReadOnlyDictionary GetAllParameterValues() + FAIL: + if (rdmMessage.SubDevice == SubDevice.Broadcast) // no Response on Broadcast Subdevice, because this can't work on a if there are more then one Device responding on a singel line. + return null; + if (rdmMessage.DestUID.IsBroadcast) // no Response on Broadcast + return null; + if (response == null) { - return base.GetAllParameterValues(); + } - private void updateParameterFromRemote(ERDM_Parameter parameter, object value) + response ??= new RDMMessage(ERDM_NackReason.UNKNOWN_PID) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + + response.TransactionCounter = rdmMessage.TransactionCounter; + response.SourceUID = rdmMessage.DestUID; + response.DestUID = rdmMessage.SourceUID; + response.SubDevice = rdmMessage.SubDevice; + if (response.ResponseType == ERDM_ResponseType.NACK_REASON) { - switch (parameter) - { - case ERDM_Parameter.DMX_START_ADDRESS: - DMXAddress = (ushort)value; - break; - case ERDM_Parameter.DMX_PERSONALITY: - CurrentPersonality = (byte)value; - break; - case ERDM_Parameter.DEVICE_LABEL: - DeviceLabel = (string)value; - break; - case ERDM_Parameter.IDENTIFY_DEVICE: - Identify = (bool)value; - break; - } + Logger?.LogTrace($"RDM NACK: {response.NackReason} for Parameter: {response.Parameter} on Device: {this.UID} with Subdevice: {response.SubDevice}"); } - private void updateParameterBag(ERDM_Parameter parameter, object index = null) + return response; + } + public sealed override IReadOnlyDictionary GetAllParameterValues() + { + return base.GetAllParameterValues(); + } + + private void updateParameterBag(ERDM_Parameter parameter, object index = null) + { + if (!IsInitialized || !_initialized) + return; + try { - if (!IsInitialized || !_initialized) - return; - try - { - addOrUpdateParameterFromParameterUpdateBag(parameter, index); - } - catch(Exception e) - { - Logger?.LogError(e); - } + addOrUpdateParameterFromParameterUpdateBag(parameter, index); + } + catch (Exception e) + { + Logger?.LogError(e); } - private void addOrUpdateParameterFromParameterUpdateBag(ERDM_Parameter parameter, object index = null) + } + private void addOrUpdateParameterFromParameterUpdateBag(ERDM_Parameter parameter, object index = null) + { + foreach (var cache in controllerCommunicationCache) { - foreach (var cache in controllerCommunicationCache) + if (cache.Value.ParameterUpdatedBag.Any(p => p.Parameter == parameter)) { - if (cache.Value.ParameterUpdatedBag.Any(p => p.Parameter == parameter)) - { - var tempQueue = new ConcurrentQueue(); - while (cache.Value.ParameterUpdatedBag.TryDequeue(out var item)) - if (!(item.Parameter.Equals(parameter) && Equals(item.Index, index))) - tempQueue.Enqueue(item); + var tempQueue = new ConcurrentQueue(); + while (cache.Value.ParameterUpdatedBag.TryDequeue(out var item)) + if (!(item.Parameter.Equals(parameter) && Equals(item.Index, index))) + tempQueue.Enqueue(item); - while (tempQueue.TryDequeue(out var item)) - cache.Value.ParameterUpdatedBag.Enqueue(item); - } - cache.Value.ParameterUpdatedBag.Enqueue(new ParameterUpdatedBag(parameter, index)); + while (tempQueue.TryDequeue(out var item)) + cache.Value.ParameterUpdatedBag.Enqueue(item); } + cache.Value.ParameterUpdatedBag.Enqueue(new ParameterUpdatedBag(parameter, index)); } - private void removeParameterFromParameterUpdateBag(ERDM_Parameter parameter, object index = null) + } + private void removeParameterFromParameterUpdateBag(ERDM_Parameter parameter, object index = null) + { + foreach (var cache in controllerCommunicationCache) { - foreach (var cache in controllerCommunicationCache) + if (cache.Value.ParameterUpdatedBag.Any(p => p.Parameter == parameter && p.Index == index)) { - if (cache.Value.ParameterUpdatedBag.Any(p => p.Parameter == parameter && p.Index == index)) - { - var tempQueue = new ConcurrentQueue(); - while (cache.Value.ParameterUpdatedBag.TryDequeue(out var item)) - if (!(item.Parameter.Equals(parameter) && Equals(item.Index, index))) - tempQueue.Enqueue(item); + var tempQueue = new ConcurrentQueue(); + while (cache.Value.ParameterUpdatedBag.TryDequeue(out var item)) + if (!(item.Parameter.Equals(parameter) && Equals(item.Index, index))) + tempQueue.Enqueue(item); - while (tempQueue.TryDequeue(out var item)) - cache.Value.ParameterUpdatedBag.Enqueue(item); - } + while (tempQueue.TryDequeue(out var item)) + cache.Value.ParameterUpdatedBag.Enqueue(item); } } + } - protected void AddStatusMessage(RDMStatusMessage statusMessage) - { - if (!SupportStatus) - throw new NotSupportedException($"The Device {this.UID} not support Status Messages."); - - int id = 0; - if (this.statusMessages.Count != 0) - id = this.statusMessages.Max(s => s.Key) + 1; - if (this.statusMessages.TryAdd(id, statusMessage)) - setParameterValue(ERDM_Parameter.STATUS_MESSAGES, this.statusMessages.Select(sm => sm.Value).ToArray()); - } - protected void ClearStatusMessage(RDMStatusMessage statusMessage) + private void fillRDMMessageWithStatusMessageData(ControllerCommunicationCache controllerCache, ERDM_Status statusCode, ref RDMMessage rdmMessage) + { + var lastSendStatusMessageID = controllerCache.GetLastSendStatusMessageID(statusCode); + var _messages = StatusMessages.Where(s => s.Key > lastSendStatusMessageID && matchStausCode(statusCode, s.Value)).OrderBy(s => s.Key).ToList(); + if (_messages.Count() != 0) { - if (!SupportStatus) - throw new NotSupportedException($"The Device {this.UID} not support Status Messages."); - this.statusMessages.Where(s => s.Value.Equals(statusMessage)).ToList().ForEach(s => + byte count = 0; + List data = new List(); + Dictionary parsedMessages = new Dictionary(); + while (count < 25 && _messages.Count != 0) { - s.Value.Clear(); - }); - setParameterValue(ERDM_Parameter.STATUS_MESSAGES, this.statusMessages.Select(sm => sm.Value).ToArray()); - } - protected void RemoveStatusMessage(RDMStatusMessage statusMessage) - { - if (!SupportStatus) - throw new NotSupportedException($"The Device {this.UID} not support Status Messages."); - - bool succes = false; - this.statusMessages.Where(s => s.Value.Equals(statusMessage)).ToList().ForEach(s => + var pair = _messages.First(); + parsedMessages.Add(pair.Key, pair.Value); + data.AddRange(pair.Value.ToPayloadData()); + _messages.RemoveAt(0); + count++; + } + if (parsedMessages.Count != 0) { - if (this.statusMessages.TryRemove(s.Key, out _)) - succes = true; - }); - if(succes) - setParameterValue(ERDM_Parameter.STATUS_MESSAGES, this.statusMessages.Select(sm => sm.Value).ToArray()); + controllerCache.SetLastSendStatusMessageID(statusCode, _messages.Count == 0 ? -1 : parsedMessages.Max(s => s.Key)); + if (_messages.Count != 0) + rdmMessage.PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK_OVERFLOW; + rdmMessage.ParameterData = data.ToArray(); + } } - private void fillRDMMessageWithStatusMessageData(ControllerCommunicationCache controllerCache, ERDM_Status statusCode, ref RDMMessage rdmMessage) + bool matchStausCode(ERDM_Status statusCode, RDMStatusMessage statusMessage) { - var lastSendStatusMessageID= controllerCache.GetLastSendStatusMessageID(statusCode); - var _messages = statusMessages.Where(s => s.Key > lastSendStatusMessageID && matchStausCode(statusCode, s.Value)).OrderBy(s => s.Key).ToList(); - if (_messages.Count() != 0) - { - byte count = 0; - List data = new List(); - Dictionary parsedMessages = new Dictionary(); - while (count < 25 && _messages.Count != 0) - { - var pair = _messages.First(); - parsedMessages.Add(pair.Key, pair.Value); - data.AddRange(pair.Value.ToPayloadData()); - _messages.RemoveAt(0); - count++; - } - if (parsedMessages.Count != 0) - { - controllerCache.SetLastSendStatusMessageID(statusCode, _messages.Count == 0 ? -1 : parsedMessages.Max(s => s.Key)); - if (_messages.Count != 0) - rdmMessage.PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK_OVERFLOW; - rdmMessage.ParameterData = data.ToArray(); - } - } - bool matchStausCode(ERDM_Status statusCode, RDMStatusMessage statusMessage) - { - if (statusCode == ERDM_Status.GET_LAST_MESSAGE) - throw new NotSupportedException($"The StatusCode: {statusCode}, not supported in this Method."); + if (statusCode == ERDM_Status.GET_LAST_MESSAGE) + throw new NotSupportedException($"The StatusCode: {statusCode}, not supported in this Method."); - if (statusMessage.EStatusType == ERDM_Status.GET_LAST_MESSAGE) - throw new NotSupportedException($"The StatusCode: {statusMessage.EStatusType}, not supported in this Method."); + if (statusMessage.EStatusType == ERDM_Status.GET_LAST_MESSAGE) + throw new NotSupportedException($"The StatusCode: {statusMessage.EStatusType}, not supported in this Method."); - var statusType = statusMessage.EStatusType & ~ERDM_Status.CLEARED; + var statusType = statusMessage.EStatusType & ~ERDM_Status.CLEARED; - return statusType >= statusCode; - } + return statusType >= statusCode; } - private ControllerCommunicationCache getControllerCommunicationCache(UID uid) + } + private ControllerCommunicationCache getControllerCommunicationCache(UID uid) + { + if (!controllerCommunicationCache.TryGetValue(uid, out var cache)) { - if (!controllerCommunicationCache.TryGetValue(uid, out var cache)) - { - cache = new ControllerCommunicationCache(uid); - controllerCommunicationCache.TryAdd(uid, cache); - } - return cache; + cache = new ControllerCommunicationCache(uid); + controllerCommunicationCache.TryAdd(uid, cache); } - protected sealed override void OnDispose() + return cache; + } + protected sealed override void OnDispose() + { + RDMSharp.Instance.RequestReceivedEvent -= Instance_RequestReceivedEvent; + try { - RDMSharp.Instance.RequestReceivedEvent -= Instance_RequestReceivedEvent; - try - { - onDispose(); - } - catch (Exception e) - { - Logger?.LogError(e); - } + onDispose(); } - protected abstract void onDispose(); - - private class OverflowCacheBag + catch (Exception e) { - public readonly ERDM_Parameter Parameter; - public readonly DateTime CreationTime; - public readonly Queue Cache = new Queue(); + Logger?.LogError(e); + } + } + protected abstract void onDispose(); - public bool Timeouted - { - get - { - return (DateTime.UtcNow - CreationTime).TotalSeconds > 5; - } - } + private class OverflowCacheBag + { + public readonly ERDM_Parameter Parameter; + public readonly DateTime CreationTime; + public readonly Queue Cache = new Queue(); - public OverflowCacheBag(ERDM_Parameter parameter, IReadOnlyCollection cache) + public bool Timeouted + { + get { - Parameter = parameter; - CreationTime = DateTime.UtcNow; - foreach (var c in cache) - Cache.Enqueue(c); + return (DateTime.UtcNow - CreationTime).TotalSeconds > 5; } } - private class ControllerCommunicationCache + public OverflowCacheBag(ERDM_Parameter parameter, IReadOnlyCollection cache) { - public readonly UID Uid; - public DateTime LastSeen = DateTime.UtcNow; - private ConcurrentDictionary lastSendStatusMessageID; - private RDMMessage lastSendQueuedOrStatusRDMMessageResponse; - private RDMMessage lastSendRDMMessageResponse; + Parameter = parameter; + CreationTime = DateTime.UtcNow; + foreach (var c in cache) + Cache.Enqueue(c); + } + } + + private class ControllerCommunicationCache + { + public readonly UID Uid; + public DateTime LastSeen = DateTime.UtcNow; + private ConcurrentDictionary lastSendStatusMessageID; + private RDMMessage lastSendQueuedOrStatusRDMMessageResponse; + private RDMMessage lastSendRDMMessageResponse; - internal ConcurrentQueue ParameterUpdatedBag = new ConcurrentQueue(); + internal ConcurrentQueue ParameterUpdatedBag = new ConcurrentQueue(); - public ControllerCommunicationCache(UID uid) - { - this.Uid = uid; - } - public void Seen() - { - LastSeen = DateTime.UtcNow; - } + public ControllerCommunicationCache(UID uid) + { + this.Uid = uid; + } + public void Seen() + { + LastSeen = DateTime.UtcNow; + } - public int GetLastSendStatusMessageID(ERDM_Status statusCode) - { - if (lastSendStatusMessageID?.TryGetValue(statusCode, out int id) ?? false) - return id; + public int GetLastSendStatusMessageID(ERDM_Status statusCode) + { + if (lastSendStatusMessageID?.TryGetValue(statusCode, out int id) ?? false) + return id; - return -1; - } + return -1; + } - public void SetLastSendStatusMessageID(ERDM_Status statusCode, int id) - { - if(lastSendStatusMessageID==null) - lastSendStatusMessageID = new ConcurrentDictionary(); + public void SetLastSendStatusMessageID(ERDM_Status statusCode, int id) + { + if (lastSendStatusMessageID == null) + lastSendStatusMessageID = new ConcurrentDictionary(); - lastSendStatusMessageID.AddOrUpdate(statusCode, id, (o, p) => id); - } - public void SetLastSendQueuedOrStatusRDMMessageResponse(RDMMessage rdmMessage) - { - lastSendQueuedOrStatusRDMMessageResponse = rdmMessage; - } - public RDMMessage GetLastSendQueuedOrStatusRDMMessageResponse() - { - return lastSendQueuedOrStatusRDMMessageResponse; - } - public void SetLastSendRDMMessageResponse(RDMMessage rdmMessage) - { - lastSendRDMMessageResponse = rdmMessage; - } - public RDMMessage GetLastSendRDMMessageResponse() - { - return lastSendRDMMessageResponse; - } + lastSendStatusMessageID.AddOrUpdate(statusCode, id, (o, p) => id); + } + public void SetLastSendQueuedOrStatusRDMMessageResponse(RDMMessage rdmMessage) + { + lastSendQueuedOrStatusRDMMessageResponse = rdmMessage; + } + public RDMMessage GetLastSendQueuedOrStatusRDMMessageResponse() + { + return lastSendQueuedOrStatusRDMMessageResponse; + } + public void SetLastSendRDMMessageResponse(RDMMessage rdmMessage) + { + lastSendRDMMessageResponse = rdmMessage; + } + public RDMMessage GetLastSendRDMMessageResponse() + { + return lastSendRDMMessageResponse; } } } \ No newline at end of file diff --git a/RDMSharp/RDM/Device/AbstractRDMCache.cs b/RDMSharp/RDM/Device/AbstractRDMCache.cs index cbca016c..07c37748 100644 --- a/RDMSharp/RDM/Device/AbstractRDMCache.cs +++ b/RDMSharp/RDM/Device/AbstractRDMCache.cs @@ -1,5 +1,7 @@ using Microsoft.Extensions.Logging; using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -8,380 +10,440 @@ using System.Threading.Tasks; using static RDMSharp.PeerToPeerProcess; -namespace RDMSharp +namespace RDMSharp; + +public abstract class AbstractRDMCache : IDisposable { - public abstract class AbstractRDMCache : IDisposable + protected static ILogger Logger = Logging.CreateLogger(); + protected bool IsDisposed { get; private set; } + protected bool IsDisposing { get; private set; } + internal ConcurrentDictionary parameterValuesDataTreeBranch { get; private set; } = new ConcurrentDictionary(); + protected ConcurrentDictionary parameterValuesDependeciePropertyBag { get; private set; } = new ConcurrentDictionary(); + + protected ConcurrentDictionary parameterValues { get; private set; } = new ConcurrentDictionary(); + public virtual IReadOnlyDictionary ParameterValues + { + get { return this.parameterValues?.AsReadOnly(); } + } + internal protected event EventHandler ParameterValueAdded; + internal protected event EventHandler ParameterValueChanged; + protected event EventHandler ParameterRequested; + protected ConcurrentDictionary parameterMetadataBag { get; private set; } = new ConcurrentDictionary(); + public virtual IReadOnlyDictionary ParameterMetadataBag { - protected static ILogger Logger = Logging.CreateLogger(); - protected bool IsDisposed { get; private set; } - protected bool IsDisposing { get; private set; } - internal ConcurrentDictionary parameterValuesDataTreeBranch { get; private set; } = new ConcurrentDictionary(); - protected ConcurrentDictionary parameterValuesDependeciePropertyBag { get; private set; } = new ConcurrentDictionary(); - - protected ConcurrentDictionary parameterValues { get; private set; } = new ConcurrentDictionary(); - public virtual IReadOnlyDictionary ParameterValues + get { return this.parameterMetadataBag?.AsReadOnly(); } + } + internal protected event EventHandler ParameterMetadataAdded; + + public class ParameterValueAddedEventArgs : EventArgs + { + public readonly ERDM_Parameter Parameter; + public readonly object Index; + public readonly object Value; + + public ParameterValueAddedEventArgs(ERDM_Parameter parameter, object value, object index = null) { - get { return this.parameterValues?.AsReadOnly(); } + Parameter = parameter; + Index = index; + Value = value; } - protected event EventHandler ParameterValueAdded; - protected event EventHandler ParameterValueChanged; - protected event EventHandler ParameterRequested; + } + public class ParameterValueChangedEventArgs : EventArgs + { + public readonly ERDM_Parameter Parameter; + public readonly object Index; + public readonly object NewValue; + public readonly object OldValue; - public class ParameterValueAddedEventArgs : EventArgs + public ParameterValueChangedEventArgs(ERDM_Parameter parameter, object newValue, object oldValue, object index = null) { - public readonly ERDM_Parameter Parameter; - public readonly object Index; - public readonly object Value; - - public ParameterValueAddedEventArgs(ERDM_Parameter parameter, object value, object index = null) - { - Parameter = parameter; - Index = index; - Value = value; - } + Parameter = parameter; + Index = index; + NewValue = newValue; + OldValue = oldValue; } - public class ParameterValueChangedEventArgs : EventArgs - { - public readonly ERDM_Parameter Parameter; - public readonly object Index; - public readonly object NewValue; - public readonly object OldValue; + } + public class ParameterRequestedEventArgs : EventArgs + { + public readonly ERDM_Parameter Parameter; + public readonly object Index; - public ParameterValueChangedEventArgs(ERDM_Parameter parameter, object newValue, object oldValue, object index = null) - { - Parameter = parameter; - Index = index; - NewValue = newValue; - OldValue = oldValue; - } - } - public class ParameterRequestedEventArgs : EventArgs + public ParameterRequestedEventArgs(ERDM_Parameter parameter, object index = null) { - public readonly ERDM_Parameter Parameter; - public readonly object Index; - - public ParameterRequestedEventArgs(ERDM_Parameter parameter, object index = null) - { - Parameter = parameter; - Index = index; - } + Parameter = parameter; + Index = index; } + } - public AbstractRDMCache() - { + public AbstractRDMCache() + { - } + } - protected void InvokeParameterValueAdded(ParameterValueAddedEventArgs e) - { - this.ParameterValueAdded?.InvokeFailSafe(this, e); - } + protected void InvokeParameterValueAdded(ParameterValueAddedEventArgs e) + { + this.ParameterValueAdded?.InvokeFailSafe(this, e); + } + protected void InvokeParameterValueChanged(ParameterValueChangedEventArgs e) + { + this.ParameterValueChanged?.InvokeFailSafe(this, e); + } - protected void updateParameterValuesDependeciePropertyBag(ERDM_Parameter parameter, DataTreeBranch dataTreeBranch) + protected void updateParameterValuesDependeciePropertyBag(ERDM_Parameter parameter, DataTreeBranch dataTreeBranch) + { + object obj = dataTreeBranch.ParsedObject; + if (obj == null) + return; + + foreach (var p in obj.GetType().GetProperties().Where(p => p.GetCustomAttributes().Any()).ToList()) { - object obj = dataTreeBranch.ParsedObject; - if (obj == null) - return; + object value = p.GetValue(obj); + foreach (var item in p.GetCustomAttributes()) + parameterValuesDependeciePropertyBag.AddOrUpdate(item.Bag, value, (o1, o2) => value); + } + } + + protected void updateParameterValuesDataTreeBranch(ParameterDataCacheBag bag, DataTreeBranch dataTreeBranch) + { + parameterValuesDataTreeBranch.AddOrUpdate(bag, dataTreeBranch, (o1, o2) => dataTreeBranch); - foreach (var p in obj.GetType().GetProperties().Where(p => p.GetCustomAttributes().Any()).ToList()) + object valueToStore = dataTreeBranch.ParsedObject ?? dataTreeBranch; + if (bag.Index == null) + this.parameterValues.AddOrUpdate(bag.Parameter, (o1) => { - object value = p.GetValue(obj); - foreach (var item in p.GetCustomAttributes()) - parameterValuesDependeciePropertyBag.AddOrUpdate(item.Bag, value, (o1, o2) => value); - } - } + try + { + return valueToStore; + } + finally + { + ParameterValueAdded?.InvokeFailSafe(this, new ParameterValueAddedEventArgs(o1, valueToStore)); + } + }, (o1, o2) => + { + try + { + if (o2.GetType() != valueToStore.GetType()) + { + if (o2 is IRDMPayloadObjectOneOf oneOf) + { + oneOf = (IRDMPayloadObjectOneOf)Activator.CreateInstance(oneOf.GetType(), valueToStore, oneOf.Count); + valueToStore = oneOf; + } + } + return valueToStore; + } + finally + { + if (o2 != valueToStore) + ParameterValueChanged?.InvokeFailSafe(this, new ParameterValueChangedEventArgs(o1, valueToStore, o2)); + } + }); - protected void updateParameterValuesDataTreeBranch(ParameterDataCacheBag bag, DataTreeBranch dataTreeBranch) + else { - parameterValuesDataTreeBranch.AddOrUpdate(bag, dataTreeBranch, (o1, o2) => dataTreeBranch); - - object valueToStore = dataTreeBranch.ParsedObject ?? dataTreeBranch; - if (bag.Index == null) - this.parameterValues.AddOrUpdate(bag.Parameter, (o1) => + this.parameterValues.AddOrUpdate(bag.Parameter, + (pid) => + //Add { try { - return valueToStore; + ConcurrentDictionary dict = new ConcurrentDictionary(); + dict.AddOrUpdate(bag.Index, valueToStore, (o1, o2) => valueToStore); + return dict; } finally { - ParameterValueAdded?.InvokeFailSafe(this, new ParameterValueAddedEventArgs(o1, valueToStore)); + ParameterValueAdded?.InvokeFailSafe(this, new ParameterValueAddedEventArgs(pid, valueToStore, bag.Index)); } - }, (o1, o2) => + }, + (pid, cd) => + // Update { + object old = null; + bool changed = false; try { - if(o2.GetType() != valueToStore.GetType()) + ConcurrentDictionary dict = cd as ConcurrentDictionary ?? new ConcurrentDictionary(); + dict.AddOrUpdate(bag.Index, valueToStore, (_, o2) => { - if(o2 is IRDMPayloadObjectOneOf oneOf) - { - oneOf = (IRDMPayloadObjectOneOf)Activator.CreateInstance(oneOf.GetType(), valueToStore, oneOf.Count); - valueToStore = oneOf; - } - } - return valueToStore; + if (o2 == valueToStore) + return valueToStore; + + old = o2; + changed = true; + return valueToStore; + }); + return dict; } - finally + catch (Exception ex) { - if (o2 != valueToStore) - ParameterValueChanged?.InvokeFailSafe(this, new ParameterValueChangedEventArgs(o1, valueToStore, o2)); + Logger?.LogError(ex); + return null; } - }); - - else - { - this.parameterValues.AddOrUpdate(bag.Parameter, - (pid) => - //Add + finally { - try - { - ConcurrentDictionary dict = new ConcurrentDictionary(); - dict.AddOrUpdate(bag.Index, valueToStore, (o1, o2) => valueToStore); - return dict; - } - finally - { + if (changed) + ParameterValueChanged?.InvokeFailSafe(this, new ParameterValueChangedEventArgs(pid, valueToStore, old, bag.Index)); + else ParameterValueAdded?.InvokeFailSafe(this, new ParameterValueAddedEventArgs(pid, valueToStore, bag.Index)); - } - }, - (pid, cd) => - // Update - { - object old = null; - bool changed = false; - try - { - ConcurrentDictionary dict = cd as ConcurrentDictionary ?? new ConcurrentDictionary(); - dict.AddOrUpdate(bag.Index, valueToStore, (_, o2) => - { - if (o2 == valueToStore) - return valueToStore; + } + }); + } - old = o2; - changed = true; - return valueToStore; - }); - return dict; - } - catch(Exception ex) - { - Logger?.LogError(ex); - return null; - } - finally - { - if (changed) - ParameterValueChanged?.InvokeFailSafe(this, new ParameterValueChangedEventArgs(pid, valueToStore, old, bag.Index)); - else - ParameterValueAdded?.InvokeFailSafe(this, new ParameterValueAddedEventArgs(pid, valueToStore, bag.Index)); - } - }); - } + ParameterRequested?.InvokeFailSafe(this, new ParameterRequestedEventArgs(bag.Parameter, bag.Index)); + } + protected virtual async Task OnSendRDMMessage(RDMMessage rdmMessage) + { + await Task.CompletedTask; + } + protected virtual async Task OnResponseMessage(RDMMessage rdmMessage) + { + await Task.CompletedTask; + } - ParameterRequested?.InvokeFailSafe(this, new ParameterRequestedEventArgs(bag.Parameter, bag.Index)); - } - protected virtual async Task OnSendRDMMessage(RDMMessage rdmMessage) - { - await Task.CompletedTask; - } - protected virtual async Task OnResponseMessage(RDMMessage rdmMessage) - { - await Task.CompletedTask; - } + internal protected void tryAddParameterMetadata(ERDM_Parameter pid) + { + if (!parameterMetadataBag.ContainsKey(pid)) + if (parameterMetadataBag.TryAdd(pid, new ParameterMetadata(pid))) + ParameterMetadataAdded?.InvokeFailSafe(this, parameterMetadataBag[pid]); + } + protected async Task runPeerToPeerProcess(PeerToPeerProcess ptpProcess) + { + ptpProcess.BeforeSendMessage = OnSendRDMMessage; + ptpProcess.ResponseMessage = OnResponseMessage; + tryAddParameterMetadata(ptpProcess.ParameterBag.PID); - protected async Task runPeerToPeerProcess(PeerToPeerProcess ptpProcess) + parameterMetadataBag[ptpProcess.ParameterBag.PID].AddPeerToPeerProcess(ptpProcess); + await ptpProcess?.Run(); + } + protected async Task requestSetParameterWithEmptyPayload(ParameterBag parameterBag, MetadataJSONObjectDefine define, UID uid, SubDevice subDevice) + { + PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.SET_COMMAND, uid, subDevice, parameterBag); + await runPeerToPeerProcess(ptpProcess); + if (!ptpProcess.ResponsePayloadObject.IsUnset) { - ptpProcess.BeforeSendMessage = OnSendRDMMessage; - ptpProcess.ResponseMessage = OnResponseMessage; - await ptpProcess?.Run(); + updateParameterValuesDependeciePropertyBag(parameterBag.PID, ptpProcess.ResponsePayloadObject); + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(parameterBag.PID), ptpProcess.ResponsePayloadObject); + return ptpProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Finished; } - protected async Task requestSetParameterWithEmptyPayload(ParameterBag parameterBag, MetadataJSONObjectDefine define, UID uid, SubDevice subDevice) - { - PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.SET_COMMAND, uid, subDevice, parameterBag); - await runPeerToPeerProcess(ptpProcess); - if (!ptpProcess.ResponsePayloadObject.IsUnset) - { - updateParameterValuesDependeciePropertyBag(parameterBag.PID, ptpProcess.ResponsePayloadObject); - updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(parameterBag.PID), ptpProcess.ResponsePayloadObject); - return ptpProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Finished; - } - return false; - } - protected async Task requestSetParameterWithPayload(ParameterBag parameterBag, MetadataJSONObjectDefine define, UID uid, SubDevice subDevice, object value) + return false; + } + protected async Task requestSetParameterWithPayload(ParameterBag parameterBag, MetadataJSONObjectDefine define, UID uid, SubDevice subDevice, object value) + { + define.GetCommand(Metadata.JSON.Command.ECommandDublicate.SetRequest, out var cmd); + var req = cmd.Value.GetRequiredProperties(); + //if (req.Length == 1) + //{ + DataTreeBranch dataTreeBranch = DataTreeBranch.FromObject(value, null, parameterBag, ERDM_Command.SET_COMMAND); + PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.SET_COMMAND, uid, subDevice, parameterBag, dataTreeBranch); + await runPeerToPeerProcess(ptpProcess); + if (ptpProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Failed) + throw new Exception($"Failed to set parameter {parameterBag.PID} with value {value}"); + if (ptpProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Finished) { - define.GetCommand(Metadata.JSON.Command.ECommandDublicate.SetRequest, out var cmd); - var req = cmd.Value.GetRequiredProperties(); - if (req.Length == 1) + if (ptpProcess.ResponsePayloadObject.IsEmpty && define.GetResponse.HasValue) { - DataTreeBranch dataTreeBranch = DataTreeBranch.FromObject(value, null, parameterBag, ERDM_Command.SET_COMMAND); - PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.SET_COMMAND, uid, subDevice, parameterBag, dataTreeBranch); - await runPeerToPeerProcess(ptpProcess); - if (ptpProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Failed) - throw new Exception($"Failed to set parameter {parameterBag.PID} with value {value}"); - if (ptpProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Finished) + if (!(define.GetResponse.Equals(define.SetRequest) || define.SetRequest.Value.EnumValue == Metadata.JSON.Command.ECommandDublicate.GetResponse)) { - if (ptpProcess.ResponsePayloadObject.IsEmpty && define.GetResponse.HasValue) + if (define.GetResponse.Value.ListOfFields.Length == 1) { + var first = dataTreeBranch.Children.FirstOrDefault(c => string.Equals(c.Name, define.GetResponse.Value.ListOfFields[0].ObjectType.Name)); + dataTreeBranch = DataTreeBranch.FromObject(first.Value, null, parameterBag, ERDM_Command.GET_COMMAND_RESPONSE); + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID), dataTreeBranch); - if (this.ParameterValues.TryGetValue(parameterBag.PID, out object cacheValue)) - { - if (value != cacheValue) - throw new Exception($"Failed to set parameter {parameterBag.PID} with value {value}, cache value is {cacheValue}"); - } } - else if (!ptpProcess.ResponsePayloadObject.IsUnset && define.GetResponse.HasValue) - updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID), ptpProcess.ResponsePayloadObject); return true; } + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID), dataTreeBranch); + if (this.ParameterValues.TryGetValue(parameterBag.PID, out object cacheValue)) + { + if (value != cacheValue) + throw new Exception($"Failed to set parameter {parameterBag.PID} with value {value}, cache value is {cacheValue}"); + } } - return false; + else if (!ptpProcess.ResponsePayloadObject.IsUnset && define.GetResponse.HasValue) + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID), ptpProcess.ResponsePayloadObject); + return true; } + //} + return false; + } - protected async Task requestGetParameterWithEmptyPayload(ParameterBag parameterBag, MetadataJSONObjectDefine define, UID uid, SubDevice subDevice) + protected async Task requestGetParameterWithEmptyPayload(ParameterBag parameterBag, MetadataJSONObjectDefine define, UID uid, SubDevice subDevice) + { + try { - try - { - PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, uid, subDevice, parameterBag); - await runPeerToPeerProcess(ptpProcess); - if (!ptpProcess.ResponsePayloadObject.IsUnset) - { - updateParameterValuesDependeciePropertyBag(ptpProcess.ParameterBag.PID, ptpProcess.ResponsePayloadObject); - updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID), ptpProcess.ResponsePayloadObject); - } - return ptpProcess.MessageCounter; - } - catch(Exception e) + PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, uid, subDevice, parameterBag); + await runPeerToPeerProcess(ptpProcess); + if (!ptpProcess.ResponsePayloadObject.IsUnset) { - Logger?.LogError(e, $"Failed to get parameter {parameterBag.PID} with empty payload"); + updateParameterValuesDependeciePropertyBag(ptpProcess.ParameterBag.PID, ptpProcess.ResponsePayloadObject); + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID), ptpProcess.ResponsePayloadObject); } - return 0; + return ptpProcess.MessageCounter; + } + catch (Exception e) + { + Logger?.LogError(e, $"Failed to get parameter {parameterBag.PID} with empty payload"); } - protected async Task requestGetParameterWithPayload(ParameterBag parameterBag, MetadataJSONObjectDefine define, UID uid, SubDevice subDevice, object i=null) + return 0; + } + protected async Task requestGetParameterWithPayload(ParameterBag parameterBag, MetadataJSONObjectDefine define, UID uid, SubDevice subDevice, object i = null) + { + define.GetCommand(Metadata.JSON.Command.ECommandDublicate.GetRequest, out var cmd); + var req = cmd.Value.GetRequiredProperties(); + if (req.Length == 1 && req[0] is Metadata.JSON.OneOfTypes.IIntegerType intType) { - define.GetCommand(Metadata.JSON.Command.ECommandDublicate.GetRequest, out var cmd); - var req = cmd.Value.GetRequiredProperties(); - if (req.Length == 1 && req[0] is Metadata.JSON.OneOfTypes.IIntegerType intType) + try { - try + string name = intType.Name; + var depBag = parameterValuesDependeciePropertyBag.FirstOrDefault(bag => bag.Key.Parameter == parameterBag.PID && bag.Key.Command == Metadata.JSON.Command.ECommandDublicate.GetRequest && string.Equals(bag.Key.Name, name)); + object dependecyValue = depBag.Value; + switch (parameterBag.PID) { - string name = intType.Name; - var depBag = parameterValuesDependeciePropertyBag.FirstOrDefault(bag => bag.Key.Parameter == parameterBag.PID && bag.Key.Command == Metadata.JSON.Command.ECommandDublicate.GetRequest && string.Equals(bag.Key.Name, name)); - IComparable dependecyValue = (IComparable)depBag.Value; + case ERDM_Parameter.STATUS_MESSAGES: + i = (byte)0; + break; + } - if (i == null) + if (i == null) + { + if (dependecyValue == null) { - if(dependecyValue == null) + switch (parameterBag.PID) { - switch (parameterBag.PID) - { - case ERDM_Parameter.STATUS_ID_DESCRIPTION: - break; - default: - Logger?.LogDebug($"No {nameof(dependecyValue)} found for {parameterBag.PID}"); - dependecyValue = (IComparable)intType.GetMaximum(); - break; - } + case ERDM_Parameter.STATUS_ID_DESCRIPTION: + case ERDM_Parameter.STATUS_MESSAGES: + case ERDM_Parameter.METADATA_PARAMETER_VERSION: + case ERDM_Parameter.METADATA_JSON: + break; + + //case ERDM_Parameter.IDENTIFY_ENDPOINT: + //case ERDM_Parameter.ENDPOINT_TO_UNIVERSE: + //case ERDM_Parameter.ENDPOINT_TIMING: + //case ERDM_Parameter.ENDPOINT_LABEL: + //case ERDM_Parameter.ENDPOINT_MODE: + //case ERDM_Parameter.BINDING_CONTROL_FIELDS: + //case ERDM_Parameter.DISCOVERY_STATE: + //case ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE: + //case ERDM_Parameter.BACKGROUND_DISCOVERY: + //case ERDM_Parameter.RDM_TRAFFIC_ENABLE: + //case ERDM_Parameter.ENDPOINT_RESPONDERS: + // if (this.parameterValues.TryGetValue(ERDM_Parameter.ENDPOINT_LIST, out object value)) + // { + // if (value is EndpointDescriptor[] endpoints) + // dependecyValue = (ushort)endpoints.Max(ep => ep.EndpointId); + // } + // break; + default: + Logger?.LogDebug($"No {nameof(dependecyValue)} found for {parameterBag.PID}"); + dependecyValue = (IComparable)intType.GetMaximum(); + break; } - if (dependecyValue != null) + } + if (dependecyValue != null) + { + if (!dependecyValue.GetType().IsArray && dependecyValue is IComparable comparable_dependecyValue) { - if (!dependecyValue.GetType().IsArray) + i = intType.GetMinimum(); + object max = intType.GetMaximum(); + object count = Convert.ChangeType(0, i.GetType()); + object dataOutOfRangeMin = Convert.ChangeType(2, i.GetType()); + while (comparable_dependecyValue.CompareTo(count) > 0) { - i = intType.GetMinimum(); - object max = intType.GetMaximum(); - object count = Convert.ChangeType(0, i.GetType()); - while (dependecyValue.CompareTo(count) > 0) - { - if (!intType.IsInRange(i)) - continue; + if (!intType.IsInRange(i)) + continue; - if (((IComparable)max).CompareTo(i) == -1) - return new RequestResult(0); + if (((IComparable)max).CompareTo(i) == -1) + return new RequestResult(0); - DataTreeBranch dataTreeBranch = new DataTreeBranch(new DataTree(name, 0, i)); - PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, uid, subDevice, parameterBag, dataTreeBranch); - await runPeerToPeerProcess(ptpProcess); - if (ptpProcess.State == EPeerToPeerProcessState.Failed && ptpProcess.NackReason.Contains(ERDM_NackReason.DATA_OUT_OF_RANGE)) + DataTreeBranch dataTreeBranch = new DataTreeBranch(new DataTree(name, 0, i)); + PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, uid, subDevice, parameterBag, dataTreeBranch); + await runPeerToPeerProcess(ptpProcess); + if (ptpProcess.State == EPeerToPeerProcessState.Failed && (ptpProcess.NackReason == ERDM_NackReason.DATA_OUT_OF_RANGE || ptpProcess.NackReason == ERDM_NackReason.UNKNOWN_PID || ptpProcess.NackReason is null)) + { + if (((IComparable)dataOutOfRangeMin).CompareTo(i) < 0) return new RequestResult(ptpProcess); - if (!ptpProcess.ResponsePayloadObject.IsUnset) - updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID, i), ptpProcess.ResponsePayloadObject); - - i = intType.IncrementJumpRange(i); - count = intType.Increment(count); } + if (!ptpProcess.ResponsePayloadObject.IsUnset) + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID, i), ptpProcess.ResponsePayloadObject); + + i = intType.IncrementJumpRange(i); + count = intType.Increment(count); } - else + } + else + { + foreach (var item in (Array)dependecyValue) { - foreach (var item in (Array)dependecyValue) - { - var type = item.GetType(); - i = type.GetProperty(depBag.Key.Property); - DataTreeBranch dataTreeBranch = new DataTreeBranch(new DataTree(name, 0, i)); - PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, uid, subDevice, parameterBag, dataTreeBranch); - await runPeerToPeerProcess(ptpProcess); - if (!ptpProcess.ResponsePayloadObject.IsUnset) - updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID, i), ptpProcess.ResponsePayloadObject); - } + var type = item.GetType(); + i = type.GetProperty(depBag.Key.Property).GetValue(item); + DataTreeBranch dataTreeBranch = new DataTreeBranch(new DataTree(name, 0, i)); + PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, uid, subDevice, parameterBag, dataTreeBranch); + await runPeerToPeerProcess(ptpProcess); + if (!ptpProcess.ResponsePayloadObject.IsUnset) + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID, i), ptpProcess.ResponsePayloadObject); } - return new RequestResult(0); } - } - else - { - DataTreeBranch dataTreeBranch = new DataTreeBranch(new DataTree(name, 0, i)); - PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, uid, subDevice, parameterBag, dataTreeBranch); - await runPeerToPeerProcess(ptpProcess); - if (!ptpProcess.ResponsePayloadObject.IsUnset) - updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID, parameterBag.PID == ERDM_Parameter.QUEUED_MESSAGE || parameterBag.PID == ERDM_Parameter.STATUS_MESSAGES ? null : i), ptpProcess.ResponsePayloadObject); - return new RequestResult(ptpProcess); + return new RequestResult(0); } } - catch (Exception e) + else { - Logger?.LogError(e, $"Failed to get parameter {parameterBag.PID} with Bag: {parameterBag}"); + DataTreeBranch dataTreeBranch = new DataTreeBranch(new DataTree(name, 0, i)); + PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, uid, subDevice, parameterBag, dataTreeBranch); + await runPeerToPeerProcess(ptpProcess); + if (!ptpProcess.ResponsePayloadObject.IsUnset) + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID, parameterBag.PID == ERDM_Parameter.QUEUED_MESSAGE || parameterBag.PID == ERDM_Parameter.STATUS_MESSAGES ? null : i), ptpProcess.ResponsePayloadObject); + return new RequestResult(ptpProcess); } } - return new RequestResult(0); + catch (Exception e) + { + Logger?.LogError(e, $"Failed to get parameter {parameterBag.PID} with Bag: {parameterBag}"); + } } + return new RequestResult(0); + } + + + public void Dispose() + { + if (this.IsDisposed || this.IsDisposing) + return; + + this.IsDisposing = true; + this.parameterValues.Clear(); + this.parameterValues = null; + this.parameterValuesDataTreeBranch.Clear(); + this.parameterValuesDataTreeBranch = null; + this.parameterValuesDependeciePropertyBag.Clear(); + this.parameterValuesDependeciePropertyBag = null; + this.IsDisposed = true; + this.IsDisposing = false; + } + + public class RequestResult + { + public readonly byte MessageCounter; + public readonly EPeerToPeerProcessState State; + public readonly Exception Exception; - public void Dispose() + public RequestResult(PeerToPeerProcess peerToPeerProcess) : this(peerToPeerProcess.MessageCounter, peerToPeerProcess.State) { - if (this.IsDisposed || this.IsDisposing) - return; - - this.IsDisposing = true; - - this.parameterValues.Clear(); - this.parameterValues = null; - this.parameterValuesDataTreeBranch.Clear(); - this.parameterValuesDataTreeBranch = null; - this.parameterValuesDependeciePropertyBag.Clear(); - this.parameterValuesDependeciePropertyBag = null; - this.IsDisposed = true; - this.IsDisposing = false; + Exception = peerToPeerProcess.Exception; } - - public class RequestResult + public RequestResult(byte messageCounter, EPeerToPeerProcessState state) { - public readonly byte MessageCounter; - public readonly EPeerToPeerProcessState State; - public readonly Exception Exception; - - public RequestResult(PeerToPeerProcess peerToPeerProcess) : this(peerToPeerProcess.MessageCounter, peerToPeerProcess.State) - { - Exception = peerToPeerProcess.Exception; - } - public RequestResult(byte messageCounter, EPeerToPeerProcessState state) - { - MessageCounter = messageCounter; - State = state; - } - public RequestResult(byte messageCounter) - { - MessageCounter = messageCounter; - } + MessageCounter = messageCounter; + State = state; + } + public RequestResult(byte messageCounter) + { + MessageCounter = messageCounter; } } } \ No newline at end of file diff --git a/RDMSharp/RDM/Device/AbstractRDMDevice.cs b/RDMSharp/RDM/Device/AbstractRDMDevice.cs index 73430791..205342b3 100644 --- a/RDMSharp/RDM/Device/AbstractRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractRDMDevice.cs @@ -1,121 +1,125 @@ -using System; +using RDMSharp.PayloadObject; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Threading.Tasks; -namespace RDMSharp +namespace RDMSharp; + +public abstract class AbstractRDMDevice : AbstractRDMCache, IRDMDevice { - public abstract class AbstractRDMDevice : AbstractRDMCache, IRDMDevice - { - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler PropertyChanged; - private readonly UID uid; - public UID UID => uid; + private readonly UID uid; + public UID UID => uid; - private readonly SubDevice subdevice; - public SubDevice Subdevice => subdevice; + private readonly SubDevice subdevice; + public SubDevice Subdevice => subdevice; - public abstract RDMDeviceInfo DeviceInfo { get; } - public abstract IReadOnlyDictionary Sensors { get; } - public abstract IReadOnlyDictionary Slots { get; } - public abstract IReadOnlyDictionary StatusMessages { get; } + public abstract RDMDeviceInfo DeviceInfo { get; } + public abstract IReadOnlyDictionary Sensors { get; } + public abstract IReadOnlyDictionary Slots { get; } + public abstract IReadOnlyDictionary StatusMessages { get; } - private List subDevices; - protected IList SubDevices_Internal { get => subDevices; } - public IReadOnlyCollection SubDevices => SubDevices_Internal?.AsReadOnly(); + private List subDevices; + protected IList SubDevices_Internal { get => subDevices; } + public IReadOnlyCollection SubDevices => SubDevices_Internal?.AsReadOnly(); - public new bool IsDisposing { get; private set; } - public new bool IsDisposed { get; private set; } - public bool IsInitialized { get; private set; } - public abstract bool IsGenerated { get; } + public new bool IsDisposing { get; private set; } + public new bool IsDisposed { get; private set; } + public bool IsInitialized { get; private set; } + public bool IsInitializing { get; private set; } + protected virtual bool AutoInitialize { get { return true; } } + public abstract bool IsGenerated { get; } - protected AbstractRDMDevice(UID uid, SubDevice? subDevice = null, IRDMDevice[] subDevices = null) - { - this.uid = uid; - this.subdevice = subDevice ?? SubDevice.Root; - if (subDevices != null && !this.Subdevice.IsRoot) - throw new NotSupportedException($"A SubDevice {this.Subdevice} can't have SubDevices."); + protected AbstractRDMDevice(UID uid, SubDevice? subDevice = null, IRDMDevice[] subDevices = null) + { + this.uid = uid; + this.subdevice = subDevice ?? SubDevice.Root; + if (subDevices != null && !this.Subdevice.IsRoot) + throw new NotSupportedException($"A SubDevice {this.Subdevice} can't have SubDevices."); - if (this.Subdevice.IsBroadcast) - throw new NotSupportedException($"A SubDevice can't be Broadcast."); + if (this.Subdevice.IsBroadcast) + throw new NotSupportedException($"A SubDevice can't be Broadcast."); - if (this.Subdevice == SubDevice.Root) - { - this.subDevices = new List(); - this.subDevices.Add(this); + if (this.Subdevice == SubDevice.Root) + { + this.subDevices = new List(); + this.subDevices.Add(this); - if (subDevices != null) - this.subDevices.AddRange(subDevices); + if (subDevices != null) + this.subDevices.AddRange(subDevices); - if (this.subDevices.Distinct().Count() != this.subDevices.Count) - throw new InvalidOperationException($"The SubDevices of {this.UID} are not unique."); + if (this.subDevices.Distinct().Count() != this.subDevices.Count) + throw new InvalidOperationException($"The SubDevices of {this.UID} are not unique."); + if (AutoInitialize) _ = performInitialize(); - } } + } - protected async Task performInitialize(RDMDeviceInfo deviceInfo=null) - { - if (this.IsInitialized) - return; + protected async Task performInitialize(RDMDeviceInfo deviceInfo = null) + { + if (this.IsInitialized) + return; + IsInitializing = true; + await initialize(deviceInfo); + IsInitialized = true; + IsInitializing = false; + } - await initialize(deviceInfo); - this.IsInitialized = true; - } + protected virtual async Task initialize(RDMDeviceInfo deviceInfo = null) + { + if (this.Subdevice.IsRoot) + foreach (AbstractRDMDevice sd in this.subDevices) + { + if (sd.Subdevice.IsRoot) + continue; + await sd.performInitialize(); + } + } - protected virtual async Task initialize(RDMDeviceInfo deviceInfo = null) - { - if (this.Subdevice.IsRoot) - foreach (AbstractRDMDevice sd in this.subDevices) - { - if (sd.Subdevice.IsRoot) - continue; - await sd.performInitialize(); - } - } + protected virtual void OnPropertyChanged(string property) + { + this.PropertyChanged.InvokeFailSafe(this, new PropertyChangedEventArgs(property)); + } - protected virtual void OnPropertyChanged(string property) - { - this.PropertyChanged.InvokeFailSafe(this, new PropertyChangedEventArgs(property)); - } + public virtual IReadOnlyDictionary GetAllParameterValues() + { + return this.ParameterValues; + } - public virtual IReadOnlyDictionary GetAllParameterValues() - { - return this.ParameterValues; - } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1816:Dispose-Methoden müssen SuppressFinalize aufrufen", Justification = "")] + public new void Dispose() + { + if (IsDisposing || IsDisposed) + return; + IsDisposing = true; - [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1816:Dispose-Methoden müssen SuppressFinalize aufrufen", Justification = "")] - public new void Dispose() + try { - if (IsDisposing || IsDisposed) - return; - IsDisposing = true; - - try - { - OnDispose(); - } - catch { } - finally - { - IsDisposed = true; - IsDisposing = false; - } + OnDispose(); } - protected abstract void OnDispose(); - - public override string ToString() + catch { } + finally { - if (!this.Subdevice.IsRoot) - return $"[{UID}] ({this.Subdevice})"; - return $"[{UID}]"; + IsDisposed = true; + IsDisposing = false; } } + protected abstract void OnDispose(); + + public override string ToString() + { + if (!this.Subdevice.IsRoot) + return $"[{UID}] ({this.Subdevice})"; + return $"[{UID}]"; + } } \ No newline at end of file diff --git a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs index 22569f4e..2a23aeef 100644 --- a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs @@ -1,5 +1,9 @@ using Microsoft.Extensions.Logging; +using RDMSharp.Extensions; using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device; +using RDMSharp.RDM.Device.Module; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -8,573 +12,697 @@ using System.Threading; using System.Threading.Tasks; -namespace RDMSharp +namespace RDMSharp; + +public interface IRDMRemoteDevice : IRDMDevice { - public interface IRDMRemoteDevice: IRDMDevice - { - bool AllDataPulled { get; } - bool Present { get; } - DateTime LastSeen { get; } - Task SetParameter(ERDM_Parameter parameter, object value = null); - } - public interface IRDMRemoteSubDevice : IRDMRemoteDevice - { - } - public abstract class AbstractRemoteRDMDevice : AbstractRDMDevice , IRDMRemoteDevice - { - public sealed override bool IsGenerated => false; + bool AllDataPulled { get; } + bool Present { get; } + DateTime LastSeen { get; } + ushort Universe { get; } + + Task SetParameter(ERDM_Parameter parameter, object value = null); +} +public interface IRDMRemoteSubDevice : IRDMRemoteDevice +{ +} +public abstract class AbstractRemoteRDMDevice : AbstractRDMDevice, IRDMRemoteDevice +{ + public sealed override bool IsGenerated => false; - private readonly ConcurrentDictionary sensors = new ConcurrentDictionary(); - public sealed override IReadOnlyDictionary Sensors { get { return sensors.AsReadOnly(); } } - public sealed override IReadOnlyDictionary Slots { get { return PersonalityModel?.Slots; } } + private readonly ConcurrentDictionary sensors = new ConcurrentDictionary(); + public sealed override IReadOnlyDictionary Sensors { get { return sensors.AsReadOnly(); } } + public sealed override IReadOnlyDictionary Slots { get { return PersonalityModel?.Slots; } } - private readonly ConcurrentDictionary statusMessages = new ConcurrentDictionary(); - public sealed override IReadOnlyDictionary StatusMessages { get { return statusMessages.AsReadOnly(); } } + private readonly ConcurrentDictionary statusMessages = new ConcurrentDictionary(); + public sealed override IReadOnlyDictionary StatusMessages { get { return statusMessages.AsReadOnly(); } } - protected ConcurrentQueue ParameterUpdatedBag = new ConcurrentQueue(); + protected ConcurrentQueue ParameterUpdatedBag = new ConcurrentQueue(); - private RDMDeviceInfo deviceInfo; - public override RDMDeviceInfo DeviceInfo { get { return deviceInfo; } } + private RDMDeviceInfo deviceInfo; + public override RDMDeviceInfo DeviceInfo { get { return deviceInfo; } } - private RDMDeviceModel deviceModel; - public RDMDeviceModel DeviceModel + private RDMDeviceModel deviceModel; + public RDMDeviceModel DeviceModel + { + get { return deviceModel; } + private set { - get { return deviceModel; } - private set - { - if (deviceModel == value) - return; - deviceModel = value; - OnPropertyChanged(nameof(DeviceModel)); - } + if (deviceModel == value) + return; + deviceModel = value; + OnPropertyChanged(nameof(DeviceModel)); } - private RDMPersonalityModel personalityModel; - public RDMPersonalityModel PersonalityModel + } + private RDMPersonalityModel personalityModel; + public RDMPersonalityModel PersonalityModel + { + get { return personalityModel; } + private set { - get { return personalityModel; } - private set - { - if (personalityModel == value) - return; - personalityModel = value; - OnPropertyChanged(nameof(PersonalityModel)); - } + if (personalityModel == value) + return; + personalityModel = value; + OnPropertyChanged(nameof(PersonalityModel)); } - public sealed override IReadOnlyDictionary ParameterValues + } + public sealed override IReadOnlyDictionary ParameterValues + { + get { - get - { - if (DeviceModel == null) - return parameterValues.AsReadOnly(); + if (DeviceModel == null) + return parameterValues.AsReadOnly(); - return DeviceModel.ParameterValues.Where(x => !parameterValues.ContainsKey(x.Key)).Concat(parameterValues).ToDictionary(k => k.Key, v => v.Value).AsReadOnly(); - } + return DeviceModel.ParameterValues.Where(x => !parameterValues.ContainsKey(x.Key)).Concat(parameterValues).ToDictionary(k => k.Key, v => v.Value).AsReadOnly(); } - - private bool allDataPulled; - public bool AllDataPulled + } + public sealed override IReadOnlyDictionary ParameterMetadataBag + { + get { - get - { - return allDataPulled; - } - private set - { - if (allDataPulled == value) - return; - allDataPulled = value; - OnPropertyChanged(nameof(AllDataPulled)); - } - } + IReadOnlyDictionary deviceModelParameterMetadataBag = null; + IReadOnlyDictionary personalityModelParameterMetadataBag = null; + if (PersonalityModel is not null) + personalityModelParameterMetadataBag = PersonalityModel.ParameterMetadataBag.Where(x => !parameterMetadataBag.ContainsKey(x.Key)).ToDictionary(k => k.Key, v => v.Value).AsReadOnly(); + if (DeviceModel is not null) + deviceModelParameterMetadataBag = DeviceModel.ParameterMetadataBag.Where(x => !parameterMetadataBag.ContainsKey(x.Key) && !(personalityModelParameterMetadataBag?.ContainsKey(x.Key) ?? false)).ToDictionary(k => k.Key, v => v.Value).AsReadOnly(); - private DateTime lastSeen; - public DateTime LastSeen - { - get - { - return lastSeen; - } - private set - { - if (lastSeen == value) - return; - lastSeen = value; - OnPropertyChanged(nameof(LastSeen)); - } + if (deviceModelParameterMetadataBag is not null || personalityModelParameterMetadataBag is not null) + return parameterMetadataBag.Concat(deviceModelParameterMetadataBag ?? Enumerable.Empty>()) + .Concat(personalityModelParameterMetadataBag ?? Enumerable.Empty>()) + .ToDictionary(k => k.Key, v => v.Value) + .AsReadOnly(); + + return parameterMetadataBag.AsReadOnly(); } + } - private DateTime lastSendQueuedMessage; + private readonly List _modules = new List(); + public IReadOnlyCollection Modules { get => _modules.AsReadOnly(); } - private bool present; - public bool Present + private bool allDataPulled; + public bool AllDataPulled + { + get { - get - { - return present; - } - internal set - { - if (present == value) - return; - present = value; - OnPropertyChanged(nameof(Present)); - } + return allDataPulled; + } + private set + { + if (allDataPulled == value) + return; + allDataPulled = value; + OnPropertyChanged(nameof(AllDataPulled)); } + } - private bool queuedSupported = true; - public bool QueuedSupported + private DateTime lastSeen; + public DateTime LastSeen + { + get { - get - { - return queuedSupported; - } - private set - { - if (queuedSupported == value) - return; - queuedSupported = value; - OnPropertyChanged(nameof(QueuedSupported)); - } + return lastSeen; + } + private set + { + if (lastSeen == value) + return; + lastSeen = value; + OnPropertyChanged(nameof(LastSeen)); } + } + private DateTime lastSendQueuedMessage; - public AbstractRemoteRDMDevice(UID uid) : base(uid) + private bool present; + public bool Present + { + get { + return present; } - public AbstractRemoteRDMDevice(UID uid, SubDevice? subDevice = null) : base(uid, subDevice) + internal set { - if (subDevice.HasValue && subDevice.Value.IsBroadcast) - throw new NotSupportedException("A SubDevice can't be Broadcast."); + if (present == value) + return; + present = value; + OnPropertyChanged(nameof(Present)); } - protected override async Task initialize(RDMDeviceInfo deviceInfo = null) + } + + private ushort universe; + public ushort Universe + { + get { - Logger?.LogDebug($"Remote RDM Device {UID} SubDevice: {Subdevice} initializing."); - await base.initialize(deviceInfo); - GlobalTimers.Instance.PresentUpdateTimerElapsed += Instance_PresentUpdateTimerElapsed; - ParameterValueAdded += AbstractRDMDevice_ParameterValueAdded; - ParameterValueChanged += AbstractRDMDevice_ParameterValueChanged; - ParameterRequested += AbstractRDMDevice_ParameterRequested; - await requestDeviceInfo(deviceInfo); - Logger ?.LogDebug($"Remote RDM Device {UID} SubDevice: {Subdevice} initialized."); + return universe; } - - private void Instance_PresentUpdateTimerElapsed(object sender, EventArgs e) + protected set { - Present = DateTime.UtcNow - lastSeen < TimeSpan.FromMilliseconds(GlobalTimers.Instance.PresentLostTime); + if (universe == value) + return; + universe = value; + OnPropertyChanged(nameof(Universe)); } + } - private async void DeviceModel_Initialized(object sender, EventArgs e) + public AbstractRemoteRDMDevice(UID uid) : base(uid) + { + } + public AbstractRemoteRDMDevice(UID uid, SubDevice? subDevice = null) : base(uid, subDevice) + { + if (subDevice.HasValue && subDevice.Value.IsBroadcast) + throw new NotSupportedException("A SubDevice can't be Broadcast."); + } + protected override async Task initialize(RDMDeviceInfo deviceInfo = null) + { + Logger?.LogDebug($"Remote RDM Device {UID} SubDevice: {Subdevice} initializing."); + await base.initialize(deviceInfo); + GlobalTimers.Instance.PresentUpdateTimerElapsed += Instance_PresentUpdateTimerElapsed; + ParameterValueAdded += AbstractRDMDevice_ParameterValueAdded; + ParameterValueChanged += AbstractRDMDevice_ParameterValueChanged; + ParameterRequested += AbstractRDMDevice_ParameterRequested; + await requestDeviceInfo(deviceInfo); + await Task.Delay(100); + await UpdateModules(); + Logger?.LogDebug($"Remote RDM Device {UID} SubDevice: {Subdevice} initialized."); + + RDMSharp.Instance.AddRemoteDeviceToCache(this); + } + + private async Task UpdateModules() + { + //while (deviceModel is null) + //{ + // await Task.Delay(100); + //} + + if (ExtensionsManager.Instance.TryGetMatchingModules(this, out var modules)) { - deviceModel.Initialized -= DeviceModel_Initialized; - deviceModel.ParameterValueAdded -= DeviceModel_ParameterValueAdded; - await getPersonalityModelAndCollectAllParameters(); - await collectParameters(); + this._modules.Clear(); + this._modules.AddRange(modules); + OnPropertyChanged(nameof(Modules)); } - private async Task collectParameters() + } + + private async void Instance_PresentUpdateTimerElapsed(object sender, EventArgs e) + { + bool result = DateTime.UtcNow - lastSeen < TimeSpan.FromMilliseconds(GlobalTimers.Instance.PresentLostTime); + + if (!result) { - await collectAllParametersOnRoot(); - await scanSubDevices(); - AllDataPulled = true; - GlobalTimers.Instance.ParameterUpdateTimerElapsed += Instance_ParameterUpdateTimerElapsed; + + _ = updateParameters(); + await Task.Delay(1000); + result = DateTime.UtcNow - lastSeen < TimeSpan.FromMilliseconds(GlobalTimers.Instance.PresentLostTime); } - private async Task scanSubDevices() - { - if (DeviceInfo.SubDeviceCount == 0) - return; - if (!this.Subdevice.IsRoot) - return; + Present = result; + } - ushort foundSubDevices = 0; - ushort currentID = 0; - var dict = new Dictionary(); - while (foundSubDevices < DeviceInfo.SubDeviceCount) - { - currentID++; - if (currentID > 512) - break; + private async void DeviceModel_Initialized(object sender, EventArgs e) + { + deviceModel.Initialized -= DeviceModel_Initialized; + deviceModel.ParameterValueAdded -= DeviceModel_ParameterValueAdded; + await getPersonalityModelAndCollectAllParameters(); + await collectParameters(); + } + private async Task collectParameters() + { + await collectAllParametersOnRoot(); + await scanSubDevices(); + AllDataPulled = true; + GlobalTimers.Instance.ParameterUpdateTimerElapsed += Instance_ParameterUpdateTimerElapsed; + } - PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, UID, new SubDevice(currentID), new ParameterBag(ERDM_Parameter.DEVICE_INFO)); - await runPeerToPeerProcess(ptpProcess); - if (ptpProcess.ResponsePayloadObject.ParsedObject is RDMDeviceInfo _deviceInfo) - { - foundSubDevices++; - var subDevice = createSubDevice(UID, ptpProcess.SubDevice); - this.SubDevices_Internal.Add(subDevice); - dict.Add(ptpProcess.SubDevice, _deviceInfo); - } - await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenRequests); - } - foreach (AbstractRemoteRDMDevice sd in this.SubDevices_Internal) + private async Task scanSubDevices() + { + if (DeviceInfo.SubDeviceCount == 0) + return; + if (!this.Subdevice.IsRoot) + return; + + ushort foundSubDevices = 0; + ushort currentID = 0; + var dict = new Dictionary(); + while (foundSubDevices < DeviceInfo.SubDeviceCount) + { + currentID++; + if (currentID > 512) + break; + + PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, UID, new SubDevice(currentID), new ParameterBag(ERDM_Parameter.DEVICE_INFO)); + await runPeerToPeerProcess(ptpProcess); + if (ptpProcess.ResponsePayloadObject.ParsedObject is RDMDeviceInfo _deviceInfo) { - if (sd.Subdevice.IsRoot) - continue; - sd.performInitialize(dict[sd.Subdevice]); + foundSubDevices++; + var subDevice = createSubDevice(UID, ptpProcess.SubDevice); + this.SubDevices_Internal.Add(subDevice); + dict.Add(ptpProcess.SubDevice, _deviceInfo); } + await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenRequests); + } + foreach (AbstractRemoteRDMDevice sd in this.SubDevices_Internal) + { + if (sd.Subdevice.IsRoot) + continue; + sd.performInitialize(dict[sd.Subdevice]); } + } - protected abstract IRDMRemoteSubDevice createSubDevice(UID uid, SubDevice subDevice); + protected abstract IRDMRemoteSubDevice createSubDevice(UID uid, SubDevice subDevice); - #region Requests + #region Requests - private async Task requestDeviceInfo(RDMDeviceInfo deviceInfo = null) + private async Task requestDeviceInfo(RDMDeviceInfo deviceInfo = null) + { + DataTreeBranch? rpl = null; + if (deviceInfo == null) { - DataTreeBranch? rpl = null; - if (deviceInfo == null) + PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, UID, Subdevice, new ParameterBag(ERDM_Parameter.DEVICE_INFO)); + await runPeerToPeerProcess(ptpProcess); + rpl = ptpProcess.ResponsePayloadObject; + if (rpl.Value.ParsedObject is RDMDeviceInfo _deviceInfo) { - PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, UID, Subdevice, new ParameterBag(ERDM_Parameter.DEVICE_INFO)); - await runPeerToPeerProcess(ptpProcess); - rpl= ptpProcess.ResponsePayloadObject; - if (rpl.Value.ParsedObject is RDMDeviceInfo _deviceInfo) - { - this.deviceInfo = _deviceInfo; - updateParameterValuesDependeciePropertyBag(ERDM_Parameter.DEVICE_INFO, ptpProcess.ResponsePayloadObject); - updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ERDM_Parameter.DEVICE_INFO), ptpProcess.ResponsePayloadObject); - await getDeviceModelAndCollectAllParameters(); - } + this.deviceInfo = _deviceInfo; + updateParameterValuesDependeciePropertyBag(ERDM_Parameter.DEVICE_INFO, ptpProcess.ResponsePayloadObject); + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ERDM_Parameter.DEVICE_INFO), ptpProcess.ResponsePayloadObject); + await getDeviceModelAndCollectAllParameters(); } else { - rpl = DataTreeBranch.FromObject(deviceInfo, null, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DEVICE_INFO); - this.deviceInfo = deviceInfo; - updateParameterValuesDependeciePropertyBag(ERDM_Parameter.DEVICE_INFO, rpl.Value); - updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ERDM_Parameter.DEVICE_INFO), rpl.Value); - await getDeviceModelAndCollectAllParameters(); + await Task.Delay(1000); + await requestDeviceInfo(); } } - private async Task requestParameters() + else + { + rpl = DataTreeBranch.FromObject(deviceInfo, null, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DEVICE_INFO); + this.deviceInfo = deviceInfo; + updateParameterValuesDependeciePropertyBag(ERDM_Parameter.DEVICE_INFO, rpl.Value); + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ERDM_Parameter.DEVICE_INFO), rpl.Value); + await getDeviceModelAndCollectAllParameters(); + } + if (DeviceModel is null) { - var parameters = this.DeviceModel?.SupportedNonBlueprintParameters.OrderBy(p=>(ushort)p).ToList(); - if (parameters == null) - return; - foreach (ERDM_Parameter parameter in parameters) + } + } + private async Task requestParameters() + { + var parameters = this.DeviceModel?.GetSupportedNonBlueprintParameters().Select(spm => spm.Parameter); + if (parameters == null) + return; + + foreach (ERDM_Parameter parameter in parameters) + { + switch (parameter) { - switch (parameter) - { - case ERDM_Parameter.DEVICE_INFO: - continue; - case ERDM_Parameter.QUEUED_MESSAGE: - continue; - case ERDM_Parameter.STATUS_MESSAGES: - await requestParameter(parameter, ERDM_Status.NONE); - continue; - } - await requestParameter(parameter); - await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenRequests); + case ERDM_Parameter.DEVICE_INFO: + continue; + case ERDM_Parameter.QUEUED_MESSAGE: + tryAddParameterMetadata(parameter); + continue; + case ERDM_Parameter.STATUS_MESSAGES: + await requestParameter(parameter, ERDM_Status.NONE); + continue; } + tryAddParameterMetadata(parameter); + await requestParameter(parameter); + await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenRequests); } - private async Task requestParameter(ERDM_Parameter parameter, object payload = null) + } + private async Task requestParameter(ERDM_Parameter parameter, object payload = null) + { + try { - try + ParameterBag parameterBag = new ParameterBag(parameter, this.DeviceModel.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); + var define = MetadataFactory.GetDefine(parameterBag); + if (define == null) { - ParameterBag parameterBag = new ParameterBag(parameter, this.DeviceModel.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); - var define = MetadataFactory.GetDefine(parameterBag); - if (define == null) - { - ConcurrentDictionary pd = null; - if (this.deviceModel.ParameterValues.TryGetValue(ERDM_Parameter.PARAMETER_DESCRIPTION, out var obj)) - pd = obj as ConcurrentDictionary; + ConcurrentDictionary pd = null; + if (this.deviceModel.ParameterValues.TryGetValue(ERDM_Parameter.PARAMETER_DESCRIPTION, out var obj)) + pd = obj as ConcurrentDictionary; - if ((pd?.TryGetValue((ushort)parameter, out var desc) ?? false) && desc is RDMParameterDescription pDesc) - { - if (pDesc.CommandClass.HasFlag(ERDM_CommandClass.GET)) - await requestGetParameterWithEmptyPayload(parameterBag, define, UID, Subdevice); - } - } - if (define?.GetRequest.HasValue ?? false) + if ((pd?.TryGetValue((ushort)parameter, out var desc) ?? false) && desc is RDMParameterDescription pDesc) { - if (define.GetRequest.Value.GetIsEmpty()) + if (pDesc.CommandClass.HasFlag(ERDM_CommandClass.GET)) await requestGetParameterWithEmptyPayload(parameterBag, define, UID, Subdevice); - else - await requestGetParameterWithPayload(parameterBag, define, UID, Subdevice, payload); } } - catch (Exception ex) + if (define?.GetRequest.HasValue ?? false) { - Logger?.LogError(ex); + if (define.GetRequest.Value.GetIsEmpty()) + await requestGetParameterWithEmptyPayload(parameterBag, define, UID, Subdevice); + else + await requestGetParameterWithPayload(parameterBag, define, UID, Subdevice, payload); } } + catch (Exception ex) + { + Logger?.LogError(ex); + } + } + public async Task RequestParameter(ERDM_Command command, ERDM_Parameter parameter) + { + ParameterBag parameterBag = new ParameterBag(parameter, this.UID.ManufacturerID, this.deviceInfo.DeviceModelId, this.deviceInfo.SoftwareVersionId); - private SemaphoreSlim updateSenaphoreSlim = new SemaphoreSlim(1); - private async Task updateParameters() + PeerToPeerProcess ptpProcess = new PeerToPeerProcess(command, this.UID, this.Subdevice, parameterBag); + await runPeerToPeerProcess(ptpProcess); + if (!ptpProcess.ResponsePayloadObject.IsUnset) { - if (QueuedSupported && deviceModel.KnownNotSupportedParameters.Contains(ERDM_Parameter.QUEUED_MESSAGE)) - QueuedSupported = false; + updateParameterValuesDependeciePropertyBag(ptpProcess.ParameterBag.PID, ptpProcess.ResponsePayloadObject); + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID), ptpProcess.ResponsePayloadObject); + } + } + public async Task RequestParameterWithPayload(ERDM_Command command, ERDM_Parameter parameter, object payload) + { + ParameterBag parameterBag = new ParameterBag(parameter, this.UID.ManufacturerID, this.deviceInfo.DeviceModelId, this.deviceInfo.SoftwareVersionId); + DataTreeBranch dataTreeBranch = DataTreeBranch.FromObject(payload, null, parameterBag, command); - if (updateSenaphoreSlim.CurrentCount == 0) - return; + PeerToPeerProcess ptpProcess = new PeerToPeerProcess(command, this.UID, this.Subdevice, parameterBag, dataTreeBranch); + await ptpProcess.Run(); + if (ptpProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Finished) + return ptpProcess.ResponsePayloadObject.ParsedObject ?? ptpProcess.ResponsePayloadObject; + + return null; + } + + private SemaphoreSlim updateSenaphoreSlim = new SemaphoreSlim(1); + private async Task updateParameters() + { + var supportedParameters = this.DeviceModel?.GetSupportedNonBlueprintParameters(); - await updateSenaphoreSlim.WaitAsync(); - try + if (updateSenaphoreSlim.CurrentCount == 0) + return; + + await updateSenaphoreSlim.WaitAsync(); + try + { + await requestQueuedMessages(); + var loopDetectionCache = new HashSet(); + while (ParameterUpdatedBag.TryPeek(out ParameterUpdatedBag bag)) { - if (QueuedSupported && !deviceModel.KnownNotSupportedParameters.Contains(ERDM_Parameter.QUEUED_MESSAGE)) - { - if (DateTime.UtcNow - lastSendQueuedMessage < TimeSpan.FromMilliseconds(GlobalTimers.Instance.QueuedUpdateTime)) - return; - ParameterBag parameterBag = new ParameterBag(ERDM_Parameter.QUEUED_MESSAGE, this.DeviceModel.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); - var define = MetadataFactory.GetDefine(parameterBag); - if (define.GetRequest.HasValue) + TimeSpan updateTime = TimeSpan.FromMilliseconds(GlobalTimers.Instance.NonQueuedUpdateTime); + //if (bag.Parameter.GetAttribute() is ParameterUpdateTimeAttribute attribute) + // updateTime = TimeSpan.FromMilliseconds(attribute.Milliseconds); + if ((supportedParameters.FirstOrDefault(spm => spm.Parameter == bag.Parameter)?.ParameterUpdateTimeMilliseconds is int milliseconds) && milliseconds >= 0) + updateTime = TimeSpan.FromMilliseconds(milliseconds); + + if (loopDetectionCache.Any(b => b.Parameter == bag.Parameter && b.Index == bag.Index)) + return; + + bool performRequestToDetectIsStillConnected = ((DateTime.UtcNow - this.lastSeen).TotalMilliseconds / (double)GlobalTimers.Instance.PresentLostTime) >= 0.9; + + if (!performRequestToDetectIsStillConnected) + if (DateTime.UtcNow - bag.Timestamp < updateTime) { - byte mc = 0; - do - { - var cts = new CancellationTokenSource(); - cts.CancelAfter(TimeSpan.FromMilliseconds(GlobalTimers.Instance.ParameterUpdateTimerInterval)); - var task = Task.Run(async () => - { - lastSendQueuedMessage = DateTime.UtcNow; - - Stopwatch sw = new Stopwatch(); - sw?.Restart(); - var result = await requestGetParameterWithPayload(parameterBag, define, UID, Subdevice, ERDM_Status.ADVISORY); - mc = result.MessageCounter; - sw?.Stop(); - if (result.State == PeerToPeerProcess.EPeerToPeerProcessState.Failed) - { - if (sw.Elapsed.TotalSeconds > 3) - QueuedSupported = false; - Logger?.LogWarning($"Queued Parameter failed after {sw.ElapsedMilliseconds}ms, Queued seems not supported, and wil be disabled"); - return; - } - Logger?.LogTrace($"Queued Parameter update took {sw.ElapsedMilliseconds}ms for {mc} messages."); - }, cts.Token); - await task; - - if (task.IsCompletedSuccessfully) - await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenQueuedUpdateRequests); - else - { - Logger?.LogTrace(task.Exception, $"Queue Parameter update failed: {task.Exception?.Message}"); - return; - } - - } - while (mc != 0); - return; + ParameterUpdatedBag.TryDequeue(out _); + ParameterUpdatedBag.Enqueue(bag); + + loopDetectionCache.Add(bag); + continue; } - } - while (ParameterUpdatedBag.TryPeek(out ParameterUpdatedBag bag)) + + loopDetectionCache.Add(bag); + + var cts = new CancellationTokenSource(); + cts.CancelAfter(TimeSpan.FromMilliseconds(GlobalTimers.Instance.ParameterUpdateTimerInterval)); + var task = Task.Run(async () => { - if (DateTime.UtcNow - bag.Timestamp < TimeSpan.FromMilliseconds(GlobalTimers.Instance.NonQueuedUpdateTime)) - return; + Stopwatch sw = new Stopwatch(); + sw?.Restart(); + await requestParameter(bag.Parameter, bag.Index); + sw?.Stop(); + Logger?.LogTrace($"Parameter update for {bag.Parameter} with index {bag.Index} took {sw.ElapsedMilliseconds}ms"); + + UpdateParameterUpdatedBag(bag.Parameter, bag.Index); + }, cts.Token); + await task; + + if (task.IsCompletedSuccessfully) + await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenNonQueuedUpdateRequests); + else + Logger?.LogTrace(task.Exception, $"Parameter update for {bag.Parameter} with index {bag.Index} failed: {task.Exception?.Message}"); + } + } + catch (Exception ex) + { + Logger?.LogError(ex); + } + finally + { + updateSenaphoreSlim.Release(); + } + } + private async Task requestQueuedMessages() + { + var supportedParameters = this.deviceModel?.GetSupportedNonBlueprintParameters(); + if (supportedParameters?.FirstOrDefault(spm => spm.Parameter == ERDM_Parameter.QUEUED_MESSAGE)?.IsSupported ?? false) + { + if (DateTime.UtcNow - lastSendQueuedMessage < TimeSpan.FromMilliseconds(GlobalTimers.Instance.QueuedUpdateTime)) + return; + ParameterBag parameterBag = new ParameterBag(ERDM_Parameter.QUEUED_MESSAGE, this.DeviceModel.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); + var define = MetadataFactory.GetDefine(parameterBag); + if (define.GetRequest.HasValue) + { + byte mc = 0; + do + { var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromMilliseconds(GlobalTimers.Instance.ParameterUpdateTimerInterval)); var task = Task.Run(async () => { + lastSendQueuedMessage = DateTime.UtcNow; + Stopwatch sw = new Stopwatch(); sw?.Restart(); - await requestParameter(bag.Parameter, bag.Index); + var result = await requestGetParameterWithPayload(parameterBag, define, UID, Subdevice, ERDM_Status.ADVISORY); + mc = result.MessageCounter; sw?.Stop(); - Logger?.LogTrace($"Parameter update for {bag.Parameter} with index {bag.Index} took {sw.ElapsedMilliseconds}ms"); - - UpdateParameterUpdatedBag(bag.Parameter, bag.Index); + if (result.State == PeerToPeerProcess.EPeerToPeerProcessState.Failed) + return; + Logger?.LogTrace($"Queued Parameter update took {sw.ElapsedMilliseconds}ms for {mc} messages."); }, cts.Token); await task; if (task.IsCompletedSuccessfully) - await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenNonQueuedUpdateRequests); + await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenQueuedUpdateRequests); else - Logger?.LogTrace(task.Exception, $"Parameter update for {bag.Parameter} with index {bag.Index} failed: {task.Exception?.Message}"); + { + Logger?.LogTrace(task.Exception, $"Queue Parameter update failed: {task.Exception?.Message}"); + return; + } + } - } - catch (Exception ex) - { - Logger?.LogError(ex); - } - finally - { - updateSenaphoreSlim.Release(); + while (mc != 0); + return; } } + } + + #endregion + private async Task getDeviceModelAndCollectAllParameters() + { + if (deviceModel != null) + return; + deviceModel = RDMDeviceModel.getDeviceModel(UID, Subdevice, DeviceInfo, new Func(RDMSharp.Instance.SendMessage)); - #endregion - private async Task getDeviceModelAndCollectAllParameters() + if (!deviceModel.IsInitialized) + while (deviceModel.IsInitializing) + await Task.Delay(3000); + + if (!deviceModel.IsInitialized) { - if (deviceModel != null) - return; - deviceModel = RDMDeviceModel.getDeviceModel(UID, Subdevice, DeviceInfo, new Func(RDMSharp.Instance.SendMessage)); - if (!deviceModel.IsInitialized) - { - deviceModel.Initialized += DeviceModel_Initialized; - deviceModel.ParameterValueAdded += DeviceModel_ParameterValueAdded; - if (!deviceModel.IsInitializing) - await deviceModel.Initialize(); - else - InvkoeDeviceModelParameterValueAdded(); - } + deviceModel.Initialized += DeviceModel_Initialized; + deviceModel.ParameterValueAdded += DeviceModel_ParameterValueAdded; + if (!deviceModel.IsInitializing) + await deviceModel.Initialize(); else - { InvkoeDeviceModelParameterValueAdded(); - await collectParameters(); - } - void InvkoeDeviceModelParameterValueAdded() - { - foreach (var item in this.deviceModel.ParameterValues) - base.InvokeParameterValueAdded(new ParameterValueAddedEventArgs(item.Key, item.Value)); - } } - - private void DeviceModel_ParameterValueAdded(object sender, ParameterValueAddedEventArgs e) + else { - base.InvokeParameterValueAdded(e); + InvkoeDeviceModelParameterValueAdded(); + await collectParameters(); } - private async Task collectAllParametersOnRoot() + if (deviceModel is null) + { + + } + void InvkoeDeviceModelParameterValueAdded() { - await requestParameters(); + foreach (var item in this.deviceModel.ParameterValues) + base.InvokeParameterValueAdded(new ParameterValueAddedEventArgs(item.Key, item.Value)); } + } - private async Task getPersonalityModelAndCollectAllParameters() + private void DeviceModel_ParameterValueAdded(object sender, ParameterValueAddedEventArgs e) + { + base.InvokeParameterValueAdded(e); + } + + private async Task collectAllParametersOnRoot() + { + await requestParameters(); + } + + private async Task getPersonalityModelAndCollectAllParameters(byte? personalityId = null) + { + if (personalityId is null) { - byte? personalityId = DeviceInfo.Dmx512CurrentPersonality.Value; + personalityId ??= DeviceInfo.Dmx512CurrentPersonality.Value; if (parameterValues.TryGetValue(ERDM_Parameter.DMX_PERSONALITY, out object value) && value is RDMDMXPersonality personality) personalityId = personality.CurrentPersonality; - - PersonalityModel = DeviceModel.getPersonalityModel(this, personalityId ?? 0); - if (!PersonalityModel.IsInitialized) - await PersonalityModel.Initialize(); } - private async void AbstractRDMDevice_ParameterValueAdded(object sender, ParameterValueAddedEventArgs e) + PersonalityModel = DeviceModel.getPersonalityModel(this, personalityId ?? 0); + if (!PersonalityModel.IsInitialized) + await PersonalityModel.Initialize(); + } + + private async void AbstractRDMDevice_ParameterValueAdded(object sender, ParameterValueAddedEventArgs e) + { + switch (e.Parameter) { - switch (e.Parameter) - { - case ERDM_Parameter.DMX_PERSONALITY: - if (DeviceModel.IsInitialized) - await getPersonalityModelAndCollectAllParameters(); - break; - case ERDM_Parameter.SENSOR_VALUE when e.Value is RDMSensorValue sensorValue: - var sensor = sensors.GetOrAdd(sensorValue.SensorId, (a) => new Sensor(a)); - if (deviceModel.GetSensorDefinitions()?.FirstOrDefault(a => a.SensorId == sensorValue.SensorId) is RDMSensorDefinition sd) - sensor.UpdateDescription(sd); - sensor.UpdateValue(sensorValue); - break; - } + case ERDM_Parameter.DMX_PERSONALITY: + if (DeviceModel.IsInitialized) + { + if (e.Value is RDMDMXPersonality personality) + await getPersonalityModelAndCollectAllParameters(personality.CurrentPersonality); + } + break; + case ERDM_Parameter.SENSOR_VALUE when e.Value is RDMSensorValue sensorValue: + var sensor = sensors.GetOrAdd(sensorValue.SensorId, (a) => new Sensor(a)); + if (deviceModel.GetSensorDefinitions()?.FirstOrDefault(a => a.SensorId == sensorValue.SensorId) is RDMSensorDefinition sd) + sensor.UpdateDescription(sd); + sensor.UpdateValue(sensorValue); + break; } - private async void AbstractRDMDevice_ParameterValueChanged(object sender, ParameterValueChangedEventArgs e) - { - switch (e.Parameter) - { - case ERDM_Parameter.DEVICE_INFO: - if (this.PersonalityModel.PersonalityID != this.DeviceInfo.Dmx512CurrentPersonality) - goto case ERDM_Parameter.DMX_PERSONALITY; - break; - case ERDM_Parameter.DMX_PERSONALITY: - if (DeviceModel.IsInitialized) - await getPersonalityModelAndCollectAllParameters(); - break; - case ERDM_Parameter.SENSOR_VALUE when e.NewValue is RDMSensorValue sensorValue: - if (sensorValue.SensorId == byte.MaxValue) //Ignore Broadcast as in Spec. - break; - var sensor = sensors.GetOrAdd(sensorValue.SensorId, (a) => new Sensor(a)); - sensor.UpdateValue(sensorValue); + } + private async void AbstractRDMDevice_ParameterValueChanged(object sender, ParameterValueChangedEventArgs e) + { + switch (e.Parameter) + { + case ERDM_Parameter.DEVICE_INFO: + if (this.PersonalityModel?.PersonalityID != this.DeviceInfo.Dmx512CurrentPersonality) + goto case ERDM_Parameter.DMX_PERSONALITY; + break; + case ERDM_Parameter.DMX_PERSONALITY: + if (DeviceModel.IsInitialized) + await getPersonalityModelAndCollectAllParameters(); + break; + case ERDM_Parameter.SENSOR_VALUE when e.NewValue is RDMSensorValue sensorValue: + if (sensorValue.SensorId == byte.MaxValue) //Ignore Broadcast as in Spec. break; - } - } - private void AbstractRDMDevice_ParameterRequested(object sender, ParameterRequestedEventArgs e) - { - LastSeen = DateTime.UtcNow; - UpdateParameterUpdatedBag(e.Parameter, e.Index); + var sensor = sensors.GetOrAdd(sensorValue.SensorId, (a) => new Sensor(a)); + sensor.UpdateValue(sensorValue); + break; } - private void UpdateParameterUpdatedBag(ERDM_Parameter parameter, object index) + } + private void AbstractRDMDevice_ParameterRequested(object sender, ParameterRequestedEventArgs e) + { + LastSeen = DateTime.UtcNow; + UpdateParameterUpdatedBag(e.Parameter, e.Index); + } + private void UpdateParameterUpdatedBag(ERDM_Parameter parameter, object index) + { + if (!Constants.BLUEPRINT_MODEL_PARAMETERS.Contains(parameter) && !Constants.BLUEPRINT_MODEL_PERSONALITY_PARAMETERS.Contains(parameter)) { - if (!Constants.BLUEPRINT_MODEL_PARAMETERS.Contains(parameter) && !Constants.BLUEPRINT_MODEL_PERSONALITY_PARAMETERS.Contains(parameter)) + if (ParameterUpdatedBag.Any(p => p.Parameter == parameter && p.Index == index)) { - if (ParameterUpdatedBag.Any(p => p.Parameter == parameter && p.Index == index)) - { - var tempQueue = new ConcurrentQueue(); - while (ParameterUpdatedBag.TryDequeue(out var item)) - if (!(item.Parameter.Equals(parameter) && Equals(item.Index, index))) - tempQueue.Enqueue(item); + var tempQueue = new ConcurrentQueue(); + while (ParameterUpdatedBag.TryDequeue(out var item)) + if (!(item.Parameter.Equals(parameter) && Equals(item.Index, index))) + tempQueue.Enqueue(item); - while (tempQueue.TryDequeue(out var item)) - ParameterUpdatedBag.Enqueue(item); - } - ParameterUpdatedBag.Enqueue(new ParameterUpdatedBag(parameter, index)); + while (tempQueue.TryDequeue(out var item)) + ParameterUpdatedBag.Enqueue(item); } + ParameterUpdatedBag.Enqueue(new ParameterUpdatedBag(parameter, index)); } + } - public async Task SetParameter(ERDM_Parameter parameter, object value = null) + public async Task SetParameter(ERDM_Parameter parameter, object value = null) + { + try { - try + ParameterBag parameterBag = new ParameterBag(parameter, this.DeviceModel.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); + var define = MetadataFactory.GetDefine(parameterBag); + if (define.SetRequest.HasValue) { - ParameterBag parameterBag = new ParameterBag(parameter, this.DeviceModel.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); - var define = MetadataFactory.GetDefine(parameterBag); - if (define.SetRequest.HasValue) - { - if (define.SetRequest.Value.GetIsEmpty()) - return await requestSetParameterWithEmptyPayload(parameterBag, define, UID, Subdevice); - else - return await requestSetParameterWithPayload(parameterBag, define, UID, Subdevice, value); - } - } - catch (Exception e) - { - Logger?.LogError(string.Empty, e); + if (define.SetRequest.Value.GetIsEmpty()) + return await requestSetParameterWithEmptyPayload(parameterBag, define, UID, Subdevice); + else + return await requestSetParameterWithPayload(parameterBag, define, UID, Subdevice, value); } - return false; } - - protected sealed override async Task OnResponseMessage(RDMMessage rdmMessage) + catch (Exception e) { - LastSeen = DateTime.UtcNow; + Logger?.LogError(string.Empty, e); + } + return false; + } - if (rdmMessage?.ResponseType == ERDM_ResponseType.NACK_REASON) - this.deviceModel?.handleNACKReason(rdmMessage); + protected sealed override async Task OnResponseMessage(RDMMessage rdmMessage) + { + LastSeen = DateTime.UtcNow; - await base.OnResponseMessage(rdmMessage); - } + if (rdmMessage?.ResponseType == ERDM_ResponseType.NACK_REASON) + this.deviceModel?.handleNACKReason(rdmMessage); - public sealed override IReadOnlyDictionary GetAllParameterValues() - { + await base.OnResponseMessage(rdmMessage); + } - IReadOnlyDictionary res = null; - if (this.DeviceModel is not null) - res = this.DeviceModel.ParameterValues; - if(this.PersonalityModel is not null) - res=res.Concat(this.PersonalityModel.ParameterValues) - .ToLookup(x => x.Key, x => x.Value) - .ToDictionary(x => x.Key, g => g.First()); ; - if (res is not null) - return res.Concat(this.ParameterValues) - .ToLookup(x => x.Key, x => x.Value) - .ToDictionary(x => x.Key, g => g.First()); - else - return base.GetAllParameterValues(); - } + public sealed override IReadOnlyDictionary GetAllParameterValues() + { + IReadOnlyDictionary res = null; + if (this.DeviceModel is not null) + res = this.DeviceModel.ParameterValues; + if (this.PersonalityModel is not null) + res = res.Concat(this.PersonalityModel.ParameterValues) + .ToLookup(x => x.Key, x => x.Value) + .ToDictionary(x => x.Key, g => g.First()); ; + if (res is not null) + return res.Concat(this.ParameterValues) + .ToLookup(x => x.Key, x => x.Value) + .ToDictionary(x => x.Key, g => g.First()); + else + return base.GetAllParameterValues(); + } - private async void Instance_ParameterUpdateTimerElapsed(object sender, EventArgs e) - { - await updateParameters(); - } - public override string ToString() + private async void Instance_ParameterUpdateTimerElapsed(object sender, EventArgs e) + { + await updateParameters(); + } + + public override string ToString() + { + return $"{base.ToString()} {this.DeviceModel}"; + } + protected sealed override void OnDispose() + { + GlobalTimers.Instance.PresentUpdateTimerElapsed -= Instance_PresentUpdateTimerElapsed; + GlobalTimers.Instance.ParameterUpdateTimerElapsed -= Instance_ParameterUpdateTimerElapsed; + try { - return $"{base.ToString()} {this.DeviceModel}"; + onDispose(); } - protected sealed override void OnDispose() + catch (Exception e) { - GlobalTimers.Instance.PresentUpdateTimerElapsed -= Instance_PresentUpdateTimerElapsed; - GlobalTimers.Instance.ParameterUpdateTimerElapsed -= Instance_ParameterUpdateTimerElapsed; - try - { - onDispose(); - } - catch (Exception e) - { - Logger?.LogError(e); - } - ParameterValueAdded -= AbstractRDMDevice_ParameterValueAdded; - ParameterValueChanged -= AbstractRDMDevice_ParameterValueChanged; - ParameterRequested -= AbstractRDMDevice_ParameterRequested; + Logger?.LogError(e); } - protected abstract void onDispose(); - - + ParameterValueAdded -= AbstractRDMDevice_ParameterValueAdded; + ParameterValueChanged -= AbstractRDMDevice_ParameterValueChanged; + ParameterRequested -= AbstractRDMDevice_ParameterRequested; } + protected abstract void onDispose(); + + } \ No newline at end of file diff --git a/RDMSharp/RDM/Device/GeneratedPersonality.cs b/RDMSharp/RDM/Device/GeneratedPersonality.cs index 7c85c705..4a5f0dce 100644 --- a/RDMSharp/RDM/Device/GeneratedPersonality.cs +++ b/RDMSharp/RDM/Device/GeneratedPersonality.cs @@ -3,39 +3,39 @@ using System.Collections.Generic; using System.Linq; -namespace RDMSharp +namespace RDMSharp; + +public class GeneratedPersonality : IPersonality { - public class GeneratedPersonality - { - public readonly byte ID; - public ushort SlotCount => (ushort)slots.Count; - public readonly string Description; - private readonly ConcurrentDictionary slots = new ConcurrentDictionary(); - public IReadOnlyDictionary Slots => slots.AsReadOnly(); + private readonly byte id; + public byte ID => id; - public GeneratedPersonality(byte id, string description, params Slot[] _slots) - { - if (id == 0) - throw new ArgumentOutOfRangeException($"{0} is not allowed as {id}"); - ID = id; - Description = description; - foreach (var slot in _slots) - { - if (!slots.TryAdd(slot.SlotId, slot)) - throw new Exception($"Cant add Slot: {slot}"); - } - var maxID = slots.Max(s => s.Key); - if (slots.Count != maxID + 1) - throw new ArgumentOutOfRangeException($"The Count not fits the last Slot ID plus one! Count: {slots.Count}, ID:{maxID} ({maxID + 1})"); - } + public ushort SlotCount => (ushort)slots.Count; - public static implicit operator RDMDMXPersonalityDescription(GeneratedPersonality _this) - { - return new RDMDMXPersonalityDescription(_this.ID, _this.SlotCount, _this.Description); - } - public override string ToString() + private readonly string description; + public string Description => description; + + private readonly ConcurrentDictionary slots = new ConcurrentDictionary(); + public IReadOnlyDictionary Slots => slots.AsReadOnly(); + + public GeneratedPersonality(byte _id, string _description, params Slot[] _slots) + { + if (_id == 0) + throw new ArgumentOutOfRangeException($"{0} is not allowed as {_id}"); + id = _id; + description = _description; + foreach (var slot in _slots) { - return $"[{ID}] ({SlotCount}) {Description}"; + if (!slots.TryAdd(slot.SlotId, slot)) + throw new Exception($"Cant add Slot: {slot}"); } + var maxID = slots.Max(s => s.Key); + if (slots.Count != maxID + 1) + throw new ArgumentOutOfRangeException($"The Count not fits the last Slot ID plus one! Count: {slots.Count}, ID:{maxID} ({maxID + 1})"); + } + + public override string ToString() + { + return $"[{ID}] ({SlotCount}) {Description}"; } -} \ No newline at end of file +} diff --git a/RDMSharp/RDM/Device/IPersonality.cs b/RDMSharp/RDM/Device/IPersonality.cs new file mode 100644 index 00000000..93773122 --- /dev/null +++ b/RDMSharp/RDM/Device/IPersonality.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace RDMSharp; + +public interface IPersonality +{ + byte ID { get; } + ushort SlotCount { get; } + string Description { get; } + IReadOnlyDictionary Slots { get; } +} diff --git a/RDMSharp/RDM/Device/Module/AbstractModule.cs b/RDMSharp/RDM/Device/Module/AbstractModule.cs new file mode 100644 index 00000000..f33c4016 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/AbstractModule.cs @@ -0,0 +1,125 @@ +using Microsoft.Extensions.Logging; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.CompilerServices; + +namespace RDMSharp.RDM.Device.Module; + +public abstract class AbstractModule : IModule +{ + protected static ILogger Logger = Logging.CreateLogger(); + + public event PropertyChangedEventHandler PropertyChanged; + + private readonly string _name; + public string Name { get => _name; } + public abstract string DisplayName { get; } + + private readonly IReadOnlyCollection _supportedParameters; + + public IReadOnlyCollection SupportedParameters { get => _supportedParameters; } + + protected AbstractGeneratedRDMDevice ParentGeneratedDevice { get; private set; } + protected AbstractRemoteRDMDevice ParentRemoteDevice { get; private set; } + protected AbstractRDMDevice ParentDevice + { + get + { + if (ParentRemoteDevice is not null) + return ParentRemoteDevice; + + return ParentGeneratedDevice; + } + } + + protected AbstractModule(string name, params ERDM_Parameter[] supportedParameters) + { + this._name = name; + this._supportedParameters = supportedParameters; + } + protected AbstractModule(AbstractRemoteRDMDevice remoteDevice, string name, params ERDM_Parameter[] supportedParameters) : this(name, supportedParameters) + { + ParentRemoteDevice = remoteDevice; + if (remoteDevice is AbstractRemoteRDMDevice device) + SetRemoteParentDevice(device); + } + public RDMMessage? HandleRequest(RDMMessage message) + { + if (!this.IsHandlingParameter(message.Parameter, message.Command)) + return null; + + ERDM_NackReason? nackReason = null; + try + { + return handleRequest(message); + } + catch (System.Exception ex) + { + nackReason = ERDM_NackReason.HARDWARE_FAULT; + } + return new RDMMessage(nackReason ?? ERDM_NackReason.UNKNOWN_PID) + { + DestUID = message.SourceUID, + SourceUID = message.SourceUID, + Command = ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE, + Parameter = message.Parameter + }; + } + protected virtual RDMMessage? handleRequest(RDMMessage message) + { + throw new System.NotImplementedException("This method should be overridden in derived classes to handle specific requests."); + } + + public virtual bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command) + { + return false; + } + + internal void SetGeneratedParentDevice(AbstractGeneratedRDMDevice device) + { + if (ParentGeneratedDevice is not null) + return; + ParentGeneratedDevice = device; + device.ParameterValueAdded += Device_ParameterValueAdded; + device.ParameterValueChanged += Device_ParameterValueChanged; + OnParentGeneratedDeviceChanged(ParentGeneratedDevice); + } + private void SetRemoteParentDevice(AbstractRemoteRDMDevice device) + { + device.ParameterValueAdded += Device_ParameterValueAdded; + device.ParameterValueChanged += Device_ParameterValueChanged; + OnRemoteParentDeviceChanged(device); + } + + protected virtual void OnRemoteParentDeviceChanged(AbstractRemoteRDMDevice device) + { + + } + + private void Device_ParameterValueAdded(object sender, AbstractRDMCache.ParameterValueAddedEventArgs e) + { + if (!this.SupportedParameters.Contains(e.Parameter)) + return; + + ParameterChanged(e.Parameter, e.Value, e.Index); + } + private void Device_ParameterValueChanged(object sender, AbstractRDMCache.ParameterValueChangedEventArgs e) + { + ParameterChanged(e.Parameter, e.NewValue, e.Index); + } + protected virtual void ParameterChanged(ERDM_Parameter parameter, object? newValue, object? index) + { + + } + + protected virtual void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + + } + + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/BootSoftwareVersionModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/BootSoftwareVersionModule.cs new file mode 100644 index 00000000..7b29bac6 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/BootSoftwareVersionModule.cs @@ -0,0 +1,85 @@ +namespace RDMSharp.RDM.Device.Module; + +public sealed class BootSoftwareVersionModule : AbstractModule +{ + private const string _moduleName = "BootSoftwareVersion"; + private const string _moduleDisplayName = "Boot Software Version"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID, + ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL + }; + + public override string DisplayName => _moduleDisplayName; + + private uint _bootSoftwareVersionId; + private string _bootSoftwareVersionLabel; + public uint BootSoftwareVersionId + { + get + { + if (ParentDevice is null) + return _bootSoftwareVersionId; + object res; + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID, out res)) + return (uint)res; + return _bootSoftwareVersionId; + } + internal set + { + _bootSoftwareVersionId = value; + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID, value); + } + } + public string BootSoftwareVersionLabel + { + get + { + if (ParentDevice is null) + return _bootSoftwareVersionLabel; + object res; + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL, out res)) + return (string)res; + return _bootSoftwareVersionLabel; + } + internal set + { + _bootSoftwareVersionLabel = value; + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL, value); + } + } + public BootSoftwareVersionModule(uint bootSoftwareVersionId, string bootSoftwareVersionLabel) : base( + _moduleName, + _moduleParameters) + { + _bootSoftwareVersionId = bootSoftwareVersionId; + _bootSoftwareVersionLabel = bootSoftwareVersionLabel; + } + public BootSoftwareVersionModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + this.BootSoftwareVersionId = _bootSoftwareVersionId; + this.BootSoftwareVersionLabel = _bootSoftwareVersionLabel; + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID: + OnPropertyChanged(nameof(BootSoftwareVersionId)); + break; + case ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL: + OnPropertyChanged(nameof(BootSoftwareVersionLabel)); + break; + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/DMX_PersonalityModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/DMX_PersonalityModule.cs new file mode 100644 index 00000000..79618683 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/DMX_PersonalityModule.cs @@ -0,0 +1,265 @@ +using RDMSharp.PayloadObject; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class DMX_PersonalityModule : AbstractModule +{ + private const string _moduleName = "DMX_Personality"; + private const string _moduleDisplayName = "DMX Personality"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.DMX_PERSONALITY, + ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION + }; + + public override string DisplayName => _moduleDisplayName; + + private IPersonality currentPersonality; + public IPersonality CurrentPersonality + { + get + { + return currentPersonality; + //if (ParentGeneratedDevice is not null) + // return _generatedPersonalities?.FirstOrDefault(p => p.ID == CurrentPersonalityId); + + //else if (ParentRemoteDevice is not null) + // return ParentRemoteDevice.PersonalityModel.Personality; + //return null; + } + private set + { + if (currentPersonality == value) + return; + currentPersonality = value; + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.DMX_PERSONALITY, new RDMDMXPersonality(value.ID, PersonalitiesCount)); + OnPropertyChanged(); + } + } + private byte _initialPersonalityId; + //public byte? CurrentPersonalityId + //{ + // get + // { + // if (ParentDevice is null) + // return _currentPersonalityId; + // object res; + // if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.DMX_PERSONALITY, out res)) + // if (res is RDMDMXPersonality personality) + // return personality.CurrentPersonality; + // return _currentPersonalityId; + // } + // set + // { + // if (!value.HasValue) + // throw new NullReferenceException($"{CurrentPersonalityId} can't be null if {ERDM_Parameter.DMX_PERSONALITY} is Supported"); + // if (value.Value == 0) + // throw new ArgumentOutOfRangeException($"{CurrentPersonalityId} can't 0 if {ERDM_Parameter.DMX_PERSONALITY} is Supported"); + + + // _currentPersonalityId = value.Value; + // if (ParentGeneratedDevice is not null) + // { + // if (!this._generatedPersonalities.Any(p => p.ID == value.Value)) + // throw new ArgumentOutOfRangeException($"No Personality found with ID: {value.Value}"); + // ParentGeneratedDevice.setParameterValue(ERDM_Parameter.DMX_PERSONALITY, new RDMDMXPersonality(value.Value, PersonalitiesCount)); + // } + // if (ParentRemoteDevice is not null) + // { + // if (!this.PersonalityDesriptions.Any(p => p.PersonalityId == value.Value)) + // throw new ArgumentOutOfRangeException($"No Personality found with ID: {value.Value}"); + // _ = ParentRemoteDevice.SetParameter(ERDM_Parameter.DMX_PERSONALITY, value); + // } + // } + //} + public IReadOnlyCollection PersonalityDesriptions + { + get + { + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, out object res)) + if (res is ConcurrentDictionary dict) + return dict.Select(d => d.Value).OfType().ToList().AsReadOnly(); + return Array.Empty(); + } + } + public readonly IReadOnlyCollection _generatedPersonalities = null; + public IReadOnlyCollection Personalities + { + get + { + if (_generatedPersonalities is not null) + return _generatedPersonalities; + + return ParentRemoteDevice.DeviceModel.KnownPersonalityModels.Select(pm => pm.Personality).ToList().AsReadOnly(); + } + } + public readonly byte PersonalitiesCount; + //private ushort currentPersonalityFootprint; + //public ushort CurrentPersonalityFootprint + //{ + // get + // { + // return currentPersonalityFootprint; + // } + // private set + // { + // if (currentPersonalityFootprint == value) + // return; + // currentPersonalityFootprint = value; + // OnPropertyChanged(); + // } + //} + + public DMX_PersonalityModule(byte initialPersonalityId, params GeneratedPersonality[] personalities) : base( + _moduleName, + _moduleParameters) + { + if (!personalities.Any(p => p.ID == initialPersonalityId)) + throw new ArgumentOutOfRangeException($"No Personality found with ID: {initialPersonalityId}"); + + _initialPersonalityId = initialPersonalityId; + _generatedPersonalities = (personalities ?? Array.Empty()).ToList().AsReadOnly(); + PersonalitiesCount = (byte)_generatedPersonalities.Count; + + } + public DMX_PersonalityModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + CurrentPersonality = ParentRemoteDevice.PersonalityModel?.Personality; + //currentPersonalityFootprint = ParentRemoteDevice.PersonalityModel.SlotCount; + } + + protected override async void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + if (_generatedPersonalities is not null) + { + if (_generatedPersonalities.Count >= byte.MaxValue) + throw new ArgumentOutOfRangeException($"There to many {_generatedPersonalities}! Maximum is {byte.MaxValue - 1}"); + + if (_generatedPersonalities.Count != 0) + { + var persDesc = new ConcurrentDictionary(); + foreach (var gPers in _generatedPersonalities) + if (!persDesc.TryAdd(gPers.ID, new RDMDMXPersonalityDescription(gPers))) + throw new Exception($"{gPers.ID} already used as {nameof(gPers.ID)}"); + + device.setParameterValue(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, persDesc); + } + } + await SetPersonality(_initialPersonalityId); + } + protected override async void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.DMX_PERSONALITY: + if (newValue is RDMDMXPersonality personality) + { + if (ParentGeneratedDevice is not null) + await SetPersonality(personality.CurrentPersonality); + + else if (ParentRemoteDevice is not null) + { + try + { + var pm = ParentRemoteDevice.DeviceModel.KnownPersonalityModels.FirstOrDefault(p => p.Personality?.ID == personality.CurrentPersonality); + if (pm is null) + pm = ParentRemoteDevice.DeviceModel.getPersonalityModel(ParentRemoteDevice, personality.CurrentPersonality); + if (!pm.IsInitialized) + await pm.Initialize(); + CurrentPersonality = pm.Personality; + } + catch (Exception ex) + { + Logger?.LogError(ex); + } + } + } + break; + case ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION when ParentGeneratedDevice is not null: + OnPropertyChanged(nameof(PersonalityDesriptions)); + break; + } + } + public override bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command) + { + if (parameter == ERDM_Parameter.DMX_PERSONALITY) + return command == ERDM_Command.SET_COMMAND; + return base.IsHandlingParameter(parameter, command); + } + protected override RDMMessage handleRequest(RDMMessage message) + { + if (message.Parameter == ERDM_Parameter.DMX_PERSONALITY) + if (message.Command == ERDM_Command.SET_COMMAND) + { + if (message.Value is byte b) + { + try + { + if (this._generatedPersonalities.FirstOrDefault(p => p.ID == b) is IPersonality pers) + CurrentPersonality = pers; + else + { + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + } + catch (Exception ex) + { + Logger?.LogError(ex); + return new RDMMessage(ERDM_NackReason.HARDWARE_FAULT) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + return new RDMMessage() + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + }; + } + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + return base.handleRequest(message); + } + public async Task SetPersonality(byte personalityId) + { + if (ParentGeneratedDevice is not null) + { + if (this._generatedPersonalities.FirstOrDefault(p => p.ID == personalityId) is not IPersonality pers) + throw new ArgumentOutOfRangeException($"No Personality found with ID: {personalityId}"); + CurrentPersonality = pers; + } + if (ParentRemoteDevice is not null) + { + if (!this.PersonalityDesriptions.Any(p => p.PersonalityId == personalityId)) + throw new ArgumentOutOfRangeException($"No Personality found with ID: {personalityId}"); + return await ParentRemoteDevice.SetParameter(ERDM_Parameter.DMX_PERSONALITY, personalityId); + } + return true; + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/DMX_StartAddressModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/DMX_StartAddressModule.cs new file mode 100644 index 00000000..f0b871ad --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/DMX_StartAddressModule.cs @@ -0,0 +1,73 @@ +using System; +using System.Threading.Tasks; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class DMX_StartAddressModule : AbstractModule +{ + private const string _moduleName = "DMX_StartAddress"; + private const string _moduleDisplayName = "DMX Start-Address"; + private const ERDM_Parameter _moduleParameter = ERDM_Parameter.DMX_START_ADDRESS; + + public override string DisplayName => _moduleDisplayName; + + private ushort _dmxAddress; + public ushort? DMXAddress + { + get + { + if (ParentDevice is null) + return _dmxAddress; + object res; + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.DMX_START_ADDRESS, out res)) + return (ushort?)res; + return _dmxAddress; + } + set + { + if (!value.HasValue) + throw new NullReferenceException($"{DMXAddress} can't be null if {ERDM_Parameter.DMX_START_ADDRESS} is Supported"); + if (value.Value == 0) + throw new ArgumentOutOfRangeException($"{DMXAddress} can't 0 if {ERDM_Parameter.DMX_START_ADDRESS} is Supported"); + if (value.Value > 512) + throw new ArgumentOutOfRangeException($"{DMXAddress} can't be greater then 512"); + + _dmxAddress = value.Value; + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.DMX_START_ADDRESS, value); + + if (ParentRemoteDevice is not null) + _ = SetDMXAddress(value.Value); + } + } + public DMX_StartAddressModule(ushort dmxAddress) : base( + _moduleName, + _moduleParameter) + { + _dmxAddress = dmxAddress; + } + public DMX_StartAddressModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameter) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + this.DMXAddress = _dmxAddress; + } + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.DMX_START_ADDRESS: + OnPropertyChanged(nameof(DMXAddress)); + break; + } + } + public async Task SetDMXAddress(ushort dmxAddress) + { + return await ParentRemoteDevice.SetParameter(ERDM_Parameter.DMX_START_ADDRESS, dmxAddress); + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/DeviceInfoModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/DeviceInfoModule.cs new file mode 100644 index 00000000..ced164a9 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/DeviceInfoModule.cs @@ -0,0 +1,97 @@ +using RDMSharp.PayloadObject; +using System; +using System.Linq; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class DeviceInfoModule : AbstractModule +{ + private const string _moduleName = "DeviceInfo"; + private const string _moduleDisplayName = "Device Info"; + private const ERDM_Parameter _moduleParameter = ERDM_Parameter.DEVICE_INFO; + + public override string DisplayName => _moduleDisplayName; + public RDMDeviceInfo DeviceInfo + { + get + { + if (ParentDevice is null) + return null; + object res; + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.DEVICE_INFO, out res)) + return (RDMDeviceInfo)res; + return null; + } + internal set + { + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.DEVICE_INFO, value); + } + } + private SoftwareVersionModule softwareVersionModule; + private DMX_StartAddressModule dmxStartAddressModule; + private DMX_PersonalityModule dmxPersonalityModule; + private SensorsModule sensorsModule; + + public DeviceInfoModule() : base( + _moduleName, + _moduleParameter) + { + } + public DeviceInfoModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameter) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + softwareVersionModule = device.Modules.OfType().FirstOrDefault(); + dmxStartAddressModule = device.Modules.OfType().FirstOrDefault(); + dmxPersonalityModule = device.Modules.OfType().FirstOrDefault(); + sensorsModule = device.Modules.OfType().FirstOrDefault(); + updateGeneratedParameterValues(); + } + protected override void OnRemoteParentDeviceChanged(AbstractRemoteRDMDevice device) + { + softwareVersionModule = device.Modules.OfType().FirstOrDefault(); + dmxStartAddressModule = device.Modules.OfType().FirstOrDefault(); + dmxPersonalityModule = device.Modules.OfType().FirstOrDefault(); + sensorsModule = device.Modules.OfType().FirstOrDefault(); + base.OnRemoteParentDeviceChanged(device); + } + private void updateGeneratedParameterValues() + { + if (ParentGeneratedDevice is null) + return; + this.DeviceInfo = new RDMDeviceInfo(1, + 0, + ParentGeneratedDevice.DeviceModelID, + ParentGeneratedDevice.ProductCategoryCoarse, + ParentGeneratedDevice.ProductCategoryFine, + softwareVersionModule?.SoftwareVersionId ?? 0, + dmx512Footprint: dmxPersonalityModule?.CurrentPersonality.SlotCount ?? 0, + dmx512CurrentPersonality: dmxPersonalityModule?.CurrentPersonality.ID ?? 0, + dmx512NumberOfPersonalities: dmxPersonalityModule?.PersonalitiesCount ?? 0, + dmx512StartAddress: (dmxStartAddressModule?.DMXAddress ?? ushort.MaxValue), + subDeviceCount: (ushort)(ParentGeneratedDevice.SubDevices?.Where(sd => !sd.Subdevice.IsRoot).Count() ?? 0), + sensorCount: (byte)(sensorsModule?.Sensors?.Count ?? 0)); + + OnPropertyChanged(nameof(DeviceInfo)); + } + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.DEVICE_INFO: + OnPropertyChanged(nameof(DeviceInfo)); + break; + case ERDM_Parameter.DMX_PERSONALITY: + case ERDM_Parameter.DMX_START_ADDRESS: + if (ParentGeneratedDevice is not null) + updateGeneratedParameterValues(); + break; + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/DeviceLabelModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/DeviceLabelModule.cs new file mode 100644 index 00000000..4df8e9bd --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/DeviceLabelModule.cs @@ -0,0 +1,59 @@ +namespace RDMSharp.RDM.Device.Module; + +public sealed class DeviceLabelModule : AbstractModule +{ + private const string _moduleName = "DeviceLabel"; + private const string _moduleDisplayName = "Device Label"; + private const ERDM_Parameter _moduleParameter = ERDM_Parameter.DEVICE_LABEL; + + public override string DisplayName => _moduleDisplayName; + + private string _deviceLabel; + public string DeviceLabel + { + get + { + if (ParentDevice is null) + return _deviceLabel; + object res; + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.DEVICE_LABEL, out res)) + return (string)res; + return _deviceLabel; + } + set + { + _deviceLabel = value; + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.DEVICE_LABEL, value); + + if (ParentRemoteDevice is not null) + _ = ParentRemoteDevice.SetParameter(ERDM_Parameter.DEVICE_LABEL, value); + } + } + public DeviceLabelModule(string deviceLabel) : base( + _moduleName, + _moduleParameter) + { + _deviceLabel = deviceLabel; + } + public DeviceLabelModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameter) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + this.DeviceLabel = _deviceLabel; + } + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.DEVICE_LABEL: + OnPropertyChanged(nameof(DeviceLabel)); + break; + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/DeviceModelDescriptionModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/DeviceModelDescriptionModule.cs new file mode 100644 index 00000000..4a792aa1 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/DeviceModelDescriptionModule.cs @@ -0,0 +1,56 @@ +namespace RDMSharp.RDM.Device.Module; + +public sealed class DeviceModelDescriptionModule : AbstractModule +{ + private const string _moduleName = "DeviceModelDescription"; + private const string _moduleDisplayName = "Device Model Description"; + private const ERDM_Parameter _moduleParameter = ERDM_Parameter.DEVICE_MODEL_DESCRIPTION; + + public override string DisplayName => _moduleDisplayName; + + private string _deviceModelDescriptionLabel; + public string DeviceModelDescription + { + get + { + if (ParentDevice is null) + return _deviceModelDescriptionLabel; + object res; + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.DEVICE_MODEL_DESCRIPTION, out res)) + return (string)res; + return _deviceModelDescriptionLabel; + } + internal set + { + _deviceModelDescriptionLabel = value; + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.DEVICE_MODEL_DESCRIPTION, value); + } + } + public DeviceModelDescriptionModule(string manufacturerLabel) : base( + _moduleName, + _moduleParameter) + { + _deviceModelDescriptionLabel = manufacturerLabel; + } + public DeviceModelDescriptionModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameter) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + this.DeviceModelDescription = _deviceModelDescriptionLabel; + } + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.DEVICE_MODEL_DESCRIPTION: + OnPropertyChanged(nameof(DeviceModelDescription)); + break; + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/IdentifyDeviceModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/IdentifyDeviceModule.cs new file mode 100644 index 00000000..169d7cbe --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/IdentifyDeviceModule.cs @@ -0,0 +1,66 @@ +using System.Threading.Tasks; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class IdentifyDeviceModule : AbstractModule +{ + private const string _moduleName = "IdentifyDevice"; + private const string _moduleDisplayName = "Identify Device"; + private const ERDM_Parameter _moduleParameter = ERDM_Parameter.IDENTIFY_DEVICE; + + public override string DisplayName => _moduleDisplayName; + + private bool _identify; + public bool Identify + { + get + { + if (ParentDevice is null) + return _identify; + object res; + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.IDENTIFY_DEVICE, out res)) + return (bool)res; + return _identify; + } + set + { + _identify = value; + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.IDENTIFY_DEVICE, value); + + if (ParentRemoteDevice is not null) + _ = SetIdentify(value); + } + } + + public IdentifyDeviceModule() : base( + _moduleName, + _moduleParameter) + { + } + public IdentifyDeviceModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameter) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + this.Identify = _identify; + } + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.IDENTIFY_DEVICE: + OnPropertyChanged(nameof(Identify)); + break; + } + } + + public async Task SetIdentify(bool value) + { + return await ParentRemoteDevice.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, value); + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/ManufacturerLabelModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/ManufacturerLabelModule.cs new file mode 100644 index 00000000..71b61605 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/ManufacturerLabelModule.cs @@ -0,0 +1,60 @@ +using System; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class ManufacturerLabelModule : AbstractModule +{ + private const string _moduleName = "ManufacturerLabel"; + private const string _moduleDisplayName = "Manufacturer Label"; + private const ERDM_Parameter _moduleParameter = ERDM_Parameter.MANUFACTURER_LABEL; + + public override string DisplayName => _moduleDisplayName; + + private string _manufacturerLabel; + public string ManufacturerLabel + { + get + { + if (ParentDevice is null) + return _manufacturerLabel; + object res; + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.MANUFACTURER_LABEL, out res)) + return (string)res; + return _manufacturerLabel; + } + internal set + { + _manufacturerLabel = value; + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.MANUFACTURER_LABEL, value); + } + } + public ManufacturerLabelModule(string manufacturerLabel) : base( + _moduleName, + _moduleParameter) + { + _manufacturerLabel = manufacturerLabel; + } + public ManufacturerLabelModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameter) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + if (string.IsNullOrWhiteSpace(_manufacturerLabel)) + _manufacturerLabel = Enum.GetName(typeof(EManufacturer), (EManufacturer)device.UID.ManufacturerID); + this.ManufacturerLabel = _manufacturerLabel; + } + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.MANUFACTURER_LABEL: + OnPropertyChanged(nameof(ManufacturerLabel)); + break; + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/ProxiedDevicesModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/ProxiedDevicesModule.cs new file mode 100644 index 00000000..95a3d027 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/ProxiedDevicesModule.cs @@ -0,0 +1,183 @@ +using RDMSharp.PayloadObject; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class ProxiedDevicesModule : AbstractModule +{ + private const string _moduleName = "ProxiedDevices"; + private const string _moduleDisplayName = "Proxied Devices"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.PROXIED_DEVICES, + ERDM_Parameter.PROXIED_DEVICES_COUNT + }; + + public override string DisplayName => _moduleDisplayName; + + public IReadOnlyCollection DeviceUIDs + { + get + { + IReadOnlyCollection uidList = null; + if (this.ParentGeneratedDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.PROXIED_DEVICES, out object proxiedDevices)) + { + if (proxiedDevices is RDMProxiedDevices obj) + uidList = obj.Devices.ToList().AsReadOnly(); + } + return uidList; + } + } + private ConcurrentDictionary> proxiedDevicesOngoingTransaktions = new ConcurrentDictionary>(); + public ProxiedDevicesModule() : base( + _moduleName, + _moduleParameters) + { + } + public ProxiedDevicesModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.PROXIED_DEVICES, new RDMProxiedDevices()); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.PROXIED_DEVICES_COUNT, new RDMProxiedDeviceCount(0, false)); + } + + protected override async void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + try + { + switch (parameter) + { + case ERDM_Parameter.PROXIED_DEVICES: + OnPropertyChanged(nameof(DeviceUIDs)); + break; + + case ERDM_Parameter.PROXIED_DEVICES_COUNT: + if (newValue is RDMProxiedDeviceCount proxiedDeviceCount && proxiedDeviceCount.ListChange) + if (this.ParentRemoteDevice is not null) + await this.ParentRemoteDevice.RequestParameter(ERDM_Command.GET_COMMAND, ERDM_Parameter.PROXIED_DEVICES); + break; + } + } + catch (Exception ex) + { + Logger?.LogError(ex); + } + } + public override bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command) + { + switch (parameter) + { + case ERDM_Parameter.PROXIED_DEVICES: + case ERDM_Parameter.PROXIED_DEVICES_COUNT: + return true; // These parameters are handled by this module. + } + return false; // Default case, not handled by this module. + } + + protected override RDMMessage handleRequest(RDMMessage message) + { + switch (message.Parameter) + { + case ERDM_Parameter.PROXIED_DEVICES when message.Command is ERDM_Command.GET_COMMAND: + if (!proxiedDevicesOngoingTransaktions.ContainsKey(message.SourceUID)) + { + var devices = DeviceUIDs; + var chunks = devices.Chunk(38); + ConcurrentQueue queue = new ConcurrentQueue(); + byte messageCounter = (byte)chunks.Count(); + foreach (var chunk in chunks) + { + messageCounter--; + queue.Enqueue(new RDMMessage() + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = message.Parameter, + ControllerFlags_or_MessageCounter = messageCounter, + ParameterData = new RDMProxiedDevices(chunk).ToPayloadData() + }); + } + proxiedDevicesOngoingTransaktions.TryAdd(message.SourceUID, queue); + } + proxiedDevicesOngoingTransaktions.TryGetValue(message.SourceUID, out ConcurrentQueue msgQueue); + if (msgQueue != null && msgQueue.TryDequeue(out RDMMessage responseMessage)) + { + if (msgQueue.IsEmpty) + { + proxiedDevicesOngoingTransaktions.TryRemove(message.SourceUID, out _); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.PROXIED_DEVICES_COUNT, new RDMProxiedDeviceCount((ushort)DeviceUIDs.Count, false)); + } + return responseMessage; + } + break; + + case ERDM_Parameter.PROXIED_DEVICES_COUNT when message.Command is ERDM_Command.GET_COMMAND: + return new RDMMessage() + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = message.Parameter, + ParameterData = (this.ParentGeneratedDevice.GetAllParameterValues()[ERDM_Parameter.PROXIED_DEVICES_COUNT] as RDMProxiedDeviceCount).ToPayloadData() + }; + } + return new RDMMessage(ERDM_NackReason.HARDWARE_FAULT) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = message.Command | ERDM_Command.RESPONSE, + Parameter = message.Parameter + }; + } + + public void AddProxiedDevices(params UID[] deviceUIDs) + { + var currentDevices = this.ParentGeneratedDevice.GetAllParameterValues()[ERDM_Parameter.PROXIED_DEVICES] as RDMProxiedDevices; + var devicesList = currentDevices.Devices.ToList(); + bool changed = false; + foreach (var deviceUID in deviceUIDs) + { + if (!devicesList.Contains(deviceUID)) + { + devicesList.Add(deviceUID); + changed = true; + } + } + if (changed) + { + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.PROXIED_DEVICES, new RDMProxiedDevices(devicesList.ToArray())); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.PROXIED_DEVICES_COUNT, new RDMProxiedDeviceCount((ushort)devicesList.Count, true)); + OnPropertyChanged(nameof(DeviceUIDs)); + } + } + public void RemoveProxiedDevices(params UID[] deviceUIDs) + { + var currentDevices = this.ParentGeneratedDevice.GetAllParameterValues()[ERDM_Parameter.PROXIED_DEVICES] as RDMProxiedDevices; + var devicesList = currentDevices.Devices.ToList(); + bool changed = false; + foreach (var deviceUID in deviceUIDs) + { + if (devicesList.Contains(deviceUID)) + { + devicesList.Remove(deviceUID); + changed = true; + } + } + if (changed) + { + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.PROXIED_DEVICES, new RDMProxiedDevices(devicesList.ToArray())); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.PROXIED_DEVICES_COUNT, new RDMProxiedDeviceCount((ushort)devicesList.Count, true)); + OnPropertyChanged(nameof(DeviceUIDs)); + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/RealTimeClockModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/RealTimeClockModule.cs new file mode 100644 index 00000000..23349ad9 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/RealTimeClockModule.cs @@ -0,0 +1,89 @@ +using RDMSharp.PayloadObject; +using System; +using System.Threading.Tasks; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class RealTimeClockModule : AbstractModule +{ + private const string _moduleName = "RealTimeClock"; + private const string _moduleDisplayName = "Real Time Clock"; + private const ERDM_Parameter _moduleParameter = ERDM_Parameter.REAL_TIME_CLOCK; + + public override string DisplayName => _moduleDisplayName; + + public DateTime? RealTimeClock + { + get + { + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.REAL_TIME_CLOCK, out object res)) + { + if (res is DateTime dateTime) + return dateTime; + if (res is RDMRealTimeClock rdmRealTimeClock) + return rdmRealTimeClock.Date; + } + return null; + } + set + { + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.REAL_TIME_CLOCK, new RDMRealTimeClock(value.Value)); + + if (ParentRemoteDevice is not null) + _ = SetClock(value.Value); + } + } + public RealTimeClockModule() : base( + _moduleName, + _moduleParameter) + { + } + public RealTimeClockModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameter) + { + GlobalTimers.Instance.RealTimeClockUpdateTimerElapsed += Instance_RealTimeClockUpdateTimerElapsed; + Task.Run(async () => + { + await Task.Delay(500); + var result = await SetClock(DateTime.Now); + }); + } + ~RealTimeClockModule() + { + GlobalTimers.Instance.RealTimeClockUpdateTimerElapsed -= Instance_RealTimeClockUpdateTimerElapsed; + GlobalTimers.Instance.PresentUpdateTimerElapsed -= Instance_PresentUpdateTimerElapsed; + } + + private async void Instance_RealTimeClockUpdateTimerElapsed(object sender, EventArgs e) + { + await SetClock(DateTime.Now); + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + this.RealTimeClock = DateTime.Now; + GlobalTimers.Instance.PresentUpdateTimerElapsed += Instance_PresentUpdateTimerElapsed; + } + + private void Instance_PresentUpdateTimerElapsed(object sender, EventArgs e) + { + this.RealTimeClock = DateTime.Now; + } + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.REAL_TIME_CLOCK: + OnPropertyChanged(nameof(RealTimeClock)); + break; + } + } + + public async Task SetClock(DateTime dateTime) + { + return await ParentRemoteDevice.SetParameter(ERDM_Parameter.REAL_TIME_CLOCK, new RDMRealTimeClock(dateTime)); + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/SelfTestsModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/SelfTestsModule.cs new file mode 100644 index 00000000..380a4516 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/SelfTestsModule.cs @@ -0,0 +1,41 @@ +namespace RDMSharp.RDM.Device.Module; + +public sealed class SelfTestsModule : AbstractModule +{ + private const string _moduleName = "SelfTests"; + private const string _moduleDisplayName = "Self Tests"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.PERFORM_SELFTEST, + ERDM_Parameter.SELF_TEST_DESCRIPTION + }; + + public override string DisplayName => _moduleDisplayName; + + public SelfTestsModule() : base( + _moduleName, + _moduleParameters) + { + } + public SelfTestsModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + throw new System.NotImplementedException(); + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + //throw new System.NotImplementedException(); + } + + //protected override RDMMessage handleRequest(RDMMessage message) + //{ + // return null; + //} +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/SensorsModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/SensorsModule.cs new file mode 100644 index 00000000..e0390c33 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/SensorsModule.cs @@ -0,0 +1,213 @@ +using RDMSharp.PayloadObject; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class SensorsModule : AbstractModule +{ + private const string _moduleName = "Sensors"; + private const string _moduleDisplayName = "Sensors"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.SENSOR_DEFINITION, + ERDM_Parameter.SENSOR_VALUE, + ERDM_Parameter.RECORD_SENSORS, + ERDM_Parameter.SENSOR_UNIT_CUSTOM, + ERDM_Parameter.SENSOR_TYPE_CUSTOM + }; + + public override string DisplayName => _moduleDisplayName; + + private readonly ConcurrentDictionary sensors = new ConcurrentDictionary(); + public IReadOnlyDictionary Sensors + { + get + { + return sensors.AsReadOnly(); + } + } + + private ConcurrentDictionary sensorDef = new ConcurrentDictionary(); + private ConcurrentDictionary sensorValue = new ConcurrentDictionary(); + private ConcurrentDictionary sensorUnit; + private ConcurrentDictionary sensorType; + + public SensorsModule(params Sensor[] sensors) : base( + _moduleName, + getSupportedParameters(sensors)) + { + if (sensors is null) + throw new ArgumentNullException(nameof(sensors), "Sensors cannot be null."); + if (sensors.Length == 0) + throw new ArgumentException("Sensors cannot be empty.", nameof(sensors)); + + foreach (var sensor in sensors) + { + if (!this.sensors.TryAdd(sensor.SensorId, sensor)) + throw new ArgumentException($"Sensor with ID {sensor.SensorId} already exists in the SensorsModule."); + + if (!sensorDef.TryAdd(sensor.SensorId, (RDMSensorDefinition)sensor)) + throw new Exception($"{sensor.SensorId} already used as {nameof(RDMSensorDefinition)}"); + + if (!sensorValue.TryAdd(sensor.SensorId, (RDMSensorValue)sensor)) + throw new Exception($"{sensor.SensorId} already used as {nameof(RDMSensorValue)}"); + + if (sensor.CustomUnit is not null) + { + if (sensorUnit is null) + sensorUnit = new ConcurrentDictionary(); + sensorUnit.TryAdd(sensor.SensorId, sensor.CustomUnit); + } + if (sensor.CustomType is not null) + { + if (sensorType is null) + sensorType = new ConcurrentDictionary(); + sensorType.TryAdd(sensor.SensorId, sensor.CustomType); + } + + sensor.PropertyChanged += Sensor_PropertyChanged; + } + } + public SensorsModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + } + + private static ERDM_Parameter[] getSupportedParameters(Sensor[] sensors) + { + List supportedParameters = new List + { + ERDM_Parameter.SENSOR_DEFINITION, + ERDM_Parameter.SENSOR_VALUE + }; + if (sensors.Any(s => s.RecordedValueSupported)) + supportedParameters.Add(ERDM_Parameter.RECORD_SENSORS); + + if (sensors.Any(s => ((byte)s.Unit) >= 0x80)) + supportedParameters.Add(ERDM_Parameter.SENSOR_UNIT_CUSTOM); + + if (sensors.Any(s => ((byte)s.Type) >= 0x80)) + supportedParameters.Add(ERDM_Parameter.SENSOR_TYPE_CUSTOM); + + return supportedParameters.ToArray(); + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.SENSOR_DEFINITION, sensorDef); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.SENSOR_VALUE, sensorValue); + if (sensorUnit is not null) + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.SENSOR_UNIT_CUSTOM, sensorUnit); + if (sensorType is not null) + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.SENSOR_TYPE_CUSTOM, sensorType); + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + } + public override bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command) + { + if (parameter == ERDM_Parameter.RECORD_SENSORS) + return command == ERDM_Command.SET_COMMAND; + + return base.IsHandlingParameter(parameter, command); + } + protected override RDMMessage handleRequest(RDMMessage message) + { + if (message.Parameter == ERDM_Parameter.RECORD_SENSORS) + if (message.Command == ERDM_Command.SET_COMMAND) + { + if (message.Value is byte sensorID) + { + try + { + if (sensorID == 0xff)// Broadcast + foreach (var sensor in sensors.Values) + sensor.RecordValue(); + else if (sensors.ContainsKey(sensorID)) + sensors[sensorID].RecordValue(); + else + { + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + } + catch (Exception ex) + { + Logger?.LogError(ex); + return new RDMMessage(ERDM_NackReason.HARDWARE_FAULT) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + return new RDMMessage() + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + }; + } + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + else + return new RDMMessage(ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = message.Command | ERDM_Command.RESPONSE + }; + return base.handleRequest(message); + } + private void Sensor_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (sender is not Sensor sensor) + return; + + switch (e.PropertyName) + { + case nameof(Sensor.Type): + case nameof(Sensor.Unit): + case nameof(Sensor.Prefix): + case nameof(Sensor.RangeMaximum): + case nameof(Sensor.RangeMinimum): + case nameof(Sensor.NormalMaximum): + case nameof(Sensor.NormalMinimum): + case nameof(Sensor.LowestHighestValueSupported): + case nameof(Sensor.RecordedValueSupported): + sensorDef.AddOrUpdate(sensor.SensorId, (RDMSensorDefinition)sensor, (o1, o2) => (RDMSensorDefinition)sensor); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.SENSOR_DEFINITION, sensorDef, sensor.SensorId); + OnPropertyChanged(nameof(Sensors)); + break; + case nameof(Sensor.PresentValue): + case nameof(Sensor.LowestValue): + case nameof(Sensor.HighestValue): + case nameof(Sensor.RecordedValue): + sensorValue.AddOrUpdate(sensor.SensorId, (RDMSensorValue)sensor, (o1, o2) => (RDMSensorValue)sensor); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.SENSOR_VALUE, sensorValue, sensor.SensorId); + OnPropertyChanged(nameof(Sensors)); + break; + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/SlotsModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/SlotsModule.cs new file mode 100644 index 00000000..ff7c9e8c --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/SlotsModule.cs @@ -0,0 +1,130 @@ +using RDMSharp.PayloadObject; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class SlotsModule : AbstractModule +{ + private const string _moduleName = "Slots"; + private const string _moduleDisplayName = "Slots"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.SLOT_INFO, + ERDM_Parameter.SLOT_DESCRIPTION, + ERDM_Parameter.DEFAULT_SLOT_VALUE + }; + + public override string DisplayName => _moduleDisplayName; + + public IPersonality CurrentPersonality + { + get + { + if (ParentGeneratedDevice is not null) + return dmxPersonalityModule.CurrentPersonality; + else if (ParentRemoteDevice is not null) + return ParentRemoteDevice.PersonalityModel.Personality; + return null; + } + } + + public IReadOnlyDictionary Slots + { + get + { + return CurrentPersonality?.Slots; + } + } + + private DMX_PersonalityModule dmxPersonalityModule; + + public SlotsModule() : base( + _moduleName, + _moduleParameters) + { + } + public SlotsModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + dmxPersonalityModule = device.Modules.OfType().FirstOrDefault(); + dmxPersonalityModule.PropertyChanged += DmxPersonalityModule_PropertyChanged; + updateParameterValues(); + } + protected override void OnRemoteParentDeviceChanged(AbstractRemoteRDMDevice device) + { + device.PropertyChanged += DmxPersonalityModule_PropertyChanged; + } + + private void DmxPersonalityModule_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (e.PropertyName != nameof(DMX_PersonalityModule.CurrentPersonality)) + return; + + updateParameterValues(); + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.DMX_PERSONALITY: + updateParameterValues(); + break; + } + } + private void updateParameterValues() + { + if (dmxPersonalityModule is null) + { + if (ParentRemoteDevice is not null) + { + dmxPersonalityModule = ParentRemoteDevice.Modules.OfType().FirstOrDefault(); + dmxPersonalityModule.PropertyChanged += DmxPersonalityModule_PropertyChanged; + } + } + if (ParentRemoteDevice is not null) + { + var pers = (RemotePersonality)CurrentPersonality; + if (!pers.AllDataPulled) + pers.PropertyChanged += Pers_PropertyChanged; + else + OnPropertyChanged(nameof(Slots)); + return; + } + + var slots = this.Slots; + var slotsCount = slots.Count; + var slotInfos = new RDMSlotInfo[slotsCount]; + var slotDesc = new ConcurrentDictionary(); + var slotDefault = new RDMDefaultSlotValue[slotsCount]; + foreach (var s in slots) + { + Slot slot = s.Value; + slotInfos[slot.SlotId] = new RDMSlotInfo(slot.SlotId, slot.Type, slot.Category); + slotDesc.TryAdd(slot.SlotId, new RDMSlotDescription(slot.SlotId, slot.Description)); + slotDefault[slot.SlotId] = new RDMDefaultSlotValue(slot.SlotId, slot.DefaultValue); + } + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.SLOT_INFO, slotInfos); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.SLOT_DESCRIPTION, slotDesc); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.DEFAULT_SLOT_VALUE, slotDefault); + OnPropertyChanged(nameof(Slots)); + } + + private void Pers_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + var pers = (RemotePersonality)sender; + pers.PropertyChanged -= Pers_PropertyChanged; + + if (e.PropertyName == nameof(pers.AllDataPulled)) + OnPropertyChanged(nameof(Slots)); + + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/SoftwareVersionModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/SoftwareVersionModule.cs new file mode 100644 index 00000000..7c7f596d --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/SoftwareVersionModule.cs @@ -0,0 +1,78 @@ +using RDMSharp.PayloadObject; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class SoftwareVersionModule : AbstractModule +{ + private const string _moduleName = "SoftwareVersion"; + private const string _moduleDisplayName = "Software Version"; + private const ERDM_Parameter _moduleParameter = ERDM_Parameter.SOFTWARE_VERSION_LABEL; + + public override string DisplayName => _moduleDisplayName; + + private uint _softwareVersionId; + private string _softwareVersionLabel; + public uint SoftwareVersionId + { + get + { + if (ParentRemoteDevice is not null) + { + object res; + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.DEVICE_INFO, out res)) + return ((RDMDeviceInfo)res).SoftwareVersionId; + } + return _softwareVersionId; + } + internal set + { + _softwareVersionId = value; + } + } + public string SoftwareVersionLabel + { + get + { + if (ParentGeneratedDevice is null && ParentRemoteDevice is null) + return _softwareVersionLabel; + object res; + if (ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.SOFTWARE_VERSION_LABEL, out res)) + return (string)res; + return _softwareVersionLabel; + } + internal set + { + _softwareVersionLabel = value; + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.SOFTWARE_VERSION_LABEL, value); + } + } + public SoftwareVersionModule(uint softwareVersionId, string softwareVersionLabel) : base( + _moduleName, + _moduleParameter) + { + _softwareVersionId = softwareVersionId; + _softwareVersionLabel = softwareVersionLabel; + } + public SoftwareVersionModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameter) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + this.SoftwareVersionId = _softwareVersionId; + this.SoftwareVersionLabel = _softwareVersionLabel; + } + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.SOFTWARE_VERSION_LABEL: + OnPropertyChanged(nameof(SoftwareVersionLabel)); + break; + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.20/2010/StatusMessageModule.cs b/RDMSharp/RDM/Device/Module/E1.20/2010/StatusMessageModule.cs new file mode 100644 index 00000000..27a03d88 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.20/2010/StatusMessageModule.cs @@ -0,0 +1,125 @@ +using RDMSharp.PayloadObject; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class StatusMessagesModule : AbstractModule +{ + private const string _moduleName = "StatusMessages"; + private const string _moduleDisplayName = "Status Messages"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.STATUS_MESSAGES, + ERDM_Parameter.CLEAR_STATUS_ID + }; + + public override string DisplayName => _moduleDisplayName; + + private ConcurrentDictionary statusMessages = new ConcurrentDictionary(); + public IReadOnlyDictionary StatusMessages { get { return statusMessages.AsReadOnly(); } } + public StatusMessagesModule() : base( + _moduleName, + _moduleParameters) + { + } + public StatusMessagesModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.STATUS_MESSAGES, new RDMStatusMessage[0]); + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + } + public override bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command) + { + if (parameter == ERDM_Parameter.CLEAR_STATUS_ID) + return true; + + return base.IsHandlingParameter(parameter, command); + } + protected override RDMMessage handleRequest(RDMMessage message) + { + if (message.Parameter == ERDM_Parameter.CLEAR_STATUS_ID) + if (message.Command == ERDM_Command.SET_COMMAND) + { + if (message.PDL == 0) + { + try + { + statusMessages?.Clear(); + OnPropertyChanged(nameof(StatusMessages)); + } + catch (Exception ex) + { + Logger?.LogError(ex); + return new RDMMessage(ERDM_NackReason.HARDWARE_FAULT) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + return new RDMMessage() + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + }; + } + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + return base.handleRequest(message); + } + public void AddStatusMessage(RDMStatusMessage statusMessage) + { + int id = 0; + if (this.statusMessages.Count != 0) + id = this.statusMessages.Max(s => s.Key) + 1; + if (this.statusMessages.TryAdd(id, statusMessage)) + { + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.STATUS_MESSAGES, this.statusMessages.Select(sm => sm.Value).ToArray()); + OnPropertyChanged(nameof(StatusMessages)); + } + } + public void ClearStatusMessage(RDMStatusMessage statusMessage) + { + this.statusMessages.Where(s => s.Value.Equals(statusMessage)).ToList().ForEach(s => + { + s.Value.Clear(); + }); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.STATUS_MESSAGES, this.statusMessages.Select(sm => sm.Value).ToArray()); + OnPropertyChanged(nameof(StatusMessages)); + } + public void RemoveStatusMessage(RDMStatusMessage statusMessage) + { + bool succes = false; + this.statusMessages.Where(s => s.Value.Equals(statusMessage)).ToList().ForEach(s => + { + if (this.statusMessages.TryRemove(s.Key, out _)) + succes = true; + }); + if (succes) + { + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.STATUS_MESSAGES, this.statusMessages.Select(sm => sm.Value).ToArray()); + OnPropertyChanged(nameof(StatusMessages)); + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.37-1/2012/CurveModule.cs b/RDMSharp/RDM/Device/Module/E1.37-1/2012/CurveModule.cs new file mode 100644 index 00000000..c2e45e16 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.37-1/2012/CurveModule.cs @@ -0,0 +1,238 @@ +using RDMSharp.PayloadObject; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class CurveModule : AbstractModule +{ + private const string _moduleName = "Curve"; + private const string _moduleDisplayName = "Curve"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.CURVE, + ERDM_Parameter.CURVE_DESCRIPTION + }; + + public override string DisplayName => _moduleDisplayName; + + private byte? currentId; + public byte? CurrentId + { + get + { + return currentId; + } + set + { + if (value is null) + return; + + if (currentId == value) + return; + + bool initial = currentId is null; + var backup = currentId; + currentId = value; + + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.CURVE, new RDMCurve(currentId.Value, this.count.Value)); + + if (initial) + return; + + if (ParentRemoteDevice is not null) + { + Task.Run(async () => + { + if (await SetCurve(value.Value)) + OnPropertyChanged(nameof(CurrentId)); + else + { + currentId = backup; + OnPropertyChanged(nameof(CurrentId)); + } + }); + } + } + } + private byte? count; + public byte? Count + { + get + { + return count; + } + private set + { + if (value == count) + return; + count = value; + OnPropertyChanged(); + } + } + + private Dictionary idDescriptionPair = new Dictionary(); + public IReadOnlyDictionary IdDescriptionPair => idDescriptionPair; + + public readonly IReadOnlyCollection _generatedCurves = null; + + private byte _initialCurveId; + + public CurveModule(byte initialCurveId, params RDMCurveDescription[] curves) : base( + _moduleName, + _moduleParameters) + { + if (!curves.Any(c => c.CurveId == initialCurveId)) + throw new ArgumentOutOfRangeException($"No Curve found with ID: {initialCurveId}"); + + _initialCurveId = initialCurveId; + _generatedCurves = (curves ?? Array.Empty()).ToList().AsReadOnly(); + Count = (byte)_generatedCurves.Count; + } + public CurveModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + if (ParentRemoteDevice.ParameterValues.TryGetValue(ERDM_Parameter.CURVE, out object val) && val is RDMCurve curve) + fillFromRemote(curve); + } + + protected override async void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + if (_generatedCurves is not null) + { + if (_generatedCurves.Count >= byte.MaxValue) + throw new ArgumentOutOfRangeException($"There to many {_generatedCurves}! Maximum is {byte.MaxValue - 1}"); + + if (_generatedCurves.Count != 0) + { + var curveDesc = new ConcurrentDictionary(); + foreach (var gCurve in _generatedCurves) + if (!curveDesc.TryAdd(gCurve.CurveId, gCurve)) + throw new Exception($"{gCurve.CurveId} already used as {nameof(gCurve.CurveId)}"); + + device.setParameterValue(ERDM_Parameter.CURVE_DESCRIPTION, curveDesc); + } + } + await SetCurve(_initialCurveId); + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + if (ParentRemoteDevice is null) + return; + + if (!_moduleParameters.Contains(parameter)) + return; + + switch (parameter) + { + case ERDM_Parameter.CURVE_DESCRIPTION: + break; + case ERDM_Parameter.CURVE when newValue is RDMCurve curve: + fillFromRemote(curve); + break; + } + } + + private void fillFromRemote(RDMCurve curve) + { + Count = curve.Curves; + if (idDescriptionPair.Count == 0 && ParentRemoteDevice is not null) + if (ParentRemoteDevice.ParameterValues.TryGetValue(ERDM_Parameter.CURVE_DESCRIPTION, out object val) && val is ConcurrentDictionary dict) + { + foreach (var pair in dict) + if (pair.Value is RDMCurveDescription curveDescription) + idDescriptionPair.Add((byte)curveDescription.Index, curveDescription.Description); + OnPropertyChanged(nameof(IdDescriptionPair)); + } + else + { + for (byte i = 1; i <= Count; i++) + idDescriptionPair.Add(i, $"Curve {i}"); + OnPropertyChanged(nameof(IdDescriptionPair)); + } + + CurrentId = curve.CurrentCurveId; + } + + public override bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command) + { + if (parameter == ERDM_Parameter.CURVE) + return command == ERDM_Command.SET_COMMAND; + return base.IsHandlingParameter(parameter, command); + } + protected override RDMMessage handleRequest(RDMMessage message) + { + if (message.Parameter == ERDM_Parameter.CURVE) + if (message.Command == ERDM_Command.SET_COMMAND) + { + if (message.Value is byte b) + { + try + { + if (this._generatedCurves.FirstOrDefault(c => c.CurveId == b) is RDMCurveDescription curve) + CurrentId = curve.CurveId; + else + { + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + } + catch (Exception ex) + { + Logger?.LogError(ex); + return new RDMMessage(ERDM_NackReason.HARDWARE_FAULT) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + return new RDMMessage() + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + }; + } + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + return base.handleRequest(message); + } + + public async Task SetCurve(byte curveId) + { + if (ParentGeneratedDevice is not null) + { + if (this._generatedCurves.FirstOrDefault(p => p.CurveId == curveId) is not RDMCurveDescription curve) + throw new ArgumentOutOfRangeException($"No Curve found with ID: {curveId}"); + CurrentId = curve.CurveId; + } + if (ParentRemoteDevice is not null) + { + if (!this.IdDescriptionPair.Any(p => p.Key == curveId)) + throw new ArgumentOutOfRangeException($"No Curve found with ID: {curveId}"); + return await ParentRemoteDevice.SetParameter(ERDM_Parameter.CURVE, curveId); + } + return true; + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.37-1/2012/ModulationFrequencyModule.cs b/RDMSharp/RDM/Device/Module/E1.37-1/2012/ModulationFrequencyModule.cs new file mode 100644 index 00000000..5176b861 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.37-1/2012/ModulationFrequencyModule.cs @@ -0,0 +1,238 @@ +using RDMSharp.PayloadObject; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class ModulationFrequencyModule : AbstractModule +{ + private const string _moduleName = "ModulationFrequency"; + private const string _moduleDisplayName = "Modulation Frequency"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.MODULATION_FREQUENCY, + ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION + }; + + public override string DisplayName => _moduleDisplayName; + + private byte? currentId; + public byte? CurrentId + { + get + { + return currentId; + } + set + { + if (value is null) + return; + + if (currentId == value) + return; + + bool initial = currentId is null; + var backup = currentId; + currentId = value; + + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.MODULATION_FREQUENCY, new RDMModulationFrequency(currentId.Value, this.count.Value)); + + if (initial) + return; + + if (ParentRemoteDevice is not null) + { + Task.Run(async () => + { + if (await SetModulationFrequency(value.Value)) + OnPropertyChanged(nameof(CurrentId)); + else + { + currentId = backup; + OnPropertyChanged(nameof(CurrentId)); + } + }); + } + } + } + private byte? count; + public byte? Count + { + get + { + return count; + } + private set + { + if (value == count) + return; + count = value; + OnPropertyChanged(); + } + } + + private Dictionary idDescriptionPair = new Dictionary(); + public IReadOnlyDictionary IdDescriptionPair => idDescriptionPair; + + public readonly IReadOnlyCollection _generatedModulationFrequencys = null; + + private byte _initialModulationFrequencyId; + + public ModulationFrequencyModule(byte initialModulationFrequencyId, params RDMModulationFrequencyDescription[] ModulationFrequencys) : base( + _moduleName, + _moduleParameters) + { + if (!ModulationFrequencys.Any(c => c.ModulationFrequencyId == initialModulationFrequencyId)) + throw new ArgumentOutOfRangeException($"No ModulationFrequency found with ID: {initialModulationFrequencyId}"); + + _initialModulationFrequencyId = initialModulationFrequencyId; + _generatedModulationFrequencys = (ModulationFrequencys ?? Array.Empty()).ToList().AsReadOnly(); + Count = (byte)_generatedModulationFrequencys.Count; + } + public ModulationFrequencyModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + if (ParentRemoteDevice.ParameterValues.TryGetValue(ERDM_Parameter.MODULATION_FREQUENCY, out object val) && val is RDMModulationFrequency ModulationFrequency) + fillFromRemote(ModulationFrequency); + } + + protected override async void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + if (_generatedModulationFrequencys is not null) + { + if (_generatedModulationFrequencys.Count >= byte.MaxValue) + throw new ArgumentOutOfRangeException($"There to many {_generatedModulationFrequencys}! Maximum is {byte.MaxValue - 1}"); + + if (_generatedModulationFrequencys.Count != 0) + { + var ModulationFrequencyDesc = new ConcurrentDictionary(); + foreach (var gModulationFrequency in _generatedModulationFrequencys) + if (!ModulationFrequencyDesc.TryAdd(gModulationFrequency.ModulationFrequencyId, gModulationFrequency)) + throw new Exception($"{gModulationFrequency.ModulationFrequencyId} already used as {nameof(gModulationFrequency.ModulationFrequencyId)}"); + + device.setParameterValue(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, ModulationFrequencyDesc); + } + } + await SetModulationFrequency(_initialModulationFrequencyId); + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + if (ParentRemoteDevice is null) + return; + + if (!_moduleParameters.Contains(parameter)) + return; + + switch (parameter) + { + case ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION: + break; + case ERDM_Parameter.MODULATION_FREQUENCY when newValue is RDMModulationFrequency ModulationFrequency: + fillFromRemote(ModulationFrequency); + break; + } + } + + private void fillFromRemote(RDMModulationFrequency modulationFrequency) + { + Count = modulationFrequency.ModulationFrequencys; + if (idDescriptionPair.Count == 0 && ParentRemoteDevice is not null) + if (ParentRemoteDevice.ParameterValues.TryGetValue(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, out object val) && val is ConcurrentDictionary dict) + { + foreach (var pair in dict) + if (pair.Value is RDMModulationFrequencyDescription modulationFrequencyDescription) + idDescriptionPair.Add((byte)modulationFrequencyDescription.Index, modulationFrequencyDescription.Description); + OnPropertyChanged(nameof(IdDescriptionPair)); + } + else + { + for (byte i = 1; i <= Count; i++) + idDescriptionPair.Add(i, $"ModulationFrequency {i}"); + OnPropertyChanged(nameof(IdDescriptionPair)); + } + + CurrentId = modulationFrequency.ModulationFrequencyId; + } + + public override bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command) + { + if (parameter == ERDM_Parameter.MODULATION_FREQUENCY) + return command == ERDM_Command.SET_COMMAND; + return base.IsHandlingParameter(parameter, command); + } + protected override RDMMessage handleRequest(RDMMessage message) + { + if (message.Parameter == ERDM_Parameter.MODULATION_FREQUENCY) + if (message.Command == ERDM_Command.SET_COMMAND) + { + if (message.Value is byte b) + { + try + { + if (this._generatedModulationFrequencys.FirstOrDefault(c => c.ModulationFrequencyId == b) is RDMModulationFrequencyDescription modulationFrequency) + CurrentId = modulationFrequency.ModulationFrequencyId; + else + { + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + } + catch (Exception ex) + { + Logger?.LogError(ex); + return new RDMMessage(ERDM_NackReason.HARDWARE_FAULT) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + return new RDMMessage() + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + }; + } + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + return base.handleRequest(message); + } + + public async Task SetModulationFrequency(byte modulationFrequencyId) + { + if (ParentGeneratedDevice is not null) + { + if (this._generatedModulationFrequencys.FirstOrDefault(p => p.ModulationFrequencyId == modulationFrequencyId) is not RDMModulationFrequencyDescription modulationFrequency) + throw new ArgumentOutOfRangeException($"No ModulationFrequency found with ID: {modulationFrequencyId}"); + CurrentId = modulationFrequency.ModulationFrequencyId; + } + if (ParentRemoteDevice is not null) + { + if (!this.IdDescriptionPair.Any(p => p.Key == modulationFrequencyId)) + throw new ArgumentOutOfRangeException($"No ModulationFrequency found with ID: {modulationFrequencyId}"); + return await ParentRemoteDevice.SetParameter(ERDM_Parameter.MODULATION_FREQUENCY, modulationFrequencyId); + } + return true; + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.37-1/2012/OutputResponseTimeModule.cs b/RDMSharp/RDM/Device/Module/E1.37-1/2012/OutputResponseTimeModule.cs new file mode 100644 index 00000000..5edaafef --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.37-1/2012/OutputResponseTimeModule.cs @@ -0,0 +1,238 @@ +using RDMSharp.PayloadObject; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class OutputResponseTimeModule : AbstractModule +{ + private const string _moduleName = "OutputResponseTime"; + private const string _moduleDisplayName = "Output Response Time"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.OUTPUT_RESPONSE_TIME, + ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION + }; + + public override string DisplayName => _moduleDisplayName; + + private byte? currentId; + public byte? CurrentId + { + get + { + return currentId; + } + set + { + if (value is null) + return; + + if (currentId == value) + return; + + bool initial = currentId is null; + var backup = currentId; + currentId = value; + + if (ParentGeneratedDevice is not null) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.OUTPUT_RESPONSE_TIME, new RDMOutputResponseTime(currentId.Value, this.count.Value)); + + if (initial) + return; + + if (ParentRemoteDevice is not null) + { + Task.Run(async () => + { + if (await SetOutputResponseTime(value.Value)) + OnPropertyChanged(nameof(CurrentId)); + else + { + currentId = backup; + OnPropertyChanged(nameof(CurrentId)); + } + }); + } + } + } + private byte? count; + public byte? Count + { + get + { + return count; + } + private set + { + if (value == count) + return; + count = value; + OnPropertyChanged(); + } + } + + private Dictionary idDescriptionPair = new Dictionary(); + public IReadOnlyDictionary IdDescriptionPair => idDescriptionPair; + + public readonly IReadOnlyCollection _generatedOutputResponseTimes = null; + + private byte _initialOutputResponseTimeId; + + public OutputResponseTimeModule(byte initialOutputResponseTimeId, params RDMOutputResponseTimeDescription[] outputResponseTimes) : base( + _moduleName, + _moduleParameters) + { + if (!outputResponseTimes.Any(c => c.OutputResponseTimeId == initialOutputResponseTimeId)) + throw new ArgumentOutOfRangeException($"No OutputResponseTime found with ID: {initialOutputResponseTimeId}"); + + _initialOutputResponseTimeId = initialOutputResponseTimeId; + _generatedOutputResponseTimes = (outputResponseTimes ?? Array.Empty()).ToList().AsReadOnly(); + Count = (byte)_generatedOutputResponseTimes.Count; + } + public OutputResponseTimeModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + if (ParentRemoteDevice.ParameterValues.TryGetValue(ERDM_Parameter.OUTPUT_RESPONSE_TIME, out object val) && val is RDMOutputResponseTime outputResponseTime) + fillFromRemote(outputResponseTime); + } + + protected override async void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + if (_generatedOutputResponseTimes is not null) + { + if (_generatedOutputResponseTimes.Count >= byte.MaxValue) + throw new ArgumentOutOfRangeException($"There to many {_generatedOutputResponseTimes}! Maximum is {byte.MaxValue - 1}"); + + if (_generatedOutputResponseTimes.Count != 0) + { + var outputResponseTimeDesc = new ConcurrentDictionary(); + foreach (var gOutputResponseTime in _generatedOutputResponseTimes) + if (!outputResponseTimeDesc.TryAdd(gOutputResponseTime.OutputResponseTimeId, gOutputResponseTime)) + throw new Exception($"{gOutputResponseTime.OutputResponseTimeId} already used as {nameof(gOutputResponseTime.OutputResponseTimeId)}"); + + device.setParameterValue(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, outputResponseTimeDesc); + } + } + await SetOutputResponseTime(_initialOutputResponseTimeId); + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + if (ParentRemoteDevice is null) + return; + + if (!_moduleParameters.Contains(parameter)) + return; + + switch (parameter) + { + case ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION: + break; + case ERDM_Parameter.OUTPUT_RESPONSE_TIME when newValue is RDMOutputResponseTime outputResponseTime: + fillFromRemote(outputResponseTime); + break; + } + } + + private void fillFromRemote(RDMOutputResponseTime outputResponseTime) + { + Count = outputResponseTime.ResponseTimes; + if (idDescriptionPair.Count == 0 && ParentRemoteDevice is not null) + if (ParentRemoteDevice.ParameterValues.TryGetValue(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, out object val) && val is ConcurrentDictionary dict) + { + foreach (var pair in dict) + if (pair.Value is RDMOutputResponseTimeDescription outputResponseTimeDescription) + idDescriptionPair.Add((byte)outputResponseTimeDescription.Index, outputResponseTimeDescription.Description); + OnPropertyChanged(nameof(IdDescriptionPair)); + } + else + { + for (byte i = 1; i <= Count; i++) + idDescriptionPair.Add(i, $"OutputResponseTime {i}"); + OnPropertyChanged(nameof(IdDescriptionPair)); + } + + CurrentId = outputResponseTime.CurrentResponseTimeId; + } + + public override bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command) + { + if (parameter == ERDM_Parameter.OUTPUT_RESPONSE_TIME) + return command == ERDM_Command.SET_COMMAND; + return base.IsHandlingParameter(parameter, command); + } + protected override RDMMessage handleRequest(RDMMessage message) + { + if (message.Parameter == ERDM_Parameter.OUTPUT_RESPONSE_TIME) + if (message.Command == ERDM_Command.SET_COMMAND) + { + if (message.Value is byte b) + { + try + { + if (this._generatedOutputResponseTimes.FirstOrDefault(c => c.OutputResponseTimeId == b) is RDMOutputResponseTimeDescription outputResponseTime) + CurrentId = outputResponseTime.OutputResponseTimeId; + else + { + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + } + catch (Exception ex) + { + Logger?.LogError(ex); + return new RDMMessage(ERDM_NackReason.HARDWARE_FAULT) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + return new RDMMessage() + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + }; + } + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + Command = ERDM_Command.SET_COMMAND_RESPONSE + }; + } + return base.handleRequest(message); + } + + public async Task SetOutputResponseTime(byte outputResponseTimeId) + { + if (ParentGeneratedDevice is not null) + { + if (this._generatedOutputResponseTimes.FirstOrDefault(p => p.OutputResponseTimeId == outputResponseTimeId) is not RDMOutputResponseTimeDescription outputResponseTime) + throw new ArgumentOutOfRangeException($"No OutputResponseTime found with ID: {outputResponseTimeId}"); + CurrentId = outputResponseTime.OutputResponseTimeId; + } + if (ParentRemoteDevice is not null) + { + if (!this.IdDescriptionPair.Any(p => p.Key == outputResponseTimeId)) + throw new ArgumentOutOfRangeException($"No OutputResponseTime found with ID: {outputResponseTimeId}"); + return await ParentRemoteDevice.SetParameter(ERDM_Parameter.OUTPUT_RESPONSE_TIME, outputResponseTimeId); + } + return true; + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.37-1/2012/PresetsModule.cs b/RDMSharp/RDM/Device/Module/E1.37-1/2012/PresetsModule.cs new file mode 100644 index 00000000..89c99639 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.37-1/2012/PresetsModule.cs @@ -0,0 +1,41 @@ +namespace RDMSharp.RDM.Device.Module; + +public sealed class PresetsModule : AbstractModule +{ + private const string _moduleName = "Presets"; + private const string _moduleDisplayName = "Presets"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.PRESET_PLAYBACK, + ERDM_Parameter.CAPTURE_PRESET + }; + public override string DisplayName => _moduleDisplayName; + + + public PresetsModule() : base( + _moduleName, + _moduleParameters) + { + } + public PresetsModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + throw new System.NotImplementedException(); + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + //throw new System.NotImplementedException(); + } + + //protected override RDMMessage handleRequest(RDMMessage message) + //{ + // return null; + //} +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.37-2/2015/InterfaceModule.cs b/RDMSharp/RDM/Device/Module/E1.37-2/2015/InterfaceModule.cs new file mode 100644 index 00000000..df63d2b4 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.37-2/2015/InterfaceModule.cs @@ -0,0 +1,292 @@ +using RDMSharp.PayloadObject; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class InterfaceModule : AbstractModule +{ + private const string _moduleName = "Interface"; + private const string _moduleDisplayName = "Interface"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.LIST_INTERFACES, + ERDM_Parameter.INTERFACE_LABEL, + ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, + ERDM_Parameter.IPV4_DHCP_MODE, + ERDM_Parameter.IPV4_ZEROCONF_MODE, + ERDM_Parameter.IPV4_CURRENT_ADDRESS, + ERDM_Parameter.IPV4_STATIC_ADDRESS, + ERDM_Parameter.INTERFACE_RENEW_DHCP, + ERDM_Parameter.INTERFACE_RELEASE_DHCP, + ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION + }; + + public override string DisplayName => _moduleDisplayName; + + private IReadOnlyCollection _interfaces; + public IReadOnlyCollection Interfaces + { + get + { + return _interfaces; + } + } + private ConcurrentDictionary lableDict = new ConcurrentDictionary(); + private ConcurrentDictionary hardwareAddressTypeDict = new ConcurrentDictionary(); + private ConcurrentDictionary currentAddressDict = new ConcurrentDictionary(); + private ConcurrentDictionary staticAddressDict = new ConcurrentDictionary(); + private ConcurrentDictionary dhcpModeDict = new ConcurrentDictionary(); + private ConcurrentDictionary zeroConfModeDict = new ConcurrentDictionary(); + + private ConcurrentDictionary> applyConfigQueueDict = new ConcurrentDictionary>(); + public InterfaceModule(IReadOnlyCollection interfaces) : base( + _moduleName, + _moduleParameters) + { + _interfaces = interfaces; + } + public InterfaceModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + + foreach (var iface in _interfaces) + { + lableDict.TryAdd(iface.InterfaceId, new GetInterfaceNameResponse(iface.InterfaceId, iface.Lable)); + hardwareAddressTypeDict.TryAdd(iface.InterfaceId, new GetHardwareAddressResponse(iface.InterfaceId, iface.MACAddress)); + currentAddressDict.TryAdd(iface.InterfaceId, new GetIPv4CurrentAddressResponse(iface.InterfaceId, iface.CurrentIP, iface.CurrentSubnetMask, (byte)(iface.DHCP ? 1 : 0))); + staticAddressDict.TryAdd(iface.InterfaceId, new GetSetIPv4StaticAddress(iface.InterfaceId, iface.StaticIP, iface.StaticSubnetMask)); + dhcpModeDict.TryAdd(iface.InterfaceId, new GetSetIPV4_xxx_Mode(iface.InterfaceId, iface.DHCP)); + zeroConfModeDict.TryAdd(iface.InterfaceId, new GetSetIPV4_xxx_Mode(iface.InterfaceId, iface.ZeroConf)); + iface.PropertyChanged += Iface_PropertyChanged; + } + + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.INTERFACE_LABEL, lableDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, hardwareAddressTypeDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.IPV4_CURRENT_ADDRESS, currentAddressDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.IPV4_STATIC_ADDRESS, staticAddressDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.IPV4_DHCP_MODE, dhcpModeDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.IPV4_ZEROCONF_MODE, zeroConfModeDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.LIST_INTERFACES, _interfaces.Select(i => new InterfaceDescriptor(i.InterfaceId, i.HardwareType)).ToArray()); + } + + private void Iface_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (sender is not Interface iface) + return; + switch (e.PropertyName) + { + case (nameof(Interface.DHCP)): + var newDHCPValue = new GetSetIPV4_xxx_Mode(iface.InterfaceId, iface.DHCP); + this.dhcpModeDict.AddOrUpdate(iface.InterfaceId, (_) => newDHCPValue, (_, _) => newDHCPValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.IPV4_DHCP_MODE, this.dhcpModeDict, iface.InterfaceId); + break; + case (nameof(Interface.ZeroConf)): + var newZeroConfValue = new GetSetIPV4_xxx_Mode(iface.InterfaceId, iface.ZeroConf); + this.zeroConfModeDict.AddOrUpdate(iface.InterfaceId, (_) => newZeroConfValue, (_, _) => newZeroConfValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.IPV4_ZEROCONF_MODE, this.zeroConfModeDict, iface.InterfaceId); + break; + + case (nameof(Interface.StaticIP)): + case (nameof(Interface.StaticSubnetMask)): + var newIPv4StaticAddressValue = new GetSetIPv4StaticAddress(iface.InterfaceId, iface.StaticIP, iface.StaticSubnetMask); + this.staticAddressDict.AddOrUpdate(iface.InterfaceId, (_) => newIPv4StaticAddressValue, (_, _) => newIPv4StaticAddressValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.IPV4_STATIC_ADDRESS, this.staticAddressDict, iface.InterfaceId); + break; + case (nameof(Interface.CurrentIP)): + case (nameof(Interface.CurrentSubnetMask)): + var newIPv4CurrentAddressValue = new GetIPv4CurrentAddressResponse(iface.InterfaceId, iface.StaticIP, iface.StaticSubnetMask); + this.currentAddressDict.AddOrUpdate(iface.InterfaceId, (_) => newIPv4CurrentAddressValue, (_, _) => newIPv4CurrentAddressValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.IPV4_CURRENT_ADDRESS, this.currentAddressDict, iface.InterfaceId); + break; + } + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + Interface? iface = null; + if (index is not null && index is uint ui) + iface = _interfaces.FirstOrDefault(iface => iface.InterfaceId == ui); + + if (newValue is ConcurrentDictionary dict && index is not null) + newValue = dict.GetValueOrDefault(index); + + switch (parameter) + { + case ERDM_Parameter.LIST_INTERFACES: + OnPropertyChanged(nameof(Interfaces)); + break; + case ERDM_Parameter.IPV4_DHCP_MODE: + if (iface is not null) + iface.DHCP = ((GetSetIPV4_xxx_Mode)newValue).Enabled; + break; + case ERDM_Parameter.IPV4_ZEROCONF_MODE: + if (iface is not null) + iface.ZeroConf = ((GetSetIPV4_xxx_Mode)newValue).Enabled; + break; + } + } + protected override RDMMessage handleRequest(RDMMessage message) + { + switch (message.Parameter) + { + case ERDM_Parameter.IPV4_ZEROCONF_MODE when message.Command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.IPV4_DHCP_MODE when message.Command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.IPV4_STATIC_ADDRESS when message.Command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION when message.Command is ERDM_Command.SET_COMMAND: + if (message.Value is null) + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + + if (message.PDL >= 4) + { + byte[] parameterData = message.ParameterData.Take(4).ToArray(); + uint interfaceId = message.ParameterData.Length > 0 ? Tools.DataToUInt(ref parameterData) : 0; + + if (_interfaces.FirstOrDefault(iface => iface.InterfaceId == interfaceId) is not Interface iface) + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + try + { +#if DEBUG + if (message.SourceUID.Equals(new UID(0xeeee, 0xf0f0f0f0))) + throw new System.Exception("Simulated hardware fault for testing purposes."); +#endif + if (message.Parameter != ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION) + applyConfigQueueDict.GetOrAdd(interfaceId, (_) => { return new ConcurrentQueue(); }).Enqueue(new RDMMessage(message.BuildMessage())); + else + { + if (applyConfigQueueDict.TryGetValue(interfaceId, out ConcurrentQueue queue)) + while (queue.TryDequeue(out RDMMessage applyMessage)) + { + switch (applyMessage.Parameter) + { + case ERDM_Parameter.IPV4_DHCP_MODE when applyMessage.Value is GetSetIPV4_xxx_Mode dhcpMode: + iface.DHCP = dhcpMode.Enabled; + break; + case ERDM_Parameter.IPV4_ZEROCONF_MODE when applyMessage.Value is GetSetIPV4_xxx_Mode zeroConfMode: + iface.ZeroConf = zeroConfMode.Enabled; + break; + case ERDM_Parameter.IPV4_STATIC_ADDRESS when applyMessage.Value is GetSetIPv4StaticAddress staticAddress: + iface.SetStaticIP(staticAddress.IPAddress, staticAddress.Netmask); + break; + } + } + } + + return new RDMMessage() + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + } + catch (Exception ex) + { + Logger?.LogError(ex); + } + } + break; + case ERDM_Parameter.INTERFACE_RENEW_DHCP when message.Command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.INTERFACE_RELEASE_DHCP when message.Command is ERDM_Command.SET_COMMAND: + if (message.Value is not uint ifaceId) + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + if (_interfaces.FirstOrDefault(iface => iface.InterfaceId == ifaceId) is not Interface iface2) + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + try + { + switch (message.Parameter) + { + case ERDM_Parameter.INTERFACE_RENEW_DHCP: + if (iface2.StaticIP != IPv4Address.Empty || !iface2.DHCP) + return new RDMMessage(ERDM_NackReason.ACTION_NOT_SUPPORTED) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + iface2.RenewDHCP(); + break; + case ERDM_Parameter.INTERFACE_RELEASE_DHCP: + if (iface2.CurrentIP_DHCPStatus != ERDM_DHCPStatusMode.ACTIVE) + return new RDMMessage(ERDM_NackReason.ACTION_NOT_SUPPORTED) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + iface2.ReleaseDHCP(); + break; + } + } + catch (Exception ex) + { + Logger?.LogError(ex); + } + return new RDMMessage() + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + break; + default: + break; + } + return new RDMMessage(ERDM_NackReason.HARDWARE_FAULT) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = message.Command | ERDM_Command.RESPONSE, + Parameter = message.Parameter + }; + } + public override bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command) + { + switch (parameter) + { + case ERDM_Parameter.IPV4_DHCP_MODE when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.IPV4_ZEROCONF_MODE when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.IPV4_STATIC_ADDRESS when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.INTERFACE_RENEW_DHCP when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.INTERFACE_RELEASE_DHCP when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION when command is ERDM_Command.SET_COMMAND: + return true; + } + return base.IsHandlingParameter(parameter, command); + } +} diff --git a/RDMSharp/RDM/Device/Module/E1.37-5/2024/TagsModule.cs b/RDMSharp/RDM/Device/Module/E1.37-5/2024/TagsModule.cs new file mode 100644 index 00000000..5b8e36ea --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.37-5/2024/TagsModule.cs @@ -0,0 +1,345 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class TagsModule : AbstractModule +{ + private const string _moduleName = "Tags"; + private const string _moduleDisplayName = "Tags"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.LIST_TAGS, + ERDM_Parameter.ADD_TAG, + ERDM_Parameter.REMOVE_TAG, + ERDM_Parameter.CHECK_TAG, + ERDM_Parameter.CLEAR_TAGS + }; + + public override string DisplayName => _moduleDisplayName; + + private List tags = new List(); + public IReadOnlyCollection Tags + { + get + { + IReadOnlyCollection tagList = null; + if (this.ParentDevice.GetAllParameterValues().TryGetValue(ERDM_Parameter.LIST_TAGS, out object tags)) + if (tags is IReadOnlyCollection _tagList) + tagList = _tagList; + + return tagList; + } + } + public TagsModule() : base( + _moduleName, + _moduleParameters) + { + } + public TagsModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.LIST_TAGS, tags.ToArray()); + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + switch (parameter) + { + case ERDM_Parameter.LIST_TAGS: + OnPropertyChanged(nameof(Tags)); + break; + } + } + public override bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command) + { + switch (parameter) + { + case ERDM_Parameter.LIST_TAGS: + break; + case ERDM_Parameter.ADD_TAG: + case ERDM_Parameter.REMOVE_TAG: + case ERDM_Parameter.CLEAR_TAGS: + case ERDM_Parameter.CHECK_TAG: + return true; // These parameters are handled by this module. + } + return false; // Default case, not handled by this module. + } + + protected override RDMMessage handleRequest(RDMMessage message) + { + switch (message.Parameter) + { + case ERDM_Parameter.ADD_TAG when message.Command is ERDM_Command.SET_COMMAND: + if (message.Value is string tag) + { + if (string.IsNullOrWhiteSpace(tag)) + { + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + } + try + { +#if DEBUG + if (tag.Equals("GeNeRaTeHaRdWaReFaUlT")) + throw new System.Exception("Simulated hardware fault for testing purposes."); +#endif + if (!validateTag(tag)) + { + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + } + if (!tags.Contains(tag)) + tags.Add(tag); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.LIST_TAGS, tags.ToArray()); + return new RDMMessage() + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + } + catch (System.Exception ex) + { + Logger?.LogError(ex); + } + break; + } + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + case ERDM_Parameter.REMOVE_TAG when message.Command is ERDM_Command.SET_COMMAND: + if (message.Value is string tag2) + { + if (string.IsNullOrWhiteSpace(tag2)) + { + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + } + try + { +#if DEBUG + if (tag2.Equals("GeNeRaTeHaRdWaReFaUlT")) + throw new System.Exception("Simulated hardware fault for testing purposes."); +#endif + if (!validateTag(tag2) || !tags.Contains(tag2)) + { + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + } + tags.Remove(tag2); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.LIST_TAGS, tags.ToArray()); + return new RDMMessage() + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + } + catch (System.Exception ex) + { + Logger?.LogError(ex); + } + break; + } + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + + case ERDM_Parameter.CHECK_TAG when message.Command is ERDM_Command.GET_COMMAND: + + if (message.Value is string tag3) + { + if (string.IsNullOrWhiteSpace(tag3)) + { + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + } + try + { +#if DEBUG + if (tag3.Equals("GeNeRaTeHaRdWaReFaUlT")) + throw new System.Exception("Simulated hardware fault for testing purposes."); +#endif + if (!validateTag(tag3)) + { + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + } + bool tagExists = tags.Contains(tag3); + return new RDMMessage() + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = message.Parameter, + ParameterData = tagExists ? new byte[] { 0x01 } : new byte[] { 0x00 } + }; + } + catch (System.Exception ex) + { + Logger?.LogError(ex); + } + break; + } + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + case ERDM_Parameter.CLEAR_TAGS when message.Command is ERDM_Command.SET_COMMAND: + try + { +#if DEBUG + if (message.SourceUID.Equals(new UID(0xeeee, 0xf0f0f0f0))) + throw new System.Exception("Simulated hardware fault for testing purposes."); +#endif + tags.Clear(); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.LIST_TAGS, tags.ToArray()); + } + catch (System.Exception ex) + { + Logger?.LogError(ex); + break; + } + return new RDMMessage() + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + case ERDM_Parameter.ADD_TAG: + case ERDM_Parameter.REMOVE_TAG: + case ERDM_Parameter.CHECK_TAG: + case ERDM_Parameter.CLEAR_TAGS: + return new RDMMessage(ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = message.Command | ERDM_Command.RESPONSE, + Parameter = message.Parameter + }; + } + return new RDMMessage(ERDM_NackReason.HARDWARE_FAULT) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = message.Command | ERDM_Command.RESPONSE, + Parameter = message.Parameter + }; + } + + public async Task AddTag(string tag) + { + if (string.IsNullOrWhiteSpace(tag)) + throw new System.ArgumentException("Tag can't be null or whitespace.", nameof(tag)); + if (!validateTag(tag)) + throw new System.ArgumentOutOfRangeException(nameof(tag), "Tag must not exceed 32 characters."); + if (this.ParentGeneratedDevice is not null) + { + if (!tags.Contains(tag)) + { + tags.Add(tag); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.LIST_TAGS, tags.ToArray()); + } + } + else if (this.ParentRemoteDevice is not null) + await this.ParentRemoteDevice.SetParameter(ERDM_Parameter.ADD_TAG, tag); + } + public async Task RemoveTag(string tag) + { + if (string.IsNullOrWhiteSpace(tag)) + throw new System.ArgumentException("Tag can't be null or whitespace.", nameof(tag)); + if (!validateTag(tag)) + throw new System.ArgumentOutOfRangeException(nameof(tag), "Tag must not exceed 32 characters."); + if (this.ParentGeneratedDevice is not null) + { + if (tags.Contains(tag)) + { + tags.Remove(tag); + if (this.ParentGeneratedDevice is not null) + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.LIST_TAGS, tags.ToArray()); + } + } + else if (this.ParentRemoteDevice is not null) + await this.ParentRemoteDevice.SetParameter(ERDM_Parameter.REMOVE_TAG, tag); + } + public async Task CheckTag(string tag) + { + if (string.IsNullOrWhiteSpace(tag)) + throw new System.ArgumentException("Tag can't be null or whitespace.", nameof(tag)); + if (!validateTag(tag)) + throw new System.ArgumentOutOfRangeException(nameof(tag), "Tag must not exceed 32 characters."); + + if (this.ParentGeneratedDevice is not null) + return tags.Contains(tag); + else if (this.ParentRemoteDevice is not null) + { + var result = await this.ParentRemoteDevice.RequestParameterWithPayload(ERDM_Command.GET_COMMAND, ERDM_Parameter.CHECK_TAG, tag); + if (result is bool _boolValue) + return _boolValue; + } + return false; + } + public async Task ClearTags() + { + tags.Clear(); + if (this.ParentGeneratedDevice is not null) + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.LIST_TAGS, tags.ToArray()); + else if (this.ParentRemoteDevice is not null) + await this.ParentRemoteDevice.RequestParameter(ERDM_Command.SET_COMMAND, ERDM_Parameter.CLEAR_TAGS); + } + private bool validateTag(string tag) + { + return tag.Length <= 32; + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/Module/E1.37-7/2019/EndpointsModule.cs b/RDMSharp/RDM/Device/Module/E1.37-7/2019/EndpointsModule.cs new file mode 100644 index 00000000..bcc06801 --- /dev/null +++ b/RDMSharp/RDM/Device/Module/E1.37-7/2019/EndpointsModule.cs @@ -0,0 +1,460 @@ +using RDMSharp.PayloadObject; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; + +namespace RDMSharp.RDM.Device.Module; + +public sealed class EndpointsModule : AbstractModule +{ + private const string _moduleName = "Endpoints"; + private const string _moduleDisplayName = "Endpoints"; + private static readonly ERDM_Parameter[] _moduleParameters = new ERDM_Parameter[] + { + ERDM_Parameter.ENDPOINT_LIST, + ERDM_Parameter.ENDPOINT_LIST_CHANGE, + ERDM_Parameter.IDENTIFY_ENDPOINT, + ERDM_Parameter.ENDPOINT_TO_UNIVERSE, + ERDM_Parameter.ENDPOINT_MODE, + ERDM_Parameter.ENDPOINT_LABEL, + ERDM_Parameter.RDM_TRAFFIC_ENABLE, + ERDM_Parameter.DISCOVERY_STATE, + ERDM_Parameter.BACKGROUND_DISCOVERY, + ERDM_Parameter.ENDPOINT_TIMING, + ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, + ERDM_Parameter.ENDPOINT_RESPONDERS, + ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, + ERDM_Parameter.BINDING_CONTROL_FIELDS, + ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, + ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION + }; + + public override string DisplayName => _moduleDisplayName; + + private Dictionary _endpoints; + public IReadOnlyDictionary Endpoints + { + get + { + return _endpoints; + } + } + + internal void AddEndpoint(Endpoint endpoint) + { + if (_endpoints.ContainsKey(endpoint.EndpointId)) + throw new ArgumentException($"An endpoint with the ID {endpoint.EndpointId} already exists."); + _endpoints.Add(endpoint.EndpointId, endpoint); + ListChanged++; + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_LIST, new GetEndpointListResponse(listChanged, _endpoints.Values.Select(ep => new EndpointDescriptor(ep.EndpointId, ep.Type)).ToArray())); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_LIST_CHANGE, ListChanged); + } + internal void RemoveEndpoint(ushort endpointId) + { + if (!_endpoints.ContainsKey(endpointId)) + throw new ArgumentException($"No endpoint with the ID {endpointId} exists."); + _endpoints.Remove(endpointId); + ListChanged++; + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_LIST, new GetEndpointListResponse(listChanged, _endpoints.Values.Select(ep => new EndpointDescriptor(ep.EndpointId, ep.Type)).ToArray())); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_LIST_CHANGE, ListChanged); + } + + private uint listChanged; + public uint ListChanged + { + get { return listChanged; } + private set + { + if (listChanged == value) + return; + listChanged = value; + OnPropertyChanged(nameof(ListChanged)); + } + } + + private byte _backgroundQueuedStatusPolicy; + public byte BackgroundQueuedStatusPolicy + { + get { return _backgroundQueuedStatusPolicy; } + set + { + if (_backgroundQueuedStatusPolicy == value) + return; + _backgroundQueuedStatusPolicy = value; + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, new GetBackgroundQueuedStatusPolicyResponse(this._backgroundQueuedStatusPolicy, (byte)this.backgroundQueueStatusPolicyDescriptionDict.Count)); + OnPropertyChanged(nameof(BackgroundQueuedStatusPolicy)); + } + } + private IDictionary _backgroundQueuedStatusPolicyDescriptions; + public IReadOnlyDictionary BackgroundQueuedStatusPolicyDescriptions + { + get { return _backgroundQueuedStatusPolicyDescriptions.AsReadOnly(); } + } + private IDictionary _timingDescriptions; + public IReadOnlyDictionary TimingDescriptions + { + get { return _timingDescriptions.AsReadOnly(); } + } + + private ConcurrentDictionary identifyDict = new ConcurrentDictionary(); + private ConcurrentDictionary universeDict = new ConcurrentDictionary(); + private ConcurrentDictionary modeDict = new ConcurrentDictionary(); + private ConcurrentDictionary lableDict = new ConcurrentDictionary(); + private ConcurrentDictionary rdmTraficDict = new ConcurrentDictionary(); + private ConcurrentDictionary discoveryStateDict = new ConcurrentDictionary(); + private ConcurrentDictionary backgroundDiscoveryDict = new ConcurrentDictionary(); + private ConcurrentDictionary timingDict = new ConcurrentDictionary(); + private ConcurrentDictionary respondersDict = new ConcurrentDictionary(); + private ConcurrentDictionary responderListChangedDict = new ConcurrentDictionary(); + + private ConcurrentDictionary timingDescriptionDict = new ConcurrentDictionary(); + private ConcurrentDictionary backgroundQueueStatusPolicyDescriptionDict = new ConcurrentDictionary(); + + public EndpointsModule( + byte backgroundQueuedStatusPolicy, + IDictionary backgroundQueuedStatusPolicyDescriptions, + IDictionary timingDescriptions, + IReadOnlyCollection endpoints) : base( + _moduleName, + _moduleParameters) + { + _backgroundQueuedStatusPolicy = backgroundQueuedStatusPolicy; + if (backgroundQueuedStatusPolicyDescriptions.Count > byte.MaxValue) + throw new IndexOutOfRangeException($"Maximum lenght of {nameof(backgroundQueuedStatusPolicyDescriptions)} is {byte.MaxValue}"); + _backgroundQueuedStatusPolicyDescriptions = backgroundQueuedStatusPolicyDescriptions; + + if (timingDescriptions.Count > byte.MaxValue) + throw new IndexOutOfRangeException($"Maximum lenght of {nameof(timingDescriptions)} is {byte.MaxValue}"); + _timingDescriptions = timingDescriptions; + + _endpoints = new Dictionary(); + + if (endpoints.Any(ep => ep.EndpointId == 0)) + throw new ArgumentOutOfRangeException(nameof(endpoints)); + + foreach (var epoint in endpoints) + _endpoints.Add(epoint.EndpointId, epoint); + } + public EndpointsModule(AbstractRemoteRDMDevice remoteDevice) : base( + remoteDevice, + _moduleName, + _moduleParameters) + { + _endpoints = new Dictionary(); + _backgroundQueuedStatusPolicyDescriptions = new Dictionary(); + _timingDescriptions = new Dictionary(); + } + + protected override void OnParentGeneratedDeviceChanged(AbstractGeneratedRDMDevice device) + { + + foreach (var epoint in _endpoints.Values) + { + identifyDict.TryAdd(epoint.EndpointId, new GetSetIdentifyEndpoint(epoint.EndpointId, epoint.Identify)); + universeDict.TryAdd(epoint.EndpointId, new GetSetEndpointToUniverse(epoint.EndpointId, epoint.Universe)); + modeDict.TryAdd(epoint.EndpointId, new GetSetEndpointMode(epoint.EndpointId, epoint.Mode)); + lableDict.TryAdd(epoint.EndpointId, new GetSetEndpointLabel(epoint.EndpointId, epoint.Lable)); + rdmTraficDict.TryAdd(epoint.EndpointId, new GetSetEndpointRDMTrafficEnable(epoint.EndpointId, epoint.RDMTraffic)); + discoveryStateDict.TryAdd(epoint.EndpointId, new GetDiscoveryStateResponse(epoint.EndpointId, epoint.DiscoveryStateCount, epoint.DiscoveryState)); + backgroundDiscoveryDict.TryAdd(epoint.EndpointId, new GetSetEndpointBackgroundDiscovery(epoint.EndpointId, epoint.BackgroundDiscovery)); + timingDict.TryAdd(epoint.EndpointId, new GetEndpointTimingResponse(epoint.EndpointId, epoint.Timing, (byte)this.TimingDescriptions.Count)); + respondersDict.TryAdd(epoint.EndpointId, new GetEndpointRespondersResponse(epoint.EndpointId, epoint.ResponderListChanged, epoint.Responders.ToArray())); + responderListChangedDict.TryAdd(epoint.EndpointId, new GetEndpointResponderListChangeResponse(epoint.EndpointId, epoint.ResponderListChanged)); + epoint.PropertyChanged += Endpoint_PropertyChanged; + } + + foreach (var bDisc in _backgroundQueuedStatusPolicyDescriptions) + backgroundQueueStatusPolicyDescriptionDict.TryAdd(bDisc.Key, new GetBackgroundQueuedStatusPolicyDescriptionResponse(bDisc.Key, bDisc.Value)); + + foreach (var tDisc in _timingDescriptions) + timingDescriptionDict.TryAdd(tDisc.Key, new GetEndpointTimingDescriptionResponse(tDisc.Key, tDisc.Value)); + + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.IDENTIFY_ENDPOINT, identifyDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_TO_UNIVERSE, universeDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_MODE, modeDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_LABEL, lableDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.RDM_TRAFFIC_ENABLE, rdmTraficDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.DISCOVERY_STATE, discoveryStateDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.BACKGROUND_DISCOVERY, backgroundDiscoveryDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_TIMING, timingDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_RESPONDERS, respondersDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, responderListChangedDict); + + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, backgroundQueueStatusPolicyDescriptionDict); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, timingDescriptionDict); + + //ParentGeneratedDevice.setParameterValue(ERDM_Parameter.BINDING_CONTROL_FIELDS, null); // Handled dynamically in handleRequest, because of two identifiers (endpoint and responder UID) + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, new GetBackgroundQueuedStatusPolicyResponse(this._backgroundQueuedStatusPolicy, (byte)this.backgroundQueueStatusPolicyDescriptionDict.Count)); + + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_LIST, new GetEndpointListResponse(listChanged, _endpoints.Values.Select(ep => new EndpointDescriptor(ep.EndpointId, ep.Type)).ToArray())); + ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_LIST_CHANGE, listChanged); + } + + private void Endpoint_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + Endpoint endpoint = (Endpoint)sender; + + switch (e.PropertyName) + { + case (nameof(Endpoint.Identify)): + var newIdentifyValue = new GetSetIdentifyEndpoint(endpoint.EndpointId, endpoint.Identify); + this.identifyDict.AddOrUpdate(endpoint.EndpointId, (_) => newIdentifyValue, (_, _) => newIdentifyValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.IDENTIFY_ENDPOINT, this.identifyDict, endpoint.EndpointId); + break; + case (nameof(Endpoint.Universe)): + var newUniverseValue = new GetSetEndpointToUniverse(endpoint.EndpointId, endpoint.Universe); + this.universeDict.AddOrUpdate(endpoint.EndpointId, (_) => newUniverseValue, (_, _) => newUniverseValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_TO_UNIVERSE, this.universeDict, endpoint.EndpointId); + break; + case (nameof(Endpoint.Mode)): + var newModeValue = new GetSetEndpointMode(endpoint.EndpointId, endpoint.Mode); + this.modeDict.AddOrUpdate(endpoint.EndpointId, (_) => newModeValue, (_, _) => newModeValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_MODE, this.modeDict, endpoint.EndpointId); + break; + case (nameof(Endpoint.Lable)): + var newLableValue = new GetSetEndpointLabel(endpoint.EndpointId, endpoint.Lable); + this.lableDict.AddOrUpdate(endpoint.EndpointId, (_) => newLableValue, (_, _) => newLableValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_LABEL, this.lableDict, endpoint.EndpointId); + break; + case (nameof(Endpoint.RDMTraffic)): + var newRDMTrafficValue = new GetSetEndpointRDMTrafficEnable(endpoint.EndpointId, endpoint.RDMTraffic); + this.rdmTraficDict.AddOrUpdate(endpoint.EndpointId, (_) => newRDMTrafficValue, (_, _) => newRDMTrafficValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.RDM_TRAFFIC_ENABLE, this.rdmTraficDict, endpoint.EndpointId); + break; + case (nameof(Endpoint.DiscoveryState)): + case (nameof(Endpoint.DiscoveryStateCount)): + var newDiscoveryStateValue = new GetDiscoveryStateResponse(endpoint.EndpointId, endpoint.DiscoveryStateCount, endpoint.DiscoveryState); + this.discoveryStateDict.AddOrUpdate(endpoint.EndpointId, (_) => newDiscoveryStateValue, (_, _) => newDiscoveryStateValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.DISCOVERY_STATE, this.discoveryStateDict, endpoint.EndpointId); + break; + case (nameof(Endpoint.BackgroundDiscovery)): + var newBackgroundDiscoveryValue = new GetSetEndpointBackgroundDiscovery(endpoint.EndpointId, endpoint.BackgroundDiscovery); + this.backgroundDiscoveryDict.AddOrUpdate(endpoint.EndpointId, (_) => newBackgroundDiscoveryValue, (_, _) => newBackgroundDiscoveryValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.BACKGROUND_DISCOVERY, this.backgroundDiscoveryDict, endpoint.EndpointId); + break; + case (nameof(Endpoint.Timing)): + var newTimingValue = new GetEndpointTimingResponse(endpoint.EndpointId, endpoint.Timing, (byte)this.TimingDescriptions.Count); + this.timingDescriptionDict.AddOrUpdate(endpoint.EndpointId, (_) => newTimingValue, (_, _) => newTimingValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_TIMING, this.timingDescriptionDict, endpoint.EndpointId); + break; + case (nameof(Endpoint.Responders)): + var newRespondersValue = new GetEndpointRespondersResponse(endpoint.EndpointId, endpoint.ResponderListChanged, endpoint.Responders.ToArray()); + this.respondersDict.AddOrUpdate(endpoint.EndpointId, (_) => newRespondersValue, (_, _) => newRespondersValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_RESPONDERS, this.respondersDict, endpoint.EndpointId); + break; + case (nameof(Endpoint.ResponderListChanged)): + var newResponderListChangedValue = new GetEndpointResponderListChangeResponse(endpoint.EndpointId, endpoint.ResponderListChanged); + this.responderListChangedDict.AddOrUpdate(endpoint.EndpointId, (_) => newResponderListChangedValue, (_, _) => newResponderListChangedValue); + this.ParentGeneratedDevice.setParameterValue(ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, this.responderListChangedDict, endpoint.EndpointId); + break; + } + } + + protected override void ParameterChanged(ERDM_Parameter parameter, object newValue, object index) + { + Endpoint? endpoint = null; + if (index is not null && index is ushort ui) + endpoint = _endpoints.Values.FirstOrDefault(epoint => epoint.EndpointId == ui); + + if (newValue is ConcurrentDictionary dict && index is not null) + newValue = dict.GetValueOrDefault(index); + + switch (parameter) + { + case ERDM_Parameter.ENDPOINT_LIST: + OnPropertyChanged(nameof(Endpoints)); + break; + } + } + protected override RDMMessage handleRequest(RDMMessage message) + { + switch (message.Parameter) + { + case ERDM_Parameter.IDENTIFY_ENDPOINT when message.Command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.ENDPOINT_TO_UNIVERSE when message.Command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.ENDPOINT_MODE when message.Command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.ENDPOINT_LABEL when message.Command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.RDM_TRAFFIC_ENABLE when message.Command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.DISCOVERY_STATE when message.Command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.BACKGROUND_DISCOVERY when message.Command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.ENDPOINT_TIMING when message.Command is ERDM_Command.SET_COMMAND: + if (message.Value is null) + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + + if (message.PDL >= 3) + { + byte[] parameterData = message.ParameterData.Take(2).ToArray(); + ushort endpointId = message.ParameterData.Length > 0 ? Tools.DataToUShort(ref parameterData) : (ushort)0; + + if (_endpoints.Values.FirstOrDefault(epoint => epoint.EndpointId == endpointId) is not Endpoint epoint) + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + try + { +#if DEBUG + if (message.SourceUID.Equals(new UID(0xeeee, 0xf0f0f0f0))) + throw new System.Exception("Simulated hardware fault for testing purposes."); +#endif + switch (message.Parameter) + { + case ERDM_Parameter.IDENTIFY_ENDPOINT when message.Value is GetSetIdentifyEndpoint setIdentifyEndpoint: + epoint.Identify = setIdentifyEndpoint.IdentifyState; + break; + + case ERDM_Parameter.ENDPOINT_TO_UNIVERSE when message.Value is GetSetEndpointToUniverse setEndpointToUniverse: + epoint.Universe = setEndpointToUniverse.Universe; + break; + + case ERDM_Parameter.ENDPOINT_MODE when message.Value is GetSetEndpointMode setEndpointMode: + epoint.Mode = setEndpointMode.EndpointMode; + break; + + case ERDM_Parameter.ENDPOINT_LABEL when message.Value is GetSetEndpointLabel setEndpointLabel: + epoint.Lable = setEndpointLabel.EndpointLabel; + break; + + case ERDM_Parameter.RDM_TRAFFIC_ENABLE when message.Value is GetSetEndpointRDMTrafficEnable setEndpointRDMTrafficEnable: + epoint.RDMTraffic = setEndpointRDMTrafficEnable.RDMTrafficEnabled; + break; + + case ERDM_Parameter.DISCOVERY_STATE when message.Value is SetDiscoveryStateRequest setDiscoveryState: + epoint.DiscoveryState = setDiscoveryState.DiscoveryState; + break; + + case ERDM_Parameter.BACKGROUND_DISCOVERY when message.Value is GetSetEndpointBackgroundDiscovery setBackgroundDiscovery: + epoint.BackgroundDiscovery = setBackgroundDiscovery.BackgroundDiscovery; + break; + + case ERDM_Parameter.ENDPOINT_TIMING when message.Value is SetEndpointTimingRequest setEndpointTiming: + epoint.Timing = setEndpointTiming.TimingId; + break; + } + + return new RDMMessage() + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + } + catch (Exception ex) + { + Logger?.LogError(ex); + } + } + break; + case ERDM_Parameter.BINDING_CONTROL_FIELDS when message.Command is ERDM_Command.GET_COMMAND: + if (message.Value is null || message.Value is not GetBindingAndControlFieldsRequest getBindingAndControlFieldsRequest) + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + if (this.Endpoints.Values.FirstOrDefault(ep => ep.EndpointId == getBindingAndControlFieldsRequest.EndpointId) is not Endpoint endpoint) + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + + GetBindingAndControlFieldsResponse payload = null; + if (endpoint.BindingControlFields.TryGetValue(getBindingAndControlFieldsRequest.UID, out Endpoint.BindingControlField bindingControlField)) + payload = new GetBindingAndControlFieldsResponse(endpoint.EndpointId, bindingControlField.Uid, bindingControlField.ControlField, bindingControlField.BindingUid); + if (payload is null) + payload = new GetBindingAndControlFieldsResponse(endpoint.EndpointId, getBindingAndControlFieldsRequest.UID, 0, new UID(0, 0)); + return new RDMMessage() + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = message.Parameter, + ParameterData = Tools.ValueToData(payload) + }; + + case ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY when message.Command is ERDM_Command.SET_COMMAND: + if (message.Value is null || message.Value is not byte policyId) + return new RDMMessage(ERDM_NackReason.FORMAT_ERROR) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + if (policyId >= this.backgroundQueueStatusPolicyDescriptionDict.Count) + return new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + try + { +#if DEBUG + if (message.SourceUID.Equals(new UID(0xeeee, 0xf0f0f0f0))) + throw new System.Exception("Simulated hardware fault for testing purposes."); +#endif + this.BackgroundQueuedStatusPolicy = policyId; + return new RDMMessage() + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = ERDM_Command.SET_COMMAND_RESPONSE, + Parameter = message.Parameter + }; + + + } + catch (Exception ex) + { + Logger?.LogError(ex); + } + break; + default: + break; + } + return new RDMMessage(ERDM_NackReason.HARDWARE_FAULT) + { + SourceUID = message.DestUID, + DestUID = message.SourceUID, + Command = message.Command | ERDM_Command.RESPONSE, + Parameter = message.Parameter + }; + } + public override bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command) + { + switch (parameter) + { + case ERDM_Parameter.IDENTIFY_ENDPOINT when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.ENDPOINT_TO_UNIVERSE when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.ENDPOINT_MODE when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.ENDPOINT_LABEL when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.RDM_TRAFFIC_ENABLE when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.DISCOVERY_STATE when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.BACKGROUND_DISCOVERY when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.ENDPOINT_TIMING when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY when command is ERDM_Command.SET_COMMAND: + case ERDM_Parameter.BINDING_CONTROL_FIELDS when command is ERDM_Command.GET_COMMAND: + return true; + } + return base.IsHandlingParameter(parameter, command); + } +} diff --git a/RDMSharp/RDM/Device/Module/IModule.cs b/RDMSharp/RDM/Device/Module/IModule.cs new file mode 100644 index 00000000..8af7443c --- /dev/null +++ b/RDMSharp/RDM/Device/Module/IModule.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.ComponentModel; + +namespace RDMSharp.RDM.Device.Module; + +public interface IModule : INotifyPropertyChanged +{ + string Name { get; } + IReadOnlyCollection SupportedParameters { get; } + + RDMMessage? HandleRequest(RDMMessage message); + bool IsHandlingParameter(ERDM_Parameter parameter, ERDM_Command command); +} diff --git a/RDMSharp/RDM/Device/ParameterMetadata.cs b/RDMSharp/RDM/Device/ParameterMetadata.cs new file mode 100644 index 00000000..6127a03a --- /dev/null +++ b/RDMSharp/RDM/Device/ParameterMetadata.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace RDMSharp.RDM.Device; + +public class ParameterMetadata : INotifyPropertyChanged +{ + public readonly ERDM_Parameter Parameter; + + public event PropertyChangedEventHandler PropertyChanged; + + private EQueuedParameterCapabilitiesStatus _queuedCapabilitiesStatus = EQueuedParameterCapabilitiesStatus.Unknown; + public EQueuedParameterCapabilitiesStatus QueuedCapabilitiesStatus + { + get + { + return _queuedCapabilitiesStatus; + } + internal set + { + if (_queuedCapabilitiesStatus == value) + return; + _queuedCapabilitiesStatus = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(QueuedCapabilitiesStatus))); + } + } + + private DateTime _lastUpdated = DateTime.MinValue; + public DateTime LastUpdated + { + get + { + return _lastUpdated; + } + private set + { + if (_lastUpdated == value) + return; + _lastUpdated = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(LastUpdated))); + } + } + + private List peerToPeerProcesses = new List(); + public IReadOnlyCollection PeerToPeerProcesses => peerToPeerProcesses; + + private List requestResponseHistory = new List(); + public IReadOnlyCollection RequestResponseHistory => requestResponseHistory; + + public event EventHandler OnRequestResponseHistoryAdded; + + public ParameterMetadata(ERDM_Parameter parameter) + { + Parameter = parameter; + } + + internal void AddPeerToPeerProcess(PeerToPeerProcess process) + { + process.PropertyChanged += Process_PropertyChanged; + process.OnRequestResponseHistoryAdded += Process_OnRequestResponseHistoryAdded; + peerToPeerProcesses.Add(process); + } + + private void Process_OnRequestResponseHistoryAdded(object sender, RequestResponseHistoryEntry entry) + { + const int maxHistoryEntries = 20; + requestResponseHistory.Add(entry); + + if (requestResponseHistory.Count > maxHistoryEntries) + { + int excessEntries = requestResponseHistory.Count - maxHistoryEntries; + requestResponseHistory.RemoveRange(0, excessEntries); + } + OnRequestResponseHistoryAdded?.Invoke(this, entry); + } + + private void Process_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + PeerToPeerProcess process = sender as PeerToPeerProcess; + switch (e.PropertyName) + { + case nameof(process.State): + switch (process.State) + { + case PeerToPeerProcess.EPeerToPeerProcessState.Finished: + peerToPeerProcesses.Remove(process); + LastUpdated = DateTime.Now; + break; + case PeerToPeerProcess.EPeerToPeerProcessState.Failed: + peerToPeerProcesses.Remove(process); + break; + } + break; + + } + } +} +public enum EQueuedParameterCapabilitiesStatus : byte +{ + Unknown = 0b00000000, + QueuedMessagesParameterSupported = 0b00000010, + Try_1 = 0b00000100, + Try_2 = 0b00001000, + Try_3 = 0b00010000, + Pending = 0b00100000, + Supported = 0b01000000, + NotSupported = 0b10000000, +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/RDMDeviceModel.cs b/RDMSharp/RDM/Device/RDMDeviceModel.cs index 5e09a6ca..7c7b84bd 100644 --- a/RDMSharp/RDM/Device/RDMDeviceModel.cs +++ b/RDMSharp/RDM/Device/RDMDeviceModel.cs @@ -1,4 +1,7 @@ -using RDMSharp.Metadata; +using RDMSharp.Extensions; +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -7,349 +10,375 @@ using System.Threading; using System.Threading.Tasks; -namespace RDMSharp -{ - public sealed class RDMDeviceModel : AbstractRDMCache, IRDMDeviceModel +namespace RDMSharp; + +public sealed class RDMDeviceModel : AbstractRDMCache, IRDMDeviceModel +{ + private static ConcurrentDictionary knownDeviceModels; + public static IReadOnlyCollection KnownDeviceModels => knownDeviceModels.Values.ToList(); + internal static RDMDeviceModel getDeviceModel(UID uid, SubDevice subDevice, RDMDeviceInfo deviceInfo, Func sendRdmFunktion) { - private static ConcurrentDictionary knownDeviceModels; - public static IReadOnlyCollection KnownDeviceModels => knownDeviceModels.Values.ToList(); - internal static RDMDeviceModel getDeviceModel(UID uid, SubDevice subDevice, RDMDeviceInfo deviceInfo, Func sendRdmFunktion) + knownDeviceModels ??= new ConcurrentDictionary(); + var kdm = knownDeviceModels.Values.FirstOrDefault(dm => dm.IsModelOf(uid, subDevice, deviceInfo)); + if (kdm == null) { - knownDeviceModels ??= new ConcurrentDictionary(); - var kdm = knownDeviceModels.Values.FirstOrDefault(dm => dm.IsModelOf(uid, subDevice, deviceInfo)); - if (kdm == null) - { - kdm = new RDMDeviceModel(uid, subDevice, deviceInfo); - knownDeviceModels.TryAdd(kdm.GetHashCode(), kdm); - } - - return kdm; - + kdm = new RDMDeviceModel(uid, subDevice, deviceInfo); + knownDeviceModels.TryAdd(kdm.GetHashCode(), kdm); } + return kdm; + + } - private ConcurrentDictionary knownPersonalityModels = new ConcurrentDictionary(); - public IReadOnlyCollection KnownPersonalityModels => knownPersonalityModels.Values.ToList(); - internal RDMPersonalityModel getPersonalityModel(IRDMRemoteDevice remoteRDMDevice, byte personalityId) + private ConcurrentDictionary knownPersonalityModels = new ConcurrentDictionary(); + public IReadOnlyCollection KnownPersonalityModels => knownPersonalityModels.Values.ToList(); + internal RDMPersonalityModel getPersonalityModel(IRDMRemoteDevice remoteRDMDevice, byte personalityId) + { + try { - try + if (!DeviceInfo.Dmx512CurrentPersonality.HasValue) + return null; + var kpm = knownPersonalityModels.Values.FirstOrDefault(dm => dm.IsModelOf( + remoteRDMDevice.UID, + remoteRDMDevice.DeviceInfo.DeviceModelId, + remoteRDMDevice.DeviceInfo.SoftwareVersionId, + personalityId)); + if (kpm == null) { - if (!DeviceInfo.Dmx512CurrentPersonality.HasValue) - return null; - var kpm = knownPersonalityModels.Values.FirstOrDefault(dm => dm.IsModelOf( - remoteRDMDevice.UID, - remoteRDMDevice.DeviceInfo.DeviceModelId, - remoteRDMDevice.DeviceInfo.SoftwareVersionId, - personalityId)); - if (kpm == null) - { - kpm = new RDMPersonalityModel( - remoteRDMDevice, - personalityId); - knownPersonalityModels.TryAdd(kpm.PersonalityID, kpm); - } - return kpm; + kpm = new RDMPersonalityModel( + remoteRDMDevice, + personalityId); + knownPersonalityModels.TryAdd(kpm.PersonalityID, kpm); } - catch (Exception ex) - { - Logger?.LogError(ex); - } - return null; + return kpm; + } + catch (Exception ex) + { + Logger?.LogError(ex); } + return null; + } - public new bool IsDisposing { get; private set; } - public new bool IsDisposed { get; private set; } + public new bool IsDisposing { get; private set; } + public new bool IsDisposed { get; private set; } - public bool IsInitialized { get; private set; } = false; - public bool IsInitializing { get; private set; } = false; + public bool IsInitialized { get; private set; } = false; + public bool IsInitializing { get; private set; } = false; - public event EventHandler Initialized; - public event PropertyChangedEventHandler PropertyChanged; - public new event EventHandler ParameterValueAdded - { - add - { - base.ParameterValueAdded += value; - } - remove - { - base.ParameterValueAdded -= value; - } - } - - public readonly ushort ManufacturerID; - public readonly EManufacturer Manufacturer; - - private UID currentUsedUID; - public UID CurrentUsedUID + public event EventHandler Initialized; + public event PropertyChangedEventHandler PropertyChanged; + public new event EventHandler ParameterValueAdded + { + add { - get { return currentUsedUID; } - private set - { - if (currentUsedUID == value) - return; - currentUsedUID = value; - PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(CurrentUsedUID))); - } - } - private SubDevice currentUsedSubDevice; - public SubDevice CurrentUsedSubDevice + base.ParameterValueAdded += value; + } + remove { - get - { - return currentUsedSubDevice; - } - private set - { - if (currentUsedSubDevice == value) - return; - currentUsedSubDevice = value; - PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(CurrentUsedSubDevice))); - } + base.ParameterValueAdded -= value; } - + } - public RDMDeviceInfo DeviceInfo - { - get { return parameterValues.TryGetValue(ERDM_Parameter.DEVICE_INFO, out object value) ? value as RDMDeviceInfo : null; } - private set - { - if (this.DeviceInfo == value) - return; - - var dataTreeBranch = DataTreeBranch.FromObject(value, null, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DEVICE_INFO); - updateParameterValuesDependeciePropertyBag(ERDM_Parameter.DEVICE_INFO, dataTreeBranch); - updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ERDM_Parameter.DEVICE_INFO), dataTreeBranch); - PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(DeviceInfo))); - } - } + public readonly ushort ManufacturerID; + public readonly EManufacturer Manufacturer; - private ConcurrentDictionary supportedParameters = new ConcurrentDictionary(); - public IReadOnlyCollection SupportedParameters - { - get { return this.supportedParameters.Where(sp => sp.Value).Select(sp => sp.Key).Where(p => ((ushort)p > 0x000F)).OrderBy(p => p).ToArray().AsReadOnly(); } - } - public IReadOnlyCollection SupportedBlueprintParameters - { - get { return this.SupportedParameters.Intersect(Constants.BLUEPRINT_MODEL_PARAMETERS).OrderBy(p => p).ToList().AsReadOnly(); } + private UID currentUsedUID; + public UID CurrentUsedUID + { + get { return currentUsedUID; } + private set + { + if (currentUsedUID == value) + return; + currentUsedUID = value; + PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(CurrentUsedUID))); } - public IReadOnlyCollection SupportedPersonalityBlueprintParameters - { - get { return this.SupportedParameters.Intersect(Constants.BLUEPRINT_MODEL_PERSONALITY_PARAMETERS).OrderBy(p => p).ToList().AsReadOnly(); } + } + private SubDevice currentUsedSubDevice; + public SubDevice CurrentUsedSubDevice + { + get + { + return currentUsedSubDevice; } - public IReadOnlyCollection SupportedNonBlueprintParameters - { - get { return this.SupportedParameters.Except(SupportedBlueprintParameters).Except(SupportedPersonalityBlueprintParameters).OrderBy(p => p).ToList().AsReadOnly(); } + private set + { + if (currentUsedSubDevice == value) + return; + currentUsedSubDevice = value; + PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(CurrentUsedSubDevice))); } + } + - public IReadOnlyCollection KnownNotSupportedParameters + public RDMDeviceInfo DeviceInfo + { + get { return parameterValues.TryGetValue(ERDM_Parameter.DEVICE_INFO, out object value) ? value as RDMDeviceInfo : null; } + private set { - get { return this.supportedParameters.Where(sp => !sp.Value).Select(sp => sp.Key).OrderBy(p => p).ToArray().AsReadOnly(); } + if (this.DeviceInfo == value) + return; + + var dataTreeBranch = DataTreeBranch.FromObject(value, null, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DEVICE_INFO); + updateParameterValuesDependeciePropertyBag(ERDM_Parameter.DEVICE_INFO, dataTreeBranch); + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ERDM_Parameter.DEVICE_INFO), dataTreeBranch); + PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(DeviceInfo))); } + } - internal RDMDeviceModel(UID uid, SubDevice subdevice, RDMDeviceInfo deviceInfo) - { - DeviceInfo = deviceInfo; - CurrentUsedUID = uid; - CurrentUsedSubDevice = subdevice; - ManufacturerID = uid.ManufacturerID; - Manufacturer = (EManufacturer)uid.ManufacturerID; - this.ParameterValueAdded += RDMDeviceModel_ParameterValueAdded; - } + private ConcurrentDictionary supportedParameters = new ConcurrentDictionary(); - private SemaphoreSlim initializeSemaphoreSlim = new SemaphoreSlim(1); - internal async Task Initialize() + public IReadOnlyCollection GetSupportedParameters() + { + return this.supportedParameters.Where(sp => sp.Value.IsSupported && ((ushort)sp.Value.Parameter > 0x000F)).Select(sp => sp.Value).OrderBy(p => p.Parameter).ToArray().AsReadOnly(); + } + public IReadOnlyCollection GetSupportedBlueprintModelParameters() + { + return this.supportedParameters.Where(sp => sp.Value.IsSupported && sp.Value.IsBlueprintModel && ((ushort)sp.Value.Parameter > 0x000F)).Select(sp => sp.Value).OrderBy(p => p.Parameter).ToArray().AsReadOnly(); + } + public IReadOnlyCollection GetSupportedBlueprintModelPersonalityParameters() + { + return this.supportedParameters.Where(sp => sp.Value.IsSupported && sp.Value.IsBlueprintModelPersonality && ((ushort)sp.Value.Parameter > 0x000F)).Select(sp => sp.Value).OrderBy(p => p.Parameter).ToArray().AsReadOnly(); + } + public IReadOnlyCollection GetSupportedNonBlueprintParameters() + { + return this.supportedParameters.Where(sp => sp.Value.IsSupported && sp.Value.IsNonBlueprint && ((ushort)sp.Value.Parameter > 0x000F)).Select(sp => sp.Value).OrderBy(p => p.Parameter).ToArray().AsReadOnly(); + } + public IReadOnlyCollection GetKnownNotSupportedParameters() + { + return this.supportedParameters.Where(sp => !sp.Value.IsSupported && ((ushort)sp.Value.Parameter > 0x000F)).Select(sp => sp.Value).OrderBy(p => p.Parameter).ToArray().AsReadOnly(); + } + + internal RDMDeviceModel(UID uid, SubDevice subdevice, RDMDeviceInfo deviceInfo) + { + DeviceInfo = deviceInfo; + CurrentUsedUID = uid; + CurrentUsedSubDevice = subdevice; + ManufacturerID = uid.ManufacturerID; + Manufacturer = (EManufacturer)uid.ManufacturerID; + this.ParameterValueAdded += RDMDeviceModel_ParameterValueAdded; + } + + private SemaphoreSlim initializeSemaphoreSlim = new SemaphoreSlim(1); + internal async Task Initialize() + { + if (IsInitialized) + return; + if (initializeSemaphoreSlim.CurrentCount == 0) + return; + IsInitializing = true; + + await initializeSemaphoreSlim.WaitAsync(); + try { - if (IsInitialized) - return; - if (initializeSemaphoreSlim.CurrentCount == 0) - return; - IsInitializing = true; - - await initializeSemaphoreSlim.WaitAsync(); - try - { - await requestSupportedParameters(); - await requestBlueprintParameters(); - //await requestPersonalityBlueprintParameters(); + await requestSupportedParameters(); + await requestBlueprintParameters(this.GetSupportedBlueprintModelParameters()); + await requestSupportedParametersExtensions(); + //await requestPersonalityBlueprintParameters(); - IsInitialized = true; - } - finally - { - initializeSemaphoreSlim.Release(); - IsInitializing = false; - } - Initialized?.Invoke(this, EventArgs.Empty); + IsInitialized = true; + } + catch (Exception e) + { + Logger?.LogError(e); } + finally + { + initializeSemaphoreSlim.Release(); + IsInitializing = false; + } + Initialized?.Invoke(this, EventArgs.Empty); + } - #region Requests - private async Task requestSupportedParameters() - { - ParameterBag parameterBag = new ParameterBag(ERDM_Parameter.SUPPORTED_PARAMETERS); - PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, CurrentUsedUID, CurrentUsedSubDevice, parameterBag); - await runPeerToPeerProcess(ptpProcess); + #region Requests + private async Task requestSupportedParameters() + { + ParameterBag parameterBag = new ParameterBag(ERDM_Parameter.SUPPORTED_PARAMETERS); + PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, CurrentUsedUID, CurrentUsedSubDevice, parameterBag); + await runPeerToPeerProcess(ptpProcess); - if (!ptpProcess.ResponsePayloadObject.IsUnset) - updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(parameterBag.PID), ptpProcess.ResponsePayloadObject); + if (!ptpProcess.ResponsePayloadObject.IsUnset) + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(parameterBag.PID), ptpProcess.ResponsePayloadObject); - if (ptpProcess.ResponsePayloadObject.ParsedObject is ERDM_Parameter[] parameters) + if (ptpProcess.ResponsePayloadObject.ParsedObject is ERDM_Parameter[] parameters) + { + foreach (var para in parameters) { - foreach (var para in parameters) - { - if (!this.supportedParameters.TryGetValue(para, out _)) - supportedParameters.TryAdd(para, true); - } - if (DeviceInfo.Dmx512StartAddress.HasValue && DeviceInfo.Dmx512StartAddress >= 1 && DeviceInfo.Dmx512StartAddress.Value <= 512) // Remote Device not send DMX_START_ADDRESS Parameter but uses it! - supportedParameters.TryAdd(ERDM_Parameter.DMX_START_ADDRESS, true); + if (!this.supportedParameters.TryGetValue(para, out _)) + if (ExtensionsManager.Instance.TryGetSupportedParameterMetadata(this.Manufacturer, para, out SupportedParameterMetadata supportedParameterMetadata)) + supportedParameters.TryAdd(para, supportedParameterMetadata); + } + //if (DeviceInfo.Dmx512StartAddress.HasValue && DeviceInfo.Dmx512StartAddress >= 1 && DeviceInfo.Dmx512StartAddress.Value <= 512) // Remote Device not send DMX_START_ADDRESS Parameter but uses it! + // supportedParameters.TryAdd(ERDM_Parameter.DMX_START_ADDRESS, true); - if (DeviceInfo.Dmx512CurrentPersonality.HasValue) // Remote Device not send DMX_PERSONALITY Parameter but uses it! - supportedParameters.TryAdd(ERDM_Parameter.DMX_PERSONALITY, true); + //if (DeviceInfo.Dmx512CurrentPersonality.HasValue) // Remote Device not send DMX_PERSONALITY Parameter but uses it! + // supportedParameters.TryAdd(ERDM_Parameter.DMX_PERSONALITY, true); - if (!this.supportedParameters.ContainsKey(ERDM_Parameter.PARAMETER_DESCRIPTION) && this.supportedParameters.Any(p=> ((ushort)p.Key) >= 0x8000 && ((ushort)p.Key) <= 0xFFDF)) // Remote Device not send PARAMETER_DESCRIPTION Parameter but has Manufacture speific Parameters it! - this.supportedParameters.TryAdd(ERDM_Parameter.PARAMETER_DESCRIPTION, true); + //if (!this.supportedParameters.ContainsKey(ERDM_Parameter.PARAMETER_DESCRIPTION) && this.supportedParameters.Any(p => ((ushort)p.Key) >= 0x8000 && ((ushort)p.Key) <= 0xFFDF)) // Remote Device not send PARAMETER_DESCRIPTION Parameter but has Manufacture speific Parameters it! + // this.supportedParameters.TryAdd(ERDM_Parameter.PARAMETER_DESCRIPTION, true); - if (!this.supportedParameters.ContainsKey(ERDM_Parameter.IDENTIFY_DEVICE)) //Test it if the device supports Identify Device Parameter, if not it will be labled as not supported later on - this.supportedParameters.TryAdd(ERDM_Parameter.IDENTIFY_DEVICE, true); + //if (!this.supportedParameters.ContainsKey(ERDM_Parameter.IDENTIFY_DEVICE)) //Test it if the device supports Identify Device Parameter, if not it will be labled as not supported later on + // this.supportedParameters.TryAdd(ERDM_Parameter.IDENTIFY_DEVICE, true); - if (!this.supportedParameters.ContainsKey(ERDM_Parameter.SOFTWARE_VERSION_LABEL))//Test it if the device supports Software Version Lable Device Parameter, if not it will be labled as not supported later on - this.supportedParameters.TryAdd(ERDM_Parameter.SOFTWARE_VERSION_LABEL, true); + //if (!this.supportedParameters.ContainsKey(ERDM_Parameter.SOFTWARE_VERSION_LABEL))//Test it if the device supports Software Version Lable Device Parameter, if not it will be labled as not supported later on + // this.supportedParameters.TryAdd(ERDM_Parameter.SOFTWARE_VERSION_LABEL, true); - if (!this.supportedParameters.ContainsKey(ERDM_Parameter.FACTORY_DEFAULTS))//Test it if the device supports Factory Defaults Device Parameter, if not it will be labled as not supported later on - this.supportedParameters.TryAdd(ERDM_Parameter.FACTORY_DEFAULTS, true); + //if (!this.supportedParameters.ContainsKey(ERDM_Parameter.FACTORY_DEFAULTS))//Test it if the device supports Factory Defaults Device Parameter, if not it will be labled as not supported later on + // this.supportedParameters.TryAdd(ERDM_Parameter.FACTORY_DEFAULTS, true); - if(this.supportedParameters.Any(p=>((ushort)p.Key)>0x9000 && ((ushort)p.Key) <= 0x900D)) - this.supportedParameters.TryAdd(ERDM_Parameter.ENDPOINT_LIST, true); - } - await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenRequests); + //if (this.supportedParameters.Any(p => ((ushort)p.Key) > 0x9000 && ((ushort)p.Key) <= 0x900D)) + // this.supportedParameters.TryAdd(ERDM_Parameter.ENDPOINT_LIST, true); } - - private async Task requestBlueprintParameters() + await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenRequests); + } + private async Task requestSupportedParametersExtensions() + { + ExtensionsManager.Instance.TryGetSupportedParametersExtensions(this.Manufacturer, out IReadOnlyCollection supportedParametersExtensionsResult); + Func getExtSupportedParameters = async (dm) => { - var parameters = this.SupportedBlueprintParameters.OrderBy(p => (ushort)p).ToList(); - foreach (ERDM_Parameter parameter in parameters) + List extSupportedParameters = new List(); + foreach (var p in dm) + if (ExtensionsManager.Instance.TryGetSupportedParameterMetadata(this.Manufacturer, p, out SupportedParameterMetadata supportedParameterMetadata)) + if (supportedParameters.TryAdd(p, supportedParameterMetadata)) + extSupportedParameters.Add(supportedParameterMetadata); + + List supportedParameterMetadataToRequest = new List(); + supportedParameterMetadataToRequest.AddRange(extSupportedParameters); + if (extSupportedParameters.Where(spm => spm.IsManufacturerSpecific).Count() != 0) + supportedParameterMetadataToRequest.InsertRange(0, this.supportedParameters.Where(p => p.Key == ERDM_Parameter.PARAMETER_DESCRIPTION).Select(p => p.Value)); + await requestBlueprintParameters(supportedParameterMetadataToRequest.Where(sp => sp.IsBlueprintModel).ToList()); + }; + foreach (var ext in supportedParametersExtensionsResult) + await ext.RegisterAddSupportedParametersHandler(this, getExtSupportedParameters); + } + private async Task requestBlueprintParameters(IReadOnlyCollection parameters) + { + foreach (var spm in parameters) + { + ERDM_Parameter parameter = spm.Parameter; + if (parameter == ERDM_Parameter.SUPPORTED_PARAMETERS) + continue; + ParameterBag parameterBag = new ParameterBag(parameter, ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); + var define = MetadataFactory.GetDefine(parameterBag); + if (define?.GetRequest.HasValue ?? false) { - if (parameter == ERDM_Parameter.SUPPORTED_PARAMETERS) - continue; - ParameterBag parameterBag = new ParameterBag(parameter, ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); - var define = MetadataFactory.GetDefine(parameterBag); - if (define.GetRequest.HasValue) - { - if (define.GetRequest.Value.GetIsEmpty()) - await requestGetParameterWithEmptyPayload(parameterBag, define, CurrentUsedUID, CurrentUsedSubDevice); - else if (parameter == ERDM_Parameter.PARAMETER_DESCRIPTION) - foreach (var pid in this.supportedParameters.Where(p => (ushort)p.Key >= 0x8000 && (ushort)p.Key <= 0xFFDF).Select(p => (ushort)p.Key)) - await requestGetParameterWithPayload(parameterBag, define, CurrentUsedUID, CurrentUsedSubDevice, pid); - else - await requestGetParameterWithPayload(parameterBag, define, CurrentUsedUID, CurrentUsedSubDevice); - } - await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenRequests); + if (define.GetRequest.Value.GetIsEmpty()) + await requestGetParameterWithEmptyPayload(parameterBag, define, CurrentUsedUID, CurrentUsedSubDevice); + else if (parameter == ERDM_Parameter.PARAMETER_DESCRIPTION) + foreach (var pid in this.supportedParameters.Where(p => p.Value.IsManufacturerSpecific && p.Value.ParameterDescription is null).Select(p => (ushort)p.Key)) + { + var result = await requestGetParameterWithPayload(parameterBag, define, CurrentUsedUID, CurrentUsedSubDevice, pid); + spm.SetParameterDescription(result); + } + else + await requestGetParameterWithPayload(parameterBag, define, CurrentUsedUID, CurrentUsedSubDevice); } + await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenRequests); } - #endregion + } + #endregion - public bool IsModelOf(UID uid, SubDevice subDevice, RDMDeviceInfo other) - { - var deviceInfo = this.DeviceInfo; - if (this.ManufacturerID != uid.ManufacturerID) - return false; - if (this.CurrentUsedSubDevice != subDevice) - return false; - if (deviceInfo.DeviceModelId != other.DeviceModelId) - return false; - if (deviceInfo.RdmProtocolVersionMajor != other.RdmProtocolVersionMajor) - return false; - if (deviceInfo.RdmProtocolVersionMinor != other.RdmProtocolVersionMinor) - return false; - if (deviceInfo.SoftwareVersionId != other.SoftwareVersionId) - return false; - if (deviceInfo.Dmx512NumberOfPersonalities != other.Dmx512NumberOfPersonalities) - return false; - if (deviceInfo.ProductCategoryCoarse != other.ProductCategoryCoarse) - return false; - if (deviceInfo.ProductCategoryFine != other.ProductCategoryFine) - return false; - if (deviceInfo.SensorCount != other.SensorCount) - return false; + public bool IsModelOf(UID uid, SubDevice subDevice, RDMDeviceInfo other) + { - return true; - } - protected sealed override Task OnResponseMessage(RDMMessage rdmMessage) - { - if (rdmMessage.ResponseType == ERDM_ResponseType.NACK_REASON) - handleNACKReason(rdmMessage); - return base.OnResponseMessage(rdmMessage); - } + var deviceInfo = this.DeviceInfo; + if (other is null || deviceInfo is null) + return false; - internal bool handleNACKReason(RDMMessage rdmMessage) - { - if (rdmMessage.NackReason.Contains(ERDM_NackReason.ACTION_NOT_SUPPORTED) || rdmMessage.NackReason.Contains(ERDM_NackReason.UNKNOWN_PID)) - { - AddParameterToKnownNotSupportedParameters(rdmMessage.Parameter); - return false; - } - return true; - } - - internal void AddParameterToKnownNotSupportedParameters(ERDM_Parameter parameter) + if (this.ManufacturerID != uid.ManufacturerID) + return false; + if (this.CurrentUsedSubDevice != subDevice) + return false; + if (deviceInfo.DeviceModelId != other.DeviceModelId) + return false; + if (deviceInfo.RdmProtocolVersionMajor != other.RdmProtocolVersionMajor) + return false; + if (deviceInfo.RdmProtocolVersionMinor != other.RdmProtocolVersionMinor) + return false; + if (deviceInfo.SoftwareVersionId != other.SoftwareVersionId) + return false; + if (deviceInfo.Dmx512NumberOfPersonalities != other.Dmx512NumberOfPersonalities) + return false; + if (deviceInfo.ProductCategoryCoarse != other.ProductCategoryCoarse) + return false; + if (deviceInfo.ProductCategoryFine != other.ProductCategoryFine) + return false; + if (deviceInfo.SensorCount != other.SensorCount) + return false; + + return true; + } + protected sealed override Task OnResponseMessage(RDMMessage rdmMessage) + { + if (rdmMessage.ResponseType == ERDM_ResponseType.NACK_REASON) + handleNACKReason(rdmMessage); + return base.OnResponseMessage(rdmMessage); + } + + internal bool handleNACKReason(RDMMessage rdmMessage) + { + if (rdmMessage.NackReason == ERDM_NackReason.FORMAT_ERROR || rdmMessage.NackReason == ERDM_NackReason.UNKNOWN_PID || rdmMessage.NackReason == ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS) { - this.supportedParameters.AddOrUpdate(parameter, false, (x, y) => false); + if (this.supportedParameters.TryGetValue(rdmMessage.Parameter, out SupportedParameterMetadata supportedParameterMetadata)) + supportedParameterMetadata.HandleNack(rdmMessage); + return false; } + return true; + } - private void RDMDeviceModel_ParameterValueAdded(object sender, ParameterValueAddedEventArgs e) + private void RDMDeviceModel_ParameterValueAdded(object sender, ParameterValueAddedEventArgs e) + { + if (e.Parameter == ERDM_Parameter.PARAMETER_DESCRIPTION) { - if (e.Parameter == ERDM_Parameter.PARAMETER_DESCRIPTION) - { - if (e.Value is not RDMParameterDescription pd) - return; + if (e.Value is not RDMParameterDescription pd) + return; - var define = MetadataFactory.GetDefine(new ParameterBag((ERDM_Parameter)pd.ParameterId, this.CurrentUsedUID.ManufacturerID, this.DeviceInfo.DeviceModelId, this.DeviceInfo.SoftwareVersionId)); - if (define is null) - MetadataFactory.AddDefineFromParameterDescription(this.CurrentUsedUID, this.CurrentUsedSubDevice, this.DeviceInfo, pd); - } + var define = MetadataFactory.GetDefine(new ParameterBag((ERDM_Parameter)pd.ParameterId, this.CurrentUsedUID.ManufacturerID, this.DeviceInfo.DeviceModelId, this.DeviceInfo.SoftwareVersionId)); + if (define is null) + MetadataFactory.AddDefineFromParameterDescription(this.CurrentUsedUID, this.CurrentUsedSubDevice, this.DeviceInfo, pd); } + } - public new void Dispose() - { - if (this.IsDisposed || this.IsDisposing) - return; + public new void Dispose() + { + if (this.IsDisposed || this.IsDisposing) + return; - this.IsDisposing = true; - this.PropertyChanged = null; - this.Initialized = null; + this.IsDisposing = true; + this.PropertyChanged = null; + this.Initialized = null; - this.supportedParameters = null; - base.Dispose(); + this.supportedParameters = null; + base.Dispose(); - this.IsDisposed = true; - this.IsDisposing = false; - } + this.IsDisposed = true; + this.IsDisposing = false; + } - public IReadOnlyCollection GetSensorDefinitions() + public IReadOnlyCollection GetSensorDefinitions() + { + try { - try - { - if (!parameterValues.TryGetValue(ERDM_Parameter.SENSOR_DEFINITION, out object value)) - return Array.Empty(); - else - { - if (value is ConcurrentDictionary cd) - return cd.Values.Cast().ToArray(); - return value as RDMSensorDefinition[]; - } - } - catch + if (!parameterValues.TryGetValue(ERDM_Parameter.SENSOR_DEFINITION, out object value)) + return Array.Empty(); + else { - + if (value is ConcurrentDictionary cd) + return cd.Values.Cast().ToArray(); + return value as RDMSensorDefinition[]; } - return Array.Empty(); } - - public override string ToString() + catch { - return $"{Enum.GetName(typeof(EManufacturer), Manufacturer)}"; + } - } + return Array.Empty(); + } + + public override string ToString() + { + return $"{Enum.GetName(typeof(EManufacturer), Manufacturer)}"; + } } \ No newline at end of file diff --git a/RDMSharp/RDM/Device/RDMPersonalityModel.cs b/RDMSharp/RDM/Device/RDMPersonalityModel.cs index 50868de4..a315ab62 100644 --- a/RDMSharp/RDM/Device/RDMPersonalityModel.cs +++ b/RDMSharp/RDM/Device/RDMPersonalityModel.cs @@ -1,4 +1,5 @@ using RDMSharp.Metadata; +using RDMSharp.PayloadObject; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -7,195 +8,202 @@ using System.Threading; using System.Threading.Tasks; -namespace RDMSharp +namespace RDMSharp; + +public sealed class RDMPersonalityModel : AbstractRDMCache { - public sealed class RDMPersonalityModel : AbstractRDMCache - { - public event PropertyChangedEventHandler PropertyChanged; - public event EventHandler SlotAdded; - public event EventHandler Initialized; + public event PropertyChangedEventHandler PropertyChanged; + public event EventHandler Initialized; - public readonly ushort ManufacturerID; - public readonly EManufacturer Manufacturer; + public readonly ushort ManufacturerID; + public readonly EManufacturer Manufacturer; - public readonly ushort DeviceModelID; - public bool IsInitialized { get; private set; } = false; - public bool IsInitializing { get; private set; } = false; + public readonly ushort DeviceModelID; + public bool IsInitialized { get; private set; } = false; + public bool IsInitializing { get; private set; } = false; - //Id given from PID DMX_PERSONALITY = 0x00E0 & DMX_PERSONALITY_DESCRIPTION E1.20 - public byte PersonalityID { get; private set; } - public uint SoftwareVersionID { get; private set; } + //Id given from PID DMX_PERSONALITY = 0x00E0 & DMX_PERSONALITY_DESCRIPTION E1.20 + public byte PersonalityID { get; private set; } + public uint SoftwareVersionID { get; private set; } - //Id given from PID DMX_PERSONALITY_ID E1.37-5 - 2024 - public ushort? MajorPersonalityID { get; private set; } - public ushort? MinorPersonalityID { get; private set; } + //Id given from PID DMX_PERSONALITY_ID E1.37-5 - 2024 + public ushort? MajorPersonalityID { get; private set; } + public ushort? MinorPersonalityID { get; private set; } - private SubDevice subDevice; - public SubDevice SubDevice + private SubDevice subDevice; + public SubDevice SubDevice + { + get { - get - { - return subDevice; - } - private set - { - if (subDevice == value) - return; - subDevice = value; - PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(SubDevice))); - } + return subDevice; } + private set + { + if (subDevice == value) + return; + subDevice = value; + PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(SubDevice))); + } + } + + private readonly RemotePersonality personality; + public IPersonality Personality + { + get { return personality; } + } - private ConcurrentDictionary slots = new ConcurrentDictionary(); - public IReadOnlyDictionary Slots => slots.AsReadOnly(); - public readonly IReadOnlyCollection SupportedPersonalityBlueprintParameters; + public IReadOnlyDictionary Slots => Personality.Slots; + public readonly IReadOnlyCollection SupportedPersonalityBlueprintParameters; - private UID currentUsedUid; + private UID currentUsedUid; - public string Description { get; private set; } - public ushort SlotCount { get; private set; } + public string Description { get; private set; } + public ushort SlotCount { get; private set; } - internal RDMPersonalityModel(IRDMRemoteDevice remoteRDMDevice, byte personalityId) + internal RDMPersonalityModel(IRDMRemoteDevice remoteRDMDevice, byte personalityId) + { + currentUsedUid = remoteRDMDevice.UID; + SubDevice = remoteRDMDevice.Subdevice; + ManufacturerID = remoteRDMDevice.UID.ManufacturerID; + Manufacturer = (EManufacturer)ManufacturerID; + DeviceModelID = remoteRDMDevice.DeviceInfo.DeviceModelId; + SoftwareVersionID = remoteRDMDevice.DeviceInfo.SoftwareVersionId; + PersonalityID = personalityId; + this.ParameterValueAdded += RDMDeviceModel_ParameterValueAdded; + if (remoteRDMDevice is AbstractRemoteRDMDevice rd) { - currentUsedUid = remoteRDMDevice.UID; - SubDevice = remoteRDMDevice.Subdevice; - ManufacturerID = remoteRDMDevice.UID.ManufacturerID; - Manufacturer = (EManufacturer)ManufacturerID; - DeviceModelID = remoteRDMDevice.DeviceInfo.DeviceModelId; - SoftwareVersionID = remoteRDMDevice.DeviceInfo.SoftwareVersionId; - PersonalityID = personalityId; - this.ParameterValueAdded += RDMDeviceModel_ParameterValueAdded; - if (remoteRDMDevice is AbstractRemoteRDMDevice rd) + SupportedPersonalityBlueprintParameters = rd.DeviceModel.GetSupportedBlueprintModelPersonalityParameters().Select(spm => spm.Parameter).ToList(); + if (remoteRDMDevice.ParameterValues.TryGetValue(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, out object obj) && obj is ConcurrentDictionary dict) { - SupportedPersonalityBlueprintParameters = rd.DeviceModel.SupportedPersonalityBlueprintParameters; - if (remoteRDMDevice.ParameterValues.TryGetValue(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, out object obj) && obj is ConcurrentDictionary dict) + if (dict.TryGetValue(personalityId, out object disc) && disc is RDMDMXPersonalityDescription personalityDescription) { - if (dict.TryGetValue(personalityId, out object disc) && disc is RDMDMXPersonalityDescription personalityDescription) - { - this.Description = personalityDescription.Description; - SlotCount = personalityDescription.Slots; - var rpl=DataTreeBranch.FromObject(personalityDescription, null, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION); - updateParameterValuesDependeciePropertyBag(ERDM_Parameter.SLOT_DESCRIPTION, rpl); - } + this.Description = personalityDescription.Description; + this.SlotCount = personalityDescription.Slots; + this.personality = new RemotePersonality(personalityId, this.Description, SlotCount); + var rpl = DataTreeBranch.FromObject(personalityDescription, null, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION); + updateParameterValuesDependeciePropertyBag(ERDM_Parameter.SLOT_DESCRIPTION, rpl); } } } - private SemaphoreSlim initializeSemaphoreSlim = new SemaphoreSlim(1); - internal async Task Initialize() + } + private SemaphoreSlim initializeSemaphoreSlim = new SemaphoreSlim(1); + internal async Task Initialize() + { + if (IsInitialized) + return; + if (initializeSemaphoreSlim.CurrentCount == 0) + return; + IsInitializing = true; + + await initializeSemaphoreSlim.WaitAsync(); + try { - if (IsInitialized) - return; - if (initializeSemaphoreSlim.CurrentCount == 0) - return; - IsInitializing = true; - - await initializeSemaphoreSlim.WaitAsync(); - try - { - await requestPersonalityBlueprintParameters(); + await requestPersonalityBlueprintParameters(); - IsInitialized = true; - } - finally - { - initializeSemaphoreSlim.Release(); - IsInitializing = false; - } - Initialized?.Invoke(this, EventArgs.Empty); + IsInitialized = true; } + finally + { + initializeSemaphoreSlim.Release(); + IsInitializing = false; + } + Initialized?.Invoke(this, EventArgs.Empty); + } - internal async Task requestPersonalityBlueprintParameters() + internal async Task requestPersonalityBlueprintParameters() + { + try { - try + foreach (ERDM_Parameter parameter in this.SupportedPersonalityBlueprintParameters) { - foreach (ERDM_Parameter parameter in this.SupportedPersonalityBlueprintParameters) + tryAddParameterMetadata(parameter); + ParameterBag parameterBag = new ParameterBag(parameter, this.ManufacturerID, this.DeviceModelID, this.SoftwareVersionID); + var define = MetadataFactory.GetDefine(parameterBag); + if (define.GetRequest.HasValue) { - ParameterBag parameterBag = new ParameterBag(parameter, this.ManufacturerID, this.DeviceModelID, this.SoftwareVersionID); - var define = MetadataFactory.GetDefine(parameterBag); - if (define.GetRequest.HasValue) - { - if (define.GetRequest.Value.GetIsEmpty()) - await requestGetParameterWithEmptyPayload(parameterBag, define, currentUsedUid, SubDevice); - else - await requestGetParameterWithPayload(parameterBag, define, currentUsedUid, SubDevice); - } - await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenRequests); + if (define.GetRequest.Value.GetIsEmpty()) + await requestGetParameterWithEmptyPayload(parameterBag, define, currentUsedUid, SubDevice); + else + await requestGetParameterWithPayload(parameterBag, define, currentUsedUid, SubDevice); } - } - catch (Exception ex) - { - Logger?.LogError(ex); + await Task.Delay(GlobalTimers.Instance.UpdateDelayBetweenRequests); } } - internal void RDMDeviceModel_ParameterValueAdded(object sender, ParameterValueAddedEventArgs e) + catch (Exception ex) + { + Logger?.LogError(ex); + } + } + internal void RDMDeviceModel_ParameterValueAdded(object sender, ParameterValueAddedEventArgs e) + { + if (!Constants.BLUEPRINT_MODEL_PERSONALITY_PARAMETERS.Contains(e.Parameter)) + return; + + //var cache = sender as AbstractRDMCache; + //var bag = new ParameterDataCacheBag(e.Parameter, e.Index); + //cache.parameterValuesDataTreeBranch.TryGetValue(bag, out var value); + //updateParameterValuesDataTreeBranch(bag, value); + try { - if (!Constants.BLUEPRINT_MODEL_PERSONALITY_PARAMETERS.Contains(e.Parameter)) - return; - - //var cache = sender as AbstractRDMCache; - //var bag = new ParameterDataCacheBag(e.Parameter, e.Index); - //cache.parameterValuesDataTreeBranch.TryGetValue(bag, out var value); - //updateParameterValuesDataTreeBranch(bag, value); - if (e.Value is RDMSlotInfo[] slotInfos) { foreach (var slotInfo in slotInfos) - getOrCreate(slotInfo.SlotOffset).UpdateSlotInfo(slotInfo); + personality.getOrCreate(slotInfo.SlotOffset).UpdateSlotInfo(slotInfo); return; } if (e.Value is RDMDefaultSlotValue[] defaultSlotValues) { foreach (var defaultSlotValue in defaultSlotValues) - getOrCreate(defaultSlotValue.SlotOffset).UpdateSlotDefaultValue(defaultSlotValue); + personality.getOrCreate(defaultSlotValue.SlotOffset).UpdateSlotDefaultValue(defaultSlotValue); + + personality.AllDataPulled = true; return; } if (e.Value is RDMSlotDescription slotDescription) { - var slot = getOrCreate(Convert.ToUInt16(e.Index)); + var slot = personality.getOrCreate(Convert.ToUInt16(e.Index)); if (slot.SlotId == slotDescription.SlotId) slot.UpdateSlotDescription(slotDescription); - } - Slot getOrCreate(ushort id) - { - if (!slots.TryGetValue(id, out Slot slot1)) - { - slot1 = new Slot(id); - if (slots.TryAdd(id, slot1)) - SlotAdded?.InvokeFailSafe(this, slot1); - } - return slot1; + if (SlotCount == slot.SlotId + 1) + if (!SupportedPersonalityBlueprintParameters.Contains(ERDM_Parameter.DEFAULT_SLOT_VALUE)) + personality.AllDataPulled = true; } } - - public bool IsModelOf(UID uid, ushort deviceModelID, uint softwareVersionID, byte personalityID) - { - if (this.ManufacturerID != uid.ManufacturerID) - return false; - if (this.DeviceModelID != deviceModelID) - return false; - if (this.SoftwareVersionID != softwareVersionID) - return false; - if (this.PersonalityID != personalityID) - return false; - - return true; - } - public bool IsModelOf(UID uid, ushort majorPersonalityID, ushort minorPersonalityID) + finally { - if (this.ManufacturerID != uid.ManufacturerID) - return false; - if (this.MajorPersonalityID != majorPersonalityID) - return false; - if (this.MinorPersonalityID != minorPersonalityID) - return false; - - return true; + if (this.personality.AllDataPulled) + this.ParameterValueAdded -= RDMDeviceModel_ParameterValueAdded; } + } - public override string ToString() - { - return $"[{PersonalityID}] {Enum.GetName(typeof(EManufacturer), Manufacturer)}"; - } + public bool IsModelOf(UID uid, ushort deviceModelID, uint softwareVersionID, byte personalityID) + { + if (this.ManufacturerID != uid.ManufacturerID) + return false; + if (this.DeviceModelID != deviceModelID) + return false; + if (this.SoftwareVersionID != softwareVersionID) + return false; + if (this.PersonalityID != personalityID) + return false; + + return true; + } + public bool IsModelOf(UID uid, ushort majorPersonalityID, ushort minorPersonalityID) + { + if (this.ManufacturerID != uid.ManufacturerID) + return false; + if (this.MajorPersonalityID != majorPersonalityID) + return false; + if (this.MinorPersonalityID != minorPersonalityID) + return false; + + return true; + } + + public override string ToString() + { + return $"[{PersonalityID}] {Enum.GetName(typeof(EManufacturer), Manufacturer)}"; } } \ No newline at end of file diff --git a/RDMSharp/RDM/Device/RemotePersonality.cs b/RDMSharp/RDM/Device/RemotePersonality.cs new file mode 100644 index 00000000..f2f90e0b --- /dev/null +++ b/RDMSharp/RDM/Device/RemotePersonality.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.ComponentModel; + +namespace RDMSharp; + +public class RemotePersonality : IPersonality, INotifyPropertyChanged +{ + private readonly byte id; + public byte ID => id; + + private readonly ushort slotCount; + public ushort SlotCount => slotCount; + + private readonly string description; + public string Description => description; + + private readonly ConcurrentDictionary slots = new ConcurrentDictionary(); + + public event PropertyChangedEventHandler PropertyChanged; + public event EventHandler SlotAdded; + + public IReadOnlyDictionary Slots => slots.AsReadOnly(); + + private bool allDataPulled = false; + public bool AllDataPulled + { + get + { + return allDataPulled; + } + internal set + { + if (allDataPulled != value) + allDataPulled = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(AllDataPulled))); + } + } + + public RemotePersonality(byte _id, string _description, ushort _slotCount) + { + this.id = _id; + this.description = _description; + this.slotCount = _slotCount; + } + internal Slot getOrCreate(ushort slotId) + { + if (!slots.TryGetValue(slotId, out Slot slot1)) + { + slot1 = new Slot(slotId); + if (slots.TryAdd(slotId, slot1)) + SlotAdded?.InvokeFailSafe(this, slot1); + } + return slot1; + } + + public override string ToString() + { + return $"[{ID}] ({SlotCount}) {Description}"; + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Device/SupportedParameterMetadata.cs b/RDMSharp/RDM/Device/SupportedParameterMetadata.cs new file mode 100644 index 00000000..0ce3ea05 --- /dev/null +++ b/RDMSharp/RDM/Device/SupportedParameterMetadata.cs @@ -0,0 +1,177 @@ +using System.Collections.Concurrent; +using System.ComponentModel; + +namespace RDMSharp.RDM.Device; + +public class SupportedParameterMetadata : INotifyPropertyChanged +{ + public readonly ERDM_Parameter Parameter; + public readonly bool IsNonBlueprint; + public readonly bool IsBlueprintModel; + public readonly bool IsBlueprintModelPersonality; + + public readonly bool IsManufacturerInternal; + + public event PropertyChangedEventHandler PropertyChanged; + + private bool _isSupported = true; + public bool IsSupported + { + get + { + return _isSupported; + } + private set + { + if (_isSupported == value) + return; + _isSupported = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSupported))); + } + } + private ERDM_CommandClass _unsupportedCommandClasses = ERDM_CommandClass.NONE; + public ERDM_CommandClass UnsupportedCommandClasses + { + get + { + return _unsupportedCommandClasses; + } + private set + { + if (_unsupportedCommandClasses == value) + return; + _unsupportedCommandClasses = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(UnsupportedCommandClasses))); + } + } + + public bool IsManufacturerSpecific + { + get + { + return ((int)Parameter & 0x8000) != 0; + } + } + + private object _parameterDescription = null; + public object ParameterDescription + { + get + { + return _parameterDescription; + } + private set + { + if (_parameterDescription is not null) + return; + _parameterDescription = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ParameterDescription))); + } + } + + private string _name = null; + public string Name + { + get + { + return _name; + } + private set + { + if (_name is not null) + return; + _name = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name))); + } + } + + private int? _parameterUpdateTimeMilliseconds = null; + public int ParameterUpdateTimeMilliseconds + { + get + { + return _parameterUpdateTimeMilliseconds ?? -1; + } + internal set + { + if (_parameterUpdateTimeMilliseconds.HasValue) + return; + _parameterUpdateTimeMilliseconds = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ParameterUpdateTimeMilliseconds))); + } + } + + private ConcurrentDictionary NackReasons = new(); + + private SupportedParameterMetadata( + in ERDM_Parameter parameter, + in bool blueprintModel = false, + in bool blueprintModelPersonality = false, + in bool manufacturerInternal = false) + { + Parameter = parameter; + IsBlueprintModel = blueprintModel; + IsBlueprintModelPersonality = blueprintModelPersonality; + IsNonBlueprint = !blueprintModel && !blueprintModelPersonality; + IsManufacturerInternal = manufacturerInternal; + } + + public static SupportedParameterMetadata Create( + in ERDM_Parameter parameter, + in bool manufacturerInternal = false) + { + return new SupportedParameterMetadata(parameter, manufacturerInternal: manufacturerInternal); + } + public static SupportedParameterMetadata CreateBlueprintModel( + in ERDM_Parameter parameter, + in bool manufacturerInternal = false) + { + return new SupportedParameterMetadata(parameter, blueprintModel: true, manufacturerInternal: manufacturerInternal); + } + public static SupportedParameterMetadata CreateBlueprintModelPersonality( + in ERDM_Parameter parameter, + in bool manufacturerInternal = false) + { + return new SupportedParameterMetadata(parameter, blueprintModelPersonality: true, manufacturerInternal: manufacturerInternal); + } + + internal void HandleNack(RDMMessage message) + { + if (message.NackReason.HasValue) + { + NackReasons.TryAdd(NackReasons.Count, message.NackReason.Value); + switch (message.NackReason.Value) + { + case ERDM_NackReason.UNKNOWN_PID: + this.IsSupported = false; + break; + case ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS: + if (message.Command == ERDM_Command.GET_COMMAND_RESPONSE) + this.UnsupportedCommandClasses |= ERDM_CommandClass.GET; + if (message.Command == ERDM_Command.SET_COMMAND_RESPONSE) + this.UnsupportedCommandClasses |= ERDM_CommandClass.SET; + break; + } + } + } + + internal void SetParameterDescription(object parameterDescription) + { + ParameterDescription = parameterDescription; + } + + internal void SetName(string name) + { + Name = name; + } + + internal void SetParameterUpdateTime(int milliseconds) + { + ParameterUpdateTimeMilliseconds = milliseconds; + } + + public sealed override string ToString() + { + return $"Parameter: {Parameter}, IsSupported: {IsSupported}, IsBlueprintModel: {IsBlueprintModel}, IsBlueprintModelPersonality: {IsBlueprintModelPersonality}, IsNonBlueprint: {IsNonBlueprint}, IsManufacturerInternal: {IsManufacturerInternal}"; + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs b/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs index 14995da7..4c3cb972 100644 --- a/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs +++ b/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Logging; +using RDMSharp.PayloadObject; using System; using System.Collections.Generic; using System.ComponentModel; @@ -6,218 +7,217 @@ using System.Threading; using System.Threading.Tasks; -namespace RDMSharp +namespace RDMSharp; + +public abstract class AbstractDiscoveryTool : INotifyPropertyChanged, IDisposable { - public abstract class AbstractDiscoveryTool : INotifyPropertyChanged, IDisposable - { - private protected static ILogger Logger = Logging.CreateLogger(); - private readonly CancellationTokenSource cts = new CancellationTokenSource(); - public event PropertyChangedEventHandler PropertyChanged; - public bool discoveryInProgress; - public bool DiscoveryInProgress + private protected static ILogger Logger = Logging.CreateLogger(); + private readonly CancellationTokenSource cts = new CancellationTokenSource(); + public event PropertyChangedEventHandler PropertyChanged; + public bool discoveryInProgress; + public bool DiscoveryInProgress + { + get => discoveryInProgress; + private set { - get => discoveryInProgress; - private set - { - if (discoveryInProgress == value) - return; - discoveryInProgress = value; - PropertyChanged?.InvokeFailSafe(nameof(DiscoveryInProgress)); - } - } + if (discoveryInProgress == value) + return; + discoveryInProgress = value; + PropertyChanged?.InvokeFailSafe(nameof(DiscoveryInProgress)); + } + } - public AbstractDiscoveryTool() - { - } + public AbstractDiscoveryTool() + { + } - public async Task> PerformDiscovery(IProgress progress = null, bool full = true) - { - if (DiscoveryInProgress) return new List(); - DiscoveryInProgress = true; + public async Task> PerformDiscovery(IProgress progress = null, bool full = true) + { + if (DiscoveryInProgress) return new List(); + DiscoveryInProgress = true; - //Send DISC_UN_MUTE - if (full) + //Send DISC_UN_MUTE + if (full) + { + bool unmuted = false; + for (int t_ry = 0; t_ry < 10 && !unmuted; t_ry++) { - bool unmuted = false; - for (int t_ry = 0; t_ry < 10 && !unmuted; t_ry++) - { - RDMMessage m = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - Parameter = ERDM_Parameter.DISC_UN_MUTE, - DestUID = UID.Broadcast, - }; - await RDMSharp.Instance.SendMessage(m).WaitAsync(cts.Token); - unmuted = true; - } - if (!unmuted) + RDMMessage m = new RDMMessage() { - Logger?.LogError("Unable do send DISC_UNMUTE Command."); - return null; - } - } - //Start Binary Search for each - var erg = new RDMDiscoveryContext(progress); - await DiscoverDevicesBinarySearch(UID.Empty, UID.Broadcast - 1, erg).WaitAsync(cts.Token); + Command = ERDM_Command.DISCOVERY_COMMAND, + Parameter = ERDM_Parameter.DISC_UN_MUTE, + DestUID = UID.Broadcast, + }; + await RDMSharp.Instance.SendMessage(m).WaitAsync(cts.Token); + unmuted = true; + } + if (!unmuted) + { + Logger?.LogError("Unable do send DISC_UNMUTE Command."); + return null; + } + } + //Start Binary Search for each + var erg = new RDMDiscoveryContext(progress); + await DiscoverDevicesBinarySearch(UID.Empty, UID.Broadcast - 1, erg).WaitAsync(cts.Token); - DiscoveryInProgress = false; - return erg.FoundUIDs.ToList(); - } + DiscoveryInProgress = false; + return erg.FoundUIDs.ToList(); + } - private async Task DiscoverDevicesBinarySearch(UID uidStart, UID uidEnd, RDMDiscoveryContext context) + private async Task DiscoverDevicesBinarySearch(UID uidStart, UID uidEnd, RDMDiscoveryContext context) + { + //Robust Code Check + if (uidStart > uidEnd) return; + if (uidStart == uidEnd) { - //Robust Code Check - if (uidStart > uidEnd) return; - if (uidStart == uidEnd) - { - await TryMuteSingleDeviceAndAdd(uidStart, context); - context.RemoveRange(uidStart, uidEnd); - return; - } + await TryMuteSingleDeviceAndAdd(uidStart, context); + context.RemoveRange(uidStart, uidEnd); + return; + } - string msg = String.Format("Doing Discovery for Range {0} - {1}", uidStart, uidEnd); - Logger?.LogDebug(msg); - context.StatusString = msg; + string msg = String.Format("Doing Discovery for Range {0} - {1}", uidStart, uidEnd); + Logger?.LogDebug(msg); + context.StatusString = msg; - bool success = false; - RDMMessage response = null; - for (int t_ry = 0; t_ry < 3 && !success; t_ry++) + bool success = false; + RDMMessage response = null; + for (int t_ry = 0; t_ry < 3 && !success; t_ry++) + { + RDMMessage m = new RDMMessage() { - RDMMessage m = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH, - DestUID = UID.Broadcast, - SubDevice = SubDevice.Root, - ParameterData = new DiscUniqueBranchRequest(uidStart, uidEnd).ToPayloadData() - }; - context.IncreaseMessageCounter(); - var res = await RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(m); - if (res.Success) - { - success = res.Success; - response = res.Response; - } + Command = ERDM_Command.DISCOVERY_COMMAND, + Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH, + DestUID = UID.Broadcast, + SubDevice = SubDevice.Root, + ParameterData = new DiscUniqueBranchRequest(uidStart, uidEnd).ToPayloadData() + }; + context.IncreaseMessageCounter(); + var res = await RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(m); + if (res.Success) + { + success = res.Success; + response = res.Response; } + } - if (response == null) //Timeout, Error, No Device Responded, whatever it is, we are done - { - context.RemoveRange(uidStart, uidEnd); - return; + if (response == null) //Timeout, Error, No Device Responded, whatever it is, we are done + { + context.RemoveRange(uidStart, uidEnd); + return; + } + if (response != null && response?.ChecksumValid == true) //Great, just 1 Device responded + { + if (context.IsFalseOn(response.SourceUID) && !uidStart.Equals(response.SourceUID) && !uidEnd.Equals(response.SourceUID)) + { + // do Nothing } - if (response != null && response?.ChecksumValid == true) //Great, just 1 Device responded + else if (response.Parameter == ERDM_Parameter.DISC_UNIQUE_BRANCH && response.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE) { - if (context.IsFalseOn(response.SourceUID) && !uidStart.Equals(response.SourceUID) && !uidEnd.Equals(response.SourceUID)) - { - // do Nothing + var muted = await TryMuteSingleDeviceAndAdd(response.SourceUID, context); + if (muted == true) + { + //According to Spec, check same Branch again. + await DiscoverDevicesBinarySearch(uidStart, uidEnd, context); + return; } - else if (response.Parameter == ERDM_Parameter.DISC_UNIQUE_BRANCH && response.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE) + else if (muted == null) //An already muted Device answered again! We try to fix by carving out the UID { - var muted = await TryMuteSingleDeviceAndAdd(response.SourceUID, context); - if (muted == true) - { - //According to Spec, check same Branch again. - await DiscoverDevicesBinarySearch(uidStart, uidEnd, context); - return; - } - else if (muted == null) //An already muted Device answered again! We try to fix by carving out the UID + //Split Range at number of Device + UID shittyDevice = response.SourceUID; + if (shittyDevice == uidStart) await DiscoverDevicesBinarySearch(uidStart + 1, uidEnd, context); + else if (shittyDevice == uidEnd) await DiscoverDevicesBinarySearch(uidStart, uidEnd - 1, context); + else if (shittyDevice > uidStart && shittyDevice < uidEnd) { - //Split Range at number of Device - UID shittyDevice = response.SourceUID; - if (shittyDevice == uidStart) await DiscoverDevicesBinarySearch(uidStart + 1, uidEnd, context); - else if (shittyDevice == uidEnd) await DiscoverDevicesBinarySearch(uidStart, uidEnd - 1, context); - else if (shittyDevice > uidStart && shittyDevice < uidEnd) - { - await DiscoverDevicesBinarySearch(uidStart, shittyDevice - 1, context); - await DiscoverDevicesBinarySearch(shittyDevice + 1, uidEnd, context); - } - else - Logger?.LogWarning($"Device {response.SourceUID} answered outside of its UID Range!!! Go, throw it into the trash."); - - return; + await DiscoverDevicesBinarySearch(uidStart, shittyDevice - 1, context); + await DiscoverDevicesBinarySearch(shittyDevice + 1, uidEnd, context); } else - context.AddFalseOn(response.SourceUID); + Logger?.LogWarning($"Device {response.SourceUID} answered outside of its UID Range!!! Go, throw it into the trash."); + + return; } else - Logger?.LogWarning($"Strange Discovery Answer received {response}"); + context.AddFalseOn(response.SourceUID); } + else + Logger?.LogWarning($"Strange Discovery Answer received {response}"); + } - //Conflict Result, continue Binary search - var delta = uidEnd - uidStart; - var mid = delta / 2; - await DiscoverDevicesBinarySearch(uidStart, uidStart + mid, context); - await DiscoverDevicesBinarySearch(uidStart + mid + 1, uidEnd, context); + //Conflict Result, continue Binary search + var delta = uidEnd - uidStart; + var mid = delta / 2; + await DiscoverDevicesBinarySearch(uidStart, uidStart + mid, context); + await DiscoverDevicesBinarySearch(uidStart + mid + 1, uidEnd, context); - //To detect off by one errors in Devices, we do the same discovery, split the Range in 3 Ranges - //Only if there are at least 3 Devices to discover left (delta = 2) + //To detect off by one errors in Devices, we do the same discovery, split the Range in 3 Ranges + //Only if there are at least 3 Devices to discover left (delta = 2) - if ((ulong)delta >= 2) - { - var mid3 = delta / 3; - var offByOneContext = new RDMDiscoveryContext(); + if ((ulong)delta >= 2) + { + var mid3 = delta / 3; + var offByOneContext = new RDMDiscoveryContext(); - //AL 2020-12-08: Not sure whether usefull - //msg = String.Format("Doing OffByOne Check for Range {0} - {1}", UID.FromULong(uidStart), UID.FromULong(uidEnd)); - //context.Status = msg; + //AL 2020-12-08: Not sure whether usefull + //msg = String.Format("Doing OffByOne Check for Range {0} - {1}", UID.FromULong(uidStart), UID.FromULong(uidEnd)); + //context.Status = msg; - await DiscoverDevicesBinarySearch(uidStart, uidStart + mid3, offByOneContext); - await DiscoverDevicesBinarySearch(uidStart + mid3 + 1, uidStart + mid3 + 1 + mid3, offByOneContext); - await DiscoverDevicesBinarySearch(uidStart + mid3 + 1 + mid3 + 1, uidEnd, offByOneContext); + await DiscoverDevicesBinarySearch(uidStart, uidStart + mid3, offByOneContext); + await DiscoverDevicesBinarySearch(uidStart + mid3 + 1, uidStart + mid3 + 1 + mid3, offByOneContext); + await DiscoverDevicesBinarySearch(uidStart + mid3 + 1 + mid3 + 1, uidEnd, offByOneContext); - if (offByOneContext.FoundCount > 0) //Something was added! - { - var found = offByOneContext.FoundUIDs; - context.AddFound(found); + if (offByOneContext.FoundCount > 0) //Something was added! + { + var found = offByOneContext.FoundUIDs; + context.AddFound(found); - //Find the Bad Devices - Logger?.LogWarning($"You are lucky to use RDMSharp! Some Devices don't have a proper RDM implementation as they sem to have an off by one error, but we handled that for you: [{String.Join(",", found)}]"); - } + //Find the Bad Devices + Logger?.LogWarning($"You are lucky to use RDMSharp! Some Devices don't have a proper RDM implementation as they sem to have an off by one error, but we handled that for you: [{String.Join(",", found)}]"); } } + } - private async Task TryMuteSingleDeviceAndAdd(UID uid, RDMDiscoveryContext context) + private async Task TryMuteSingleDeviceAndAdd(UID uid, RDMDiscoveryContext context) + { + if (context.AlreadyFound(uid)) { - if (context.AlreadyFound(uid)) - { - Logger?.LogWarning($"Faulty device {uid} did not mute properly as it responded again although it was muted!"); - return null; - } + Logger?.LogWarning($"Faulty device {uid} did not mute properly as it responded again although it was muted!"); + return null; + } - //Mute Device (10 tries) - bool muted = false; - for (int t_ry = 0; t_ry < 10 && !muted; t_ry++) + //Mute Device (10 tries) + bool muted = false; + for (int t_ry = 0; t_ry < 10 && !muted; t_ry++) + { + RDMMessage muteResponse = null; + RDMMessage n = new RDMMessage() { - RDMMessage muteResponse = null; - RDMMessage n = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - Parameter = ERDM_Parameter.DISC_MUTE, - DestUID = uid - }; - var res = await RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(n); - if (res.Success) - { - muted = res.Success; - muteResponse = res.Response; - } - muted &= muteResponse != null && muteResponse.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE - && muteResponse.Parameter == ERDM_Parameter.DISC_MUTE - && muteResponse.SourceUID == uid; + Command = ERDM_Command.DISCOVERY_COMMAND, + Parameter = ERDM_Parameter.DISC_MUTE, + DestUID = uid + }; + var res = await RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(n); + if (res.Success) + { + muted = res.Success; + muteResponse = res.Response; } - if (muted) - context.AddFound(uid); - else - Logger?.LogWarning($"Unable to Mute Device {uid}. Not added to List of discovered Items. Hopefully discovery works anyway."); + muted &= muteResponse != null && muteResponse.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE + && muteResponse.Parameter == ERDM_Parameter.DISC_MUTE + && muteResponse.SourceUID == uid; + } + if (muted) + context.AddFound(uid); + else + Logger?.LogWarning($"Unable to Mute Device {uid}. Not added to List of discovered Items. Hopefully discovery works anyway."); - return muted; - } + return muted; + } - public void Dispose() - { - cts.Cancel(); - cts.Dispose(); - } - } + public void Dispose() + { + cts.Cancel(); + cts.Dispose(); + } } diff --git a/RDMSharp/RDM/Endpoint.cs b/RDMSharp/RDM/Endpoint.cs new file mode 100644 index 00000000..5bacfdb5 --- /dev/null +++ b/RDMSharp/RDM/Endpoint.cs @@ -0,0 +1,254 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using System.Text; + +[assembly: InternalsVisibleTo("RDMSharpTests")] +namespace RDMSharp; + +public class Endpoint : INotifyPropertyChanged, IEquatable +{ + public event PropertyChangedEventHandler PropertyChanged; + + public readonly ushort EndpointId; + public readonly ERDM_EndpointType Type; + + private string lable; + public string Lable + { + get { return lable; } + set + { + if (lable == value) + return; + + lable = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Lable))); + } + } + + private bool identify; + public bool Identify + { + get { return identify; } + set + { + if (identify == value) + return; + identify = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Identify))); + } + } + + private ushort universe; + public ushort Universe + { + get { return universe; } + set + { + if (universe == value) + return; + universe = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Universe))); + } + } + + private ERDM_EndpointMode mode; + public ERDM_EndpointMode Mode + { + get { return mode; } + set + { + if (mode == value) + return; + mode = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Mode))); + } + } + + private bool rdmTraffic; + public bool RDMTraffic + { + get { return rdmTraffic; } + set + { + if (rdmTraffic == value) + return; + rdmTraffic = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(RDMTraffic))); + } + } + + private ERDM_DiscoveryState discoveryState; + public ERDM_DiscoveryState DiscoveryState + { + get { return discoveryState; } + set + { + if (discoveryState == value) + return; + discoveryState = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(DiscoveryState))); + } + } + + private ushort discoveryStateCount; + public ushort DiscoveryStateCount + { + get { return discoveryStateCount; } + set + { + if (discoveryStateCount == value) + return; + discoveryStateCount = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(DiscoveryStateCount))); + } + } + + private bool backgroundDiscovery; + public bool BackgroundDiscovery + { + get { return backgroundDiscovery; } + set + { + if (backgroundDiscovery == value) + return; + backgroundDiscovery = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(BackgroundDiscovery))); + } + } + + private byte timing; + public byte Timing + { + get { return timing; } + set + { + if (timing == value) + return; + timing = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Timing))); + } + } + + private HashSet responders = new HashSet(); + public IReadOnlyCollection Responders + { + get { return responders; } + } + protected void AddResponder(UID responder) + { + if (responders.Contains(responder)) + return; + responders.Add(responder); + ResponderListChanged++; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Responders))); + } + protected void RemoveResponder(UID responder) + { + if (!responders.Contains(responder)) + return; + responders.Remove(responder); + ResponderListChanged++; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Responders))); + } + protected void SetBindingControlField(UID uid, ushort controlField, UID bindingUid) + { + bindingControlFields.AddOrUpdate(uid, new BindingControlField(uid, controlField, bindingUid), (k, v) => new BindingControlField(uid, controlField, bindingUid)); + } + protected void RemoveBindingControlField(UID uid) + { + bindingControlFields.TryRemove(uid, out _); + } + + private uint responderListChanged; + public uint ResponderListChanged + { + get { return responderListChanged; } + private set + { + if (responderListChanged == value) + return; + responderListChanged = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(ResponderListChanged))); + } + } + + private ConcurrentDictionary bindingControlFields = new ConcurrentDictionary(); + + public IReadOnlyDictionary BindingControlFields + { + get { return bindingControlFields; } + } + + public Endpoint(in ushort endpointId, in ERDM_EndpointType type) + { + this.EndpointId = endpointId; + this.Type = type; + } + internal protected Endpoint(in ushort endpointId, + in ERDM_EndpointType type, + in string lable) : this(endpointId, type) + { + Lable = lable; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"Endpoint: {this.EndpointId}"); + sb.AppendLine($"Lable: {this.Lable}"); + //sb.AppendLine($"CurrentIP: {this.CurrentIP}/{this.CurrentSubnetMask}"); + //sb.AppendLine($"MACAddress: {this.MACAddress}"); + //sb.AppendLine($"DHCP: {this.DHCP}"); + //sb.AppendLine($"ZeroConf: {this.ZeroConf}"); + + return sb.ToString(); + } + + public override bool Equals(object obj) + { + return Equals(obj as Sensor); + } + + public bool Equals(Endpoint other) + { + return other is not null && + EndpointId == other.EndpointId && + Lable == other.Lable && + Identify == other.Identify; + } + + public override int GetHashCode() + { +#if !NETSTANDARD + HashCode hash = new HashCode(); + hash.Add(EndpointId); + hash.Add(Lable); + hash.Add(Identify); + return hash.ToHashCode(); +#else + int hashCode = 1916557116; + hashCode = hashCode * -1521134295 + EndpointId.GetHashCode(); + hashCode = hashCode * -1521134295 + Lable.GetHashCode(); + hashCode = hashCode * -1521134295 + Identify.GetHashCode(); + return hashCode; +#endif + } + + public readonly struct BindingControlField + { + public readonly UID Uid; + public readonly ushort ControlField; + public readonly UID BindingUid; + + public BindingControlField(in UID uid, in ushort controlField, in UID bindingUid) + { + this.Uid = uid; + this.ControlField = controlField; + this.BindingUid = bindingUid; + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Enum/EARP_HardwareTypes.cs b/RDMSharp/RDM/Enum/EARP_HardwareTypes.cs new file mode 100644 index 00000000..908d4157 --- /dev/null +++ b/RDMSharp/RDM/Enum/EARP_HardwareTypes.cs @@ -0,0 +1,131 @@ +namespace RDMSharp +{ + public enum EARP_HardwareTypes : ushort + { + /// Reserved (RFC5494) + Reserved = 0, + + /// Ethernet (10Mb) [Jon Postel] + Ethernet = 1, + + /// Experimental Ethernet (3Mb) [Jon Postel] + ExperimentalEthernet = 2, + + /// Amateur Radio AX.25 [Philip Koch] + AmateurRadioAX25 = 3, + + /// Proteon ProNET Token Ring [Avri Doria] + ProteonProNetTokenRing = 4, + + /// Chaos [Gill Pratt] + Chaos = 5, + + /// IEEE 802 Networks [Jon Postel] + IEEE802 = 6, + + /// ARCNET (RFC1201) + Arcnet = 7, + + /// Hyperchannel [Jon Postel] + Hyperchannel = 8, + + /// Lanstar [Tom Unger] + Lanstar = 9, + + /// Autonet Short Address [Mike Burrows] + AutonetShortAddress = 10, + + /// LocalTalk [Joyce K. Reynolds] + LocalTalk = 11, + + /// LocalNet (IBM PCNet or SYTEK LocalNET) [Joseph Murdock] + LocalNet = 12, + + /// Ultra link [Rajiv Dhingra] + UltraLink = 13, + + /// SMDS [George Clapp] + SMDS = 14, + + /// Frame Relay [Andy Malis] + FrameRelay = 15, + + /// Asynchronous Transmission Mode (ATM) [JXB2] + ATM1 = 16, + + /// HDLC [Jon Postel] + HDLC = 17, + + /// Fibre Channel (RFC4338) + FibreChannel = 18, + + /// Asynchronous Transmission Mode (ATM) (RFC2225) + ATM2 = 19, + + /// Serial Line [Jon Postel] + SerialLine = 20, + + /// Asynchronous Transmission Mode (ATM) [Mike Burrows] + ATM3 = 21, + + /// MIL-STD-188-220 [Herb Jensen] + MILSTD188220 = 22, + + /// Metricom [Jonathan Stone] + Metricom = 23, + + /// IEEE 1394.1995 [Myron Hattig] + IEEE1394 = 24, + + /// MAPOS [Mitsuru Maruyama] (RFC2176) + MAPOS = 25, + + /// Twinaxial [Marion Pitts] + Twinaxial = 26, + + /// EUI-64 [Kenji Fujisawa] + EUI64 = 27, + + /// HIPARP [Jean Michel Pittet] + HIPARP = 28, + + /// IP and ARP over ISO 7816-3 [Scott Guthery] + IPoverISO78163 = 29, + + /// ARPSec [Jerome Etienne] + ARPSec = 30, + + /// IPsec tunnel (RFC3456) + IPsecTunnel = 31, + + /// InfiniBand (RFC4391) + InfiniBand = 32, + + /// TIA-102 Project 25 Common Air Interface (CAI) [Jeff Anderson, TIA TR-8.5] + TIA102CAI = 33, + + /// Wiegand Interface [Scott Guthery] + WiegandInterface = 34, + + /// Pure IP [Inaky Perez-Gonzalez] + PureIP = 35, + + /// HW_EXP1 (RFC5494) + HW_EXP1 = 36, + + /// HFI [Tseng-Hui Lin] + HFI = 37, + + /// Unified Bus (UB) [Wei Pan] + UnifiedBus = 38, + + /// HW_EXP2 (RFC5494) + HW_EXP2 = 256, + + /// AEthernet [Geoffroy Gramaize] + AEthernet = 257, + + /// Reserved (RFC5494) + Reserved65535 = 65535 + } +} diff --git a/RDMSharp/RDM/Enum/ERDM_ControllerFlags.cs b/RDMSharp/RDM/Enum/ERDM_ControllerFlags.cs new file mode 100644 index 00000000..2b97397b --- /dev/null +++ b/RDMSharp/RDM/Enum/ERDM_ControllerFlags.cs @@ -0,0 +1,11 @@ +using System; + +namespace RDMSharp; + +[Flags] +public enum ERDM_ControllerFlags : byte +{ + None = 0b00000001, + Unicode = 0b00000001, + HiResAckTimerSupport = 0b00000010, +} \ No newline at end of file diff --git a/RDMSharp/RDM/Enum/ERDM_Parameter.cs b/RDMSharp/RDM/Enum/ERDM_Parameter.cs index 99e2a473..be293484 100644 --- a/RDMSharp/RDM/Enum/ERDM_Parameter.cs +++ b/RDMSharp/RDM/Enum/ERDM_Parameter.cs @@ -1,330 +1,310 @@ using RDMSharp.Metadata; using RDMSharp.Metadata.JSON; -namespace RDMSharp -{ - /// - /// https://www.rdmprotocol.org/rdm/developers/developer-resources/ - /// - [DataTreeEnum(ERDM_Parameter.SUPPORTED_PARAMETERS, Command.ECommandDublicate.GetResponse, "pid", true, "pids")] - [DataTreeEnum(ERDM_Parameter.PARAMETER_DESCRIPTION, Command.ECommandDublicate.GetRequest, "pid")] - [DataTreeEnum(ERDM_Parameter.METADATA_JSON, Command.ECommandDublicate.GetRequest, "pid")] - [DataTreeEnum(ERDM_Parameter.METADATA_PARAMETER_VERSION, Command.ECommandDublicate.GetRequest, "pid")] - public enum ERDM_Parameter : ushort - { - NONE = 0x0000, - DISC_UNIQUE_BRANCH = 0x0001, - DISC_MUTE = 0x0002, - DISC_UN_MUTE = 0x0003, - [ParameterGroup("Proxie")] - PROXIED_DEVICES = 0x0010, - [ParameterGroup("Proxie")] - PROXIED_DEVICES_COUNT = 0x0011, - COMMS_STATUS = 0x0015, +namespace RDMSharp; - [ParameterGroup("Status")] - QUEUED_MESSAGE = 0x0020, - [ParameterGroup("Status")] - STATUS_MESSAGES = 0x0030, - [ParameterGroup("Status")] - STATUS_ID_DESCRIPTION = 0x0031, - [ParameterGroup("Status")] - CLEAR_STATUS_ID = 0x0032, - [ParameterGroup("Status")] - SUB_DEVICE_STATUS_REPORT_THRESHOLD = 0x0033, - [ParameterGroup("Status")] - QUEUED_MESSAGE_SENSOR_SUBSCRIBE = 0x0034, //E1.20-2025 +/// +/// https://www.rdmprotocol.org/rdm/developers/developer-resources/ +/// +[DataTreeEnum(ERDM_Parameter.SUPPORTED_PARAMETERS, Command.ECommandDublicate.GetResponse, "pid", true, "pids")] +[DataTreeEnum(ERDM_Parameter.PARAMETER_DESCRIPTION, Command.ECommandDublicate.GetRequest, "pid")] +[DataTreeEnum(ERDM_Parameter.METADATA_JSON, Command.ECommandDublicate.GetRequest, "pid")] +[DataTreeEnum(ERDM_Parameter.METADATA_PARAMETER_VERSION, Command.ECommandDublicate.GetRequest, "pid")] +public enum ERDM_Parameter : ushort +{ + NONE = 0x0000, + DISC_UNIQUE_BRANCH = 0x0001, + DISC_MUTE = 0x0002, + DISC_UN_MUTE = 0x0003, + [ParameterGroup("Proxie"), ParameterUpdateTime(300000)] + PROXIED_DEVICES = 0x0010, + [ParameterGroup("Proxie"), ParameterUpdateTime(5000)] + PROXIED_DEVICES_COUNT = 0x0011, + COMMS_STATUS = 0x0015, - [ParameterGroup("Info")] - SUPPORTED_PARAMETERS = 0x0050, - [ParameterGroup("Info")] - PARAMETER_DESCRIPTION = 0x0051, - [ParameterGroup("Info")] - SUPPORTED_PARAMETERS_ENHANCED = 0x0055, //E1.20-2025 - [ParameterGroup("Info")] - CONTROLLER_FLAG_SUPPORT = 0x0056, //E1.20-2025 - [ParameterGroup("Info")] - NACK_DESCRIPTION = 0x0057, //E1.20-2025 - [ParameterGroup("Info")] - PACKED_PID_SUB = 0x0058, //E1.20-2025 - [ParameterGroup("Info")] - PACKED_PID_INDEX = 0x0059, //E1.20-2025 - [ParameterGroup("Info")] - ENUM_LABEL = 0x005A, //E1.20-2025 + [ParameterGroup("Status")] + QUEUED_MESSAGE = 0x0020, + [ParameterGroup("Status"), ParameterUpdateTime(30000)] + STATUS_MESSAGES = 0x0030, + [ParameterGroup("Status")] + STATUS_ID_DESCRIPTION = 0x0031, + [ParameterGroup("Status")] + CLEAR_STATUS_ID = 0x0032, + [ParameterGroup("Status")] + SUB_DEVICE_STATUS_REPORT_THRESHOLD = 0x0033, + [ParameterGroup("Status")] + QUEUED_MESSAGE_SENSOR_SUBSCRIBE = 0x0034, //E1.20-2025 - [ParameterGroup("Info")] - DEVICE_INFO = 0x0060, - [ParameterGroup("Info")] - PRODUCT_DETAIL_ID_LIST = 0x0070, - [ParameterGroup("Info")] - DEVICE_MODEL_DESCRIPTION = 0x0080, - [ParameterGroup("Info")] - MANUFACTURER_LABEL = 0x0081, - [ParameterGroup("Info")] - DEVICE_LABEL = 0x0082, - [ParameterGroup("Control")] - FACTORY_DEFAULTS = 0x0090, - [ParameterGroup("Control")] - LANGUAGE_CAPABILITIES = 0x00A0, - [ParameterGroup("Control")] - LANGUAGE = 0x00B0, - [ParameterGroup("Firmware")] - SOFTWARE_VERSION_LABEL = 0x00C0, - [ParameterGroup("Firmware")] - BOOT_SOFTWARE_VERSION_ID = 0x00C1, - [ParameterGroup("Firmware")] - BOOT_SOFTWARE_VERSION_LABEL = 0x00C2, + [ParameterGroup("Info")] + SUPPORTED_PARAMETERS = 0x0050, + [ParameterGroup("Info")] + PARAMETER_DESCRIPTION = 0x0051, + [ParameterGroup("Info")] + SUPPORTED_PARAMETERS_ENHANCED = 0x0055, //E1.20-2025 + [ParameterGroup("Info")] + CONTROLLER_FLAG_SUPPORT = 0x0056, //E1.20-2025 + [ParameterGroup("Info")] + NACK_DESCRIPTION = 0x0057, //E1.20-2025 + [ParameterGroup("Info")] + PACKED_PID_SUB = 0x0058, //E1.20-2025 + [ParameterGroup("Info")] + PACKED_PID_INDEX = 0x0059, //E1.20-2025 + [ParameterGroup("Info")] + ENUM_LABEL = 0x005A, //E1.20-2025 - [ParameterGroup("DMX")] - DMX_PERSONALITY = 0x00E0, - [ParameterGroup("DMX")] - DMX_PERSONALITY_DESCRIPTION = 0x00E1, - [ParameterGroup("DMX")] - DMX_START_ADDRESS = 0x00F0, - [ParameterGroup("Slots")] - SLOT_INFO = 0x0120, - [ParameterGroup("Slots")] - SLOT_DESCRIPTION = 0x0121, - [ParameterGroup("Slots")] - DEFAULT_SLOT_VALUE = 0x0122, + [ParameterGroup("Info"), ParameterUpdateTime(60000)] + DEVICE_INFO = 0x0060, + [ParameterGroup("Info"), ParameterUpdateTime(601000)] + PRODUCT_DETAIL_ID_LIST = 0x0070, + [ParameterGroup("Info"), ParameterUpdateTime(602000)] + DEVICE_MODEL_DESCRIPTION = 0x0080, + [ParameterGroup("Info"), ParameterUpdateTime(603000)] + MANUFACTURER_LABEL = 0x0081, + [ParameterGroup("Info"), ParameterUpdateTime(364000)] + DEVICE_LABEL = 0x0082, + [ParameterGroup("Control"), ParameterUpdateTime(180000)] + FACTORY_DEFAULTS = 0x0090, + [ParameterGroup("Control")] + LANGUAGE_CAPABILITIES = 0x00A0, + [ParameterGroup("Control"), ParameterUpdateTime(300000)] + LANGUAGE = 0x00B0, + [ParameterGroup("Firmware"), ParameterUpdateTime(121000)] + SOFTWARE_VERSION_LABEL = 0x00C0, + [ParameterGroup("Firmware"), ParameterUpdateTime(302000)] + BOOT_SOFTWARE_VERSION_ID = 0x00C1, + [ParameterGroup("Firmware"), ParameterUpdateTime(302000)] + BOOT_SOFTWARE_VERSION_LABEL = 0x00C2, + + [ParameterGroup("DMX"), ParameterUpdateTime(62000)] + DMX_PERSONALITY = 0x00E0, + [ParameterGroup("DMX")] + DMX_PERSONALITY_DESCRIPTION = 0x00E1, + [ParameterGroup("DMX"), ParameterUpdateTime(65000)] + DMX_START_ADDRESS = 0x00F0, + [ParameterGroup("Slots")] + SLOT_INFO = 0x0120, + [ParameterGroup("Slots")] + SLOT_DESCRIPTION = 0x0121, + [ParameterGroup("Slots")] + DEFAULT_SLOT_VALUE = 0x0122, - [ParameterGroup("Sensors")] - SENSOR_DEFINITION = 0x0200, - [ParameterGroup("Sensors")] - SENSOR_VALUE = 0x0201, - [ParameterGroup("Sensors")] - RECORD_SENSORS = 0x0202, + [ParameterGroup("Sensors")] + SENSOR_DEFINITION = 0x0200, + [ParameterGroup("Sensors"), ParameterUpdateTime(20000)] + SENSOR_VALUE = 0x0201, + [ParameterGroup("Sensors")] + RECORD_SENSORS = 0x0202, - [ParameterGroup("Info")] - DEVICE_HOURS = 0x0400, - [ParameterGroup("Lamp")] - LAMP_HOURS = 0x0401, - [ParameterGroup("Lamp")] - LAMP_STRIKES = 0x0402, - [ParameterGroup("Lamp")] - LAMP_STATE = 0x0403, - [ParameterGroup("Lamp")] - LAMP_ON_MODE = 0x0404, - [ParameterGroup("Info")] - DEVICE_POWER_CYCLES = 0x0405, + [ParameterGroup("Info"), ParameterUpdateTime(301000)] + DEVICE_HOURS = 0x0400, + [ParameterGroup("Lamp"), ParameterUpdateTime(302000)] + LAMP_HOURS = 0x0401, + [ParameterGroup("Lamp"), ParameterUpdateTime(303000)] + LAMP_STRIKES = 0x0402, + [ParameterGroup("Lamp"), ParameterUpdateTime(30400)] + LAMP_STATE = 0x0403, + [ParameterGroup("Lamp"), ParameterUpdateTime(60500)] + LAMP_ON_MODE = 0x0404, + [ParameterGroup("Info"), ParameterUpdateTime(126000)] + DEVICE_POWER_CYCLES = 0x0405, - [ParameterGroup("Display")] - DISPLAY_INVERT = 0x0500, - [ParameterGroup("Display")] - DISPLAY_LEVEL = 0x0501, + [ParameterGroup("Display"), ParameterUpdateTime(307000)] + DISPLAY_INVERT = 0x0500, + [ParameterGroup("Display"), ParameterUpdateTime(308000)] + DISPLAY_LEVEL = 0x0501, - [ParameterGroup("Pan/Tilt")] - PAN_INVERT = 0x0600, - [ParameterGroup("Pan/Tilt")] - TILT_INVERT = 0x0601, - [ParameterGroup("Pan/Tilt")] - PAN_TILT_SWAP = 0x0602, - REAL_TIME_CLOCK = 0x0603, + [ParameterGroup("Pan/Tilt"), ParameterUpdateTime(180100)] + PAN_INVERT = 0x0600, + [ParameterGroup("Pan/Tilt"), ParameterUpdateTime(180200)] + TILT_INVERT = 0x0601, + [ParameterGroup("Pan/Tilt"), ParameterUpdateTime(180300)] + PAN_TILT_SWAP = 0x0602, + [ParameterUpdateTime(7200000)] + REAL_TIME_CLOCK = 0x0603, - [ParameterGroup("Control")] - IDENTIFY_DEVICE = 0x1000, - [ParameterGroup("Control")] - RESET_DEVICE = 0x1001, - [ParameterGroup("Control")] - POWER_STATE = 0x1010, - [ParameterGroup("Control")] - PERFORM_SELFTEST = 0x1020, - [ParameterGroup("Control")] - SELF_TEST_DESCRIPTION = 0x1021, - [ParameterGroup("Control")] - SELFTEST_ENHANCED = 0x1022, //E1.20-2025 - [ParameterGroup("Preset")] - CAPTURE_PRESET = 0x1030, - [ParameterGroup("Preset")] - PRESET_PLAYBACK = 0x1031, + [ParameterGroup("Control")] + IDENTIFY_DEVICE = 0x1000, + [ParameterGroup("Control")] + RESET_DEVICE = 0x1001, + [ParameterGroup("Control"), ParameterUpdateTime(30000)] + POWER_STATE = 0x1010, + [ParameterGroup("Control")] + PERFORM_SELFTEST = 0x1020, + [ParameterGroup("Control")] + SELF_TEST_DESCRIPTION = 0x1021, + [ParameterGroup("Control")] + SELFTEST_ENHANCED = 0x1022, //E1.20-2025 + [ParameterGroup("Preset")] + CAPTURE_PRESET = 0x1030, + [ParameterGroup("Preset")] + PRESET_PLAYBACK = 0x1031, - //E1.37-1 - 2012 - [ParameterGroup("DMX")] - DMX_BLOCK_ADDRESS = 0x0140, - [ParameterGroup("DMX")] - DMX_FAIL_MODE = 0x0141, - [ParameterGroup("DMX")] - DMX_STARTUP_MODE = 0x0142, + //E1.37-1 - 2012 + [ParameterGroup("DMX")] + DMX_BLOCK_ADDRESS = 0x0140, + [ParameterGroup("DMX"), ParameterUpdateTime(300000)] + DMX_FAIL_MODE = 0x0141, + [ParameterGroup("DMX")] + DMX_STARTUP_MODE = 0x0142, - [ParameterGroup("Dimming")] - DIMMER_INFO = 0x0340, - [ParameterGroup("Dimming")] - MINIMUM_LEVEL = 0x0341, - [ParameterGroup("Dimming")] - MAXIMUM_LEVEL = 0x0342, - [ParameterGroup("Dimming")] - CURVE = 0x0343, - [ParameterGroup("Dimming")] - CURVE_DESCRIPTION = 0x0344, - [ParameterGroup("Dimming")] - OUTPUT_RESPONSE_TIME = 0x0345, - [ParameterGroup("Dimming")] - OUTPUT_RESPONSE_TIME_DESCRIPTION = 0x0346, - [ParameterGroup("Dimming")] - MODULATION_FREQUENCY = 0x0347, - [ParameterGroup("Dimming")] - MODULATION_FREQUENCY_DESCRIPTION = 0x0348, + [ParameterGroup("Dimming")] + DIMMER_INFO = 0x0340, + [ParameterGroup("Dimming")] + MINIMUM_LEVEL = 0x0341, + [ParameterGroup("Dimming")] + MAXIMUM_LEVEL = 0x0342, + [ParameterGroup("Dimming"), ParameterUpdateTime(30000)] + CURVE = 0x0343, + [ParameterGroup("Dimming")] + CURVE_DESCRIPTION = 0x0344, + [ParameterGroup("Dimming"), ParameterUpdateTime(30000)] + OUTPUT_RESPONSE_TIME = 0x0345, + [ParameterGroup("Dimming")] + OUTPUT_RESPONSE_TIME_DESCRIPTION = 0x0346, + [ParameterGroup("Dimming"), ParameterUpdateTime(30000)] + MODULATION_FREQUENCY = 0x0347, + [ParameterGroup("Dimming")] + MODULATION_FREQUENCY_DESCRIPTION = 0x0348, - BURN_IN = 0x0440, + BURN_IN = 0x0440, - [ParameterGroup("Lock")] - LOCK_PIN = 0x0640, - [ParameterGroup("Lock")] - LOCK_STATE = 0x0641, - [ParameterGroup("Lock")] - LOCK_STATE_DESCRIPTION = 0x0642, + [ParameterGroup("Lock")] + LOCK_PIN = 0x0640, + [ParameterGroup("Lock")] + LOCK_STATE = 0x0641, + [ParameterGroup("Lock")] + LOCK_STATE_DESCRIPTION = 0x0642, - [ParameterGroup("Control")] - IDENTIFY_MODE = 0x1040, - [ParameterGroup("Preset")] - PRESET_INFO = 0x1041, - [ParameterGroup("Preset")] - PRESET_STATUS = 0x1042, - [ParameterGroup("Preset")] - PRESET_MERGEMODE = 0x1043, - [ParameterGroup("Control")] - POWER_ON_SELF_TEST = 0x1044, + [ParameterGroup("Control")] + IDENTIFY_MODE = 0x1040, + [ParameterGroup("Preset")] + PRESET_INFO = 0x1041, + [ParameterGroup("Preset")] + PRESET_STATUS = 0x1042, + [ParameterGroup("Preset")] + PRESET_MERGEMODE = 0x1043, + [ParameterGroup("Control")] + POWER_ON_SELF_TEST = 0x1044, - //E1.37-2 - 2015 - [ParameterGroup("Network")] - LIST_INTERFACES = 0x0700, - [ParameterGroup("Network")] - INTERFACE_LABEL = 0x0701, - [ParameterGroup("Network")] - INTERFACE_HARDWARE_ADDRESS_TYPE = 0x0702, - [ParameterGroup("Network")] - IPV4_DHCP_MODE = 0x0703, - [ParameterGroup("Network")] - IPV4_ZEROCONF_MODE = 0x0704, - [ParameterGroup("Network")] - IPV4_CURRENT_ADDRESS = 0x0705, - [ParameterGroup("Network")] - IPV4_STATIC_ADDRESS = 0x0706, - [ParameterGroup("Network")] - INTERFACE_RENEW_DHCP = 0x0707, - [ParameterGroup("Network")] - INTERFACE_RELEASE_DHCP = 0x0708, - [ParameterGroup("Network")] - INTERFACE_APPLY_CONFIGURATION = 0x0709, - [ParameterGroup("Network")] - IPV4_DEFAULT_ROUTE = 0x070A, - [ParameterGroup("Network")] - DNS_IPV4_NAME_SERVER = 0x070B, - [ParameterGroup("Network")] - DNS_HOSTNAME = 0x070C, - [ParameterGroup("Network")] - DNS_DOMAIN_NAME = 0x070D, + //E1.37-2 - 2015 + [ParameterGroup("Network")] + LIST_INTERFACES = 0x0700, + [ParameterGroup("Network")] + INTERFACE_LABEL = 0x0701, + [ParameterGroup("Network")] + INTERFACE_HARDWARE_ADDRESS_TYPE = 0x0702, + [ParameterGroup("Network")] + IPV4_DHCP_MODE = 0x0703, + [ParameterGroup("Network")] + IPV4_ZEROCONF_MODE = 0x0704, + [ParameterGroup("Network")] + IPV4_CURRENT_ADDRESS = 0x0705, + [ParameterGroup("Network")] + IPV4_STATIC_ADDRESS = 0x0706, + [ParameterGroup("Network")] + INTERFACE_RENEW_DHCP = 0x0707, + [ParameterGroup("Network")] + INTERFACE_RELEASE_DHCP = 0x0708, + [ParameterGroup("Network")] + INTERFACE_APPLY_CONFIGURATION = 0x0709, + [ParameterGroup("Network")] + IPV4_DEFAULT_ROUTE = 0x070A, + [ParameterGroup("Network")] + DNS_IPV4_NAME_SERVER = 0x070B, + [ParameterGroup("Network")] + DNS_HOSTNAME = 0x070C, + [ParameterGroup("Network")] + DNS_DOMAIN_NAME = 0x070D, - //E1.33 - 2019 RDM-Net - [ParameterGroup("E1.33")] - COMPONENT_SCOPE = 0x0800, - [ParameterGroup("E1.33")] - SEARCH_DOMAIN = 0x0801, - [ParameterGroup("E1.33")] - TCP_COMMS_STATUS = 0x0802, - [ParameterGroup("E1.33")] - BROKER_STATUS = 0x0803, - - //E1.37-7 - 2019 - [ParameterGroup("E1.37-7")] - ENDPOINT_LIST = 0x0900, - [ParameterGroup("E1.37-7")] - ENDPOINT_LIST_CHANGE = 0x0901, - [ParameterGroup("E1.37-7")] - IDENTIFY_ENDPOINT = 0x0902, - [ParameterGroup("E1.37-7")] - ENDPOINT_TO_UNIVERSE = 0x0903, - [ParameterGroup("E1.37-7")] - ENDPOINT_MODE = 0x0904, - [ParameterGroup("E1.37-7")] - ENDPOINT_LABEL = 0x0905, - [ParameterGroup("E1.37-7")] - RDM_TRAFFIC_ENABLE = 0x0906, - [ParameterGroup("E1.37-7")] - DISCOVERY_STATE = 0x0907, - [ParameterGroup("E1.37-7")] - BACKGROUND_DISCOVERY = 0x0908, - [ParameterGroup("E1.37-7")] - ENDPOINT_TIMING = 0x0909, - [ParameterGroup("E1.37-7")] - ENDPOINT_TIMING_DESCRIPTION = 0x090A, - [ParameterGroup("E1.37-7")] - ENDPOINT_RESPONDERS = 0x090B, - [ParameterGroup("E1.37-7")] - ENDPOINT_RESPONDER_LIST_CHANGE = 0x090C, - [ParameterGroup("E1.37-7")] - BINDING_CONTROL_FIELDS = 0x090D, - [ParameterGroup("E1.37-7")] - BACKGROUND_QUEUED_STATUS_POLICY = 0x090E, - [ParameterGroup("E1.37-7")] - BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION = 0x090F, + //E1.33 - 2019 RDM-Net + [ParameterGroup("E1.33")] + COMPONENT_SCOPE = 0x0800, + [ParameterGroup("E1.33")] + SEARCH_DOMAIN = 0x0801, + [ParameterGroup("E1.33")] + TCP_COMMS_STATUS = 0x0802, + [ParameterGroup("E1.33")] + BROKER_STATUS = 0x0803, - //E1.37-5 - 2024 - [ParameterGroup("URL")] - MANUFACTURER_URL = 0x00D0, - [ParameterGroup("URL")] - PRODUCT_URL = 0x00D1, - [ParameterGroup("URL")] - FIRMWARE_URL = 0x00D2, - [ParameterGroup("Info")] - SERIAL_NUMBER = 0x00D3, - [ParameterGroup("Info")] - DEVICE_INFO_OFFSTAGE = 0x00D4, - [ParameterGroup("Control")] - TEST_DATA = 0x0016, - [ParameterGroup("Control")] - COMMS_STATUS_NSC = 0x0017, - [ParameterGroup("Control")] - IDENTIFY_TIMEOUT = 0x1050, - [ParameterGroup("Control")] - POWER_OFF_READY = 0x1051, - [ParameterGroup("Control")] - SHIPPING_LOCK = 0x0650, - [ParameterGroup("Tag")] - LIST_TAGS = 0x0651, - [ParameterGroup("Tag")] - ADD_TAG = 0x0652, - [ParameterGroup("Tag")] - REMOVE_TAG = 0x0653, - [ParameterGroup("Tag")] - CHECK_TAG = 0x0654, - [ParameterGroup("Tag")] - CLEAR_TAGS = 0x0655, - [ParameterGroup("Info")] - DEVICE_UNIT_NUMBER = 0x0656, - [ParameterGroup("DMX")] - DMX_PERSONALITY_ID = 0x00E2, - [ParameterGroup("Sensor")] - SENSOR_TYPE_CUSTOM = 0x0210, - [ParameterGroup("Sensor")] - SENSOR_UNIT_CUSTOM = 0x0211, - [ParameterGroup("Metadata")] - METADATA_PARAMETER_VERSION = 0x0052, - [ParameterGroup("Metadata")] - METADATA_JSON = 0x0053, - [ParameterGroup("Metadata")] - METADATA_JSON_URL = 0x0054, + //E1.37-7 - 2019 + [ParameterGroup("E1.37-7")] + ENDPOINT_LIST = 0x0900, + [ParameterGroup("E1.37-7")] + ENDPOINT_LIST_CHANGE = 0x0901, + [ParameterGroup("E1.37-7")] + IDENTIFY_ENDPOINT = 0x0902, + [ParameterGroup("E1.37-7")] + ENDPOINT_TO_UNIVERSE = 0x0903, + [ParameterGroup("E1.37-7")] + ENDPOINT_MODE = 0x0904, + [ParameterGroup("E1.37-7")] + ENDPOINT_LABEL = 0x0905, + [ParameterGroup("E1.37-7")] + RDM_TRAFFIC_ENABLE = 0x0906, + [ParameterGroup("E1.37-7")] + DISCOVERY_STATE = 0x0907, + [ParameterGroup("E1.37-7")] + BACKGROUND_DISCOVERY = 0x0908, + [ParameterGroup("E1.37-7")] + ENDPOINT_TIMING = 0x0909, + [ParameterGroup("E1.37-7")] + ENDPOINT_TIMING_DESCRIPTION = 0x090A, + [ParameterGroup("E1.37-7")] + ENDPOINT_RESPONDERS = 0x090B, + [ParameterGroup("E1.37-7")] + ENDPOINT_RESPONDER_LIST_CHANGE = 0x090C, + [ParameterGroup("E1.37-7")] + BINDING_CONTROL_FIELDS = 0x090D, + [ParameterGroup("E1.37-7")] + BACKGROUND_QUEUED_STATUS_POLICY = 0x090E, + [ParameterGroup("E1.37-7")] + BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION = 0x090F, - ////SGM specific IDs - //SERIAL_NUMBER_SGM = 0x8060, - //REFRESH_RATE = 0x8620, - ////=0x8621, - ////=0x8622, - //DIMMING_CURVE = 0x8623, - ////=0x8624, - //FAN_MODE = 0x8625, - //CRMX_LOG_OFF = 0x8626, - ////=0x8627, - //DIM_MODE = 0x8628, - //INVERT_PIXEL_ORDER = 0x8629, - //NORTH_CALIBRATION = 0x8630, - //BATTERY_EXTENSION = 0x8631, - //SMPS_CALIBRATION = 0x8632, - //WIRELESS_DMX = 0x8633, - ////=3635, - ////ACTIVE_ERROR = 0x8636, - //CRMX_BRIDGE_MODE = 0x8637 - } + //E1.37-5 - 2024 + [ParameterGroup("URL"), ParameterUpdateTime(600000)] + MANUFACTURER_URL = 0x00D0, + [ParameterGroup("URL"), ParameterUpdateTime(600000)] + PRODUCT_URL = 0x00D1, + [ParameterGroup("URL"), ParameterUpdateTime(600000)] + FIRMWARE_URL = 0x00D2, + [ParameterGroup("Info"), ParameterUpdateTime(600000)] + SERIAL_NUMBER = 0x00D3, + [ParameterGroup("Info")] + DEVICE_INFO_OFFSTAGE = 0x00D4, + [ParameterGroup("Control")] + TEST_DATA = 0x0016, + [ParameterGroup("Control")] + COMMS_STATUS_NSC = 0x0017, + [ParameterGroup("Control")] + IDENTIFY_TIMEOUT = 0x1050, + [ParameterGroup("Control")] + POWER_OFF_READY = 0x1051, + [ParameterGroup("Control")] + SHIPPING_LOCK = 0x0650, + [ParameterGroup("Tag"), ParameterUpdateTime(60000)] + LIST_TAGS = 0x0651, + [ParameterGroup("Tag")] + ADD_TAG = 0x0652, + [ParameterGroup("Tag")] + REMOVE_TAG = 0x0653, + [ParameterGroup("Tag")] + CHECK_TAG = 0x0654, + [ParameterGroup("Tag")] + CLEAR_TAGS = 0x0655, + [ParameterGroup("Info"), ParameterUpdateTime(120000)] + DEVICE_UNIT_NUMBER = 0x0656, + [ParameterGroup("DMX"), ParameterUpdateTime(120000)] + DMX_PERSONALITY_ID = 0x00E2, + [ParameterGroup("Sensor")] + SENSOR_TYPE_CUSTOM = 0x0210, + [ParameterGroup("Sensor")] + SENSOR_UNIT_CUSTOM = 0x0211, + [ParameterGroup("Metadata"), ParameterUpdateTime(600000)] + METADATA_PARAMETER_VERSION = 0x0052, + [ParameterGroup("Metadata"), ParameterUpdateTime(600000)] + METADATA_JSON = 0x0053, + [ParameterGroup("Metadata"), ParameterUpdateTime(600000)] + METADATA_JSON_URL = 0x0054 } diff --git a/RDMSharp/RDM/GlobalTimers.cs b/RDMSharp/RDM/GlobalTimers.cs index 5512f4ca..5add39e8 100644 --- a/RDMSharp/RDM/GlobalTimers.cs +++ b/RDMSharp/RDM/GlobalTimers.cs @@ -1,178 +1,245 @@ -using System; +using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("RDMSharp.Tests")] -namespace RDMSharp +namespace RDMSharp; + +public class GlobalTimers { - public class GlobalTimers + private static readonly ILogger Logger = Logging.CreateLogger(); + private static GlobalTimers instance = null; + public static GlobalTimers Instance { - private static GlobalTimers instance = null; - public static GlobalTimers Instance + get { - get - { - if (instance == null) - instance = new GlobalTimers(); - return instance; - } + if (instance == null) + instance = new GlobalTimers(); + return instance; } + } - public const int DefaultQueuedUpdateTime = 4000; // 4 seconds - public const int DefaultNonQueuedUpdateTime = 10000; // 10 seconds - public const int DefaultUpdateDelayBetweenRequests = 50; // 50 milliseconds - public const int DefaultUpdateDelayBetweenQueuedUpdateRequests = 200; // 200 milliseconds - public const int DefaultUpdateDelayBetweenNonQueuedUpdateRequests = 500; // 500 milliseconds - public const int DefaultPresentLostTime = 15000; // 15 seconds + public const int DefaultQueuedUpdateTime = 10000; // 10 seconds + public const int DefaultNonQueuedUpdateTime = 60000; // 60 seconds + public const int DefaultUpdateDelayBetweenRequests = 50; // 50 milliseconds + public const int DefaultUpdateDelayBetweenQueuedUpdateRequests = 200; // 200 milliseconds + public const int DefaultUpdateDelayBetweenNonQueuedUpdateRequests = 500; // 500 milliseconds + public const int DefaultPresentLostTime = 15000; // 15 seconds - public const int DefaultDiscoveryTimeout = 5; // 5 milliseconds + public const int DefaultDiscoveryTimeout = 5; // 5 milliseconds - public const int DefaultParameterUpdateTimerInterval = 10000; // 10 seconds - public const int DefaultPresentUpdateTimerInterval = 500; // 0.5 seconds - public int QueuedUpdateTime { get; set; } = DefaultQueuedUpdateTime; - public int NonQueuedUpdateTime { get; set; } = DefaultNonQueuedUpdateTime; - public int UpdateDelayBetweenRequests { get; set; } = DefaultUpdateDelayBetweenRequests; - public int UpdateDelayBetweenQueuedUpdateRequests { get; set; } = DefaultUpdateDelayBetweenQueuedUpdateRequests; - public int UpdateDelayBetweenNonQueuedUpdateRequests { get; set; } = DefaultUpdateDelayBetweenNonQueuedUpdateRequests; - public int PresentLostTime { get; set; } = DefaultPresentLostTime; + public const int DefaultParameterUpdateTimerInterval = 7500; // 7.5 seconds + public const int DefaultPresentUpdateTimerInterval = 500; // 0.5 seconds + public const int DefaultRealTimeClockUpdateTimerInterval = 1800000; // 30 minutes + public int QueuedUpdateTime { get; set; } = DefaultQueuedUpdateTime; + public int NonQueuedUpdateTime { get; set; } = DefaultNonQueuedUpdateTime; + public int UpdateDelayBetweenRequests { get; set; } = DefaultUpdateDelayBetweenRequests; + public int UpdateDelayBetweenQueuedUpdateRequests { get; set; } = DefaultUpdateDelayBetweenQueuedUpdateRequests; + public int UpdateDelayBetweenNonQueuedUpdateRequests { get; set; } = DefaultUpdateDelayBetweenNonQueuedUpdateRequests; + public int PresentLostTime { get; set; } = DefaultPresentLostTime; - public int DiscoveryTimeout { get; set; } = DefaultDiscoveryTimeout; + public int DiscoveryTimeout { get; set; } = DefaultDiscoveryTimeout; - private int parameterUpdateTimerInterval = DefaultParameterUpdateTimerInterval; - public int ParameterUpdateTimerInterval + private int parameterUpdateTimerInterval = DefaultParameterUpdateTimerInterval; + public int ParameterUpdateTimerInterval + { + get { - get - { - return parameterUpdateTimerInterval; - } - set - { - parameterUpdateTimerInterval = value; - if (parameterUpdateTimer != null) - parameterUpdateTimer.Interval = value; - } + return parameterUpdateTimerInterval; } - - private int presentUpdateTimerInterval = DefaultPresentUpdateTimerInterval; - public int PresentUpdateTimerInterval + set { - get - { - return presentUpdateTimerInterval; - } - set - { - presentUpdateTimerInterval = value; - if (presentUpdateTimer != null) - presentUpdateTimer.Interval = value; - } + parameterUpdateTimerInterval = value; + if (parameterUpdateTimer != null) + parameterUpdateTimer.Interval = value; } + } - private System.Timers.Timer parameterUpdateTimer = null; - private System.Timers.Timer presentUpdateTimer = null; - - private event EventHandler parameterUpdateTimerElapsed; - public event EventHandler ParameterUpdateTimerElapsed + private int presentUpdateTimerInterval = DefaultPresentUpdateTimerInterval; + public int PresentUpdateTimerInterval + { + get { - add - { - if (parameterUpdateTimer == null) - initializeParameterUpdateTimer(); - - parameterUpdateTimerElapsed += value; - } - remove - { - parameterUpdateTimerElapsed -= value; - - if (parameterUpdateTimer != null && parameterUpdateTimerElapsed == null) - destroyParameterUpdateTimer(); - } + return presentUpdateTimerInterval; } - private event EventHandler presentUpdateTimerElapsed; - public event EventHandler PresentUpdateTimerElapsed + set { - add - { - if (presentUpdateTimerElapsed == null) - initializePresentUpdateTimer(); - - presentUpdateTimerElapsed += value; - } - remove - { - presentUpdateTimerElapsed -= value; - - if (presentUpdateTimerElapsed != null && presentUpdateTimerElapsed == null) - destroyPresentUpdateTimer(); - } + presentUpdateTimerInterval = value; + if (presentUpdateTimer != null) + presentUpdateTimer.Interval = value; } - private void initializeParameterUpdateTimer() + } + + private int realTimeClockUpdateTimerInterval = DefaultRealTimeClockUpdateTimerInterval; + public int RealTimeClockUpdateTimerInterval + { + get { - if (parameterUpdateTimer != null) - return; - parameterUpdateTimer = new System.Timers.Timer(ParameterUpdateTimerInterval); - parameterUpdateTimer.Elapsed += ParameterUpdateTimer_Elapsed; - parameterUpdateTimer.Enabled = true; + return realTimeClockUpdateTimerInterval; } - private void destroyParameterUpdateTimer() + set { - if (parameterUpdateTimer == null) - return; - parameterUpdateTimer.Enabled = false; - parameterUpdateTimer.Elapsed -= ParameterUpdateTimer_Elapsed; - parameterUpdateTimer.Dispose(); - parameterUpdateTimer = null; + realTimeClockUpdateTimerInterval = value; + if (realTimeClockUpdateTimer != null) + realTimeClockUpdateTimer.Interval = value; } + } + + private System.Timers.Timer parameterUpdateTimer = null; + private System.Timers.Timer presentUpdateTimer = null; + private System.Timers.Timer realTimeClockUpdateTimer = null; - private void initializePresentUpdateTimer() + private event EventHandler parameterUpdateTimerElapsed; + public event EventHandler ParameterUpdateTimerElapsed + { + add { - if (parameterUpdateTimer != null) - return; - presentUpdateTimer = new System.Timers.Timer(PresentUpdateTimerInterval); - presentUpdateTimer.Elapsed += PresentUpdateTimer_Elapsed; - presentUpdateTimer.Enabled = true; + if (parameterUpdateTimer == null) + initializeParameterUpdateTimer(); + + parameterUpdateTimerElapsed += value; } - private void destroyPresentUpdateTimer() + remove { - if (parameterUpdateTimer == null) - return; - presentUpdateTimer.Enabled = false; - presentUpdateTimer.Elapsed -= PresentUpdateTimer_Elapsed; - presentUpdateTimer.Dispose(); - presentUpdateTimer = null; + parameterUpdateTimerElapsed -= value; + + if (parameterUpdateTimer != null && parameterUpdateTimerElapsed == null) + destroyParameterUpdateTimer(); } - public void ResetAllTimersToDefault() + } + private event EventHandler presentUpdateTimerElapsed; + public event EventHandler PresentUpdateTimerElapsed + { + add { - QueuedUpdateTime = DefaultQueuedUpdateTime; - NonQueuedUpdateTime = DefaultNonQueuedUpdateTime; - UpdateDelayBetweenRequests = DefaultUpdateDelayBetweenRequests; - UpdateDelayBetweenQueuedUpdateRequests = DefaultUpdateDelayBetweenQueuedUpdateRequests; - UpdateDelayBetweenNonQueuedUpdateRequests = DefaultUpdateDelayBetweenNonQueuedUpdateRequests; - PresentLostTime = DefaultPresentLostTime; + if (presentUpdateTimerElapsed == null) + initializePresentUpdateTimer(); - DiscoveryTimeout = DefaultDiscoveryTimeout; + presentUpdateTimerElapsed += value; + } + remove + { + presentUpdateTimerElapsed -= value; - ParameterUpdateTimerInterval = DefaultParameterUpdateTimerInterval; - PresentUpdateTimerInterval = DefaultPresentUpdateTimerInterval; + if (presentUpdateTimerElapsed != null && presentUpdateTimerElapsed == null) + destroyPresentUpdateTimer(); } - internal void InternalAllTimersToTestSpeed() + } + + private event EventHandler realTimeClockUpdateTimerElapsed; + public event EventHandler RealTimeClockUpdateTimerElapsed + { + add { - ResetAllTimersToDefault(); - QueuedUpdateTime = 30; - NonQueuedUpdateTime = 30; - UpdateDelayBetweenRequests = 0; - UpdateDelayBetweenQueuedUpdateRequests = 0; - UpdateDelayBetweenNonQueuedUpdateRequests = 0; - PresentLostTime = 10000; + if (realTimeClockUpdateTimerElapsed == null) + initializeRealTimeClockUpdateTimer(); - DiscoveryTimeout = 15; + realTimeClockUpdateTimerElapsed += value; + } + remove + { + realTimeClockUpdateTimerElapsed -= value; - ParameterUpdateTimerInterval = 15; - PresentUpdateTimerInterval = 1000; + if (realTimeClockUpdateTimerElapsed != null && realTimeClockUpdateTimerElapsed == null) + destroyRealTimeClockUpdateTimer(); } + } + private void initializeParameterUpdateTimer() + { + Logger?.LogInformation("InitializeParameterUpdateTimer"); + if (parameterUpdateTimer != null) + return; + parameterUpdateTimer = new System.Timers.Timer(ParameterUpdateTimerInterval); + parameterUpdateTimer.Elapsed += ParameterUpdateTimer_Elapsed; + parameterUpdateTimer.Enabled = true; + } + private void destroyParameterUpdateTimer() + { + Logger?.LogCritical("DestroyParameterUpdateTimer"); + if (parameterUpdateTimer == null) + return; + parameterUpdateTimer.Enabled = false; + parameterUpdateTimer.Elapsed -= ParameterUpdateTimer_Elapsed; + parameterUpdateTimer.Dispose(); + parameterUpdateTimer = null; + } + + private void initializePresentUpdateTimer() + { + Logger?.LogInformation("InitializePresentUpdateTimer"); + if (parameterUpdateTimer != null) + return; + presentUpdateTimer = new System.Timers.Timer(PresentUpdateTimerInterval); + presentUpdateTimer.Elapsed += PresentUpdateTimer_Elapsed; + presentUpdateTimer.Enabled = true; + } + private void destroyPresentUpdateTimer() + { + Logger?.LogCritical("DestroyPresentUpdateTimer"); + if (parameterUpdateTimer == null) + return; + presentUpdateTimer.Enabled = false; + presentUpdateTimer.Elapsed -= PresentUpdateTimer_Elapsed; + presentUpdateTimer.Dispose(); + presentUpdateTimer = null; + } + + private void initializeRealTimeClockUpdateTimer() + { + Logger?.LogInformation("InitializeRealTimeClockUpdateTimer"); + if (parameterUpdateTimer != null) + return; + realTimeClockUpdateTimer = new System.Timers.Timer(RealTimeClockUpdateTimerInterval); + realTimeClockUpdateTimer.Elapsed += RealTimeClockUpdateTimer_Elapsed; + realTimeClockUpdateTimer.Enabled = true; + } + private void destroyRealTimeClockUpdateTimer() + { + Logger?.LogCritical("DestroyRealTimeClockUpdateTimer"); + if (parameterUpdateTimer == null) + return; + realTimeClockUpdateTimer.Enabled = false; + realTimeClockUpdateTimer.Elapsed -= RealTimeClockUpdateTimer_Elapsed; + realTimeClockUpdateTimer.Dispose(); + realTimeClockUpdateTimer = null; + } + + + public void ResetAllTimersToDefault() + { + Logger?.LogCritical("ResetAllTimersToDefault"); + QueuedUpdateTime = DefaultQueuedUpdateTime; + NonQueuedUpdateTime = DefaultNonQueuedUpdateTime; + UpdateDelayBetweenRequests = DefaultUpdateDelayBetweenRequests; + UpdateDelayBetweenQueuedUpdateRequests = DefaultUpdateDelayBetweenQueuedUpdateRequests; + UpdateDelayBetweenNonQueuedUpdateRequests = DefaultUpdateDelayBetweenNonQueuedUpdateRequests; + PresentLostTime = DefaultPresentLostTime; + + DiscoveryTimeout = DefaultDiscoveryTimeout; + + ParameterUpdateTimerInterval = DefaultParameterUpdateTimerInterval; + PresentUpdateTimerInterval = DefaultPresentUpdateTimerInterval; + } + internal void InternalAllTimersToTestSpeed() + { + ResetAllTimersToDefault(); + QueuedUpdateTime = 30; + NonQueuedUpdateTime = 30; + UpdateDelayBetweenRequests = 0; + UpdateDelayBetweenQueuedUpdateRequests = 0; + UpdateDelayBetweenNonQueuedUpdateRequests = 0; + PresentLostTime = 10000; + + DiscoveryTimeout = 15; - private void ParameterUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + ParameterUpdateTimerInterval = 15; + PresentUpdateTimerInterval = 1000; + } + + private void ParameterUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + try { - // Parallelisierung: Alle Handler parallel ausführen, falls mehrere abonniert sind var handlers = parameterUpdateTimerElapsed?.GetInvocationList(); if (handlers != null) { @@ -182,28 +249,68 @@ private void ParameterUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEv { ((EventHandler)handler)?.Invoke(sender, EventArgs.Empty); } - catch + catch (Exception ex) { + Logger?.LogError(ex, "Error in ParameterUpdateTimerElapsed handler"); } }); } } - private void PresentUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + catch (Exception ex) + { + Logger?.LogError(ex, "Error in ParameterUpdateTimer_Elapsed"); + } + } + private void PresentUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + try { var handlers = presentUpdateTimerElapsed?.GetInvocationList(); if (handlers != null) { System.Threading.Tasks.Parallel.ForEach(handlers, handler => { + try + { + ((EventHandler)handler)?.InvokeFailSafe(sender, EventArgs.Empty); + } + catch (Exception ex) + { + Logger?.LogError(ex, "Error in PresentUpdateTimerElapsed handler"); + } + }); + } + } + catch (Exception ex) + { + Logger?.LogError(ex, "Error in PresentUpdateTimer_Elapsed"); + } + } + private void RealTimeClockUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + try + { + Random random = new Random(); + var handlers = realTimeClockUpdateTimerElapsed?.GetInvocationList(); + if (handlers != null) + { + System.Threading.Tasks.Parallel.ForEachAsync(handlers, async (handler, token) => + { + await Task.Delay(random.Next(1000, 15000)); //Add some randomness to distribute the load on the bus. try { ((EventHandler)handler)?.Invoke(sender, EventArgs.Empty); } - catch + catch (Exception ex) { + Logger?.LogError(ex, "Error in RealTimeClockUpdateTimerElapsed handler"); } }); } } + catch (Exception ex) + { + Logger?.LogError(ex, "Error in RealTimeClockUpdateTimer_Elapsed"); + } } } diff --git a/RDMSharp/RDM/IRDMDevice.cs b/RDMSharp/RDM/IRDMDevice.cs index e701273a..9cbde9ce 100644 --- a/RDMSharp/RDM/IRDMDevice.cs +++ b/RDMSharp/RDM/IRDMDevice.cs @@ -1,24 +1,24 @@ -using System; +using RDMSharp.PayloadObject; +using System; using System.Collections.Generic; using System.ComponentModel; -namespace RDMSharp +namespace RDMSharp; + +public interface IRDMDevice : IDisposable, INotifyPropertyChanged { - public interface IRDMDevice : IDisposable, INotifyPropertyChanged - { - UID UID { get; } - SubDevice Subdevice { get; } + UID UID { get; } + SubDevice Subdevice { get; } - RDMDeviceInfo DeviceInfo { get; } + RDMDeviceInfo DeviceInfo { get; } - IReadOnlyDictionary ParameterValues { get; } - IReadOnlyDictionary Sensors { get; } - IReadOnlyDictionary Slots { get; } + IReadOnlyDictionary ParameterValues { get; } + IReadOnlyDictionary Sensors { get; } + IReadOnlyDictionary Slots { get; } - bool IsDisposing { get; } - bool IsDisposed { get; } + bool IsDisposing { get; } + bool IsDisposed { get; } - bool IsInitialized { get; } - bool IsGenerated { get; } - } + bool IsInitialized { get; } + bool IsGenerated { get; } } \ No newline at end of file diff --git a/RDMSharp/RDM/IRDMDeviceModel.cs b/RDMSharp/RDM/IRDMDeviceModel.cs index 24ae8970..de3009ae 100644 --- a/RDMSharp/RDM/IRDMDeviceModel.cs +++ b/RDMSharp/RDM/IRDMDeviceModel.cs @@ -1,19 +1,29 @@ -using System; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device; +using System; using System.Collections.Generic; +using System.ComponentModel; +using static RDMSharp.AbstractRDMCache; -namespace RDMSharp +namespace RDMSharp; + +public interface IRDMDeviceModel : IDisposable { - public interface IRDMDeviceModel : IDisposable - { - IReadOnlyCollection SupportedParameters { get; } - IReadOnlyCollection SupportedBlueprintParameters { get; } - IReadOnlyCollection SupportedNonBlueprintParameters { get; } - IReadOnlyCollection KnownNotSupportedParameters { get; } - IReadOnlyCollection GetSensorDefinitions(); - IReadOnlyDictionary ParameterValues { get; } + IReadOnlyCollection GetSupportedParameters(); + IReadOnlyCollection GetSupportedBlueprintModelParameters(); + IReadOnlyCollection GetSupportedBlueprintModelPersonalityParameters(); + IReadOnlyCollection GetSupportedNonBlueprintParameters(); + IReadOnlyCollection GetKnownNotSupportedParameters(); + IReadOnlyCollection GetSensorDefinitions(); + IReadOnlyDictionary ParameterValues { get; } + + event EventHandler Initialized; + event PropertyChangedEventHandler PropertyChanged; + event EventHandler ParameterValueAdded; + + RDMDeviceInfo DeviceInfo { get; } - bool IsDisposing { get; } - bool IsDisposed { get; } - bool IsModelOf(UID uid, SubDevice subDevice, RDMDeviceInfo other); - } + bool IsDisposing { get; } + bool IsDisposed { get; } + bool IsModelOf(UID uid, SubDevice subDevice, RDMDeviceInfo other); } diff --git a/RDMSharp/RDM/Interface.cs b/RDMSharp/RDM/Interface.cs new file mode 100644 index 00000000..18b24552 --- /dev/null +++ b/RDMSharp/RDM/Interface.cs @@ -0,0 +1,295 @@ +using System; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using System.Text; + +[assembly: InternalsVisibleTo("RDMSharpTests")] +namespace RDMSharp +{ + public class Interface : INotifyPropertyChanged, IEquatable + { + public event PropertyChangedEventHandler PropertyChanged; + public event EventHandler CurrentIPChanged; + public event EventHandler StaticIPChanged; + + public readonly uint InterfaceId; + + private string lable; + public string Lable + { + get { return lable; } + private set + { + if (lable == value) + return; + + lable = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Lable))); + } + } + + private ERDM_DHCPStatusMode currentIP_DHCPStatus; + public ERDM_DHCPStatusMode CurrentIP_DHCPStatus + { + get { return currentIP_DHCPStatus; } + private set + { + if (currentIP_DHCPStatus == value) + return; + currentIP_DHCPStatus = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(CurrentIP_DHCPStatus))); + } + } + + private IPv4Address currentIP; + public IPv4Address CurrentIP + { + get { return currentIP; } + private set + { + if (currentIP == value) + return; + + currentIP = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(CurrentIP))); + } + } + + private byte currentSubnetMask; + public byte CurrentSubnetMask + { + get { return currentSubnetMask; } + private set + { + if (currentSubnetMask == value) + return; + + currentSubnetMask = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(CurrentSubnetMask))); + } + } + private IPv4Address staticIP; + public IPv4Address StaticIP + { + get { return staticIP; } + private set + { + if (staticIP == value) + return; + + staticIP = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(StaticIP))); + if (!dhcp) + { + currentIP_DHCPStatus = ERDM_DHCPStatusMode.INACTIVE; + CurrentIP = staticIP; + } + } + } + + private byte staticSubnetMask; + public byte StaticSubnetMask + { + get { return staticSubnetMask; } + private set + { + if (staticSubnetMask == value) + return; + + staticSubnetMask = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(StaticSubnetMask))); + if (!dhcp) + { + currentIP_DHCPStatus = ERDM_DHCPStatusMode.INACTIVE; + CurrentSubnetMask = staticSubnetMask; + } + } + } + + public readonly IPv4Address DefaultIP; + public readonly byte DefaultSubnetMask; + + private MACAddress macAddress; + public MACAddress MACAddress + { + get { return macAddress; } + private set + { + if (macAddress == value) + return; + + macAddress = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(MACAddress))); + } + } + + private bool dhcp; + public bool DHCP + { + get { return dhcp; } + set + { + if (dhcp == value) + return; + + dhcp = value; + if (!value) + { + CurrentIP = StaticIP; + CurrentSubnetMask = StaticSubnetMask; + } + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(DHCP))); + } + } + private bool zeroConf; + public bool ZeroConf + { + get { return zeroConf; } + set + { + if (zeroConf == value) + return; + + zeroConf = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(ZeroConf))); + } + } + + private EARP_HardwareTypes hardwareType; + public EARP_HardwareTypes HardwareType + { + get { return hardwareType; } + private set + { + if (hardwareType == value) + return; + + hardwareType = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(HardwareType))); + } + } + + public Interface(in byte interfaceId) + { + this.InterfaceId = interfaceId; + } + internal protected Interface(in byte interfaceId, + in string lable, + in IPv4Address zeroconfIp, + in byte zeroconfSubnetMask, + in MACAddress macAddress, + in EARP_HardwareTypes hardwareType) : this(interfaceId) + { + Lable = lable; + DefaultIP = zeroconfIp; + DefaultSubnetMask = zeroconfSubnetMask; + staticIP = DefaultIP; + staticSubnetMask = DefaultSubnetMask; + currentIP = StaticIP; + currentSubnetMask = StaticSubnetMask; + MACAddress = macAddress; + HardwareType = hardwareType; + dhcp = false; + zeroConf = true; + currentIP_DHCPStatus = ERDM_DHCPStatusMode.INACTIVE; + } + + public void SetStaticIP(in IPv4Address staticIP, in byte staticSubnetMask) + { + if (staticSubnetMask < 0 || staticSubnetMask > 32) + throw new ArgumentOutOfRangeException(nameof(staticSubnetMask), "Subnet mask must be between 0 and 32"); + StaticIP = staticIP; + StaticSubnetMask = staticSubnetMask; + + this.StaticIPChanged?.InvokeFailSafe(this, EventArgs.Empty); + if (!dhcp) + this.SetCurrentIP(staticIP, staticSubnetMask, false); + } + protected void SetCurrentIP(in IPv4Address currentIP, in byte currentSubnetMask, in bool isGivenByDHCP) + { + if (currentSubnetMask < 0 || currentSubnetMask > 32) + throw new ArgumentOutOfRangeException(nameof(currentSubnetMask), "Subnet mask must be between 0 and 32"); + + this.CurrentIP = currentIP; + this.CurrentSubnetMask = currentSubnetMask; + this.CurrentIP_DHCPStatus = isGivenByDHCP ? ERDM_DHCPStatusMode.ACTIVE : ERDM_DHCPStatusMode.INACTIVE; + + this.CurrentIPChanged?.InvokeFailSafe(this, EventArgs.Empty); + } + + public virtual void RenewDHCP() + { + } + + public virtual void ReleaseDHCP() + { + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"Interface: {this.InterfaceId}"); + sb.AppendLine($"Lable: {this.Lable}"); + sb.AppendLine($"CurrentIP: {this.CurrentIP}/{this.CurrentSubnetMask}"); + sb.AppendLine($"MACAddress: {this.MACAddress}"); + sb.AppendLine($"DHCP: {this.DHCP}"); + sb.AppendLine($"ZeroConf: {this.ZeroConf}"); + + return sb.ToString(); + } + + public override bool Equals(object obj) + { + return Equals(obj as Sensor); + } + + public bool Equals(Interface other) + { + return other is not null && + InterfaceId == other.InterfaceId && + Lable == other.Lable && + DefaultIP == other.DefaultIP && + DefaultSubnetMask == other.DefaultSubnetMask && + StaticIP == other.StaticIP && + StaticSubnetMask == other.StaticSubnetMask && + CurrentIP == other.CurrentIP && + CurrentSubnetMask == other.CurrentSubnetMask && + MACAddress == other.MACAddress && + DHCP == other.DHCP && + ZeroConf == other.ZeroConf; + } + + public override int GetHashCode() + { +#if !NETSTANDARD + HashCode hash = new HashCode(); + hash.Add(InterfaceId); + hash.Add(Lable); + hash.Add(DefaultIP); + hash.Add(DefaultSubnetMask); + hash.Add(StaticIP); + hash.Add(StaticSubnetMask); + hash.Add(CurrentIP); + hash.Add(CurrentSubnetMask); + hash.Add(MACAddress); + hash.Add(DHCP); + hash.Add(ZeroConf); + return hash.ToHashCode(); +#else + int hashCode = 1916557166; + hashCode = hashCode * -1521134295 + InterfaceId.GetHashCode(); + hashCode = hashCode * -1521134295 + Lable.GetHashCode(); + hashCode = hashCode * -1521134295 + DefaultIP.GetHashCode(); + hashCode = hashCode * -1521134295 + DefaultSubnetMask.GetHashCode(); + hashCode = hashCode * -1521134295 + StaticIP.GetHashCode(); + hashCode = hashCode * -1521134295 + StaticSubnetMask.GetHashCode(); + hashCode = hashCode * -1521134295 + CurrentIP.GetHashCode(); + hashCode = hashCode * -1521134295 + CurrentSubnetMask.GetHashCode(); + hashCode = hashCode * -1521134295 + MACAddress.GetHashCode(); + hashCode = hashCode * -1521134295 + DHCP.GetHashCode(); + hashCode = hashCode * -1521134295 + ZeroConf.GetHashCode(); + return hashCode; +#endif + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/Logging.cs b/RDMSharp/RDM/Logging.cs index cc340be0..b6184d3c 100644 --- a/RDMSharp/RDM/Logging.cs +++ b/RDMSharp/RDM/Logging.cs @@ -1,36 +1,39 @@ using Microsoft.Extensions.Logging; using System; -namespace RDMSharp +namespace RDMSharp; + +[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2254:Vorlage muss ein statischer Ausdruck sein", Justification = "")] +public static class Logging { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2254:Vorlage muss ein statischer Ausdruck sein", Justification = "")] - public static class Logging + private static ILoggerFactory loggerFactory; + public static ILoggerFactory LoggerFactory { - private static ILoggerFactory loggerFactory; - public static ILoggerFactory LoggerFactory + get { - get - { - return loggerFactory ??= Microsoft.Extensions.Logging.LoggerFactory.Create((builder) => - { - }); - } - set + return loggerFactory ??= Microsoft.Extensions.Logging.LoggerFactory.Create((builder) => { - if (loggerFactory != null) - throw new InvalidOperationException("LoggerFactory is already set. It can only be set once."); - loggerFactory = value; - } + //builder + //.ClearProviders() + //.AddConsole(options => { options.TimestampFormat = "[HH:mm:ss.fff] "; }) + //.SetMinimumLevel(LogLevel.Trace); + }); + } + set + { + if (loggerFactory != null) + throw new InvalidOperationException("LoggerFactory is already set. It can only be set once."); + loggerFactory = value; } - internal static ILogger CreateLogger() => LoggerFactory.CreateLogger(); - internal static ILogger CreateLogger(Type type) => LoggerFactory.CreateLogger(type); - internal static ILogger CreateLogger(string categoryName) => LoggerFactory.CreateLogger(categoryName); - - public static void LogTrace(this ILogger logger, Exception exception) => logger?.LogTrace(exception, message: string.Empty); - public static void LogDebug(this ILogger logger, Exception exception) => logger?.LogDebug(exception, message: string.Empty); - public static void LogInformation(this ILogger logger, Exception exception) => logger?.LogInformation(exception, message: string.Empty); - public static void LogWarning(this ILogger logger, Exception exception) => logger?.LogWarning(exception, message: string.Empty); - public static void LogError(this ILogger logger, Exception exception) => logger?.LogError(exception, message: string.Empty); - public static void LogCritical(this ILogger logger, Exception exception) => logger?.LogCritical(exception, message: string.Empty); } + internal static ILogger CreateLogger() => LoggerFactory.CreateLogger(); + internal static ILogger CreateLogger(Type type) => LoggerFactory.CreateLogger(type); + internal static ILogger CreateLogger(string categoryName) => LoggerFactory.CreateLogger(categoryName); + + public static void LogTrace(this ILogger logger, Exception exception) => logger?.LogTrace(exception, message: string.Empty); + public static void LogDebug(this ILogger logger, Exception exception) => logger?.LogDebug(exception, message: string.Empty); + public static void LogInformation(this ILogger logger, Exception exception) => logger?.LogInformation(exception, message: string.Empty); + public static void LogWarning(this ILogger logger, Exception exception) => logger?.LogWarning(exception, message: string.Empty); + public static void LogError(this ILogger logger, Exception exception) => logger?.LogError(exception, message: string.Empty); + public static void LogCritical(this ILogger logger, Exception exception) => logger?.LogCritical(exception, message: string.Empty); } diff --git a/RDMSharp/RDM/ParameterGroupAttribute.cs b/RDMSharp/RDM/ParameterGroupAttribute.cs index 878eb05d..6f7c89f6 100644 --- a/RDMSharp/RDM/ParameterGroupAttribute.cs +++ b/RDMSharp/RDM/ParameterGroupAttribute.cs @@ -16,4 +16,4 @@ public override string ToString() { return Name; } -} \ No newline at end of file +} diff --git a/RDMSharp/RDM/ParameterUpdateTimeAttribute.cs b/RDMSharp/RDM/ParameterUpdateTimeAttribute.cs new file mode 100644 index 00000000..169faa79 --- /dev/null +++ b/RDMSharp/RDM/ParameterUpdateTimeAttribute.cs @@ -0,0 +1,19 @@ +using System; + +namespace RDMSharp.Metadata; + +[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] +public class ParameterUpdateTimeAttribute : Attribute +{ + public readonly int Milliseconds; + + public ParameterUpdateTimeAttribute(int milliseconds) + { + Milliseconds = milliseconds; + } + + public override string ToString() + { + return $"{Milliseconds}ms"; + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/AbstractRDMPayloadObject.cs b/RDMSharp/RDM/PayloadObject/AbstractRDMPayloadObject.cs index d6f71951..15725142 100644 --- a/RDMSharp/RDM/PayloadObject/AbstractRDMPayloadObject.cs +++ b/RDMSharp/RDM/PayloadObject/AbstractRDMPayloadObject.cs @@ -1,37 +1,36 @@ using System; using System.Linq; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +public abstract class AbstractRDMPayloadObject : IRDMPayloadObject, IEquatable { - public abstract class AbstractRDMPayloadObject : IRDMPayloadObject, IEquatable - { - public abstract byte[] ToPayloadData(); + public abstract byte[] ToPayloadData(); - public override sealed bool Equals(object obj) - { - if (ReferenceEquals(obj, null)) return false; + public override sealed bool Equals(object obj) + { + if (ReferenceEquals(obj, null)) return false; - return obj is IRDMPayloadObject o - && o.GetType() == this.GetType() - && o.ToPayloadData().SequenceEqual(ToPayloadData()); - } + return obj is IRDMPayloadObject o + && o.GetType() == this.GetType() + && o.ToPayloadData().SequenceEqual(ToPayloadData()); + } - public override sealed int GetHashCode() - { - return ToPayloadData().GenerateHashCode(); - } - - public bool Equals(IRDMPayloadObject other) - { - return other.Equals(this); - } + public override sealed int GetHashCode() + { + return ToPayloadData().GenerateHashCode(); } - public abstract class AbstractRDMPayloadObjectOneOf : AbstractRDMPayloadObject, IRDMPayloadObjectOneOf + + public bool Equals(IRDMPayloadObject other) { - public abstract Type IndexType { get; } - public abstract object MinIndex { get; } - public abstract object Index { get; } - public abstract object Count { get; } - public abstract ERDM_Parameter DescriptorParameter { get; } + return other.Equals(this); } -} +} +public abstract class AbstractRDMPayloadObjectOneOf : AbstractRDMPayloadObject, IRDMPayloadObjectOneOf +{ + public abstract Type IndexType { get; } + public abstract object MinIndex { get; } + public abstract object Index { get; } + public abstract object Count { get; } + public abstract ERDM_Parameter DescriptorParameter { get; } +} diff --git a/RDMSharp/RDM/PayloadObject/AcknowledgeTimer.cs b/RDMSharp/RDM/PayloadObject/AcknowledgeTimer.cs index c395b0cc..207c9722 100644 --- a/RDMSharp/RDM/PayloadObject/AcknowledgeTimer.cs +++ b/RDMSharp/RDM/PayloadObject/AcknowledgeTimer.cs @@ -1,57 +1,56 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +public interface IAcknowledgeTimer +{ + public TimeSpan EstimidatedResponseTime { get; } +} +public class AcknowledgeTimer : AbstractRDMPayloadObject, IAcknowledgeTimer { - public interface IAcknowledgeTimer - { - public TimeSpan EstimidatedResponseTime { get; } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2208")] + public AcknowledgeTimer( + TimeSpan estimidatedResponseTime = default) : this((ushort)(estimidatedResponseTime.TotalSeconds * 10.0)) + { + if (estimidatedResponseTime.TotalSeconds / 10 > ushort.MaxValue) + throw new ArgumentOutOfRangeException("The Timer is to long for the Resolution of 16-bit ushort"); + } + private AcknowledgeTimer( + ushort _estimidatedResponseTimeRaw = default) + { + this.estimidatedResponseTimeRaw = _estimidatedResponseTimeRaw; + this.EstimidatedResponseTime = TimeSpan.FromSeconds(this.estimidatedResponseTimeRaw / 10.0); + } + + public TimeSpan EstimidatedResponseTime { get; private set; } + private readonly ushort estimidatedResponseTimeRaw; + public const int PDL = 2; + + public override string ToString() + { + return $"AcknowledgeTimer: {EstimidatedResponseTime}"; + } + + public static AcknowledgeTimer FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, new ERDM_Parameter[0], PDL); + if (msg.ResponseType != ERDM_ResponseType.ACK_TIMER) throw new Exception($"ResponseType is not {ERDM_ResponseType.ACK_TIMER}"); + + return FromPayloadData(msg.ParameterData); + } + public static AcknowledgeTimer FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + + var i = new AcknowledgeTimer(Tools.DataToUShort(ref data)); + + return i; } - public class AcknowledgeTimer : AbstractRDMPayloadObject, IAcknowledgeTimer + public override byte[] ToPayloadData() { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2208")] - public AcknowledgeTimer( - TimeSpan estimidatedResponseTime = default) : this((ushort)(estimidatedResponseTime.TotalSeconds * 10.0)) - { - if (estimidatedResponseTime.TotalSeconds / 10 > ushort.MaxValue) - throw new ArgumentOutOfRangeException("The Timer is to long for the Resolution of 16-bit ushort"); - } - private AcknowledgeTimer( - ushort _estimidatedResponseTimeRaw = default) - { - this.estimidatedResponseTimeRaw = _estimidatedResponseTimeRaw; - this.EstimidatedResponseTime = TimeSpan.FromSeconds(this.estimidatedResponseTimeRaw / 10.0); - } - - public TimeSpan EstimidatedResponseTime { get; private set; } - private readonly ushort estimidatedResponseTimeRaw; - public const int PDL = 2; - - public override string ToString() - { - return $"AcknowledgeTimer: {EstimidatedResponseTime}"; - } - - public static AcknowledgeTimer FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, new ERDM_Parameter[0], PDL); - if (msg.ResponseType != ERDM_ResponseType.ACK_TIMER) throw new Exception($"ResponseType is not {ERDM_ResponseType.ACK_TIMER}"); - - return FromPayloadData(msg.ParameterData); - } - public static AcknowledgeTimer FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new AcknowledgeTimer(Tools.DataToUShort(ref data)); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.estimidatedResponseTimeRaw)); - return data.ToArray(); - } + List data = new List(); + data.AddRange(Tools.ValueToData(this.estimidatedResponseTimeRaw)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/AcknowledgeTimerHighRes.cs b/RDMSharp/RDM/PayloadObject/AcknowledgeTimerHighRes.cs index cea59347..2cb711bd 100644 --- a/RDMSharp/RDM/PayloadObject/AcknowledgeTimerHighRes.cs +++ b/RDMSharp/RDM/PayloadObject/AcknowledgeTimerHighRes.cs @@ -1,53 +1,52 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +public class AcknowledgeTimerHighRes : AbstractRDMPayloadObject, IAcknowledgeTimer { - public class AcknowledgeTimerHighRes : AbstractRDMPayloadObject, IAcknowledgeTimer + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2208")] + public AcknowledgeTimerHighRes( + TimeSpan estimidatedResponseTime = default) : this((ushort)(estimidatedResponseTime.TotalSeconds * 1000.0)) + { + if (estimidatedResponseTime.TotalSeconds / 10 > ushort.MaxValue) + throw new ArgumentOutOfRangeException("The Timer is to long for the Resolution of 16-bit ushort"); + } + private AcknowledgeTimerHighRes( + ushort _estimidatedResponseTimeRaw = default) + { + this.estimidatedResponseTimeRaw = _estimidatedResponseTimeRaw; + this.EstimidatedResponseTime = TimeSpan.FromSeconds(this.estimidatedResponseTimeRaw / 1000.0); + } + + public TimeSpan EstimidatedResponseTime { get; private set; } + private readonly ushort estimidatedResponseTimeRaw; + public const int PDL = 2; + + public override string ToString() + { + return $"AcknowledgeTimerHighRes: {EstimidatedResponseTime}"; + } + + public static AcknowledgeTimerHighRes FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, new ERDM_Parameter[0], PDL); + if (msg.ResponseType != ERDM_ResponseType.ACK_TIMER_HI_RES) throw new Exception($"ResponseType is not {ERDM_ResponseType.ACK_TIMER_HI_RES}"); + + return FromPayloadData(msg.ParameterData); + } + public static AcknowledgeTimerHighRes FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + + var i = new AcknowledgeTimerHighRes(Tools.DataToUShort(ref data)); + + return i; + } + public override byte[] ToPayloadData() { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2208")] - public AcknowledgeTimerHighRes( - TimeSpan estimidatedResponseTime = default) : this((ushort)(estimidatedResponseTime.TotalSeconds * 1000.0)) - { - if (estimidatedResponseTime.TotalSeconds / 10 > ushort.MaxValue) - throw new ArgumentOutOfRangeException("The Timer is to long for the Resolution of 16-bit ushort"); - } - private AcknowledgeTimerHighRes( - ushort _estimidatedResponseTimeRaw = default) - { - this.estimidatedResponseTimeRaw = _estimidatedResponseTimeRaw; - this.EstimidatedResponseTime = TimeSpan.FromSeconds(this.estimidatedResponseTimeRaw / 1000.0); - } - - public TimeSpan EstimidatedResponseTime { get; private set; } - private readonly ushort estimidatedResponseTimeRaw; - public const int PDL = 2; - - public override string ToString() - { - return $"AcknowledgeTimerHighRes: {EstimidatedResponseTime}"; - } - - public static AcknowledgeTimerHighRes FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, new ERDM_Parameter[0], PDL); - if (msg.ResponseType != ERDM_ResponseType.ACK_TIMER_HI_RES) throw new Exception($"ResponseType is not {ERDM_ResponseType.ACK_TIMER_HI_RES}"); - - return FromPayloadData(msg.ParameterData); - } - public static AcknowledgeTimerHighRes FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new AcknowledgeTimerHighRes(Tools.DataToUShort(ref data)); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.estimidatedResponseTimeRaw)); - return data.ToArray(); - } + List data = new List(); + data.AddRange(Tools.ValueToData(this.estimidatedResponseTimeRaw)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/DiscMuteUnmuteResponse.cs b/RDMSharp/RDM/PayloadObject/DiscMuteUnmuteResponse.cs index cf5fc546..672161d8 100644 --- a/RDMSharp/RDM/PayloadObject/DiscMuteUnmuteResponse.cs +++ b/RDMSharp/RDM/PayloadObject/DiscMuteUnmuteResponse.cs @@ -1,83 +1,82 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +public class DiscMuteUnmuteResponse : AbstractRDMPayloadObject { - public class DiscMuteUnmuteResponse : AbstractRDMPayloadObject + public DiscMuteUnmuteResponse( + bool managedProxyFlag = false, + bool subDeviceFlag = false, + bool bootLoaderFlag = false, + bool proxiedDeviceFlag = false, + UID? bindingUID = null) { - public DiscMuteUnmuteResponse( - bool managedProxyFlag = false, - bool subDeviceFlag = false, - bool bootLoaderFlag = false, - bool proxiedDeviceFlag = false, - UID? bindingUID = null) - { - ManagedProxyFlag = managedProxyFlag; - SubDeviceFlag = subDeviceFlag; - BootLoaderFlag = bootLoaderFlag; - ProxiedDeviceFlag = proxiedDeviceFlag; - BindingUID = bindingUID; - } + ManagedProxyFlag = managedProxyFlag; + SubDeviceFlag = subDeviceFlag; + BootLoaderFlag = bootLoaderFlag; + ProxiedDeviceFlag = proxiedDeviceFlag; + BindingUID = bindingUID; + } - /// - /// The Managed Proxy Flag (Bit 0) shall be set to 1 when the responder is a Proxy device. See Section 8 for information on Proxy Devices. - /// - public bool ManagedProxyFlag { get; private set; } - /// - /// The Sub-Device Flag (Bit 1) shall be set to 1 when the responder supports Sub-Devices. See Section 9 for information on Sub-Devices. - /// - public bool SubDeviceFlag { get; private set; } - /// - /// The Boot-Loader Flag (Bit 2) shall only be set to 1 when the device is incapable of normal operation until receiving a firmware upload. It is expected that when in this Boot-Loader mode the device will be capable of very limited RDM communication. The process of uploading firmware is beyond the scope of this document. - /// - public bool BootLoaderFlag { get; private set; } - /// - /// The Proxied Device Flag (Bit 3) shall only be set to 1 when a Proxy is responding to Discovery on behalf of another device.This flag indicates that the response has come from a Proxy, rather than the actual device. - /// - public bool ProxiedDeviceFlag { get; private set; } + /// + /// The Managed Proxy Flag (Bit 0) shall be set to 1 when the responder is a Proxy device. See Section 8 for information on Proxy Devices. + /// + public bool ManagedProxyFlag { get; private set; } + /// + /// The Sub-Device Flag (Bit 1) shall be set to 1 when the responder supports Sub-Devices. See Section 9 for information on Sub-Devices. + /// + public bool SubDeviceFlag { get; private set; } + /// + /// The Boot-Loader Flag (Bit 2) shall only be set to 1 when the device is incapable of normal operation until receiving a firmware upload. It is expected that when in this Boot-Loader mode the device will be capable of very limited RDM communication. The process of uploading firmware is beyond the scope of this document. + /// + public bool BootLoaderFlag { get; private set; } + /// + /// The Proxied Device Flag (Bit 3) shall only be set to 1 when a Proxy is responding to Discovery on behalf of another device.This flag indicates that the response has come from a Proxy, rather than the actual device. + /// + public bool ProxiedDeviceFlag { get; private set; } - public UID? BindingUID { get; private set; } = null; + public UID? BindingUID { get; private set; } = null; - public const int PDL = 2; - public const int PDLWithBindUID = 8; + public const int PDL = 2; + public const int PDLWithBindUID = 8; - public override string ToString() - { - if (BindingUID.HasValue) - return $"DiscMuteUnmuteResponse:{Environment.NewLine}ManagedProxyFlag: {ManagedProxyFlag}{Environment.NewLine}SubDeviceFlag: {SubDeviceFlag}{Environment.NewLine}BootLoaderFlag: {BootLoaderFlag}{Environment.NewLine}ProxiedDeviceFlag: {ProxiedDeviceFlag}{Environment.NewLine}BindingUID: {BindingUID}"; - return $"DiscMuteUnmuteResponse:{Environment.NewLine}ManagedProxyFlag: {ManagedProxyFlag}{Environment.NewLine}SubDeviceFlag: {SubDeviceFlag}{Environment.NewLine}BootLoaderFlag: {BootLoaderFlag}{Environment.NewLine}ProxiedDeviceFlag: {ProxiedDeviceFlag}"; - } - public static DiscMuteUnmuteResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.DISCOVERY_COMMAND_RESPONSE, new ERDM_Parameter[] { ERDM_Parameter.DISC_MUTE, ERDM_Parameter.DISC_UN_MUTE }, PDL, PDLWithBindUID); + public override string ToString() + { + if (BindingUID.HasValue) + return $"DiscMuteUnmuteResponse:{Environment.NewLine}ManagedProxyFlag: {ManagedProxyFlag}{Environment.NewLine}SubDeviceFlag: {SubDeviceFlag}{Environment.NewLine}BootLoaderFlag: {BootLoaderFlag}{Environment.NewLine}ProxiedDeviceFlag: {ProxiedDeviceFlag}{Environment.NewLine}BindingUID: {BindingUID}"; + return $"DiscMuteUnmuteResponse:{Environment.NewLine}ManagedProxyFlag: {ManagedProxyFlag}{Environment.NewLine}SubDeviceFlag: {SubDeviceFlag}{Environment.NewLine}BootLoaderFlag: {BootLoaderFlag}{Environment.NewLine}ProxiedDeviceFlag: {ProxiedDeviceFlag}"; + } + public static DiscMuteUnmuteResponse FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.DISCOVERY_COMMAND_RESPONSE, new ERDM_Parameter[] { ERDM_Parameter.DISC_MUTE, ERDM_Parameter.DISC_UN_MUTE }, PDL, PDLWithBindUID); - return FromPayloadData(msg.ParameterData); - } - public static DiscMuteUnmuteResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL, PDLWithBindUID); + return FromPayloadData(msg.ParameterData); + } + public static DiscMuteUnmuteResponse FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL, PDLWithBindUID); - bool[] boolArray = Tools.DataToBoolArray(ref data, 16); - UID? uid = null; - if (data.Length == PDLWithBindUID - PDL) - uid = Tools.DataToRDMUID(ref data); - var i = new DiscMuteUnmuteResponse( - managedProxyFlag: boolArray[0], - subDeviceFlag: boolArray[1], - bootLoaderFlag: boolArray[2], - proxiedDeviceFlag: boolArray[3], - bindingUID: uid); + bool[] boolArray = Tools.DataToBoolArray(ref data, 16); + UID? uid = null; + if (data.Length == PDLWithBindUID - PDL) + uid = Tools.DataToRDMUID(ref data); + var i = new DiscMuteUnmuteResponse( + managedProxyFlag: boolArray[0], + subDeviceFlag: boolArray[1], + bootLoaderFlag: boolArray[2], + proxiedDeviceFlag: boolArray[3], + bindingUID: uid); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.ManagedProxyFlag, this.SubDeviceFlag, this.BootLoaderFlag, this.ProxiedDeviceFlag)); - while (data.Count < 2) { data.Add(new byte()); } - if (BindingUID.HasValue) - data.AddRange(Tools.ValueToData(this.BindingUID)); - return data.ToArray(); - } + return i; + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.ManagedProxyFlag, this.SubDeviceFlag, this.BootLoaderFlag, this.ProxiedDeviceFlag)); + while (data.Count < 2) { data.Add(new byte()); } + if (BindingUID.HasValue) + data.AddRange(Tools.ValueToData(this.BindingUID)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/DiscUniqueBranchRequest.cs b/RDMSharp/RDM/PayloadObject/DiscUniqueBranchRequest.cs index 5af53b8e..aa1e370b 100644 --- a/RDMSharp/RDM/PayloadObject/DiscUniqueBranchRequest.cs +++ b/RDMSharp/RDM/PayloadObject/DiscUniqueBranchRequest.cs @@ -1,45 +1,44 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +public class DiscUniqueBranchRequest : AbstractRDMPayloadObject { - public class DiscUniqueBranchRequest : AbstractRDMPayloadObject + public DiscUniqueBranchRequest(in UID startUid, in UID endUid) + { + StartUid = startUid; + EndUid = endUid; + } + + public UID StartUid { get; private set; } + public UID EndUid { get; private set; } + + public const int PDL = 12; + + public override string ToString() + { + return $"DiscUniqueBranchRequest:{Environment.NewLine}StartUid: {StartUid}{Environment.NewLine}EndUid: {EndUid}"; + } + public static DiscUniqueBranchRequest FromMessage(RDMMessage msg) { - public DiscUniqueBranchRequest(in UID startUid, in UID endUid) - { - StartUid = startUid; - EndUid = endUid; - } - - public UID StartUid { get; private set; } - public UID EndUid { get; private set; } - - public const int PDL = 12; - - public override string ToString() - { - return $"DiscUniqueBranchRequest:{Environment.NewLine}StartUid: {StartUid}{Environment.NewLine}EndUid: {EndUid}"; - } - public static DiscUniqueBranchRequest FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.DISCOVERY_COMMAND, ERDM_Parameter.DISC_UNIQUE_BRANCH, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static DiscUniqueBranchRequest FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new DiscUniqueBranchRequest(Tools.DataToRDMUID(ref data), Tools.DataToRDMUID(ref data)); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - - data.AddRange(Tools.ValueToData(this.StartUid)); - data.AddRange(Tools.ValueToData(this.EndUid)); - return data.ToArray(); - } + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.DISCOVERY_COMMAND, ERDM_Parameter.DISC_UNIQUE_BRANCH, PDL); + + return FromPayloadData(msg.ParameterData); + } + public static DiscUniqueBranchRequest FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + var i = new DiscUniqueBranchRequest(Tools.DataToRDMUID(ref data), Tools.DataToRDMUID(ref data)); + + return i; + } + public override byte[] ToPayloadData() + { + List data = new List(); + + data.AddRange(Tools.ValueToData(this.StartUid)); + data.AddRange(Tools.ValueToData(this.EndUid)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/EndpointDescriptor.cs b/RDMSharp/RDM/PayloadObject/EndpointDescriptor.cs new file mode 100644 index 00000000..06a9dd3c --- /dev/null +++ b/RDMSharp/RDM/PayloadObject/EndpointDescriptor.cs @@ -0,0 +1,41 @@ +using RDMSharp.Metadata; +using System.Collections.Generic; + +namespace RDMSharp.PayloadObject; + +public class EndpointDescriptor : AbstractRDMPayloadObject +{ + [DataTreeObjectConstructor] + public EndpointDescriptor( + [DataTreeObjectParameter("id")] ushort endpointId = 0, + [DataTreeObjectParameter("type")] byte endpointType = 0) : this(endpointId, (ERDM_EndpointType)endpointType) + { + } + + public EndpointDescriptor(ushort endpointId = 0, ERDM_EndpointType endpointType = 0) + { + this.EndpointId = endpointId; + this.EndpointType = endpointType; + } + + + [DataTreeObjectProperty("id", 0)] + public ushort EndpointId { get; private set; } + + [DataTreeObjectProperty("type", 1)] + public ERDM_EndpointType EndpointType { get; private set; } + + public const int PDL = 3; + + public override string ToString() + { + return $"Id: {EndpointId} EndpointType: {EndpointType}"; + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.EndpointType)); + return data.ToArray(); + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponse.cs b/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponse.cs index d45b2216..31fb6054 100644 --- a/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponse.cs @@ -2,65 +2,49 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, Command.ECommandDublicate.GetResponse)] +public class GetBackgroundQueuedStatusPolicyDescriptionResponse : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription { - [DataTreeObject(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, Command.ECommandDublicate.GetResponse)] - public class GetBackgroundQueuedStatusPolicyDescriptionResponse : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription - { - [DataTreeObjectConstructor] - public GetBackgroundQueuedStatusPolicyDescriptionResponse( - [DataTreeObjectParameter("policy")] byte policyId = 1, - [DataTreeObjectParameter("description")] string description = default) - { - this.PolicyId = policyId; + [DataTreeObjectConstructor] + public GetBackgroundQueuedStatusPolicyDescriptionResponse( + [DataTreeObjectParameter("policy")] byte policyId = 1, + [DataTreeObjectParameter("description")] string description = default) + { + this.PolicyId = policyId; - if (string.IsNullOrWhiteSpace(description)) - return; + if (string.IsNullOrWhiteSpace(description)) + return; - if (description.Length > 32) - description = description.Substring(0, 32); + if (description.Length > 32) + description = description.Substring(0, 32); - this.Description = description; - } + this.Description = description; + } - public ERDM_PolicyType Policy { get { return (ERDM_PolicyType)PolicyId; } } - [DataTreeObjectProperty("policy", 0)] - public byte PolicyId { get; private set; } - [DataTreeObjectProperty("description", 1)] - public string Description { get; private set; } + public ERDM_PolicyType Policy { get { return (ERDM_PolicyType)PolicyId; } } + [DataTreeObjectProperty("policy", 0)] + public byte PolicyId { get; private set; } + [DataTreeObjectProperty("description", 1)] + public string Description { get; private set; } - public object MinIndex => (byte)1; - public object Index => PolicyId; + public object MinIndex => (byte)1; + public object Index => PolicyId; - public const int PDL_MIN = 0x01; - public const int PDL_MAX = PDL_MIN + 32; - - public override string ToString() - { - return $"Policy: {Policy} - Description: {Description}"; - } - public static GetBackgroundQueuedStatusPolicyDescriptionResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, PDL_MIN, PDL_MAX); + public const int PDL_MIN = 0x01; + public const int PDL_MAX = PDL_MIN + 32; - return FromPayloadData(msg.ParameterData); - } - public static GetBackgroundQueuedStatusPolicyDescriptionResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - - var i = new GetBackgroundQueuedStatusPolicyDescriptionResponse( - policyId: Tools.DataToByte(ref data), - description: Tools.DataToString(ref data)); + public override string ToString() + { + return $"Policy: {Policy} - Description: {Description}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.PolicyId)); - data.AddRange(Tools.ValueToData(this.Description)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.PolicyId)); + data.AddRange(Tools.ValueToData(this.Description)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponse.cs b/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponse.cs index 4e074c7e..27ee709d 100644 --- a/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponse.cs @@ -3,63 +3,48 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, Command.ECommandDublicate.GetResponse)] +public class GetBackgroundQueuedStatusPolicyResponse : AbstractRDMPayloadObjectOneOf { - [DataTreeObject(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, Command.ECommandDublicate.GetResponse)] - public class GetBackgroundQueuedStatusPolicyResponse : AbstractRDMPayloadObjectOneOf - { - [DataTreeObjectConstructor] - public GetBackgroundQueuedStatusPolicyResponse( - [DataTreeObjectParameter("policy_setting")] byte policyId = 1, - [DataTreeObjectParameter("policy_setting_count")] byte policies = default) - { - this.PolicyId = policyId; - this.Policies = policies; - } + [DataTreeObjectConstructor] + public GetBackgroundQueuedStatusPolicyResponse( + [DataTreeObjectParameter("policy_setting")] byte policyId = 1, + [DataTreeObjectParameter("policy_setting_count")] byte policies = default) + { + this.PolicyId = policyId; + this.Policies = policies; + } - public ERDM_PolicyType Policy { get { return (ERDM_PolicyType)PolicyId; } } - [DataTreeObjectProperty("policy_setting", 0)] - public byte PolicyId { get; private set; } - [DataTreeObjectDependecieProperty("policy", ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("policy_setting_count", 1)] - public byte Policies { get; private set; } + public ERDM_PolicyType Policy { get { return (ERDM_PolicyType)PolicyId; } } + [DataTreeObjectProperty("policy_setting", 0)] + public byte PolicyId { get; private set; } + [DataTreeObjectDependecieProperty("policy", ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("policy_setting_count", 1)] + public byte Policies { get; private set; } - public override Type IndexType => typeof(byte); + public override Type IndexType => typeof(byte); - public override object MinIndex => (byte)1; - public override object Index => PolicyId; + public override object MinIndex => (byte)1; + public override object Index => PolicyId; - public override object Count => Policies; + public override object Count => Policies; - public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION; + public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION; - public const int PDL = 2; + public const int PDL = 2; - public override string ToString() - { - return $"Policy: {Policy} of {Policies}"; - } - public static GetBackgroundQueuedStatusPolicyResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetBackgroundQueuedStatusPolicyResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new GetBackgroundQueuedStatusPolicyResponse( - policyId: Tools.DataToByte(ref data), - policies: Tools.DataToByte(ref data)); + public override string ToString() + { + return $"Policy: {Policy} of {Policies}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.PolicyId)); - data.AddRange(Tools.ValueToData(this.Policies)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.PolicyId)); + data.AddRange(Tools.ValueToData(this.Policies)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsRequest.cs b/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsRequest.cs index 5a8323c6..900caf10 100644 --- a/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsRequest.cs +++ b/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsRequest.cs @@ -2,54 +2,36 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.BINDING_CONTROL_FIELDS, Command.ECommandDublicate.GetRequest)] +public class GetBindingAndControlFieldsRequest : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.BINDING_CONTROL_FIELDS, Command.ECommandDublicate.GetRequest)] - public class GetBindingAndControlFieldsRequest : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetBindingAndControlFieldsRequest( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("uid")] UID uid = default) { - [DataTreeObjectConstructor] - public GetBindingAndControlFieldsRequest( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, - [DataTreeObjectParameter("uid")] UID uid = default) - { - this.EndpointId = endpointId; - this.UID = uid; - } - - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("uid", 1)] - public UID UID { get; private set; } - public const int PDL = 0x08; - - public override string ToString() - { - return $"Endpoint: {EndpointId} - UID: {UID}"; - } - - public static GetBindingAndControlFieldsRequest FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND, ERDM_Parameter.BINDING_CONTROL_FIELDS, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetBindingAndControlFieldsRequest FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + this.EndpointId = endpointId; + this.UID = uid; + } - var i = new GetBindingAndControlFieldsRequest( - endpointId: Tools.DataToUShort(ref data), - uid: Tools.DataToRDMUID(ref data)); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("uid", 1)] + public UID UID { get; private set; } + public const int PDL = 0x08; - return i; - } + public override string ToString() + { + return $"Endpoint: {EndpointId} - UID: {UID}"; + } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.UID)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.UID)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsResponse.cs b/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsResponse.cs index f0bf03c8..b6974cb5 100644 --- a/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsResponse.cs @@ -2,65 +2,45 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.BINDING_CONTROL_FIELDS, Command.ECommandDublicate.GetResponse)] +public class GetBindingAndControlFieldsResponse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.BINDING_CONTROL_FIELDS, Command.ECommandDublicate.GetResponse)] - public class GetBindingAndControlFieldsResponse : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetBindingAndControlFieldsResponse( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("uid")] UID uid = default, + [DataTreeObjectParameter("control")] ushort controlField = default, + [DataTreeObjectParameter("binding_uid")] UID bindingUID = default) { - [DataTreeObjectConstructor] - public GetBindingAndControlFieldsResponse( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, - [DataTreeObjectParameter("uid")] UID uid = default, - [DataTreeObjectParameter("control")] ushort controlField = default, - [DataTreeObjectParameter("binding_uid")] UID bindingUID = default) - { - this.EndpointId = endpointId; - this.UID = uid; - this.ControlField = controlField; - this.BindingUID = bindingUID; - } - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("uid", 1)] - public UID UID { get; private set; } - [DataTreeObjectProperty("control", 2)] - public ushort ControlField { get; private set; } - [DataTreeObjectProperty("binding_uid", 3)] - public UID BindingUID { get; private set; } - public const int PDL = 0x10; - - public override string ToString() - { - return $"Endpoint: {EndpointId} - UID: {UID} ControlField: {ControlField} BindingUID: {BindingUID}"; - } - - public static GetBindingAndControlFieldsResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.BINDING_CONTROL_FIELDS, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetBindingAndControlFieldsResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new GetBindingAndControlFieldsResponse( - endpointId: Tools.DataToUShort(ref data), - uid: Tools.DataToRDMUID(ref data), - controlField: Tools.DataToUShort(ref data), - bindingUID: Tools.DataToRDMUID(ref data)); + this.EndpointId = endpointId; + this.UID = uid; + this.ControlField = controlField; + this.BindingUID = bindingUID; + } + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("uid", 1)] + public UID UID { get; private set; } + [DataTreeObjectProperty("control", 2)] + public ushort ControlField { get; private set; } + [DataTreeObjectProperty("binding_uid", 3)] + public UID BindingUID { get; private set; } + public const int PDL = 0x10; - return i; - } + public override string ToString() + { + return $"Endpoint: {EndpointId} - UID: {UID} ControlField: {ControlField} BindingUID: {BindingUID}"; + } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.UID)); - data.AddRange(Tools.ValueToData(this.ControlField)); - data.AddRange(Tools.ValueToData(this.BindingUID)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.UID)); + data.AddRange(Tools.ValueToData(this.ControlField)); + data.AddRange(Tools.ValueToData(this.BindingUID)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetBrokerStatusResponse.cs b/RDMSharp/RDM/PayloadObject/GetBrokerStatusResponse.cs index 036e0b8d..df80bffb 100644 --- a/RDMSharp/RDM/PayloadObject/GetBrokerStatusResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetBrokerStatusResponse.cs @@ -2,53 +2,52 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.BROKER_STATUS, Command.ECommandDublicate.GetRequest)] +public class GetBrokerStatusResponse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.BROKER_STATUS, Command.ECommandDublicate.GetRequest)] - public class GetBrokerStatusResponse : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetBrokerStatusResponse( + [DataTreeObjectParameter("setAllowed")] bool setAllowed = default, + [DataTreeObjectParameter("brokerStatus")] ERDM_BrokerStatus brokerStatus = default) + { + this.SetAllowed = setAllowed; + this.BrokerStatus = brokerStatus; + } + [DataTreeObjectProperty("setAllowed", 0)] + public bool SetAllowed { get; private set; } + [DataTreeObjectProperty("brokerStatus", 1)] + public ERDM_BrokerStatus BrokerStatus { get; private set; } + public const int PDL = 0x02; + + public override string ToString() + { + return $"SetAllowed: {SetAllowed} - BrokerStatus: {BrokerStatus}"; + } + + public static GetBrokerStatusResponse FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.BROKER_STATUS, PDL); + + return FromPayloadData(msg.ParameterData); + } + public static GetBrokerStatusResponse FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + + var i = new GetBrokerStatusResponse( + setAllowed: Tools.DataToBool(ref data), + brokerStatus: Tools.DataToEnum(ref data)); + + return i; + } + + public override byte[] ToPayloadData() { - [DataTreeObjectConstructor] - public GetBrokerStatusResponse( - [DataTreeObjectParameter("setAllowed")] bool setAllowed = default, - [DataTreeObjectParameter("brokerStatus")] ERDM_BrokerStatus brokerStatus = default) - { - this.SetAllowed = setAllowed; - this.BrokerStatus = brokerStatus; - } - [DataTreeObjectProperty("setAllowed", 0)] - public bool SetAllowed { get; private set; } - [DataTreeObjectProperty("brokerStatus", 1)] - public ERDM_BrokerStatus BrokerStatus { get; private set; } - public const int PDL = 0x02; - - public override string ToString() - { - return $"SetAllowed: {SetAllowed} - BrokerStatus: {BrokerStatus}"; - } - - public static GetBrokerStatusResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.BROKER_STATUS, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetBrokerStatusResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new GetBrokerStatusResponse( - setAllowed: Tools.DataToBool(ref data), - brokerStatus: Tools.DataToEnum(ref data)); - - return i; - } - - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.SetAllowed)); - data.AddRange(Tools.ValueToData(this.BrokerStatus)); - return data.ToArray(); - } + List data = new List(); + data.AddRange(Tools.ValueToData(this.SetAllowed)); + data.AddRange(Tools.ValueToData(this.BrokerStatus)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetCommunicationStatusNullStartCodeResponse.cs b/RDMSharp/RDM/PayloadObject/GetCommunicationStatusNullStartCodeResponse.cs index d8551e3d..fbb2c4bf 100644 --- a/RDMSharp/RDM/PayloadObject/GetCommunicationStatusNullStartCodeResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetCommunicationStatusNullStartCodeResponse.cs @@ -3,147 +3,132 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.COMMS_STATUS_NSC, Command.ECommandDublicate.GetResponse)] +public class GetCommunicationStatusNullStartCodeResponse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.COMMS_STATUS_NSC, Command.ECommandDublicate.GetResponse)] - public class GetCommunicationStatusNullStartCodeResponse : AbstractRDMPayloadObject + public GetCommunicationStatusNullStartCodeResponse( + uint? additiveChecksumOfMostRecentPacket = null, + uint? packetCount = null, + ushort? mostRecentSlotCount = null, + ushort? minimumSlotCount = null, + ushort? maximumSlotCount = null, + uint? numberOfPacketsWithAnError = null) { - public GetCommunicationStatusNullStartCodeResponse( - uint? additiveChecksumOfMostRecentPacket = null, - uint? packetCount = null, - ushort? mostRecentSlotCount = null, - ushort? minimumSlotCount = null, - ushort? maximumSlotCount = null, - uint? numberOfPacketsWithAnError = null) - { - AdditiveChecksumOfMostRecentPacket = additiveChecksumOfMostRecentPacket; - PacketCount = packetCount; - MostRecentSlotCount = mostRecentSlotCount; - MinimumSlotCount = minimumSlotCount; - MaximumSlotCount = maximumSlotCount; - NumberOfPacketsWithAnError = numberOfPacketsWithAnError; - } - [DataTreeObjectConstructor] - public GetCommunicationStatusNullStartCodeResponse( - [DataTreeObjectParameter("supported")] bool[] supported, - [DataTreeObjectParameter("additive_checksum")] uint additiveChecksumOfMostRecentPacket, - [DataTreeObjectParameter("packet_count")] uint packetCount, - [DataTreeObjectParameter("most_recent_slot_count")] ushort mostRecentSlotCount, - [DataTreeObjectParameter("min_slot_count")] ushort minimumSlotCount, - [DataTreeObjectParameter("max_slot_count")] ushort maximumSlotCount, - [DataTreeObjectParameter("error_count")] uint numberOfPacketsWithAnError) - { - if (supported[0]) - AdditiveChecksumOfMostRecentPacket = additiveChecksumOfMostRecentPacket; - - if (supported[1]) - PacketCount = packetCount; - - if (supported[2]) - MostRecentSlotCount = mostRecentSlotCount; - - if (supported[3]) - MinimumSlotCount = minimumSlotCount; - - if (supported[4]) - MaximumSlotCount = maximumSlotCount; + AdditiveChecksumOfMostRecentPacket = additiveChecksumOfMostRecentPacket; + PacketCount = packetCount; + MostRecentSlotCount = mostRecentSlotCount; + MinimumSlotCount = minimumSlotCount; + MaximumSlotCount = maximumSlotCount; + NumberOfPacketsWithAnError = numberOfPacketsWithAnError; + } + [DataTreeObjectConstructor] + public GetCommunicationStatusNullStartCodeResponse( + [DataTreeObjectParameter("supported/additive_checksum")] bool additiveChecksumSupported, + [DataTreeObjectParameter("supported/packet_count")] bool packetCountSupported, + [DataTreeObjectParameter("supported/most_recent_slot_count")] bool mostRecentSlotCountSupported, + [DataTreeObjectParameter("supported/min_slot_count")] bool minSlotCountSupported, + [DataTreeObjectParameter("supported/max_slot_count")] bool maxSlotCountSupported, + [DataTreeObjectParameter("supported/error_count")] bool errorCountSupported, + [DataTreeObjectParameter("additive_checksum")] uint additiveChecksumOfMostRecentPacket, + [DataTreeObjectParameter("packet_count")] uint packetCount, + [DataTreeObjectParameter("most_recent_slot_count")] ushort mostRecentSlotCount, + [DataTreeObjectParameter("min_slot_count")] ushort minimumSlotCount, + [DataTreeObjectParameter("max_slot_count")] ushort maximumSlotCount, + [DataTreeObjectParameter("error_count")] uint numberOfPacketsWithAnError) : this( + additiveChecksumSupported ? additiveChecksumOfMostRecentPacket : null, + packetCountSupported ? packetCount : null, + mostRecentSlotCountSupported ? mostRecentSlotCount : null, + minSlotCountSupported ? minimumSlotCount : null, + maxSlotCountSupported ? maximumSlotCount : null, + errorCountSupported ? numberOfPacketsWithAnError : null + ) + { + } - if (supported[5]) - NumberOfPacketsWithAnError = numberOfPacketsWithAnError; - } + [DataTreeObjectProperty("supported/additive_checksum", 0)] + public bool AdditiveChecksumSupported + { + get => AdditiveChecksumOfMostRecentPacket is not null; + } + [DataTreeObjectProperty("supported/packet_count", 1)] + public bool PacketCountSupported + { + get => PacketCount is not null; + } + [DataTreeObjectProperty("supported/most_recent_slot_count", 2)] + public bool MostRecentSlotCountSupported + { + get => MostRecentSlotCount is not null; + } + [DataTreeObjectProperty("supported/min_slot_count", 3)] + public bool MinimumSlotCountSupported + { + get => MinimumSlotCount is not null; + } + [DataTreeObjectProperty("supported/max_slot_count", 4)] + public bool MaximumSlotCountSupported + { + get => MaximumSlotCount is not null; + } + [DataTreeObjectProperty("supported/error_count", 5)] + public bool ErrorCountSupported + { + get => NumberOfPacketsWithAnError is not null; + } - [DataTreeObjectProperty("supported", 0)] - public bool[] Supported - { - get - { - return new bool[] { - AdditiveChecksumOfMostRecentPacket is not null, - PacketCount is not null, - MostRecentSlotCount is not null, - MinimumSlotCount is not null, - MaximumSlotCount is not null, - NumberOfPacketsWithAnError is not null - }; - } - } - [DataTreeObjectProperty("additive_checksum", 1)] - public uint? AdditiveChecksumOfMostRecentPacket { get; private set; } - [DataTreeObjectProperty("packet_count", 2)] - public uint? PacketCount { get; private set; } - [DataTreeObjectProperty("most_recent_slot_count", 3)] - public ushort? MostRecentSlotCount { get; private set; } - [DataTreeObjectProperty("min_slot_count", 4)] - public ushort? MinimumSlotCount { get; private set; } - [DataTreeObjectProperty("max_slot_count", 5)] - public ushort? MaximumSlotCount { get; private set; } - [DataTreeObjectProperty("error_count", 6)] - public uint? NumberOfPacketsWithAnError { get; private set; } - public const int PDL = 0x13; - public override string ToString() - { - StringBuilder b = new StringBuilder(); - if (AdditiveChecksumOfMostRecentPacket.HasValue) - b.AppendLine($"AdditiveChecksumOfMostRecentPacket: {AdditiveChecksumOfMostRecentPacket}"); - if (PacketCount.HasValue) - b.AppendLine($"PacketCount: {PacketCount}"); - if (MostRecentSlotCount.HasValue) - b.AppendLine($"MostRecentSlotCount: {MostRecentSlotCount}"); - if (MinimumSlotCount.HasValue) - b.AppendLine($"MinimumSlotCount: {MinimumSlotCount}"); - if (MaximumSlotCount.HasValue) - b.AppendLine($"MaximumSlotCount: {MaximumSlotCount}"); - if (NumberOfPacketsWithAnError.HasValue) - b.AppendLine($"NumberOfPacketsWithAnError: {NumberOfPacketsWithAnError}"); - return b.ToString(); - } - public static GetCommunicationStatusNullStartCodeResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.COMMS_STATUS_NSC, PDL); + [DataTreeObjectProperty("additive_checksum", 1)] + public uint? AdditiveChecksumOfMostRecentPacket { get; private set; } + [DataTreeObjectProperty("packet_count", 2)] + public uint? PacketCount { get; private set; } + [DataTreeObjectProperty("most_recent_slot_count", 3)] + public ushort? MostRecentSlotCount { get; private set; } + [DataTreeObjectProperty("min_slot_count", 4)] + public ushort? MinimumSlotCount { get; private set; } + [DataTreeObjectProperty("max_slot_count", 5)] + public ushort? MaximumSlotCount { get; private set; } + [DataTreeObjectProperty("error_count", 6)] + public uint? NumberOfPacketsWithAnError { get; private set; } + public const int PDL = 0x13; - return FromPayloadData(msg.ParameterData); - } - public static GetCommunicationStatusNullStartCodeResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var flags = Tools.DataToBoolArray(ref data, 8); - var additiveChecksumOfMostRecentPacket = Tools.DataToUInt(ref data); - var packetCount = Tools.DataToUInt(ref data); - var mostRecentSlotCount = Tools.DataToUShort(ref data); - var minimumSlotCount = Tools.DataToUShort(ref data); - var maximumSlotCount = Tools.DataToUShort(ref data); - var numberOfPacketsWithAnError = Tools.DataToUInt(ref data); - var i = new GetCommunicationStatusNullStartCodeResponse( - additiveChecksumOfMostRecentPacket: flags[0] ? additiveChecksumOfMostRecentPacket : null, - packetCount: flags[1] ? packetCount : null, - mostRecentSlotCount: flags[2] ? mostRecentSlotCount : null, - minimumSlotCount: flags[3] ? minimumSlotCount : null, - maximumSlotCount: flags[4] ? maximumSlotCount : null, - numberOfPacketsWithAnError: flags[5] ? numberOfPacketsWithAnError : null - ); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + if (AdditiveChecksumOfMostRecentPacket.HasValue) + b.AppendLine($"AdditiveChecksumOfMostRecentPacket: {AdditiveChecksumOfMostRecentPacket}"); + if (PacketCount.HasValue) + b.AppendLine($"PacketCount: {PacketCount}"); + if (MostRecentSlotCount.HasValue) + b.AppendLine($"MostRecentSlotCount: {MostRecentSlotCount}"); + if (MinimumSlotCount.HasValue) + b.AppendLine($"MinimumSlotCount: {MinimumSlotCount}"); + if (MaximumSlotCount.HasValue) + b.AppendLine($"MaximumSlotCount: {MaximumSlotCount}"); + if (NumberOfPacketsWithAnError.HasValue) + b.AppendLine($"NumberOfPacketsWithAnError: {NumberOfPacketsWithAnError}"); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData( - this.AdditiveChecksumOfMostRecentPacket.HasValue, - this.PacketCount.HasValue, - this.MostRecentSlotCount.HasValue, - this.MinimumSlotCount.HasValue, - this.MaximumSlotCount.HasValue, - this.NumberOfPacketsWithAnError.HasValue, - false, - false)); - data.AddRange(Tools.ValueToData(this.AdditiveChecksumOfMostRecentPacket)); - data.AddRange(Tools.ValueToData(this.PacketCount)); - data.AddRange(Tools.ValueToData(this.MostRecentSlotCount)); - data.AddRange(Tools.ValueToData(this.MinimumSlotCount)); - data.AddRange(Tools.ValueToData(this.MaximumSlotCount)); - data.AddRange(Tools.ValueToData(this.NumberOfPacketsWithAnError)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData( + this.AdditiveChecksumOfMostRecentPacket.HasValue, + this.PacketCount.HasValue, + this.MostRecentSlotCount.HasValue, + this.MinimumSlotCount.HasValue, + this.MaximumSlotCount.HasValue, + this.NumberOfPacketsWithAnError.HasValue, + false, + false)); + data.AddRange(Tools.ValueToData(this.AdditiveChecksumOfMostRecentPacket)); + data.AddRange(Tools.ValueToData(this.PacketCount)); + data.AddRange(Tools.ValueToData(this.MostRecentSlotCount)); + data.AddRange(Tools.ValueToData(this.MinimumSlotCount)); + data.AddRange(Tools.ValueToData(this.MaximumSlotCount)); + data.AddRange(Tools.ValueToData(this.NumberOfPacketsWithAnError)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageRequest.cs b/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageRequest.cs index a80fc2c2..5cd40a90 100644 --- a/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageRequest.cs +++ b/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageRequest.cs @@ -3,64 +3,46 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DEVICE_INFO_OFFSTAGE, Command.ECommandDublicate.GetRequest)] +public class GetDeviceInfoOffstageRequest : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.DEVICE_INFO_OFFSTAGE, Command.ECommandDublicate.GetRequest)] - public class GetDeviceInfoOffstageRequest : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetDeviceInfoOffstageRequest( + [DataTreeObjectParameter("root_personality")] byte rootPersonality = 1, + [DataTreeObjectParameter("subdevice")] ushort subDeviceRequested = 0, + [DataTreeObjectParameter("subdevice_personality")] byte subDevicePersonalityRequested = 0) { - [DataTreeObjectConstructor] - public GetDeviceInfoOffstageRequest( - [DataTreeObjectParameter("root_personality")] byte rootPersonality = 1, - [DataTreeObjectParameter("subdevice")] ushort subDeviceRequested = 0, - [DataTreeObjectParameter("subdevice_personality")] byte subDevicePersonalityRequested = 0) - { - RootPersonality = rootPersonality; - SubDeviceRequested = subDeviceRequested; - SubDevicePersonalityRequested = subDevicePersonalityRequested; - } - - [DataTreeObjectProperty("root_personality", 0)] - public byte RootPersonality { get; private set; } - [DataTreeObjectProperty("subdevice", 1)] - public ushort SubDeviceRequested { get; private set; } - [DataTreeObjectProperty("subdevice_personality", 2)] - public byte SubDevicePersonalityRequested { get; private set; } - public const int PDL = 4; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine($"RootPersonality: {RootPersonality}"); - b.AppendLine($"SubDeviceRequested: {SubDeviceRequested}"); - b.AppendLine($"SubDevicePersonalityRequested: {SubDevicePersonalityRequested}"); + RootPersonality = rootPersonality; + SubDeviceRequested = subDeviceRequested; + SubDevicePersonalityRequested = subDevicePersonalityRequested; + } - return b.ToString(); - } - public static GetDeviceInfoOffstageRequest FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND, ERDM_Parameter.DEVICE_INFO_OFFSTAGE, PDL); + [DataTreeObjectProperty("root_personality", 0)] + public byte RootPersonality { get; private set; } + [DataTreeObjectProperty("subdevice", 1)] + public ushort SubDeviceRequested { get; private set; } + [DataTreeObjectProperty("subdevice_personality", 2)] + public byte SubDevicePersonalityRequested { get; private set; } + public const int PDL = 4; - return FromPayloadData(msg.ParameterData); - } - public static GetDeviceInfoOffstageRequest FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine($"RootPersonality: {RootPersonality}"); + b.AppendLine($"SubDeviceRequested: {SubDeviceRequested}"); + b.AppendLine($"SubDevicePersonalityRequested: {SubDevicePersonalityRequested}"); - var i = new GetDeviceInfoOffstageRequest( - rootPersonality: Tools.DataToByte(ref data), - subDeviceRequested: Tools.DataToUShort(ref data), - subDevicePersonalityRequested: Tools.DataToByte(ref data) - ); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.RootPersonality)); - data.AddRange(Tools.ValueToData(this.SubDeviceRequested)); - data.AddRange(Tools.ValueToData(this.SubDevicePersonalityRequested)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.RootPersonality)); + data.AddRange(Tools.ValueToData(this.SubDeviceRequested)); + data.AddRange(Tools.ValueToData(this.SubDevicePersonalityRequested)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageResponse.cs b/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageResponse.cs index b08834b5..34d082a9 100644 --- a/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageResponse.cs @@ -3,126 +3,107 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DEVICE_INFO_OFFSTAGE, Command.ECommandDublicate.GetResponse)] +public class GetDeviceInfoOffstageResponse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.DEVICE_INFO_OFFSTAGE, Command.ECommandDublicate.GetResponse)] - public class GetDeviceInfoOffstageResponse : AbstractRDMPayloadObject + public GetDeviceInfoOffstageResponse( + byte rootPersonality = 1, + ushort subDeviceRequested = 0, + byte subDevicePersonalityRequested = 0, + RDMDeviceInfo deviceInfo = null) { - public GetDeviceInfoOffstageResponse( - byte rootPersonality = 1, - ushort subDeviceRequested = 0, - byte subDevicePersonalityRequested = 0, - RDMDeviceInfo deviceInfo = null) - { - RootPersonality = rootPersonality; - SubDeviceRequested = subDeviceRequested; - SubDevicePersonalityRequested = subDevicePersonalityRequested; - DeviceInfo = deviceInfo; - } - - [DataTreeObjectConstructor] - public GetDeviceInfoOffstageResponse( - [DataTreeObjectParameter("root_personality")] byte rootPersonality, - [DataTreeObjectParameter("subdevice")] ushort subDeviceRequested, - [DataTreeObjectParameter("subdevice_personality")] byte subDevicePersonalityRequested, - [DataTreeObjectParameter("protocol_major")] byte rdmProtocolVersionMajor, - [DataTreeObjectParameter("protocol_minor")] byte rdmProtocolVersionMinor, - [DataTreeObjectParameter("device_model_id")] ushort deviceModelId, - [DataTreeObjectParameter("product_category")] ushort productCategory, - [DataTreeObjectParameter("software_version_id")] uint softwareVersionId, - [DataTreeObjectParameter("dmx_footprint")] ushort dmx512Footprint, - [DataTreeObjectParameter("current_personality")] byte dmx512CurrentPersonality, - [DataTreeObjectParameter("personality_count")] byte dmx512NumberOfPersonalities, - [DataTreeObjectParameter("dmx_start_address")] ushort dmx512StartAddress, - [DataTreeObjectParameter("sub_device_count")] ushort subDeviceCount, - [DataTreeObjectParameter("sensor_count")] byte sensorCount) - : this(rootPersonality, - subDeviceRequested, - subDevicePersonalityRequested, - new RDMDeviceInfo( - rdmProtocolVersionMajor, - rdmProtocolVersionMinor, - deviceModelId, - productCategory, - softwareVersionId, - dmx512Footprint, - dmx512CurrentPersonality, - dmx512NumberOfPersonalities, - dmx512StartAddress, - subDeviceCount, - sensorCount)) - { - } - - [DataTreeObjectProperty("root_personality", 0)] - public byte RootPersonality { get; private set; } - [DataTreeObjectProperty("subdevice", 1)] - public ushort SubDeviceRequested { get; private set; } - [DataTreeObjectProperty("subdevice_personality", 2)] - public byte SubDevicePersonalityRequested { get; private set; } + RootPersonality = rootPersonality; + SubDeviceRequested = subDeviceRequested; + SubDevicePersonalityRequested = subDevicePersonalityRequested; + DeviceInfo = deviceInfo; + } - [DataTreeObjectProperty("protocol_major", 3)] - public byte RdmProtocolVersionMajor { get => DeviceInfo.RdmProtocolVersionMajor; } - [DataTreeObjectProperty("protocol_minor", 4)] - public byte RdmProtocolVersionMinor { get => DeviceInfo.RdmProtocolVersionMinor; } - [DataTreeObjectProperty("device_model_id", 5)] - public ushort DeviceModelId { get => DeviceInfo.DeviceModelId; } - [DataTreeObjectProperty("product_category", 6)] - public ushort ProductCategory { get => DeviceInfo.ProductCategory; } - [DataTreeObjectProperty("software_version_id", 7)] - public uint SoftwareVersionId { get => DeviceInfo.SoftwareVersionId; } - [DataTreeObjectProperty("dmx_footprint", 8)] - public ushort? Dmx512Footprint { get => DeviceInfo.Dmx512Footprint; } - [DataTreeObjectProperty("current_personality", 9)] - public byte? Dmx512CurrentPersonality { get => DeviceInfo.Dmx512CurrentPersonality; } - [DataTreeObjectProperty("personality_count", 10)] - public byte Dmx512NumberOfPersonalities { get => DeviceInfo.Dmx512NumberOfPersonalities; } - [DataTreeObjectProperty("dmx_start_address", 11)] - public ushort? Dmx512StartAddress { get => DeviceInfo.Dmx512StartAddress; } - [DataTreeObjectProperty("sub_device_count", 12)] - public ushort SubDeviceCount { get => DeviceInfo.SubDeviceCount; } - [DataTreeObjectProperty("sensor_count", 13)] - public byte SensorCount { get => DeviceInfo.SensorCount; } - public RDMDeviceInfo DeviceInfo { get; private set; } - public const int PDL = 4 + RDMDeviceInfo.PDL; + [DataTreeObjectConstructor] + public GetDeviceInfoOffstageResponse( + [DataTreeObjectParameter("root_personality")] byte rootPersonality, + [DataTreeObjectParameter("subdevice")] ushort subDeviceRequested, + [DataTreeObjectParameter("subdevice_personality")] byte subDevicePersonalityRequested, + [DataTreeObjectParameter("protocol_major")] byte rdmProtocolVersionMajor, + [DataTreeObjectParameter("protocol_minor")] byte rdmProtocolVersionMinor, + [DataTreeObjectParameter("device_model_id")] ushort deviceModelId, + [DataTreeObjectParameter("product_category")] ushort productCategory, + [DataTreeObjectParameter("software_version_id")] uint softwareVersionId, + [DataTreeObjectParameter("dmx_footprint")] ushort dmx512Footprint, + [DataTreeObjectParameter("current_personality")] byte dmx512CurrentPersonality, + [DataTreeObjectParameter("personality_count")] byte dmx512NumberOfPersonalities, + [DataTreeObjectParameter("dmx_start_address")] ushort dmx512StartAddress, + [DataTreeObjectParameter("sub_device_count")] ushort subDeviceCount, + [DataTreeObjectParameter("sensor_count")] byte sensorCount) + : this(rootPersonality, + subDeviceRequested, + subDevicePersonalityRequested, + new RDMDeviceInfo( + rdmProtocolVersionMajor, + rdmProtocolVersionMinor, + deviceModelId, + productCategory, + softwareVersionId, + dmx512Footprint, + dmx512CurrentPersonality, + dmx512NumberOfPersonalities, + dmx512StartAddress, + subDeviceCount, + sensorCount)) + { + } - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine($"RootPersonality: {RootPersonality}"); - b.AppendLine($"SubDeviceRequested: {SubDeviceRequested}"); - b.AppendLine($"SubDevicePersonalityRequested: {SubDevicePersonalityRequested}"); - b.AppendLine($"DeviceInfo: {DeviceInfo}"); + [DataTreeObjectProperty("root_personality", 0)] + public byte RootPersonality { get; private set; } + [DataTreeObjectProperty("subdevice", 1)] + public ushort SubDeviceRequested { get; private set; } + [DataTreeObjectProperty("subdevice_personality", 2)] + public byte SubDevicePersonalityRequested { get; private set; } - return b.ToString(); - } - public static GetDeviceInfoOffstageResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DEVICE_INFO_OFFSTAGE, PDL); + [DataTreeObjectProperty("protocol_major", 3)] + public byte RdmProtocolVersionMajor { get => DeviceInfo.RdmProtocolVersionMajor; } + [DataTreeObjectProperty("protocol_minor", 4)] + public byte RdmProtocolVersionMinor { get => DeviceInfo.RdmProtocolVersionMinor; } + [DataTreeObjectProperty("device_model_id", 5)] + public ushort DeviceModelId { get => DeviceInfo.DeviceModelId; } + [DataTreeObjectProperty("product_category", 6)] + public ushort ProductCategory { get => DeviceInfo.ProductCategory; } + [DataTreeObjectProperty("software_version_id", 7)] + public uint SoftwareVersionId { get => DeviceInfo.SoftwareVersionId; } + [DataTreeObjectProperty("dmx_footprint", 8)] + public ushort? Dmx512Footprint { get => DeviceInfo.Dmx512Footprint; } + [DataTreeObjectProperty("current_personality", 9)] + public byte? Dmx512CurrentPersonality { get => DeviceInfo.Dmx512CurrentPersonality; } + [DataTreeObjectProperty("personality_count", 10)] + public byte Dmx512NumberOfPersonalities { get => DeviceInfo.Dmx512NumberOfPersonalities; } + [DataTreeObjectProperty("dmx_start_address", 11)] + public ushort? Dmx512StartAddress { get => DeviceInfo.Dmx512StartAddress; } + [DataTreeObjectProperty("sub_device_count", 12)] + public ushort SubDeviceCount { get => DeviceInfo.SubDeviceCount; } + [DataTreeObjectProperty("sensor_count", 13)] + public byte SensorCount { get => DeviceInfo.SensorCount; } + public RDMDeviceInfo DeviceInfo { get; private set; } + public const int PDL = 4 + RDMDeviceInfo.PDL; - return FromPayloadData(msg.ParameterData); - } - public static GetDeviceInfoOffstageResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine($"RootPersonality: {RootPersonality}"); + b.AppendLine($"SubDeviceRequested: {SubDeviceRequested}"); + b.AppendLine($"SubDevicePersonalityRequested: {SubDevicePersonalityRequested}"); + b.AppendLine($"DeviceInfo: {DeviceInfo}"); - var i = new GetDeviceInfoOffstageResponse( - rootPersonality: Tools.DataToByte(ref data), - subDeviceRequested: Tools.DataToUShort(ref data), - subDevicePersonalityRequested: Tools.DataToByte(ref data), - deviceInfo: RDMDeviceInfo.FromPayloadData(data) - ); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.RootPersonality)); - data.AddRange(Tools.ValueToData(this.SubDeviceRequested)); - data.AddRange(Tools.ValueToData(this.SubDevicePersonalityRequested)); - data.AddRange(Tools.ValueToData(this.DeviceInfo)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.RootPersonality)); + data.AddRange(Tools.ValueToData(this.SubDeviceRequested)); + data.AddRange(Tools.ValueToData(this.SubDevicePersonalityRequested)); + data.AddRange(Tools.ValueToData(this.DeviceInfo)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetDiscoveryStateResponse.cs b/RDMSharp/RDM/PayloadObject/GetDiscoveryStateResponse.cs index 93cff0e6..4ec7ee86 100644 --- a/RDMSharp/RDM/PayloadObject/GetDiscoveryStateResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetDiscoveryStateResponse.cs @@ -2,68 +2,49 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DISCOVERY_STATE, Command.ECommandDublicate.GetResponse)] +public class GetDiscoveryStateResponse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.DISCOVERY_STATE, Command.ECommandDublicate.GetResponse)] - public class GetDiscoveryStateResponse : AbstractRDMPayloadObject + public GetDiscoveryStateResponse( + ushort endpointId = default, + ushort deviceCount = default, + ERDM_DiscoveryState discoveryState = default) { - public GetDiscoveryStateResponse( - ushort endpointId = default, - ushort deviceCount = default, - ERDM_DiscoveryState discoveryState = default) - { - this.EndpointId = endpointId; - this.DeviceCount = deviceCount; - this.DiscoveryState = discoveryState; - } - - [DataTreeObjectConstructor] - public GetDiscoveryStateResponse( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId, - [DataTreeObjectParameter("device_count")] ushort deviceCount, - [DataTreeObjectParameter("state")] byte discoveryState) : - this(endpointId, deviceCount, (ERDM_DiscoveryState)discoveryState) - { - } - - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("device_count", 1)] - public ushort DeviceCount { get; private set; } - [DataTreeObjectProperty("state", 2)] - public ERDM_DiscoveryState DiscoveryState { get; private set; } - public const int PDL = 0x05; - - public override string ToString() - { - return $"Endpoint: {EndpointId} - DiscoveryState: {DiscoveryState} DeviceCount: {DeviceCount}"; - } - - public static GetDiscoveryStateResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DISCOVERY_STATE, PDL); + this.EndpointId = endpointId; + this.DeviceCount = deviceCount; + this.DiscoveryState = discoveryState; + } - return FromPayloadData(msg.ParameterData); - } - public static GetDiscoveryStateResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + [DataTreeObjectConstructor] + public GetDiscoveryStateResponse( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId, + [DataTreeObjectParameter("device_count")] ushort deviceCount, + [DataTreeObjectParameter("state")] byte discoveryState) : + this(endpointId, deviceCount, (ERDM_DiscoveryState)discoveryState) + { + } - var i = new GetDiscoveryStateResponse( - endpointId: Tools.DataToUShort(ref data), - deviceCount: Tools.DataToUShort(ref data), - discoveryState: Tools.DataToEnum(ref data)); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("device_count", 1)] + public ushort DeviceCount { get; private set; } + [DataTreeObjectProperty("state", 2)] + public ERDM_DiscoveryState DiscoveryState { get; private set; } + public const int PDL = 0x05; - return i; - } + public override string ToString() + { + return $"Endpoint: {EndpointId} - DiscoveryState: {DiscoveryState} DeviceCount: {DeviceCount}"; + } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.DeviceCount)); - data.AddRange(Tools.ValueToData(this.DiscoveryState)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.DeviceCount)); + data.AddRange(Tools.ValueToData(this.DiscoveryState)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetEndpointListResponse.cs b/RDMSharp/RDM/PayloadObject/GetEndpointListResponse.cs index 30736356..2d1522d3 100644 --- a/RDMSharp/RDM/PayloadObject/GetEndpointListResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetEndpointListResponse.cs @@ -1,131 +1,66 @@ using RDMSharp.Metadata; using RDMSharp.Metadata.JSON; -using System; using System.Collections.Generic; -using System.Linq; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.ENDPOINT_LIST, Command.ECommandDublicate.GetResponse)] +public class GetEndpointListResponse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.ENDPOINT_LIST, Command.ECommandDublicate.GetResponse, true, "endpoints")] - public class GetEndpointListResponse : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetEndpointListResponse( + [DataTreeObjectParameter("list_change_number")] uint listChangedNumber = 0, + [DataTreeObjectParameter("endpoints")] params EndpointDescriptor[] endpoints) { - [DataTreeObjectConstructor] - public GetEndpointListResponse( - [DataTreeObjectParameter("list_change_number")] uint listChangedNumber = 0, - [DataTreeObjectParameter("endpoints")] params EndpointDescriptor[] endpoints) - { - this.ListChangedNumber = listChangedNumber; - this.Endpoints = endpoints; - } - /// - /// The Endpoint List Change Number is a monotonically increasing number used by controllers to - /// track that the list of Endpoints has changed, or that an Endpoint Type has changed.This Change - /// Number shall be incremented by one each time the set of Endpoints change. The Change - /// Number is an unsigned 32-bit field which shall roll over from 0xFFFFFFFF to 0. Upon start-up - /// (due to power-on reset, start of software, etc) this field shall be initialized to 0. - /// - [DataTreeObjectProperty("list_change_number", 0)] - public uint ListChangedNumber { get; private set; } - - [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.IDENTIFY_ENDPOINT, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_TO_UNIVERSE, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_MODE, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_LABEL, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.RDM_TRAFFIC_ENABLE, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.DISCOVERY_STATE, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.BACKGROUND_DISCOVERY, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_RESPONDERS, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.BINDING_CONTROL_FIELDS, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("endpoints", 1)] - public EndpointDescriptor[] Endpoints { get; private set; } - public const int PDL_MIN = 0x07; - public const int PDL_MAX = 0xE5; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("GetEndpointListResponse"); - b.AppendLine($"ListChangedNumber: {ListChangedNumber.ToString("X")}"); - b.AppendLine($"Endpoints:"); - foreach (EndpointDescriptor _interface in Endpoints) - b.AppendLine(_interface.ToString()); - - return b.ToString(); - } - public static GetEndpointListResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.ENDPOINT_LIST, PDL_MIN, PDL_MAX); - - return FromPayloadData(msg.ParameterData); - } - public static GetEndpointListResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - - uint listChangedNumber = Tools.DataToUInt(ref data); - - List _endpoints = new List(); - int pdl = EndpointDescriptor.PDL; - while (data.Length >= pdl) - { - var bytes = data.Take(pdl).ToArray(); - _endpoints.Add(EndpointDescriptor.FromPayloadData(bytes)); - data = data.Skip(pdl).ToArray(); - } - - var i = new GetEndpointListResponse(listChangedNumber, _endpoints.ToArray()); - - if (data.Length != 0) - throw new Exception("After deserialization data should be empty!"); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.ListChangedNumber)); - - foreach (EndpointDescriptor _interface in Endpoints) - data.AddRange(_interface.ToPayloadData()); - - return data.ToArray(); - } + this.ListChangedNumber = listChangedNumber; + this.Endpoints = endpoints; } - public class EndpointDescriptor : AbstractRDMPayloadObject + /// + /// The Endpoint List Change Number is a monotonically increasing number used by controllers to + /// track that the list of Endpoints has changed, or that an Endpoint Type has changed.This Change + /// Number shall be incremented by one each time the set of Endpoints change. The Change + /// Number is an unsigned 32-bit field which shall roll over from 0xFFFFFFFF to 0. Upon start-up + /// (due to power-on reset, start of software, etc) this field shall be initialized to 0. + /// + [DataTreeObjectProperty("list_change_number", 0)] + public uint ListChangedNumber { get; private set; } + + [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.IDENTIFY_ENDPOINT, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_TO_UNIVERSE, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_MODE, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_LABEL, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.RDM_TRAFFIC_ENABLE, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.DISCOVERY_STATE, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.BACKGROUND_DISCOVERY, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_RESPONDERS, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("endpoint_id", nameof(EndpointDescriptor.EndpointId), ERDM_Parameter.BINDING_CONTROL_FIELDS, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("endpoints/", 1)] + public EndpointDescriptor[] Endpoints { get; private set; } + public const int PDL_MIN = 0x07; + public const int PDL_MAX = 0xE5; + + public override string ToString() { - public EndpointDescriptor(ushort endpointId = 0, ERDM_EndpointType endpointType = 0) - { - this.EndpointId = endpointId; - this.EndpointType = endpointType; - } - - public ushort EndpointId { get; private set; } - public ERDM_EndpointType EndpointType { get; private set; } - public const int PDL = 3; - - public override string ToString() - { - return $"Id: {EndpointId} EndpointType: {EndpointType}"; - } - public static EndpointDescriptor FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + StringBuilder b = new StringBuilder(); + b.AppendLine("GetEndpointListResponse"); + b.AppendLine($"ListChangedNumber: {ListChangedNumber.ToString("X")}"); + b.AppendLine($"Endpoints:"); + foreach (EndpointDescriptor _interface in Endpoints) + b.AppendLine(_interface.ToString()); + + return b.ToString(); + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.ListChangedNumber)); - var i = new EndpointDescriptor( - endpointId: Tools.DataToUShort(ref data), - endpointType: Tools.DataToEnum(ref data)); + foreach (EndpointDescriptor _interface in Endpoints) + data.AddRange(_interface.ToPayloadData()); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.EndpointType)); - return data.ToArray(); - } + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetEndpointResponderListChangeResponse.cs b/RDMSharp/RDM/PayloadObject/GetEndpointResponderListChangeResponse.cs index e775e617..f11b77b3 100644 --- a/RDMSharp/RDM/PayloadObject/GetEndpointResponderListChangeResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetEndpointResponderListChangeResponse.cs @@ -2,54 +2,36 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, Command.ECommandDublicate.GetResponse)] +public class GetEndpointResponderListChangeResponse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, Command.ECommandDublicate.GetResponse)] - public class GetEndpointResponderListChangeResponse : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetEndpointResponderListChangeResponse( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("list_change_number")] uint listChangeNumber = default) { - [DataTreeObjectConstructor] - public GetEndpointResponderListChangeResponse( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, - [DataTreeObjectParameter("list_change_number")] uint listChangeNumber = default) - { - this.EndpointId = endpointId; - this.ListChangeNumber = listChangeNumber; - } - - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("list_change_number", 1)] - public uint ListChangeNumber { get; private set; } - public const int PDL = 0x06; - - public override string ToString() - { - return $"Endpoint: {EndpointId} Responder ListChangeNumber: {ListChangeNumber:X}"; - } - - public static GetEndpointResponderListChangeResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetEndpointResponderListChangeResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + this.EndpointId = endpointId; + this.ListChangeNumber = listChangeNumber; + } - var i = new GetEndpointResponderListChangeResponse( - endpointId: Tools.DataToUShort(ref data), - listChangeNumber: Tools.DataToUInt(ref data)); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("list_change_number", 1)] + public uint ListChangeNumber { get; private set; } + public const int PDL = 0x06; - return i; - } + public override string ToString() + { + return $"Endpoint: {EndpointId} Responder ListChangeNumber: {ListChangeNumber:X}"; + } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.ListChangeNumber)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.ListChangeNumber)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetEndpointRespondersResponse.cs b/RDMSharp/RDM/PayloadObject/GetEndpointRespondersResponse.cs index a67d8a7e..390666ad 100644 --- a/RDMSharp/RDM/PayloadObject/GetEndpointRespondersResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetEndpointRespondersResponse.cs @@ -1,78 +1,65 @@ using RDMSharp.Metadata; using RDMSharp.Metadata.JSON; -using System; using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.ENDPOINT_RESPONDERS, Command.ECommandDublicate.GetResponse)] +public class GetEndpointRespondersResponse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.ENDPOINT_RESPONDERS, Command.ECommandDublicate.GetResponse)] - public class GetEndpointRespondersResponse : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetEndpointRespondersResponse( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("list_change_number")] uint listChangedNumber = default, + [DataTreeObjectParameter(ERDM_Parameter.ENDPOINT_RESPONDERS, "uids", true)] params UID[] uids) { - [DataTreeObjectConstructor] - public GetEndpointRespondersResponse( - [DataTreeObjectParameter("list_change_number")] uint listChangedNumber = 0, - [DataTreeObjectParameter("uids")] params UID[] uids) - { - this.ListChangedNumber = listChangedNumber; - this.UIDs = uids; - } - /// - /// The Endpoint List Change Number is a monotonically increasing number used by controllers to - /// track that the list of Endpoints has changed, or that an Endpoint Type has changed.This Change - /// Number shall be incremented by one each time the set of Endpoints change. The Change - /// Number is an unsigned 32-bit field which shall roll over from 0xFFFFFFFF to 0. Upon start-up - /// (due to power-on reset, start of software, etc) this field shall be initialized to 0. - /// - [DataTreeObjectProperty("list_change_number", 0)] - public uint ListChangedNumber { get; private set; } - [DataTreeObjectProperty("uids", 1)] - public UID[] UIDs { get; private set; } - public const int PDL_MIN = 0x07; - public const int PDL_MAX = 0xE5; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("GetEndpointRespondersResponse"); - b.AppendLine($"ListChangedNumber: {ListChangedNumber.ToString("X")}"); - b.AppendLine($"UIDs:"); - foreach (UID uid in UIDs) - b.AppendLine(uid.ToString()); + this.EndpointId = endpointId; + this.ListChangedNumber = listChangedNumber; + this.UIDs = uids ?? new UID[0]; + } - return b.ToString(); - } - public static GetEndpointRespondersResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.ENDPOINT_RESPONDERS, PDL_MIN, PDL_MAX); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } - return FromPayloadData(msg.ParameterData); - } - public static GetEndpointRespondersResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); + /// + /// The Endpoint List Change Number is a monotonically increasing number used by controllers to + /// track that the list of Endpoints has changed, or that an Endpoint Type has changed.This Change + /// Number shall be incremented by one each time the set of Endpoints change. The Change + /// Number is an unsigned 32-bit field which shall roll over from 0xFFFFFFFF to 0. Upon start-up + /// (due to power-on reset, start of software, etc) this field shall be initialized to 0. + /// + [DataTreeObjectProperty("list_change_number", 1)] + public uint ListChangedNumber { get; private set; } - uint listChangedNumber = Tools.DataToUInt(ref data); + [DataTreeObjectProperty("uids/uid", 2)] + public UID[] UIDs { get; private set; } - List uids = new List(); - while (data.Length >= 6) - uids.Add(Tools.DataToRDMUID(ref data)); + public const int PDL_MIN = 0x06; + public const int PDL_MAX = 0xE4; - var i = new GetEndpointRespondersResponse(listChangedNumber, uids.ToArray()); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("GetEndpointRespondersResponse"); + b.AppendLine($"EndpointId: {EndpointId.ToString("X")}"); + b.AppendLine($"ListChangedNumber: {ListChangedNumber.ToString("X")}"); + b.AppendLine($"UIDs:"); + if (UIDs is not null) + foreach (UID uid in UIDs) + b.AppendLine(uid.ToString()); - if (data.Length != 0) - throw new Exception("After deserialization data should be empty!"); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.ListChangedNumber)); + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.ListChangedNumber)); - data.AddRange(Tools.ValueToData(this.UIDs)); + data.AddRange(Tools.ValueToData(this.UIDs)); - return data.ToArray(); - } + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetEndpointTimingDescriptionResponse.cs b/RDMSharp/RDM/PayloadObject/GetEndpointTimingDescriptionResponse.cs index 9c7c56ed..3a121dc6 100644 --- a/RDMSharp/RDM/PayloadObject/GetEndpointTimingDescriptionResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetEndpointTimingDescriptionResponse.cs @@ -2,66 +2,48 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, Command.ECommandDublicate.GetResponse)] +public class GetEndpointTimingDescriptionResponse : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription { - [DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, Command.ECommandDublicate.GetResponse)] - public class GetEndpointTimingDescriptionResponse : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription - { - [DataTreeObjectConstructor] - public GetEndpointTimingDescriptionResponse( - [DataTreeObjectParameter("setting")] byte timingtId = 1, - [DataTreeObjectParameter("description")] string description = default) - { - this.TimingId = timingtId; + [DataTreeObjectConstructor] + public GetEndpointTimingDescriptionResponse( + [DataTreeObjectParameter("setting")] byte timingtId = 1, + [DataTreeObjectParameter("description")] string description = default) + { + this.TimingId = timingtId; - if (string.IsNullOrWhiteSpace(description)) - return; + if (string.IsNullOrWhiteSpace(description)) + return; - if (description.Length > 32) - description = description.Substring(0, 32); + if (description.Length > 32) + description = description.Substring(0, 32); - this.Description = description; - } + this.Description = description; + } - [DataTreeObjectProperty("setting", 0)] - public byte TimingId { get; private set; } - [DataTreeObjectProperty("description", 1)] - public string Description { get; private set; } + [DataTreeObjectProperty("setting", 0)] + public byte TimingId { get; private set; } + [DataTreeObjectProperty("description", 1)] + public string Description { get; private set; } - public object MinIndex => (byte)1; - public object Index => TimingId; + public object MinIndex => (byte)1; + public object Index => TimingId; - public const int PDL_MIN = 0x01; - public const int PDL_MAX = PDL_MIN + 32; - - public override string ToString() - { - return $"Timing: {TimingId} - Description: {Description}"; - } - - public static GetEndpointTimingDescriptionResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, PDL_MIN, PDL_MAX); + public const int PDL_MIN = 0x01; + public const int PDL_MAX = PDL_MIN + 32; - return FromPayloadData(msg.ParameterData); - } - public static GetEndpointTimingDescriptionResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - - var i = new GetEndpointTimingDescriptionResponse( - timingtId: Tools.DataToByte(ref data), - description: Tools.DataToString(ref data)); - - return i; - } + public override string ToString() + { + return $"Timing: {TimingId} - Description: {Description}"; + } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.TimingId)); - data.AddRange(Tools.ValueToData(this.Description)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.TimingId)); + data.AddRange(Tools.ValueToData(this.Description)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetEndpointTimingResponse.cs b/RDMSharp/RDM/PayloadObject/GetEndpointTimingResponse.cs index 4a076252..6c69677e 100644 --- a/RDMSharp/RDM/PayloadObject/GetEndpointTimingResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetEndpointTimingResponse.cs @@ -3,69 +3,53 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicate.GetResponse)] +public class GetEndpointTimingResponse : AbstractRDMPayloadObjectOneOf { - [DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicate.GetResponse)] - public class GetEndpointTimingResponse : AbstractRDMPayloadObjectOneOf - { - [DataTreeObjectConstructor] - public GetEndpointTimingResponse( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, - [DataTreeObjectParameter("setting")] byte timingId = 1, - [DataTreeObjectParameter("setting_count")] byte timings = default) - { - this.EndpointId = endpointId; - this.TimingId = timingId; - this.Timings = timings; - } + [DataTreeObjectConstructor] + public GetEndpointTimingResponse( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("setting")] byte timingId = 1, + [DataTreeObjectParameter("setting_count")] byte timings = default) + { + this.EndpointId = endpointId; + this.TimingId = timingId; + this.Timings = timings; + } - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("setting", 1)] - public byte TimingId { get; private set; } - [DataTreeObjectDependecieProperty("setting", ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("setting", ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("setting_count", 2)] - public byte Timings { get; private set; } + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("setting", 1)] + public byte TimingId { get; private set; } + [DataTreeObjectDependecieProperty("setting", ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("setting", ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("setting_count", 2)] + public byte Timings { get; private set; } - public override Type IndexType => typeof(byte); - public override object MinIndex => (byte)1; + public override Type IndexType => typeof(byte); + public override object MinIndex => (byte)1; - public override object Index => TimingId; + public override object Index => TimingId; - public override object Count => Timings; + public override object Count => Timings; - public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION; + public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION; - public const int PDL = 4; - - public override string ToString() - { - return $"Endpoint: {EndpointId} TimingId: {TimingId} of {Timings}"; - } - public static GetEndpointTimingResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.ENDPOINT_TIMING, PDL); + public const int PDL = 4; - return FromPayloadData(msg.ParameterData); - } - public static GetEndpointTimingResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new GetEndpointTimingResponse( - endpointId: Tools.DataToUShort(ref data), - timingId: Tools.DataToByte(ref data), - timings: Tools.DataToByte(ref data)); + public override string ToString() + { + return $"Endpoint: {EndpointId} TimingId: {TimingId} of {Timings}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.TimingId)); - data.AddRange(Tools.ValueToData(this.Timings)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.TimingId)); + data.AddRange(Tools.ValueToData(this.Timings)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/GetHardwareAddressResponse.cs b/RDMSharp/RDM/PayloadObject/GetHardwareAddressResponse.cs index 5020d09e..ea6375ac 100644 --- a/RDMSharp/RDM/PayloadObject/GetHardwareAddressResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetHardwareAddressResponse.cs @@ -2,53 +2,52 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, Command.ECommandDublicate.GetResponse)] +public class GetHardwareAddressResponse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, Command.ECommandDublicate.GetResponse)] - public class GetHardwareAddressResponse : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetHardwareAddressResponse( + [DataTreeObjectParameter("id")] uint interfaceId = 0, + [DataTreeObjectParameter("address")] MACAddress hardwareAddress = default) + { + this.InterfaceId = interfaceId; + this.HardwareAddress = hardwareAddress; + } + + [DataTreeObjectProperty("id", 0)] + public uint InterfaceId { get; private set; } + [DataTreeObjectProperty("address", 1)] + public MACAddress HardwareAddress { get; private set; } + public const int PDL = 0x0A; + + public override string ToString() + { + return $"GetHardwareAddressResponse: {InterfaceId} - {HardwareAddress}"; + } + + public static GetHardwareAddressResponse FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, PDL); + + return FromPayloadData(msg.ParameterData); + } + public static GetHardwareAddressResponse FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + + var i = new GetHardwareAddressResponse( + interfaceId: Tools.DataToUInt(ref data), + hardwareAddress: new MACAddress(data)); + + return i; + } + public override byte[] ToPayloadData() { - [DataTreeObjectConstructor] - public GetHardwareAddressResponse( - [DataTreeObjectParameter("id")] uint interfaceId = 0, - [DataTreeObjectParameter("address")] MACAddress hardwareAddress = default) - { - this.InterfaceId = interfaceId; - this.HardwareAddress = hardwareAddress; - } - - [DataTreeObjectProperty("id", 0)] - public uint InterfaceId { get; private set; } - [DataTreeObjectProperty("address", 1)] - public MACAddress HardwareAddress { get; private set; } - public const int PDL = 0x0A; - - public override string ToString() - { - return $"GetHardwareAddressResponse: {InterfaceId} - {HardwareAddress}"; - } - - public static GetHardwareAddressResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetHardwareAddressResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new GetHardwareAddressResponse( - interfaceId: Tools.DataToUInt(ref data), - hardwareAddress: new MACAddress(data)); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.InterfaceId)); - data.AddRange((byte[])this.HardwareAddress); - return data.ToArray(); - } + List data = new List(); + data.AddRange(Tools.ValueToData(this.InterfaceId)); + data.AddRange((byte[])this.HardwareAddress); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetIPv4CurrentAddressResponse.cs b/RDMSharp/RDM/PayloadObject/GetIPv4CurrentAddressResponse.cs index ab295f19..3ec2db61 100644 --- a/RDMSharp/RDM/PayloadObject/GetIPv4CurrentAddressResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetIPv4CurrentAddressResponse.cs @@ -2,78 +2,76 @@ using RDMSharp.Metadata.JSON; using System; using System.Collections.Generic; -using System.Net; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.IPV4_CURRENT_ADDRESS, Command.ECommandDublicate.GetResponse)] +public class GetIPv4CurrentAddressResponse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.IPV4_CURRENT_ADDRESS, Command.ECommandDublicate.GetResponse)] - public class GetIPv4CurrentAddressResponse : AbstractRDMPayloadObject + public GetIPv4CurrentAddressResponse( + uint interfaceId = 0, + IPv4Address ipAddress = default, + byte netmask = 24, + ERDM_DHCPStatusMode dhcpStatus = ERDM_DHCPStatusMode.UNKNOWN) { - public GetIPv4CurrentAddressResponse( - uint interfaceId = 0, - IPv4Address ipAddress = default, - byte netmask = 24, - ERDM_DHCPStatusMode dhcpStatus = ERDM_DHCPStatusMode.UNKNOWN) - { - this.InterfaceId = interfaceId; - this.IPAddress = ipAddress; - if (netmask > 32) - throw new Exception($"The valid range of {nameof(netmask)} is from 0 to 32"); + this.InterfaceId = interfaceId; + this.IPAddress = ipAddress; + if (netmask > 32) + throw new Exception($"The valid range of {nameof(netmask)} is from 0 to 32"); - this.Netmask = netmask; - this.DHCPStatus = dhcpStatus; - } - [DataTreeObjectConstructor] - public GetIPv4CurrentAddressResponse( - [DataTreeObjectParameter("id")] uint interfaceId, - [DataTreeObjectParameter("address")] IPv4Address ipAddress, - [DataTreeObjectParameter("netmask")] byte netmask, - [DataTreeObjectParameter("dhcp_status")] byte dhcpStatus) - : this(interfaceId, ipAddress, netmask, (ERDM_DHCPStatusMode)dhcpStatus) - { - } + this.Netmask = netmask; + this.DHCPStatus = dhcpStatus; + } + [DataTreeObjectConstructor] + public GetIPv4CurrentAddressResponse( + [DataTreeObjectParameter("id")] uint interfaceId, + [DataTreeObjectParameter("address")] IPv4Address ipAddress, + [DataTreeObjectParameter("netmask")] byte netmask, + [DataTreeObjectParameter("dhcp_status")] byte dhcpStatus) + : this(interfaceId, ipAddress, netmask, (ERDM_DHCPStatusMode)dhcpStatus) + { + } - [DataTreeObjectProperty("id", 0)] - public uint InterfaceId { get; private set; } - [DataTreeObjectProperty("address", 1)] - public IPv4Address IPAddress { get; private set; } - [DataTreeObjectProperty("netmask", 2)] - public byte Netmask { get; private set; } - [DataTreeObjectProperty("dhcp_status", 3)] - public ERDM_DHCPStatusMode DHCPStatus { get; private set; } - public const int PDL = 0x0A; + [DataTreeObjectProperty("id", 0)] + public uint InterfaceId { get; private set; } + [DataTreeObjectProperty("address", 1)] + public IPv4Address IPAddress { get; private set; } + [DataTreeObjectProperty("netmask", 2)] + public byte Netmask { get; private set; } + [DataTreeObjectProperty("dhcp_status", 3)] + public ERDM_DHCPStatusMode DHCPStatus { get; private set; } + public const int PDL = 0x0A; - public override string ToString() - { - return $"{InterfaceId} - {IPAddress}/{Netmask} \tDHCP: {DHCPStatus}"; - } + public override string ToString() + { + return $"{InterfaceId} - {IPAddress}/{Netmask} \tDHCP: {DHCPStatus}"; + } - public static GetIPv4CurrentAddressResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.IPV4_CURRENT_ADDRESS, PDL); + public static GetIPv4CurrentAddressResponse FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.IPV4_CURRENT_ADDRESS, PDL); - return FromPayloadData(msg.ParameterData); - } - public static GetIPv4CurrentAddressResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + return FromPayloadData(msg.ParameterData); + } + public static GetIPv4CurrentAddressResponse FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new GetIPv4CurrentAddressResponse( - interfaceId: Tools.DataToUInt(ref data), - ipAddress: Tools.DataToIPAddressIPv4(ref data), - netmask: Tools.DataToByte(ref data), - dhcpStatus: Tools.DataToEnum(ref data)); + var i = new GetIPv4CurrentAddressResponse( + interfaceId: Tools.DataToUInt(ref data), + ipAddress: Tools.DataToIPAddressIPv4(ref data), + netmask: Tools.DataToByte(ref data), + dhcpStatus: Tools.DataToEnum(ref data)); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.InterfaceId)); - data.AddRange(Tools.ValueToData(this.IPAddress)); - data.AddRange(Tools.ValueToData(this.Netmask)); - data.AddRange(Tools.ValueToData(this.DHCPStatus)); - return data.ToArray(); - } + return i; + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.InterfaceId)); + data.AddRange(Tools.ValueToData(this.IPAddress)); + data.AddRange(Tools.ValueToData(this.Netmask)); + data.AddRange(Tools.ValueToData(this.DHCPStatus)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetInterfaceListResponse.cs b/RDMSharp/RDM/PayloadObject/GetInterfaceListResponse.cs deleted file mode 100644 index 3dfb5b28..00000000 --- a/RDMSharp/RDM/PayloadObject/GetInterfaceListResponse.cs +++ /dev/null @@ -1,116 +0,0 @@ -using RDMSharp.Metadata; -using RDMSharp.Metadata.JSON; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace RDMSharp -{ - [DataTreeObject(ERDM_Parameter.LIST_INTERFACES, Command.ECommandDublicate.GetResponse, true, "interfaces")] - public class GetInterfaceListResponse : AbstractRDMPayloadObject - { - [DataTreeObjectConstructor] - public GetInterfaceListResponse([DataTreeObjectParameter("interfaces")] params InterfaceDescriptor[] interfaces) - { - this.Interfaces = interfaces; - } - - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.INTERFACE_LABEL, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.IPV4_DHCP_MODE, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.IPV4_DHCP_MODE, Command.ECommandDublicate.SetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.IPV4_ZEROCONF_MODE, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.IPV4_ZEROCONF_MODE, Command.ECommandDublicate.SetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.IPV4_CURRENT_ADDRESS, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.IPV4_CURRENT_ADDRESS, Command.ECommandDublicate.SetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.IPV4_STATIC_ADDRESS, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.IPV4_STATIC_ADDRESS, Command.ECommandDublicate.SetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION, Command.ECommandDublicate.SetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.INTERFACE_RENEW_DHCP, Command.ECommandDublicate.SetRequest)] - [DataTreeObjectDependecieProperty("id", nameof(InterfaceDescriptor.InterfaceId), ERDM_Parameter.INTERFACE_RELEASE_DHCP, Command.ECommandDublicate.SetRequest)] - [DataTreeObjectProperty("interfaces", 0)] - public InterfaceDescriptor[] Interfaces { get; private set; } - public const int PDL_MIN = 0; - public const int PDL_MAX = 0xE6; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("GetInterfaceListResponse"); - b.AppendLine($"Interfaces:"); - if (Interfaces is not null) - foreach (InterfaceDescriptor _interface in Interfaces) - b.AppendLine(_interface.ToString()); - - return b.ToString(); - } - public static GetInterfaceListResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.LIST_INTERFACES, PDL_MIN, PDL_MAX); - - return FromPayloadData(msg.ParameterData); - } - public static GetInterfaceListResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - - List _interfaces = new List(); - int pdl = 6; - while (data.Length >= pdl) - { - var bytes = data.Take(pdl).ToArray(); - _interfaces.Add(InterfaceDescriptor.FromPayloadData(bytes)); - data = data.Skip(pdl).ToArray(); - } - - var i = new GetInterfaceListResponse(_interfaces.ToArray()); - - if (data.Length != 0) - throw new Exception("After deserialization data should be empty!"); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - foreach (InterfaceDescriptor _interface in Interfaces) - data.AddRange(_interface.ToPayloadData()); - return data.ToArray(); - } - } - public class InterfaceDescriptor : AbstractRDMPayloadObject - { - public InterfaceDescriptor(uint interfaceId = 0, ushort hardwareType = 0) - { - this.InterfaceId = interfaceId; - this.HardwareType = hardwareType; - } - - public uint InterfaceId { get; private set; } - public ushort HardwareType { get; private set; } - public const int PDL = 6; - - public override string ToString() - { - return $"Id: {InterfaceId} HardwareType: {HardwareType}"; - } - public static InterfaceDescriptor FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new InterfaceDescriptor( - interfaceId: Tools.DataToUInt(ref data), - hardwareType: Tools.DataToUShort(ref data)); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.InterfaceId)); - data.AddRange(Tools.ValueToData(this.HardwareType)); - return data.ToArray(); - } - } -} \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetInterfaceNameResponse.cs b/RDMSharp/RDM/PayloadObject/GetInterfaceNameResponse.cs index 9be84297..cedad711 100644 --- a/RDMSharp/RDM/PayloadObject/GetInterfaceNameResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetInterfaceNameResponse.cs @@ -2,61 +2,60 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.INTERFACE_LABEL, Command.ECommandDublicate.GetResponse)] +public class GetInterfaceNameResponse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.INTERFACE_LABEL, Command.ECommandDublicate.GetResponse)] - public class GetInterfaceNameResponse : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetInterfaceNameResponse( + [DataTreeObjectParameter("id")] uint interfaceId = 0, + [DataTreeObjectParameter("label")] string label = "") + { + this.InterfaceId = interfaceId; + + if (string.IsNullOrWhiteSpace(label)) + return; + + if (label.Length > 32) + label = label.Substring(0, 32); + + this.Label = label; + } + + [DataTreeObjectProperty("id", 0)] + public uint InterfaceId { get; private set; } + [DataTreeObjectProperty("label", 1)] + public string Label { get; private set; } + public const int PDL_MIN = 4; + public const int PDL_MAX = PDL_MIN + 32; + + public override string ToString() + { + return $"GetInterfaceNameResponse: {InterfaceId} - {Label}"; + } + + public static GetInterfaceNameResponse FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.INTERFACE_LABEL, PDL_MIN, PDL_MAX); + + return FromPayloadData(msg.ParameterData); + } + public static GetInterfaceNameResponse FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); + + var i = new GetInterfaceNameResponse( + interfaceId: Tools.DataToUInt(ref data), + label: Tools.DataToString(ref data)); + + return i; + } + public override byte[] ToPayloadData() { - [DataTreeObjectConstructor] - public GetInterfaceNameResponse( - [DataTreeObjectParameter("id")] uint interfaceId = 0, - [DataTreeObjectParameter("label")] string label = "") - { - this.InterfaceId = interfaceId; - - if (string.IsNullOrWhiteSpace(label)) - return; - - if (label.Length > 32) - label = label.Substring(0, 32); - - this.Label = label; - } - - [DataTreeObjectProperty("id", 0)] - public uint InterfaceId { get; private set; } - [DataTreeObjectProperty("label", 1)] - public string Label { get; private set; } - public const int PDL_MIN = 4; - public const int PDL_MAX = PDL_MIN + 32; - - public override string ToString() - { - return $"GetInterfaceNameResponse: {InterfaceId} - {Label}"; - } - - public static GetInterfaceNameResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.INTERFACE_LABEL, PDL_MIN, PDL_MAX); - - return FromPayloadData(msg.ParameterData); - } - public static GetInterfaceNameResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - - var i = new GetInterfaceNameResponse( - interfaceId: Tools.DataToUInt(ref data), - label: Tools.DataToString(ref data)); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.InterfaceId)); - data.AddRange(Tools.ValueToData(this.Label, 32)); - return data.ToArray(); - } + List data = new List(); + data.AddRange(Tools.ValueToData(this.InterfaceId)); + data.AddRange(Tools.ValueToData(this.Label, 32)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/GetLockStateResponse.cs b/RDMSharp/RDM/PayloadObject/GetLockStateResponse.cs index 6aeb73af..95b11d41 100644 --- a/RDMSharp/RDM/PayloadObject/GetLockStateResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetLockStateResponse.cs @@ -3,63 +3,48 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.LOCK_STATE, Command.ECommandDublicate.GetResponse)] +public class GetLockStateResponse : AbstractRDMPayloadObjectOneOf { - [DataTreeObject(ERDM_Parameter.LOCK_STATE, Command.ECommandDublicate.GetResponse)] - public class GetLockStateResponse : AbstractRDMPayloadObjectOneOf - { - [DataTreeObjectConstructor] - public GetLockStateResponse( - [DataTreeObjectParameter("state")] byte currentLockStateId = 1, - [DataTreeObjectParameter("state_count")] byte lockStates = 0) - { - this.CurrentLockStateId = currentLockStateId; - this.LockStates = lockStates; - } + [DataTreeObjectConstructor] + public GetLockStateResponse( + [DataTreeObjectParameter("state")] byte currentLockStateId = 1, + [DataTreeObjectParameter("state_count")] byte lockStates = 0) + { + this.CurrentLockStateId = currentLockStateId; + this.LockStates = lockStates; + } - [DataTreeObjectProperty("state", 0)] - public byte CurrentLockStateId { get; private set; } + [DataTreeObjectProperty("state", 0)] + public byte CurrentLockStateId { get; private set; } - [DataTreeObjectDependecieProperty("state", ERDM_Parameter.LOCK_STATE_DESCRIPTION, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("state_count", 1)] - public byte LockStates { get; private set; } + [DataTreeObjectDependecieProperty("state", ERDM_Parameter.LOCK_STATE_DESCRIPTION, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("state_count", 1)] + public byte LockStates { get; private set; } - public override Type IndexType => typeof(byte); - public override object MinIndex => (byte)1; + public override Type IndexType => typeof(byte); + public override object MinIndex => (byte)0; - public override object Index => CurrentLockStateId; + public override object Index => CurrentLockStateId; - public override object Count => LockStates; + public override object Count => LockStates; - public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.LOCK_STATE_DESCRIPTION; + public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.LOCK_STATE_DESCRIPTION; - public const int PDL = 2; - - public override string ToString() - { - return $"RDMLockState: {CurrentLockStateId} of {LockStates}"; - } - public static GetLockStateResponse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.LOCK_STATE, PDL); + public const int PDL = 2; - return FromPayloadData(msg.ParameterData); - } - public static GetLockStateResponse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new GetLockStateResponse( - currentLockStateId: Tools.DataToByte(ref data), - lockStates: Tools.DataToByte(ref data)); + public override string ToString() + { + return $"RDMLockState: {CurrentLockStateId} of {LockStates}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.CurrentLockStateId)); - data.AddRange(Tools.ValueToData(this.LockStates)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.CurrentLockStateId)); + data.AddRange(Tools.ValueToData(this.LockStates)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/GetSetComponentScope.cs b/RDMSharp/RDM/PayloadObject/GetSetComponentScope.cs index a3aa685c..8c9e5fba 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetComponentScope.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetComponentScope.cs @@ -7,175 +7,174 @@ using System.Net.Sockets; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.COMPONENT_SCOPE, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.COMPONENT_SCOPE, Command.ECommandDublicate.SetRequest)] +public class GetSetComponentScope : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.COMPONENT_SCOPE, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.COMPONENT_SCOPE, Command.ECommandDublicate.SetRequest)] - public class GetSetComponentScope : AbstractRDMPayloadObject - { - [DataTreeObjectConstructor] - public GetSetComponentScope( - [DataTreeObjectParameter("scope_slot")] ushort scopeSlot = default, - [DataTreeObjectParameter("scope_string")] string scopeString = default, - [DataTreeObjectParameter("static_config_type")] ERDM_StaticConfig staticConfigType = default, - [DataTreeObjectParameter("static_broker_ipv4")] IPAddress staticBrokerIPv4 = default, - [DataTreeObjectParameter("static_broker_ipv6")] IPAddress staticBrokerIPv6 = default, - [DataTreeObjectParameter("static_broker_port")] ushort staticBrokerPort = default) - { + [DataTreeObjectConstructor] + public GetSetComponentScope( + [DataTreeObjectParameter("scope_slot")] ushort scopeSlot = default, + [DataTreeObjectParameter("scope_string")] string scopeString = default, + [DataTreeObjectParameter("static_config_type")] ERDM_StaticConfig staticConfigType = default, + [DataTreeObjectParameter("static_broker_ipv4")] IPAddress staticBrokerIPv4 = default, + [DataTreeObjectParameter("static_broker_ipv6")] IPAddress staticBrokerIPv6 = default, + [DataTreeObjectParameter("static_broker_port")] ushort staticBrokerPort = default) + { - if (string.IsNullOrWhiteSpace(scopeString)) - return; + if (string.IsNullOrWhiteSpace(scopeString)) + return; - if (scopeString.Length > 62) - scopeString = scopeString.Substring(0, 62); + if (scopeString.Length > 62) + scopeString = scopeString.Substring(0, 62); - this.ScopeSlot = scopeSlot; - this.ScopeString = scopeString; - this.StaticConfigType = staticConfigType; - switch (staticConfigType) - { - case ERDM_StaticConfig.IPv4: - if (staticBrokerIPv4 != null) - if (staticBrokerIPv4.AddressFamily != AddressFamily.InterNetwork) - throw new ArgumentException($"{nameof(staticBrokerIPv4)} should be IPv4 ;)"); - this.StaticBrokerIPv4 = staticBrokerIPv4; - break; - case ERDM_StaticConfig.IPv6: - if (staticBrokerIPv6 != null) - if (staticBrokerIPv6.AddressFamily != AddressFamily.InterNetworkV6) - throw new ArgumentException($"{nameof(staticBrokerIPv6)} should be IPv6 ;)"); - this.StaticBrokerIPv6 = staticBrokerIPv6; - break; - } - this.StaticBrokerPort = staticBrokerPort; + this.ScopeSlot = scopeSlot; + this.ScopeString = scopeString; + this.StaticConfigType = staticConfigType; + switch (staticConfigType) + { + case ERDM_StaticConfig.IPv4: + if (staticBrokerIPv4 != null) + if (staticBrokerIPv4.AddressFamily != AddressFamily.InterNetwork) + throw new ArgumentException($"{nameof(staticBrokerIPv4)} should be IPv4 ;)"); + this.StaticBrokerIPv4 = staticBrokerIPv4; + break; + case ERDM_StaticConfig.IPv6: + if (staticBrokerIPv6 != null) + if (staticBrokerIPv6.AddressFamily != AddressFamily.InterNetworkV6) + throw new ArgumentException($"{nameof(staticBrokerIPv6)} should be IPv6 ;)"); + this.StaticBrokerIPv6 = staticBrokerIPv6; + break; } + this.StaticBrokerPort = staticBrokerPort; + } - public GetSetComponentScope( - ushort scopeSlot = default, - string scopeString = default, - IPAddress staticBroker = default, - ushort staticBrokerPort = default) : this( - scopeSlot: scopeSlot, - scopeString: scopeString, - staticConfigType: getStaticConfig(staticBroker), - staticBrokerIPv4: staticBroker?.AddressFamily == AddressFamily.InterNetwork ? staticBroker : null, - staticBrokerIPv6: staticBroker?.AddressFamily == AddressFamily.InterNetworkV6 ? staticBroker : null, - staticBrokerPort: staticBrokerPort) + public GetSetComponentScope( + ushort scopeSlot = default, + string scopeString = default, + IPAddress staticBroker = default, + ushort staticBrokerPort = default) : this( + scopeSlot: scopeSlot, + scopeString: scopeString, + staticConfigType: getStaticConfig(staticBroker), + staticBrokerIPv4: staticBroker?.AddressFamily == AddressFamily.InterNetwork ? staticBroker : null, + staticBrokerIPv6: staticBroker?.AddressFamily == AddressFamily.InterNetworkV6 ? staticBroker : null, + staticBrokerPort: staticBrokerPort) + { + } + private static ERDM_StaticConfig getStaticConfig(IPAddress ipaddress) + { + switch (ipaddress?.AddressFamily) { + case AddressFamily.InterNetwork: + return ERDM_StaticConfig.IPv4; + case AddressFamily.InterNetworkV6: + return ERDM_StaticConfig.IPv6; } - private static ERDM_StaticConfig getStaticConfig(IPAddress ipaddress) - { - switch (ipaddress?.AddressFamily) - { - case AddressFamily.InterNetwork: - return ERDM_StaticConfig.IPv4; - case AddressFamily.InterNetworkV6: - return ERDM_StaticConfig.IPv6; - } - return ERDM_StaticConfig.NO; - } + return ERDM_StaticConfig.NO; + } - [DataTreeObjectProperty("scope_slot", 0)] - public ushort ScopeSlot { get; private set; } - [DataTreeObjectProperty("scope_string", 1)] - public string ScopeString { get; private set; } - [DataTreeObjectProperty("static_config_type", 3)] - public ERDM_StaticConfig StaticConfigType { get; private set; } - [DataTreeObjectProperty("static_broker_ipv4", 4)] - public IPv4Address StaticBrokerIPv4 { get; private set; } - [DataTreeObjectProperty("static_broker_ipv6", 5)] - public IPAddress StaticBrokerIPv6 { get; private set; } - [DataTreeObjectProperty("static_broker_port", 6)] - public ushort StaticBrokerPort { get; private set; } + [DataTreeObjectProperty("scope_slot", 0)] + public ushort ScopeSlot { get; private set; } + [DataTreeObjectProperty("scope_string", 1)] + public string ScopeString { get; private set; } + [DataTreeObjectProperty("static_config_type", 3)] + public ERDM_StaticConfig StaticConfigType { get; private set; } + [DataTreeObjectProperty("static_broker_ipv4", 4)] + public IPv4Address StaticBrokerIPv4 { get; private set; } + [DataTreeObjectProperty("static_broker_ipv6", 5)] + public IPAddress StaticBrokerIPv6 { get; private set; } + [DataTreeObjectProperty("static_broker_port", 6)] + public ushort StaticBrokerPort { get; private set; } - public const int PDL = 0x54; + public const int PDL = 0x54; - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("GetSetComponentScope"); - b.AppendLine($"ScopeSlot: {ScopeSlot}"); - b.AppendLine($"ScopeString: {ScopeString}"); - b.AppendLine($"StaticConfigType: {StaticConfigType}"); - b.AppendLine($"StaticBrokerIPv4: {StaticBrokerIPv4}"); - b.AppendLine($"StaticBrokerIPv6: {StaticBrokerIPv6}"); - b.AppendLine($"StaticBrokerPort: {StaticBrokerPort}"); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("GetSetComponentScope"); + b.AppendLine($"ScopeSlot: {ScopeSlot}"); + b.AppendLine($"ScopeString: {ScopeString}"); + b.AppendLine($"StaticConfigType: {StaticConfigType}"); + b.AppendLine($"StaticBrokerIPv4: {StaticBrokerIPv4}"); + b.AppendLine($"StaticBrokerIPv6: {StaticBrokerIPv6}"); + b.AppendLine($"StaticBrokerPort: {StaticBrokerPort}"); - return b.ToString(); - } + return b.ToString(); + } - public static GetSetComponentScope FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.COMPONENT_SCOPE, PDL); + public static GetSetComponentScope FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.COMPONENT_SCOPE, PDL); - return FromPayloadData(msg.ParameterData); - } - public static GetSetComponentScope FromPayloadData(byte[] data) + return FromPayloadData(msg.ParameterData); + } + public static GetSetComponentScope FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + var scopeSlot = Tools.DataToUShort(ref data); + var scopeString = Tools.DataToString(ref data, 63).Replace("\u0000", ""); + var staticConfigType = Tools.DataToEnum(ref data); + IPv4Address? staticBrokerIPv4 = null; + IPAddress staticBrokerIPv6 = null; + switch (staticConfigType) { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var scopeSlot = Tools.DataToUShort(ref data); - var scopeString = Tools.DataToString(ref data, 63).Replace("\u0000", ""); - var staticConfigType = Tools.DataToEnum(ref data); - IPv4Address? staticBrokerIPv4 = null; - IPAddress staticBrokerIPv6 = null; - switch (staticConfigType) - { - case ERDM_StaticConfig.IPv4: - staticBrokerIPv4 = Tools.DataToIPAddressIPv4(ref data); - data = data.Skip(12).ToArray(); - break; - case ERDM_StaticConfig.IPv6: - staticBrokerIPv6 = Tools.DataToIPAddressIPv6(ref data); - break; - case ERDM_StaticConfig.NO: - default: - data = data.Skip(16).ToArray(); - break; - } + case ERDM_StaticConfig.IPv4: + staticBrokerIPv4 = Tools.DataToIPAddressIPv4(ref data); + data = data.Skip(12).ToArray(); + break; + case ERDM_StaticConfig.IPv6: + staticBrokerIPv6 = Tools.DataToIPAddressIPv6(ref data); + break; + case ERDM_StaticConfig.NO: + default: + data = data.Skip(16).ToArray(); + break; + } - ushort staticBrokerPort = Tools.DataToUShort(ref data); - var i = new GetSetComponentScope( - scopeSlot: scopeSlot, - scopeString: scopeString, - staticConfigType: staticConfigType, - staticBrokerIPv4: staticBrokerIPv4, - staticBrokerIPv6: staticBrokerIPv6, - staticBrokerPort: staticBrokerPort); + ushort staticBrokerPort = Tools.DataToUShort(ref data); + var i = new GetSetComponentScope( + scopeSlot: scopeSlot, + scopeString: scopeString, + staticConfigType: staticConfigType, + staticBrokerIPv4: staticBrokerIPv4, + staticBrokerIPv6: staticBrokerIPv6, + staticBrokerPort: staticBrokerPort); - return i; - } - public override byte[] ToPayloadData() - { - List scopeStringBytes = new List(); - scopeStringBytes.AddRange(Tools.ValueToData(this.ScopeString, 62)); - while (scopeStringBytes.Count < 63) - scopeStringBytes.Add(0); + return i; + } + public override byte[] ToPayloadData() + { + List scopeStringBytes = new List(); + scopeStringBytes.AddRange(Tools.ValueToData(this.ScopeString, 62)); + while (scopeStringBytes.Count < 63) + scopeStringBytes.Add(0); - var slotBytes = Tools.ValueToData(this.ScopeSlot); - var configTypeBytes = Tools.ValueToData(this.StaticConfigType); - var brokerPortBytes = Tools.ValueToData(this.StaticBrokerPort); + var slotBytes = Tools.ValueToData(this.ScopeSlot); + var configTypeBytes = Tools.ValueToData(this.StaticConfigType); + var brokerPortBytes = Tools.ValueToData(this.StaticBrokerPort); - List data = new List(); - data.AddRange(slotBytes); - data.AddRange(scopeStringBytes); - data.AddRange(configTypeBytes); - switch (this.StaticConfigType) - { - case ERDM_StaticConfig.IPv4: - data.AddRange(Tools.ValueToData(this.StaticBrokerIPv4)); - data.AddRange(new byte[12]);//Fill the rest with zeros - break; - case ERDM_StaticConfig.IPv6: - data.AddRange(Tools.ValueToData(this.StaticBrokerIPv6)); - break; - case ERDM_StaticConfig.NO: - default: - data.AddRange(new byte[16]);//Fill the rest with zeros - break; - } - data.AddRange(brokerPortBytes); - return data.ToArray(); + List data = new List(); + data.AddRange(slotBytes); + data.AddRange(scopeStringBytes); + data.AddRange(configTypeBytes); + switch (this.StaticConfigType) + { + case ERDM_StaticConfig.IPv4: + data.AddRange(Tools.ValueToData(this.StaticBrokerIPv4)); + data.AddRange(new byte[12]);//Fill the rest with zeros + break; + case ERDM_StaticConfig.IPv6: + data.AddRange(Tools.ValueToData(this.StaticBrokerIPv6)); + break; + case ERDM_StaticConfig.NO: + default: + data.AddRange(new byte[16]);//Fill the rest with zeros + break; } + data.AddRange(brokerPortBytes); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointBackgroundDiscovery.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointBackgroundDiscovery.cs index f587b0f8..e8cbca5b 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointBackgroundDiscovery.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointBackgroundDiscovery.cs @@ -2,55 +2,37 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.BACKGROUND_DISCOVERY, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.BACKGROUND_DISCOVERY, Command.ECommandDublicate.SetRequest)] +public class GetSetEndpointBackgroundDiscovery : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.BACKGROUND_DISCOVERY, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.BACKGROUND_DISCOVERY, Command.ECommandDublicate.SetRequest)] - public class GetSetEndpointBackgroundDiscovery : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetSetEndpointBackgroundDiscovery( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("enabled")] bool backgroundDiscovery = default) { - [DataTreeObjectConstructor] - public GetSetEndpointBackgroundDiscovery( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, - [DataTreeObjectParameter("enabled")] bool backgroundDiscovery = default) - { - this.EndpointId = endpointId; - this.BackgroundDiscovery = backgroundDiscovery; - } - - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("enabled", 1)] - public bool BackgroundDiscovery { get; private set; } - public const int PDL = 0x03; - - public override string ToString() - { - return $"Endpoint: {EndpointId} - BackgroundDiscovery: {BackgroundDiscovery}"; - } - - public static GetSetEndpointBackgroundDiscovery FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.BACKGROUND_DISCOVERY, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetSetEndpointBackgroundDiscovery FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + this.EndpointId = endpointId; + this.BackgroundDiscovery = backgroundDiscovery; + } - var i = new GetSetEndpointBackgroundDiscovery( - endpointId: Tools.DataToUShort(ref data), - backgroundDiscovery: Tools.DataToBool(ref data)); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("enabled", 1)] + public bool BackgroundDiscovery { get; private set; } + public const int PDL = 0x03; - return i; - } + public override string ToString() + { + return $"Endpoint: {EndpointId} - BackgroundDiscovery: {BackgroundDiscovery}"; + } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.BackgroundDiscovery)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.BackgroundDiscovery)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointIdentify.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointIdentify.cs index 83d596af..f51245dc 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointIdentify.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointIdentify.cs @@ -2,55 +2,37 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.IDENTIFY_ENDPOINT, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.IDENTIFY_ENDPOINT, Command.ECommandDublicate.SetRequest)] +public class GetSetIdentifyEndpoint : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.IDENTIFY_ENDPOINT, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.IDENTIFY_ENDPOINT, Command.ECommandDublicate.SetRequest)] - public class GetSetIdentifyEndpoint : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetSetIdentifyEndpoint( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("identify_state")] bool identifyState = default) { - [DataTreeObjectConstructor] - public GetSetIdentifyEndpoint( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, - [DataTreeObjectParameter("identify_state")] bool identifyState = default) - { - this.EndpointId = endpointId; - this.IdentifyState = identifyState; - } - - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("identify_state", 1)] - public bool IdentifyState { get; private set; } - public const int PDL = 0x03; - - public override string ToString() - { - return $"Endpoint: {EndpointId} - Identify: {IdentifyState}"; - } - - public static GetSetIdentifyEndpoint FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.IDENTIFY_ENDPOINT, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetSetIdentifyEndpoint FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + this.EndpointId = endpointId; + this.IdentifyState = identifyState; + } - var i = new GetSetIdentifyEndpoint( - endpointId: Tools.DataToUShort(ref data), - identifyState: Tools.DataToBool(ref data)); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("identify_state", 1)] + public bool IdentifyState { get; private set; } + public const int PDL = 0x03; - return i; - } + public override string ToString() + { + return $"Endpoint: {EndpointId} - Identify: {IdentifyState}"; + } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.IdentifyState)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.IdentifyState)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointLabel.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointLabel.cs index a1e615c3..08d6f505 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointLabel.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointLabel.cs @@ -2,63 +2,45 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.ENDPOINT_LABEL, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.ENDPOINT_LABEL, Command.ECommandDublicate.SetRequest)] +public class GetSetEndpointLabel : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.ENDPOINT_LABEL, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.ENDPOINT_LABEL, Command.ECommandDublicate.SetRequest)] - public class GetSetEndpointLabel : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetSetEndpointLabel( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("label")] string endpointLabel = default) { - [DataTreeObjectConstructor] - public GetSetEndpointLabel( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, - [DataTreeObjectParameter("label")] string endpointLabel = default) - { - this.EndpointId = endpointId; - - if (string.IsNullOrWhiteSpace(endpointLabel)) - return; - - if (endpointLabel.Length > 32) - endpointLabel = endpointLabel.Substring(0, 32); - - this.EndpointLabel = endpointLabel; - } - - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("label", 1)] - public string EndpointLabel { get; private set; } - public const int PDL_MIN = 0x02; - public const int PDL_MAX = PDL_MIN + 32; + this.EndpointId = endpointId; - public override string ToString() - { - return $"Endpoint: {EndpointId} - EndpointLabel: {EndpointLabel}"; - } + if (string.IsNullOrWhiteSpace(endpointLabel)) + return; - public static GetSetEndpointLabel FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.ENDPOINT_LABEL, PDL_MIN, PDL_MAX); + if (endpointLabel.Length > 32) + endpointLabel = endpointLabel.Substring(0, 32); - return FromPayloadData(msg.ParameterData); - } - public static GetSetEndpointLabel FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); + this.EndpointLabel = endpointLabel; + } - var i = new GetSetEndpointLabel( - endpointId: Tools.DataToUShort(ref data), - endpointLabel: Tools.DataToString(ref data)); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("label", 1)] + public string EndpointLabel { get; private set; } + public const int PDL_MIN = 0x02; + public const int PDL_MAX = PDL_MIN + 32; - return i; - } + public override string ToString() + { + return $"Endpoint: {EndpointId} - EndpointLabel: {EndpointLabel}"; + } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.EndpointLabel)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.EndpointLabel)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointMode.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointMode.cs index d2dac5b3..56b0e9e8 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointMode.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointMode.cs @@ -2,62 +2,45 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.ENDPOINT_MODE, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.ENDPOINT_MODE, Command.ECommandDublicate.SetRequest)] +public class GetSetEndpointMode : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.ENDPOINT_MODE, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.ENDPOINT_MODE, Command.ECommandDublicate.SetRequest)] - public class GetSetEndpointMode : AbstractRDMPayloadObject + public GetSetEndpointMode( + ushort endpointId = default, + ERDM_EndpointMode endpointMode = default) { - public GetSetEndpointMode( - ushort endpointId = default, - ERDM_EndpointMode endpointMode = default) - { - this.EndpointId = endpointId; - this.EndpointMode = endpointMode; - } - - [DataTreeObjectConstructor] - public GetSetEndpointMode( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, - [DataTreeObjectParameter("mode")] byte endpointMode = default) : - this(endpointId, (ERDM_EndpointMode)endpointMode) - { - } - - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("mode", 1)] - public ERDM_EndpointMode EndpointMode { get; private set; } - public const int PDL = 0x03; - - public override string ToString() - { - return $"Endpoint: {EndpointId} - EndpointMode: {EndpointMode}"; - } + this.EndpointId = endpointId; + this.EndpointMode = endpointMode; + } - public static GetSetEndpointMode FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.ENDPOINT_MODE, PDL); + [DataTreeObjectConstructor] + public GetSetEndpointMode( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("mode")] byte endpointMode = default) : + this(endpointId, (ERDM_EndpointMode)endpointMode) + { + } - return FromPayloadData(msg.ParameterData); - } - public static GetSetEndpointMode FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("mode", 1)] + public ERDM_EndpointMode EndpointMode { get; private set; } + public const int PDL = 0x03; - var i = new GetSetEndpointMode( - endpointId: Tools.DataToUShort(ref data), - endpointMode: Tools.DataToEnum(ref data)); + public override string ToString() + { + return $"Endpoint: {EndpointId} - EndpointMode: {EndpointMode}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.EndpointMode)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.EndpointMode)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointRDMTrafficEnable.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointRDMTrafficEnable.cs index ea7c735e..5647a720 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointRDMTrafficEnable.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointRDMTrafficEnable.cs @@ -2,55 +2,37 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.RDM_TRAFFIC_ENABLE, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.RDM_TRAFFIC_ENABLE, Command.ECommandDublicate.SetRequest)] +public class GetSetEndpointRDMTrafficEnable : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.RDM_TRAFFIC_ENABLE, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.RDM_TRAFFIC_ENABLE, Command.ECommandDublicate.SetRequest)] - public class GetSetEndpointRDMTrafficEnable : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetSetEndpointRDMTrafficEnable( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("rdm_enabled")] bool rdmTrafficEnabled = default) { - [DataTreeObjectConstructor] - public GetSetEndpointRDMTrafficEnable( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, - [DataTreeObjectParameter("rdm_enabled")] bool rdmTrafficEnabled = default) - { - this.EndpointId = endpointId; - this.RDMTrafficEnabled = rdmTrafficEnabled; - } - - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("rdm_enabled", 1)] - public bool RDMTrafficEnabled { get; private set; } - public const int PDL = 0x03; - - public override string ToString() - { - return $"Endpoint: {EndpointId} - RDM Traffic Enabled: {RDMTrafficEnabled}"; - } - - public static GetSetEndpointRDMTrafficEnable FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.RDM_TRAFFIC_ENABLE, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetSetEndpointRDMTrafficEnable FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + this.EndpointId = endpointId; + this.RDMTrafficEnabled = rdmTrafficEnabled; + } - var i = new GetSetEndpointRDMTrafficEnable( - endpointId: Tools.DataToUShort(ref data), - rdmTrafficEnabled: Tools.DataToBool(ref data)); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("rdm_enabled", 1)] + public bool RDMTrafficEnabled { get; private set; } + public const int PDL = 0x03; - return i; - } + public override string ToString() + { + return $"Endpoint: {EndpointId} - RDM Traffic Enabled: {RDMTrafficEnabled}"; + } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.RDMTrafficEnabled)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.RDMTrafficEnabled)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointToUniverse.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointToUniverse.cs index 198f7998..57bd837b 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointToUniverse.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointToUniverse.cs @@ -2,55 +2,37 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.ENDPOINT_TO_UNIVERSE, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.ENDPOINT_TO_UNIVERSE, Command.ECommandDublicate.SetRequest)] +public class GetSetEndpointToUniverse : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.ENDPOINT_TO_UNIVERSE, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.ENDPOINT_TO_UNIVERSE, Command.ECommandDublicate.SetRequest)] - public class GetSetEndpointToUniverse : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetSetEndpointToUniverse( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("universe")] ushort universe = default) { - [DataTreeObjectConstructor] - public GetSetEndpointToUniverse( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, - [DataTreeObjectParameter("universe")] ushort universe = default) - { - this.EndpointId = endpointId; - this.Universe = universe; - } - - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("universe", 1)] - public ushort Universe { get; private set; } - public const int PDL = 0x04; - - public override string ToString() - { - return $"Endpoint: {EndpointId} to Universe: {Universe}"; - } - - public static GetSetEndpointToUniverse FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.ENDPOINT_TO_UNIVERSE, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetSetEndpointToUniverse FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + this.EndpointId = endpointId; + this.Universe = universe; + } - var i = new GetSetEndpointToUniverse( - endpointId: Tools.DataToUShort(ref data), - universe: Tools.DataToUShort(ref data)); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("universe", 1)] + public ushort Universe { get; private set; } + public const int PDL = 0x04; - return i; - } + public override string ToString() + { + return $"Endpoint: {EndpointId} to Universe: {Universe}"; + } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.Universe)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.Universe)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetSetIPV4_xxx_Mode.cs b/RDMSharp/RDM/PayloadObject/GetSetIPV4_xxx_Mode.cs index 20336283..279def4f 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetIPV4_xxx_Mode.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetIPV4_xxx_Mode.cs @@ -2,56 +2,55 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.IPV4_DHCP_MODE, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.IPV4_DHCP_MODE, Command.ECommandDublicate.SetRequest)] +[DataTreeObject(ERDM_Parameter.IPV4_ZEROCONF_MODE, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.IPV4_ZEROCONF_MODE, Command.ECommandDublicate.SetRequest)] +public class GetSetIPV4_xxx_Mode : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.IPV4_DHCP_MODE, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.IPV4_DHCP_MODE, Command.ECommandDublicate.SetRequest)] - [DataTreeObject(ERDM_Parameter.IPV4_ZEROCONF_MODE, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.IPV4_ZEROCONF_MODE, Command.ECommandDublicate.SetRequest)] - public class GetSetIPV4_xxx_Mode : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetSetIPV4_xxx_Mode( + [DataTreeObjectParameter("id")] uint interfaceId = 0, + [DataTreeObjectParameter("mode")] bool enabled = false) + { + this.InterfaceId = interfaceId; + this.Enabled = enabled; + } + + [DataTreeObjectProperty("id", 0)] + public uint InterfaceId { get; private set; } + [DataTreeObjectProperty("mode", 1)] + public bool Enabled { get; private set; } + public const int PDL = 5; + + public override string ToString() + { + return $"GetSet-xxx-Mode: {InterfaceId} - {Enabled}"; + } + + public static GetSetIPV4_xxx_Mode FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.IPV4_DHCP_MODE, PDL); + + return FromPayloadData(msg.ParameterData); + } + public static GetSetIPV4_xxx_Mode FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + + var i = new GetSetIPV4_xxx_Mode( + interfaceId: Tools.DataToUInt(ref data), + enabled: Tools.DataToBool(ref data)); + + return i; + } + public override byte[] ToPayloadData() { - [DataTreeObjectConstructor] - public GetSetIPV4_xxx_Mode( - [DataTreeObjectParameter("id")] uint interfaceId = 0, - [DataTreeObjectParameter("mode")] bool enabled = false) - { - this.InterfaceId = interfaceId; - this.Enabled = enabled; - } - - [DataTreeObjectProperty("id", 0)] - public uint InterfaceId { get; private set; } - [DataTreeObjectProperty("mode", 1)] - public bool Enabled { get; private set; } - public const int PDL = 5; - - public override string ToString() - { - return $"GetSetDHCPMode: {InterfaceId} - {Enabled}"; - } - - public static GetSetIPV4_xxx_Mode FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.IPV4_DHCP_MODE, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetSetIPV4_xxx_Mode FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new GetSetIPV4_xxx_Mode( - interfaceId: Tools.DataToUInt(ref data), - enabled: Tools.DataToBool(ref data)); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.InterfaceId)); - data.AddRange(Tools.ValueToData(this.Enabled)); - return data.ToArray(); - } + List data = new List(); + data.AddRange(Tools.ValueToData(this.InterfaceId)); + data.AddRange(Tools.ValueToData(this.Enabled)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/GetSetIPv4DefaultRoute.cs b/RDMSharp/RDM/PayloadObject/GetSetIPv4DefaultRoute.cs index 038bc2bc..fa952f4d 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetIPv4DefaultRoute.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetIPv4DefaultRoute.cs @@ -2,55 +2,54 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.IPV4_DEFAULT_ROUTE, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.IPV4_DEFAULT_ROUTE, Command.ECommandDublicate.SetRequest)] +public class GetSetIPv4DefaultRoute : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.IPV4_DEFAULT_ROUTE, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.IPV4_DEFAULT_ROUTE, Command.ECommandDublicate.SetRequest)] - public class GetSetIPv4DefaultRoute : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetSetIPv4DefaultRoute( + [DataTreeObjectParameter("id")] uint interfaceId = 0, + [DataTreeObjectParameter("default_route")] IPv4Address ipAddress = default) + { + this.InterfaceId = interfaceId; + this.IPAddress = ipAddress; + } + + [DataTreeObjectProperty("id", 0)] + public uint InterfaceId { get; private set; } + [DataTreeObjectProperty("default_route", 1)] + public IPv4Address IPAddress { get; private set; } + public const int PDL = 0x08; + + public override string ToString() + { + return $"{InterfaceId} - {IPAddress}"; + } + + public static GetSetIPv4DefaultRoute FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.IPV4_DEFAULT_ROUTE, PDL); + + return FromPayloadData(msg.ParameterData); + } + public static GetSetIPv4DefaultRoute FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + + var i = new GetSetIPv4DefaultRoute( + interfaceId: Tools.DataToUInt(ref data), + ipAddress: Tools.DataToIPAddressIPv4(ref data)); + + return i; + } + + public override byte[] ToPayloadData() { - [DataTreeObjectConstructor] - public GetSetIPv4DefaultRoute( - [DataTreeObjectParameter("id")] uint interfaceId = 0, - [DataTreeObjectParameter("default_route")] IPv4Address ipAddress = default) - { - this.InterfaceId = interfaceId; - this.IPAddress = ipAddress; - } - - [DataTreeObjectProperty("id", 0)] - public uint InterfaceId { get; private set; } - [DataTreeObjectProperty("default_route", 1)] - public IPv4Address IPAddress { get; private set; } - public const int PDL = 0x08; - - public override string ToString() - { - return $"{InterfaceId} - {IPAddress}"; - } - - public static GetSetIPv4DefaultRoute FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.IPV4_DEFAULT_ROUTE, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetSetIPv4DefaultRoute FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new GetSetIPv4DefaultRoute( - interfaceId: Tools.DataToUInt(ref data), - ipAddress: Tools.DataToIPAddressIPv4(ref data)); - - return i; - } - - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.InterfaceId)); - data.AddRange(Tools.ValueToData(this.IPAddress)); - return data.ToArray(); - } + List data = new List(); + data.AddRange(Tools.ValueToData(this.InterfaceId)); + data.AddRange(Tools.ValueToData(this.IPAddress)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetSetIPv4NameServer.cs b/RDMSharp/RDM/PayloadObject/GetSetIPv4NameServer.cs index 5312fa29..370762ea 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetIPv4NameServer.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetIPv4NameServer.cs @@ -2,55 +2,54 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DNS_IPV4_NAME_SERVER, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.DNS_IPV4_NAME_SERVER, Command.ECommandDublicate.SetRequest)] +public class GetSetIPv4NameServer : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.DNS_IPV4_NAME_SERVER, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.DNS_IPV4_NAME_SERVER, Command.ECommandDublicate.SetRequest)] - public class GetSetIPv4NameServer : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetSetIPv4NameServer( + [DataTreeObjectParameter("index")] byte nameServerIndex = 0, + [DataTreeObjectParameter("address")] IPv4Address ipAddress = default) + { + this.NameServerIndex = nameServerIndex; + this.IPAddress = ipAddress; + } + + [DataTreeObjectProperty("index", 0)] + public byte NameServerIndex { get; private set; } + [DataTreeObjectProperty("address", 1)] + public IPv4Address IPAddress { get; private set; } + public const int PDL = 0x05; + + public override string ToString() + { + return $"{NameServerIndex} - {IPAddress}"; + } + + public static GetSetIPv4NameServer FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DNS_IPV4_NAME_SERVER, PDL); + + return FromPayloadData(msg.ParameterData); + } + public static GetSetIPv4NameServer FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + + var i = new GetSetIPv4NameServer( + nameServerIndex: Tools.DataToByte(ref data), + ipAddress: Tools.DataToIPAddressIPv4(ref data)); + + return i; + } + + public override byte[] ToPayloadData() { - [DataTreeObjectConstructor] - public GetSetIPv4NameServer( - [DataTreeObjectParameter("index")] byte nameServerIndex = 0, - [DataTreeObjectParameter("address")] IPv4Address ipAddress = default) - { - this.NameServerIndex = nameServerIndex; - this.IPAddress = ipAddress; - } - - [DataTreeObjectProperty("index", 0)] - public byte NameServerIndex { get; private set; } - [DataTreeObjectProperty("address", 1)] - public IPv4Address IPAddress { get; private set; } - public const int PDL = 0x05; - - public override string ToString() - { - return $"{NameServerIndex} - {IPAddress}"; - } - - public static GetSetIPv4NameServer FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DNS_IPV4_NAME_SERVER, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static GetSetIPv4NameServer FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new GetSetIPv4NameServer( - nameServerIndex: Tools.DataToByte(ref data), - ipAddress: Tools.DataToIPAddressIPv4(ref data)); - - return i; - } - - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.NameServerIndex)); - data.AddRange(Tools.ValueToData(this.IPAddress)); - return data.ToArray(); - } + List data = new List(); + data.AddRange(Tools.ValueToData(this.NameServerIndex)); + data.AddRange(Tools.ValueToData(this.IPAddress)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/GetSetIPv4StaticAddress.cs b/RDMSharp/RDM/PayloadObject/GetSetIPv4StaticAddress.cs index 5319fe93..8988895c 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetIPv4StaticAddress.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetIPv4StaticAddress.cs @@ -3,63 +3,62 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.IPV4_STATIC_ADDRESS, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.IPV4_STATIC_ADDRESS, Command.ECommandDublicate.SetRequest)] +public class GetSetIPv4StaticAddress : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.IPV4_STATIC_ADDRESS, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.IPV4_STATIC_ADDRESS, Command.ECommandDublicate.SetRequest)] - public class GetSetIPv4StaticAddress : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public GetSetIPv4StaticAddress( + [DataTreeObjectParameter("id")] uint interfaceId = 0, + [DataTreeObjectParameter("address")] IPv4Address ipAddress = default, + [DataTreeObjectParameter("netmask")] byte netmask = 24) { - [DataTreeObjectConstructor] - public GetSetIPv4StaticAddress( - [DataTreeObjectParameter("id")] uint interfaceId = 0, - [DataTreeObjectParameter("address")] IPv4Address ipAddress = default, - [DataTreeObjectParameter("netmask")] byte netmask = 24) - { - this.InterfaceId = interfaceId; - this.IPAddress = ipAddress; - if (netmask > 32) - throw new Exception($"The valid range of {nameof(netmask)} is from 0 to 32"); + this.InterfaceId = interfaceId; + this.IPAddress = ipAddress; + if (netmask > 32) + throw new Exception($"The valid range of {nameof(netmask)} is from 0 to 32"); - this.Netmask = netmask; - } + this.Netmask = netmask; + } - [DataTreeObjectProperty("id", 0)] - public uint InterfaceId { get; private set; } - [DataTreeObjectProperty("address", 1)] - public IPv4Address IPAddress { get; private set; } - [DataTreeObjectProperty("netmask", 2)] - public byte Netmask { get; private set; } - public const int PDL = 0x09; + [DataTreeObjectProperty("id", 0)] + public uint InterfaceId { get; private set; } + [DataTreeObjectProperty("address", 1)] + public IPv4Address IPAddress { get; private set; } + [DataTreeObjectProperty("netmask", 2)] + public byte Netmask { get; private set; } + public const int PDL = 0x09; - public override string ToString() - { - return $"{InterfaceId} - {IPAddress}/{Netmask}"; - } + public override string ToString() + { + return $"{InterfaceId} - {IPAddress}/{Netmask}"; + } - public static GetSetIPv4StaticAddress FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.IPV4_STATIC_ADDRESS, PDL); + public static GetSetIPv4StaticAddress FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.IPV4_STATIC_ADDRESS, PDL); - return FromPayloadData(msg.ParameterData); - } - public static GetSetIPv4StaticAddress FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + return FromPayloadData(msg.ParameterData); + } + public static GetSetIPv4StaticAddress FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new GetSetIPv4StaticAddress( - interfaceId: Tools.DataToUInt(ref data), - ipAddress: Tools.DataToIPAddressIPv4(ref data), - netmask: Tools.DataToByte(ref data)); + var i = new GetSetIPv4StaticAddress( + interfaceId: Tools.DataToUInt(ref data), + ipAddress: Tools.DataToIPAddressIPv4(ref data), + netmask: Tools.DataToByte(ref data)); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.InterfaceId)); - data.AddRange(Tools.ValueToData(this.IPAddress)); - data.AddRange(Tools.ValueToData(this.Netmask)); - return data.ToArray(); - } + return i; + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.InterfaceId)); + data.AddRange(Tools.ValueToData(this.IPAddress)); + data.AddRange(Tools.ValueToData(this.Netmask)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/IRDMPayloadObject.cs b/RDMSharp/RDM/PayloadObject/IRDMPayloadObject.cs index 5ac2eb42..8b8e9704 100644 --- a/RDMSharp/RDM/PayloadObject/IRDMPayloadObject.cs +++ b/RDMSharp/RDM/PayloadObject/IRDMPayloadObject.cs @@ -1,7 +1,6 @@ -namespace RDMSharp -{ - public interface IRDMPayloadObject - { - byte[] ToPayloadData(); - } +namespace RDMSharp.PayloadObject; + +public interface IRDMPayloadObject +{ + byte[] ToPayloadData(); } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectIndex.cs b/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectIndex.cs index c4704d3f..f1c9a506 100644 --- a/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectIndex.cs +++ b/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectIndex.cs @@ -1,8 +1,7 @@ -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +public interface IRDMPayloadObjectIndex : IRDMPayloadObject { - public interface IRDMPayloadObjectIndex : IRDMPayloadObject - { - object MinIndex { get; } - object Index { get; } - } + object MinIndex { get; } + object Index { get; } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectOneOf.cs b/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectOneOf.cs index ed5c51b9..71490816 100644 --- a/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectOneOf.cs +++ b/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectOneOf.cs @@ -1,11 +1,10 @@ using System; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +public interface IRDMPayloadObjectOneOf : IRDMPayloadObjectIndex { - public interface IRDMPayloadObjectOneOf : IRDMPayloadObjectIndex - { - Type IndexType { get; } - object Count { get; } - ERDM_Parameter DescriptorParameter { get; } - } + Type IndexType { get; } + object Count { get; } + ERDM_Parameter DescriptorParameter { get; } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectOneOfDescription.cs b/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectOneOfDescription.cs index 48ea228e..cb20805a 100644 --- a/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectOneOfDescription.cs +++ b/RDMSharp/RDM/PayloadObject/IRDMPayloadObjectOneOfDescription.cs @@ -1,8 +1,7 @@ -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +public interface IRDMPayloadObjectOneOfDescription { - public interface IRDMPayloadObjectOneOfDescription - { - object Index { get; } - string Description { get; } - } + object Index { get; } + string Description { get; } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/InterfaceDescriptor.cs b/RDMSharp/RDM/PayloadObject/InterfaceDescriptor.cs new file mode 100644 index 00000000..710d8244 --- /dev/null +++ b/RDMSharp/RDM/PayloadObject/InterfaceDescriptor.cs @@ -0,0 +1,52 @@ +using RDMSharp.Metadata; +using RDMSharp.Metadata.JSON; +using System.Collections.Generic; + +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.LIST_INTERFACES, Command.ECommandDublicate.GetResponse, true, "interfaces")] +public class InterfaceDescriptor : AbstractRDMPayloadObject +{ + [DataTreeObjectConstructor] + public InterfaceDescriptor( + [DataTreeObjectParameter("id")] uint interfaceId = 0, + [DataTreeObjectParameter("hardware_type")] ushort hardwareType = 0) + { + this.InterfaceId = interfaceId; + this._HardwareType = hardwareType; + } + public InterfaceDescriptor(uint interfaceId, EARP_HardwareTypes hardwareType) + { + this.InterfaceId = interfaceId; + this._HardwareType = (ushort)hardwareType; + } + + [DataTreeObjectProperty("id", 0)] + public uint InterfaceId { get; private set; } + [DataTreeObjectProperty("hardware_type", 1)] + public ushort _HardwareType { get; private set; } + public EARP_HardwareTypes HardwareType { get => (EARP_HardwareTypes)this._HardwareType; } + public const int PDL = 6; + + public override string ToString() + { + return $"Id: {InterfaceId} HardwareType: {HardwareType}"; + } + public static InterfaceDescriptor FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + + var i = new InterfaceDescriptor( + interfaceId: Tools.DataToUInt(ref data), + hardwareType: Tools.DataToUShort(ref data)); + + return i; + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.InterfaceId)); + data.AddRange(Tools.ValueToData(this.HardwareType)); + return data.ToArray(); + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMCommunicationStatus.cs b/RDMSharp/RDM/PayloadObject/RDMCommunicationStatus.cs index 4fa952a1..116763ab 100644 --- a/RDMSharp/RDM/PayloadObject/RDMCommunicationStatus.cs +++ b/RDMSharp/RDM/PayloadObject/RDMCommunicationStatus.cs @@ -3,66 +3,65 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.COMMS_STATUS, Command.ECommandDublicate.GetResponse)] +public class RDMCommunicationStatus : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.COMMS_STATUS, Command.ECommandDublicate.GetResponse)] - public class RDMCommunicationStatus : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMCommunicationStatus( + [DataTreeObjectParameter("short_message")] ushort shortMessage = 0, + [DataTreeObjectParameter("length_mismatch")] ushort lengthMismatch = 0, + [DataTreeObjectParameter("checksum_fail")] ushort checksumFail = 0) { - [DataTreeObjectConstructor] - public RDMCommunicationStatus( - [DataTreeObjectParameter("short_message")] ushort shortMessage = 0, - [DataTreeObjectParameter("length_mismatch")] ushort lengthMismatch = 0, - [DataTreeObjectParameter("checksum_fail")] ushort checksumFail = 0) - { - this.ShortMessage = shortMessage; - this.LengthMismatch = lengthMismatch; - this.ChecksumFail = checksumFail; - } + this.ShortMessage = shortMessage; + this.LengthMismatch = lengthMismatch; + this.ChecksumFail = checksumFail; + } - [DataTreeObjectProperty("short_message", 0)] - public ushort ShortMessage { get; private set; } - [DataTreeObjectProperty("length_mismatch", 1)] - public ushort LengthMismatch { get; private set; } - [DataTreeObjectProperty("checksum_fail", 2)] - public ushort ChecksumFail { get; private set; } + [DataTreeObjectProperty("short_message", 0)] + public ushort ShortMessage { get; private set; } + [DataTreeObjectProperty("length_mismatch", 1)] + public ushort LengthMismatch { get; private set; } + [DataTreeObjectProperty("checksum_fail", 2)] + public ushort ChecksumFail { get; private set; } - public const int PDL = 6; + public const int PDL = 6; - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMProxiedDeviceCount"); - b.AppendLine($"ShortMessage: {ShortMessage}"); - b.AppendLine($"LengthMismatch: {LengthMismatch}"); - b.AppendLine($"ChecksumFail: {ChecksumFail}"); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMProxiedDeviceCount"); + b.AppendLine($"ShortMessage: {ShortMessage}"); + b.AppendLine($"LengthMismatch: {LengthMismatch}"); + b.AppendLine($"ChecksumFail: {ChecksumFail}"); - return b.ToString(); - } + return b.ToString(); + } - public static RDMCommunicationStatus FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.COMMS_STATUS, PDL); + public static RDMCommunicationStatus FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.COMMS_STATUS, PDL); - return FromPayloadData(msg.ParameterData); - } - public static RDMCommunicationStatus FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new RDMCommunicationStatus( - shortMessage: Tools.DataToUShort(ref data), - lengthMismatch: Tools.DataToUShort(ref data), - checksumFail: Tools.DataToUShort(ref data) - ); + return FromPayloadData(msg.ParameterData); + } + public static RDMCommunicationStatus FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + var i = new RDMCommunicationStatus( + shortMessage: Tools.DataToUShort(ref data), + lengthMismatch: Tools.DataToUShort(ref data), + checksumFail: Tools.DataToUShort(ref data) + ); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.ShortMessage)); - data.AddRange(Tools.ValueToData(this.LengthMismatch)); - data.AddRange(Tools.ValueToData(this.ChecksumFail)); - return data.ToArray(); - } + return i; + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.ShortMessage)); + data.AddRange(Tools.ValueToData(this.LengthMismatch)); + data.AddRange(Tools.ValueToData(this.ChecksumFail)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMCurve.cs b/RDMSharp/RDM/PayloadObject/RDMCurve.cs index ad36f853..98538e07 100644 --- a/RDMSharp/RDM/PayloadObject/RDMCurve.cs +++ b/RDMSharp/RDM/PayloadObject/RDMCurve.cs @@ -3,63 +3,48 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.CURVE, Command.ECommandDublicate.GetResponse)] +public class RDMCurve : AbstractRDMPayloadObjectOneOf { - [DataTreeObject(ERDM_Parameter.CURVE, Command.ECommandDublicate.GetResponse)] - public class RDMCurve : AbstractRDMPayloadObjectOneOf - { - [DataTreeObjectConstructor] - public RDMCurve( - [DataTreeObjectParameter("curve")] byte currentCurveId = 1, - [DataTreeObjectParameter("curve_count")] byte curves = 0) - { - this.CurrentCurveId = currentCurveId; - this.Curves = curves; - } + [DataTreeObjectConstructor] + public RDMCurve( + [DataTreeObjectParameter("curve")] byte currentCurveId = 1, + [DataTreeObjectParameter("curve_count")] byte curves = 0) + { + this.CurrentCurveId = currentCurveId; + this.Curves = curves; + } - [DataTreeObjectProperty("curve", 0)] - public byte CurrentCurveId { get; private set; } + [DataTreeObjectProperty("curve", 0)] + public byte CurrentCurveId { get; private set; } - [DataTreeObjectDependecieProperty("curve", ERDM_Parameter.CURVE_DESCRIPTION, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("curve_count", 1)] - public byte Curves { get; private set; } + [DataTreeObjectDependecieProperty("curve", ERDM_Parameter.CURVE_DESCRIPTION, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("curve_count", 1)] + public byte Curves { get; private set; } - public override Type IndexType => typeof(byte); - public override object MinIndex => (byte)1; + public override Type IndexType => typeof(byte); + public override object MinIndex => (byte)1; - public override object Index => CurrentCurveId; + public override object Index => CurrentCurveId; - public override object Count => Curves; + public override object Count => Curves; - public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.CURVE_DESCRIPTION; + public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.CURVE_DESCRIPTION; - public const int PDL = 2; - - public override string ToString() - { - return $"RDMCurve: {CurrentCurveId} of {Curves}"; - } - public static RDMCurve FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.CURVE, PDL); + public const int PDL = 2; - return FromPayloadData(msg.ParameterData); - } - public static RDMCurve FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new RDMCurve( - currentCurveId: Tools.DataToByte(ref data), - curves: Tools.DataToByte(ref data)); + public override string ToString() + { + return $"RDMCurve: {CurrentCurveId} of {Curves}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.CurrentCurveId)); - data.AddRange(Tools.ValueToData(this.Curves)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.CurrentCurveId)); + data.AddRange(Tools.ValueToData(this.Curves)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMCurveDescription.cs b/RDMSharp/RDM/PayloadObject/RDMCurveDescription.cs index ff78f625..67d32d89 100644 --- a/RDMSharp/RDM/PayloadObject/RDMCurveDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMCurveDescription.cs @@ -2,66 +2,48 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.CURVE_DESCRIPTION, Command.ECommandDublicate.GetResponse)] +public class RDMCurveDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription { - [DataTreeObject(ERDM_Parameter.CURVE_DESCRIPTION, Command.ECommandDublicate.GetResponse)] - public class RDMCurveDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription - { - [DataTreeObjectConstructor] - public RDMCurveDescription( - [DataTreeObjectParameter("curve")] byte curveId = 1, - [DataTreeObjectParameter("description")] string description = "") - { - this.CurveId = curveId; + [DataTreeObjectConstructor] + public RDMCurveDescription( + [DataTreeObjectParameter("curve")] byte curveId = 1, + [DataTreeObjectParameter("description")] string description = "") + { + this.CurveId = curveId; - if (string.IsNullOrWhiteSpace(description)) - return; + if (string.IsNullOrWhiteSpace(description)) + return; - if (description.Length > 32) - description = description.Substring(0, 32); + if (description.Length > 32) + description = description.Substring(0, 32); - this.Description = description; - } + this.Description = description; + } - [DataTreeObjectProperty("curve", 0)] - public byte CurveId { get; private set; } + [DataTreeObjectProperty("curve", 0)] + public byte CurveId { get; private set; } - [DataTreeObjectProperty("description", 1)] - public string Description { get; private set; } + [DataTreeObjectProperty("description", 1)] + public string Description { get; private set; } - public object MinIndex => (byte)1; - public object Index => CurveId; + public object MinIndex => (byte)1; + public object Index => CurveId; - public const int PDL_MIN = 1; - public const int PDL_MAX = PDL_MIN + 32; - - public override string ToString() - { - return $"RDMCurveDescription: {CurveId} - {Description}"; - } - - public static RDMCurveDescription FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.CURVE_DESCRIPTION, PDL_MIN, PDL_MAX); + public const int PDL_MIN = 1; + public const int PDL_MAX = PDL_MIN + 32; - return FromPayloadData(msg.ParameterData); - } - public static RDMCurveDescription FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - - var i = new RDMCurveDescription( - curveId: Tools.DataToByte(ref data), - description: Tools.DataToString(ref data)); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.CurveId)); - data.AddRange(Tools.ValueToData(this.Description, 32)); - return data.ToArray(); - } + public override string ToString() + { + return $"RDMCurveDescription: {CurveId} - {Description}"; + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.CurveId)); + data.AddRange(Tools.ValueToData(this.Description, 32)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMDMXBlockAddress.cs b/RDMSharp/RDM/PayloadObject/RDMDMXBlockAddress.cs index 2cefba6b..59ca3820 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDMXBlockAddress.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDMXBlockAddress.cs @@ -3,60 +3,59 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DMX_BLOCK_ADDRESS, Command.ECommandDublicate.GetResponse)] +public class RDMDMXBlockAddress : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.DMX_BLOCK_ADDRESS, Command.ECommandDublicate.GetResponse)] - public class RDMDMXBlockAddress : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMDMXBlockAddress( + [DataTreeObjectParameter("total_subdevice_footprint")] ushort totalSubDeviceFootprint = 0, + [DataTreeObjectParameter("base_dmx_address")] ushort baseDMX512Address = 0) + { + this.TotalSubDeviceFootprint = totalSubDeviceFootprint; + this.BaseDMX512Address = baseDMX512Address; + } + + [DataTreeObjectProperty("total_subdevice_footprint", 0)] + public ushort TotalSubDeviceFootprint { get; private set; } + + [DataTreeObjectProperty("base_dmx_address", 1)] + public ushort BaseDMX512Address { get; private set; } + public const int PDL = 4; + + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMDMXBlockAddress"); + b.AppendLine($"TotalSubDeviceFootprint: {TotalSubDeviceFootprint}"); + b.AppendLine($"BaseDMX512Address: {BaseDMX512Address}"); + + return b.ToString(); + } + + public static RDMDMXBlockAddress FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_BLOCK_ADDRESS, PDL); + + return FromPayloadData(msg.ParameterData); + } + public static RDMDMXBlockAddress FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + + var i = new RDMDMXBlockAddress( + totalSubDeviceFootprint: Tools.DataToUShort(ref data), + baseDMX512Address: Tools.DataToUShort(ref data) + ); + + return i; + } + public override byte[] ToPayloadData() { - [DataTreeObjectConstructor] - public RDMDMXBlockAddress( - [DataTreeObjectParameter("total_subdevice_footprint")] ushort totalSubDeviceFootprint = 0, - [DataTreeObjectParameter("base_dmx_address")] ushort baseDMX512Address = 0) - { - this.TotalSubDeviceFootprint = totalSubDeviceFootprint; - this.BaseDMX512Address = baseDMX512Address; - } - - [DataTreeObjectProperty("total_subdevice_footprint", 0)] - public ushort TotalSubDeviceFootprint { get; private set; } - - [DataTreeObjectProperty("base_dmx_address", 1)] - public ushort BaseDMX512Address { get; private set; } - public const int PDL = 4; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMDMXBlockAddress"); - b.AppendLine($"TotalSubDeviceFootprint: {TotalSubDeviceFootprint}"); - b.AppendLine($"BaseDMX512Address: {BaseDMX512Address}"); - - return b.ToString(); - } - - public static RDMDMXBlockAddress FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_BLOCK_ADDRESS, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static RDMDMXBlockAddress FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new RDMDMXBlockAddress( - totalSubDeviceFootprint: Tools.DataToUShort(ref data), - baseDMX512Address: Tools.DataToUShort(ref data) - ); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.TotalSubDeviceFootprint)); - data.AddRange(Tools.ValueToData(this.BaseDMX512Address)); - return data.ToArray(); - } + List data = new List(); + data.AddRange(Tools.ValueToData(this.TotalSubDeviceFootprint)); + data.AddRange(Tools.ValueToData(this.BaseDMX512Address)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs b/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs index c6d6486e..33582ce9 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs @@ -3,62 +3,61 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DMX_PERSONALITY, Command.ECommandDublicate.GetResponse)] +public class RDMDMXPersonality : AbstractRDMPayloadObjectOneOf { - [DataTreeObject(ERDM_Parameter.DMX_PERSONALITY, Command.ECommandDublicate.GetResponse)] - public class RDMDMXPersonality : AbstractRDMPayloadObjectOneOf - { - [DataTreeObjectConstructor] - public RDMDMXPersonality( - [DataTreeObjectParameter("personality")] byte currentPersonality = 1, - [DataTreeObjectParameter("personality_count")] byte ofPersonalities = 0) - { - this.CurrentPersonality = currentPersonality; - this.OfPersonalities = ofPersonalities; - } + [DataTreeObjectConstructor] + public RDMDMXPersonality( + [DataTreeObjectParameter("personality")] byte currentPersonality = 1, + [DataTreeObjectParameter("personality_count")] byte ofPersonalities = 0) + { + this.CurrentPersonality = currentPersonality; + this.OfPersonalities = ofPersonalities; + } - [DataTreeObjectProperty("personality", 0)] - public byte CurrentPersonality { get; private set; } - [DataTreeObjectDependecieProperty("personality", ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("personality", 0)] + public byte CurrentPersonality { get; private set; } + [DataTreeObjectDependecieProperty("personality", ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("personality_count", 1)] - public byte OfPersonalities { get; private set; } + [DataTreeObjectProperty("personality_count", 1)] + public byte OfPersonalities { get; private set; } - public override Type IndexType => CurrentPersonality.GetType(); - public override object MinIndex => (byte)1; - public override object Index => CurrentPersonality; - public override object Count => OfPersonalities; + public override Type IndexType => CurrentPersonality.GetType(); + public override object MinIndex => (byte)1; + public override object Index => CurrentPersonality; + public override object Count => OfPersonalities; - public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION; + public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION; - public const int PDL = 2; + public const int PDL = 2; - public override string ToString() - { - return $"{CurrentPersonality} of {OfPersonalities}"; - } - public static RDMDMXPersonality FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_PERSONALITY, PDL); + public override string ToString() + { + return $"{CurrentPersonality} of {OfPersonalities}"; + } + public static RDMDMXPersonality FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_PERSONALITY, PDL); - return FromPayloadData(msg.ParameterData); - } - public static RDMDMXPersonality FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new RDMDMXPersonality( - currentPersonality: Tools.DataToByte(ref data), - ofPersonalities: Tools.DataToByte(ref data) - ); + return FromPayloadData(msg.ParameterData); + } + public static RDMDMXPersonality FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + var i = new RDMDMXPersonality( + currentPersonality: Tools.DataToByte(ref data), + ofPersonalities: Tools.DataToByte(ref data) + ); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.CurrentPersonality)); - data.AddRange(Tools.ValueToData(this.OfPersonalities)); - return data.ToArray(); - } + return i; + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.CurrentPersonality)); + data.AddRange(Tools.ValueToData(this.OfPersonalities)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs b/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs index 6098402d..805fc5b0 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs @@ -2,75 +2,78 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, Command.ECommandDublicate.GetResponse)] +public class RDMDMXPersonalityDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription { - [DataTreeObject(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, Command.ECommandDublicate.GetResponse)] - public class RDMDMXPersonalityDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription - { - [DataTreeObjectConstructor] - public RDMDMXPersonalityDescription( - [DataTreeObjectParameter("personality")] byte personalityId = 1, - [DataTreeObjectParameter("dmx_slots_required")] ushort slots = 0, - [DataTreeObjectParameter("description")] string description = "") - { - this.PersonalityId = personalityId; - this.Slots = slots; + [DataTreeObjectConstructor] + public RDMDMXPersonalityDescription( + [DataTreeObjectParameter("personality")] byte personalityId = 1, + [DataTreeObjectParameter("dmx_slots_required")] ushort slots = 0, + [DataTreeObjectParameter("description")] string description = "") + { + this.PersonalityId = personalityId; + this.Slots = slots; - if (string.IsNullOrWhiteSpace(description)) - return; + if (string.IsNullOrWhiteSpace(description)) + return; - if (description.Length > 32) - description = description.Substring(0, 32); + if (description.Length > 32) + description = description.Substring(0, 32); - this.Description = description; - } + this.Description = description; + } + + public RDMDMXPersonalityDescription(IPersonality pesronality) : this(pesronality.ID, pesronality.SlotCount, pesronality.Description) + { + } - [DataTreeObjectProperty("personality", 0)] - public byte PersonalityId { get; private set; } + [DataTreeObjectProperty("personality", 0)] + public byte PersonalityId { get; private set; } - [DataTreeObjectDependecieProperty("slot", ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("dmx_slots_required", 1)] - public ushort Slots { get; private set; } + [DataTreeObjectDependecieProperty("slot", ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("dmx_slots_required", 1)] + public ushort Slots { get; private set; } - [DataTreeObjectProperty("description", 2)] - public string Description { get; private set; } + [DataTreeObjectProperty("description", 2)] + public string Description { get; private set; } - public object MinIndex => (byte)1; - public object Index => PersonalityId; + public object MinIndex => (byte)1; + public object Index => PersonalityId; - public const int PDL_MIN = 3; - public const int PDL_MAX = PDL_MIN + 32; + public const int PDL_MIN = 3; + public const int PDL_MAX = PDL_MIN + 32; - public override string ToString() - { - return $"{PersonalityId} ({Slots}) - {Description}"; - } + public override string ToString() + { + return $"{PersonalityId} ({Slots}) - {Description}"; + } - public static RDMDMXPersonalityDescription FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, PDL_MIN, PDL_MAX); + public static RDMDMXPersonalityDescription FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, PDL_MIN, PDL_MAX); - return FromPayloadData(msg.ParameterData); - } - public static RDMDMXPersonalityDescription FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); + return FromPayloadData(msg.ParameterData); + } + public static RDMDMXPersonalityDescription FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - var i = new RDMDMXPersonalityDescription( - personalityId: Tools.DataToByte(ref data), - slots: Tools.DataToUShort(ref data), - description: Tools.DataToString(ref data)); + var i = new RDMDMXPersonalityDescription( + personalityId: Tools.DataToByte(ref data), + slots: Tools.DataToUShort(ref data), + description: Tools.DataToString(ref data)); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.PersonalityId)); - data.AddRange(Tools.ValueToData(this.Slots)); - data.AddRange(Tools.ValueToData(this.Description, 32)); - return data.ToArray(); - } + return i; + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.PersonalityId)); + data.AddRange(Tools.ValueToData(this.Slots)); + data.AddRange(Tools.ValueToData(this.Description, 32)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMDMX_xxxx_Mode.cs b/RDMSharp/RDM/PayloadObject/RDMDMX_xxxx_Mode.cs index a60355f7..388cbda9 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDMX_xxxx_Mode.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDMX_xxxx_Mode.cs @@ -3,79 +3,60 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DMX_FAIL_MODE, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.DMX_FAIL_MODE, Command.ECommandDublicate.SetRequest)] +[DataTreeObject(ERDM_Parameter.DMX_STARTUP_MODE, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.DMX_STARTUP_MODE, Command.ECommandDublicate.SetRequest)] +public class RDMDMX_xxxx_Mode : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.DMX_FAIL_MODE, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.DMX_FAIL_MODE, Command.ECommandDublicate.SetRequest)] - [DataTreeObject(ERDM_Parameter.DMX_STARTUP_MODE, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.DMX_STARTUP_MODE, Command.ECommandDublicate.SetRequest)] - public class RDMDMX_xxxx_Mode : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMDMX_xxxx_Mode( + [DataTreeObjectParameter("scene_num")] ushort scene = 0, + [DataTreeObjectParameter(ERDM_Parameter.DMX_FAIL_MODE, "loss_of_signal_delay_time"), DataTreeObjectParameter(ERDM_Parameter.DMX_STARTUP_MODE, "startup_delay_time")] double delay = 0, + [DataTreeObjectParameter("hold_time")] double holdTime = 0, + [DataTreeObjectParameter("level")] byte level = 0) { - [DataTreeObjectConstructor] - public RDMDMX_xxxx_Mode( - [DataTreeObjectParameter("scene_num")] ushort scene = 0, - [DataTreeObjectParameter(ERDM_Parameter.DMX_FAIL_MODE, "loss_of_signal_delay_time"),DataTreeObjectParameter(ERDM_Parameter.DMX_STARTUP_MODE, "startup_delay_time")] ushort delay = 0, - [DataTreeObjectParameter("hold_time")] ushort holdTime = 0, - [DataTreeObjectParameter("level")] byte level = 0) - { - this.Scene = scene; - this.Delay = delay; - this.HoldTime = holdTime; - this.Level = level; - } - - [DataTreeObjectProperty("scene_num", 0)] - public ushort Scene { get; private set; } - - [DataTreeObjectProperty(ERDM_Parameter.DMX_FAIL_MODE, "loss_of_signal_delay_time", 1)] - [DataTreeObjectProperty(ERDM_Parameter.DMX_STARTUP_MODE, "startup_delay_time", 1)] - public ushort Delay { get; private set; } - - [DataTreeObjectProperty("hold_time", 2)] - public ushort HoldTime { get; private set; } - - [DataTreeObjectProperty("level", 3)] - public byte Level { get; private set; } - public const int PDL = 7; + this.Scene = scene; + this.Delay = delay; + this.HoldTime = holdTime; + this.Level = level; + } - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMDMXFailMode"); - b.AppendLine($"Scene: {Scene}"); - b.AppendLine($"Delay: {Delay}"); - b.AppendLine($"HoldTime: {HoldTime}"); - b.AppendLine($"Level: {Level}"); + [DataTreeObjectProperty("scene_num", 0)] + public ushort Scene { get; private set; } - return b.ToString(); - } + [DataTreeObjectProperty(ERDM_Parameter.DMX_FAIL_MODE, "loss_of_signal_delay_time", 1)] + [DataTreeObjectProperty(ERDM_Parameter.DMX_STARTUP_MODE, "startup_delay_time", 1)] + public double Delay { get; private set; } - public static RDMDMX_xxxx_Mode FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_FAIL_MODE, PDL); + [DataTreeObjectProperty("hold_time", 2)] + public double HoldTime { get; private set; } - return FromPayloadData(msg.ParameterData); - } - public static RDMDMX_xxxx_Mode FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + [DataTreeObjectProperty("level", 3)] + public byte Level { get; private set; } + public const int PDL = 7; - var i = new RDMDMX_xxxx_Mode( - scene: Tools.DataToUShort(ref data), - delay: Tools.DataToUShort(ref data), - holdTime: Tools.DataToUShort(ref data), - level: Tools.DataToByte(ref data)); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMDMX_xxxx_Mode"); + b.AppendLine($"Scene: {Scene}"); + b.AppendLine($"Delay: {Delay}s"); + b.AppendLine($"HoldTime: {HoldTime}s"); + b.AppendLine($"Level: {Level}"); + + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.Scene)); - data.AddRange(Tools.ValueToData(this.Delay)); - data.AddRange(Tools.ValueToData(this.HoldTime)); - data.AddRange(Tools.ValueToData(this.Level)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.Scene)); + data.AddRange(Tools.ValueToData((ushort)(this.Delay * 10))); + data.AddRange(Tools.ValueToData((ushort)(this.HoldTime * 10))); + data.AddRange(Tools.ValueToData(this.Level)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMDefaultSlotValue.cs b/RDMSharp/RDM/PayloadObject/RDMDefaultSlotValue.cs index f692fb62..acefaf4f 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDefaultSlotValue.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDefaultSlotValue.cs @@ -3,57 +3,41 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DEFAULT_SLOT_VALUE, Command.ECommandDublicate.GetResponse, true, "slots")] +public class RDMDefaultSlotValue : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.DEFAULT_SLOT_VALUE, Command.ECommandDublicate.GetResponse, true, "slots")] - public class RDMDefaultSlotValue : AbstractRDMPayloadObject - { - [DataTreeObjectConstructor] - public RDMDefaultSlotValue( - [DataTreeObjectParameter("id")] ushort slotOffset = 0, - [DataTreeObjectParameter("default_value")] byte defaultSlotValue = 0) - { - this.SlotOffset = slotOffset; - this.DefaultSlotValue = defaultSlotValue; - } + [DataTreeObjectConstructor] + public RDMDefaultSlotValue( + [DataTreeObjectParameter("id")] ushort slotOffset = 0, + [DataTreeObjectParameter("default_value")] byte defaultSlotValue = 0) + { + this.SlotOffset = slotOffset; + this.DefaultSlotValue = defaultSlotValue; + } - [DataTreeObjectProperty("id", 0)] - public ushort SlotOffset { get; private set; } - [DataTreeObjectProperty("default_value", 1)] - public byte DefaultSlotValue { get; private set; } - public const int PDL = 3; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMDefaultSlotValue"); - b.AppendLine($"SlotOffset: {SlotOffset}"); - b.AppendLine($"DefaultSlotValue: {DefaultSlotValue}"); + [DataTreeObjectProperty("id", 0)] + public ushort SlotOffset { get; private set; } + [DataTreeObjectProperty("default_value", 1)] + public byte DefaultSlotValue { get; private set; } + public const int PDL = 3; - return b.ToString(); - } - - public static RDMDefaultSlotValue FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DEFAULT_SLOT_VALUE, PDL); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMDefaultSlotValue"); + b.AppendLine($"SlotOffset: {SlotOffset}"); + b.AppendLine($"DefaultSlotValue: {DefaultSlotValue}"); - return FromPayloadData(msg.ParameterData); - } - public static RDMDefaultSlotValue FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + return b.ToString(); + } - var i = new RDMDefaultSlotValue( - slotOffset: Tools.DataToUShort(ref data), - defaultSlotValue: Tools.DataToByte(ref data)); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.SlotOffset)); - data.AddRange(Tools.ValueToData(this.DefaultSlotValue)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.SlotOffset)); + data.AddRange(Tools.ValueToData(this.DefaultSlotValue)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs b/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs index 0c9fabf9..33c97336 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs @@ -3,166 +3,139 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DEVICE_INFO, Command.ECommandDublicate.GetResponse)] +public class RDMDeviceInfo : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.DEVICE_INFO, Command.ECommandDublicate.GetResponse)] - public class RDMDeviceInfo : AbstractRDMPayloadObject + public RDMDeviceInfo( + byte rdmProtocolVersionMajor = 1, + byte rdmProtocolVersionMinor = 0, + ushort deviceModelId = 0, + ERDM_ProductCategoryCoarse productCategoryCoarse = ERDM_ProductCategoryCoarse.NOT_DECLARED, + ERDM_ProductCategoryFine productCategoryFine = ERDM_ProductCategoryFine.NOT_DECLARED, + uint softwareVersionId = 0, + ushort dmx512Footprint = 0, + byte dmx512CurrentPersonality = 0, + byte dmx512NumberOfPersonalities = 0, + ushort dmx512StartAddress = 0, + ushort subDeviceCount = 0, + byte sensorCount = 0) + { + RdmProtocolVersionMajor = rdmProtocolVersionMajor; + RdmProtocolVersionMinor = rdmProtocolVersionMinor; + DeviceModelId = deviceModelId; + ProductCategoryCoarse = productCategoryCoarse; + ProductCategoryFine = productCategoryFine; + SoftwareVersionId = softwareVersionId; + Dmx512Footprint = dmx512Footprint; + Dmx512CurrentPersonality = dmx512CurrentPersonality; + Dmx512NumberOfPersonalities = dmx512NumberOfPersonalities; + Dmx512StartAddress = dmx512StartAddress; + SubDeviceCount = subDeviceCount; + SensorCount = sensorCount; + } + [DataTreeObjectConstructor] + public RDMDeviceInfo( + [DataTreeObjectParameter("protocol_major")] byte rdmProtocolVersionMajor, + [DataTreeObjectParameter("protocol_minor")] byte rdmProtocolVersionMinor, + [DataTreeObjectParameter("device_model_id")] ushort deviceModelId, + [DataTreeObjectParameter("product_category")] ushort productCategory, + [DataTreeObjectParameter("software_version_id")] uint softwareVersionId, + [DataTreeObjectParameter("dmx_footprint")] ushort dmx512Footprint, + [DataTreeObjectParameter("current_personality")] byte dmx512CurrentPersonality, + [DataTreeObjectParameter("personality_count")] byte dmx512NumberOfPersonalities, + [DataTreeObjectParameter("dmx_start_address")] ushort dmx512StartAddress, + [DataTreeObjectParameter("sub_device_count")] ushort subDeviceCount, + [DataTreeObjectParameter("sensor_count")] byte sensorCount) : + this(rdmProtocolVersionMajor, + rdmProtocolVersionMinor, + deviceModelId, + (ERDM_ProductCategoryCoarse)(byte)(productCategory >> 8), + (ERDM_ProductCategoryFine)productCategory, + softwareVersionId, + dmx512Footprint, + dmx512CurrentPersonality, + dmx512NumberOfPersonalities, + dmx512StartAddress, + subDeviceCount, + sensorCount) + { + } + + [DataTreeObjectProperty("protocol_major", 0)] + public byte RdmProtocolVersionMajor { get; private set; } + + [DataTreeObjectProperty("protocol_minor", 1)] + public byte RdmProtocolVersionMinor { get; private set; } + + [DataTreeObjectProperty("device_model_id", 2)] + public ushort DeviceModelId { get; private set; } + public ERDM_ProductCategoryCoarse ProductCategoryCoarse { get; private set; } + public ERDM_ProductCategoryFine ProductCategoryFine { get; private set; } + + [DataTreeObjectProperty("product_category", 3)] + public ushort ProductCategory => (ushort)ProductCategoryFine; + + [DataTreeObjectProperty("software_version_id", 4)] + public uint SoftwareVersionId { get; private set; } + + [DataTreeObjectDependecieProperty("slot", ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("dmx_footprint", 5)] + public ushort? Dmx512Footprint { get; private set; } + + [DataTreeObjectProperty("current_personality", 6)] + public byte? Dmx512CurrentPersonality { get; private set; } + + [DataTreeObjectDependecieProperty("personality", ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("personality", ERDM_Parameter.DMX_PERSONALITY_ID, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("personality_count", 7)] + public byte Dmx512NumberOfPersonalities { get; private set; } + + [DataTreeObjectProperty("dmx_start_address", 8)] + public ushort? Dmx512StartAddress { get; private set; } + + [DataTreeObjectProperty("sub_device_count", 9)] + public ushort SubDeviceCount { get; private set; } + + [DataTreeObjectDependecieProperty("sensor", ERDM_Parameter.SENSOR_DEFINITION, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectDependecieProperty("sensor", ERDM_Parameter.SENSOR_VALUE, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("sensor_count", 10)] + public byte SensorCount { get; private set; } + + public const int PDL = 19; + + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine($"RDM protocol version: {RdmProtocolVersionMajor}.{RdmProtocolVersionMinor}"); + b.AppendLine($"Device model ID: {DeviceModelId}"); + b.AppendLine($"Product category: {ProductCategoryCoarse} / {ProductCategoryFine}"); + b.AppendLine($"Software version ID: 0x{SoftwareVersionId.ToString("X")}"); + b.AppendLine($"DMX512 start address: {Dmx512StartAddress}"); + b.AppendLine($"DMX512 Footprint: {Dmx512Footprint}"); + b.AppendLine($"DMX512 Personality: {Dmx512CurrentPersonality} / {Dmx512NumberOfPersonalities}"); + b.AppendLine($"Number of subdevices: {SubDeviceCount}"); + b.AppendLine($"Number of sensors: {SensorCount}"); + + return b.ToString(); + } + + public override byte[] ToPayloadData() { - public RDMDeviceInfo( - byte rdmProtocolVersionMajor = 1, - byte rdmProtocolVersionMinor = 0, - ushort deviceModelId = 0, - ERDM_ProductCategoryCoarse productCategoryCoarse = ERDM_ProductCategoryCoarse.NOT_DECLARED, - ERDM_ProductCategoryFine productCategoryFine = ERDM_ProductCategoryFine.NOT_DECLARED, - uint softwareVersionId = 0, - ushort dmx512Footprint = 0, - byte dmx512CurrentPersonality = 0, - byte dmx512NumberOfPersonalities = 0, - ushort dmx512StartAddress = 0, - ushort subDeviceCount = 0, - byte sensorCount = 0) - { - RdmProtocolVersionMajor = rdmProtocolVersionMajor; - RdmProtocolVersionMinor = rdmProtocolVersionMinor; - DeviceModelId = deviceModelId; - ProductCategoryCoarse = productCategoryCoarse; - ProductCategoryFine = productCategoryFine; - SoftwareVersionId = softwareVersionId; - Dmx512Footprint = dmx512Footprint; - Dmx512CurrentPersonality = dmx512CurrentPersonality; - Dmx512NumberOfPersonalities = dmx512NumberOfPersonalities; - Dmx512StartAddress = dmx512StartAddress; - SubDeviceCount = subDeviceCount; - SensorCount = sensorCount; - } - [DataTreeObjectConstructor] - public RDMDeviceInfo( - [DataTreeObjectParameter("protocol_major")] byte rdmProtocolVersionMajor, - [DataTreeObjectParameter("protocol_minor")] byte rdmProtocolVersionMinor, - [DataTreeObjectParameter("device_model_id")] ushort deviceModelId, - [DataTreeObjectParameter("product_category")] ushort productCategory, - [DataTreeObjectParameter("software_version_id")] uint softwareVersionId, - [DataTreeObjectParameter("dmx_footprint")] ushort dmx512Footprint, - [DataTreeObjectParameter("current_personality")] byte dmx512CurrentPersonality, - [DataTreeObjectParameter("personality_count")] byte dmx512NumberOfPersonalities, - [DataTreeObjectParameter("dmx_start_address")] ushort dmx512StartAddress, - [DataTreeObjectParameter("sub_device_count")] ushort subDeviceCount, - [DataTreeObjectParameter("sensor_count")] byte sensorCount) : - this(rdmProtocolVersionMajor, - rdmProtocolVersionMinor, - deviceModelId, - (ERDM_ProductCategoryCoarse)(byte)(productCategory >> 8), - (ERDM_ProductCategoryFine)productCategory, - softwareVersionId, - dmx512Footprint, - dmx512CurrentPersonality, - dmx512NumberOfPersonalities, - dmx512StartAddress, - subDeviceCount, - sensorCount) - { - } - - [DataTreeObjectProperty("protocol_major", 0)] - public byte RdmProtocolVersionMajor { get; private set; } - - [DataTreeObjectProperty("protocol_minor", 1)] - public byte RdmProtocolVersionMinor { get; private set; } - - [DataTreeObjectProperty("device_model_id", 2)] - public ushort DeviceModelId { get; private set; } - public ERDM_ProductCategoryCoarse ProductCategoryCoarse { get; private set; } - public ERDM_ProductCategoryFine ProductCategoryFine { get; private set; } - - [DataTreeObjectProperty("product_category", 3)] - public ushort ProductCategory => (ushort)ProductCategoryFine; - - [DataTreeObjectProperty("software_version_id", 4)] - public uint SoftwareVersionId { get; private set; } - - [DataTreeObjectDependecieProperty("slot", ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("dmx_footprint", 5)] - public ushort? Dmx512Footprint { get; private set; } - - [DataTreeObjectProperty("current_personality", 6)] - public byte? Dmx512CurrentPersonality { get; private set; } - - [DataTreeObjectDependecieProperty("personality", ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("personality", ERDM_Parameter.DMX_PERSONALITY_ID, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("personality_count", 7)] - public byte Dmx512NumberOfPersonalities { get; private set; } - - [DataTreeObjectProperty("dmx_start_address", 8)] - public ushort? Dmx512StartAddress { get; private set; } - - [DataTreeObjectProperty("sub_device_count", 9)] - public ushort SubDeviceCount { get; private set; } - - [DataTreeObjectDependecieProperty("sensor", ERDM_Parameter.SENSOR_DEFINITION, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectDependecieProperty("sensor", ERDM_Parameter.SENSOR_VALUE, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("sensor_count", 10)] - public byte SensorCount { get; private set; } - - public const int PDL = 19; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine($"RDM protocol version: {RdmProtocolVersionMajor}.{RdmProtocolVersionMinor}"); - b.AppendLine($"Device model ID: {DeviceModelId}"); - b.AppendLine($"Product category: {ProductCategoryCoarse} / {ProductCategoryFine}"); - b.AppendLine($"Software version ID: 0x{SoftwareVersionId.ToString("X")}"); - b.AppendLine($"DMX512 start address: {Dmx512StartAddress}"); - b.AppendLine($"DMX512 Footprint: {Dmx512Footprint}"); - b.AppendLine($"DMX512 Personality: {Dmx512CurrentPersonality} / {Dmx512NumberOfPersonalities}"); - b.AppendLine($"Number of subdevices: {SubDeviceCount}"); - b.AppendLine($"Number of sensors: {SensorCount}"); - - return b.ToString(); - } - public static RDMDeviceInfo FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DEVICE_INFO, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static RDMDeviceInfo FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new RDMDeviceInfo( - rdmProtocolVersionMajor: Tools.DataToByte(ref data), - rdmProtocolVersionMinor: Tools.DataToByte(ref data), - deviceModelId: Tools.DataToUShort(ref data), - productCategoryCoarse: (ERDM_ProductCategoryCoarse)data[0], //Because we need this byte in productCategoryFine too - productCategoryFine: Tools.DataToEnum(ref data), - softwareVersionId: Tools.DataToUInt(ref data), - dmx512Footprint: Tools.DataToUShort(ref data), - dmx512CurrentPersonality: Tools.DataToByte(ref data), - dmx512NumberOfPersonalities: Tools.DataToByte(ref data), - dmx512StartAddress: Tools.DataToUShort(ref data), - subDeviceCount: Tools.DataToUShort(ref data), - sensorCount: Tools.DataToByte(ref data) - ); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.RdmProtocolVersionMajor)); - data.AddRange(Tools.ValueToData(this.RdmProtocolVersionMinor)); - data.AddRange(Tools.ValueToData(this.DeviceModelId)); - //data.AddRange(Tools.ValueToData(this.ProductCategoryCoarse));//Because we this byte is in productCategoryFine too - data.AddRange(Tools.ValueToData(this.ProductCategoryFine)); - data.AddRange(Tools.ValueToData(this.SoftwareVersionId)); - data.AddRange(Tools.ValueToData(this.Dmx512Footprint)); - data.AddRange(Tools.ValueToData(this.Dmx512CurrentPersonality)); - data.AddRange(Tools.ValueToData(this.Dmx512NumberOfPersonalities)); - data.AddRange(Tools.ValueToData(this.Dmx512StartAddress)); - data.AddRange(Tools.ValueToData(this.SubDeviceCount)); - data.AddRange(Tools.ValueToData(this.SensorCount)); - return data.ToArray(); - } + List data = new List(); + data.AddRange(Tools.ValueToData(this.RdmProtocolVersionMajor)); + data.AddRange(Tools.ValueToData(this.RdmProtocolVersionMinor)); + data.AddRange(Tools.ValueToData(this.DeviceModelId)); + //data.AddRange(Tools.ValueToData(this.ProductCategoryCoarse));//Because we this byte is in productCategoryFine too + data.AddRange(Tools.ValueToData(this.ProductCategoryFine)); + data.AddRange(Tools.ValueToData(this.SoftwareVersionId)); + data.AddRange(Tools.ValueToData(this.Dmx512Footprint)); + data.AddRange(Tools.ValueToData(this.Dmx512CurrentPersonality)); + data.AddRange(Tools.ValueToData(this.Dmx512NumberOfPersonalities)); + data.AddRange(Tools.ValueToData(this.Dmx512StartAddress)); + data.AddRange(Tools.ValueToData(this.SubDeviceCount)); + data.AddRange(Tools.ValueToData(this.SensorCount)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMDimmerInfo.cs b/RDMSharp/RDM/PayloadObject/RDMDimmerInfo.cs index 85527fc9..8e10aa9f 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDimmerInfo.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDimmerInfo.cs @@ -4,96 +4,74 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DIMMER_INFO, Command.ECommandDublicate.GetResponse)] +public class RDMDimmerInfo : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.DIMMER_INFO, Command.ECommandDublicate.GetResponse)] - public class RDMDimmerInfo : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMDimmerInfo( + [DataTreeObjectParameter("min_level_lower_limit")] ushort minimumLevelLowerLimit = 0xFFFF, + [DataTreeObjectParameter("min_level_upper_limit")] ushort minimumLevelUpperLimit = 0xFFFF, + [DataTreeObjectParameter("max_level_lower_limit")] ushort maximumLevelLowerLimit = 0xFFFF, + [DataTreeObjectParameter("max_level_upper_limit")] ushort maximumLevelUpperLimit = 0xFFFF, + [DataTreeObjectParameter("curve_count")] byte numberOfSupportedCurves = 0, + [DataTreeObjectParameter("levels_resolution_bits")] byte levelsResolution = 1, + [DataTreeObjectParameter("min_level_split_levels_supported")] bool minimumLevelSplitLevelsSupported = false) { - [DataTreeObjectConstructor] - public RDMDimmerInfo( - [DataTreeObjectParameter("min_level_lower_limit")] ushort minimumLevelLowerLimit = 0xFFFF, - [DataTreeObjectParameter("min_level_upper_limit")] ushort minimumLevelUpperLimit = 0xFFFF, - [DataTreeObjectParameter("max_level_lower_limit")] ushort maximumLevelLowerLimit = 0xFFFF, - [DataTreeObjectParameter("max_level_upper_limit")] ushort maximumLevelUpperLimit = 0xFFFF, - [DataTreeObjectParameter("curve_count")] byte numberOfSupportedCurves = 0, - [DataTreeObjectParameter("levels_resolution_bits")] byte levelsResolution = 1, - [DataTreeObjectParameter("min_level_split_levels_supported")] bool minimumLevelSplitLevelsSupported = false) - { - if (levelsResolution < 0x01 || levelsResolution > 0x10) - throw new ArgumentOutOfRangeException($"{nameof(levelsResolution)} shold be a value between 1 and 31 but is {levelsResolution}"); - - this.MinimumLevelLowerLimit = minimumLevelLowerLimit; - this.MinimumLevelUpperLimit = minimumLevelUpperLimit; - this.MaximumLevelLowerLimit = maximumLevelLowerLimit; - this.MaximumLevelUpperLimit = maximumLevelUpperLimit; - this.NumberOfSupportedCurves = numberOfSupportedCurves; - this.LevelsResolution = levelsResolution; - this.MinimumLevelSplitLevelsSupported = minimumLevelSplitLevelsSupported; - } - - [DataTreeObjectProperty("min_level_lower_limit", 0)] - public ushort MinimumLevelLowerLimit { get; private set; } - [DataTreeObjectProperty("min_level_upper_limit", 1)] - public ushort MinimumLevelUpperLimit { get; private set; } - [DataTreeObjectProperty("max_level_lower_limit", 2)] - public ushort MaximumLevelLowerLimit { get; private set; } - [DataTreeObjectProperty("max_level_upper_limit", 3)] - public ushort MaximumLevelUpperLimit { get; private set; } - [DataTreeObjectProperty("curve_count", 4)] - public byte NumberOfSupportedCurves { get; private set; } - [DataTreeObjectProperty("levels_resolution_bits", 5)] - public byte LevelsResolution { get; private set; } - [DataTreeObjectProperty("min_level_split_levels_supported", 6)] - public bool MinimumLevelSplitLevelsSupported { get; private set; } - public const int PDL = 11; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMDimmerInfo"); - b.AppendLine($"MinimumLevelLowerLimit: {MinimumLevelLowerLimit}"); - b.AppendLine($"MinimumLevelUpperLimit: {MinimumLevelUpperLimit}"); - b.AppendLine($"MaximumLevelLowerLimit: {MaximumLevelLowerLimit}"); - b.AppendLine($"MaximumLevelUpperLimit: {MaximumLevelUpperLimit}"); - b.AppendLine($"NumberOfSupportedCurves: {NumberOfSupportedCurves}"); - b.AppendLine($"LevelsResolution: {LevelsResolution}"); - b.AppendLine($"MinimumLevelSplitLevelsSupported: {MinimumLevelSplitLevelsSupported}"); + if (levelsResolution < 0x01 || levelsResolution > 0x10) + throw new ArgumentOutOfRangeException($"{nameof(levelsResolution)} shold be a value between 1 and 31 but is {levelsResolution}"); - return b.ToString(); - } + this.MinimumLevelLowerLimit = minimumLevelLowerLimit; + this.MinimumLevelUpperLimit = minimumLevelUpperLimit; + this.MaximumLevelLowerLimit = maximumLevelLowerLimit; + this.MaximumLevelUpperLimit = maximumLevelUpperLimit; + this.NumberOfSupportedCurves = numberOfSupportedCurves; + this.LevelsResolution = levelsResolution; + this.MinimumLevelSplitLevelsSupported = minimumLevelSplitLevelsSupported; + } - public static RDMDimmerInfo FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DIMMER_INFO, PDL); + [DataTreeObjectProperty("min_level_lower_limit", 0)] + public ushort MinimumLevelLowerLimit { get; private set; } + [DataTreeObjectProperty("min_level_upper_limit", 1)] + public ushort MinimumLevelUpperLimit { get; private set; } + [DataTreeObjectProperty("max_level_lower_limit", 2)] + public ushort MaximumLevelLowerLimit { get; private set; } + [DataTreeObjectProperty("max_level_upper_limit", 3)] + public ushort MaximumLevelUpperLimit { get; private set; } + [DataTreeObjectProperty("curve_count", 4)] + public byte NumberOfSupportedCurves { get; private set; } + [DataTreeObjectProperty("levels_resolution_bits", 5)] + public byte LevelsResolution { get; private set; } + [DataTreeObjectProperty("min_level_split_levels_supported", 6)] + public bool MinimumLevelSplitLevelsSupported { get; private set; } + public const int PDL = 11; - return FromPayloadData(msg.ParameterData); - } - public static RDMDimmerInfo FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMDimmerInfo"); + b.AppendLine($"MinimumLevelLowerLimit: {MinimumLevelLowerLimit}"); + b.AppendLine($"MinimumLevelUpperLimit: {MinimumLevelUpperLimit}"); + b.AppendLine($"MaximumLevelLowerLimit: {MaximumLevelLowerLimit}"); + b.AppendLine($"MaximumLevelUpperLimit: {MaximumLevelUpperLimit}"); + b.AppendLine($"NumberOfSupportedCurves: {NumberOfSupportedCurves}"); + b.AppendLine($"LevelsResolution: {LevelsResolution}"); + b.AppendLine($"MinimumLevelSplitLevelsSupported: {MinimumLevelSplitLevelsSupported}"); - var i = new RDMDimmerInfo( - minimumLevelLowerLimit: Tools.DataToUShort(ref data), - minimumLevelUpperLimit: Tools.DataToUShort(ref data), - maximumLevelLowerLimit: Tools.DataToUShort(ref data), - maximumLevelUpperLimit: Tools.DataToUShort(ref data), - numberOfSupportedCurves: Tools.DataToByte(ref data), - levelsResolution: Tools.DataToByte(ref data), - minimumLevelSplitLevelsSupported: Tools.DataToBool(ref data)); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.MinimumLevelLowerLimit)); - data.AddRange(Tools.ValueToData(this.MinimumLevelUpperLimit)); - data.AddRange(Tools.ValueToData(this.MaximumLevelLowerLimit)); - data.AddRange(Tools.ValueToData(this.MaximumLevelUpperLimit)); - data.AddRange(Tools.ValueToData(this.NumberOfSupportedCurves)); - data.AddRange(Tools.ValueToData(this.LevelsResolution)); - data.AddRange(Tools.ValueToData(this.MinimumLevelSplitLevelsSupported)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.MinimumLevelLowerLimit)); + data.AddRange(Tools.ValueToData(this.MinimumLevelUpperLimit)); + data.AddRange(Tools.ValueToData(this.MaximumLevelLowerLimit)); + data.AddRange(Tools.ValueToData(this.MaximumLevelUpperLimit)); + data.AddRange(Tools.ValueToData(this.NumberOfSupportedCurves)); + data.AddRange(Tools.ValueToData(this.LevelsResolution)); + data.AddRange(Tools.ValueToData(this.MinimumLevelSplitLevelsSupported)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMLockStateDescription.cs b/RDMSharp/RDM/PayloadObject/RDMLockStateDescription.cs index 97940bc8..52844bac 100644 --- a/RDMSharp/RDM/PayloadObject/RDMLockStateDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMLockStateDescription.cs @@ -2,65 +2,48 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.LOCK_STATE_DESCRIPTION, Command.ECommandDublicate.GetResponse)] +public class RDMLockStateDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription { - [DataTreeObject(ERDM_Parameter.LOCK_STATE_DESCRIPTION, Command.ECommandDublicate.GetResponse)] - public class RDMLockStateDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription - { - [DataTreeObjectConstructor] - public RDMLockStateDescription( - [DataTreeObjectParameter("state")] byte lockStateId = 1, - [DataTreeObjectParameter("description")] string description = "") - { - this.LockStateId = lockStateId; + [DataTreeObjectConstructor] + public RDMLockStateDescription( + [DataTreeObjectParameter("state")] byte lockStateId = default, + [DataTreeObjectParameter("description")] string description = "") + { + this.LockStateId = lockStateId; - if (string.IsNullOrWhiteSpace(description)) - return; + if (string.IsNullOrWhiteSpace(description)) + return; - if (description.Length > 32) - description = description.Substring(0, 32); + if (description.Length > 32) + description = description.Substring(0, 32); - this.Description = description; - } + this.Description = description; + } - [DataTreeObjectProperty("state", 0)] - public byte LockStateId { get; private set; } - [DataTreeObjectProperty("description", 1)] - public string Description { get; private set; } + [DataTreeObjectProperty("state", 0)] + public byte LockStateId { get; private set; } + [DataTreeObjectProperty("description", 1)] + public string Description { get; private set; } - public object MinIndex => (byte)1; - public object Index => LockStateId; + public object MinIndex => (byte)1; + public object Index => LockStateId; - public const int PDL_MIN = 1; - public const int PDL_MAX = PDL_MIN + 32; - - public override string ToString() - { - return $"RDMLockStateDescription: {LockStateId} - {Description}"; - } - - public static RDMLockStateDescription FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.LOCK_STATE_DESCRIPTION, PDL_MIN, PDL_MAX); + public const int PDL_MIN = 1; + public const int PDL_MAX = PDL_MIN + 32; - return FromPayloadData(msg.ParameterData); - } - public static RDMLockStateDescription FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - - var i = new RDMLockStateDescription( - lockStateId: Tools.DataToByte(ref data), - description: Tools.DataToString(ref data)); + public override string ToString() + { + return $"RDMLockStateDescription: {LockStateId} - {Description}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.LockStateId)); - data.AddRange(Tools.ValueToData(this.Description, 32)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.LockStateId)); + data.AddRange(Tools.ValueToData(this.Description, 32)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMMetadataJson.cs b/RDMSharp/RDM/PayloadObject/RDMMetadataJson.cs index 1c6c320e..275c71be 100644 --- a/RDMSharp/RDM/PayloadObject/RDMMetadataJson.cs +++ b/RDMSharp/RDM/PayloadObject/RDMMetadataJson.cs @@ -3,66 +3,50 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.METADATA_JSON, Command.ECommandDublicate.GetResponse)] +public class RDMMetadataJson : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.METADATA_JSON, Command.ECommandDublicate.GetResponse)] - public class RDMMetadataJson : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMMetadataJson( + [DataTreeObjectParameter("pid")] ushort parameterId, + [DataTreeObjectParameter("json")] string json) : this((ERDM_Parameter)parameterId, json) { - [DataTreeObjectConstructor] - public RDMMetadataJson( - [DataTreeObjectParameter("pid")] ERDM_Parameter parameterId, - [DataTreeObjectParameter("json")] string json) - { - this.ParameterId = parameterId; - this.JSON = json; - } - - [DataTreeObjectProperty("pid", 0)] - public ERDM_Parameter ParameterId { get; private set; } - [DataTreeObjectProperty("json", 1)] - public string JSON { get; private set; } - - public object Index => ParameterId; - - public const int PDL_MIN = 0x02; - public const int PDL_MAX = 0xE7; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMMetadataParameterVersion"); - b.AppendLine($"ParameterId: {ParameterId}"); - b.AppendLine($"JSON: {JSON}"); + } + public RDMMetadataJson( + ERDM_Parameter parameterId, + string json) + { + this.ParameterId = parameterId; + this.JSON = json; + } - return b.ToString(); - } + [DataTreeObjectProperty("pid", 0)] + public ERDM_Parameter ParameterId { get; private set; } + [DataTreeObjectProperty("json", 1)] + public string JSON { get; private set; } - public static RDMMetadataJson FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.METADATA_JSON, PDL_MIN, PDL_MAX); + public object Index => ParameterId; - return FromPayloadData(msg.ParameterData); - } - public static RDMMetadataJson FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); + public const int PDL_MIN = 0x02; + public const int PDL_MAX = 0xE7; - var parameterId = (ERDM_Parameter)Tools.DataToUShort(ref data); - var json = Tools.DataToString(ref data); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMMetadataParameterVersion"); + b.AppendLine($"ParameterId: {ParameterId}"); + b.AppendLine($"JSON: {JSON}"); - var i = new RDMMetadataJson( - parameterId: parameterId, - json: json - ); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.ParameterId)); - data.AddRange(Tools.ValueToData(this.JSON)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.ParameterId)); + data.AddRange(Tools.ValueToData(this.JSON, 0)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMMetadataParameterVersion.cs b/RDMSharp/RDM/PayloadObject/RDMMetadataParameterVersion.cs index 96fa0688..c3443989 100644 --- a/RDMSharp/RDM/PayloadObject/RDMMetadataParameterVersion.cs +++ b/RDMSharp/RDM/PayloadObject/RDMMetadataParameterVersion.cs @@ -3,65 +3,47 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.METADATA_PARAMETER_VERSION, Command.ECommandDublicate.GetResponse)] +public class RDMMetadataParameterVersion : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.METADATA_PARAMETER_VERSION, Command.ECommandDublicate.GetResponse)] - public class RDMMetadataParameterVersion : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMMetadataParameterVersion( + [DataTreeObjectParameter("pid")] ushort parameterId, + [DataTreeObjectParameter("version")] ushort version) : this((ERDM_Parameter)parameterId, version) { - [DataTreeObjectConstructor] - public RDMMetadataParameterVersion( - [DataTreeObjectParameter("pid")] ERDM_Parameter parameterId, - [DataTreeObjectParameter("version")] ushort version) - { - this.ParameterId = parameterId; - this.Version = version; - } - - [DataTreeObjectProperty("pid", 0)] - public ERDM_Parameter ParameterId { get; private set; } - [DataTreeObjectProperty("version", 1)] - public ushort Version { get; private set; } - - public object Index => ParameterId; - - public const int PDL = 0x04; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMMetadataParameterVersion"); - b.AppendLine($"ParameterId: {ParameterId}"); - b.AppendLine($"Version: {Version}"); - - return b.ToString(); - } + } + public RDMMetadataParameterVersion( + ERDM_Parameter parameterId, + ushort version) + { + this.ParameterId = parameterId; + this.Version = version; + } - public static RDMMetadataParameterVersion FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.METADATA_PARAMETER_VERSION, PDL); + [DataTreeObjectProperty("pid", 0)] + public ERDM_Parameter ParameterId { get; private set; } + [DataTreeObjectProperty("version", 1)] + public ushort Version { get; private set; } - return FromPayloadData(msg.ParameterData); - } - public static RDMMetadataParameterVersion FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + public const int PDL = 0x04; - var parameterId = (ERDM_Parameter)Tools.DataToUShort(ref data); - var version = Tools.DataToUShort(ref data); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMMetadataParameterVersion"); + b.AppendLine($"ParameterId: {ParameterId}"); + b.AppendLine($"Version: {Version}"); - var i = new RDMMetadataParameterVersion( - parameterId: parameterId, - version: version - ); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.ParameterId)); - data.AddRange(Tools.ValueToData(this.Version)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.ParameterId)); + data.AddRange(Tools.ValueToData(this.Version)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMMinimumLevel.cs b/RDMSharp/RDM/PayloadObject/RDMMinimumLevel.cs index 0dde6ee8..1ef14f69 100644 --- a/RDMSharp/RDM/PayloadObject/RDMMinimumLevel.cs +++ b/RDMSharp/RDM/PayloadObject/RDMMinimumLevel.cs @@ -3,66 +3,48 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.MINIMUM_LEVEL, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.MINIMUM_LEVEL, Command.ECommandDublicate.SetRequest)] +public class RDMMinimumLevel : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.MINIMUM_LEVEL, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.MINIMUM_LEVEL, Command.ECommandDublicate.SetRequest)] - public class RDMMinimumLevel : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMMinimumLevel( + [DataTreeObjectParameter("min_level_increasing")] ushort minimumLevelIncrease = 0, + [DataTreeObjectParameter("min_level_decreasing")] ushort minimumLevelDecrease = 0, + [DataTreeObjectParameter("on_below_min")] bool onBelowMinimum = false) { - [DataTreeObjectConstructor] - public RDMMinimumLevel( - [DataTreeObjectParameter("min_level_increasing")] ushort minimumLevelIncrease = 0, - [DataTreeObjectParameter("min_level_decreasing")] ushort minimumLevelDecrease = 0, - [DataTreeObjectParameter("on_below_min")] bool onBelowMinimum = false) - { - this.MinimumLevelIncrease = minimumLevelIncrease; - this.MinimumLevelDecrease = minimumLevelDecrease; - this.OnBelowMinimum = onBelowMinimum; - } - - [DataTreeObjectProperty("min_level_increasing", 0)] - public ushort MinimumLevelIncrease { get; private set; } - [DataTreeObjectProperty("min_level_decreasing", 1)] - public ushort MinimumLevelDecrease { get; private set; } - [DataTreeObjectProperty("on_below_min", 2)] - public bool OnBelowMinimum { get; private set; } - public const int PDL = 5; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMMinimumLevel"); - b.AppendLine($"MinimumLevelIncrease: {MinimumLevelIncrease}"); - b.AppendLine($"MinimumLevelDecrease: {MinimumLevelDecrease}"); - b.AppendLine($"OnBelowMinimum: {OnBelowMinimum}"); - - return b.ToString(); - } + this.MinimumLevelIncrease = minimumLevelIncrease; + this.MinimumLevelDecrease = minimumLevelDecrease; + this.OnBelowMinimum = onBelowMinimum; + } - public static RDMMinimumLevel FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.MINIMUM_LEVEL, PDL); + [DataTreeObjectProperty("min_level_increasing", 0)] + public ushort MinimumLevelIncrease { get; private set; } + [DataTreeObjectProperty("min_level_decreasing", 1)] + public ushort MinimumLevelDecrease { get; private set; } + [DataTreeObjectProperty("on_below_min", 2)] + public bool OnBelowMinimum { get; private set; } + public const int PDL = 5; - return FromPayloadData(msg.ParameterData); - } - public static RDMMinimumLevel FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMMinimumLevel"); + b.AppendLine($"MinimumLevelIncrease: {MinimumLevelIncrease}"); + b.AppendLine($"MinimumLevelDecrease: {MinimumLevelDecrease}"); + b.AppendLine($"OnBelowMinimum: {OnBelowMinimum}"); - var i = new RDMMinimumLevel( - minimumLevelIncrease: Tools.DataToUShort(ref data), - minimumLevelDecrease: Tools.DataToUShort(ref data), - onBelowMinimum: Tools.DataToBool(ref data)); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.MinimumLevelIncrease)); - data.AddRange(Tools.ValueToData(this.MinimumLevelDecrease)); - data.AddRange(Tools.ValueToData(this.OnBelowMinimum)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.MinimumLevelIncrease)); + data.AddRange(Tools.ValueToData(this.MinimumLevelDecrease)); + data.AddRange(Tools.ValueToData(this.OnBelowMinimum)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMModulationFrequency.cs b/RDMSharp/RDM/PayloadObject/RDMModulationFrequency.cs index de4916c9..64d92dbf 100644 --- a/RDMSharp/RDM/PayloadObject/RDMModulationFrequency.cs +++ b/RDMSharp/RDM/PayloadObject/RDMModulationFrequency.cs @@ -3,63 +3,48 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.MODULATION_FREQUENCY, Command.ECommandDublicate.GetResponse)] +public class RDMModulationFrequency : AbstractRDMPayloadObjectOneOf { - [DataTreeObject(ERDM_Parameter.MODULATION_FREQUENCY, Command.ECommandDublicate.GetResponse)] - public class RDMModulationFrequency : AbstractRDMPayloadObjectOneOf - { - [DataTreeObjectConstructor] - public RDMModulationFrequency( - [DataTreeObjectParameter("setting")] byte modulationFrequencyId = 1, - [DataTreeObjectParameter("setting_count")] byte modulationFrequencys = 0) - { - this.ModulationFrequencyId = modulationFrequencyId; - this.ModulationFrequencys = modulationFrequencys; - } + [DataTreeObjectConstructor] + public RDMModulationFrequency( + [DataTreeObjectParameter("setting")] byte modulationFrequencyId = 1, + [DataTreeObjectParameter("setting_count")] byte modulationFrequencys = 0) + { + this.ModulationFrequencyId = modulationFrequencyId; + this.ModulationFrequencys = modulationFrequencys; + } - [DataTreeObjectProperty("setting", 0)] - public byte ModulationFrequencyId { get; private set; } + [DataTreeObjectProperty("setting", 0)] + public byte ModulationFrequencyId { get; private set; } - [DataTreeObjectDependecieProperty("setting", ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("setting_count", 1)] - public byte ModulationFrequencys { get; private set; } + [DataTreeObjectDependecieProperty("setting", ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("setting_count", 1)] + public byte ModulationFrequencys { get; private set; } - public override Type IndexType => typeof(byte); - public override object MinIndex => (byte)1; + public override Type IndexType => typeof(byte); + public override object MinIndex => (byte)1; - public override object Index => ModulationFrequencyId; + public override object Index => ModulationFrequencyId; - public override object Count => ModulationFrequencys; + public override object Count => ModulationFrequencys; - public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION; + public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION; - public const int PDL = 2; - - public override string ToString() - { - return $"RDMModulationFrequency: {ModulationFrequencyId} of {ModulationFrequencys}"; - } - public static RDMModulationFrequency FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.MODULATION_FREQUENCY, PDL); + public const int PDL = 2; - return FromPayloadData(msg.ParameterData); - } - public static RDMModulationFrequency FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new RDMModulationFrequency( - modulationFrequencyId: Tools.DataToByte(ref data), - modulationFrequencys: Tools.DataToByte(ref data)); + public override string ToString() + { + return $"RDMModulationFrequency: {ModulationFrequencyId} of {ModulationFrequencys}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.ModulationFrequencyId)); - data.AddRange(Tools.ValueToData(this.ModulationFrequencys)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.ModulationFrequencyId)); + data.AddRange(Tools.ValueToData(this.ModulationFrequencys)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMModulationFrequencyDescription.cs b/RDMSharp/RDM/PayloadObject/RDMModulationFrequencyDescription.cs index 466c366b..30f831ef 100644 --- a/RDMSharp/RDM/PayloadObject/RDMModulationFrequencyDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMModulationFrequencyDescription.cs @@ -2,83 +2,65 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, Command.ECommandDublicate.GetResponse)] +public class RDMModulationFrequencyDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription { - [DataTreeObject(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, Command.ECommandDublicate.GetResponse)] - public class RDMModulationFrequencyDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription - { - [DataTreeObjectConstructor] - public RDMModulationFrequencyDescription( - [DataTreeObjectParameter("setting")] byte modulationFrequencyId = 1, - [DataTreeObjectParameter("frequency")] uint? frequency = null, - [DataTreeObjectParameter("description")] string description = "") - { - this.ModulationFrequencyId = modulationFrequencyId; + [DataTreeObjectConstructor] + public RDMModulationFrequencyDescription( + [DataTreeObjectParameter("setting")] byte modulationFrequencyId = 1, + [DataTreeObjectParameter("frequency")] uint? frequency = null, + [DataTreeObjectParameter("description")] string description = "") + { + this.ModulationFrequencyId = modulationFrequencyId; - if (frequency != uint.MaxValue && frequency.HasValue) - this.Frequency = frequency; + if (frequency != uint.MaxValue && frequency.HasValue) + this.Frequency = frequency; - if (string.IsNullOrWhiteSpace(description)) - return; + if (string.IsNullOrWhiteSpace(description)) + return; - if (description.Length > 32) - description = description.Substring(0, 32); + if (description.Length > 32) + description = description.Substring(0, 32); - this.Description = description; - } + this.Description = description; + } - [DataTreeObjectProperty("setting", 0)] - public byte ModulationFrequencyId { get; private set; } + [DataTreeObjectProperty("setting", 0)] + public byte ModulationFrequencyId { get; private set; } - [DataTreeObjectProperty("frequency", 1)] - public uint? Frequency { get; private set; } + [DataTreeObjectProperty("frequency", 1, uint.MaxValue)] + public uint? Frequency { get; private set; } - [DataTreeObjectProperty("description", 2)] - public string Description { get; private set; } + [DataTreeObjectProperty("description", 2)] + public string Description { get; private set; } - public object MinIndex => (byte)1; - public object Index => ModulationFrequencyId; + public object MinIndex => (byte)1; + public object Index => ModulationFrequencyId; - public const int PDL_MIN = 5; - public const int PDL_MAX = PDL_MIN + 32; - - public override string ToString() - { - if (this.Frequency.HasValue) - return $"RDMModulationFrequencyDescription: {ModulationFrequencyId} ({Frequency}Hz) - {Description}"; - - return $"RDMModulationFrequencyDescription: {ModulationFrequencyId} - {Description}"; - } + public const int PDL_MIN = 5; + public const int PDL_MAX = PDL_MIN + 32; - public static RDMModulationFrequencyDescription FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, PDL_MIN, PDL_MAX); + public override string ToString() + { + if (this.Frequency.HasValue) + return $"RDMModulationFrequencyDescription: {ModulationFrequencyId} ({Frequency}Hz) - {Description}"; - return FromPayloadData(msg.ParameterData); - } - public static RDMModulationFrequencyDescription FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - - var i = new RDMModulationFrequencyDescription( - modulationFrequencyId: Tools.DataToByte(ref data), - frequency: Tools.DataToUInt(ref data), - description: Tools.DataToString(ref data)); + return $"RDMModulationFrequencyDescription: {ModulationFrequencyId} - {Description}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.ModulationFrequencyId)); + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.ModulationFrequencyId)); - if (this.Frequency.HasValue) - data.AddRange(Tools.ValueToData(this.Frequency)); - else - data.AddRange(Tools.ValueToData(uint.MaxValue)); + if (this.Frequency.HasValue) + data.AddRange(Tools.ValueToData(this.Frequency)); + else + data.AddRange(Tools.ValueToData(uint.MaxValue)); - data.AddRange(Tools.ValueToData(this.Description, 32)); - return data.ToArray(); - } + data.AddRange(Tools.ValueToData(this.Description, 32)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMOutputResponseTime.cs b/RDMSharp/RDM/PayloadObject/RDMOutputResponseTime.cs index 7c02ac1d..e31ddb0a 100644 --- a/RDMSharp/RDM/PayloadObject/RDMOutputResponseTime.cs +++ b/RDMSharp/RDM/PayloadObject/RDMOutputResponseTime.cs @@ -3,62 +3,47 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.OUTPUT_RESPONSE_TIME, Command.ECommandDublicate.GetResponse)] +public class RDMOutputResponseTime : AbstractRDMPayloadObjectOneOf { - [DataTreeObject(ERDM_Parameter.OUTPUT_RESPONSE_TIME, Command.ECommandDublicate.GetResponse)] - public class RDMOutputResponseTime : AbstractRDMPayloadObjectOneOf - { - [DataTreeObjectConstructor] - public RDMOutputResponseTime( - [DataTreeObjectParameter("setting")] byte currentResponseTimeId = 1, - [DataTreeObjectParameter("setting_count")] byte responseTimes = 0) - { - this.CurrentResponseTimeId = currentResponseTimeId; - this.ResponseTimes = responseTimes; - } + [DataTreeObjectConstructor] + public RDMOutputResponseTime( + [DataTreeObjectParameter("setting")] byte currentResponseTimeId = 1, + [DataTreeObjectParameter("setting_count")] byte responseTimes = 0) + { + this.CurrentResponseTimeId = currentResponseTimeId; + this.ResponseTimes = responseTimes; + } - [DataTreeObjectProperty("setting", 0)] - public byte CurrentResponseTimeId { get; private set; } - [DataTreeObjectDependecieProperty("setting", ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, Command.ECommandDublicate.GetRequest)] - [DataTreeObjectProperty("setting_count", 1)] - public byte ResponseTimes { get; private set; } + [DataTreeObjectProperty("setting", 0)] + public byte CurrentResponseTimeId { get; private set; } + [DataTreeObjectDependecieProperty("setting", ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, Command.ECommandDublicate.GetRequest)] + [DataTreeObjectProperty("setting_count", 1)] + public byte ResponseTimes { get; private set; } - public override Type IndexType => typeof(byte); - public override object MinIndex => (byte)1; + public override Type IndexType => typeof(byte); + public override object MinIndex => (byte)1; - public override object Index => CurrentResponseTimeId; + public override object Index => CurrentResponseTimeId; - public override object Count => ResponseTimes; + public override object Count => ResponseTimes; - public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION; + public override ERDM_Parameter DescriptorParameter => ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION; - public const int PDL = 2; - - public override string ToString() - { - return $"RDMOutputResponseTime: {CurrentResponseTimeId} of {ResponseTimes}"; - } - public static RDMOutputResponseTime FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.OUTPUT_RESPONSE_TIME, PDL); + public const int PDL = 2; - return FromPayloadData(msg.ParameterData); - } - public static RDMOutputResponseTime FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new RDMOutputResponseTime( - currentResponseTimeId: Tools.DataToByte(ref data), - responseTimes: Tools.DataToByte(ref data)); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.CurrentResponseTimeId)); - data.AddRange(Tools.ValueToData(this.ResponseTimes)); - return data.ToArray(); - } + public override string ToString() + { + return $"RDMOutputResponseTime: {CurrentResponseTimeId} of {ResponseTimes}"; + } + + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.CurrentResponseTimeId)); + data.AddRange(Tools.ValueToData(this.ResponseTimes)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMOutputResponseTimeDescription.cs b/RDMSharp/RDM/PayloadObject/RDMOutputResponseTimeDescription.cs index aafb002c..8a99a389 100644 --- a/RDMSharp/RDM/PayloadObject/RDMOutputResponseTimeDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMOutputResponseTimeDescription.cs @@ -2,65 +2,48 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, Command.ECommandDublicate.GetResponse)] +public class RDMOutputResponseTimeDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription { - [DataTreeObject(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, Command.ECommandDublicate.GetResponse)] - public class RDMOutputResponseTimeDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex, IRDMPayloadObjectOneOfDescription - { - [DataTreeObjectConstructor] - public RDMOutputResponseTimeDescription( - [DataTreeObjectParameter("setting")] byte outputResponseTimeId = 1, - [DataTreeObjectParameter("description")] string description = "") - { - this.OutputResponseTimeId = outputResponseTimeId; + [DataTreeObjectConstructor] + public RDMOutputResponseTimeDescription( + [DataTreeObjectParameter("setting")] byte outputResponseTimeId = 1, + [DataTreeObjectParameter("description")] string description = "") + { + this.OutputResponseTimeId = outputResponseTimeId; - if (string.IsNullOrWhiteSpace(description)) - return; + if (string.IsNullOrWhiteSpace(description)) + return; - if (description.Length > 32) - description = description.Substring(0, 32); + if (description.Length > 32) + description = description.Substring(0, 32); - this.Description = description; - } + this.Description = description; + } - [DataTreeObjectProperty("setting", 0)] - public byte OutputResponseTimeId { get; private set; } - [DataTreeObjectProperty("description", 1)] - public string Description { get; private set; } + [DataTreeObjectProperty("setting", 0)] + public byte OutputResponseTimeId { get; private set; } + [DataTreeObjectProperty("description", 1)] + public string Description { get; private set; } - public object MinIndex => (byte)1; - public object Index => OutputResponseTimeId; + public object MinIndex => (byte)1; + public object Index => OutputResponseTimeId; - public const int PDL_MIN = 1; - public const int PDL_MAX = PDL_MIN + 32; - - public override string ToString() - { - return $"RDMOutputResponseTimeDescription: {OutputResponseTimeId} - {Description}"; - } - - public static RDMOutputResponseTimeDescription FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, PDL_MIN, PDL_MAX); + public const int PDL_MIN = 1; + public const int PDL_MAX = PDL_MIN + 32; - return FromPayloadData(msg.ParameterData); - } - public static RDMOutputResponseTimeDescription FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - - var i = new RDMOutputResponseTimeDescription( - outputResponseTimeId: Tools.DataToByte(ref data), - description: Tools.DataToString(ref data)); + public override string ToString() + { + return $"RDMOutputResponseTimeDescription: {OutputResponseTimeId} - {Description}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.OutputResponseTimeId)); - data.AddRange(Tools.ValueToData(this.Description, 32)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.OutputResponseTimeId)); + data.AddRange(Tools.ValueToData(this.Description, 32)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMParameterDescription.cs b/RDMSharp/RDM/PayloadObject/RDMParameterDescription.cs index 90342a0b..0dcacec6 100644 --- a/RDMSharp/RDM/PayloadObject/RDMParameterDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMParameterDescription.cs @@ -4,143 +4,116 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.PARAMETER_DESCRIPTION, Command.ECommandDublicate.GetResponse)] +public class RDMParameterDescription : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.PARAMETER_DESCRIPTION, Command.ECommandDublicate.GetResponse)] - public class RDMParameterDescription : AbstractRDMPayloadObject + [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060")] + public RDMParameterDescription( + ushort parameterId = 0, + byte pdlSize = 0, + ERDM_DataType dataType = ERDM_DataType.NOT_DEFINED, + ERDM_CommandClass commandClass = ERDM_CommandClass.GET, + byte type = 0, //Obsolete + ERDM_SensorUnit unit = ERDM_SensorUnit.NONE, + ERDM_UnitPrefix prefix = ERDM_UnitPrefix.NONE, + uint minValidValue = 0, + uint maxValidValue = 0, + uint defaultValue = 0, + string description = "") { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060")] - public RDMParameterDescription( - ushort parameterId = 0, - byte pdlSize = 0, - ERDM_DataType dataType = ERDM_DataType.NOT_DEFINED, - ERDM_CommandClass commandClass = ERDM_CommandClass.GET, - byte type = 0, //Obsolete - ERDM_SensorUnit unit = ERDM_SensorUnit.NONE, - ERDM_UnitPrefix prefix = ERDM_UnitPrefix.NONE, - uint minValidValue = 0, - uint maxValidValue = 0, - uint defaultValue = 0, - string description = "") - { - this.ParameterId = parameterId; - this.PDLSize = pdlSize; - this.DataType = dataType; - this.CommandClass = commandClass; + this.ParameterId = parameterId; + this.PDLSize = pdlSize; + this.DataType = dataType; + this.CommandClass = commandClass; #pragma warning disable CS0612 - this.Type = type; + this.Type = type; #pragma warning restore CS0612 - this.Unit = unit; - this.Prefix = prefix; - this.MinValidValue = minValidValue; - this.MaxValidValue = maxValidValue; - this.DefaultValue = defaultValue; - - if (string.IsNullOrWhiteSpace(description)) - return; - - if (description.Length > 32) - description = description.Substring(0, 32); + this.Unit = unit; + this.Prefix = prefix; + this.MinValidValue = minValidValue; + this.MaxValidValue = maxValidValue; + this.DefaultValue = defaultValue; - this.Description = description; - } - [DataTreeObjectConstructor] - public RDMParameterDescription( - [DataTreeObjectParameter("pid")] ushort parameterId, - [DataTreeObjectParameter("pdl")] byte pdlSize, - [DataTreeObjectParameter("data_type")] byte dataType, - [DataTreeObjectParameter("command_class")] byte commandClass, - [DataTreeObjectParameter("type")] byte type, //Obsolete - [DataTreeObjectParameter("unit")] byte unit, - [DataTreeObjectParameter("unit_prefix")] byte prefix, - [DataTreeObjectParameter("min_valid_value")] uint minValidValue, - [DataTreeObjectParameter("max_valid_value")] uint maxValidValue, - [DataTreeObjectParameter("default_value")] uint defaultValue, - [DataTreeObjectParameter("description")] string description) - : this(parameterId, pdlSize, (ERDM_DataType)dataType, (ERDM_CommandClass)commandClass, type, (ERDM_SensorUnit)unit, (ERDM_UnitPrefix)prefix, minValidValue, maxValidValue, defaultValue, description) - { - } + if (string.IsNullOrWhiteSpace(description)) + return; - [DataTreeObjectProperty("pid", 0)] - public ushort ParameterId { get; private set; } - [DataTreeObjectProperty("pdl", 1)] - public byte PDLSize { get; private set; } - [DataTreeObjectProperty("data_type", 2)] - public ERDM_DataType DataType { get; private set; } - [DataTreeObjectProperty("command_class", 3)] - public ERDM_CommandClass CommandClass { get; private set; } + if (description.Length > 32) + description = description.Substring(0, 32); - [DataTreeObjectProperty("type", 4), Obsolete] - public byte Type { get; private set; } //Obsolete - [DataTreeObjectProperty("unit", 5)] - public ERDM_SensorUnit Unit { get; private set; } - [DataTreeObjectProperty("unit_prefix", 6)] - public ERDM_UnitPrefix Prefix { get; private set; } - [DataTreeObjectProperty("min_valid_value", 7)] - public uint MinValidValue { get; private set; } - [DataTreeObjectProperty("max_valid_value", 8)] - public uint MaxValidValue { get; private set; } - [DataTreeObjectProperty("default_value", 9)] - public uint DefaultValue { get; private set; } - [DataTreeObjectProperty("description", 10)] - public string Description { get; private set; } - public const int PDL_MIN = 20; - public const int PDL_MAX = PDL_MIN + 32; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine($"{Description}:"); - b.AppendLine($"DataType: {DataType}"); - b.AppendLine($"CommandClass: {CommandClass}"); - b.AppendLine($"MinValid: {this.Prefix.GetNormalizedValue(this.MinValidValue)}"); - b.AppendLine($"MaxValid: {this.Prefix.GetNormalizedValue(this.MaxValidValue)}"); - b.AppendLine($"Default: {this.Prefix.GetNormalizedValue(this.DefaultValue)}"); - b.AppendLine($"Unit: {Unit}"); - return b.ToString(); - } + this.Description = description; + } + [DataTreeObjectConstructor] + public RDMParameterDescription( + [DataTreeObjectParameter("pid")] ushort parameterId, + [DataTreeObjectParameter("pdl")] byte pdlSize, + [DataTreeObjectParameter("data_type")] byte dataType, + [DataTreeObjectParameter("command_class")] byte commandClass, + [DataTreeObjectParameter("type")] byte type, //Obsolete + [DataTreeObjectParameter("unit")] byte unit, + [DataTreeObjectParameter("unit_prefix")] byte prefix, + [DataTreeObjectParameter("min_valid_value")] uint minValidValue, + [DataTreeObjectParameter("max_valid_value")] uint maxValidValue, + [DataTreeObjectParameter("default_value")] uint defaultValue, + [DataTreeObjectParameter("description")] string description) + : this(parameterId, pdlSize, (ERDM_DataType)dataType, (ERDM_CommandClass)commandClass, type, (ERDM_SensorUnit)unit, (ERDM_UnitPrefix)prefix, minValidValue, maxValidValue, defaultValue, description) + { + } - public static RDMParameterDescription FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.PARAMETER_DESCRIPTION, PDL_MIN, PDL_MAX); + [DataTreeObjectProperty("pid", 0)] + public ushort ParameterId { get; private set; } + [DataTreeObjectProperty("pdl", 1)] + public byte PDLSize { get; private set; } + [DataTreeObjectProperty("data_type", 2)] + public ERDM_DataType DataType { get; private set; } + [DataTreeObjectProperty("command_class", 3)] + public ERDM_CommandClass CommandClass { get; private set; } - return FromPayloadData(msg.ParameterData); - } - public static RDMParameterDescription FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); + [DataTreeObjectProperty("type", 4), Obsolete] + public byte Type { get; private set; } //Obsolete + [DataTreeObjectProperty("unit", 5)] + public ERDM_SensorUnit Unit { get; private set; } + [DataTreeObjectProperty("unit_prefix", 6)] + public ERDM_UnitPrefix Prefix { get; private set; } + [DataTreeObjectProperty("min_valid_value", 7)] + public uint MinValidValue { get; private set; } + [DataTreeObjectProperty("max_valid_value", 8)] + public uint MaxValidValue { get; private set; } + [DataTreeObjectProperty("default_value", 9)] + public uint DefaultValue { get; private set; } + [DataTreeObjectProperty("description", 10)] + public string Description { get; private set; } + public const int PDL_MIN = 20; + public const int PDL_MAX = PDL_MIN + 32; - var i = new RDMParameterDescription( - parameterId: Tools.DataToUShort(ref data), - pdlSize: Tools.DataToByte(ref data), - dataType: Tools.DataToEnum(ref data), - commandClass: Tools.DataToEnum(ref data), - type: Tools.DataToByte(ref data),//Obsolet, but need it in constructor to remove the byte from Data - unit: Tools.DataToEnum(ref data), - prefix: Tools.DataToEnum(ref data), - minValidValue: Tools.DataToUInt(ref data), - maxValidValue: Tools.DataToUInt(ref data), - defaultValue: Tools.DataToUInt(ref data), - description: Tools.DataToString(ref data) - ); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine($"{Description}:"); + b.AppendLine($"DataType: {DataType}"); + b.AppendLine($"CommandClass: {CommandClass}"); + b.AppendLine($"MinValid: {this.Prefix.GetNormalizedValue(this.MinValidValue)}"); + b.AppendLine($"MaxValid: {this.Prefix.GetNormalizedValue(this.MaxValidValue)}"); + b.AppendLine($"Default: {this.Prefix.GetNormalizedValue(this.DefaultValue)}"); + b.AppendLine($"Unit: {Unit}"); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.ParameterId)); - data.AddRange(Tools.ValueToData(this.PDLSize)); - data.AddRange(Tools.ValueToData(this.DataType)); - data.AddRange(Tools.ValueToData(this.CommandClass)); - data.AddRange(Tools.ValueToData((byte)0x00)); - data.AddRange(Tools.ValueToData(this.Unit)); - data.AddRange(Tools.ValueToData(this.Prefix)); - data.AddRange(Tools.ValueToData(this.MinValidValue)); - data.AddRange(Tools.ValueToData(this.MaxValidValue)); - data.AddRange(Tools.ValueToData(this.DefaultValue)); - data.AddRange(Tools.ValueToData(this.Description, 32)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.ParameterId)); + data.AddRange(Tools.ValueToData(this.PDLSize)); + data.AddRange(Tools.ValueToData(this.DataType)); + data.AddRange(Tools.ValueToData(this.CommandClass)); + data.AddRange(Tools.ValueToData(this.Type)); + data.AddRange(Tools.ValueToData(this.Unit)); + data.AddRange(Tools.ValueToData(this.Prefix)); + data.AddRange(Tools.ValueToData(this.MinValidValue)); + data.AddRange(Tools.ValueToData(this.MaxValidValue)); + data.AddRange(Tools.ValueToData(this.DefaultValue)); + data.AddRange(Tools.ValueToData(this.Description, 32)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMPersonalityId.cs b/RDMSharp/RDM/PayloadObject/RDMPersonalityId.cs index 1623e545..80454e68 100644 --- a/RDMSharp/RDM/PayloadObject/RDMPersonalityId.cs +++ b/RDMSharp/RDM/PayloadObject/RDMPersonalityId.cs @@ -3,74 +3,51 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DMX_PERSONALITY_ID, Command.ECommandDublicate.GetResponse)] +public class RDMPersonalityId : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { - [DataTreeObject(ERDM_Parameter.DMX_PERSONALITY_ID, Command.ECommandDublicate.GetResponse)] - public class RDMPersonalityId : AbstractRDMPayloadObject, IRDMPayloadObjectIndex + [DataTreeObjectConstructor] + public RDMPersonalityId( + [DataTreeObjectParameter("personality")] byte personalityId = 0, + [DataTreeObjectParameter("major_id")] uint majorPersonalityId = 0, + [DataTreeObjectParameter("minor_id")] uint minorPersonalityId = 0) { - [DataTreeObjectConstructor] - public RDMPersonalityId( - [DataTreeObjectParameter("personality")] byte personalityId = 0, - [DataTreeObjectParameter("major_id")] ushort majorPersonalityId = 0, - [DataTreeObjectParameter("minor_id")] ushort minorPersonalityId = 0) - { - this.PersonalityId = personalityId; - this.MinorPersonalityId = majorPersonalityId; - this.MinorPersonalityId = minorPersonalityId; - } - - [DataTreeObjectProperty("personality", 0)] - public byte PersonalityId { get; private set; } - [DataTreeObjectProperty("major_id", 1)] - public ushort MajorPersonalityId { get; private set; } - [DataTreeObjectProperty("minor_id", 2)] - public ushort MinorPersonalityId { get; private set; } - - public object MinIndex => (byte)1; - public object Index => PersonalityId; - - public const int PDL = 5; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMPersonalityId"); - b.AppendLine($"PersonalityId: {PersonalityId}"); - b.AppendLine($"MajorPersonalityId: 0x{MajorPersonalityId:X4}"); - b.AppendLine($"MinorPersonalityId: 0x{MinorPersonalityId:X4}"); + this.PersonalityId = personalityId; + this.MajorPersonalityId = majorPersonalityId; + this.MinorPersonalityId = minorPersonalityId; + } - return b.ToString(); - } + [DataTreeObjectProperty("personality", 0)] + public byte PersonalityId { get; private set; } + [DataTreeObjectProperty("major_id", 1)] + public uint MajorPersonalityId { get; private set; } + [DataTreeObjectProperty("minor_id", 2)] + public uint MinorPersonalityId { get; private set; } - public static RDMPersonalityId FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_PERSONALITY_ID, PDL); + public object MinIndex => (byte)1; + public object Index => PersonalityId; - return FromPayloadData(msg.ParameterData); - } - public static RDMPersonalityId FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + public const int PDL = 9; - var personalityId = Tools.DataToByte(ref data); - var majorPersonalityId = Tools.DataToUShort(ref data); - var minorPersonalityId = Tools.DataToUShort(ref data); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMPersonalityId"); + b.AppendLine($"PersonalityId: {PersonalityId}"); + b.AppendLine($"MajorPersonalityId: 0x{MajorPersonalityId:X4}"); + b.AppendLine($"MinorPersonalityId: 0x{MinorPersonalityId:X4}"); - var i = new RDMPersonalityId( - personalityId: personalityId, - majorPersonalityId: majorPersonalityId, - minorPersonalityId: minorPersonalityId - ); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.PersonalityId)); - data.AddRange(Tools.ValueToData(this.MajorPersonalityId)); - data.AddRange(Tools.ValueToData(this.MinorPersonalityId)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.PersonalityId)); + data.AddRange(Tools.ValueToData(this.MajorPersonalityId)); + data.AddRange(Tools.ValueToData(this.MinorPersonalityId)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMPresetInfo.cs b/RDMSharp/RDM/PayloadObject/RDMPresetInfo.cs index aa9ba051..b4c2ce65 100644 --- a/RDMSharp/RDM/PayloadObject/RDMPresetInfo.cs +++ b/RDMSharp/RDM/PayloadObject/RDMPresetInfo.cs @@ -3,230 +3,161 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.PRESET_INFO, Command.ECommandDublicate.GetResponse)] +public class RDMPresetInfo : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.PRESET_INFO, Command.ECommandDublicate.GetResponse)] - public class RDMPresetInfo : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMPresetInfo( + [DataTreeObjectParameter("level_field_supported")] bool levelFieldSupported = false, + [DataTreeObjectParameter("preset_sequence_supported")] bool presetSequenceSupported = false, + [DataTreeObjectParameter("split_times_supported")] bool splitTimesSupported = false, + [DataTreeObjectParameter("dmx_fail_infinite_delay_time_supported")] bool dmx512FailInfiniteDelayTimeSupported = false, + [DataTreeObjectParameter("dmx_fail_infinite_hold_time_supported")] bool dmx512FailInfiniteHoldTimeSupported = false, + [DataTreeObjectParameter("startup_infinite_hold_time_supported")] bool startupInfiniteHoldTimeSupported = false, + [DataTreeObjectParameter("max_scene_number")] ushort maximumSceneNumber = 0, + [DataTreeObjectParameter("preset_min_fade_time")] double minimumPresetFadeTimeSupported = 0, + [DataTreeObjectParameter("preset_max_fade_time")] double maximumPresetFadeTimeSupported = 0, + [DataTreeObjectParameter("preset_min_wait_time")] double minimumPresetWaitTimeSupported = 0, + [DataTreeObjectParameter("preset_max_wait_time")] double maximumPresetWaitTimeSupported = 0, + [DataTreeObjectParameter("dmx_fail_min_delay_time")] double? minimumDMX512FailDelayTimeSupported = null, + [DataTreeObjectParameter("dmx_fail_max_delay_time")] double? maximumDMX512FailDelayTimeSupported = null, + [DataTreeObjectParameter("dmx_fail_min_hold_time")] double? minimumDMX512FailDelayHoldSupported = null, + [DataTreeObjectParameter("dmx_fail_max_hold_time")] double? maximumDMX512FailDelayHoldSupported = null, + [DataTreeObjectParameter("startup_min_delay_time")] double? minimumStartupDelayTimeSupported = null, + [DataTreeObjectParameter("startup_max_delay_time")] double? maximumStartupDelayTimeSupported = null, + [DataTreeObjectParameter("startup_min_hold_time")] double? minimumStartupDelayHoldSupported = null, + [DataTreeObjectParameter("startup_max_hold_time")] double? maximumStartupDelayHoldSupported = null) { - [DataTreeObjectConstructor] - public RDMPresetInfo( - [DataTreeObjectParameter("level_field_supported")] bool levelFieldSupported = false, - [DataTreeObjectParameter("preset_sequence_supported")] bool presetSequenceSupported = false, - [DataTreeObjectParameter("split_times_supported")] bool splitTimesSupported = false, - [DataTreeObjectParameter("dmx_fail_infinite_delay_time_supported")] bool dmx512FailInfiniteDelayTimeSupported = false, - [DataTreeObjectParameter("dmx_fail_infinite_hold_time_supported")] bool dmx512FailInfiniteHoldTimeSupported = false, - [DataTreeObjectParameter("startup_infinite_hold_time_supported")] bool startupInfiniteHoldTimeSupported = false, - [DataTreeObjectParameter("max_scene_number")] ushort maximumSceneNumber = 0, - [DataTreeObjectParameter("preset_min_fade_time")] ushort minimumPresetFadeTimeSupported = 0, - [DataTreeObjectParameter("preset_max_fade_time")] ushort maximumPresetFadeTimeSupported = 0, - [DataTreeObjectParameter("preset_min_wait_time")] ushort minimumPresetWaitTimeSupported = 0, - [DataTreeObjectParameter("preset_max_wait_time")] ushort maximumPresetWaitTimeSupported = 0, - [DataTreeObjectParameter("dmx_fail_min_delay_time")] ushort? minimumDMX512FailDelayTimeSupported = null, - [DataTreeObjectParameter("dmx_fail_max_delay_time")] ushort? maximumDMX512FailDelayTimeSupported = null, - [DataTreeObjectParameter("dmx_fail_min_hold_time")] ushort? minimumDMX512FailDelayHoldSupported = null, - [DataTreeObjectParameter("dmx_fail_max_hold_time")] ushort? maximumDMX512FailDelayHoldSupported = null, - [DataTreeObjectParameter("startup_min_delay_time")] ushort? minimumStartupDelayTimeSupported = null, - [DataTreeObjectParameter("startup_max_delay_time")] ushort? maximumStartupDelayTimeSupported = null, - [DataTreeObjectParameter("startup_min_hold_time")] ushort? minimumStartupDelayHoldSupported = null, - [DataTreeObjectParameter("startup_max_hold_time")] ushort? maximumStartupDelayHoldSupported = null) - { - this.LevelFieldSupported = levelFieldSupported; - this.PresetSequenceSupported = presetSequenceSupported; - this.SplitTimesSupported = splitTimesSupported; - this.DMX512FailInfiniteDelayTimeSupported = dmx512FailInfiniteDelayTimeSupported; - this.DMX512FailInfiniteHoldTimeSupported = dmx512FailInfiniteHoldTimeSupported; - this.StartupInfiniteHoldTimeSupported = startupInfiniteHoldTimeSupported; - this.MaximumSceneNumber = maximumSceneNumber; - this.MinimumPresetFadeTimeSupported = minimumPresetFadeTimeSupported; - this.MaximumPresetFadeTimeSupported = maximumPresetFadeTimeSupported; - this.MinimumPresetWaitTimeSupported = minimumPresetWaitTimeSupported; - this.MaximumPresetWaitTimeSupported = maximumPresetWaitTimeSupported; - this.MinimumDMX512FailDelayTimeSupported = minimumDMX512FailDelayTimeSupported; - this.MaximumDMX512FailDelayTimeSupported = maximumDMX512FailDelayTimeSupported; - this.MinimumDMX512FailDelayHoldSupported = minimumDMX512FailDelayHoldSupported; - this.MaximumDMX512FailDelayHoldSupported = maximumDMX512FailDelayHoldSupported; - this.MinimumStartupDelayTimeSupported = minimumStartupDelayTimeSupported; - this.MaximumStartupDelayTimeSupported = maximumStartupDelayTimeSupported; - this.MinimumStartupDelayHoldSupported = minimumStartupDelayHoldSupported; - this.MaximumStartupDelayHoldSupported = maximumStartupDelayHoldSupported; - } - - [DataTreeObjectProperty("level_field_supported", 0)] - public bool LevelFieldSupported { get; private set; } - [DataTreeObjectProperty("preset_sequence_supported", 1)] - public bool PresetSequenceSupported { get; private set; } - [DataTreeObjectProperty("split_times_supported", 2)] - public bool SplitTimesSupported { get; private set; } - [DataTreeObjectProperty("dmx_fail_infinite_delay_time_supported", 3)] - public bool DMX512FailInfiniteDelayTimeSupported { get; private set; } - [DataTreeObjectProperty("dmx_fail_infinite_hold_time_supported", 4)] - public bool DMX512FailInfiniteHoldTimeSupported { get; private set; } - [DataTreeObjectProperty("startup_infinite_hold_time_supported", 5)] - public bool StartupInfiniteHoldTimeSupported { get; private set; } - [DataTreeObjectProperty("max_scene_number", 6)] - public ushort MaximumSceneNumber { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("preset_min_fade_time", 7)] - public ushort MinimumPresetFadeTimeSupported { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("preset_max_fade_time", 8)] - public ushort MaximumPresetFadeTimeSupported { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("preset_min_wait_time", 9)] - public ushort MinimumPresetWaitTimeSupported { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("preset_max_wait_time", 10)] - public ushort MaximumPresetWaitTimeSupported { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("dmx_fail_min_delay_time", 11)] - public ushort? MinimumDMX512FailDelayTimeSupported { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("dmx_fail_max_delay_time", 12)] - public ushort? MaximumDMX512FailDelayTimeSupported { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("dmx_fail_min_hold_time", 13)] - public ushort? MinimumDMX512FailDelayHoldSupported { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("dmx_fail_max_hold_time", 14)] - public ushort? MaximumDMX512FailDelayHoldSupported { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("startup_min_delay_time", 15)] - public ushort? MinimumStartupDelayTimeSupported { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("startup_max_delay_time", 16)] - public ushort? MaximumStartupDelayTimeSupported { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("startup_min_hold_time", 17)] - public ushort? MinimumStartupDelayHoldSupported { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("startup_max_hold_time", 18)] - public ushort? MaximumStartupDelayHoldSupported { get; private set; } - - public const int PDL = 0x20; + this.LevelFieldSupported = levelFieldSupported; + this.PresetSequenceSupported = presetSequenceSupported; + this.SplitTimesSupported = splitTimesSupported; + this.DMX512FailInfiniteDelayTimeSupported = dmx512FailInfiniteDelayTimeSupported; + this.DMX512FailInfiniteHoldTimeSupported = dmx512FailInfiniteHoldTimeSupported; + this.StartupInfiniteHoldTimeSupported = startupInfiniteHoldTimeSupported; + this.MaximumSceneNumber = maximumSceneNumber; + this.MinimumPresetFadeTimeSupported = minimumPresetFadeTimeSupported; + this.MaximumPresetFadeTimeSupported = maximumPresetFadeTimeSupported; + this.MinimumPresetWaitTimeSupported = minimumPresetWaitTimeSupported; + this.MaximumPresetWaitTimeSupported = maximumPresetWaitTimeSupported; + this.MinimumDMX512FailDelayTimeSupported = minimumDMX512FailDelayTimeSupported; + this.MaximumDMX512FailDelayTimeSupported = maximumDMX512FailDelayTimeSupported; + this.MinimumDMX512FailDelayHoldSupported = minimumDMX512FailDelayHoldSupported; + this.MaximumDMX512FailDelayHoldSupported = maximumDMX512FailDelayHoldSupported; + this.MinimumStartupDelayTimeSupported = minimumStartupDelayTimeSupported; + this.MaximumStartupDelayTimeSupported = maximumStartupDelayTimeSupported; + this.MinimumStartupDelayHoldSupported = minimumStartupDelayHoldSupported; + this.MaximumStartupDelayHoldSupported = maximumStartupDelayHoldSupported; + } - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMPresetInfo"); - if (this.LevelFieldSupported) - b.AppendLine($"LevelFieldSupported: {LevelFieldSupported}"); - if (this.PresetSequenceSupported) - b.AppendLine($"PresetSequenceSupported: {PresetSequenceSupported}"); - if (this.SplitTimesSupported) - b.AppendLine($"SplitTimesSupported: {SplitTimesSupported}"); - if (this.DMX512FailInfiniteDelayTimeSupported) - b.AppendLine($"DMX512FailInfiniteDelayTimeSupported: {DMX512FailInfiniteDelayTimeSupported}"); - if (this.DMX512FailInfiniteHoldTimeSupported) - b.AppendLine($"DMX512FailInfiniteHoldTimeSupported: {DMX512FailInfiniteHoldTimeSupported}"); - if (this.StartupInfiniteHoldTimeSupported) - b.AppendLine($"StartupInfiniteHoldTimeSupported: {StartupInfiniteHoldTimeSupported}"); + [DataTreeObjectProperty("level_field_supported", 0)] + public bool LevelFieldSupported { get; private set; } + [DataTreeObjectProperty("preset_sequence_supported", 1)] + public bool PresetSequenceSupported { get; private set; } + [DataTreeObjectProperty("split_times_supported", 2)] + public bool SplitTimesSupported { get; private set; } + [DataTreeObjectProperty("dmx_fail_infinite_delay_time_supported", 3)] + public bool DMX512FailInfiniteDelayTimeSupported { get; private set; } + [DataTreeObjectProperty("dmx_fail_infinite_hold_time_supported", 4)] + public bool DMX512FailInfiniteHoldTimeSupported { get; private set; } + [DataTreeObjectProperty("startup_infinite_hold_time_supported", 5)] + public bool StartupInfiniteHoldTimeSupported { get; private set; } + [DataTreeObjectProperty("max_scene_number", 6)] + public ushort MaximumSceneNumber { get; private set; } - b.AppendLine($"MaximumSceneNumber: {MaximumSceneNumber}"); - b.AppendLine($"MinimumPresetFadeTimeSupported: {MinimumPresetFadeTimeSupported / 10.0}s"); - b.AppendLine($"MaximumPresetFadeTimeSupported: {MaximumPresetFadeTimeSupported / 10.0}s"); - b.AppendLine($"MinimumPresetWaitTimeSupported: {MinimumPresetWaitTimeSupported / 10.0}s"); - b.AppendLine($"MaximumPresetWaitTimeSupported: {MaximumPresetWaitTimeSupported / 10.0}s"); + [DataTreeObjectProperty("preset_min_fade_time", 7)] + public double MinimumPresetFadeTimeSupported { get; private set; } + [DataTreeObjectProperty("preset_max_fade_time", 8)] + public double MaximumPresetFadeTimeSupported { get; private set; } + [DataTreeObjectProperty("preset_min_wait_time", 9)] + public double MinimumPresetWaitTimeSupported { get; private set; } + [DataTreeObjectProperty("preset_max_wait_time", 10)] + public double MaximumPresetWaitTimeSupported { get; private set; } + [DataTreeObjectProperty("dmx_fail_min_delay_time", 11)] + public double? MinimumDMX512FailDelayTimeSupported { get; private set; } + [DataTreeObjectProperty("dmx_fail_max_delay_time", 12)] + public double? MaximumDMX512FailDelayTimeSupported { get; private set; } + [DataTreeObjectProperty("dmx_fail_min_hold_time", 13)] + public double? MinimumDMX512FailDelayHoldSupported { get; private set; } + [DataTreeObjectProperty("dmx_fail_max_hold_time", 14)] + public double? MaximumDMX512FailDelayHoldSupported { get; private set; } + [DataTreeObjectProperty("startup_min_delay_time", 15)] + public double? MinimumStartupDelayTimeSupported { get; private set; } + [DataTreeObjectProperty("startup_max_delay_time", 16)] + public double? MaximumStartupDelayTimeSupported { get; private set; } + [DataTreeObjectProperty("startup_min_hold_time", 17)] + public double? MinimumStartupDelayHoldSupported { get; private set; } + [DataTreeObjectProperty("startup_max_hold_time", 18)] + public double? MaximumStartupDelayHoldSupported { get; private set; } - if (this.MinimumDMX512FailDelayTimeSupported.HasValue) - b.AppendLine($"MinimumDMX512FailDelayTimeSupported: {MinimumDMX512FailDelayTimeSupported / 10.0}s"); - if (this.MaximumDMX512FailDelayTimeSupported.HasValue) - b.AppendLine($"MaximumDMX512FailDelayTimeSupported: {MaximumDMX512FailDelayTimeSupported / 10.0}s"); - if (this.MinimumDMX512FailDelayHoldSupported.HasValue) - b.AppendLine($"MinimumDMX512FailDelayHoldSupported: {MinimumDMX512FailDelayHoldSupported / 10.0}s"); - if (this.MaximumDMX512FailDelayHoldSupported.HasValue) - b.AppendLine($"MaximumDMX512FailDelayHoldSupported: {MaximumDMX512FailDelayHoldSupported / 10.0}s"); - if (this.MinimumStartupDelayTimeSupported.HasValue) - b.AppendLine($"MinimumStartupDelayTimeSupported: {MinimumStartupDelayTimeSupported / 10.0}s"); - if (this.MaximumStartupDelayTimeSupported.HasValue) - b.AppendLine($"MaximumStartupDelayTimeSupported: {MaximumStartupDelayTimeSupported / 10.0}s"); - if (this.MinimumStartupDelayHoldSupported.HasValue) - b.AppendLine($"MinimumStartupDelayHoldSupported: {MinimumStartupDelayHoldSupported / 10.0}s"); - if (this.MaximumStartupDelayHoldSupported.HasValue) - b.AppendLine($"MaximumStartupDelayHoldSupported: {MaximumStartupDelayHoldSupported / 10.0}s"); + public const int PDL = 0x20; - return b.ToString(); - } + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMPresetInfo"); + if (this.LevelFieldSupported) + b.AppendLine($"LevelFieldSupported: {LevelFieldSupported}"); + if (this.PresetSequenceSupported) + b.AppendLine($"PresetSequenceSupported: {PresetSequenceSupported}"); + if (this.SplitTimesSupported) + b.AppendLine($"SplitTimesSupported: {SplitTimesSupported}"); + if (this.DMX512FailInfiniteDelayTimeSupported) + b.AppendLine($"DMX512FailInfiniteDelayTimeSupported: {DMX512FailInfiniteDelayTimeSupported}"); + if (this.DMX512FailInfiniteHoldTimeSupported) + b.AppendLine($"DMX512FailInfiniteHoldTimeSupported: {DMX512FailInfiniteHoldTimeSupported}"); + if (this.StartupInfiniteHoldTimeSupported) + b.AppendLine($"StartupInfiniteHoldTimeSupported: {StartupInfiniteHoldTimeSupported}"); - public static RDMPresetInfo FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.PRESET_INFO, PDL); + b.AppendLine($"MaximumSceneNumber: {MaximumSceneNumber}"); + b.AppendLine($"MinimumPresetFadeTimeSupported: {MinimumPresetFadeTimeSupported}s"); + b.AppendLine($"MaximumPresetFadeTimeSupported: {MaximumPresetFadeTimeSupported}s"); + b.AppendLine($"MinimumPresetWaitTimeSupported: {MinimumPresetWaitTimeSupported}s"); + b.AppendLine($"MaximumPresetWaitTimeSupported: {MaximumPresetWaitTimeSupported}s"); - return FromPayloadData(msg.ParameterData); - } - public static RDMPresetInfo FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + if (this.MinimumDMX512FailDelayTimeSupported.HasValue) + b.AppendLine($"MinimumDMX512FailDelayTimeSupported: {MinimumDMX512FailDelayTimeSupported}s"); + if (this.MaximumDMX512FailDelayTimeSupported.HasValue) + b.AppendLine($"MaximumDMX512FailDelayTimeSupported: {MaximumDMX512FailDelayTimeSupported}s"); + if (this.MinimumDMX512FailDelayHoldSupported.HasValue) + b.AppendLine($"MinimumDMX512FailDelayHoldSupported: {MinimumDMX512FailDelayHoldSupported}s"); + if (this.MaximumDMX512FailDelayHoldSupported.HasValue) + b.AppendLine($"MaximumDMX512FailDelayHoldSupported: {MaximumDMX512FailDelayHoldSupported}s"); + if (this.MinimumStartupDelayTimeSupported.HasValue) + b.AppendLine($"MinimumStartupDelayTimeSupported: {MinimumStartupDelayTimeSupported}s"); + if (this.MaximumStartupDelayTimeSupported.HasValue) + b.AppendLine($"MaximumStartupDelayTimeSupported: {MaximumStartupDelayTimeSupported}s"); + if (this.MinimumStartupDelayHoldSupported.HasValue) + b.AppendLine($"MinimumStartupDelayHoldSupported: {MinimumStartupDelayHoldSupported}s"); + if (this.MaximumStartupDelayHoldSupported.HasValue) + b.AppendLine($"MaximumStartupDelayHoldSupported: {MaximumStartupDelayHoldSupported}s"); - var i = new RDMPresetInfo( - levelFieldSupported: Tools.DataToBool(ref data), - presetSequenceSupported: Tools.DataToBool(ref data), - splitTimesSupported: Tools.DataToBool(ref data), - dmx512FailInfiniteDelayTimeSupported: Tools.DataToBool(ref data), - dmx512FailInfiniteHoldTimeSupported: Tools.DataToBool(ref data), - startupInfiniteHoldTimeSupported: Tools.DataToBool(ref data), - maximumSceneNumber: Tools.DataToUShort(ref data), - minimumPresetFadeTimeSupported: Tools.DataToUShort(ref data), - maximumPresetFadeTimeSupported: Tools.DataToUShort(ref data), - minimumPresetWaitTimeSupported: Tools.DataToUShort(ref data), - maximumPresetWaitTimeSupported: Tools.DataToUShort(ref data), - minimumDMX512FailDelayTimeSupported: Tools.DataToUShort(ref data), - maximumDMX512FailDelayTimeSupported: Tools.DataToUShort(ref data), - minimumDMX512FailDelayHoldSupported: Tools.DataToUShort(ref data), - maximumDMX512FailDelayHoldSupported: Tools.DataToUShort(ref data), - minimumStartupDelayTimeSupported: Tools.DataToUShort(ref data), - maximumStartupDelayTimeSupported: Tools.DataToUShort(ref data), - minimumStartupDelayHoldSupported: Tools.DataToUShort(ref data), - maximumStartupDelayHoldSupported: Tools.DataToUShort(ref data)); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.LevelFieldSupported)); - data.AddRange(Tools.ValueToData(this.PresetSequenceSupported)); - data.AddRange(Tools.ValueToData(this.SplitTimesSupported)); - data.AddRange(Tools.ValueToData(this.DMX512FailInfiniteDelayTimeSupported)); - data.AddRange(Tools.ValueToData(this.DMX512FailInfiniteHoldTimeSupported)); - data.AddRange(Tools.ValueToData(this.StartupInfiniteHoldTimeSupported)); - data.AddRange(Tools.ValueToData(this.MaximumSceneNumber)); - data.AddRange(Tools.ValueToData(this.MinimumPresetFadeTimeSupported)); - data.AddRange(Tools.ValueToData(this.MaximumPresetFadeTimeSupported)); - data.AddRange(Tools.ValueToData(this.MinimumPresetWaitTimeSupported)); - data.AddRange(Tools.ValueToData(this.MaximumPresetWaitTimeSupported)); - data.AddRange(Tools.ValueToData(this.MinimumDMX512FailDelayTimeSupported ?? ushort.MaxValue)); - data.AddRange(Tools.ValueToData(this.MaximumDMX512FailDelayTimeSupported ?? ushort.MaxValue)); - data.AddRange(Tools.ValueToData(this.MinimumDMX512FailDelayHoldSupported ?? ushort.MaxValue)); - data.AddRange(Tools.ValueToData(this.MaximumDMX512FailDelayHoldSupported ?? ushort.MaxValue)); - data.AddRange(Tools.ValueToData(this.MinimumStartupDelayTimeSupported ?? ushort.MaxValue)); - data.AddRange(Tools.ValueToData(this.MaximumStartupDelayTimeSupported ?? ushort.MaxValue)); - data.AddRange(Tools.ValueToData(this.MinimumStartupDelayHoldSupported ?? ushort.MaxValue)); - data.AddRange(Tools.ValueToData(this.MaximumStartupDelayHoldSupported ?? ushort.MaxValue)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.LevelFieldSupported)); + data.AddRange(Tools.ValueToData(this.PresetSequenceSupported)); + data.AddRange(Tools.ValueToData(this.SplitTimesSupported)); + data.AddRange(Tools.ValueToData(this.DMX512FailInfiniteDelayTimeSupported)); + data.AddRange(Tools.ValueToData(this.DMX512FailInfiniteHoldTimeSupported)); + data.AddRange(Tools.ValueToData(this.StartupInfiniteHoldTimeSupported)); + data.AddRange(Tools.ValueToData(this.MaximumSceneNumber)); + data.AddRange(Tools.ValueToData((ushort)(this.MinimumPresetFadeTimeSupported * 10))); + data.AddRange(Tools.ValueToData((ushort)(this.MaximumPresetFadeTimeSupported * 10))); + data.AddRange(Tools.ValueToData((ushort)(this.MinimumPresetWaitTimeSupported * 10))); + data.AddRange(Tools.ValueToData((ushort)(this.MaximumPresetWaitTimeSupported * 10))); + data.AddRange(Tools.ValueToData((ushort)((this.MinimumDMX512FailDelayTimeSupported ?? ushort.MaxValue) * 10))); + data.AddRange(Tools.ValueToData((ushort)((this.MaximumDMX512FailDelayTimeSupported ?? ushort.MaxValue) * 10))); + data.AddRange(Tools.ValueToData((ushort)((this.MinimumDMX512FailDelayHoldSupported ?? ushort.MaxValue) * 10))); + data.AddRange(Tools.ValueToData((ushort)((this.MaximumDMX512FailDelayHoldSupported ?? ushort.MaxValue) * 10))); + data.AddRange(Tools.ValueToData((ushort)((this.MinimumStartupDelayTimeSupported ?? ushort.MaxValue) * 10))); + data.AddRange(Tools.ValueToData((ushort)((this.MaximumStartupDelayTimeSupported ?? ushort.MaxValue) * 10))); + data.AddRange(Tools.ValueToData((ushort)((this.MinimumStartupDelayHoldSupported ?? ushort.MaxValue) * 10))); + data.AddRange(Tools.ValueToData((ushort)((this.MaximumStartupDelayHoldSupported ?? ushort.MaxValue) * 10))); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMPresetPlayback.cs b/RDMSharp/RDM/PayloadObject/RDMPresetPlayback.cs index ee97ba34..3c9a8761 100644 --- a/RDMSharp/RDM/PayloadObject/RDMPresetPlayback.cs +++ b/RDMSharp/RDM/PayloadObject/RDMPresetPlayback.cs @@ -3,61 +3,60 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.PRESET_PLAYBACK, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.PRESET_PLAYBACK, Command.ECommandDublicate.SetRequest)] +public class RDMPresetPlayback : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.PRESET_PLAYBACK, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.PRESET_PLAYBACK, Command.ECommandDublicate.SetRequest)] - public class RDMPresetPlayback : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMPresetPlayback( + [DataTreeObjectParameter("mode")] ushort mode = 0, + [DataTreeObjectParameter("level")] byte level = 0) + { + this.Mode = mode; + this.Level = level; + } + + public ERDM_PresetPlayback EMode { get { return (ERDM_PresetPlayback)this.Mode; } } + [DataTreeObjectProperty("mode", 0)] + public ushort Mode { get; private set; } + [DataTreeObjectProperty("level", 1)] + public byte Level { get; private set; } + public const int PDL = 3; + + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("PresetPlayback"); + b.AppendLine($"Mode: {EMode}({Mode})"); + b.AppendLine($"Level: {Level}"); + + return b.ToString(); + } + + public static RDMPresetPlayback FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.PRESET_PLAYBACK, PDL); + + return FromPayloadData(msg.ParameterData); + } + public static RDMPresetPlayback FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + + var i = new RDMPresetPlayback( + mode: Tools.DataToUShort(ref data), + level: Tools.DataToByte(ref data) + ); + + return i; + } + public override byte[] ToPayloadData() { - [DataTreeObjectConstructor] - public RDMPresetPlayback( - [DataTreeObjectParameter("mode")] ushort mode = 0, - [DataTreeObjectParameter("level")] byte level = 0) - { - this.Mode = mode; - this.Level = level; - } - - public ERDM_PresetPlayback EMode { get { return (ERDM_PresetPlayback)this.Mode; } } - [DataTreeObjectProperty("mode", 0)] - public ushort Mode { get; private set; } - [DataTreeObjectProperty("level", 1)] - public byte Level { get; private set; } - public const int PDL = 3; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMProxiedDeviceCount"); - b.AppendLine($"Mode: {EMode}({Mode})"); - b.AppendLine($"Level: {Level}"); - - return b.ToString(); - } - - public static RDMPresetPlayback FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.PRESET_PLAYBACK, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static RDMPresetPlayback FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new RDMPresetPlayback( - mode: Tools.DataToUShort(ref data), - level: Tools.DataToByte(ref data) - ); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.Mode)); - data.AddRange(Tools.ValueToData(this.Level)); - return data.ToArray(); - } + List data = new List(); + data.AddRange(Tools.ValueToData(this.Mode)); + data.AddRange(Tools.ValueToData(this.Level)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMPresetStatus.cs b/RDMSharp/RDM/PayloadObject/RDMPresetStatus.cs index a36678c4..8ca9d051 100644 --- a/RDMSharp/RDM/PayloadObject/RDMPresetStatus.cs +++ b/RDMSharp/RDM/PayloadObject/RDMPresetStatus.cs @@ -3,102 +3,73 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.PRESET_STATUS, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.PRESET_STATUS, Command.ECommandDublicate.SetRequest)] +[DataTreeObject(ERDM_Parameter.CAPTURE_PRESET, Command.ECommandDublicate.SetRequest)] +public class RDMPresetStatus : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.PRESET_STATUS, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.PRESET_STATUS, Command.ECommandDublicate.SetRequest)] - [DataTreeObject(ERDM_Parameter.CAPTURE_PRESET, Command.ECommandDublicate.SetRequest)] - public class RDMPresetStatus : AbstractRDMPayloadObject + public RDMPresetStatus( + ushort sceneId = 0, + double upFadeTime = 0, + double downFadeTime = 0, + double waitTime = 0, + ERDM_PresetProgrammed programmed = ERDM_PresetProgrammed.NOT_PROGRAMMED) { - public RDMPresetStatus( - ushort sceneId = 0, - ushort upFadeTime = 0, - ushort downFadeTime = 0, - ushort waitTime = 0, - ERDM_PresetProgrammed programmed = ERDM_PresetProgrammed.NOT_PROGRAMMED) - { - this.SceneId = sceneId; - this.UpFadeTime = upFadeTime; - this.DownFadeTime = downFadeTime; - this.WaitTime = waitTime; - this.EProgrammed = programmed; - } - - [DataTreeObjectConstructor] - public RDMPresetStatus( - [DataTreeObjectParameter("scene_num")] ushort sceneId, - [DataTreeObjectParameter("up_fade_time")] ushort upFadeTime, - [DataTreeObjectParameter("down_fade_time")] ushort downFadeTime, - [DataTreeObjectParameter("wait_time")] ushort waitTime, - [DataTreeObjectParameter("programmed")] byte programmed) - : this(sceneId, upFadeTime, downFadeTime, waitTime, (ERDM_PresetProgrammed)programmed) - { - } - - [DataTreeObjectProperty("scene_num", 0)] - public ushort SceneId { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("up_fade_time", 1)] - public ushort UpFadeTime { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("down_fade_time", 2)] - public ushort DownFadeTime { get; private set; } - /// - /// Tenths of a second - /// - [DataTreeObjectProperty("wait_time", 3)] - public ushort WaitTime { get; private set; } - public ERDM_PresetProgrammed EProgrammed { get { return (ERDM_PresetProgrammed)Programmed; } private set { Programmed = (byte)value; } } - [DataTreeObjectProperty("programmed", 4)] - public byte Programmed { get; private set; } - - public const int PDL = 0x09; + this.SceneId = sceneId; + this.UpFadeTime = upFadeTime; + this.DownFadeTime = downFadeTime; + this.WaitTime = waitTime; + this.EProgrammed = programmed; + } - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMPresetStatus"); - b.AppendLine($"SceneId: {SceneId}"); - b.AppendLine($"UpFadeTime: {UpFadeTime / 10.0}s"); - b.AppendLine($"DownFadeTime: {DownFadeTime / 10.0}s"); - b.AppendLine($"WaitTime: {WaitTime / 10.0}s"); - b.AppendLine($"Programmed: {EProgrammed}"); + [DataTreeObjectConstructor] + public RDMPresetStatus( + [DataTreeObjectParameter("scene_num")] ushort sceneId, + [DataTreeObjectParameter("up_fade_time")] double upFadeTime, + [DataTreeObjectParameter("down_fade_time")] double downFadeTime, + [DataTreeObjectParameter("wait_time")] double waitTime, + [DataTreeObjectParameter("programmed")] byte programmed) + : this(sceneId, upFadeTime, downFadeTime, waitTime, (ERDM_PresetProgrammed)programmed) + { + } - return b.ToString(); - } + [DataTreeObjectProperty("scene_num", 0)] + public ushort SceneId { get; private set; } + [DataTreeObjectProperty("up_fade_time", 1)] + public double UpFadeTime { get; private set; } + [DataTreeObjectProperty("down_fade_time", 2)] + public double DownFadeTime { get; private set; } + [DataTreeObjectProperty("wait_time", 3)] + public double WaitTime { get; private set; } + public ERDM_PresetProgrammed EProgrammed { get { return (ERDM_PresetProgrammed)Programmed; } private set { Programmed = (byte)value; } } + [DataTreeObjectProperty("programmed", 4)] + public byte Programmed { get; private set; } - public static RDMPresetStatus FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.PRESET_STATUS, PDL); + public const int PDL = 0x09; - return FromPayloadData(msg.ParameterData); - } - public static RDMPresetStatus FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMPresetStatus"); + b.AppendLine($"SceneId: {SceneId}"); + b.AppendLine($"UpFadeTime: {UpFadeTime}s"); + b.AppendLine($"DownFadeTime: {DownFadeTime}s"); + b.AppendLine($"WaitTime: {WaitTime}s"); + b.AppendLine($"Programmed: {EProgrammed}"); - var i = new RDMPresetStatus( - sceneId: Tools.DataToUShort(ref data), - upFadeTime: Tools.DataToUShort(ref data), - downFadeTime: Tools.DataToUShort(ref data), - waitTime: Tools.DataToUShort(ref data), - programmed: Tools.DataToEnum(ref data)); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.SceneId)); - data.AddRange(Tools.ValueToData(this.UpFadeTime)); - data.AddRange(Tools.ValueToData(this.DownFadeTime)); - data.AddRange(Tools.ValueToData(this.WaitTime)); - data.AddRange(Tools.ValueToData(this.EProgrammed)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.SceneId)); + data.AddRange(Tools.ValueToData((ushort)(this.UpFadeTime * 1))); + data.AddRange(Tools.ValueToData((ushort)(this.DownFadeTime * 1))); + data.AddRange(Tools.ValueToData((ushort)(this.WaitTime * 1))); + data.AddRange(Tools.ValueToData(this.EProgrammed)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMProxiedDeviceCount.cs b/RDMSharp/RDM/PayloadObject/RDMProxiedDeviceCount.cs index e3c38cda..5752e381 100644 --- a/RDMSharp/RDM/PayloadObject/RDMProxiedDeviceCount.cs +++ b/RDMSharp/RDM/PayloadObject/RDMProxiedDeviceCount.cs @@ -3,59 +3,41 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.PROXIED_DEVICES_COUNT, Command.ECommandDublicate.GetResponse)] +public class RDMProxiedDeviceCount : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.PROXIED_DEVICES_COUNT, Command.ECommandDublicate.GetResponse)] - public class RDMProxiedDeviceCount : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMProxiedDeviceCount( + [DataTreeObjectParameter("device_count")] ushort deviceCount = 0, + [DataTreeObjectParameter("list_change")] bool listChange = false) { - [DataTreeObjectConstructor] - public RDMProxiedDeviceCount( - [DataTreeObjectParameter("device_count")] ushort deviceCount = 0, - [DataTreeObjectParameter("list_change")] bool listChange = false) - { - this.DeviceCount = deviceCount; - this.ListChange = listChange; - } - - [DataTreeObjectProperty("device_count", 0)] - public ushort DeviceCount { get; private set; } - [DataTreeObjectProperty("list_change", 1)] - public bool ListChange { get; private set; } - public const int PDL = 3; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMProxiedDeviceCount"); - b.AppendLine($"DeviceCount: {DeviceCount}"); - b.AppendLine($"ListChange: {ListChange}"); - - return b.ToString(); - } + this.DeviceCount = deviceCount; + this.ListChange = listChange; + } - public static RDMProxiedDeviceCount FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.PROXIED_DEVICES_COUNT, PDL); + [DataTreeObjectProperty("device_count", 0)] + public ushort DeviceCount { get; private set; } + [DataTreeObjectProperty("list_change", 1)] + public bool ListChange { get; private set; } + public const int PDL = 3; - return FromPayloadData(msg.ParameterData); - } - public static RDMProxiedDeviceCount FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMProxiedDeviceCount"); + b.AppendLine($"DeviceCount: {DeviceCount}"); + b.AppendLine($"ListChange: {ListChange}"); - var i = new RDMProxiedDeviceCount( - deviceCount: Tools.DataToUShort(ref data), - listChange: Tools.DataToBool(ref data) - ); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.DeviceCount)); - data.AddRange(Tools.ValueToData(this.ListChange)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.DeviceCount)); + data.AddRange(Tools.ValueToData(this.ListChange)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMProxiedDevices.cs b/RDMSharp/RDM/PayloadObject/RDMProxiedDevices.cs index b0457020..83f2e162 100644 --- a/RDMSharp/RDM/PayloadObject/RDMProxiedDevices.cs +++ b/RDMSharp/RDM/PayloadObject/RDMProxiedDevices.cs @@ -1,59 +1,39 @@ using RDMSharp.Metadata; -using System; +using RDMSharp.Metadata.JSON; using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.PROXIED_DEVICES, Command.ECommandDublicate.GetResponse, true)] +public class RDMProxiedDevices : AbstractRDMPayloadObject { - //[DataTreeObject(ERDM_Parameter.PROXIED_DEVICES, Command.ECommandDublicte.GetResponse, path: "device_uids")] Dont use this because its an Arrya and this is handled faster - public class RDMProxiedDevices : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMProxiedDevices([DataTreeObjectParameter(ERDM_Parameter.PROXIED_DEVICES, "device_uids", true)] params UID[] devices) { - [DataTreeObjectConstructor] - public RDMProxiedDevices(/*[DataTreeObjectParameter("device_uid", true)]*/ params UID[] devices) - { - this.Devices = devices; - } + this.Devices = devices; + } - public UID[] Devices { get; private set; } - public const int PDL_MIN = 0; - public const int PDL_MAX = 0xE4; + [DataTreeObjectProperty("device_uids/device_uid", 0)] + public UID[] Devices { get; private set; } + public const int PDL_MIN = 0; + public const int PDL_MAX = 0xE4; - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMProxiedDevices"); - b.AppendLine($"Devices:"); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMProxiedDevices"); + b.AppendLine($"Devices:"); + if (Devices is not null) foreach (UID device in Devices) b.AppendLine(device.ToString()); - return b.ToString(); - } - public static RDMProxiedDevices FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.PROXIED_DEVICES, PDL_MIN, PDL_MAX); - - return FromPayloadData(msg.ParameterData); - } - public static RDMProxiedDevices FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - - List uids = new List(); - while (data.Length >= 6) - uids.Add(Tools.DataToRDMUID(ref data)); - - var i = new RDMProxiedDevices(uids.ToArray()); - - if (data.Length != 0) - throw new Exception("After deserialization data should be empty!"); - - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.Devices)); - return data.ToArray(); - } + return b.ToString(); + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.Devices)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMRealTimeClock.cs b/RDMSharp/RDM/PayloadObject/RDMRealTimeClock.cs index b9f60e24..6f7e93e4 100644 --- a/RDMSharp/RDM/PayloadObject/RDMRealTimeClock.cs +++ b/RDMSharp/RDM/PayloadObject/RDMRealTimeClock.cs @@ -3,112 +3,93 @@ using System; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.REAL_TIME_CLOCK, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.REAL_TIME_CLOCK, Command.ECommandDublicate.SetRequest)] +public class RDMRealTimeClock : AbstractRDMPayloadObject, IComparable { - [DataTreeObject(ERDM_Parameter.REAL_TIME_CLOCK, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.REAL_TIME_CLOCK, Command.ECommandDublicate.SetRequest)] - public class RDMRealTimeClock : AbstractRDMPayloadObject, IComparable + [DataTreeObjectConstructor] + public RDMRealTimeClock( + [DataTreeObjectParameter("year")] ushort year = 2003, + [DataTreeObjectParameter("month")] byte month = 1, + [DataTreeObjectParameter("day")] byte day = 1, + [DataTreeObjectParameter("hour")] byte hour = 0, + [DataTreeObjectParameter("minute")] byte minute = 0, + [DataTreeObjectParameter("second")] byte second = 0) { - [DataTreeObjectConstructor] - public RDMRealTimeClock( - [DataTreeObjectParameter("year")] ushort year = 2003, - [DataTreeObjectParameter("month")] byte month = 1, - [DataTreeObjectParameter("day")] byte day = 1, - [DataTreeObjectParameter("hour")] byte hour = 0, - [DataTreeObjectParameter("minute")] byte minute = 0, - [DataTreeObjectParameter("second")] byte second = 0) - { - if (year < 2003) - throw new ArgumentOutOfRangeException($"{nameof(year)} shold be a value between 2003 and 65535 but is {year}"); - if (month < 1 || month > 12) - throw new ArgumentOutOfRangeException($"{nameof(month)} shold be a value between 1 and 12 but is {month}"); - if (day < 1 || day > 31) - throw new ArgumentOutOfRangeException($"{nameof(day)} shold be a value between 1 and 31 but is {day}"); - if (hour > 23) - throw new ArgumentOutOfRangeException($"{nameof(hour)} shold be a value between 0 and 23 but is {hour}"); - if (minute > 59) - throw new ArgumentOutOfRangeException($"{nameof(minute)} shold be a value between 0 and 59 but is {minute}"); - if (second > 59) - throw new ArgumentOutOfRangeException($"{nameof(second)} shold be a value between 0 and 59 but is {second}"); - - this.Year = year; - this.Month = month; - this.Day = day; - this.Hour = hour; - this.Minute = minute; - this.Second = second; + if (year < 2003) + throw new ArgumentOutOfRangeException($"{nameof(year)} shold be a value between 2003 and 65535 but is {year}"); + if (month < 1 || month > 12) + throw new ArgumentOutOfRangeException($"{nameof(month)} shold be a value between 1 and 12 but is {month}"); + if (day < 1 || day > 31) + throw new ArgumentOutOfRangeException($"{nameof(day)} shold be a value between 1 and 31 but is {day}"); + if (hour > 23) + throw new ArgumentOutOfRangeException($"{nameof(hour)} shold be a value between 0 and 23 but is {hour}"); + if (minute > 59) + throw new ArgumentOutOfRangeException($"{nameof(minute)} shold be a value between 0 and 59 but is {minute}"); + if (second > 59) + throw new ArgumentOutOfRangeException($"{nameof(second)} shold be a value between 0 and 59 but is {second}"); - this.Date = new DateTime(year, month, day, hour, minute, second); - } - public RDMRealTimeClock(DateTime dateTime) - : this((ushort)dateTime.Year, - (byte)dateTime.Month, - (byte)dateTime.Day, - (byte)dateTime.Hour, - (byte)dateTime.Minute, - (byte)dateTime.Second) - { + this.Year = year; + this.Month = month; + this.Day = day; + this.Hour = hour; + this.Minute = minute; + this.Second = second; - } + this.Date = new DateTime(year, month, day, hour, minute, second); + } + public RDMRealTimeClock(DateTime dateTime) + : this((ushort)dateTime.Year, + (byte)dateTime.Month, + (byte)dateTime.Day, + (byte)dateTime.Hour, + (byte)dateTime.Minute, + (byte)dateTime.Second) + { - public DateTime Date { get; private set; } + } - [DataTreeObjectProperty("year", 0)] - public ushort Year { get; private set; } - [DataTreeObjectProperty("month", 1)] - public byte Month { get; private set; } - [DataTreeObjectProperty("day", 2)] - public byte Day { get; private set; } - [DataTreeObjectProperty("hour", 3)] - public byte Hour { get; private set; } - [DataTreeObjectProperty("minute", 4)] - public byte Minute { get; private set; } - [DataTreeObjectProperty("second", 5)] - public byte Second { get; private set; } - public const int PDL = 7; + public DateTime Date { get; private set; } - public override string ToString() - { - return $"{Date:G}"; - } - public static RDMRealTimeClock FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.REAL_TIME_CLOCK, PDL); + [DataTreeObjectProperty("year", 0)] + public ushort Year { get; private set; } + [DataTreeObjectProperty("month", 1)] + public byte Month { get; private set; } + [DataTreeObjectProperty("day", 2)] + public byte Day { get; private set; } + [DataTreeObjectProperty("hour", 3)] + public byte Hour { get; private set; } + [DataTreeObjectProperty("minute", 4)] + public byte Minute { get; private set; } + [DataTreeObjectProperty("second", 5)] + public byte Second { get; private set; } + public const int PDL = 7; - return FromPayloadData(msg.ParameterData); - } - public static RDMRealTimeClock FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + public override string ToString() + { + return $"{Date:G}"; + } - var i = new RDMRealTimeClock( - year: Tools.DataToUShort(ref data), - month: Tools.DataToByte(ref data), - day: Tools.DataToByte(ref data), - hour: Tools.DataToByte(ref data), - minute: Tools.DataToByte(ref data), - second: Tools.DataToByte(ref data)); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.Year)); - data.AddRange(Tools.ValueToData(this.Month)); - data.AddRange(Tools.ValueToData(this.Day)); - data.AddRange(Tools.ValueToData(this.Hour)); - data.AddRange(Tools.ValueToData(this.Minute)); - data.AddRange(Tools.ValueToData(this.Second)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.Year)); + data.AddRange(Tools.ValueToData(this.Month)); + data.AddRange(Tools.ValueToData(this.Day)); + data.AddRange(Tools.ValueToData(this.Hour)); + data.AddRange(Tools.ValueToData(this.Minute)); + data.AddRange(Tools.ValueToData(this.Second)); + return data.ToArray(); + } - public int CompareTo(object obj) + public int CompareTo(object obj) + { + if (obj is RDMRealTimeClock rtc) { - if (obj is RDMRealTimeClock rtc) - { - return this.Date.CompareTo(rtc.Date); - } - throw new ArgumentException("Object is not a RDMRealTimeClock", nameof(obj)); + return this.Date.CompareTo(rtc.Date); } + throw new ArgumentException("Object is not a RDMRealTimeClock", nameof(obj)); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMSelfTestDescription.cs b/RDMSharp/RDM/PayloadObject/RDMSelfTestDescription.cs index 6a48e80a..9729d671 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSelfTestDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSelfTestDescription.cs @@ -3,67 +3,66 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.SELF_TEST_DESCRIPTION, Command.ECommandDublicate.GetResponse)] +public class RDMSelfTestDescription : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.SELF_TEST_DESCRIPTION, Command.ECommandDublicate.GetResponse)] - public class RDMSelfTestDescription : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMSelfTestDescription( + [DataTreeObjectParameter("self_test_num")] byte selfTestRequester = 0, + [DataTreeObjectParameter("label")] string description = "") { - [DataTreeObjectConstructor] - public RDMSelfTestDescription( - [DataTreeObjectParameter("self_test_num")] byte selfTestRequester = 0, - [DataTreeObjectParameter("label")] string description = "") - { - this.SelfTestRequester = selfTestRequester; + this.SelfTestRequester = selfTestRequester; - if (string.IsNullOrWhiteSpace(description)) - return; + if (string.IsNullOrWhiteSpace(description)) + return; - if (description.Length > 32) - description = description.Substring(0, 32); + if (description.Length > 32) + description = description.Substring(0, 32); - this.Description = description; - } + this.Description = description; + } - [DataTreeObjectProperty("self_test_num", 0)] - public byte SelfTestRequester { get; private set; } - [DataTreeObjectProperty("label", 1)] - public string Description { get; private set; } + [DataTreeObjectProperty("self_test_num", 0)] + public byte SelfTestRequester { get; private set; } + [DataTreeObjectProperty("label", 1)] + public string Description { get; private set; } - public const int PDL_MIN = 1; - public const int PDL_MAX = PDL_MIN + 32; + public const int PDL_MIN = 1; + public const int PDL_MAX = PDL_MIN + 32; - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMSelfTestDescription"); - b.AppendLine($"SelfTestRequester: {SelfTestRequester}"); - b.AppendLine($"Description: {Description}"); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMSelfTestDescription"); + b.AppendLine($"SelfTestRequester: {SelfTestRequester}"); + b.AppendLine($"Description: {Description}"); - return b.ToString(); - } + return b.ToString(); + } - public static RDMSelfTestDescription FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.SELF_TEST_DESCRIPTION, PDL_MIN, PDL_MAX); + public static RDMSelfTestDescription FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.SELF_TEST_DESCRIPTION, PDL_MIN, PDL_MAX); - return FromPayloadData(msg.ParameterData); - } - public static RDMSelfTestDescription FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); + return FromPayloadData(msg.ParameterData); + } + public static RDMSelfTestDescription FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - var i = new RDMSelfTestDescription( - selfTestRequester: Tools.DataToByte(ref data), - description: Tools.DataToString(ref data)); + var i = new RDMSelfTestDescription( + selfTestRequester: Tools.DataToByte(ref data), + description: Tools.DataToString(ref data)); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.SelfTestRequester)); - data.AddRange(Tools.ValueToData(this.Description, 32)); - return data.ToArray(); - } + return i; + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.SelfTestRequester)); + data.AddRange(Tools.ValueToData(this.Description, 32)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMSensorDefinition.cs b/RDMSharp/RDM/PayloadObject/RDMSensorDefinition.cs index 269bf1fd..8605ee50 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSensorDefinition.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSensorDefinition.cs @@ -3,171 +3,133 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp -{ - [DataTreeObject(ERDM_Parameter.SENSOR_DEFINITION, Command.ECommandDublicate.GetResponse)] - public class RDMSensorDefinition : AbstractRDMPayloadObject, IRDMPayloadObjectIndex +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.SENSOR_DEFINITION, Command.ECommandDublicate.GetResponse)] +public class RDMSensorDefinition : AbstractRDMPayloadObject, IRDMPayloadObjectIndex +{ + public RDMSensorDefinition( + byte sensorId = 0, + ERDM_SensorType type = (ERDM_SensorType)0, + ERDM_SensorUnit unit = (ERDM_SensorUnit)0, + ERDM_UnitPrefix prefix = (ERDM_UnitPrefix)0, + short rangeMinimum = 0, + short rangeMaximum = 0, + short normalMinimum = 0, + short normalMaximum = 0, + bool lowestHighestValueSupported = false, + bool recordedValueSupported = false, + string description = "") { - public RDMSensorDefinition( - byte sensorId = 0, - ERDM_SensorType type = (ERDM_SensorType)0, - ERDM_SensorUnit unit = (ERDM_SensorUnit)0, - ERDM_UnitPrefix prefix = (ERDM_UnitPrefix)0, - short rangeMinimum = 0, - short rangeMaximum = 0, - short normalMinimum = 0, - short normalMaximum = 0, - bool lowestHighestValueSupported = false, - bool recordedValueSupported = false, - string description = "") - { - this.SensorId = sensorId; - this.Type = type; - this.Unit = unit; - this.Prefix = prefix; - this.RangeMaximum = rangeMaximum; - this.RangeMinimum = rangeMinimum; - this.NormalMaximum = normalMaximum; - this.NormalMinimum = normalMinimum; - this.LowestHighestValueSupported = lowestHighestValueSupported; - this.RecordedValueSupported = recordedValueSupported; + this.SensorId = sensorId; + this.Type = type; + this.Unit = unit; + this.Prefix = prefix; + this.RangeMaximum = rangeMaximum; + this.RangeMinimum = rangeMinimum; + this.NormalMaximum = normalMaximum; + this.NormalMinimum = normalMinimum; + this.LowestHighestValueSupported = lowestHighestValueSupported; + this.RecordedValueSupported = recordedValueSupported; - if (string.IsNullOrWhiteSpace(description)) - return; + if (string.IsNullOrWhiteSpace(description)) + return; - if (description.Length > 32) - description = description.Substring(0, 32); + if (description.Length > 32) + description = description.Substring(0, 32); - this.Description = description; - } + this.Description = description; + } - [DataTreeObjectConstructor] - public RDMSensorDefinition( - [DataTreeObjectParameter("sensor")] byte sensorId, - [DataTreeObjectParameter("type")] byte type, - [DataTreeObjectParameter("unit")] byte unit, - [DataTreeObjectParameter("unit_prefix")] byte prefix, - [DataTreeObjectParameter("range_min_value")] short rangeMinimum, - [DataTreeObjectParameter("range_max_value")] short rangeMaximum, - [DataTreeObjectParameter("normal_min_value")] short normalMinimum, - [DataTreeObjectParameter("normal_max_value")] short normalMaximum, - [DataTreeObjectParameter("recorded_value_support/recorded_value_supported")] bool recordedValueSupported, - [DataTreeObjectParameter("recorded_value_support/low_high_detected_values_supported")] bool lowestHighestValueSupported, - [DataTreeObjectParameter("description")] string description) - : this(sensorId, - (ERDM_SensorType)type, - (ERDM_SensorUnit)unit, - (ERDM_UnitPrefix)prefix, - rangeMinimum, - rangeMaximum, - normalMinimum, - normalMaximum, - lowestHighestValueSupported, - recordedValueSupported, - description) - { - } + [DataTreeObjectConstructor] + public RDMSensorDefinition( + [DataTreeObjectParameter("sensor")] byte sensorId, + [DataTreeObjectParameter("type")] byte type, + [DataTreeObjectParameter("unit")] byte unit, + [DataTreeObjectParameter("unit_prefix")] byte prefix, + [DataTreeObjectParameter("range_min_value")] short rangeMinimum, + [DataTreeObjectParameter("range_max_value")] short rangeMaximum, + [DataTreeObjectParameter("normal_min_value")] short normalMinimum, + [DataTreeObjectParameter("normal_max_value")] short normalMaximum, + [DataTreeObjectParameter("recorded_value_support/recorded_value_supported")] bool recordedValueSupported, + [DataTreeObjectParameter("recorded_value_support/low_high_detected_values_supported")] bool lowestHighestValueSupported, + [DataTreeObjectParameter("description")] string description) + : this(sensorId, + (ERDM_SensorType)type, + (ERDM_SensorUnit)unit, + (ERDM_UnitPrefix)prefix, + rangeMinimum, + rangeMaximum, + normalMinimum, + normalMaximum, + lowestHighestValueSupported, + recordedValueSupported, + description) + { + } - [DataTreeObjectProperty("sensor", 0)] - public byte SensorId { get; private set; } - [DataTreeObjectProperty("type", 1)] - public ERDM_SensorType Type { get; private set; } - [DataTreeObjectProperty("unit", 2)] - public ERDM_SensorUnit Unit { get; private set; } - [DataTreeObjectProperty("unit_prefix", 3)] - public ERDM_UnitPrefix Prefix { get; private set; } - [DataTreeObjectProperty("range_min_value", 4)] - public short RangeMinimum { get; private set; } - [DataTreeObjectProperty("range_max_value", 5)] - public short RangeMaximum { get; private set; } - [DataTreeObjectProperty("normal_min_value", 6)] - public short NormalMinimum { get; private set; } - [DataTreeObjectProperty("normal_max_value", 7)] - public short NormalMaximum { get; private set; } - [DataTreeObjectProperty("recorded_value_support/recorded_value_supported", 0)] - public bool LowestHighestValueSupported { get; private set; } - [DataTreeObjectProperty("recorded_value_support/low_high_detected_values_supported", 1)] - public bool RecordedValueSupported { get; private set; } - [DataTreeObjectProperty("description", 9)] - public string Description { get; private set; } + [DataTreeObjectProperty("sensor", 0)] + public byte SensorId { get; private set; } + [DataTreeObjectProperty("type", 1)] + public ERDM_SensorType Type { get; private set; } + [DataTreeObjectProperty("unit", 2)] + public ERDM_SensorUnit Unit { get; private set; } + [DataTreeObjectProperty("unit_prefix", 3)] + public ERDM_UnitPrefix Prefix { get; private set; } + [DataTreeObjectProperty("range_min_value", 4)] + public short RangeMinimum { get; private set; } + [DataTreeObjectProperty("range_max_value", 5)] + public short RangeMaximum { get; private set; } + [DataTreeObjectProperty("normal_min_value", 6)] + public short NormalMinimum { get; private set; } + [DataTreeObjectProperty("normal_max_value", 7)] + public short NormalMaximum { get; private set; } + [DataTreeObjectProperty("recorded_value_support/recorded_value_supported", 0)] + public bool RecordedValueSupported { get; private set; } + [DataTreeObjectProperty("recorded_value_support/low_high_detected_values_supported", 1)] + public bool LowestHighestValueSupported { get; private set; } + [DataTreeObjectProperty("description", 9)] + public string Description { get; private set; } - public object MinIndex => (byte)0; - public object Index => SensorId; + public object MinIndex => (byte)0; + public object Index => SensorId; - public const int PDL_MIN = 13; - public const int PDL_MAX = PDL_MIN + 32; - - public override string ToString() - { - string _unit = Unit.GetUnitSymbol(); - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMSensorDefinition"); - b.AppendLine($"SensorId: {SensorId}"); - b.AppendLine($"Type: {Type}"); - b.AppendLine($"Unit: {Unit}({_unit})"); - b.AppendLine($"Prefix: {Prefix}"); - b.AppendLine($"RangeMinimum: {Prefix.GetNormalizedValue(RangeMinimum)}{_unit}"); - b.AppendLine($"RangeMaximum: {Prefix.GetNormalizedValue(RangeMaximum)}{_unit}"); - b.AppendLine($"NormalMinimum: {Prefix.GetNormalizedValue(NormalMinimum)}{_unit}"); - b.AppendLine($"NormalMaximum: {Prefix.GetNormalizedValue(NormalMaximum)}{_unit}"); - b.AppendLine($"LowestHighestValueSupported: {LowestHighestValueSupported}"); - b.AppendLine($"RecordedValueSupported: {RecordedValueSupported}"); - b.AppendLine($"Description: {Description}"); - - return b.ToString(); - } - - public static RDMSensorDefinition FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.SENSOR_DEFINITION, PDL_MIN, PDL_MAX); + public const int PDL_MIN = 13; + public const int PDL_MAX = PDL_MIN + 32; - return FromPayloadData(msg.ParameterData); - } - public static RDMSensorDefinition FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); - - var sensorId = Tools.DataToByte(ref data); - var type = Tools.DataToEnum(ref data); - var unit = Tools.DataToEnum(ref data); - var prefix = Tools.DataToEnum(ref data); - var rangeMinimum = Tools.DataToShort(ref data); - var rangeMaximum = Tools.DataToShort(ref data); - var normalMinimum = Tools.DataToShort(ref data); - var normalMaximum = Tools.DataToShort(ref data); - var @boolArray = Tools.DataToBoolArray(ref data, 2); - var description = Tools.DataToString(ref data); + public override string ToString() + { + string _unit = Unit.GetUnitSymbol(); + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMSensorDefinition"); + b.AppendLine($"SensorId: {SensorId}"); + b.AppendLine($"Type: {Type}"); + b.AppendLine($"Unit: {Unit}({_unit})"); + b.AppendLine($"Prefix: {Prefix}"); + b.AppendLine($"RangeMinimum: {Prefix.GetNormalizedValue(RangeMinimum)}{_unit}"); + b.AppendLine($"RangeMaximum: {Prefix.GetNormalizedValue(RangeMaximum)}{_unit}"); + b.AppendLine($"NormalMinimum: {Prefix.GetNormalizedValue(NormalMinimum)}{_unit}"); + b.AppendLine($"NormalMaximum: {Prefix.GetNormalizedValue(NormalMaximum)}{_unit}"); + b.AppendLine($"LowestHighestValueSupported: {LowestHighestValueSupported}"); + b.AppendLine($"RecordedValueSupported: {RecordedValueSupported}"); + b.AppendLine($"Description: {Description}"); - var i = new RDMSensorDefinition( - sensorId: sensorId, - type: type, - unit: unit, - prefix: prefix, - rangeMinimum: rangeMinimum, - rangeMaximum: rangeMaximum, - normalMinimum: normalMinimum, - normalMaximum: normalMaximum, - lowestHighestValueSupported: @boolArray[1], - recordedValueSupported: @boolArray[0], - description: description - ); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.SensorId)); - data.AddRange(Tools.ValueToData(this.Type)); - data.AddRange(Tools.ValueToData(this.Unit)); - data.AddRange(Tools.ValueToData(this.Prefix)); - data.AddRange(Tools.ValueToData(this.RangeMinimum)); - data.AddRange(Tools.ValueToData(this.RangeMaximum)); - data.AddRange(Tools.ValueToData(this.NormalMinimum)); - data.AddRange(Tools.ValueToData(this.NormalMaximum)); - data.AddRange(Tools.ValueToData(this.RecordedValueSupported, this.LowestHighestValueSupported)); - data.AddRange(Tools.ValueToData(this.Description, 32)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.SensorId)); + data.AddRange(Tools.ValueToData(this.Type)); + data.AddRange(Tools.ValueToData(this.Unit)); + data.AddRange(Tools.ValueToData(this.Prefix)); + data.AddRange(Tools.ValueToData(this.RangeMinimum)); + data.AddRange(Tools.ValueToData(this.RangeMaximum)); + data.AddRange(Tools.ValueToData(this.NormalMinimum)); + data.AddRange(Tools.ValueToData(this.NormalMaximum)); + data.AddRange(Tools.ValueToData(this.RecordedValueSupported, this.LowestHighestValueSupported)); + data.AddRange(Tools.ValueToData(this.Description, 32)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMSensorTypeCustomDefine.cs b/RDMSharp/RDM/PayloadObject/RDMSensorTypeCustomDefine.cs index 84ba2931..911d9b89 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSensorTypeCustomDefine.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSensorTypeCustomDefine.cs @@ -3,67 +3,46 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.SENSOR_TYPE_CUSTOM, Command.ECommandDublicate.GetResponse)] +public class RDMSensorTypeCustomDefine : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { - [DataTreeObject(ERDM_Parameter.SENSOR_TYPE_CUSTOM, Command.ECommandDublicate.GetResponse)] - public class RDMSensorTypeCustomDefine : AbstractRDMPayloadObject, IRDMPayloadObjectIndex + [DataTreeObjectConstructor] + public RDMSensorTypeCustomDefine( + [DataTreeObjectParameter("sensor_type")] byte id, + [DataTreeObjectParameter("label")] string label) { - [DataTreeObjectConstructor] - public RDMSensorTypeCustomDefine( - [DataTreeObjectParameter("sensor_type")] byte id, - [DataTreeObjectParameter("label")] string label) - { - this.Id = id; - this.Label = label; - } - - [DataTreeObjectProperty("sensor_type", 0)] - public byte Id { get; private set; } - [DataTreeObjectProperty("label", 1)] - public string Label { get; private set; } - - public object MinIndex => (byte)0x80; - public object Index => Id; - - public const int PDL_MIN = 0x01; - public const int PDL_MAX = 0x21; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMSensorTypeCustomDefine"); - b.AppendLine($"Id: 0x{Id:X2}"); - b.AppendLine($"Label: {Label}"); + this.Id = id; + this.Label = label; + } - return b.ToString(); - } + [DataTreeObjectProperty("sensor_type", 0)] + public byte Id { get; private set; } + [DataTreeObjectProperty("label", 1)] + public string Label { get; private set; } - public static RDMSensorTypeCustomDefine FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.SENSOR_TYPE_CUSTOM, PDL_MIN, PDL_MAX); + public object MinIndex => (byte)0x80; + public object Index => Id; - return FromPayloadData(msg.ParameterData); - } - public static RDMSensorTypeCustomDefine FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); + public const int PDL_MIN = 0x01; + public const int PDL_MAX = 0x21; - var id = Tools.DataToByte(ref data); - var label = Tools.DataToString(ref data, 32); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMSensorTypeCustomDefine"); + b.AppendLine($"Id: 0x{Id:X2}"); + b.AppendLine($"Label: {Label}"); - var i = new RDMSensorTypeCustomDefine( - id: id, - label: label - ); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.Id)); - data.AddRange(Tools.ValueToData(this.Label)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.Id)); + data.AddRange(Tools.ValueToData(this.Label)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMSensorUnitCustomDefine.cs b/RDMSharp/RDM/PayloadObject/RDMSensorUnitCustomDefine.cs index 6ca52150..ac76edb4 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSensorUnitCustomDefine.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSensorUnitCustomDefine.cs @@ -3,67 +3,46 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.SENSOR_UNIT_CUSTOM, Command.ECommandDublicate.GetResponse)] +public class RDMSensorUnitCustomDefine : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { - [DataTreeObject(ERDM_Parameter.SENSOR_UNIT_CUSTOM, Command.ECommandDublicate.GetResponse)] - public class RDMSensorUnitCustomDefine : AbstractRDMPayloadObject, IRDMPayloadObjectIndex + [DataTreeObjectConstructor] + public RDMSensorUnitCustomDefine( + [DataTreeObjectParameter("sensor_unit")] byte id, + [DataTreeObjectParameter("label")] string label) { - [DataTreeObjectConstructor] - public RDMSensorUnitCustomDefine( - [DataTreeObjectParameter("sensor_unit")] byte id, - [DataTreeObjectParameter("label")] string label) - { - this.Id = id; - this.Label = label; - } - - [DataTreeObjectProperty("sensor_unit", 0)] - public byte Id { get; private set; } - [DataTreeObjectProperty("label", 1)] - public string Label { get; private set; } - - public object MinIndex => (byte)0x80; - public object Index => Id; - - public const int PDL_MIN = 0x01; - public const int PDL_MAX = 0x21; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMSensorUnitCustomDefine"); - b.AppendLine($"Id: 0x{Id:X2}"); - b.AppendLine($"Label: {Label}"); + this.Id = id; + this.Label = label; + } - return b.ToString(); - } + [DataTreeObjectProperty("sensor_unit", 0)] + public byte Id { get; private set; } + [DataTreeObjectProperty("label", 1)] + public string Label { get; private set; } - public static RDMSensorUnitCustomDefine FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.SENSOR_UNIT_CUSTOM, PDL_MIN, PDL_MAX); + public object MinIndex => (byte)0x80; + public object Index => Id; - return FromPayloadData(msg.ParameterData); - } - public static RDMSensorUnitCustomDefine FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); + public const int PDL_MIN = 0x01; + public const int PDL_MAX = 0x21; - var id = Tools.DataToByte(ref data); - var label = Tools.DataToString(ref data, 32); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMSensorUnitCustomDefine"); + b.AppendLine($"Id: 0x{Id:X2}"); + b.AppendLine($"Label: {Label}"); - var i = new RDMSensorUnitCustomDefine( - id: id, - label: label - ); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.Id)); - data.AddRange(Tools.ValueToData(this.Label)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.Id)); + data.AddRange(Tools.ValueToData(this.Label)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMSensorValue.cs b/RDMSharp/RDM/PayloadObject/RDMSensorValue.cs index 0b31c642..615318de 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSensorValue.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSensorValue.cs @@ -3,90 +3,70 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.SENSOR_VALUE, Command.ECommandDublicate.GetResponse)] +[DataTreeObject(ERDM_Parameter.SENSOR_VALUE, Command.ECommandDublicate.SetResponse)] +public class RDMSensorValue : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { - [DataTreeObject(ERDM_Parameter.SENSOR_VALUE, Command.ECommandDublicate.GetResponse)] - [DataTreeObject(ERDM_Parameter.SENSOR_VALUE, Command.ECommandDublicate.SetResponse)] - public class RDMSensorValue : AbstractRDMPayloadObject, IRDMPayloadObjectIndex - { - [DataTreeObjectConstructor] - public RDMSensorValue( - [DataTreeObjectParameter("sensor")] byte sensorId = 0, - [DataTreeObjectParameter("value")] short presentvalue = 0, - [DataTreeObjectParameter("lowest_detected")] short lowestValue = 0, - [DataTreeObjectParameter("highest_detected")] short highestValue = 0, - [DataTreeObjectParameter("recorded_value")] short recordedValue = 0) - { - this.SensorId = sensorId; - this.PresentValue = presentvalue; - this.LowestValue = lowestValue; - this.HighestValue = highestValue; - this.RecordedValue = recordedValue; - } + [DataTreeObjectConstructor] + public RDMSensorValue( + [DataTreeObjectParameter("sensor")] byte sensorId = 0, + [DataTreeObjectParameter("value")] short presentvalue = 0, + [DataTreeObjectParameter("lowest_detected")] short lowestValue = 0, + [DataTreeObjectParameter("highest_detected")] short highestValue = 0, + [DataTreeObjectParameter("recorded_value")] short recordedValue = 0) + { + this.SensorId = sensorId; + this.PresentValue = presentvalue; + this.LowestValue = lowestValue; + this.HighestValue = highestValue; + this.RecordedValue = recordedValue; + } - [DataTreeObjectProperty("sensor", 0)] - public byte SensorId { get; private set; } + [DataTreeObjectProperty("sensor", 0)] + public byte SensorId { get; private set; } - [DataTreeObjectProperty("value", 1)] - public short PresentValue { get; private set; } + [DataTreeObjectProperty("value", 1)] + public short PresentValue { get; private set; } - [DataTreeObjectProperty("lowest_detected", 2)] - public short LowestValue { get; private set; } + [DataTreeObjectProperty("lowest_detected", 2)] + public short LowestValue { get; private set; } - [DataTreeObjectProperty("highest_detected", 3)] - public short HighestValue { get; private set; } + [DataTreeObjectProperty("highest_detected", 3)] + public short HighestValue { get; private set; } - [DataTreeObjectProperty("recorded_value", 4)] - public short RecordedValue { get; private set; } + [DataTreeObjectProperty("recorded_value", 4)] + public short RecordedValue { get; private set; } - public object MinIndex => (byte)0; + public object MinIndex => (byte)0; - public object Index => SensorId; + public object Index => SensorId; - public const int PDL = 9; - + public const int PDL = 9; - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMSensorValue"); - b.AppendLine($"SensorId: {SensorId}"); - b.AppendLine($"PresentValue: {PresentValue}"); - b.AppendLine($"LowestValue: {LowestValue}"); - b.AppendLine($"HighestValue: {HighestValue}"); - b.AppendLine($"RecordedValue: {RecordedValue}"); - return b.ToString(); - } + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMSensorValue"); + b.AppendLine($"SensorId: {SensorId}"); + b.AppendLine($"PresentValue: {PresentValue}"); + b.AppendLine($"LowestValue: {LowestValue}"); + b.AppendLine($"HighestValue: {HighestValue}"); + b.AppendLine($"RecordedValue: {RecordedValue}"); - public static RDMSensorValue FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.SENSOR_VALUE, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static RDMSensorValue FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - - var i = new RDMSensorValue( - sensorId: Tools.DataToByte(ref data), - presentvalue: Tools.DataToShort(ref data), - lowestValue: Tools.DataToShort(ref data), - highestValue: Tools.DataToShort(ref data), - recordedValue: Tools.DataToShort(ref data)); + return b.ToString(); + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.SensorId)); - data.AddRange(Tools.ValueToData(this.PresentValue)); - data.AddRange(Tools.ValueToData(this.LowestValue)); - data.AddRange(Tools.ValueToData(this.HighestValue)); - data.AddRange(Tools.ValueToData(this.RecordedValue)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.SensorId)); + data.AddRange(Tools.ValueToData(this.PresentValue)); + data.AddRange(Tools.ValueToData(this.LowestValue)); + data.AddRange(Tools.ValueToData(this.HighestValue)); + data.AddRange(Tools.ValueToData(this.RecordedValue)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs b/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs index 750dfea4..508e1824 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs @@ -2,63 +2,46 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicate.GetResponse)] +public class RDMSlotDescription : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicate.GetResponse)] - public class RDMSlotDescription : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public RDMSlotDescription( + [DataTreeObjectParameter("slot")] ushort slotId = 0, + [DataTreeObjectParameter("description")] string description = "") { - [DataTreeObjectConstructor] - public RDMSlotDescription( - [DataTreeObjectParameter("slot")] ushort slotId = 0, - [DataTreeObjectParameter("description")] string description = "") - { - this.SlotId = slotId; - - if (string.IsNullOrWhiteSpace(description)) - return; - - if (description.Length > 32) - description = description.Substring(0, 32); - - this.Description = description; - } + this.SlotId = slotId; - [DataTreeObjectProperty("slot", 0)] - public ushort SlotId { get; private set; } + if (string.IsNullOrWhiteSpace(description)) + return; - [DataTreeObjectProperty("description", 1)] - public string Description { get; private set; } + if (description.Length > 32) + description = description.Substring(0, 32); - public const int PDL_MIN = 2; - public const int PDL_MAX = PDL_MIN + 32; + this.Description = description; + } - public override string ToString() - { - return $"RDMSlotDescription: {SlotId} - {Description}"; - } + [DataTreeObjectProperty("slot", 0)] + public ushort SlotId { get; private set; } - public static RDMSlotDescription FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDLRange(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.SLOT_DESCRIPTION, PDL_MIN, PDL_MAX); + [DataTreeObjectProperty("description", 1)] + public string Description { get; private set; } - return FromPayloadData(msg.ParameterData); - } - public static RDMSlotDescription FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(data, PDL_MIN, PDL_MAX); + public const int PDL_MIN = 2; + public const int PDL_MAX = PDL_MIN + 32; - var i = new RDMSlotDescription( - slotId: Tools.DataToUShort(ref data), - description: Tools.DataToString(ref data)); + public override string ToString() + { + return $"RDMSlotDescription: {SlotId} - {Description}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.SlotId)); - data.AddRange(Tools.ValueToData(this.Description, 32)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.SlotId)); + data.AddRange(Tools.ValueToData(this.Description, 32)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/RDMSlotInfo.cs b/RDMSharp/RDM/PayloadObject/RDMSlotInfo.cs index 0ce11077..89694e01 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSlotInfo.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSlotInfo.cs @@ -3,73 +3,57 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.SLOT_INFO, Command.ECommandDublicate.GetResponse, true, "slots")] +public class RDMSlotInfo : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.SLOT_INFO, Command.ECommandDublicate.GetResponse, true, "slots")] - public class RDMSlotInfo : AbstractRDMPayloadObject + public RDMSlotInfo( + ushort slotOffset = default, + ERDM_SlotType slotType = default, + ERDM_SlotCategory slotLabelId = default) { - public RDMSlotInfo( - ushort slotOffset = default, - ERDM_SlotType slotType = default, - ERDM_SlotCategory slotLabelId = default) - { - this.SlotOffset = slotOffset; - this.SlotType = slotType; - this.SlotLabelId = slotLabelId; - } - - [DataTreeObjectConstructor] - public RDMSlotInfo( - [DataTreeObjectParameter("id")] ushort slotOffset, - [DataTreeObjectParameter("type")] byte slotType, - [DataTreeObjectParameter("label_id")] ushort slotLabelId) - : this(slotOffset, (ERDM_SlotType)slotType, (ERDM_SlotCategory)slotLabelId) - { - } + this.SlotOffset = slotOffset; + this.SlotType = slotType; + this.SlotLabelId = slotLabelId; + } - [DataTreeObjectProperty("id", 0)] - public ushort SlotOffset { get; private set; } + [DataTreeObjectConstructor] + public RDMSlotInfo( + [DataTreeObjectParameter("id")] ushort slotOffset, + [DataTreeObjectParameter("type")] byte slotType, + [DataTreeObjectParameter("label_id")] ushort slotLabelId) + : this(slotOffset, (ERDM_SlotType)slotType, (ERDM_SlotCategory)slotLabelId) + { + } - [DataTreeObjectProperty("type", 1)] - public ERDM_SlotType SlotType { get; private set; } + [DataTreeObjectProperty("id", 0)] + public ushort SlotOffset { get; private set; } - [DataTreeObjectProperty("label_id", 2)] - public ERDM_SlotCategory SlotLabelId { get; private set; } - public const int PDL = 5; + [DataTreeObjectProperty("type", 1)] + public ERDM_SlotType SlotType { get; private set; } - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMSlotInfo"); - b.AppendLine($"SlotOffset: {SlotOffset}"); - b.AppendLine($"SlotType: {SlotType}"); - b.AppendLine($"SlotLabelId: {SlotLabelId}"); + [DataTreeObjectProperty("label_id", 2)] + public ERDM_SlotCategory SlotLabelId { get; private set; } + public const int PDL = 5; - return b.ToString(); - } - public static RDMSlotInfo FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.SLOT_INFO, PDL); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMSlotInfo"); + b.AppendLine($"SlotOffset: {SlotOffset}"); + b.AppendLine($"SlotType: {SlotType}"); + b.AppendLine($"SlotLabelId: {SlotLabelId}"); - return FromPayloadData(msg.ParameterData); - } - public static RDMSlotInfo FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + return b.ToString(); + } - var i = new RDMSlotInfo( - slotOffset: Tools.DataToUShort(ref data), - slotType: Tools.DataToEnum(ref data), - slotLabelId: Tools.DataToEnum(ref data)); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.SlotOffset)); - data.AddRange(Tools.ValueToData(this.SlotType)); - data.AddRange(Tools.ValueToData(this.SlotLabelId)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.SlotOffset)); + data.AddRange(Tools.ValueToData(this.SlotType)); + data.AddRange(Tools.ValueToData(this.SlotLabelId)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs b/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs index 4032d03e..069b852e 100644 --- a/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs +++ b/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs @@ -4,128 +4,127 @@ using System.Collections.Generic; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.STATUS_MESSAGES, Command.ECommandDublicate.GetResponse, true, "slots")] +public class RDMStatusMessage : AbstractRDMPayloadObject, IEquatable { - [DataTreeObject(ERDM_Parameter.STATUS_MESSAGES, Command.ECommandDublicate.GetResponse, true, "slots")] - public class RDMStatusMessage : AbstractRDMPayloadObject, IEquatable + public RDMStatusMessage( + ushort subDeviceId = 0, + ERDM_Status statusType = (ERDM_Status)0, + ERDM_StatusMessage statusMessage = (ERDM_StatusMessage)0, + short dataValue1 = 0, + short dataValue2 = 0) { - public RDMStatusMessage( - ushort subDeviceId = 0, - ERDM_Status statusType = (ERDM_Status)0, - ERDM_StatusMessage statusMessage = (ERDM_StatusMessage)0, - short dataValue1 = 0, - short dataValue2 = 0) - { - this.SubDeviceId = subDeviceId; - this.EStatusType = statusType; - this.EStatusMessage = statusMessage; - this.DataValue1 = dataValue1; - this.DataValue2 = dataValue2; - } + this.SubDeviceId = subDeviceId; + this.EStatusType = statusType; + this.EStatusMessage = statusMessage; + this.DataValue1 = dataValue1; + this.DataValue2 = dataValue2; + } - [DataTreeObjectConstructor] - public RDMStatusMessage( - [DataTreeObjectParameter("subdevice_id")] ushort subDeviceId, - [DataTreeObjectParameter("status_type")] byte statusType, - [DataTreeObjectParameter("status_message_id")] ushort statusMessage, - [DataTreeObjectParameter("data_value_1")] short dataValue1, - [DataTreeObjectParameter("data_value_2")] short dataValue2) - : this(subDeviceId, (ERDM_Status)statusType, (ERDM_StatusMessage)statusMessage, dataValue1, dataValue2) + [DataTreeObjectConstructor] + public RDMStatusMessage( + [DataTreeObjectParameter("subdevice_id")] ushort subDeviceId, + [DataTreeObjectParameter("status_type")] byte statusType, + [DataTreeObjectParameter("status_message_id")] ushort statusMessage, + [DataTreeObjectParameter("data_value_1")] short dataValue1, + [DataTreeObjectParameter("data_value_2")] short dataValue2) + : this(subDeviceId, (ERDM_Status)statusType, (ERDM_StatusMessage)statusMessage, dataValue1, dataValue2) + { + } + + [DataTreeObjectProperty("subdevice_id", 0)] + public ushort SubDeviceId { get; private set; } + public ERDM_Status EStatusType + { + get { + return (ERDM_Status)StatusType; } - - [DataTreeObjectProperty("subdevice_id", 0)] - public ushort SubDeviceId { get; private set; } - public ERDM_Status EStatusType + private set { - get - { - return (ERDM_Status)StatusType; - } - private set - { - StatusType = (byte)value; - } + StatusType = (byte)value; } - [DataTreeObjectProperty("status_type", 1)] - public byte StatusType { get; private set; } - public ERDM_StatusMessage EStatusMessage + } + [DataTreeObjectProperty("status_type", 1)] + public byte StatusType { get; private set; } + public ERDM_StatusMessage EStatusMessage + { + get { - get - { - return (ERDM_StatusMessage)StatusMessage; - } - private set - { - StatusMessage = (ushort)value; - } + return (ERDM_StatusMessage)StatusMessage; } - [DataTreeObjectProperty("status_message_id", 2)] - public ushort StatusMessage { get; private set; } - [DataTreeObjectProperty("data_value_1", 3)] - public short DataValue1 { get; private set; } - [DataTreeObjectProperty("data_value_2", 4)] - public short DataValue2 { get; private set; } - public const int PDL = 9; - public string FormatedString => EStatusMessage.GetStatusMessage(DataValue1, DataValue2); - - internal void Clear() + private set { - EStatusType |= ERDM_Status.CLEARED; + StatusMessage = (ushort)value; } + } + [DataTreeObjectProperty("status_message_id", 2)] + public ushort StatusMessage { get; private set; } + [DataTreeObjectProperty("data_value_1", 3)] + public short DataValue1 { get; private set; } + [DataTreeObjectProperty("data_value_2", 4)] + public short DataValue2 { get; private set; } + public const int PDL = 9; + public string FormatedString => EStatusMessage.GetStatusMessage(DataValue1, DataValue2); - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("RDMStatusMessage"); - b.AppendLine($"SubDeviceId: {SubDeviceId}"); - b.AppendLine($"StatusType: {EStatusType}"); - b.AppendLine($"StatusMessage: {EStatusMessage}"); - b.AppendLine($"DataValue1: {DataValue1}"); - b.AppendLine($"DataValue2: {DataValue2}"); - b.AppendLine($"FormatedString: {FormatedString}"); + internal void Clear() + { + EStatusType |= ERDM_Status.CLEARED; + } - return b.ToString(); - } - public static RDMStatusMessage FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.STATUS_MESSAGES, PDL); + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("RDMStatusMessage"); + b.AppendLine($"SubDeviceId: {SubDeviceId}"); + b.AppendLine($"StatusType: {EStatusType}"); + b.AppendLine($"StatusMessage: {EStatusMessage}"); + b.AppendLine($"DataValue1: {DataValue1}"); + b.AppendLine($"DataValue2: {DataValue2}"); + b.AppendLine($"FormatedString: {FormatedString}"); - return FromPayloadData(msg.ParameterData); - } - public static RDMStatusMessage FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + return b.ToString(); + } + public static RDMStatusMessage FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.STATUS_MESSAGES, PDL); - var i = new RDMStatusMessage( - subDeviceId: Tools.DataToUShort(ref data), - statusType: Tools.DataToEnum(ref data), - statusMessage: Tools.DataToEnum(ref data), - dataValue1: Tools.DataToShort(ref data), - dataValue2: Tools.DataToShort(ref data) - ); - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.SubDeviceId)); - data.AddRange(Tools.ValueToData(this.EStatusType)); - data.AddRange(Tools.ValueToData(this.EStatusMessage)); - data.AddRange(Tools.ValueToData(this.DataValue1)); - data.AddRange(Tools.ValueToData(this.DataValue2)); - return data.ToArray(); - } + return FromPayloadData(msg.ParameterData); + } + public static RDMStatusMessage FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - public bool Equals(RDMStatusMessage other) - { - if (other is null) return false; - if (ReferenceEquals(this, other)) return true; - return this.SubDeviceId == other.SubDeviceId && - this.EStatusType == other.EStatusType && - this.EStatusMessage == other.EStatusMessage && - this.DataValue1 == other.DataValue1 && - this.DataValue2 == other.DataValue2; - } + var i = new RDMStatusMessage( + subDeviceId: Tools.DataToUShort(ref data), + statusType: Tools.DataToEnum(ref data), + statusMessage: Tools.DataToEnum(ref data), + dataValue1: Tools.DataToShort(ref data), + dataValue2: Tools.DataToShort(ref data) + ); + return i; + } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.SubDeviceId)); + data.AddRange(Tools.ValueToData(this.EStatusType)); + data.AddRange(Tools.ValueToData(this.EStatusMessage)); + data.AddRange(Tools.ValueToData(this.DataValue1)); + data.AddRange(Tools.ValueToData(this.DataValue2)); + return data.ToArray(); + } + + public bool Equals(RDMStatusMessage other) + { + if (other is null) return false; + if (ReferenceEquals(this, other)) return true; + return this.SubDeviceId == other.SubDeviceId && + this.EStatusType == other.EStatusType && + this.EStatusMessage == other.EStatusMessage && + this.DataValue1 == other.DataValue1 && + this.DataValue2 == other.DataValue2; } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/RequestRange.cs b/RDMSharp/RDM/PayloadObject/RequestRange.cs index ce7a1949..a7bd438a 100644 --- a/RDMSharp/RDM/PayloadObject/RequestRange.cs +++ b/RDMSharp/RDM/PayloadObject/RequestRange.cs @@ -1,50 +1,49 @@ -using System; -using System.Collections.Generic; - -namespace RDMSharp -{ - public class RequestRange : IRequestRange, IRequestRange - { - - object IRequestRange.Start => _start; - - object IRequestRange.End => _end; - - T IRequestRange.Start => (T)Convert.ChangeType(_start, typeof(T)); - - T IRequestRange.End => (T)Convert.ChangeType(_end, typeof(T)); - - private ulong _start; - private ulong _end; - - public RequestRange(T start, T end) - { - _start = Convert.ToUInt64(start); - _end = Convert.ToUInt64(end); - } - - IEnumerable IRequestRange.ToEnumerator() - { - for (ulong i = _start; i <= _end; i++) - yield return (T)Convert.ChangeType(i, typeof(T)); - } - IEnumerable IRequestRange.ToEnumerator() - { - for (ulong i = _start; i <= _end; i++) - yield return (T)Convert.ChangeType(i, typeof(T)); - } - } - public interface IRequestRange - { - T Start { get; } - T End { get; } - public IEnumerable ToEnumerator(); - } - public interface IRequestRange - { - object Start { get; } - object End { get; } - - public IEnumerable ToEnumerator(); - } -} \ No newline at end of file +//using System; +//using System.Collections.Generic; + +//namespace RDMSharp.PayloadObject; + +//public class RequestRange : IRequestRange, IRequestRange +//{ + +// object IRequestRange.Start => _start; + +// object IRequestRange.End => _end; + +// T IRequestRange.Start => (T)Convert.ChangeType(_start, typeof(T)); + +// T IRequestRange.End => (T)Convert.ChangeType(_end, typeof(T)); + +// private ulong _start; +// private ulong _end; + +// public RequestRange(T start, T end) +// { +// _start = Convert.ToUInt64(start); +// _end = Convert.ToUInt64(end); +// } + +// IEnumerable IRequestRange.ToEnumerator() +// { +// for (ulong i = _start; i <= _end; i++) +// yield return (T)Convert.ChangeType(i, typeof(T)); +// } +// IEnumerable IRequestRange.ToEnumerator() +// { +// for (ulong i = _start; i <= _end; i++) +// yield return (T)Convert.ChangeType(i, typeof(T)); +// } +//} +//public interface IRequestRange +//{ +// T Start { get; } +// T End { get; } +// public IEnumerable ToEnumerator(); +//} +//public interface IRequestRange +//{ +// object Start { get; } +// object End { get; } + +// public IEnumerable ToEnumerator(); +//} \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/SetDiscoveryStateRequest.cs b/RDMSharp/RDM/PayloadObject/SetDiscoveryStateRequest.cs index c66593f6..3bd90183 100644 --- a/RDMSharp/RDM/PayloadObject/SetDiscoveryStateRequest.cs +++ b/RDMSharp/RDM/PayloadObject/SetDiscoveryStateRequest.cs @@ -2,60 +2,42 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.DISCOVERY_STATE, Command.ECommandDublicate.SetRequest)] +public class SetDiscoveryStateRequest : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.DISCOVERY_STATE, Command.ECommandDublicate.SetResponse)] - public class SetDiscoveryStateRequest : AbstractRDMPayloadObject + public SetDiscoveryStateRequest( + ushort endpointId = default, + ERDM_DiscoveryState discoveryState = default) { - public SetDiscoveryStateRequest( - ushort endpointId = default, - ERDM_DiscoveryState discoveryState = default) - { - this.EndpointId = endpointId; - this.DiscoveryState = discoveryState; - } - [DataTreeObjectConstructor] - public SetDiscoveryStateRequest( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId, - [DataTreeObjectParameter("state")] byte discoveryState) - : this(endpointId, (ERDM_DiscoveryState)discoveryState) - { - } - - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("state", 1)] - public ERDM_DiscoveryState DiscoveryState { get; private set; } - public const int PDL = 0x03; - - public override string ToString() - { - return $"Endpoint: {EndpointId} - DiscoveryState: {DiscoveryState}"; - } - - public static SetDiscoveryStateRequest FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DISCOVERY_STATE, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static SetDiscoveryStateRequest FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + this.EndpointId = endpointId; + this.DiscoveryState = discoveryState; + } + [DataTreeObjectConstructor] + public SetDiscoveryStateRequest( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId, + [DataTreeObjectParameter("state")] byte discoveryState) + : this(endpointId, (ERDM_DiscoveryState)discoveryState) + { + } - var i = new SetDiscoveryStateRequest( - endpointId: Tools.DataToUShort(ref data), - discoveryState: Tools.DataToEnum(ref data)); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("state", 1)] + public ERDM_DiscoveryState DiscoveryState { get; private set; } + public const int PDL = 0x03; - return i; - } + public override string ToString() + { + return $"Endpoint: {EndpointId} - DiscoveryState: {DiscoveryState}"; + } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.DiscoveryState)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.DiscoveryState)); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PayloadObject/SetEndpointTimingRequest.cs b/RDMSharp/RDM/PayloadObject/SetEndpointTimingRequest.cs index 612115bb..428b0152 100644 --- a/RDMSharp/RDM/PayloadObject/SetEndpointTimingRequest.cs +++ b/RDMSharp/RDM/PayloadObject/SetEndpointTimingRequest.cs @@ -2,53 +2,37 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp -{ - [DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicate.SetRequest)] +namespace RDMSharp.PayloadObject; - public class SetEndpointTimingRequest : AbstractRDMPayloadObject - { - [DataTreeObjectConstructor] - public SetEndpointTimingRequest( - [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, - [DataTreeObjectParameter("setting")] byte timingId = default) - { - this.EndpointId = endpointId; - this.TimingId = timingId; - } +[DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicate.SetRequest)] - [DataTreeObjectProperty("endpoint_id", 0)] - public ushort EndpointId { get; private set; } - [DataTreeObjectProperty("setting", 1)] - public byte TimingId { get; private set; } - public byte Timings { get; private set; } - public const int PDL = 3; +public class SetEndpointTimingRequest : AbstractRDMPayloadObject +{ + [DataTreeObjectConstructor] + public SetEndpointTimingRequest( + [DataTreeObjectParameter("endpoint_id")] ushort endpointId = default, + [DataTreeObjectParameter("setting")] byte timingId = default) + { + this.EndpointId = endpointId; + this.TimingId = timingId; + } - public override string ToString() - { - return $"Endpoint: {EndpointId} TimingId: {TimingId}"; - } - public static SetEndpointTimingRequest FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.ENDPOINT_TIMING, PDL); + [DataTreeObjectProperty("endpoint_id", 0)] + public ushort EndpointId { get; private set; } + [DataTreeObjectProperty("setting", 1)] + public byte TimingId { get; private set; } + public const int PDL = 3; - return FromPayloadData(msg.ParameterData); - } - public static SetEndpointTimingRequest FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new SetEndpointTimingRequest( - endpointId: Tools.DataToUShort(ref data), - timingId: Tools.DataToByte(ref data)); + public override string ToString() + { + return $"Endpoint: {EndpointId} TimingId: {TimingId}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.EndpointId)); - data.AddRange(Tools.ValueToData(this.TimingId)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.EndpointId)); + data.AddRange(Tools.ValueToData(this.TimingId)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/SetLockPinRequest.cs b/RDMSharp/RDM/PayloadObject/SetLockPinRequest.cs index 471ce6cf..afb74a82 100644 --- a/RDMSharp/RDM/PayloadObject/SetLockPinRequest.cs +++ b/RDMSharp/RDM/PayloadObject/SetLockPinRequest.cs @@ -2,52 +2,36 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.LOCK_PIN, Command.ECommandDublicate.SetRequest)] +public class SetLockPinRequest : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.LOCK_PIN, Command.ECommandDublicate.SetRequest)] - public class SetLockPinRequest : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public SetLockPinRequest( + [DataTreeObjectParameter("new_pin_code")] ushort newPinCode = 0, + [DataTreeObjectParameter("current_pin_code")] ushort currentPinCode = 0) { - [DataTreeObjectConstructor] - public SetLockPinRequest( - [DataTreeObjectParameter("new_pin_code")] ushort newPinCode = 0, - [DataTreeObjectParameter("current_pin_code")] ushort currentPinCode = 0) - { - this.NewPinCode = newPinCode; - this.CurrentPinCode = currentPinCode; - } - - [DataTreeObjectProperty("new_pin_code", 0)] - public ushort NewPinCode { get; private set; } - [DataTreeObjectProperty("current_pin_code", 1)] - public ushort CurrentPinCode { get; private set; } - public const int PDL = 4; - - public override string ToString() - { - return $"New PIN Code: {NewPinCode} Current PIN Code: {CurrentPinCode}"; - } - public static SetLockPinRequest FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.SET_COMMAND, ERDM_Parameter.LOCK_PIN, PDL); + this.NewPinCode = newPinCode; + this.CurrentPinCode = currentPinCode; + } - return FromPayloadData(msg.ParameterData); - } - public static SetLockPinRequest FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + [DataTreeObjectProperty("new_pin_code", 0)] + public ushort NewPinCode { get; private set; } + [DataTreeObjectProperty("current_pin_code", 1)] + public ushort CurrentPinCode { get; private set; } + public const int PDL = 4; - var i = new SetLockPinRequest( - newPinCode: Tools.DataToUShort(ref data), - currentPinCode: Tools.DataToUShort(ref data)); + public override string ToString() + { + return $"New PIN Code: {NewPinCode} Current PIN Code: {CurrentPinCode}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.NewPinCode)); - data.AddRange(Tools.ValueToData(this.CurrentPinCode)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.NewPinCode)); + data.AddRange(Tools.ValueToData(this.CurrentPinCode)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/SetLockStateRequest.cs b/RDMSharp/RDM/PayloadObject/SetLockStateRequest.cs index 75782952..7099f518 100644 --- a/RDMSharp/RDM/PayloadObject/SetLockStateRequest.cs +++ b/RDMSharp/RDM/PayloadObject/SetLockStateRequest.cs @@ -2,51 +2,36 @@ using RDMSharp.Metadata.JSON; using System.Collections.Generic; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.LOCK_STATE, Command.ECommandDublicate.SetRequest)] +public class SetLockStateRequest : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.LOCK_STATE, Command.ECommandDublicate.SetRequest)] - public class SetLockStateRequest : AbstractRDMPayloadObject + [DataTreeObjectConstructor] + public SetLockStateRequest( + [DataTreeObjectParameter("pin_code")] ushort pinCode = 0, + [DataTreeObjectParameter("state")] byte lockStateId = 0) { - [DataTreeObjectConstructor] - public SetLockStateRequest( - [DataTreeObjectParameter("pin_code")] ushort pinCode = 0, - [DataTreeObjectParameter("state")] byte lockStateId = 0) - { - this.PinCode = pinCode; - this.LockStateId = lockStateId; - } - - [DataTreeObjectProperty("pin_code", 0)] - public ushort PinCode { get; private set; } - [DataTreeObjectProperty("state", 1)] - public byte LockStateId { get; private set; } - public const int PDL = 3; + this.PinCode = pinCode; + this.LockStateId = lockStateId; + } - public override string ToString() - { - return $"PIN Code: {PinCode} Lock State: {LockStateId}"; - } - public static SetLockStateRequest FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.SET_COMMAND, ERDM_Parameter.LOCK_STATE, PDL); + [DataTreeObjectProperty("pin_code", 0)] + public ushort PinCode { get; private set; } + [DataTreeObjectProperty("state", 1)] + public byte LockStateId { get; private set; } + public const int PDL = 3; - return FromPayloadData(msg.ParameterData); - } - public static SetLockStateRequest FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var i = new SetLockStateRequest( - pinCode: Tools.DataToUShort(ref data), - lockStateId: Tools.DataToByte(ref data)); + public override string ToString() + { + return $"PIN Code: {PinCode} Lock State: {LockStateId}"; + } - return i; - } - public override byte[] ToPayloadData() - { - List data = new List(); - data.AddRange(Tools.ValueToData(this.PinCode)); - data.AddRange(Tools.ValueToData(this.LockStateId)); - return data.ToArray(); - } + public override byte[] ToPayloadData() + { + List data = new List(); + data.AddRange(Tools.ValueToData(this.PinCode)); + data.AddRange(Tools.ValueToData(this.LockStateId)); + return data.ToArray(); } } diff --git a/RDMSharp/RDM/PayloadObject/TCPCommsEntry.cs b/RDMSharp/RDM/PayloadObject/TCPCommsEntry.cs index cff4797e..f9bcaba7 100644 --- a/RDMSharp/RDM/PayloadObject/TCPCommsEntry.cs +++ b/RDMSharp/RDM/PayloadObject/TCPCommsEntry.cs @@ -6,105 +6,104 @@ using System.Net.Sockets; using System.Text; -namespace RDMSharp +namespace RDMSharp.PayloadObject; + +[DataTreeObject(ERDM_Parameter.TCP_COMMS_STATUS, Command.ECommandDublicate.GetResponse)] +public class TCPCommsEntry : AbstractRDMPayloadObject { - [DataTreeObject(ERDM_Parameter.TCP_COMMS_STATUS, Command.ECommandDublicate.GetResponse)] - public class TCPCommsEntry : AbstractRDMPayloadObject - { - [DataTreeObjectConstructor] - public TCPCommsEntry( - [DataTreeObjectParameter("scopeString")] string scopeString = default, - [DataTreeObjectParameter("brokerAddress")] IPAddress brokerAddress = default, - [DataTreeObjectParameter("brokerPort")] ushort brokerPort = default, - [DataTreeObjectParameter("unhealthyTCPEvents")] ushort unhealthyTCPEvents = default) - { - - if (string.IsNullOrWhiteSpace(scopeString)) - return; - - if (scopeString.Length > 62) - scopeString = scopeString.Substring(0, 62); - - - this.ScopeString = scopeString; - this.BrokerAdress = brokerAddress; - this.BrokerPort = brokerPort; - this.UnhealthyTCPEvents = unhealthyTCPEvents; - } + [DataTreeObjectConstructor] + public TCPCommsEntry( + [DataTreeObjectParameter("scopeString")] string scopeString = default, + [DataTreeObjectParameter("brokerAddress")] IPAddress brokerAddress = default, + [DataTreeObjectParameter("brokerPort")] ushort brokerPort = default, + [DataTreeObjectParameter("unhealthyTCPEvents")] ushort unhealthyTCPEvents = default) + { + + if (string.IsNullOrWhiteSpace(scopeString)) + return; + + if (scopeString.Length > 62) + scopeString = scopeString.Substring(0, 62); + + + this.ScopeString = scopeString; + this.BrokerAdress = brokerAddress; + this.BrokerPort = brokerPort; + this.UnhealthyTCPEvents = unhealthyTCPEvents; + } - [DataTreeObjectProperty("scopeString", 0)] - public string ScopeString { get; private set; } - [DataTreeObjectProperty("brokerAddress", 1)] - public IPAddress BrokerAdress { get; private set; } - [DataTreeObjectProperty("brokerPort", 2)] - public ushort BrokerPort { get; private set; } - [DataTreeObjectProperty("unhealthyTCPEvents", 3)] - public ushort UnhealthyTCPEvents { get; private set; } - - public const int PDL = 0x57; - - public override string ToString() - { - StringBuilder b = new StringBuilder(); - b.AppendLine("TCPCommsEntry"); - b.AppendLine($"ScopeString: {ScopeString}"); - b.AppendLine($"BrokerAdress: {BrokerAdress}"); - b.AppendLine($"BrokerPort: {BrokerPort}"); - b.AppendLine($"UnhealthyTCPEvents: {UnhealthyTCPEvents}"); - - return b.ToString(); - } - - public static TCPCommsEntry FromMessage(RDMMessage msg) - { - RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.TCP_COMMS_STATUS, PDL); - - return FromPayloadData(msg.ParameterData); - } - public static TCPCommsEntry FromPayloadData(byte[] data) - { - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); - var scopeString = Tools.DataToString(ref data, 63).Replace("\u0000", ""); - byte[] ipv4Bytes = data.Take(4).ToArray(); - byte[] ipv6Bytes = data.Skip(4).Take(16).ToArray(); - data = data.Skip(20).ToArray(); - IPAddress brokerAddress = null; - - if (ipv4Bytes.Any(b => b != 0)) - brokerAddress = Tools.DataToIPAddressIPv4(ref ipv4Bytes); - else if (ipv6Bytes.Any(b => b != 0)) - brokerAddress = Tools.DataToIPAddressIPv6(ref ipv6Bytes); - - ushort staticBrokerPort = Tools.DataToUShort(ref data); - ushort unhealthyTCPEvents = Tools.DataToUShort(ref data); - - var i = new TCPCommsEntry( - scopeString: scopeString, - brokerAddress: brokerAddress, - brokerPort: staticBrokerPort, - unhealthyTCPEvents: unhealthyTCPEvents); - - return i; - } - public override byte[] ToPayloadData() - { - List scopeStringBytes = new List(); - scopeStringBytes.AddRange(Tools.ValueToData(this.ScopeString, 62)); - while (scopeStringBytes.Count < 63) - scopeStringBytes.Add(0); - var ipv4Bytes = this.BrokerAdress?.AddressFamily == AddressFamily.InterNetwork ? Tools.ValueToData(this.BrokerAdress) : new byte[4]; - var ipv6Bytes = this.BrokerAdress?.AddressFamily == AddressFamily.InterNetworkV6 ? Tools.ValueToData(this.BrokerAdress) : new byte[16]; - - var brokerPortBytes = Tools.ValueToData(this.BrokerPort); - var unhealthyTCPEventsBytes = Tools.ValueToData(this.UnhealthyTCPEvents); - - List data = new List(); - data.AddRange(scopeStringBytes); - data.AddRange(ipv4Bytes); - data.AddRange(ipv6Bytes); - data.AddRange(brokerPortBytes); - data.AddRange(unhealthyTCPEventsBytes); - return data.ToArray(); - } + [DataTreeObjectProperty("scopeString", 0)] + public string ScopeString { get; private set; } + [DataTreeObjectProperty("brokerAddress", 1)] + public IPAddress BrokerAdress { get; private set; } + [DataTreeObjectProperty("brokerPort", 2)] + public ushort BrokerPort { get; private set; } + [DataTreeObjectProperty("unhealthyTCPEvents", 3)] + public ushort UnhealthyTCPEvents { get; private set; } + + public const int PDL = 0x57; + + public override string ToString() + { + StringBuilder b = new StringBuilder(); + b.AppendLine("TCPCommsEntry"); + b.AppendLine($"ScopeString: {ScopeString}"); + b.AppendLine($"BrokerAdress: {BrokerAdress}"); + b.AppendLine($"BrokerPort: {BrokerPort}"); + b.AppendLine($"UnhealthyTCPEvents: {UnhealthyTCPEvents}"); + + return b.ToString(); + } + + public static TCPCommsEntry FromMessage(RDMMessage msg) + { + RDMMessageInvalidException.ThrowIfInvalidPDL(msg, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.TCP_COMMS_STATUS, PDL); + + return FromPayloadData(msg.ParameterData); + } + public static TCPCommsEntry FromPayloadData(byte[] data) + { + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(data, PDL); + var scopeString = Tools.DataToString(ref data, 63).Replace("\u0000", ""); + byte[] ipv4Bytes = data.Take(4).ToArray(); + byte[] ipv6Bytes = data.Skip(4).Take(16).ToArray(); + data = data.Skip(20).ToArray(); + IPAddress brokerAddress = null; + + if (ipv4Bytes.Any(b => b != 0)) + brokerAddress = Tools.DataToIPAddressIPv4(ref ipv4Bytes); + else if (ipv6Bytes.Any(b => b != 0)) + brokerAddress = Tools.DataToIPAddressIPv6(ref ipv6Bytes); + + ushort staticBrokerPort = Tools.DataToUShort(ref data); + ushort unhealthyTCPEvents = Tools.DataToUShort(ref data); + + var i = new TCPCommsEntry( + scopeString: scopeString, + brokerAddress: brokerAddress, + brokerPort: staticBrokerPort, + unhealthyTCPEvents: unhealthyTCPEvents); + + return i; + } + public override byte[] ToPayloadData() + { + List scopeStringBytes = new List(); + scopeStringBytes.AddRange(Tools.ValueToData(this.ScopeString, 62)); + while (scopeStringBytes.Count < 63) + scopeStringBytes.Add(0); + var ipv4Bytes = this.BrokerAdress?.AddressFamily == AddressFamily.InterNetwork ? Tools.ValueToData(this.BrokerAdress) : new byte[4]; + var ipv6Bytes = this.BrokerAdress?.AddressFamily == AddressFamily.InterNetworkV6 ? Tools.ValueToData(this.BrokerAdress) : new byte[16]; + + var brokerPortBytes = Tools.ValueToData(this.BrokerPort); + var unhealthyTCPEventsBytes = Tools.ValueToData(this.UnhealthyTCPEvents); + + List data = new List(); + data.AddRange(scopeStringBytes); + data.AddRange(ipv4Bytes); + data.AddRange(ipv6Bytes); + data.AddRange(brokerPortBytes); + data.AddRange(unhealthyTCPEventsBytes); + return data.ToArray(); } } \ No newline at end of file diff --git a/RDMSharp/RDM/PeerToPeerProcess.cs b/RDMSharp/RDM/PeerToPeerProcess.cs index 8e14d406..fdff4fcf 100644 --- a/RDMSharp/RDM/PeerToPeerProcess.cs +++ b/RDMSharp/RDM/PeerToPeerProcess.cs @@ -1,196 +1,317 @@ using Microsoft.Extensions.Logging; using RDMSharp.Metadata; +using RDMSharp.PayloadObject; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Threading; using System.Threading.Tasks; using static RDMSharp.Metadata.JSON.Command; -namespace RDMSharp +namespace RDMSharp; + +public class PeerToPeerProcess : INotifyPropertyChanged { - public class PeerToPeerProcess - { - private static readonly ILogger Logger = Logging.CreateLogger(); + private static readonly ILogger Logger = Logging.CreateLogger(); - public enum EPeerToPeerProcessState + public enum EPeerToPeerProcessState + { + Waiting, + Running, + Finished, + Failed + } + public readonly ERDM_Command Command; + public readonly UID UID; + public readonly SubDevice SubDevice; + public ParameterBag ParameterBag { get; private set; } + public readonly DataTreeBranch RequestPayloadObject; + private DataTreeBranch _responsePayloadObject = DataTreeBranch.Unset; + public DataTreeBranch ResponsePayloadObject + { + get { - Waiting, - Running, - Finished, - Failed + return _responsePayloadObject; } - public readonly ERDM_Command Command; - public readonly UID UID; - public readonly SubDevice SubDevice; - public ParameterBag ParameterBag { get; private set; } - public readonly DataTreeBranch RequestPayloadObject; - public DataTreeBranch ResponsePayloadObject { get; private set; } = DataTreeBranch.Unset; - - public MetadataJSONObjectDefine Define { get; private set; } - public EPeerToPeerProcessState State { get; private set; } = EPeerToPeerProcessState.Waiting; - - public Exception Exception { get; private set; } - public ERDM_NackReason[] NackReason { get; private set; } - - private RDMMessage request = null; - private RDMMessage response = null; - public Func BeforeSendMessage; - public Func ResponseMessage; - public byte MessageCounter => response?.MessageCounter ?? 0; - private SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1); - - public PeerToPeerProcess(ERDM_Command command, UID uid, SubDevice subDevice, ParameterBag parameterBag, DataTreeBranch? payloadObject = null) + private set { - if (command != ERDM_Command.GET_COMMAND) - if (command != ERDM_Command.SET_COMMAND) - throw new ArgumentException($"{nameof(command)} should be {ERDM_Command.GET_COMMAND} or {ERDM_Command.SET_COMMAND}"); + if (_responsePayloadObject == value) + return; + _responsePayloadObject = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ResponsePayloadObject))); + } + } - Command = command; - UID = uid; - SubDevice = subDevice; - ParameterBag = parameterBag; - RequestPayloadObject = payloadObject ?? DataTreeBranch.Unset; + public MetadataJSONObjectDefine Define { get; private set; } + private EPeerToPeerProcessState _state = EPeerToPeerProcessState.Waiting; + public EPeerToPeerProcessState State + { + get + { + return _state; + } + private set + { + if (_state == value) + return; + _state = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(State))); + } + } - Logger?.LogTrace($"Create PeerToPeerProcess: {Command} UID: {UID} SubDevice: {SubDevice} Parameter: {ParameterBag.PID} PayloadObject: {RequestPayloadObject.ToString()}"); + private Exception _exception; + public Exception Exception + { + get + { + return _exception; - //if (ParameterBag.PID != ERDM_Parameter.QUEUED_MESSAGE) - Define = MetadataFactory.GetDefine(ParameterBag); } - - public async Task Run(AsyncRDMRequestHelper asyncRDMRequestHelper = null) + private set { - asyncRDMRequestHelper ??= RDMSharp.Instance.AsyncRDMRequestHelper; - if (State != EPeerToPeerProcessState.Waiting) + if (_exception == value) return; - if (SemaphoreSlim.CurrentCount == 0) + _exception = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Exception))); + } + } + + private ERDM_NackReason? _nackReason; + public ERDM_NackReason? NackReason + { + get + { + return _nackReason; + } + private set + { + if (_nackReason == value) return; - await SemaphoreSlim.WaitAsync(); - State = EPeerToPeerProcessState.Running; - try + _nackReason = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(NackReason))); + } + } + + private RDMMessage request = null; + private RDMMessage response = null; + public Func BeforeSendMessage; + public Func ResponseMessage; + + private ConcurrentBag requestResponseHistory = new ConcurrentBag(); + public IEnumerable RequestResponseHistory => requestResponseHistory.ToList(); + + internal event EventHandler OnRequestResponseHistoryAdded; + + public byte MessageCounter => response?.MessageCounter ?? 0; + private SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1); + + public event PropertyChangedEventHandler PropertyChanged; + + public PeerToPeerProcess(ERDM_Command command, UID uid, SubDevice subDevice, ParameterBag parameterBag, DataTreeBranch? payloadObject = null) + { + if (command != ERDM_Command.GET_COMMAND) + if (command != ERDM_Command.SET_COMMAND) + throw new ArgumentException($"{nameof(command)} should be {ERDM_Command.GET_COMMAND} or {ERDM_Command.SET_COMMAND}"); + + Command = command; + UID = uid; + SubDevice = subDevice; + ParameterBag = parameterBag; + RequestPayloadObject = payloadObject ?? DataTreeBranch.Unset; + + Logger?.LogTrace($"Create PeerToPeerProcess: {Command} UID: {UID} SubDevice: {SubDevice} Parameter: {ParameterBag.PID} PayloadObject: {RequestPayloadObject.ToString()}"); + + //if (ParameterBag.PID != ERDM_Parameter.QUEUED_MESSAGE) + Define = MetadataFactory.GetDefine(ParameterBag); + } + + public async Task Run(AsyncRDMRequestHelper asyncRDMRequestHelper = null) + { + asyncRDMRequestHelper ??= RDMSharp.Instance.AsyncRDMRequestHelper; + if (State != EPeerToPeerProcessState.Waiting) + return; + if (SemaphoreSlim.CurrentCount == 0) + return; + await SemaphoreSlim.WaitAsync(); + State = EPeerToPeerProcessState.Running; + try + { + ECommandDublicate commandRequest = ECommandDublicate.GetRequest; + if (Command == ERDM_Command.SET_COMMAND) + commandRequest = ECommandDublicate.SetRequest; + + ECommandDublicate commandResponse = ECommandDublicate.GetResponse; + if (Command == ERDM_Command.SET_COMMAND) + commandResponse = ECommandDublicate.SetResponse; + + byte[] parameterData = null; + if (Define != null) + parameterData = MetadataFactory.ParsePayloadToData(Define, commandRequest, RequestPayloadObject).First(); + request = new RDMMessage() + { + Command = Command, + DestUID = UID, + SubDevice = SubDevice, + Parameter = ParameterBag.PID, + ParameterData = parameterData + }; + List bytes = new List(); + bool done = false; + int counter = 0; + do { - ECommandDublicate commandRequest = ECommandDublicate.GetRequest; - if (Command == ERDM_Command.SET_COMMAND) - commandRequest = ECommandDublicate.SetRequest; - - ECommandDublicate commandResponse = ECommandDublicate.GetResponse; - if (Command == ERDM_Command.SET_COMMAND) - commandResponse = ECommandDublicate.SetResponse; - - byte[] parameterData = null; - if (Define != null) - parameterData = MetadataFactory.ParsePayloadToData(Define, commandRequest, RequestPayloadObject).First(); - request = new RDMMessage() + try { - Command = Command, - DestUID = UID, - SubDevice = SubDevice, - Parameter = ParameterBag.PID, - ParameterData = parameterData - }; - List bytes = new List(); - bool done = false; - int counter = 0; - do + await RDMSharp.Instance.lockTransaktion(UID, TimeSpan.FromSeconds(7)); + } + catch (TimeoutException) { - counter++; - if (BeforeSendMessage != null) - await BeforeSendMessage(request); - if (response?.ResponseType == ERDM_ResponseType.ACK) - return; - var responseResult = await asyncRDMRequestHelper.RequestMessage(request); - if (!responseResult.Success || - (responseResult.Response is not null && responseResult.Response.ResponseType == ERDM_ResponseType.NACK_REASON)) - { - State = EPeerToPeerProcessState.Failed; - NackReason= responseResult.Response.NackReason; - if (responseResult.Response is not null) - ResponseMessage?.InvokeFailSafe(responseResult.Response); - return; - } - response = responseResult.Response; - switch (responseResult.Response.ResponseType) - { - case ERDM_ResponseType.ACK_TIMER: - case ERDM_ResponseType.ACK_TIMER_HI_RES: - if (response.Value is IAcknowledgeTimer timer) - { - await Task.Delay(timer.EstimidatedResponseTime); - request.Parameter = ERDM_Parameter.QUEUED_MESSAGE; - //Send Message on next loop - continue; - } - break; - case ERDM_ResponseType.ACK: - bytes.AddRange(response.ParameterData); - done = true; - var _byteArray = bytes.ToArray(); - bytes.Clear(); - bytes = null; - if (request.Parameter == ERDM_Parameter.QUEUED_MESSAGE) + + } + + counter++; + if (response?.ResponseType == ERDM_ResponseType.ACK) + return; + if (BeforeSendMessage != null) + await BeforeSendMessage(request); + var historyEntry = new RequestResponseHistoryEntry(request); + requestResponseHistory.Add(historyEntry); + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(RequestResponseHistory))); + OnRequestResponseHistoryAdded?.Invoke(this, historyEntry); + + RequestResult responseResult; + try + { + responseResult = await asyncRDMRequestHelper.RequestMessage(request); + } + finally + { + RDMSharp.Instance.unlockTransaktion(UID); + } + + if (responseResult.Timeout) + { + historyEntry.SetResponse(responseResult.Response, "Timeout"); + State = EPeerToPeerProcessState.Failed; + return; + } + if (responseResult.Disposing) + { + historyEntry.SetResponse(responseResult.Response, "Disposing"); + State = EPeerToPeerProcessState.Failed; + return; + } + if (!responseResult.Success || + (responseResult.Response is not null && responseResult.Response.ResponseType == ERDM_ResponseType.NACK_REASON)) + { + historyEntry.SetResponse(responseResult.Response, "NACK"); + State = EPeerToPeerProcessState.Failed; + NackReason = responseResult.Response?.NackReason; + if (responseResult.Response is not null) + ResponseMessage?.InvokeFailSafe(responseResult.Response); + return; + } + + response = responseResult.Response; + historyEntry.SetResponse(response); + switch (responseResult.Response.ResponseType) + { + case ERDM_ResponseType.ACK_TIMER: + case ERDM_ResponseType.ACK_TIMER_HI_RES: + if (response.AcknowledgeTimer is IAcknowledgeTimer timer) + { + await Task.Delay(timer.EstimidatedResponseTime); + request = new RDMMessage() { - ParameterBag = new ParameterBag(response.Parameter, ParameterBag.ManufacturerID, ParameterBag.DeviceModelID, ParameterBag.SoftwareVersionID); - Define = MetadataFactory.GetDefine(ParameterBag); - } - if (Define != null) - ResponsePayloadObject = MetadataFactory.ParseDataToPayload(Define, commandResponse, _byteArray); - State = EPeerToPeerProcessState.Finished; - - ResponseMessage?.InvokeFailSafe(responseResult.Response); - return; - case ERDM_ResponseType.ACK_OVERFLOW: - bytes.AddRange(response.ParameterData); + Command = ERDM_Command.GET_COMMAND, + DestUID = UID, + SubDevice = SubDevice, + Parameter = ERDM_Parameter.QUEUED_MESSAGE, + ParameterData = new byte[] { 2 } + }; + //Send Message on next loop continue; + } + break; + case ERDM_ResponseType.ACK: + bytes.AddRange(response.ParameterData); + done = true; + var _byteArray = bytes.ToArray(); + bytes.Clear(); + bytes = null; + if (request.Parameter == ERDM_Parameter.QUEUED_MESSAGE) + { + ParameterBag = new ParameterBag(response.Parameter, ParameterBag.ManufacturerID, ParameterBag.DeviceModelID, ParameterBag.SoftwareVersionID); + Define = MetadataFactory.GetDefine(ParameterBag); + } + if (Define != null) + ResponsePayloadObject = MetadataFactory.ParseDataToPayload(Define, commandResponse, _byteArray); + State = EPeerToPeerProcessState.Finished; + + ResponseMessage?.InvokeFailSafe(responseResult.Response); + return; + case ERDM_ResponseType.ACK_OVERFLOW: + bytes.AddRange(response.ParameterData); + continue; - } - //if ((response.ResponseType == ERDM_ResponseType.ACK_TIMER || - // response.ResponseType == ERDM_ResponseType.ACK_TIMER_HI_RES) && response.Value is IAcknowledgeTimer timer) - //{ - // await Task.Delay(timer.EstimidatedResponseTime); - // request.Parameter = ERDM_Parameter.QUEUED_MESSAGE; - // //Send Message on next loop - // continue; - //} - //if (response.ResponseType == ERDM_ResponseType.ACK) - //{ - // bytes.AddRange(response.ParameterData); - // done = true; - // var _byteArray = bytes.ToArray(); - // bytes.Clear(); - // bytes = null; - // if (request.Parameter == ERDM_Parameter.QUEUED_MESSAGE) - // { - // ParameterBag = new ParameterBag(response.Parameter, ParameterBag.ManufacturerID, ParameterBag.DeviceModelID, ParameterBag.SoftwareVersionID); - // Define = MetadataFactory.GetDefine(ParameterBag); - // } - // if (Define != null) - // ResponsePayloadObject = MetadataFactory.ParseDataToPayload(Define, commandResponse, _byteArray); - // State = EPeerToPeerProcessState.Finished; - - // ResponseMessage?.InvokeFailSafe(responseResult.Response); - // return; - //} - //if (response.ResponseType == ERDM_ResponseType.ACK_OVERFLOW) - //{ - // bytes.AddRange(response.ParameterData); - // //Do nothing else send another Request - // //Send Message on next loop - // continue; - //} } - while (!done && State == EPeerToPeerProcessState.Running); - } - catch (Exception e) - { - Logger?.LogError(e); - this.Exception = e; - State = EPeerToPeerProcessState.Failed; - } - finally - { - SemaphoreSlim.Release(); + //if ((response.ResponseType == ERDM_ResponseType.ACK_TIMER || + // response.ResponseType == ERDM_ResponseType.ACK_TIMER_HI_RES) && response.Value is IAcknowledgeTimer timer) + //{ + // await Task.Delay(timer.EstimidatedResponseTime); + // request.Parameter = ERDM_Parameter.QUEUED_MESSAGE; + // //Send Message on next loop + // continue; + //} + //if (response.ResponseType == ERDM_ResponseType.ACK) + //{ + // bytes.AddRange(response.ParameterData); + // done = true; + // var _byteArray = bytes.ToArray(); + // bytes.Clear(); + // bytes = null; + // if (request.Parameter == ERDM_Parameter.QUEUED_MESSAGE) + // { + // ParameterBag = new ParameterBag(response.Parameter, ParameterBag.ManufacturerID, ParameterBag.DeviceModelID, ParameterBag.SoftwareVersionID); + // Define = MetadataFactory.GetDefine(ParameterBag); + // } + // if (Define != null) + // ResponsePayloadObject = MetadataFactory.ParseDataToPayload(Define, commandResponse, _byteArray); + // State = EPeerToPeerProcessState.Finished; + + // ResponseMessage?.InvokeFailSafe(responseResult.Response); + // return; + //} + //if (response.ResponseType == ERDM_ResponseType.ACK_OVERFLOW) + //{ + // bytes.AddRange(response.ParameterData); + // //Do nothing else send another Request + // //Send Message on next loop + // continue; + //} } + while (!done && State == EPeerToPeerProcessState.Running); + } + catch (TimeoutException te) + { + Logger?.LogInformation($"Timeout while running PeerToPeerProcess: {Command} UID: {UID} SubDevice: {SubDevice} Parameter: {ParameterBag.PID}"); + State = EPeerToPeerProcessState.Failed; + } + catch (Exception e) + { + Logger?.LogError(e); + this.Exception = e; + State = EPeerToPeerProcessState.Failed; + } + finally + { + var last = requestResponseHistory.LastOrDefault(); + if (last is not null) + if (last.State is null) + last.SetResponse(null, "Fail"); + SemaphoreSlim.Release(); } } -} \ No newline at end of file +} diff --git a/RDMSharp/RDM/RDMMessage.cs b/RDMSharp/RDM/RDMMessage.cs index 1429a2af..b5560aec 100644 --- a/RDMSharp/RDM/RDMMessage.cs +++ b/RDMSharp/RDM/RDMMessage.cs @@ -1,558 +1,657 @@ using Microsoft.Extensions.Logging; using RDMSharp.Metadata; -using RDMSharp.Metadata.JSON; +using RDMSharp.PayloadObject; using System; using System.Collections.Generic; using System.Linq; using System.Text; +using _AcknowledgeTimer = RDMSharp.PayloadObject.AcknowledgeTimer; -namespace RDMSharp -{ - public class RDMMessage : IEquatable - { - private static readonly ILogger Logger = Logging.CreateLogger(); - private byte[] _parameterData = Array.Empty(); - private byte? preambleCount = null; +namespace RDMSharp; - public RDMMessage() - { +public class RDMMessage : IEquatable +{ + private static readonly ILogger Logger = Logging.CreateLogger(); + private byte[] _parameterData = Array.Empty(); + private byte? preambleCount = null; - } - public RDMMessage(in byte[] data) - { + public RDMMessage() + { + + } + public RDMMessage(in byte[] data) + { #if NETSTANDARD - if (data == null) - throw new ArgumentNullException(nameof(data)); + if (data == null) + throw new ArgumentNullException(nameof(data)); #else - ArgumentNullException.ThrowIfNull(data); + ArgumentNullException.ThrowIfNull(data); #endif - if (data.Length < 26) + if (data.Length < 26) + { + if (data.Length >= 17 && (data[0] == 0xFE || data[0] == 0xAA)) { - if (data.Length >= 17 && (data[0] == 0xFE || data[0] == 0xAA)) - { - Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE; - Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH; + Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE; + Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH; - //Parse Byte[] According to Spec - //data could have a Preample of 0 - 7 bytes, search for Preample seperator - int dataIndex = Array.IndexOf(data, (byte)0xAA); - if (dataIndex == -1) //No Preamble seperator found, corrupt - throw new Exception("No Preamble seperator found, corrupt"); - if (data.Length - dataIndex < 17) //Data Missing, corrupt - throw new Exception("Data Missing, corrupt"); - if (dataIndex >= 8) //Data Missing, corrupt - throw new Exception("Data Missing, corrupt"); + //Parse Byte[] According to Spec + //data could have a Preample of 0 - 7 bytes, search for Preample seperator + int dataIndex = Array.IndexOf(data, (byte)0xAA); + if (dataIndex == -1) //No Preamble seperator found, corrupt + throw new Exception("No Preamble seperator found, corrupt"); + if (data.Length - dataIndex < 17) //Data Missing, corrupt + throw new Exception("Data Missing, corrupt"); + if (dataIndex >= 8) //Data Missing, corrupt + throw new Exception("Data Missing, corrupt"); - preambleCount = (byte)dataIndex; + preambleCount = (byte)dataIndex; - //Calc Checksum - DeserializedChecksum1 = (ushort)(((data[dataIndex + 13] & data[dataIndex + 14]) << 8) | - (data[dataIndex + 15] & data[dataIndex + 16])); + //Calc Checksum + DeserializedChecksum1 = (ushort)(((data[dataIndex + 13] & data[dataIndex + 14]) << 8) | + (data[dataIndex + 15] & data[dataIndex + 16])); - DeserializedChecksum2 = (ushort)data.Skip(dataIndex + 1).Take(12).Sum(c => (int)c); + DeserializedChecksum2 = (ushort)data.Skip(dataIndex + 1).Take(12).Sum(c => (int)c); - ushort manId = (ushort)(((data[dataIndex + 1] & data[dataIndex + 2]) << 8) | - (data[dataIndex + 3] & data[dataIndex + 4])); + ushort manId = (ushort)(((data[dataIndex + 1] & data[dataIndex + 2]) << 8) | + (data[dataIndex + 3] & data[dataIndex + 4])); - uint devId = (uint)(((data[dataIndex + 5] & data[dataIndex + 6]) << 24) | - ((data[dataIndex + 7] & data[dataIndex + 8]) << 16) | - ((data[dataIndex + 9] & data[dataIndex + 10]) << 8) | - (data[dataIndex + 11] & data[dataIndex + 12])); + uint devId = (uint)(((data[dataIndex + 5] & data[dataIndex + 6]) << 24) | + ((data[dataIndex + 7] & data[dataIndex + 8]) << 16) | + ((data[dataIndex + 9] & data[dataIndex + 10]) << 8) | + (data[dataIndex + 11] & data[dataIndex + 12])); - SourceUID = new UID(manId, devId); - return; - } - else - throw new IndexOutOfRangeException($"{nameof(data)} Length is {data.Length} but has to be at least 26"); - } + SourceUID = new UID(manId, devId); + return; + } + else + throw new IndexOutOfRangeException($"{nameof(data)} Length is {data.Length} but has to be at least 26"); + } - //Check startcode and sub-startcode - if (data[0] != 0xCC || data[1] != 0x01) - throw new Exception("Start-Code invalid"); + //Check startcode and sub-startcode + if (data[0] != 0xCC || data[1] != 0x01) + throw new Exception("Start-Code invalid"); - byte length = data[2]; + byte length = data[2]; - if (data.Length < length + 2) - throw new Exception("DataLength not fit Length in Header"); + if (data.Length < length + 2) + throw new Exception("DataLength not fit Length in Header"); - //Calc Checksum - DeserializedChecksum1 = (ushort)((data[length] << 8) | data[length + 1]); - DeserializedChecksum2 = (ushort)data.Take(length).Sum(c => (int)c); + //Calc Checksum + DeserializedChecksum1 = (ushort)((data[length] << 8) | data[length + 1]); + DeserializedChecksum2 = (ushort)data.Take(length).Sum(c => (int)c); - ushort manIdDest = (ushort)((data[3] << 8) | data[4]); - uint devIdDest = (uint)((data[5] << 24) | (data[6] << 16) | (data[7] << 8) | data[8]); - ushort manIdSource = (ushort)((data[9] << 8) | data[10]); - uint devIdSource = (uint)((data[11] << 24) | (data[12] << 16) | (data[13] << 8) | data[14]); + ushort manIdDest = (ushort)((data[3] << 8) | data[4]); + uint devIdDest = (uint)((data[5] << 24) | (data[6] << 16) | (data[7] << 8) | data[8]); + ushort manIdSource = (ushort)((data[9] << 8) | data[10]); + uint devIdSource = (uint)((data[11] << 24) | (data[12] << 16) | (data[13] << 8) | data[14]); - byte paramLength = data[23]; + byte paramLength = data[23]; - SourceUID = new UID(manIdSource, devIdSource); - DestUID = new UID(manIdDest, devIdDest); - TransactionCounter = data[15]; - PortID_or_Responsetype = data[16]; - MessageCounter = data[17]; - SubDevice = new SubDevice((ushort)((data[18] << 8) | data[19])); - Command = (ERDM_Command)data[20]; - Parameter = (ERDM_Parameter)((data[21] << 8) | data[22]); - ParameterData = data.Skip(24).Take(paramLength).ToArray(); + SourceUID = new UID(manIdSource, devIdSource); + DestUID = new UID(manIdDest, devIdDest); + TransactionCounter = data[15]; + var portIDorResponseType = data[16]; + PortID_or_Responsetype = portIDorResponseType; + ControllerFlags_or_MessageCounter = data[17]; + SubDevice = new SubDevice((ushort)((data[18] << 8) | data[19])); + Command = (ERDM_Command)data[20]; + PortID_or_Responsetype = portIDorResponseType;// Set again in case it was changed in Command-Setter + if (Command.HasFlag(ERDM_Command.RESPONSE) && PortID_or_Responsetype != 0 && paramLength != 2) + { + switch (PortID_or_Responsetype) + { + case 0x03: + if (MessageCounter == 0) + { + Logger?.LogWarning("There is something wrong in this Message, ResponseType is not matching PDL"); + PortID_or_Responsetype = 0; + } + break; + case 0x01: + case 0x02: + case 0x04: + default: + Logger?.LogWarning("There is something wrong in this Message, ResponseType is not matching PDL"); + PortID_or_Responsetype = 0; + break; + } } - public RDMMessage(params ERDM_NackReason[] nackReasons) - { - if (nackReasons == null) - return; - if (nackReasons.Length == 0) - return; - - nackReason = nackReasons; - PortID_or_Responsetype = (byte)ERDM_ResponseType.NACK_REASON; - } + Parameter = (ERDM_Parameter)((data[21] << 8) | data[22]); + ParameterData = data.Skip(24).Take(paramLength).ToArray(); + } + public RDMMessage(ERDM_NackReason nackReason) + { + _nackReason = nackReason; + PortID_or_Responsetype = (byte)ERDM_ResponseType.NACK_REASON; + } + public RDMMessage(AcknowledgeTimer acknowledgeTimer) + { + _acknowledgeTimer = acknowledgeTimer; + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK_TIMER; + } + public RDMMessage(AcknowledgeTimerHighRes acknowledgeTimerHighRes) + { + _acknowledgeTimer = acknowledgeTimerHighRes; + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK_TIMER_HI_RES; + } - public byte MessageLength + public byte MessageLength + { + get { - get - { - byte b = 24; //The 1st 24 bytes are always the same - b += PDL; - return b; - } + byte b = 24; //The 1st 24 bytes are always the same + b += PDL; + return b; } + } - public UID SourceUID { get; set; } + public UID SourceUID { get; set; } - public UID DestUID { get; set; } + public UID DestUID { get; set; } - public byte TransactionCounter { get; set; } + public byte TransactionCounter { get; set; } - private byte portID_or_Responsetype; - public byte PortID_or_Responsetype + private byte portID_or_Responsetype = 1; + public byte PortID_or_Responsetype + { + get + { + return portID_or_Responsetype; + } + set { - get - { - return portID_or_Responsetype; - } - set - { - if (value == portID_or_Responsetype) - return; + if (value == portID_or_Responsetype) + return; - valueCache = null; + valueCache = null; - portID_or_Responsetype = value; - } - } - - public byte MessageCounter { get; set; } - public byte? PreambleCount + portID_or_Responsetype = value; + } + } + + public byte? MessageCounter + { + get + { + if (this.Command.HasFlag(ERDM_Command.RESPONSE)) + return ControllerFlags_or_MessageCounter; + return null; + } + } + public ERDM_ControllerFlags? ControllerFlags + { + get + { + if (!this.Command.HasFlag(ERDM_Command.RESPONSE)) + return (ERDM_ControllerFlags)ControllerFlags_or_MessageCounter; + return null; + } + } + public byte ControllerFlags_or_MessageCounter { get; set; } + public byte? PreambleCount + { + get { - get - { - if (this.Command != ERDM_Command.DISCOVERY_COMMAND_RESPONSE) - return null; + if (this.Command != ERDM_Command.DISCOVERY_COMMAND_RESPONSE) + return null; - if (this.Parameter != ERDM_Parameter.DISC_UNIQUE_BRANCH) - return null; + if (this.Parameter != ERDM_Parameter.DISC_UNIQUE_BRANCH) + return null; - return preambleCount; - } - set - { - if (this.Command != ERDM_Command.DISCOVERY_COMMAND_RESPONSE) - return; + return preambleCount; + } + set + { + if (this.Command != ERDM_Command.DISCOVERY_COMMAND_RESPONSE) + return; - if (this.Parameter != ERDM_Parameter.DISC_UNIQUE_BRANCH) - return; + if (this.Parameter != ERDM_Parameter.DISC_UNIQUE_BRANCH) + return; - if (preambleCount == value) - return; + if (preambleCount == value) + return; - preambleCount = value; - } - } + preambleCount = value; + } + } - public SubDevice SubDevice { get; set; } + public SubDevice SubDevice { get; set; } - private ERDM_Command command; - public ERDM_Command Command + private ERDM_Command command; + public ERDM_Command Command + { + get { - get - { - return command; - } - set - { - if (value == command) - return; - valueCache = null; - command = value; - } + return command; } + set + { + if (value == command) + return; + + if (value.HasFlag(ERDM_Command.RESPONSE) && command == ERDM_Command.NONE && PortID_or_Responsetype == 1 && _acknowledgeTimer is null) + PortID_or_Responsetype = 0; // Set To ACK, bacause default as Request is 1 and 1 as Response is Timer... Bad! + valueCache = null; + command = value; + } + } - private ERDM_Parameter parameter; - public ERDM_Parameter Parameter + private ERDM_Parameter parameter; + public ERDM_Parameter Parameter + { + get { - get - { - return parameter; - } - set - { - if (value == parameter) - return; - valueCache = null; - parameter = value; - } + return parameter; + } + set + { + if (value == parameter) + return; + valueCache = null; + parameter = value; } + } - private ERDM_NackReason[] nackReason = null; + private ERDM_NackReason? _nackReason = null; - public ERDM_NackReason[] NackReason + public ERDM_NackReason? NackReason + { + get { - get - { - if (ResponseType != ERDM_ResponseType.NACK_REASON) - return null; + if (ResponseType != ERDM_ResponseType.NACK_REASON) + return null; - if (nackReason != null) - return nackReason; + if (_nackReason != null) + return _nackReason; + byte[] data = _parameterData.ToArray(); - List reasons = new List(); - while (_parameterData.Length > 1) - { - var res = Tools.DataToEnum(ref _parameterData); - reasons.Add(res); - } - nackReason = reasons.ToArray(); - return nackReason; - } + _nackReason = Tools.DataToEnum(ref data); + return _nackReason; } + } + private IAcknowledgeTimer? _acknowledgeTimer = null; - public byte PDL + public IAcknowledgeTimer? AcknowledgeTimer + { + get { - get { return (byte)ParameterData.Length; } + if (ResponseType != ERDM_ResponseType.ACK_TIMER && ResponseType != ERDM_ResponseType.ACK_TIMER_HI_RES) + return null; + + if (_acknowledgeTimer != null) + return _acknowledgeTimer; + + byte[] data = _parameterData.ToArray(); + try + { + switch (ResponseType) + { + case ERDM_ResponseType.ACK_TIMER: + _acknowledgeTimer = _AcknowledgeTimer.FromPayloadData(data); + break; + case ERDM_ResponseType.ACK_TIMER_HI_RES: + _acknowledgeTimer = AcknowledgeTimerHighRes.FromPayloadData(data); + break; + } + } + catch (Exception e) + { + Logger?.LogWarning(e); + } + return _acknowledgeTimer; } + } - public byte[] ParameterData - { - get { return _parameterData; } - set - { - if (_parameterData == value) - return; - - valueCache = null; - - if (value == null) - _parameterData = Array.Empty(); - else - { - if (value.Length > 255 - 24) throw new ArgumentException("ParameterData to large!"); - _parameterData = value; - } + public byte PDL + { + get + { + switch (ResponseType) + { + case ERDM_ResponseType.NACK_REASON: + case ERDM_ResponseType.ACK_TIMER: + case ERDM_ResponseType.ACK_TIMER_HI_RES: + return 2; } + return (byte)ParameterData.Length; } + } - public ushort Checksum + public byte[] ParameterData + { + get { - get + switch (this.ResponseType) { - int sum = 0xCC + 0x01; //Start Code and Sub Start Code - sum += MessageLength; - - sum += SourceUID.ToBytes().Sum(c => (int)c); - sum += DestUID.ToBytes().Sum(c => (int)c); - - sum += TransactionCounter; - sum += PortID_or_Responsetype; - sum += MessageCounter; - sum += ((ushort)SubDevice) & 0xFF; - sum += (((ushort)SubDevice) >> 8) & 0xFF; - sum += (byte)Command; - ushort para = (ushort)Parameter; - sum += para & 0xFF; - sum += (para >> 8) & 0xFF; - sum += PDL; - foreach (byte b in ParameterData) - sum += b; - - return (ushort)(sum % 0x10000); + case ERDM_ResponseType.NACK_REASON: + return Tools.ValueToData(_nackReason); + case ERDM_ResponseType.ACK_TIMER: + case ERDM_ResponseType.ACK_TIMER_HI_RES: + return Tools.ValueToData(_acknowledgeTimer); } - } - public ushort? DeserializedChecksum1 - { - get; - private set; - } - public ushort? DeserializedChecksum2 - { - get; - private set; + return _parameterData; } - public bool ChecksumValid - { - get + set + { + if (_parameterData == value) + return; + + valueCache = null; + + if (value == null) + _parameterData = Array.Empty(); + else { - return DeserializedChecksum1 == DeserializedChecksum2; - } + if (value.Length > 255 - 24) throw new ArgumentException("ParameterData to large!"); + _parameterData = value; + } } + } - public ERDM_ResponseType? ResponseType + public ushort Checksum + { + get { - get - { - if (this.Command.HasFlag(ERDM_Command.RESPONSE)) - return (ERDM_ResponseType)PortID_or_Responsetype; - return null; - } + int sum = 0xCC + 0x01; //Start Code and Sub Start Code + sum += MessageLength; + + sum += SourceUID.ToBytes().Sum(c => (int)c); + sum += DestUID.ToBytes().Sum(c => (int)c); + + sum += TransactionCounter; + sum += PortID_or_Responsetype; + sum += ControllerFlags_or_MessageCounter; + sum += ((ushort)SubDevice) & 0xFF; + sum += (((ushort)SubDevice) >> 8) & 0xFF; + sum += (byte)Command; + ushort para = (ushort)Parameter; + sum += para & 0xFF; + sum += (para >> 8) & 0xFF; + sum += PDL; + foreach (byte b in ParameterData) + sum += b; + + return (ushort)(sum % 0x10000); + } + } + public ushort? DeserializedChecksum1 + { + get; + private set; + } + public ushort? DeserializedChecksum2 + { + get; + private set; + } + public bool ChecksumValid + { + get + { + return DeserializedChecksum1 == DeserializedChecksum2; } - public byte? PortID + } + + public ERDM_ResponseType? ResponseType + { + get { - get - { - if (!this.Command.HasFlag(ERDM_Command.RESPONSE)) - return PortID_or_Responsetype; - return null; - } + if (this.Command.HasFlag(ERDM_Command.RESPONSE)) + return (ERDM_ResponseType)PortID_or_Responsetype; + return null; + } + } + public byte? PortID + { + get + { + if (!this.Command.HasFlag(ERDM_Command.RESPONSE)) + return PortID_or_Responsetype; + return null; } + } - public bool IsAck + public bool IsAck + { + get { - get - { - if (!ResponseType.HasValue) - return false; - - ERDM_ResponseType resp = ResponseType.Value; - return - resp == ERDM_ResponseType.ACK || - resp == ERDM_ResponseType.ACK_OVERFLOW || - resp == ERDM_ResponseType.ACK_TIMER || - resp == ERDM_ResponseType.ACK_TIMER_HI_RES; - } + if (!ResponseType.HasValue) + return false; + + ERDM_ResponseType resp = ResponseType.Value; + return + resp == ERDM_ResponseType.ACK || + resp == ERDM_ResponseType.ACK_OVERFLOW || + resp == ERDM_ResponseType.ACK_TIMER || + resp == ERDM_ResponseType.ACK_TIMER_HI_RES; } + } - public byte[] BuildMessage() + public byte[] BuildMessage() + { + List ret = null; + switch (Command) { - List ret = null; - switch (Command) - { - case ERDM_Command.DISCOVERY_COMMAND_RESPONSE when Parameter == ERDM_Parameter.DISC_UNIQUE_BRANCH: - - byte preamble = preambleCount ?? 7; - if (preamble > 7) throw new ArgumentOutOfRangeException("preambleCount has to be within 0 and 7"); - ret = new List(preamble + 17); - for (int i = 0; i < preamble; i++) - ret.Add(0xFE); - ret.Add(0xAA); - var uidBytes = ((byte[])SourceUID); - for (int b = 0; b < uidBytes.Length; b++) - { - ret.Add((byte)(uidBytes[b] | 0xAA)); - ret.Add((byte)(uidBytes[b] | 0x55)); - } - ushort cs = (ushort)ret.Skip(preamble + 1).Take(12).Sum(c => c); - ret.Add((byte)((cs >> 8) | 0xAA)); - ret.Add((byte)((cs >> 8) | 0x55)); - ret.Add((byte)((cs & 0xFF) | 0xAA)); - ret.Add((byte)((cs & 0xFF) | 0x55)); - return ret.ToArray(); - default: - ret = new List(MessageLength + 2) - { - 0xcc, 0x01, MessageLength - }; - ret.AddRange(DestUID.ToBytes()); - ret.AddRange(SourceUID.ToBytes()); - ret.Add(TransactionCounter); - ret.Add(PortID_or_Responsetype); - ret.Add(MessageCounter); - ret.Add((byte)(((ushort)SubDevice) >> 8)); - ret.Add((byte)SubDevice); - ret.Add((byte)Command); - - ushort para = (ushort)Parameter; - ret.Add((byte)(para >> 8)); - ret.Add((byte)para); - ret.Add(PDL); - ret.AddRange(ParameterData); - - ret.Add((byte)(Checksum >> 8)); - ret.Add((byte)Checksum); - - return ret.ToArray(); - } + case ERDM_Command.DISCOVERY_COMMAND_RESPONSE when Parameter == ERDM_Parameter.DISC_UNIQUE_BRANCH: + + byte preamble = preambleCount ?? 7; + if (preamble > 7) throw new ArgumentOutOfRangeException("preambleCount has to be within 0 and 7"); + ret = new List(preamble + 17); + for (int i = 0; i < preamble; i++) + ret.Add(0xFE); + ret.Add(0xAA); + var uidBytes = ((byte[])SourceUID); + for (int b = 0; b < uidBytes.Length; b++) + { + ret.Add((byte)(uidBytes[b] | 0xAA)); + ret.Add((byte)(uidBytes[b] | 0x55)); + } + ushort cs = (ushort)ret.Skip(preamble + 1).Take(12).Sum(c => c); + ret.Add((byte)((cs >> 8) | 0xAA)); + ret.Add((byte)((cs >> 8) | 0x55)); + ret.Add((byte)((cs & 0xFF) | 0xAA)); + ret.Add((byte)((cs & 0xFF) | 0x55)); + return ret.ToArray(); + default: + ret = new List(MessageLength + 2) + { + 0xcc, 0x01, MessageLength + }; + ret.AddRange(DestUID.ToBytes()); + ret.AddRange(SourceUID.ToBytes()); + ret.Add(TransactionCounter); + ret.Add(PortID_or_Responsetype); + ret.Add(ControllerFlags_or_MessageCounter); + ret.Add((byte)(((ushort)SubDevice) >> 8)); + ret.Add((byte)SubDevice); + ret.Add((byte)Command); + + ushort para = (ushort)Parameter; + ret.Add((byte)(para >> 8)); + ret.Add((byte)para); + ret.Add(PDL); + ret.AddRange(ParameterData); + + ret.Add((byte)(Checksum >> 8)); + ret.Add((byte)Checksum); + + return ret.ToArray(); } + } - private object valueCache = null; - [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2200:Erneut ausführen, um Stapeldetails beizubehalten", Justification = "")] - public object Value + private object valueCache = null; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2200:Erneut ausführen, um Stapeldetails beizubehalten", Justification = "")] + public object Value + { + get { - get + try { - try + switch (this.ResponseType) { - if (this.ResponseType == ERDM_ResponseType.ACK_TIMER) - return valueCache = AcknowledgeTimer.FromPayloadData(this.ParameterData); - if (this.ResponseType == ERDM_ResponseType.ACK_TIMER_HI_RES) - return valueCache = AcknowledgeTimerHighRes.FromPayloadData(this.ParameterData); - if (this.Parameter == ERDM_Parameter.DISC_UNIQUE_BRANCH && this.Command == ERDM_Command.DISCOVERY_COMMAND) - return valueCache = DiscUniqueBranchRequest.FromPayloadData(this.ParameterData); - if (this.Parameter == ERDM_Parameter.DISC_MUTE && this.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE) - return valueCache = DiscMuteUnmuteResponse.FromPayloadData(this.ParameterData); - if (this.Parameter == ERDM_Parameter.DISC_UN_MUTE && this.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE) - return valueCache = DiscMuteUnmuteResponse.FromPayloadData(this.ParameterData); - - if (this.ParameterData?.Length == 0) - return valueCache = null; - - ushort manufacturer = 0; - if (this.Command.HasFlag(ERDM_Command.RESPONSE)) - manufacturer = SourceUID.ManufacturerID; - else - manufacturer = DestUID.ManufacturerID; - - var parameterBag = new ParameterBag(this.Parameter, manufacturer); - var define = MetadataFactory.GetDefine(parameterBag); - var cd = Tools.ConvertCommandDublicateToCommand(Command); - Metadata.JSON.Command? cmd = null; - if ((this.ParameterData?.Length ?? 0) == 0) + case ERDM_ResponseType.NACK_REASON: + case ERDM_ResponseType.ACK_TIMER: + case ERDM_ResponseType.ACK_TIMER_HI_RES: return null; + } + if (this.Parameter == ERDM_Parameter.DISC_UNIQUE_BRANCH && this.Command == ERDM_Command.DISCOVERY_COMMAND) + return valueCache = DiscUniqueBranchRequest.FromPayloadData(this.ParameterData); + if (this.Parameter == ERDM_Parameter.DISC_MUTE && this.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE) + return valueCache = DiscMuteUnmuteResponse.FromPayloadData(this.ParameterData); + if (this.Parameter == ERDM_Parameter.DISC_UN_MUTE && this.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE) + return valueCache = DiscMuteUnmuteResponse.FromPayloadData(this.ParameterData); - if (define is null) - return null; + if (this.ParameterData?.Length == 0) + return valueCache = null; - try - { - define.GetCommand(cd, out cmd); - if (cmd is null || !cmd.HasValue) - return null; - if(cmd.Value.GetIsEmpty()) - return null; - return valueCache = MetadataFactory.ParseDataToPayload(define, cd, this.ParameterData).ParsedObject; - } - catch (Exception ex) - { - StringBuilder b = new StringBuilder(128); - b.AppendLine("Dest: " + DestUID); - b.AppendLine("Source: " + SourceUID); - b.AppendLine("Transaction: " + TransactionCounter); - b.AppendLine("MessageCounter: " + MessageCounter); - if (ResponseType.HasValue) - b.AppendLine("Responsetype: " + ResponseType); - if (PortID.HasValue) - b.AppendLine("PortID: " + PortID); - b.AppendLine("SubDevice: " + SubDevice); - b.AppendLine("Command: " + Command); - b.AppendLine("Parameter: " + ((ERDM_Parameter)Parameter).ToString()); - Logger?.LogError(ex,$"Message: {b.ToString()}"); - throw ex; - } + ushort manufacturer = 0; + if (this.Command.HasFlag(ERDM_Command.RESPONSE)) + manufacturer = SourceUID.ManufacturerID; + else + manufacturer = DestUID.ManufacturerID; + + var parameterBag = new ParameterBag(this.Parameter, manufacturer); + var define = MetadataFactory.GetDefine(parameterBag); + var cd = Tools.ConvertCommandDublicateToCommand(Command); + Metadata.JSON.Command? cmd = null; + if ((this.ParameterData?.Length ?? 0) == 0) + return null; + + if (define is null) + return null; + + try + { + define.GetCommand(cd, out cmd); + if (cmd is null || !cmd.HasValue) + return null; + if (cmd.Value.GetIsEmpty()) + return null; + return valueCache = MetadataFactory.ParseDataToPayload(define, cd, this.ParameterData).ParsedObject; } catch (Exception ex) { - Logger?.LogError(ex); + StringBuilder b = new StringBuilder(128); + b.AppendLine("Dest: " + DestUID); + b.AppendLine("Source: " + SourceUID); + b.AppendLine("Transaction: " + TransactionCounter); + b.AppendLine("MessageCounter: " + MessageCounter); + if (ResponseType.HasValue) + b.AppendLine("Responsetype: " + ResponseType); + if (PortID.HasValue) + b.AppendLine("PortID: " + PortID); + b.AppendLine("SubDevice: " + SubDevice); + b.AppendLine("Command: " + Command); + b.AppendLine("Parameter: " + ((ERDM_Parameter)Parameter).ToString()); + Logger?.LogError(ex, $"Message: {b.ToString()}"); throw ex; } } - } + catch (Exception ex) + { + Logger?.LogError(ex); + throw ex; + } + } + } - public override string ToString() - { - StringBuilder b = new StringBuilder(128); - b.AppendLine("Dest: " + DestUID); - b.AppendLine("Source: " + SourceUID); - b.AppendLine("Transaction: " + TransactionCounter); - b.AppendLine("MessageCounter: " + MessageCounter); - if (ResponseType.HasValue) - b.AppendLine("Responsetype: " + ResponseType); - if (PortID.HasValue) - b.AppendLine("PortID: " + PortID); - b.AppendLine("SubDevice: " + SubDevice); - b.AppendLine("Command: " + Command); - b.AppendLine("Parameter: " + ((ERDM_Parameter)Parameter).ToString()); - if ( - Command == ERDM_Command.GET_COMMAND_RESPONSE || - Command == ERDM_Command.SET_COMMAND || - Command == ERDM_Command.SET_COMMAND_RESPONSE || - Command.HasFlag(ERDM_Command.DISCOVERY_COMMAND)) + public override string ToString() + { + StringBuilder b = new StringBuilder(128); + b.AppendLine("Dest: " + DestUID); + b.AppendLine("Source: " + SourceUID); + b.AppendLine("Transaction: " + TransactionCounter); + b.AppendLine("MessageCounter: " + MessageCounter); + if (ResponseType.HasValue) + b.AppendLine("Responsetype: " + ResponseType); + if (PortID.HasValue) + b.AppendLine("PortID: " + PortID); + b.AppendLine("SubDevice: " + SubDevice); + b.AppendLine("Command: " + Command); + b.AppendLine("Parameter: " + ((ERDM_Parameter)Parameter).ToString()); + if ( + Command == ERDM_Command.GET_COMMAND_RESPONSE || + Command == ERDM_Command.SET_COMMAND || + Command == ERDM_Command.SET_COMMAND_RESPONSE || + Command.HasFlag(ERDM_Command.DISCOVERY_COMMAND)) + { + object val = null; + try + { + val = this.Value; + } + catch { - object val = null; - try - { - val = this.Value; - } - catch - { - } - if (val != null) - b.AppendLine("Value: " + valueString()); + } + if (val != null) + b.AppendLine("Value: " + valueString()); - string valueString() + string valueString() + { + string value; + if (val is Array array) { - string value; - if (val is Array array) - { - List list = new List(); - foreach (var a in array) - list.Add(a.ToString()); - value = string.Join("," + Environment.NewLine, list); - } - else if (val is string str) - value = $"\"{str}\""; - else - value = Value?.ToString() ?? "[NULL]"; - if (value.Contains(Environment.NewLine) && !value.StartsWith(Environment.NewLine)) - { - value = Environment.NewLine + value; - value = value.Replace(Environment.NewLine, Environment.NewLine + "\t"); - } - return value; + List list = new List(); + foreach (var a in array) + list.Add(a.ToString()); + value = string.Join("," + Environment.NewLine, list); } - } - //Add More if required + else if (val is string str) + value = $"\"{str}\""; + else + value = Value?.ToString() ?? "[NULL]"; + if (value.Contains(Environment.NewLine) && !value.StartsWith(Environment.NewLine)) + { + value = Environment.NewLine + value; + value = value.Replace(Environment.NewLine, Environment.NewLine + "\t"); + } + return value; + } + } + //Add More if required - return b.ToString(); - } + return b.ToString(); + } - public override bool Equals(object obj) - { - return Equals(obj as RDMMessage); - } + public override bool Equals(object obj) + { + return Equals(obj as RDMMessage); + } - public bool Equals(RDMMessage other) - { - bool res = other is not null && - MessageLength == other.MessageLength && - SourceUID.Equals(other.SourceUID) && - DestUID.Equals(other.DestUID) && - TransactionCounter == other.TransactionCounter && - PortID_or_Responsetype == other.PortID_or_Responsetype && - MessageCounter == other.MessageCounter && - SubDevice.Equals(other.SubDevice) && - Command == other.Command && - Parameter == other.Parameter && - EqualityComparer.Default.Equals(NackReason, other.NackReason) && - PDL == other.PDL && - ParameterData.SequenceEqual(other.ParameterData) && - Checksum == other.Checksum && - ChecksumValid == other.ChecksumValid && - ResponseType == other.ResponseType && - IsAck == other.IsAck && - preambleCount == other.preambleCount; - return res; - } - public override int GetHashCode() + public bool Equals(RDMMessage other) + { + bool res = other is not null && + MessageLength == other.MessageLength && + SourceUID.Equals(other.SourceUID) && + DestUID.Equals(other.DestUID) && + TransactionCounter == other.TransactionCounter && + PortID_or_Responsetype == other.PortID_or_Responsetype && + MessageCounter == other.MessageCounter && + SubDevice.Equals(other.SubDevice) && + Command == other.Command && + Parameter == other.Parameter && + NackReason == other.NackReason && + PDL == other.PDL && + ParameterData.SequenceEqual(other.ParameterData) && + Checksum == other.Checksum && + ChecksumValid == other.ChecksumValid && + ResponseType == other.ResponseType && + IsAck == other.IsAck && + preambleCount == other.preambleCount; + return res; + } + public override int GetHashCode() + { + unchecked { - unchecked - { - var bytes = BuildMessage(); - var result = 0; - foreach (byte b in bytes) - result = (result * 31) ^ b; - return result; - } + var bytes = BuildMessage(); + var result = 0; + foreach (byte b in bytes) + result = (result * 31) ^ b; + return result; } - } + } } diff --git a/RDMSharp/RDM/RDMMessageInvalidException.cs b/RDMSharp/RDM/RDMMessageInvalidException.cs index 34ee6223..e2588470 100644 --- a/RDMSharp/RDM/RDMMessageInvalidException.cs +++ b/RDMSharp/RDM/RDMMessageInvalidException.cs @@ -1,44 +1,47 @@ using System; using System.Linq; -namespace RDMSharp +namespace RDMSharp; + +public class RDMMessageInvalidException : Exception { - public class RDMMessageInvalidException : Exception + public readonly RDMMessage RDMMessage; + protected RDMMessageInvalidException(RDMMessage rdmMessage, string message) : base(message) + { + RDMMessage = rdmMessage; + } + internal static void ThrowIfInvalid(RDMMessage msg, ERDM_Command expectedCommand, params ERDM_Parameter[] expectedParameters) { - public readonly RDMMessage RDMMessage; - protected RDMMessageInvalidException(RDMMessage rdmMessage, string message) : base(message) - { - RDMMessage = rdmMessage; - } - internal static void ThrowIfInvalid(RDMMessage msg, ERDM_Command expectedCommand, params ERDM_Parameter[] expectedParameters) - { #if NETSTANDARD - if (msg == null) - throw new ArgumentNullException($"Argument {nameof(msg)} can't be null"); + if (msg == null) + throw new ArgumentNullException($"Argument {nameof(msg)} can't be null"); #else - ArgumentNullException.ThrowIfNull(msg); + ArgumentNullException.ThrowIfNull(msg); #endif - if (expectedCommand.HasFlag(ERDM_Command.RESPONSE) && !msg.IsAck) throw new RDMMessageInvalidException(msg, $"NACK Reason: {(ERDM_NackReason)msg.ParameterData[0]}"); - if (msg.Command != expectedCommand) throw new RDMMessageInvalidException(msg, $"Command is not the expected Command: {expectedCommand}"); - if (expectedParameters.Length != 0 && !expectedParameters.Contains(msg.Parameter)) throw new RDMMessageInvalidException(msg, $"Parameter is not one of the expected Parameters: {string.Join(";", expectedParameters)}"); - } - internal static void ThrowIfInvalidPDL(RDMMessage msg, ERDM_Command expectedCommand, ERDM_Parameter expectedParameter, params int[] expectedPDL) - { - ThrowIfInvalid(msg, expectedCommand, expectedParameter); - if (!expectedPDL.Contains(msg.PDL)) throw new RDMMessageInvalidException(msg, $"PayloadDataLength is fitting the given Values {string.Join(";", expectedPDL)}"); - } - internal static void ThrowIfInvalidPDL(RDMMessage msg, ERDM_Command expectedCommand, ERDM_Parameter[] expectedParameters, params int[] expectedPDL) + if (expectedCommand.HasFlag(ERDM_Command.RESPONSE) && !msg.IsAck) { - ThrowIfInvalid(msg, expectedCommand, expectedParameters); - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(msg, expectedPDL); - RDMMessageInvalidPDLException.ThrowIfInvalidPDL(msg.ParameterData, expectedPDL); - } - internal static void ThrowIfInvalidPDLRange(RDMMessage msg, ERDM_Command expectedCommand, ERDM_Parameter expectedParameter, int expectedMinPDL, int expectedMaxPDL) - { - ThrowIfInvalid(msg, expectedCommand, expectedParameter); - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(msg, expectedMinPDL, expectedMaxPDL); - RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(msg.ParameterData, expectedMinPDL, expectedMaxPDL); + byte[] data = msg.ParameterData.ToArray(); + throw new RDMMessageInvalidException(msg, $"NACK Reason: {Tools.DataToEnum(ref data)}"); } + if (msg.Command != expectedCommand) throw new RDMMessageInvalidException(msg, $"Command is not the expected Command: {expectedCommand}"); + if (expectedParameters.Length != 0 && !expectedParameters.Contains(msg.Parameter)) throw new RDMMessageInvalidException(msg, $"Parameter is not one of the expected Parameters: {string.Join(";", expectedParameters)}"); + } + internal static void ThrowIfInvalidPDL(RDMMessage msg, ERDM_Command expectedCommand, ERDM_Parameter expectedParameter, params int[] expectedPDL) + { + ThrowIfInvalid(msg, expectedCommand, expectedParameter); + if (!expectedPDL.Contains(msg.PDL)) throw new RDMMessageInvalidException(msg, $"PayloadDataLength is fitting the given Values {string.Join(";", expectedPDL)}"); + } + internal static void ThrowIfInvalidPDL(RDMMessage msg, ERDM_Command expectedCommand, ERDM_Parameter[] expectedParameters, params int[] expectedPDL) + { + ThrowIfInvalid(msg, expectedCommand, expectedParameters); + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(msg, expectedPDL); + RDMMessageInvalidPDLException.ThrowIfInvalidPDL(msg.ParameterData, expectedPDL); + } + internal static void ThrowIfInvalidPDLRange(RDMMessage msg, ERDM_Command expectedCommand, ERDM_Parameter expectedParameter, int expectedMinPDL, int expectedMaxPDL) + { + ThrowIfInvalid(msg, expectedCommand, expectedParameter); + RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(msg, expectedMinPDL, expectedMaxPDL); + RDMMessageInvalidPDLException.ThrowIfInvalidPDLRange(msg.ParameterData, expectedMinPDL, expectedMaxPDL); } } \ No newline at end of file diff --git a/RDMSharp/RDM/RequestResponseHistoryEntry.cs b/RDMSharp/RDM/RequestResponseHistoryEntry.cs new file mode 100644 index 00000000..32248370 --- /dev/null +++ b/RDMSharp/RDM/RequestResponseHistoryEntry.cs @@ -0,0 +1,73 @@ +using System; +using System.ComponentModel; + +namespace RDMSharp; + +public class RequestResponseHistoryEntry : INotifyPropertyChanged +{ + public readonly DateTime Timestamp = DateTime.Now; + public readonly RDMMessage Request; + + private DateTime? _timestampRespone; + public DateTime? TimestampResponse + { + get + { + return _timestampRespone; + } + private set + { + if (_timestampRespone == value) + return; + _timestampRespone = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TimestampResponse))); + } + } + + private RDMMessage _response; + public RDMMessage Response + { + get + { + return _response; + } + private set + { + if (_response == value) + return; + _response = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Response))); + } + } + + private string _state; + public string State + { + get + { + return _state; + } + private set + { + if (_state == value) + return; + _state = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(State))); + } + } + + + public event PropertyChangedEventHandler PropertyChanged; + + public RequestResponseHistoryEntry(RDMMessage request) + { + Request = request; + } + + internal void SetResponse(RDMMessage response, string state = "Success") + { + Response = response; + TimestampResponse = DateTime.Now; + State = state; + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/RequestResult.cs b/RDMSharp/RDM/RequestResult.cs index cd40d0dc..0b0ddd4c 100644 --- a/RDMSharp/RDM/RequestResult.cs +++ b/RDMSharp/RDM/RequestResult.cs @@ -1,30 +1,31 @@ using System; -namespace RDMSharp +namespace RDMSharp; + +public readonly struct RequestResult { - public readonly struct RequestResult - { - public readonly RDMMessage Request; - public readonly RDMMessage Response; - public readonly bool Success; - public readonly bool Cancel; - public readonly TimeSpan? ElapsedTime; + public readonly RDMMessage Request; + public readonly RDMMessage Response; + public readonly bool Success; + public readonly bool Timeout; + public readonly bool Disposing; + public readonly TimeSpan? ElapsedTime; - public RequestResult(in RDMMessage request, in bool cancle = false) - { - Request = request; - Response = null; - Success = false; - Cancel = cancle; - ElapsedTime = null; - } + public RequestResult(in RDMMessage request, in bool timeout = false, in bool disposing = false) + { + Request = request; + Response = null; + Success = false; + Timeout = timeout; + Disposing = disposing; + ElapsedTime = null; + } - public RequestResult(in RDMMessage request, in RDMMessage response, TimeSpan elapsedTime) - { - Request = request; - Response = response; - Success = true; - ElapsedTime = elapsedTime; - } + public RequestResult(in RDMMessage request, in RDMMessage response, TimeSpan elapsedTime) + { + Request = request; + Response = response; + Success = true; + ElapsedTime = elapsedTime; } } \ No newline at end of file diff --git a/RDMSharp/RDM/Sensor.cs b/RDMSharp/RDM/Sensor.cs index 4c57bba0..2afca541 100644 --- a/RDMSharp/RDM/Sensor.cs +++ b/RDMSharp/RDM/Sensor.cs @@ -1,446 +1,471 @@ -using System; +using RDMSharp.PayloadObject; +using System; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Text; [assembly: InternalsVisibleTo("RDMSharpTests")] -namespace RDMSharp +namespace RDMSharp; + +public class Sensor : INotifyPropertyChanged, IEquatable { - public class Sensor : INotifyPropertyChanged, IEquatable - { - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler PropertyChanged; + public event EventHandler SensorUpdated; - public readonly byte SensorId; + public readonly byte SensorId; - private ERDM_SensorType type; - public ERDM_SensorType Type + private ERDM_SensorType type; + public ERDM_SensorType Type + { + get { return type; } + private set { - get { return type; } - private set - { - if (type == value) - return; - - type = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Type))); - } - } + if (type == value) + return; - private ERDM_SensorUnit unit; - public ERDM_SensorUnit Unit - { - get { return unit; } - private set - { - if (unit == value) - return; - - unit = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Unit))); - } + type = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Type))); } + } + public readonly RDMSensorTypeCustomDefine CustomType; - private ERDM_UnitPrefix prefix; - public ERDM_UnitPrefix Prefix + private ERDM_SensorUnit unit; + public ERDM_SensorUnit Unit + { + get { return unit; } + private set { - get { return prefix; } - private set - { - if (prefix == value) - return; - - prefix = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Prefix))); - } - } + if (unit == value) + return; - private short rangeMinimum; - public short RangeMinimum - { - get { return rangeMinimum; } - private set - { - if (rangeMinimum == value) - return; - - rangeMinimum = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(RangeMinimum))); - } + unit = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Unit))); } + } + public readonly RDMSensorUnitCustomDefine CustomUnit; - private short rangeMaximum; - public short RangeMaximum + private ERDM_UnitPrefix prefix; + public ERDM_UnitPrefix Prefix + { + get { return prefix; } + private set { - get { return rangeMaximum; } - private set - { - if (rangeMaximum == value) - return; - - rangeMaximum = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(RangeMaximum))); - } - } + if (prefix == value) + return; - private short normalMinimum; - public short NormalMinimum - { - get { return normalMinimum; } - private set - { - if (normalMinimum == value) - return; - - normalMinimum = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(NormalMinimum))); - } + prefix = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Prefix))); } + } - private short normalMaximum; - public short NormalMaximum + private short rangeMinimum; + public short RangeMinimum + { + get { return rangeMinimum; } + private set { - get { return normalMaximum; } - private set - { - if (normalMaximum == value) - return; - - normalMaximum = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(NormalMaximum))); - } - } + if (rangeMinimum == value) + return; - private bool lowestHighestValueSupported; - public bool LowestHighestValueSupported - { - get { return lowestHighestValueSupported; } - private set - { - if (lowestHighestValueSupported == value) - return; - - lowestHighestValueSupported = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(LowestHighestValueSupported))); - } + rangeMinimum = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(RangeMinimum))); } + } - private bool recordedValueSupported; - public bool RecordedValueSupported + private short rangeMaximum; + public short RangeMaximum + { + get { return rangeMaximum; } + private set { - get { return recordedValueSupported; } - private set - { - if (recordedValueSupported == value) - return; - - recordedValueSupported = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(RecordedValueSupported))); - } - } + if (rangeMaximum == value) + return; - private string description; - public string Description - { - get { return description; } - private set - { - if (description == value) - return; - - description = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Description))); - } + rangeMaximum = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(RangeMaximum))); } + } - private short presentValue; - public short PresentValue - { - get { return presentValue; } - private set - { - if (presentValue == value) - return; - - presentValue = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(PresentValue))); - } - } - private short lowestValue; - public short LowestValue - { - get { return lowestValue; } - private set - { - if (lowestValue == value) - return; - - lowestValue = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(LowestValue))); - } - } - private short highestValue; - public short HighestValue + private short normalMinimum; + public short NormalMinimum + { + get { return normalMinimum; } + private set { - get { return highestValue; } - private set - { - if (highestValue == value) - return; - - highestValue = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(HighestValue))); - } + if (normalMinimum == value) + return; + + normalMinimum = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(NormalMinimum))); } - private short recordedValue; - public short RecordedValue + } + + private short normalMaximum; + public short NormalMaximum + { + get { return normalMaximum; } + private set { - get { return recordedValue; } - private set - { - if (recordedValue == value) - return; - - recordedValue = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(RecordedValue))); - } + if (normalMaximum == value) + return; + + normalMaximum = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(NormalMaximum))); } - public Sensor(in byte sensorId) + } + + private bool lowestHighestValueSupported; + public bool LowestHighestValueSupported + { + get { return lowestHighestValueSupported; } + private set { - this.SensorId = sensorId; + if (lowestHighestValueSupported == value) + return; + + lowestHighestValueSupported = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(LowestHighestValueSupported))); } - internal protected Sensor(in byte sensorId, - in ERDM_SensorType type, - in ERDM_SensorUnit unit, - in ERDM_UnitPrefix prefix, - in string description, - in short rangeMinimum, - in short rangeMaximum, - in short normalMinimum, - in short normalMaximum, - in bool lowestHighestValueSupported = false, - in bool recordedValueSupported = false) : this(sensorId) + } + + private bool recordedValueSupported; + public bool RecordedValueSupported + { + get { return recordedValueSupported; } + private set { - if (String.IsNullOrWhiteSpace(description)) - throw new ArgumentNullException(nameof(description)); - - Type = type; - Unit = unit; - Prefix = prefix; - Description = description; - RangeMinimum = rangeMinimum; - RangeMaximum = rangeMaximum; - NormalMinimum = normalMinimum; - NormalMaximum = normalMaximum; - LowestHighestValueSupported = lowestHighestValueSupported; - RecordedValueSupported = recordedValueSupported; + if (recordedValueSupported == value) + return; + + recordedValueSupported = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(RecordedValueSupported))); } - public Sensor(in byte sensorId, - in short initValue, - in ERDM_SensorType type, - in ERDM_SensorUnit unit, - in ERDM_UnitPrefix prefix, - in string description, - in short rangeMinimum, - in short rangeMaximum, - in short normalMinimum, - in short normalMaximum, - in bool lowestHighestValueSupported = false, - in bool recordedValueSupported = false) : this( - sensorId, - type, - unit, - prefix, - description, - rangeMinimum, - rangeMaximum, - normalMinimum, - normalMaximum, - lowestHighestValueSupported, - recordedValueSupported) + } + + private string description; + public string Description + { + get { return description; } + private set { - this.UpdateValue(initValue); - if (LowestHighestValueSupported) - { - LowestValue = initValue; - HighestValue = initValue; - } + if (description == value) + return; + + description = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Description))); } - internal void UpdateDescription(RDMSensorDefinition sensorDescription) + } + + private short presentValue; + public short PresentValue + { + get { return presentValue; } + private set { - if (this.SensorId != sensorDescription.SensorId) - throw new InvalidOperationException($"The given {nameof(sensorDescription)} has not the expected id of {this.SensorId} but {sensorDescription.SensorId}"); - - this.Description = sensorDescription.Description; - this.Type = sensorDescription.Type; - this.Unit = sensorDescription.Unit; - this.Prefix = sensorDescription.Prefix; - this.RangeMinimum = sensorDescription.RangeMinimum; - this.RangeMaximum = sensorDescription.RangeMaximum; - this.NormalMinimum = sensorDescription.NormalMinimum; - this.NormalMaximum = sensorDescription.NormalMaximum; - this.LowestHighestValueSupported = sensorDescription.LowestHighestValueSupported; - this.RecordedValueSupported = sensorDescription.RecordedValueSupported; + if (presentValue == value) + return; + + presentValue = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(PresentValue))); } - internal void UpdateValue(RDMSensorValue sensorValue) + } + private short lowestValue; + public short LowestValue + { + get { return lowestValue; } + private set { - if (this.SensorId != sensorValue.SensorId) - throw new InvalidOperationException($"The given {nameof(sensorValue)} has not the expected id of {this.SensorId} but {sensorValue.SensorId}"); + if (lowestValue == value) + return; - this.PresentValue = sensorValue.PresentValue; - this.LowestValue = sensorValue.LowestValue; - this.HighestValue = sensorValue.HighestValue; - this.RecordedValue = sensorValue.RecordedValue; + lowestValue = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(LowestValue))); } - - protected virtual void UpdateValue(short value) + } + private short highestValue; + public short HighestValue + { + get { return highestValue; } + private set { - PresentValue = value; - if (this.LowestHighestValueSupported) - updateLowestHighestValue(value); + if (highestValue == value) + return; + + highestValue = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(HighestValue))); } - private void updateLowestHighestValue(short value) + } + private short recordedValue; + public short RecordedValue + { + get { return recordedValue; } + private set { - LowestValue = Math.Min(LowestValue, value); - HighestValue = Math.Max(HighestValue, value); + if (recordedValue == value) + return; + + recordedValue = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(RecordedValue))); } - internal void RecordValue() + } + public Sensor(in byte sensorId) + { + this.SensorId = sensorId; + } + internal protected Sensor(in byte sensorId, + in ERDM_SensorType type, + in ERDM_SensorUnit unit, + in ERDM_UnitPrefix prefix, + in string description, + in short rangeMinimum, + in short rangeMaximum, + in short normalMinimum, + in short normalMaximum, + in bool lowestHighestValueSupported = false, + in bool recordedValueSupported = false, + in RDMSensorUnitCustomDefine customUnit = null, + in RDMSensorTypeCustomDefine customType = null) : this(sensorId) + { + if (String.IsNullOrWhiteSpace(description)) + throw new ArgumentNullException(nameof(description)); + + Type = type; + Unit = unit; + Prefix = prefix; + Description = description; + RangeMinimum = rangeMinimum; + RangeMaximum = rangeMaximum; + NormalMinimum = normalMinimum; + NormalMaximum = normalMaximum; + LowestHighestValueSupported = lowestHighestValueSupported; + RecordedValueSupported = recordedValueSupported; + CustomUnit = customUnit; + CustomType = customType; + + if ((byte)Unit >= 0x80 && customUnit is null) + throw new ArgumentException($"The given {nameof(unit)} is a custom unit but no {nameof(customUnit)} is given.", nameof(unit)); + + if ((byte)Type >= 0x80 && customType is null) + throw new ArgumentException($"The given {nameof(type)} is a custom type but no {nameof(customType)} is given.", nameof(type)); + + if (customUnit is not null && customUnit.Id != (byte)Unit) + throw new ArgumentException($"The given {nameof(customUnit)} does not match the given {nameof(unit)}.", nameof(customUnit)); + + if (customType is not null && customType.Id != (byte)Type) + throw new ArgumentException($"The given {nameof(customType)} does not match the given {nameof(type)}.", nameof(customType)); + } + public Sensor(in byte sensorId, + in short initValue, + in ERDM_SensorType type, + in ERDM_SensorUnit unit, + in ERDM_UnitPrefix prefix, + in string description, + in short rangeMinimum, + in short rangeMaximum, + in short normalMinimum, + in short normalMaximum, + in bool lowestHighestValueSupported = false, + in bool recordedValueSupported = false, + in RDMSensorUnitCustomDefine customUnit = null, + in RDMSensorTypeCustomDefine customType = null) : this( + sensorId, + type, + unit, + prefix, + description, + rangeMinimum, + rangeMaximum, + normalMinimum, + normalMaximum, + lowestHighestValueSupported, + recordedValueSupported, + customUnit, + customType) + { + this.UpdateValue(initValue); + if (LowestHighestValueSupported) { - if (this.RecordedValueSupported) - RecordedValue = PresentValue; + LowestValue = initValue; + HighestValue = initValue; } - internal void ResetValues() - { - LowestValue = PresentValue; - HighestValue = PresentValue; + } + internal void UpdateDescription(RDMSensorDefinition sensorDescription) + { + if (this.SensorId != sensorDescription.SensorId) + throw new InvalidOperationException($"The given {nameof(sensorDescription)} has not the expected id of {this.SensorId} but {sensorDescription.SensorId}"); + + this.Description = sensorDescription.Description; + this.Type = sensorDescription.Type; + this.Unit = sensorDescription.Unit; + this.Prefix = sensorDescription.Prefix; + this.RangeMinimum = sensorDescription.RangeMinimum; + this.RangeMaximum = sensorDescription.RangeMaximum; + this.NormalMinimum = sensorDescription.NormalMinimum; + this.NormalMaximum = sensorDescription.NormalMaximum; + this.LowestHighestValueSupported = sensorDescription.LowestHighestValueSupported; + this.RecordedValueSupported = sensorDescription.RecordedValueSupported; + } + internal void UpdateValue(RDMSensorValue sensorValue) + { + if (this.SensorId != sensorValue.SensorId) + throw new InvalidOperationException($"The given {nameof(sensorValue)} has not the expected id of {this.SensorId} but {sensorValue.SensorId}"); + + this.PresentValue = sensorValue.PresentValue; + this.LowestValue = sensorValue.LowestValue; + this.HighestValue = sensorValue.HighestValue; + this.RecordedValue = sensorValue.RecordedValue; + this.SensorUpdated?.InvokeFailSafe(this, EventArgs.Empty); + } + + protected virtual void UpdateValue(short value) + { + PresentValue = value; + if (this.LowestHighestValueSupported) + updateLowestHighestValue(value); + this.SensorUpdated?.InvokeFailSafe(this, EventArgs.Empty); + } + private void updateLowestHighestValue(short value) + { + LowestValue = Math.Min(LowestValue, value); + HighestValue = Math.Max(HighestValue, value); + } + internal void RecordValue() + { + if (this.RecordedValueSupported) RecordedValue = PresentValue; - } + } + internal void ResetValues() + { + LowestValue = PresentValue; + HighestValue = PresentValue; + RecordedValue = PresentValue; + } - public string GetFormatedString() + public string GetFormatedString() + { + StringBuilder sb = new StringBuilder(); + sb.Append(Tools.GetFormatedSensorValue(PresentValue, Prefix, Unit)); + if (LowestHighestValueSupported) { - StringBuilder sb = new StringBuilder(); - sb.Append(Tools.GetFormatedSensorValue(PresentValue, Prefix, Unit)); - if (LowestHighestValueSupported) - { - sb.Append(" "); - sb.Append($"Lowest: {Tools.GetFormatedSensorValue(LowestValue, Prefix, Unit)}"); - sb.Append(" "); - sb.Append($"Highest: {Tools.GetFormatedSensorValue(HighestValue, Prefix, Unit)}"); - } - if (RecordedValueSupported) - { - sb.Append(" "); - sb.Append($"Recorded: {Tools.GetFormatedSensorValue(RecordedValue, Prefix, Unit)}"); - } - - return sb.ToString(); + sb.Append(" "); + sb.Append($"Lowest: {Tools.GetFormatedSensorValue(LowestValue, Prefix, Unit)}"); + sb.Append(" "); + sb.Append($"Highest: {Tools.GetFormatedSensorValue(HighestValue, Prefix, Unit)}"); } - public override string ToString() + if (RecordedValueSupported) { - StringBuilder sb = new StringBuilder(); - sb.AppendLine($"Sensor: {this.SensorId}"); - sb.AppendLine($"Formated: {this.GetFormatedString()}"); - sb.AppendLine($"Type: {this.Type}"); - sb.AppendLine($"Unit: {this.Unit}"); - sb.AppendLine($"Prefix: {this.Prefix}"); - sb.AppendLine($"Description: {this.Description}"); - sb.AppendLine($"RangeMinimum: {this.RangeMinimum}"); - sb.AppendLine($"RangeMaximum: {this.RangeMaximum}"); - sb.AppendLine($"NormalMinimum: {this.NormalMinimum}"); - sb.AppendLine($"NormalMaximum: {this.NormalMaximum}"); - sb.AppendLine($"LowestHighestValueSupported: {this.LowestHighestValueSupported}"); - sb.AppendLine($"RecordedValueSupported: {this.RecordedValueSupported}"); - sb.AppendLine($"PresentValue: {this.PresentValue}"); - if (LowestHighestValueSupported) - { - sb.AppendLine($"LowestValue: {this.LowestValue}"); - sb.AppendLine($"HighestValue: {this.HighestValue}"); - } - if (RecordedValueSupported) - sb.AppendLine($"RecordedValue: {this.RecordedValue}"); - - return sb.ToString(); + sb.Append(" "); + sb.Append($"Recorded: {Tools.GetFormatedSensorValue(RecordedValue, Prefix, Unit)}"); } - public override bool Equals(object obj) + return sb.ToString(); + } + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"Sensor: {this.SensorId}"); + sb.AppendLine($"Formated: {this.GetFormatedString()}"); + sb.AppendLine($"Type: {this.Type}"); + sb.AppendLine($"Unit: {this.Unit}"); + sb.AppendLine($"Prefix: {this.Prefix}"); + sb.AppendLine($"Description: {this.Description}"); + sb.AppendLine($"RangeMinimum: {this.RangeMinimum}"); + sb.AppendLine($"RangeMaximum: {this.RangeMaximum}"); + sb.AppendLine($"NormalMinimum: {this.NormalMinimum}"); + sb.AppendLine($"NormalMaximum: {this.NormalMaximum}"); + sb.AppendLine($"LowestHighestValueSupported: {this.LowestHighestValueSupported}"); + sb.AppendLine($"RecordedValueSupported: {this.RecordedValueSupported}"); + sb.AppendLine($"PresentValue: {this.PresentValue}"); + if (LowestHighestValueSupported) { - return Equals(obj as Sensor); + sb.AppendLine($"LowestValue: {this.LowestValue}"); + sb.AppendLine($"HighestValue: {this.HighestValue}"); } + if (RecordedValueSupported) + sb.AppendLine($"RecordedValue: {this.RecordedValue}"); - public bool Equals(Sensor other) - { - return other is not null && - SensorId == other.SensorId && - Type == other.Type && - Unit == other.Unit && - Prefix == other.Prefix && - RangeMinimum == other.RangeMinimum && - RangeMaximum == other.RangeMaximum && - NormalMinimum == other.NormalMinimum && - NormalMaximum == other.NormalMaximum && - LowestHighestValueSupported == other.LowestHighestValueSupported && - RecordedValueSupported == other.RecordedValueSupported && - Description == other.Description && - PresentValue == other.PresentValue && - LowestValue == other.LowestValue && - HighestValue == other.HighestValue && - RecordedValue == other.RecordedValue; - } + return sb.ToString(); + } - public override int GetHashCode() - { + public override bool Equals(object obj) + { + return Equals(obj as Sensor); + } + + public bool Equals(Sensor other) + { + return other is not null && + SensorId == other.SensorId && + Type == other.Type && + Unit == other.Unit && + Prefix == other.Prefix && + RangeMinimum == other.RangeMinimum && + RangeMaximum == other.RangeMaximum && + NormalMinimum == other.NormalMinimum && + NormalMaximum == other.NormalMaximum && + LowestHighestValueSupported == other.LowestHighestValueSupported && + RecordedValueSupported == other.RecordedValueSupported && + Description == other.Description && + PresentValue == other.PresentValue && + LowestValue == other.LowestValue && + HighestValue == other.HighestValue && + RecordedValue == other.RecordedValue; + } + + public override int GetHashCode() + { #if !NETSTANDARD - HashCode hash = new HashCode(); - hash.Add(SensorId); - hash.Add(Type); - hash.Add(Unit); - hash.Add(Prefix); - hash.Add(RangeMinimum); - hash.Add(RangeMaximum); - hash.Add(NormalMinimum); - hash.Add(NormalMaximum); - hash.Add(LowestHighestValueSupported); - hash.Add(RecordedValueSupported); - hash.Add(Description); - return hash.ToHashCode(); + HashCode hash = new HashCode(); + hash.Add(SensorId); + hash.Add(Type); + hash.Add(Unit); + hash.Add(Prefix); + hash.Add(RangeMinimum); + hash.Add(RangeMaximum); + hash.Add(NormalMinimum); + hash.Add(NormalMaximum); + hash.Add(LowestHighestValueSupported); + hash.Add(RecordedValueSupported); + hash.Add(Description); + return hash.ToHashCode(); #else - int hashCode = 1916557166; - hashCode = hashCode * -1521134295 + SensorId.GetHashCode(); - hashCode = hashCode * -1521134295 + Type.GetHashCode(); - hashCode = hashCode * -1521134295 + Unit.GetHashCode(); - hashCode = hashCode * -1521134295 + Prefix.GetHashCode(); - hashCode = hashCode * -1521134295 + RangeMinimum.GetHashCode(); - hashCode = hashCode * -1521134295 + RangeMaximum.GetHashCode(); - hashCode = hashCode * -1521134295 + NormalMinimum.GetHashCode(); - hashCode = hashCode * -1521134295 + NormalMaximum.GetHashCode(); - hashCode = hashCode * -1521134295 + LowestHighestValueSupported.GetHashCode(); - hashCode = hashCode * -1521134295 + RecordedValueSupported.GetHashCode(); - hashCode = hashCode * -1521134295 + Description.GetHashCode(); - return hashCode; + int hashCode = 1916557166; + hashCode = hashCode * -1521134295 + SensorId.GetHashCode(); + hashCode = hashCode * -1521134295 + Type.GetHashCode(); + hashCode = hashCode * -1521134295 + Unit.GetHashCode(); + hashCode = hashCode * -1521134295 + Prefix.GetHashCode(); + hashCode = hashCode * -1521134295 + RangeMinimum.GetHashCode(); + hashCode = hashCode * -1521134295 + RangeMaximum.GetHashCode(); + hashCode = hashCode * -1521134295 + NormalMinimum.GetHashCode(); + hashCode = hashCode * -1521134295 + NormalMaximum.GetHashCode(); + hashCode = hashCode * -1521134295 + LowestHighestValueSupported.GetHashCode(); + hashCode = hashCode * -1521134295 + RecordedValueSupported.GetHashCode(); + hashCode = hashCode * -1521134295 + Description.GetHashCode(); + return hashCode; #endif - } + } - public static implicit operator RDMSensorDefinition(Sensor _this) - { - return new RDMSensorDefinition(_this.SensorId, - _this.Type, - _this.Unit, - _this.Prefix, - _this.RangeMinimum, - _this.RangeMaximum, - _this.NormalMinimum, - _this.NormalMaximum, - _this.LowestHighestValueSupported, - _this.RecordedValueSupported, - _this.Description); - } - public static implicit operator RDMSensorValue(Sensor _this) - { - return new RDMSensorValue(_this.SensorId, - _this.PresentValue, - _this.LowestValue, - _this.HighestValue, - _this.RecordedValue); - } + public static implicit operator RDMSensorDefinition(Sensor _this) + { + return new RDMSensorDefinition(_this.SensorId, + _this.Type, + _this.Unit, + _this.Prefix, + _this.RangeMinimum, + _this.RangeMaximum, + _this.NormalMinimum, + _this.NormalMaximum, + _this.LowestHighestValueSupported, + _this.RecordedValueSupported, + _this.Description); + } + public static implicit operator RDMSensorValue(Sensor _this) + { + return new RDMSensorValue(_this.SensorId, + _this.PresentValue, + _this.LowestValue, + _this.HighestValue, + _this.RecordedValue); } } \ No newline at end of file diff --git a/RDMSharp/RDM/Slot.cs b/RDMSharp/RDM/Slot.cs index 4e411d3d..327307e5 100644 --- a/RDMSharp/RDM/Slot.cs +++ b/RDMSharp/RDM/Slot.cs @@ -1,170 +1,170 @@ -using System; +using RDMSharp.PayloadObject; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Text; -namespace RDMSharp +namespace RDMSharp; + +public class Slot : INotifyPropertyChanged, IEquatable { - public class Slot : INotifyPropertyChanged, IEquatable - { - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler PropertyChanged; - public readonly ushort SlotId; + public readonly ushort SlotId; - private ERDM_SlotType type; - public ERDM_SlotType Type + private ERDM_SlotType type; + public ERDM_SlotType Type + { + get { return type; } + private set { - get { return type; } - private set - { - if (type == value) - return; - - type = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Type))); - } - } + if (type == value) + return; - private ERDM_SlotCategory category; - public ERDM_SlotCategory Category - { - get { return category; } - private set - { - if (category == value) - return; - - category = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Category))); - } + type = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Type))); } + } - private string description; - public string Description + private ERDM_SlotCategory category; + public ERDM_SlotCategory Category + { + get { return category; } + private set { - get { return description; } - private set - { - if (description == value) - return; - - description = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Description))); - } - } + if (category == value) + return; - private byte defaultValue; - public byte DefaultValue - { - get { return defaultValue; } - private set - { - if (defaultValue == value) - return; - - defaultValue = value; - this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(DefaultValue))); - } + category = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Category))); } + } - public Slot(in ushort slotId) - { - this.SlotId = slotId; - } - public Slot( - in ushort slotId, - in ERDM_SlotCategory category, - in ERDM_SlotType type, - in string description = null, - in byte defaultValue = 0) : this(slotId) - { - this.Category = category; - this.Type = type; - this.Description = description; - this.DefaultValue = defaultValue; - } - public Slot( - in ushort slotId, - in ERDM_SlotCategory category, - in string description = null, - in byte defaultValue = 0) : this(slotId, category, ERDM_SlotType.PRIMARY, description: description, defaultValue: defaultValue) + private string description; + public string Description + { + get { return description; } + private set { + if (description == value) + return; + + description = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(Description))); } + } - internal void UpdateSlotInfo(RDMSlotInfo slotInfo) + private byte defaultValue; + public byte DefaultValue + { + get { return defaultValue; } + private set { - if (this.SlotId != slotInfo.SlotOffset) - throw new InvalidOperationException($"The given {nameof(slotInfo)} has not the expected id of {this.SlotId} but {slotInfo.SlotOffset}"); + if (defaultValue == value) + return; - this.Type = slotInfo.SlotType; - this.Category = slotInfo.SlotLabelId; + defaultValue = value; + this.PropertyChanged?.InvokeFailSafe(this, new PropertyChangedEventArgs(nameof(DefaultValue))); } + } - internal void UpdateSlotDescription(RDMSlotDescription slotDescription) - { - if (this.SlotId != slotDescription.SlotId) - throw new InvalidOperationException($"The given {nameof(slotDescription)} has not the expected id of {this.SlotId} but {slotDescription.SlotId}"); + public Slot(in ushort slotId) + { + this.SlotId = slotId; + } + public Slot( + in ushort slotId, + in ERDM_SlotCategory category, + in ERDM_SlotType type, + in string description = null, + in byte defaultValue = 0) : this(slotId) + { + this.Category = category; + this.Type = type; + this.Description = description; + this.DefaultValue = defaultValue; + } + public Slot( + in ushort slotId, + in ERDM_SlotCategory category, + in string description = null, + in byte defaultValue = 0) : this(slotId, category, ERDM_SlotType.PRIMARY, description: description, defaultValue: defaultValue) + { + } - this.Description = slotDescription.Description; - } + internal void UpdateSlotInfo(RDMSlotInfo slotInfo) + { + if (this.SlotId != slotInfo.SlotOffset) + throw new InvalidOperationException($"The given {nameof(slotInfo)} has not the expected id of {this.SlotId} but {slotInfo.SlotOffset}"); - internal void UpdateSlotDefaultValue(RDMDefaultSlotValue defaultSlotValue) - { - if (this.SlotId != defaultSlotValue.SlotOffset) - throw new InvalidOperationException($"The given {nameof(defaultSlotValue)} has not the expected id of {this.SlotId} but {defaultSlotValue.SlotOffset}"); + this.Type = slotInfo.SlotType; + this.Category = slotInfo.SlotLabelId; + } - this.DefaultValue = defaultSlotValue.DefaultSlotValue; - } + internal void UpdateSlotDescription(RDMSlotDescription slotDescription) + { + if (this.SlotId != slotDescription.SlotId) + throw new InvalidOperationException($"The given {nameof(slotDescription)} has not the expected id of {this.SlotId} but {slotDescription.SlotId}"); - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine($"Slot: {this.SlotId}"); - sb.AppendLine($"Category: {this.Category}"); - sb.AppendLine($"Type: {this.Type}"); - sb.AppendLine($"Description: {this.Description}"); - sb.AppendLine($"DefaultValue: {this.DefaultValue}"); - return sb.ToString(); - } + this.Description = slotDescription.Description; + } - public override bool Equals(object obj) - { - return Equals(obj as Slot); - } + internal void UpdateSlotDefaultValue(RDMDefaultSlotValue defaultSlotValue) + { + if (this.SlotId != defaultSlotValue.SlotOffset) + throw new InvalidOperationException($"The given {nameof(defaultSlotValue)} has not the expected id of {this.SlotId} but {defaultSlotValue.SlotOffset}"); - public bool Equals(Slot other) - { - return other is not null && - SlotId == other.SlotId && - Type == other.Type && - Category == other.Category && - Description == other.Description && - DefaultValue == other.DefaultValue; - } + this.DefaultValue = defaultSlotValue.DefaultSlotValue; + } - public override int GetHashCode() - { + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"Slot: {this.SlotId}"); + sb.AppendLine($"Category: {this.Category}"); + sb.AppendLine($"Type: {this.Type}"); + sb.AppendLine($"Description: {this.Description}"); + sb.AppendLine($"DefaultValue: {this.DefaultValue}"); + return sb.ToString(); + } + + public override bool Equals(object obj) + { + return Equals(obj as Slot); + } + + public bool Equals(Slot other) + { + return other is not null && + SlotId == other.SlotId && + Type == other.Type && + Category == other.Category && + Description == other.Description && + DefaultValue == other.DefaultValue; + } + + public override int GetHashCode() + { #if !NETSTANDARD - return HashCode.Combine(SlotId, Type, Category, Description, DefaultValue); + return HashCode.Combine(SlotId, Type, Category, Description, DefaultValue); #else - int hashCode = 1916557166; - hashCode = hashCode * -1521134295 + SlotId.GetHashCode(); - hashCode = hashCode * -1521134295 + Type.GetHashCode(); - hashCode = hashCode * -1521134295 + Category.GetHashCode(); - hashCode = hashCode * -1521134295 + Description.GetHashCode(); - hashCode = hashCode * -1521134295 + DefaultValue.GetHashCode(); - return hashCode; + int hashCode = 1916557166; + hashCode = hashCode * -1521134295 + SlotId.GetHashCode(); + hashCode = hashCode * -1521134295 + Type.GetHashCode(); + hashCode = hashCode * -1521134295 + Category.GetHashCode(); + hashCode = hashCode * -1521134295 + Description.GetHashCode(); + hashCode = hashCode * -1521134295 + DefaultValue.GetHashCode(); + return hashCode; #endif - } + } - public static bool operator ==(Slot left, Slot right) - { - return EqualityComparer.Default.Equals(left, right); - } + public static bool operator ==(Slot left, Slot right) + { + return EqualityComparer.Default.Equals(left, right); + } - public static bool operator !=(Slot left, Slot right) - { - return !(left == right); - } + public static bool operator !=(Slot left, Slot right) + { + return !(left == right); } } \ No newline at end of file diff --git a/RDMSharp/RDM/Tools.cs b/RDMSharp/RDM/Tools.cs index fbd2ada0..91ac595a 100644 --- a/RDMSharp/RDM/Tools.cs +++ b/RDMSharp/RDM/Tools.cs @@ -1,4 +1,5 @@ -using System; +using RDMSharp.PayloadObject; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; @@ -9,605 +10,617 @@ using System.Text; using static RDMSharp.Metadata.JSON.Command; -namespace RDMSharp -{ - public static class Constants +namespace RDMSharp; + +public static class Constants +{ + public static readonly ERDM_Parameter[] BLUEPRINT_MODEL_PARAMETERS = new ERDM_Parameter[] { - public static readonly ERDM_Parameter[] BLUEPRINT_MODEL_PARAMETERS = new ERDM_Parameter[] - { - ERDM_Parameter.SUPPORTED_PARAMETERS, - ERDM_Parameter.PARAMETER_DESCRIPTION, - ERDM_Parameter.MANUFACTURER_LABEL, - ERDM_Parameter.MANUFACTURER_URL, - ERDM_Parameter.DEVICE_MODEL_DESCRIPTION, - ERDM_Parameter.PRODUCT_DETAIL_ID_LIST, - ERDM_Parameter.PRODUCT_URL, - ERDM_Parameter.FIRMWARE_URL, + ERDM_Parameter.SUPPORTED_PARAMETERS, + ERDM_Parameter.SUPPORTED_PARAMETERS_ENHANCED, + ERDM_Parameter.CONTROLLER_FLAG_SUPPORT, + ERDM_Parameter.PARAMETER_DESCRIPTION, + ERDM_Parameter.MANUFACTURER_LABEL, + ERDM_Parameter.MANUFACTURER_URL, + ERDM_Parameter.DEVICE_MODEL_DESCRIPTION, + ERDM_Parameter.PRODUCT_DETAIL_ID_LIST, + ERDM_Parameter.PRODUCT_URL, + ERDM_Parameter.FIRMWARE_URL, - ERDM_Parameter.METADATA_JSON_URL, - ERDM_Parameter.METADATA_JSON, - ERDM_Parameter.METADATA_PARAMETER_VERSION, + ERDM_Parameter.PACKED_PID_SUB, + ERDM_Parameter.PACKED_PID_INDEX, - ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, - ERDM_Parameter.DMX_PERSONALITY_ID, + ERDM_Parameter.METADATA_JSON_URL, + ERDM_Parameter.METADATA_JSON, + ERDM_Parameter.METADATA_PARAMETER_VERSION, - ERDM_Parameter.SENSOR_DEFINITION, - ERDM_Parameter.SENSOR_TYPE_CUSTOM, - ERDM_Parameter.SENSOR_UNIT_CUSTOM, + ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, + ERDM_Parameter.DMX_PERSONALITY_ID, - ERDM_Parameter.CURVE_DESCRIPTION, - ERDM_Parameter.DIMMER_INFO, - ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, - ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, - ERDM_Parameter.LOCK_STATE_DESCRIPTION, + ERDM_Parameter.SENSOR_DEFINITION, + ERDM_Parameter.SENSOR_TYPE_CUSTOM, + ERDM_Parameter.SENSOR_UNIT_CUSTOM, - ERDM_Parameter.SELF_TEST_DESCRIPTION, - ERDM_Parameter.STATUS_ID_DESCRIPTION, - ERDM_Parameter.LANGUAGE_CAPABILITIES, - ERDM_Parameter.SOFTWARE_VERSION_LABEL, - ERDM_Parameter.LIST_INTERFACES, - ERDM_Parameter.INTERFACE_LABEL, + ERDM_Parameter.PRESET_INFO, - }; + ERDM_Parameter.CURVE_DESCRIPTION, + ERDM_Parameter.DIMMER_INFO, + ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, + ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, + ERDM_Parameter.LOCK_STATE_DESCRIPTION, - public static readonly ERDM_Parameter[] BLUEPRINT_MODEL_PERSONALITY_PARAMETERS = new ERDM_Parameter[] - { - ERDM_Parameter.SLOT_DESCRIPTION, - ERDM_Parameter.SLOT_INFO, - ERDM_Parameter.DEFAULT_SLOT_VALUE - }; - } - public static class Tools + ERDM_Parameter.SELF_TEST_DESCRIPTION, + ERDM_Parameter.STATUS_ID_DESCRIPTION, + ERDM_Parameter.LANGUAGE_CAPABILITIES, + ERDM_Parameter.SOFTWARE_VERSION_LABEL, + ERDM_Parameter.LIST_INTERFACES, + ERDM_Parameter.INTERFACE_LABEL, + + ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, + ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, + + ERDM_Parameter.NACK_DESCRIPTION, + ERDM_Parameter.ENUM_LABEL + }; + + public static readonly ERDM_Parameter[] BLUEPRINT_MODEL_PERSONALITY_PARAMETERS = new ERDM_Parameter[] + { + ERDM_Parameter.SLOT_DESCRIPTION, + ERDM_Parameter.SLOT_INFO, + ERDM_Parameter.DEFAULT_SLOT_VALUE + }; +} +public static class Tools +{ + public static int GenerateHashCode(this IEnumerable enumerable) { - public static int GenerateHashCode(this IEnumerable enumerable) - { - int hash = 0; - if (enumerable == null) return hash; + int hash = 0; + if (enumerable == null) return hash; - int mul = 1; - foreach (var a in enumerable) - hash += (a?.GetHashCode() * mul++) ?? 0; + int mul = 1; + foreach (var a in enumerable) + hash += (a?.GetHashCode() * mul++) ?? 0; - return hash; - } - public static string FormatNumber(double number) - { - string[] prefixes = { "", "k", "M", "G", "T", "P", "E", "Z", "Y" }; - string[] suffixes = { "", "m", "µ", "n", "p", "f", "a", "z", "y" }; + return hash; + } + public static string FormatNumber(double number) + { + string[] prefixes = { "", "k", "M", "G", "T", "P", "E", "Z", "Y" }; + string[] suffixes = { "", "m", "µ", "n", "p", "f", "a", "z", "y" }; - int prefixIndex = 0; - int suffixIndex = 0; + int prefixIndex = 0; + int suffixIndex = 0; - while (Math.Abs(number) >= 1000 && prefixIndex < prefixes.Length - 1) - { - number /= 1000; - prefixIndex++; - } + while (Math.Abs(number) >= 1000 && prefixIndex < prefixes.Length - 1) + { + number /= 1000; + prefixIndex++; + } - while (Math.Abs(number) < 1 && suffixIndex < suffixes.Length - 1) - { - number *= 1000; - suffixIndex++; - } + while (Math.Abs(number) < 1 && suffixIndex < suffixes.Length - 1) + { + number *= 1000; + suffixIndex++; + } - number = Math.Round(number, 2); - if (number == 0) - return "0"; + number = Math.Round(number, 2); + if (number == 0) + return "0"; - string prefix = prefixes[prefixIndex]; - string suffix = suffixes[suffixIndex]; + string prefix = prefixes[prefixIndex]; + string suffix = suffixes[suffixIndex]; - return $"{number:0.##}{prefix}{suffix}"; - } + return $"{number:0.##}{prefix}{suffix}"; + } - public static string GetFormatedSensorValue(in uint value, in ERDM_UnitPrefix prefix, in ERDM_SensorUnit unit) - { - return $"{FormatNumber(prefix.GetNormalizedValue(value))}{unit.GetUnitSymbol()}"; - } - public static string GetFormatedSensorValue(in short value, in ERDM_UnitPrefix prefix, in ERDM_SensorUnit unit) - { - return $"{FormatNumber(prefix.GetNormalizedValue(value))}{unit.GetUnitSymbol()}"; - } + public static string GetFormatedSensorValue(in uint value, in ERDM_UnitPrefix prefix, in ERDM_SensorUnit unit) + { + return $"{FormatNumber(prefix.GetNormalizedValue(value))}{unit.GetUnitSymbol()}"; + } + public static string GetFormatedSensorValue(in short value, in ERDM_UnitPrefix prefix, in ERDM_SensorUnit unit) + { + return $"{FormatNumber(prefix.GetNormalizedValue(value))}{unit.GetUnitSymbol()}"; + } - public static double GetNormalizedValue(this ERDM_UnitPrefix prefix, in uint value) - { - return value * (prefix.GetAttribute().Multiplyer); - } - public static double GetNormalizedValue(this ERDM_UnitPrefix prefix, in short value) - { - return value * (prefix.GetAttribute().Multiplyer); - } + public static double GetNormalizedValue(this ERDM_UnitPrefix prefix, in uint value) + { + return value * (prefix.GetAttribute().Multiplyer); + } + public static double GetNormalizedValue(this ERDM_UnitPrefix prefix, in short value) + { + return value * (prefix.GetAttribute().Multiplyer); + } - public static string GetUnitSymbol(this ERDM_SensorUnit unit) - { - return unit.GetAttribute().Unit; - } + public static string GetUnitSymbol(this ERDM_SensorUnit unit) + { + return unit.GetAttribute().Unit; + } - public static string GetStatusMessage(this ERDM_StatusMessage status, in short dataValue1 = 0, in short dataValue2 = 0) - { - return status.GetAttribute().GetFormatedString(dataValue1, dataValue2) ?? string.Empty; - } - public static string GetEnumDescription(Enum value) - { - return value.GetAttribute()?.Description ?? value.ToString(); - } - public static TAttribute GetAttribute(this Enum value) - where TAttribute : Attribute - { - var type = value.GetType(); - var name = Enum.GetName(type, value); - if (string.IsNullOrWhiteSpace(name)) - return null; - return type.GetField(name) // I prefer to get attributes this way - .GetCustomAttributes(false) - .OfType() - .SingleOrDefault(); - } - public static List FindClassesWithAttribute() where TAttribute : Attribute - { - Assembly assembly = Assembly.GetExecutingAssembly(); - return assembly.GetTypes() - .Where(t => (t.IsClass || t.IsEnum) && t.GetCustomAttributes().Any(a => a is TAttribute)) - .ToList(); - } + public static string GetStatusMessage(this ERDM_StatusMessage status, in short dataValue1 = 0, in short dataValue2 = 0) + { + return status.GetAttribute()?.GetFormatedString(dataValue1, dataValue2) ?? string.Empty; + } + public static string GetEnumDescription(Enum value) + { + return value.GetAttribute()?.Description ?? value.ToString(); + } + public static TAttribute GetAttribute(this Enum value) + where TAttribute : Attribute + { + var type = value.GetType(); + var name = Enum.GetName(type, value); + if (string.IsNullOrWhiteSpace(name)) + return null; + return type.GetField(name) // I prefer to get attributes this way + .GetCustomAttributes(false) + .OfType() + .SingleOrDefault(); + } + public static List FindClassesWithAttribute() where TAttribute : Attribute + { + var assemblys = AppDomain.CurrentDomain.GetAssemblies(); + List types = new List(); + foreach (var assembly in assemblys) + types.AddRange(assembly.GetTypes().Where(t => (t.IsClass || t.IsEnum) && t.GetCustomAttributes().Any(a => a is TAttribute))); + return types; + } - public static IEnumerable EncaseData(byte[] data) - { - List enumerable = new List(); - enumerable.Add(data); - return enumerable.AsReadOnly(); - } - public static byte[] ValueToData(params bool[] bits) + public static IEnumerable EncaseData(byte[] data) + { + List enumerable = new List(); + enumerable.Add(data); + return enumerable.AsReadOnly(); + } + public static byte[] ValueToData(params bool[] bits) + { + return ValueToData(bits, trim: 0); + } + public static byte[] ValueToData(object value, int trim = 32) + { + if (value == null) + return Array.Empty(); + + if (value is Enum @enum) { - return ValueToData(bits, trim: 0); + switch (@enum.GetTypeCode()) + { + default: + case TypeCode.Byte: + value = (byte)value; + break; + case TypeCode.SByte: + value = (sbyte)value; + break; + case TypeCode.Int16: + value = (short)value; + break; + case TypeCode.UInt16: + value = (ushort)value; + break; + case TypeCode.Int32: + value = (int)value; + break; + case TypeCode.UInt32: + value = (uint)value; + break; + case TypeCode.Int64: + value = (long)value; + break; + case TypeCode.UInt64: + value = (ulong)value; + break; + } } - public static byte[] ValueToData(object value, int trim = 32) - { - if (value == null) - return Array.Empty(); - if (value is Enum @enum) - { - switch (@enum.GetTypeCode()) + switch (value) + { + case AbstractRDMPayloadObject[] @payloadObjectArray: + List l1Bytes = new List(); + foreach (AbstractRDMPayloadObject payloadObject in @payloadObjectArray) + l1Bytes.AddRange(payloadObject.ToPayloadData()); + return l1Bytes.ToArray(); + case AbstractRDMPayloadObject @payloadObject: + return payloadObject.ToPayloadData(); + + case byte[] @byteArray: + return @byteArray; + case bool[] @boolArray: + int byteCount = (int)Math.Ceiling(@boolArray.Length / 8.0); + byte[] _resArray = new byte[byteCount]; + for (int bitIndex = 0; bitIndex < @boolArray.Length; bitIndex++) { - default: - case TypeCode.Byte: - value = (byte)value; - break; - case TypeCode.SByte: - value = (sbyte)value; - break; - case TypeCode.Int16: - value = (short)value; - break; - case TypeCode.UInt16: - value = (ushort)value; - break; - case TypeCode.Int32: - value = (int)value; - break; - case TypeCode.UInt32: - value = (uint)value; - break; - case TypeCode.Int64: - value = (long)value; - break; - case TypeCode.UInt64: - value = (ulong)value; - break; + int byteIndex = bitIndex / 8; + int bitInByteIndex = bitIndex % 8; + byte mask = (byte)(1 << bitInByteIndex); + if (boolArray[bitIndex]) + _resArray[byteIndex] |= mask; } - } - - switch (value) - { - case AbstractRDMPayloadObject[] @payloadObjectArray: - List l1Bytes = new List(); - foreach (AbstractRDMPayloadObject payloadObject in @payloadObjectArray) - l1Bytes.AddRange(payloadObject.ToPayloadData()); - return l1Bytes.ToArray(); - case AbstractRDMPayloadObject @payloadObject: - return payloadObject.ToPayloadData(); - - case byte[] @byteArray: - return @byteArray; - case bool[] @boolArray: - int byteCount = (int)Math.Ceiling(@boolArray.Length / 8.0); - byte[] _resArray = new byte[byteCount]; - for (int bitIndex = 0; bitIndex < @boolArray.Length; bitIndex++) - { - int byteIndex = bitIndex / 8; - int bitInByteIndex = bitIndex % 8; - byte mask = (byte)(1 << bitInByteIndex); - if (boolArray[bitIndex]) - _resArray[byteIndex] |= mask; - } - return _resArray; - case UID[] @uidArray: - List lBytes = new List(); - foreach (UID uid in @uidArray) - lBytes.AddRange(uid.ToBytes()); - return lBytes.ToArray(); - case UID @uid: - return @uid.ToBytes().ToArray(); + return _resArray; + case UID[] @uidArray: + List lBytes = new List(); + foreach (UID uid in @uidArray) + lBytes.AddRange(uid.ToBytes()); + return lBytes.ToArray(); + case UID @uid: + return @uid.ToBytes().ToArray(); - case IPv4Address @ipv4Address: - return (byte[])@ipv4Address; - case IPAddress @ipAddress: - if (@ipAddress.AddressFamily == AddressFamily.InterNetwork) - { - //AL 2022-09-11: Commented out as ipAddress.Address is deprecated - //List ipBytes = new List(); - //byte[] ipAddressBytes = Tools.ValueToData((uint)@ipAddress.Address); - //for (int i = 3; i >= 0; i--) - // ipBytes.Add(ipAddressBytes[i]); - //return ipBytes.ToArray(); - - return ipAddress.GetAddressBytes(); //In case the Bytes are in reverse order use .Reverse().ToArray(); - } - else if (@ipAddress.AddressFamily == AddressFamily.InterNetworkV6) - { - return @ipAddress.GetAddressBytes(); - } - throw new NotSupportedException(); - - case byte @byte: - return DoOneByte(@byte); - case sbyte @sbyte: - return DoOneByte((byte)@sbyte); - case ushort @ushort: - return DoTwoByte(@ushort); - case short @short: - return DoTwoByte((ushort)@short); - case int @int: - return DoFourByte((uint)@int); - case uint @uint: - return DoFourByte(@uint); - case long @long: - return DoEightByte((ulong)@long); - case ulong @ulong: - return DoEightByte(@ulong); + case IPv4Address @ipv4Address: + return (byte[])@ipv4Address; + case IPAddress @ipAddress: + if (@ipAddress.AddressFamily == AddressFamily.InterNetwork) + { + //AL 2022-09-11: Commented out as ipAddress.Address is deprecated + //List ipBytes = new List(); + //byte[] ipAddressBytes = Tools.ValueToData((uint)@ipAddress.Address); + //for (int i = 3; i >= 0; i--) + // ipBytes.Add(ipAddressBytes[i]); + //return ipBytes.ToArray(); + + return ipAddress.GetAddressBytes(); //In case the Bytes are in reverse order use .Reverse().ToArray(); + } + else if (@ipAddress.AddressFamily == AddressFamily.InterNetworkV6) + { + return @ipAddress.GetAddressBytes(); + } + throw new NotSupportedException(); + + case byte @byte: + return DoOneByte(@byte); + case sbyte @sbyte: + return DoOneByte((byte)@sbyte); + case ushort @ushort: + return DoTwoByte(@ushort); + case short @short: + return DoTwoByte((ushort)@short); + case int @int: + return DoFourByte((uint)@int); + case uint @uint: + return DoFourByte(@uint); + case long @long: + return DoEightByte((ulong)@long); + case ulong @ulong: + return DoEightByte(@ulong); #if NET7_0_OR_GREATER - case Int128 @long: - return DoSixteenByte((UInt128)@long); - case UInt128 @ulong: - return DoSixteenByte(@ulong); + case Int128 @long: + return DoSixteenByte((UInt128)@long); + case UInt128 @ulong: + return DoSixteenByte(@ulong); #endif - case string @string: - if (trim >= 1) - if (@string.Length > trim) - @string = @string.Substring(0, trim); + case string @string: + if (trim >= 1) + if (@string.Length > trim) + @string = @string.Substring(0, trim); - return Encoding.UTF8.GetBytes(@string); + return Encoding.UTF8.GetBytes(@string); - case bool @bool: - return new byte[] { (byte)(@bool ? 1 : 0) }; + case bool @bool: + return new byte[] { (byte)(@bool ? 1 : 0) }; - default: - throw new NotSupportedException(value.GetType().Name); - } + default: + throw new NotSupportedException(value.GetType().Name); + } - //Local Functions + //Local Functions - byte[] DoOneByte(byte b) => new byte[] { b }; - byte[] DoTwoByte(ushort s) => new byte[] { (byte)(s >> 8), (byte)s }; - byte[] DoFourByte(uint i) => new byte[] { (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte)i }; - byte[] DoEightByte(ulong i) => new byte[] { (byte)(i >> 56), (byte)(i >> 48), (byte)(i >> 40), (byte)(i >> 32), (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte)i }; + byte[] DoOneByte(byte b) => new byte[] { b }; + byte[] DoTwoByte(ushort s) => new byte[] { (byte)(s >> 8), (byte)s }; + byte[] DoFourByte(uint i) => new byte[] { (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte)i }; + byte[] DoEightByte(ulong i) => new byte[] { (byte)(i >> 56), (byte)(i >> 48), (byte)(i >> 40), (byte)(i >> 32), (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte)i }; #if NET7_0_OR_GREATER - byte[] DoSixteenByte(UInt128 i) => new byte[] { (byte)(i >> 120), (byte)(i >> 112), (byte)(i >> 104), (byte)(i >> 96), (byte)(i >> 88), (byte)(i >> 80), (byte)(i >> 72), (byte)(i >> 64), (byte)(i >> 56), (byte)(i >> 48), (byte)(i >> 40), (byte)(i >> 32), (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte)i }; + byte[] DoSixteenByte(UInt128 i) => new byte[] { (byte)(i >> 120), (byte)(i >> 112), (byte)(i >> 104), (byte)(i >> 96), (byte)(i >> 88), (byte)(i >> 80), (byte)(i >> 72), (byte)(i >> 64), (byte)(i >> 56), (byte)(i >> 48), (byte)(i >> 40), (byte)(i >> 32), (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte)i }; #endif - } + } - public static byte DataToByte(ref byte[] data) - { - const int length = 1; - if (data.Length < length) - throw new IndexOutOfRangeException(); + public static byte DataToByte(ref byte[] data) + { + const int length = 1; + if (data.Length < length) + throw new IndexOutOfRangeException(); - byte result = (byte)data[0]; + byte result = (byte)data[0]; - data = data.Skip(length).ToArray(); - return result; - } - public static sbyte DataToSByte(ref byte[] data) - { - const int length = 1; - if (data.Length < length) - throw new IndexOutOfRangeException(); + data = data.Skip(length).ToArray(); + return result; + } + public static sbyte DataToSByte(ref byte[] data) + { + const int length = 1; + if (data.Length < length) + throw new IndexOutOfRangeException(); - sbyte result = (sbyte)data[0]; + sbyte result = (sbyte)data[0]; - data = data.Skip(length).ToArray(); - return result; - } - public static short DataToShort(ref byte[] data) - { - const int length = 2; - if (data.Length < length) - throw new IndexOutOfRangeException(); + data = data.Skip(length).ToArray(); + return result; + } + public static short DataToShort(ref byte[] data) + { + const int length = 2; + if (data.Length < length) + throw new IndexOutOfRangeException(); - short result = (short)((data[0] << 8) | data[1]); + short result = (short)((data[0] << 8) | data[1]); - data = data.Skip(length).ToArray(); - return result; - } - public static ushort DataToUShort(ref byte[] data) - { - const int length = 2; - if (data.Length < length) - throw new IndexOutOfRangeException(); + data = data.Skip(length).ToArray(); + return result; + } + public static ushort DataToUShort(ref byte[] data) + { + const int length = 2; + if (data.Length < length) + throw new IndexOutOfRangeException(); - ushort result = (ushort)((data[0] << 8) | data[1]); + ushort result = (ushort)((data[0] << 8) | data[1]); - data = data.Skip(length).ToArray(); - return result; - } - public static int DataToInt(ref byte[] data) - { - const int length = 4; - if (data.Length < length) - throw new IndexOutOfRangeException(); + data = data.Skip(length).ToArray(); + return result; + } + public static int DataToInt(ref byte[] data) + { + const int length = 4; + if (data.Length < length) + throw new IndexOutOfRangeException(); - int result = (int)data[0] << 24 | - (int)data[1] << 16 | - (int)data[2] << 8 | - (int)data[3]; + int result = (int)data[0] << 24 | + (int)data[1] << 16 | + (int)data[2] << 8 | + (int)data[3]; - data = data.Skip(length).ToArray(); - return result; - } - public static uint DataToUInt(ref byte[] data) - { - const int length = 4; - if (data.Length < length) - throw new IndexOutOfRangeException(); + data = data.Skip(length).ToArray(); + return result; + } + public static uint DataToUInt(ref byte[] data) + { + const int length = 4; + if (data.Length < length) + throw new IndexOutOfRangeException(); - uint result = (uint)data[0] << 24 | - (uint)data[1] << 16 | - (uint)data[2] << 8 | - (uint)data[3]; + uint result = (uint)data[0] << 24 | + (uint)data[1] << 16 | + (uint)data[2] << 8 | + (uint)data[3]; - data = data.Skip(length).ToArray(); - return result; - } - public static long DataToLong(ref byte[] data) - { - const int length = 8; - if (data.Length < length) - throw new IndexOutOfRangeException(); - - long result = (long)data[0] << 56 | - (long)data[1] << 48 | - (long)data[2] << 40 | - (long)data[3] << 32 | - (long)data[4] << 24 | - (long)data[5] << 16 | - (long)data[6] << 8 | - (long)data[7]; - - data = data.Skip(length).ToArray(); - return result; - } - public static ulong DataToULong(ref byte[] data) - { - const int length = 8; - if (data.Length < length) - throw new IndexOutOfRangeException(); - - ulong result = (ulong)data[0] << 56 | - (ulong)data[1] << 48 | - (ulong)data[2] << 40 | - (ulong)data[3] << 32 | - (ulong)data[4] << 24 | - (ulong)data[5] << 16 | - (ulong)data[6] << 8 | - (ulong)data[7]; - - data = data.Skip(length).ToArray(); - return result; - } + data = data.Skip(length).ToArray(); + return result; + } + public static long DataToLong(ref byte[] data) + { + const int length = 8; + if (data.Length < length) + throw new IndexOutOfRangeException(); + + long result = (long)data[0] << 56 | + (long)data[1] << 48 | + (long)data[2] << 40 | + (long)data[3] << 32 | + (long)data[4] << 24 | + (long)data[5] << 16 | + (long)data[6] << 8 | + (long)data[7]; + + data = data.Skip(length).ToArray(); + return result; + } + public static ulong DataToULong(ref byte[] data) + { + const int length = 8; + if (data.Length < length) + throw new IndexOutOfRangeException(); + + ulong result = (ulong)data[0] << 56 | + (ulong)data[1] << 48 | + (ulong)data[2] << 40 | + (ulong)data[3] << 32 | + (ulong)data[4] << 24 | + (ulong)data[5] << 16 | + (ulong)data[6] << 8 | + (ulong)data[7]; + + data = data.Skip(length).ToArray(); + return result; + } #if NET7_0_OR_GREATER - public static Int128 DataToInt128(ref byte[] data) - { - const int length = 16; - if (data.Length < length) - throw new IndexOutOfRangeException(); + public static Int128 DataToInt128(ref byte[] data) + { + const int length = 16; + if (data.Length < length) + throw new IndexOutOfRangeException(); - Int128 result = (Int128)data[0] << 120 | - (Int128)data[1] << 112 | - (Int128)data[2] << 104 | - (Int128)data[3] << 96 | - (Int128)data[4] << 88 | - (Int128)data[5] << 80 | - (Int128)data[6] << 72 | - (Int128)data[7] << 64 | - (Int128)data[8] << 56 | - (Int128)data[9] << 48 | - (Int128)data[10] << 40 | - (Int128)data[11] << 32 | - (Int128)data[12] << 24 | - (Int128)data[13] << 16 | - (Int128)data[14] << 8 | - (Int128)data[15]; + Int128 result = (Int128)data[0] << 120 | + (Int128)data[1] << 112 | + (Int128)data[2] << 104 | + (Int128)data[3] << 96 | + (Int128)data[4] << 88 | + (Int128)data[5] << 80 | + (Int128)data[6] << 72 | + (Int128)data[7] << 64 | + (Int128)data[8] << 56 | + (Int128)data[9] << 48 | + (Int128)data[10] << 40 | + (Int128)data[11] << 32 | + (Int128)data[12] << 24 | + (Int128)data[13] << 16 | + (Int128)data[14] << 8 | + (Int128)data[15]; - data = data.Skip(length).ToArray(); - return result; - } - public static UInt128 DataToUInt128(ref byte[] data) - { - const int length = 16; - if (data.Length < length) - throw new IndexOutOfRangeException(); + data = data.Skip(length).ToArray(); + return result; + } + public static UInt128 DataToUInt128(ref byte[] data) + { + const int length = 16; + if (data.Length < length) + throw new IndexOutOfRangeException(); - UInt128 result = (UInt128)data[0] << 120 | - (UInt128)data[1] << 112 | - (UInt128)data[2] << 104 | - (UInt128)data[3] << 96 | - (UInt128)data[4] << 88 | - (UInt128)data[5] << 80 | - (UInt128)data[6] << 72 | - (UInt128)data[7] << 64 | - (UInt128)data[8] << 56 | - (UInt128)data[9] << 48 | - (UInt128)data[10] << 40 | - (UInt128)data[11] << 32 | - (UInt128)data[12] << 24 | - (UInt128)data[13] << 16 | - (UInt128)data[14] << 8 | - (UInt128)data[15]; + UInt128 result = (UInt128)data[0] << 120 | + (UInt128)data[1] << 112 | + (UInt128)data[2] << 104 | + (UInt128)data[3] << 96 | + (UInt128)data[4] << 88 | + (UInt128)data[5] << 80 | + (UInt128)data[6] << 72 | + (UInt128)data[7] << 64 | + (UInt128)data[8] << 56 | + (UInt128)data[9] << 48 | + (UInt128)data[10] << 40 | + (UInt128)data[11] << 32 | + (UInt128)data[12] << 24 | + (UInt128)data[13] << 16 | + (UInt128)data[14] << 8 | + (UInt128)data[15]; - data = data.Skip(length).ToArray(); - return result; - } + data = data.Skip(length).ToArray(); + return result; + } #endif - public static UID DataToRDMUID(ref byte[] data) - { - const int length = 6; - if (data.Length < length) - throw new IndexOutOfRangeException(); + public static UID DataToRDMUID(ref byte[] data) + { + const int length = 6; + if (data.Length < length) + throw new IndexOutOfRangeException(); - return new UID(DataToUShort(ref data), DataToUInt(ref data)); ; - } + return new UID(DataToUShort(ref data), DataToUInt(ref data)); ; + } - public static string DataToString(ref byte[] data, int take = 0) - { - string res; - if (take != 0) - { - res = Encoding.UTF8.GetString(data.Take(take).ToArray()); - data = data.Skip(take).ToArray(); - } - else - { - res = Encoding.UTF8.GetString(data); - data = Array.Empty(); - } - return res; - } - - public static bool DataToBool(ref byte[] data) + public static string DataToString(ref byte[] data, int take = 0) + { + string res; + if (take != 0) { - const int length = 1; - if (data.Length < length) - throw new IndexOutOfRangeException(); - - bool res = false; - if (data[0] == (byte)0x01) - res = true; - - data = data.Skip(length).ToArray(); - return res; + res = Encoding.UTF8.GetString(data.Take(take).ToArray()); + data = data.Skip(take).ToArray(); } - public static bool[] DataToBoolArray(ref byte[] data, int bitCount) + else { - List res = new List(); - int length = (int)Math.Ceiling(bitCount / 8.0); - if (data.Length < length) - throw new IndexOutOfRangeException(); - - for (int bitIndex = 0; bitIndex < bitCount; bitIndex++) - { - int byteIndex = bitIndex / 8; - int bitInByteIndex = bitIndex % 8; - byte mask = (byte)(1 << bitInByteIndex); - res.Add((data[byteIndex] & mask) != 0); - } - - data = data.Skip(length).ToArray(); - return res.ToArray(); + res = Encoding.UTF8.GetString(data); + data = Array.Empty(); } - public static T DataToEnum(ref byte[] data) where T : Enum - { - var en = Enum.GetValues(typeof(T)); - var enums = en.Cast(); + return res; + } + + public static bool DataToBool(ref byte[] data) + { + const int length = 1; + if (data.Length < length) + throw new IndexOutOfRangeException(); - switch (enums.FirstOrDefault()?.GetTypeCode()) - { - default: - case TypeCode.Byte: - return (T)Enum.ToObject(typeof(T), DataToByte(ref data)); - case TypeCode.SByte: - return (T)Enum.ToObject(typeof(T), DataToSByte(ref data)); + bool res = false; + if (data[0] == (byte)0x01) + res = true; - case TypeCode.Int16: - return (T)Enum.ToObject(typeof(T), DataToShort(ref data)); - case TypeCode.UInt16: - return (T)Enum.ToObject(typeof(T), DataToUShort(ref data)); + data = data.Skip(length).ToArray(); + return res; + } + public static bool[] DataToBoolArray(ref byte[] data, int bitCount) + { + List res = new List(); + int length = (int)Math.Ceiling(bitCount / 8.0); + if (data.Length < length) + throw new IndexOutOfRangeException(); - case TypeCode.Int32: - return (T)Enum.ToObject(typeof(T), DataToInt(ref data)); - case TypeCode.UInt32: - return (T)Enum.ToObject(typeof(T), DataToUInt(ref data)); + for (int bitIndex = 0; bitIndex < bitCount; bitIndex++) + { + int byteIndex = bitIndex / 8; + int bitInByteIndex = bitIndex % 8; + byte mask = (byte)(1 << bitInByteIndex); + res.Add((data[byteIndex] & mask) != 0); + } + data = data.Skip(length).ToArray(); + return res.ToArray(); + } + public static T DataToEnum(ref byte[] data) where T : Enum + { + var en = Enum.GetValues(typeof(T)); + var enums = en.Cast(); - case TypeCode.Int64: - return (T)Enum.ToObject(typeof(T), DataToLong(ref data)); - case TypeCode.UInt64: - return (T)Enum.ToObject(typeof(T), DataToULong(ref data)); - } + switch (enums.FirstOrDefault()?.GetTypeCode()) + { + default: + case TypeCode.Byte: + return (T)Enum.ToObject(typeof(T), DataToByte(ref data)); + case TypeCode.SByte: + return (T)Enum.ToObject(typeof(T), DataToSByte(ref data)); + + case TypeCode.Int16: + return (T)Enum.ToObject(typeof(T), DataToShort(ref data)); + case TypeCode.UInt16: + return (T)Enum.ToObject(typeof(T), DataToUShort(ref data)); + + case TypeCode.Int32: + return (T)Enum.ToObject(typeof(T), DataToInt(ref data)); + case TypeCode.UInt32: + return (T)Enum.ToObject(typeof(T), DataToUInt(ref data)); + + + case TypeCode.Int64: + return (T)Enum.ToObject(typeof(T), DataToLong(ref data)); + case TypeCode.UInt64: + return (T)Enum.ToObject(typeof(T), DataToULong(ref data)); } - public static IPv4Address DataToIPAddressIPv4(ref byte[] @data) - { - const int length = 4; - if (data.Length < length) - throw new IndexOutOfRangeException(); + } + public static IPv4Address DataToIPAddressIPv4(ref byte[] @data) + { + const int length = 4; + if (data.Length < length) + throw new IndexOutOfRangeException(); - byte[] bytes = new byte[length]; - for (int i = 0; i < bytes.Length; i++) - bytes[i] = Tools.DataToByte(ref data); + byte[] bytes = new byte[length]; + for (int i = 0; i < bytes.Length; i++) + bytes[i] = Tools.DataToByte(ref data); - return new IPv4Address(bytes); - } - public static IPAddress DataToIPAddressIPv6(ref byte[] @data) - { - const int length = 16; - if (data.Length < length) - throw new IndexOutOfRangeException(); + return new IPv4Address(bytes); + } + public static IPAddress DataToIPAddressIPv6(ref byte[] @data) + { + const int length = 16; + if (data.Length < length) + throw new IndexOutOfRangeException(); - byte[] bytes = new byte[length]; - for (int i = 0; i < bytes.Length; i++) - bytes[i] = Tools.DataToByte(ref data); + byte[] bytes = new byte[length]; + for (int i = 0; i < bytes.Length; i++) + bytes[i] = Tools.DataToByte(ref data); - return new IPAddress(bytes); - } - public static IReadOnlyList AsReadOnly(this IList list) - { + return new IPAddress(bytes); + } + public static IReadOnlyList AsReadOnly(this IList list) + { #if NETSTANDARD - if (list == null) - throw new ArgumentNullException(nameof(list)); + if (list == null) + throw new ArgumentNullException(nameof(list)); #else - ArgumentNullException.ThrowIfNull(list); + ArgumentNullException.ThrowIfNull(list); #endif - if (list is List instance) - return instance.AsReadOnly(); - return new ReadOnlyCollection(list); - } - public static IReadOnlyDictionary AsReadOnly(this IDictionary source) - { + if (list is List instance) + return instance.AsReadOnly(); + return new ReadOnlyCollection(list); + } + public static IReadOnlyDictionary AsReadOnly(this IDictionary source) + { #if NETSTANDARD - if (source == null) - throw new ArgumentNullException(nameof(source)); + if (source == null) + throw new ArgumentNullException(nameof(source)); #else - ArgumentNullException.ThrowIfNull(source); + ArgumentNullException.ThrowIfNull(source); #endif - return new ReadOnlyDictionary(source); - } - public static ECommandDublicate ConvertCommandDublicateToCommand(ERDM_Command v) + return new ReadOnlyDictionary(source); + } + public static ECommandDublicate ConvertCommandDublicateToCommand(ERDM_Command v) + { + switch (v) { - switch (v) - { - case ERDM_Command.GET_COMMAND: - return ECommandDublicate.GetRequest; - case ERDM_Command.GET_COMMAND_RESPONSE: - return ECommandDublicate.GetResponse; - case ERDM_Command.SET_COMMAND: - return ECommandDublicate.SetRequest; - case ERDM_Command.SET_COMMAND_RESPONSE: - return ECommandDublicate.SetResponse; - } - throw new NotSupportedException(); - } + case ERDM_Command.GET_COMMAND: + return ECommandDublicate.GetRequest; + case ERDM_Command.GET_COMMAND_RESPONSE: + return ECommandDublicate.GetResponse; + case ERDM_Command.SET_COMMAND: + return ECommandDublicate.SetRequest; + case ERDM_Command.SET_COMMAND_RESPONSE: + return ECommandDublicate.SetResponse; + } + throw new NotSupportedException(); } } diff --git a/RDMSharp/RDMSharp.cs b/RDMSharp/RDMSharp.cs index 9cfd1bd8..053d24bd 100644 --- a/RDMSharp/RDMSharp.cs +++ b/RDMSharp/RDMSharp.cs @@ -1,106 +1,152 @@ -using System; +using RDMSharp.Metadata; +using System; using System.Collections.Concurrent; +using System.Linq; +using System.Threading; using System.Threading.Tasks; -namespace RDMSharp +namespace RDMSharp; + +public class RDMSharp { - public class RDMSharp + private static RDMSharp _instance; + public static RDMSharp Instance { - private static RDMSharp _instance; - public static RDMSharp Instance + get { - get - { - return _instance; - } + return _instance; } + } - public readonly UID ControllerUID; - public readonly Func SendMessage; - public readonly AsyncRDMRequestHelper AsyncRDMRequestHelper; - public event EventHandler? ResponseReceivedEvent; - public event EventHandler? RequestReceivedEvent; + public readonly UID ControllerUID; + public readonly Func SendMessage; + public readonly AsyncRDMRequestHelper AsyncRDMRequestHelper; + public event EventHandler? ResponseReceivedEvent; + public event EventHandler? RequestReceivedEvent; - private readonly ConcurrentDictionary transactionCounters = new ConcurrentDictionary(); + private readonly ConcurrentDictionary transactionCounters = new ConcurrentDictionary(); + private readonly ConcurrentDictionary transactionLock = new ConcurrentDictionary(); + private readonly ConcurrentBag remoteDeviceCache = new ConcurrentBag(); - private RDMSharp(UID controllerUID, Func sendMessage) - { - _instance = this ?? throw new InvalidOperationException("RDMSharp instance already exists. Use Instance property to access it."); + private RDMSharp(UID controllerUID, Func sendMessage) + { + _instance = this ?? throw new InvalidOperationException("RDMSharp instance already exists. Use Instance property to access it."); - this.ControllerUID = controllerUID; + this.ControllerUID = controllerUID; - SendMessage = sendMessage ?? throw new ArgumentNullException(nameof(sendMessage), "SendMethode can't be null."); - AsyncRDMRequestHelper = new AsyncRDMRequestHelper(async (rdmMessage) => - { - rdmMessage.SourceUID = ControllerUID; - await SendMessage.Invoke(rdmMessage); - }); - } - public void ResponseReceived(RDMMessage rdmMessage) - { - if (!AsyncRDMRequestHelper.ReceiveMessage(rdmMessage)) - ResponseReceivedEvent?.InvokeFailSafe(this, rdmMessage); - } - public bool RequestReceived(RDMMessage request, out RDMMessage response) + SendMessage = sendMessage ?? throw new ArgumentNullException(nameof(sendMessage), "SendMethode can't be null."); + AsyncRDMRequestHelper = new AsyncRDMRequestHelper(async (rdmMessage) => { - RDMMessage _response = null; - var e = new RequestReceivedEventArgs(request); - var handlers = RequestReceivedEvent?.GetInvocationList() ?? Array.Empty(); + rdmMessage.SourceUID = ControllerUID; + await SendMessage.Invoke(rdmMessage); + }); + } + public void ResponseReceived(RDMMessage rdmMessage) + { + if (!AsyncRDMRequestHelper.ReceiveMessage(rdmMessage)) + ResponseReceivedEvent?.InvokeFailSafe(this, rdmMessage); + } + public bool RequestReceived(RDMMessage request, out RDMMessage response) + { + RDMMessage _response = null; + var e = new RequestReceivedEventArgs(request); + var handlers = RequestReceivedEvent?.GetInvocationList() ?? Array.Empty(); - // Parallel ausführen, aber Reihenfolge der Responses beachten - ParallelOptions parallelOptions = new ParallelOptions - { - MaxDegreeOfParallelism = Environment.ProcessorCount // Optional: Setze die maximale Parallelität - }; - Parallel.ForEach(handlers, parallelOptions, (handler, state) => + // Parallel ausführen, aber Reihenfolge der Responses beachten + ParallelOptions parallelOptions = new ParallelOptions + { + MaxDegreeOfParallelism = Environment.ProcessorCount // Optional: Setze die maximale Parallelität + }; + Parallel.ForEach(handlers, parallelOptions, (handler, state) => + { + handler.InvokeFailSafe(this, e); + if (e.Response is not null) { - handler.InvokeFailSafe(this, e); - if (e.Response is not null) + if (request.Command != ERDM_Command.DISCOVERY_COMMAND || request.DestUID.IsBroadcast) { - if (request.Command != ERDM_Command.DISCOVERY_COMMAND || request.DestUID.IsBroadcast) - { - _response = e.Response; - state.Stop(); // Beende Parallel.ForEach, wenn eine Response gefunden wurde - } + _response = e.Response; + state.Stop(); // Beende Parallel.ForEach, wenn eine Response gefunden wurde } - }); + } + }); - response = _response; - return response is not null; - } + response = _response; + return response is not null; + } - public static void Initialize(UID controllerUID, Func sendMethode) + public static async Task Initialize(UID controllerUID, Func sendMethode) + { + if (_instance != null) { - if (_instance != null) - { - throw new InvalidOperationException("RDMSharp instance already exists. Use Instance property to access it."); - } - _instance = new RDMSharp(controllerUID, sendMethode); + throw new InvalidOperationException("RDMSharp instance already exists. Use Instance property to access it."); } + _instance = new RDMSharp(controllerUID, sendMethode); + await MetadataFactory.AwaitInitialize(); + } - public class RequestReceivedEventArgs : EventArgs + public class RequestReceivedEventArgs : EventArgs + { + public RDMMessage Request { get; } + public RDMMessage Response { get; set; } + public RequestReceivedEventArgs(RDMMessage request) { - public RDMMessage Request { get; } - public RDMMessage Response { get; set; } - public RequestReceivedEventArgs(RDMMessage request) - { - Request = request ?? throw new ArgumentNullException(nameof(request), "Request can't be null."); - Response = null; - } + Request = request ?? throw new ArgumentNullException(nameof(request), "Request can't be null."); + Response = null; } - internal byte getTransactionCounter(UID uid) + } + internal byte getTransactionCounter(UID uid) + { + if (transactionCounters.TryGetValue(uid, out byte tc)) { - if (transactionCounters.TryGetValue(uid, out byte tc)) - { - tc++; - transactionCounters.AddOrUpdate(uid, (a) => tc, (b, c) => tc); - return tc; - } - else + tc++; + transactionCounters.AddOrUpdate(uid, (a) => tc, (b, c) => tc); + return tc; + } + else + { + transactionCounters.TryAdd(uid, 0); + return 0; + } + } + internal Task lockTransaktion(UID uid, TimeSpan? timeout = null) + { + if (!transactionLock.TryGetValue(uid, out SemaphoreSlim semaphore)) + { + semaphore = new SemaphoreSlim(1); + transactionLock.TryAdd(uid, semaphore); + } + + if (timeout.HasValue) + try { - transactionCounters.TryAdd(uid, 0); - return 0; + return semaphore.WaitAsync(timeout.Value); } + catch (TimeoutException) { }// Ignore Exception + else + return semaphore.WaitAsync(); + + return Task.CompletedTask; + } + internal void unlockTransaktion(UID uid) + { + if (transactionLock.TryGetValue(uid, out SemaphoreSlim? semaphore)) + { + semaphore.Release(); } } + + internal void AddRemoteDeviceToCache(AbstractRemoteRDMDevice abstractRemoteRDMDevice) + { + remoteDeviceCache.Add(abstractRemoteRDMDevice); + } + public bool TryGetRemoteDeviceFromCache(UID uid, SubDevice subDevice, out AbstractRemoteRDMDevice abstractRemoteRDMDevice) + { + abstractRemoteRDMDevice = null; + try + { + abstractRemoteRDMDevice = remoteDeviceCache.Where(rd => rd.UID.Equals(uid)).Where(rd => rd.Subdevice.Equals(subDevice)).FirstOrDefault(rd => !(rd.IsDisposed || rd.IsDisposing)); + } + catch { return false; } + return abstractRemoteRDMDevice is not null; + } } \ No newline at end of file diff --git a/RDMSharp/RDMSharp.csproj b/RDMSharp/RDMSharp.csproj index 3422b478..42f3d80d 100644 --- a/RDMSharp/RDMSharp.csproj +++ b/RDMSharp/RDMSharp.csproj @@ -1,7 +1,9 @@ - + - net6.0;net7.0;net8.0;net9.0 + net6.0;net7.0;net8.0;net9.0;net10.0 LICENSE.md + CC BY-NC 4.0 + https://creativecommons.org/licenses/by-nc/4.0/legalcode 0.0.14 https://github.com/DMXControl/RDMSharp $(RepositoryUrl) @@ -11,6 +13,7 @@ Icons\RDMSharp.ico This library abstracts the communication using RDM in C# and takes a lot of work off the developer, as well as enables a standardized use of RDM in C# DMXControl-Projects e.V. + DMXControl-Projects e.V. Patrick Grote $(AssemblyName) latest @@ -31,12 +34,12 @@ - - + + - - - + + + @@ -46,6 +49,8 @@ + + diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CAPTURE_PRESET.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CAPTURE_PRESET.json index 3f6854ef..45d33224 100644 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CAPTURE_PRESET.json +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CAPTURE_PRESET.json @@ -9,9 +9,7 @@ "set_request": [ { "name": "scene_num", - "type": "uint16", - "units": 21, - "prefixPower": -1 + "type": "uint16" }, { "name": "up_fade_time", diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CONTROLLER_FLAG_SUPPORT.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CONTROLLER_FLAG_SUPPORT.json new file mode 100644 index 00000000..b2c2239e --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CONTROLLER_FLAG_SUPPORT.json @@ -0,0 +1,26 @@ +{ + "name": "CONTROLLER_FLAG_SUPPORT", + "displayName": "Controller Flag Support", + "manufacturer_id": 0, + "pid": 86, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [], + "get_response": [ + { + "name": "controller_flags", + "type": "bitField", + "size": 8, + "bits": [ + { + "name": "unicode", + "index": 0 + }, + { + "name": "hi_res_ack_timer_support", + "index": 1 + } + ] + } + ] +} \ No newline at end of file diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/ENUM_LABEL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/ENUM_LABEL.json new file mode 100644 index 00000000..5d0c9d1b --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/ENUM_LABEL.json @@ -0,0 +1,37 @@ +{ + "name": "ENUM_LABEL", + "displayName": "Enum Label", + "manufacturer_id": 0, + "pid": 90, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "pid", + "type": "uint16" + }, + { + "name": "enum_index", + "type": "uint32" + } + ], + "get_response": [ + { + "name": "pid", + "type": "uint16" + }, + { + "name": "enum_index", + "type": "uint32" + }, + { + "name": "enum_index_maximum", + "type": "uint32" + }, + { + "name": "description", + "type": "string", + "maxLength": 32 + } + ] +} \ No newline at end of file diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/NACK_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/NACK_DESCRIPTION.json new file mode 100644 index 00000000..c147b33c --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/NACK_DESCRIPTION.json @@ -0,0 +1,25 @@ +{ + "name": "NACK_DESCRIPTION", + "displayName": "NACK Description", + "manufacturer_id": 0, + "pid": 87, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "nack_reason_number", + "type": "uint16" + } + ], + "get_response": [ + { + "name": "nack_reason_number", + "type": "uint16" + }, + { + "name": "description", + "type": "string", + "maxLength": 32 + } + ] +} \ No newline at end of file diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_INDEX.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_INDEX.json new file mode 100644 index 00000000..cdd3d25a --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_INDEX.json @@ -0,0 +1,51 @@ +{ + "name": "PACKED_PID_INDEX", + "displayName": "Packed PID Index", + "manufacturer_id": 0, + "pid": 89, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "pid", + "type": "uint16", + "notes": "Some PIDs are disallowed from being packed. See \"Table A-3: RDM Categories/Parameter ID Defines\" of the ANSI E1.20-202x specification." + }, + { + "name": "first_item", + "type": "uint16" + }, + { + "name": "item_count", + "type": "uint16", + "labels": [ + { + "name": "All Data", + "value": 65535 + } + ] + } + ], + "get_response": [ + { + "name": "pid", + "type": "uint16" + }, + { + "name": "first_item", + "type": "uint16" + }, + { + "name": "entry_count", + "type": "uint8" + }, + { + "name": "entries", + "type": "list", + "itemType": { "type": "pdEnvelope" } + } + ], + "set_request_subdevice_range": [ "root", "subdevices" ], + "set_request": "get_response", + "set_response": [] +} \ No newline at end of file diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_SUB.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_SUB.json new file mode 100644 index 00000000..c7183b16 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_SUB.json @@ -0,0 +1,85 @@ +{ + "name": "PACKED_PID_SUB", + "displayName": "Packed PID Sub", + "manufacturer_id": 0, + "pid": 88, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "pid", + "type": "uint16", + "notes": "Some PIDs are disallowed from being packed. See \"Table A-3: RDM Categories/Parameter ID Defines\" of the ANSI E1.20-202x specification." + }, + { + "name": "index", + "type": "uint16" + }, + { + "name": "first_subdevice", + "type": "uint16", + "ranges": [ + { + "minimum": 0, + "maximum": 65520 + } + ] + }, + { + "name": "subdevice_count", + "type": "uint16", + "ranges": [ + { + "minimum": 1, + "maximum": 65520 + }, + { + "minimum": 65535, + "maximum": 65535 + } + ], + "labels": [ + { + "name": "All Subdevices", + "value": 65535 + } + ] + } + ], + "get_response": [ + { + "name": "pid", + "type": "uint16" + }, + { + "name": "index", + "type": "uint16" + }, + { + "name": "entries", + "type": "list", + "itemType": { + "type": "compound", + "subtypes": [ + { + "name": "subdevice", + "type": "uint16", + "ranges": [ + { + "minimum": 0, + "maximum": 65520 + } + ] + }, + { + "name": "subdevice_entry", + "type": "pdEnvelope" + } + ] + } + } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": "get_response", + "set_response": [] +} \ No newline at end of file diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json new file mode 100644 index 00000000..10ed8ebe --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json @@ -0,0 +1,19 @@ +{ + "name": "QUEUED_MESSAGE_SENSOR_SUBSCRIBE", + "displayName": "Queued Message Sensor Subscribe", + "manufacturer_id": 0, + "pid": 52, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "sensor_numbers", + "type": "list", + "itemType": { + "name": "sensor_number", + "type": "uint8" + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/REAL_TIME_CLOCK.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/REAL_TIME_CLOCK.json index 15feb96e..4fae45bb 100644 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/REAL_TIME_CLOCK.json +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/REAL_TIME_CLOCK.json @@ -1,6 +1,6 @@ { "name": "REAL_TIME_CLOCK", - "displayName": "Real TIme Clock", + "displayName": "Real Time Clock", "manufacturer_id": 0, "pid": 1539, "version": 1, diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SELFTEST_ENHANCED.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SELFTEST_ENHANCED.json new file mode 100644 index 00000000..65bd90ce --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SELFTEST_ENHANCED.json @@ -0,0 +1,68 @@ +{ + "name": "SELFTEST_ENHANCED", + "displayName": "Selftest Enhanced", + "manufacturer_id": 0, + "pid": 4130, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "pid", + "notes": "A Responder may declare a Manufacturer-specific PID value that provides enumeration of the Manufacturer-specific Result Codes. This field shall contain the Value of that PID", + "type": "uint16" + }, + { + "name": "pids", + "type": "list", + "itemType": { + "type": "compound", + "subtypes": [ + { + "name": "self_test_num", + "type": "uint8" + }, + { + "name": "self_test_status", + "type": "uint8" + }, + { + "name": "self_test_capability", + "type": "bitField", + "size": 16, + "bits": [ + { + "name": "auto_termitates", + "index": 0 + }, + { + "name": "dmx512_start_code_operation_restricted", + "index": 1 + }, + { + "name": "rdm_operation_restricted", + "index": 2 + }, + { + "name": "self_test_all_ignores_individual_test_auto_terminate_flag", + "index": 3 + }, + { + "name": "manufacturer_specific_result_codes_available", + "index": 4 + }, + { + "name": "status_messages_generated", + "index": 5 + } + ] + }, + { + "name": "result_code", + "type": "uint16" + } + ] + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_DEFINITION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_DEFINITION.json index 3ecac352..2bb7de0a 100644 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_DEFINITION.json +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_DEFINITION.json @@ -455,4 +455,4 @@ "maxLength": 32 } ] -} +} \ No newline at end of file diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS_ENHANCED.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS_ENHANCED.json new file mode 100644 index 00000000..c42d09fd --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS_ENHANCED.json @@ -0,0 +1,55 @@ +{ + "name": "SUPPORTED_PARAMETERS_ENHANCED", + "displayName": "Supported Parameters Enhanced", + "manufacturer_id": 0, + "pid": 85, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "pids", + "type": "list", + "itemType": { + "type": "compound", + "subtypes": [ + { + "name": "pid", + "type": "uint16" + }, + { + "name": "pid_support", + "type": "bitField", + "size": 16, + "bits": [ + { + "name": "get_supported", + "index": 0 + }, + { + "name": "set_supported", + "index": 1 + }, + { + "name": "packed_pid_sub_get_supported", + "index": 2 + }, + { + "name": "packed_pid_sub_set_supported", + "index": 3 + }, + { + "name": "packed_pid_index_get_supported", + "index": 4 + }, + { + "name": "packed_pid_index_set_supported", + "index": 5 + } + ] + } + ] + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CHECK_TAG.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CHECK_TAG.json index cb1e97ab..f0c50a9f 100644 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CHECK_TAG.json +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CHECK_TAG.json @@ -4,15 +4,15 @@ "manufacturer_id": 0, "pid": 1620, "version": 1, - "set_request_subdevice_range": [ "root", "subdevices" ], - "set_request": [ + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ { "name": "tag", "type": "string", "maxLength": 32 } ], - "set_response": [ + "get_response": [ { "name": "status", "type": "boolean", diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/LIST_TAGS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/LIST_TAGS.json index 9f718d25..fe49f26c 100644 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/LIST_TAGS.json +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/LIST_TAGS.json @@ -10,6 +10,7 @@ { "name": "tags", "type": "bytes", + "format": "string[]", "notes": "NUL-delimited." } ] diff --git a/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs b/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs index 88aea7b0..ec141093 100644 --- a/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs +++ b/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs @@ -1,78 +1,47 @@ -namespace RDMSharpTests.Devices.Mock -{ - internal abstract class AbstractMockGeneratedDevice : AbstractGeneratedRDMDevice - { +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +namespace RDMSharpTests.Devices.Mock; - public new string SoftwareVersionLabel - { - get - { - return base.SoftwareVersionLabel; - } - internal set - { - base.SoftwareVersionLabel = value; - } - } +internal abstract class AbstractMockGeneratedDevice : AbstractGeneratedRDMDevice +{ + public AbstractMockGeneratedDevice(UID uid, IRDMDevice[]? subDevices = null, IReadOnlyCollection mudules = null) : base(uid, subDevices: subDevices, modules: mudules) + { + } + public AbstractMockGeneratedDevice(UID uid, SubDevice subDevice, IReadOnlyCollection mudules = null) : base(uid, subDevice, modules: mudules) + { + } + internal RDMMessage? ProcessRequestMessage_Internal(RDMMessage request) + { + return base.processRequestMessage(request); + } - public new string BootSoftwareVersionLabel - { - get - { - return base.BootSoftwareVersionLabel; - } - internal set - { - base.BootSoftwareVersionLabel = value; - } - } - public AbstractMockGeneratedDevice(UID uid, ERDM_Parameter[] parameters, string manufacturer, Sensor[]? sensors = null, IRDMDevice[]? subDevices = null) : base(uid, parameters, manufacturer, sensors: sensors, subDevices: subDevices) - { - } - public AbstractMockGeneratedDevice(UID uid, SubDevice subDevice, ERDM_Parameter[] parameters, string manufacturer, Sensor[]? sensors = null) : base(uid, subDevice, parameters, manufacturer, sensors: sensors) - { - } - internal RDMMessage? ProcessRequestMessage_Internal(RDMMessage request) - { - return base.processRequestMessage(request); - } + internal void AddStatusMessage(RDMStatusMessage statusMessage) + { + base.statusMessageModule?.AddStatusMessage(statusMessage); + } + internal void ClearStatusMessage(RDMStatusMessage statusMessage) + { + base.statusMessageModule?.ClearStatusMessage(statusMessage); + } + internal void RemoveStatusMessage(RDMStatusMessage statusMessage) + { + base.statusMessageModule?.RemoveStatusMessage(statusMessage); + } - internal new void AddStatusMessage(RDMStatusMessage statusMessage) - { - base.AddStatusMessage(statusMessage); - } - internal new void ClearStatusMessage(RDMStatusMessage statusMessage) - { - base.ClearStatusMessage(statusMessage); - } - internal new void RemoveStatusMessage(RDMStatusMessage statusMessage) - { - base.RemoveStatusMessage(statusMessage); - } - internal new void AddSensors(params Sensor[] sensor) - { - base.AddSensors(sensor); - } - internal new void RemoveSensors(params Sensor[] sensor) + protected sealed override void onDispose() + { + try { - base.RemoveSensors(sensor); + OnDispose(); } - - protected sealed override void onDispose() + catch (Exception e) { - try - { - OnDispose(); - } - catch (Exception e) - { - Logger?.LogError(e); - } + Logger?.LogError(e); } + } #pragma warning disable CS0114 - protected abstract void OnDispose(); + protected abstract void OnDispose(); #pragma warning restore CS0114 - } } diff --git a/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs b/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs index 0516fae9..6953704f 100644 --- a/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs +++ b/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs @@ -1,134 +1,142 @@ -namespace RDMSharpTests.Devices.Mock +using RDMSharp.RDM.Device.Module; + +namespace RDMSharpTests.Devices.Mock; + +internal class MockGeneratedDevice1 : AbstractMockGeneratedDevice { - internal class MockGeneratedDevice1 : AbstractMockGeneratedDevice + public override EManufacturer ManufacturerID { - public override EManufacturer ManufacturerID + get { - get - { - return (EManufacturer)UID.ManufacturerID; - } + return (EManufacturer)UID.ManufacturerID; } - public override ushort DeviceModelID => 20; - public override ERDM_ProductCategoryCoarse ProductCategoryCoarse => ERDM_ProductCategoryCoarse.CONTROL; - public override ERDM_ProductCategoryFine ProductCategoryFine => ERDM_ProductCategoryFine.DATA_CONVERSION; - public override uint SoftwareVersionID => 0x1234; - public override string DeviceModelDescription => "Test Model Description"; - public override bool SupportDMXAddress => true; + } + public override ushort DeviceModelID => 20; + public override ERDM_ProductCategoryCoarse ProductCategoryCoarse => ERDM_ProductCategoryCoarse.CONTROL; + public override ERDM_ProductCategoryFine ProductCategoryFine => ERDM_ProductCategoryFine.DATA_CONVERSION; - private static readonly GeneratedPersonality[] PERSONALITYS = new GeneratedPersonality[] { - new GeneratedPersonality(1, "5CH RGB", - new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer" ), - new Slot(1, ERDM_SlotCategory.STROBE, "Strobe" , 33), - new Slot(2, ERDM_SlotCategory.COLOR_ADD_RED, "Red" ), - new Slot(3, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green" ), - new Slot(4, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue" )), - new GeneratedPersonality(2, "8CH RGBAWY", - new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer" ), - new Slot(1, ERDM_SlotCategory.STROBE, "Strobe" , 33), - new Slot(2, ERDM_SlotCategory.COLOR_ADD_RED, "Red" ), - new Slot(3, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green" ), - new Slot(4, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue" ), - new Slot(5, ERDM_SlotCategory.COLOR_CORRECTION, "Amber" ), - new Slot(6, ERDM_SlotCategory.COLOR_CORRECTION, "White" ), - new Slot(7, ERDM_SlotCategory.COLOR_CORRECTION, "Yellow" )), - new GeneratedPersonality(3, "9CH RGB 16-Bit", - new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer" ), - new Slot(1, ERDM_SlotCategory.INTENSITY,ERDM_SlotType.SEC_FINE, "Dimmer Fine"), - new Slot(2, ERDM_SlotCategory.STROBE, "Strobe" , 33), - new Slot(3, ERDM_SlotCategory.COLOR_ADD_RED, "Red" ), - new Slot(4, ERDM_SlotCategory.COLOR_ADD_RED, ERDM_SlotType.SEC_FINE,"Red Fine"), - new Slot(5, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green" ), - new Slot(6, ERDM_SlotCategory.COLOR_ADD_GREEN, ERDM_SlotType.SEC_FINE,"Green Fine"), - new Slot(7, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue" ), - new Slot(8, ERDM_SlotCategory.COLOR_ADD_BLUE,ERDM_SlotType.SEC_FINE, "Blue Fine" )) }; + private static readonly GeneratedPersonality[] PERSONALITYS = new GeneratedPersonality[] { + new GeneratedPersonality(1, "5CH RGB", + new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer" ), + new Slot(1, ERDM_SlotCategory.STROBE, "Strobe" , 33), + new Slot(2, ERDM_SlotCategory.COLOR_ADD_RED, "Red" ), + new Slot(3, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green" ), + new Slot(4, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue" )), + new GeneratedPersonality(2, "8CH RGBAWY", + new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer" ), + new Slot(1, ERDM_SlotCategory.STROBE, "Strobe" , 33), + new Slot(2, ERDM_SlotCategory.COLOR_ADD_RED, "Red" ), + new Slot(3, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green" ), + new Slot(4, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue" ), + new Slot(5, ERDM_SlotCategory.COLOR_CORRECTION, "Amber" ), + new Slot(6, ERDM_SlotCategory.COLOR_CORRECTION, "White" ), + new Slot(7, ERDM_SlotCategory.COLOR_CORRECTION, "Yellow" )), + new GeneratedPersonality(3, "9CH RGB 16-Bit", + new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer" ), + new Slot(1, ERDM_SlotCategory.INTENSITY,ERDM_SlotType.SEC_FINE, "Dimmer Fine"), + new Slot(2, ERDM_SlotCategory.STROBE, "Strobe" , 33), + new Slot(3, ERDM_SlotCategory.COLOR_ADD_RED, "Red" ), + new Slot(4, ERDM_SlotCategory.COLOR_ADD_RED, ERDM_SlotType.SEC_FINE,"Red Fine"), + new Slot(5, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green" ), + new Slot(6, ERDM_SlotCategory.COLOR_ADD_GREEN, ERDM_SlotType.SEC_FINE,"Green Fine"), + new Slot(7, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue" ), + new Slot(8, ERDM_SlotCategory.COLOR_ADD_BLUE,ERDM_SlotType.SEC_FINE, "Blue Fine" )) }; - private static Sensor[] GetSensors() { - return new Sensor[] { - new MockSensorTemp(0, 1, 3000), - new MockSensorTemp(1, 2, 8000), - new MockSensorTemp(2, 3, 12000), - new MockSensorVolt3_3(3, 331), - new MockSensorVolt5(4, 498) }; - } - public override GeneratedPersonality[] Personalities => PERSONALITYS; + private static Sensor[] GetSensors() + { + return new Sensor[] { + new MockSensorTemp(0, 1, 3000), + new MockSensorTemp(1, 2, 8000), + new MockSensorTemp(2, 3, 12000), + new MockSensorVolt3_3(3, 331), + new MockSensorVolt5(4, 498) }; + } - public override bool SupportQueued => true; + public override bool SupportQueued => true; - public override bool SupportStatus => true; - - public MockGeneratedDevice1(UID uid) : base(uid, SubDevice.Root, new ERDM_Parameter[] { ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL }, "Dummy Manufacturer 9FFF", GetSensors()) - { - this.DeviceLabel = "Dummy Device 1"; - this.SoftwareVersionLabel = $"Dummy Software"; - this.BootSoftwareVersionLabel = $"Dummy Bootloader Software"; - } - protected sealed override void OnDispose() - { - } + public MockGeneratedDevice1(UID uid, IReadOnlyCollection modules = null) : base(uid, SubDevice.Root, GetModules().Concat(modules ?? Array.Empty()).ToList().AsReadOnly()) + { + } + private static IReadOnlyCollection GetModules() + { + return new IModule[] { + new DeviceLabelModule("Dummy Device 1"), + new ManufacturerLabelModule("Dummy Manufacturer 9FFF"), + new DeviceModelDescriptionModule("Test Model Description"), + new SoftwareVersionModule(1234, $"Dummy Software"), + new BootSoftwareVersionModule(123, $"Dummy Bootloader Software"), + new DMX_StartAddressModule(1), + new DMX_PersonalityModule(1,PERSONALITYS), + new SlotsModule(), + new SensorsModule(GetSensors()), + new StatusMessagesModule() + }; + } + protected sealed override void OnDispose() + { + } - private class MockSensorTemp : MockGeneratedSensor - { - public MockSensorTemp(in byte sensorId, in byte number, in short initValue) : base(sensorId, initValue, ERDM_SensorType.TEMPERATURE, ERDM_SensorUnit.CENTIGRADE, ERDM_UnitPrefix.CENTI, $"Mock Temp. {number}", -2000, 10000, 2000, 5000, true, true) - { - } - } - private class MockSensorVolt3_3 : MockGeneratedSensor - { - public MockSensorVolt3_3(in byte sensorId, in short initValue) : base(sensorId, initValue, ERDM_SensorType.VOLTAGE, ERDM_SensorUnit.VOLTS_DC, ERDM_UnitPrefix.CENTI, $"Mock 3.3V Rail", -200, 500, 330, 360, true, true) - { - } - } - private class MockSensorVolt5 : MockGeneratedSensor + private class MockSensorTemp : MockGeneratedSensor + { + public MockSensorTemp(in byte sensorId, in byte number, in short initValue) : base(sensorId, initValue, ERDM_SensorType.TEMPERATURE, ERDM_SensorUnit.CENTIGRADE, ERDM_UnitPrefix.CENTI, $"Mock Temp. {number}", -2000, 10000, 2000, 5000, true, true) { - public MockSensorVolt5(in byte sensorId, in short initValue) : base(sensorId, initValue, ERDM_SensorType.VOLTAGE, ERDM_SensorUnit.VOLTS_DC, ERDM_UnitPrefix.CENTI, $"Mock 5V Rail ", -200, 1000, 470, 530, true, true) - { - } } } - public class MockGeneratedSensor : Sensor + private class MockSensorVolt3_3 : MockGeneratedSensor { - protected MockGeneratedSensor(in byte sensorId, - in short initValue, - in ERDM_SensorType type, - in ERDM_SensorUnit unit, - in ERDM_UnitPrefix prefix, - in string description, - in short rangeMinimum, - in short rangeMaximum, - in short normalMinimum, - in short normalMaximum, - in bool lowestHighestValueSupported = false, - in bool recordedValueSupported = false) : base( - sensorId, - initValue, - type, - unit, - prefix, - description, - rangeMinimum, - rangeMaximum, - normalMinimum, - normalMaximum, - lowestHighestValueSupported, - recordedValueSupported) + public MockSensorVolt3_3(in byte sensorId, in short initValue) : base(sensorId, initValue, ERDM_SensorType.VOLTAGE, ERDM_SensorUnit.VOLTS_DC, ERDM_UnitPrefix.CENTI, $"Mock 3.3V Rail", -200, 500, 330, 360, true, true) { } - - public new void UpdateValue(short value) + } + private class MockSensorVolt5 : MockGeneratedSensor + { + public MockSensorVolt5(in byte sensorId, in short initValue) : base(sensorId, initValue, ERDM_SensorType.VOLTAGE, ERDM_SensorUnit.VOLTS_DC, ERDM_UnitPrefix.CENTI, $"Mock 5V Rail ", -200, 1000, 470, 530, true, true) { - base.UpdateValue(value); } + } +} +public class MockGeneratedSensor : Sensor +{ + protected MockGeneratedSensor(in byte sensorId, + in short initValue, + in ERDM_SensorType type, + in ERDM_SensorUnit unit, + in ERDM_UnitPrefix prefix, + in string description, + in short rangeMinimum, + in short rangeMaximum, + in short normalMinimum, + in short normalMaximum, + in bool lowestHighestValueSupported = false, + in bool recordedValueSupported = false) : base( + sensorId, + initValue, + type, + unit, + prefix, + description, + rangeMinimum, + rangeMaximum, + normalMinimum, + normalMaximum, + lowestHighestValueSupported, + recordedValueSupported) + { + } - public new void RecordValue() - { - base.RecordValue(); - } + public new void UpdateValue(short value) + { + base.UpdateValue(value); + } - public new void ResetValues() - { - base.ResetValues(); - } + public new void RecordValue() + { + base.RecordValue(); + } + public new void ResetValues() + { + base.ResetValues(); } + } \ No newline at end of file diff --git a/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs b/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs index 67f60ada..c0affb72 100644 --- a/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs +++ b/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs @@ -1,103 +1,117 @@ -namespace RDMSharpTests.Devices.Mock -{ - internal abstract class MockGeneratedDeviceWithSubDevice1 : AbstractMockGeneratedDevice - { - public override EManufacturer ManufacturerID => (EManufacturer)UID.ManufacturerID; - public override ushort DeviceModelID => 50; - public override ERDM_ProductCategoryCoarse ProductCategoryCoarse => ERDM_ProductCategoryCoarse.DIMMER; - public override ERDM_ProductCategoryFine ProductCategoryFine => ERDM_ProductCategoryFine.DIMMER_CS_LED; - public override uint SoftwareVersionID => 0x3234; - public override string DeviceModelDescription => "Test Model Description SubDevice"; - public override bool SupportDMXAddress => true; +using RDMSharp.RDM.Device.Module; - protected MockGeneratedDeviceWithSubDevice1(UID uid, MockGeneratedDeviceWithSubDeviceSub1[]? subDevices = null, Sensor[]? sensors = null) : base(uid, new ERDM_Parameter[] { ERDM_Parameter.IDENTIFY_DEVICE, ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL }, "Dummy Manufacturer 9FEF", sensors, subDevices) - { - this.DeviceLabel = "Dummy Device Master"; - this.setInitParameters(); - } - protected MockGeneratedDeviceWithSubDevice1(UID uid, SubDevice subDevice, Sensor[]? sensors = null) : base(uid, subDevice, new ERDM_Parameter[] { ERDM_Parameter.IDENTIFY_DEVICE, ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL }, "Dummy Manufacturer 9FEF", sensors) - { - this.DeviceLabel = "Dummy Device SubDevice"; - this.setInitParameters(); - } - private void setInitParameters() - { - this.trySetParameter(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL, $"Dummy Software"); - } +namespace RDMSharpTests.Devices.Mock; - +internal abstract class MockGeneratedDeviceWithSubDevice1 : AbstractMockGeneratedDevice +{ + public override EManufacturer ManufacturerID => (EManufacturer)UID.ManufacturerID; + public override ushort DeviceModelID => 50; + public override ERDM_ProductCategoryCoarse ProductCategoryCoarse => ERDM_ProductCategoryCoarse.DIMMER; + public override ERDM_ProductCategoryFine ProductCategoryFine => ERDM_ProductCategoryFine.DIMMER_CS_LED; - protected sealed override void OnDispose() - { - } + protected MockGeneratedDeviceWithSubDevice1(UID uid, MockGeneratedDeviceWithSubDeviceSub1[]? subDevices = null, IReadOnlyCollection modules = null) : base(uid, subDevices, modules) + { } - internal sealed class MockGeneratedDeviceWithSubDeviceMaster1 : MockGeneratedDeviceWithSubDevice1 + protected MockGeneratedDeviceWithSubDevice1(UID uid, SubDevice subDevice, IReadOnlyCollection modules = null) : base(uid, subDevice, modules) { - private static readonly GeneratedPersonality[] PERSONALITYS = new GeneratedPersonality[] { - new GeneratedPersonality(1, "1CH", - new Slot(0, ERDM_SlotCategory.INTENSITY_MASTER, "Master" ))}; + } - private static readonly Sensor[] SENSORS = new Sensor[] { - new MockSensorTemp(0, 1, 3000)}; - public override GeneratedPersonality[] Personalities => PERSONALITYS; - public override bool SupportQueued => true; - public override bool SupportStatus => true; + protected sealed override void OnDispose() + { + } +} +internal sealed class MockGeneratedDeviceWithSubDeviceMaster1 : MockGeneratedDeviceWithSubDevice1 +{ + private static readonly GeneratedPersonality[] PERSONALITYS = new GeneratedPersonality[] { + new GeneratedPersonality(1, "1CH", + new Slot(0, ERDM_SlotCategory.INTENSITY_MASTER, "Master" ))}; - public MockGeneratedDeviceWithSubDeviceMaster1(UID uid, ushort subDevicesCount) : base(uid, getSubDevices(uid, subDevicesCount), SENSORS) - { - } + private static readonly Sensor[] SENSORS = new Sensor[] { + new MockSensorTemp(0, 1, 3000)}; - private static MockGeneratedDeviceWithSubDeviceSub1[] getSubDevices(UID uid, ushort count) - { - var subDevice = new MockGeneratedDeviceWithSubDeviceSub1[count]; - for (ushort i = 0; i < count; i++) - subDevice[i] = new MockGeneratedDeviceWithSubDeviceSub1(uid, (ushort)(i + 1)); - return subDevice; - } - private class MockSensorTemp : Sensor - { - public MockSensorTemp(in byte sensorId, byte number, short initValue) : base(sensorId, ERDM_SensorType.TEMPERATURE, ERDM_SensorUnit.CENTIGRADE, ERDM_UnitPrefix.CENTI, $"Mock Ambient Temp. {number}", -2000, 10000, 2000, 5000, true, true) - { - UpdateValue(initValue); - } - } + public override bool SupportQueued => true; + + public MockGeneratedDeviceWithSubDeviceMaster1(UID uid, ushort subDevicesCount) : base(uid, getSubDevices(uid, subDevicesCount), GetModulesMaster()) + { } - internal sealed class MockGeneratedDeviceWithSubDeviceSub1 : MockGeneratedDeviceWithSubDevice1 + private static IReadOnlyCollection GetModulesMaster() { - private static readonly GeneratedPersonality[] PERSONALITYS = new GeneratedPersonality[] { - new GeneratedPersonality(1, "1CH", - new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer" ))}; + return new IModule[] { + new DeviceLabelModule("Dummy Device Master"), + new ManufacturerLabelModule("Dummy Manufacturer 9FEF"), + new DeviceModelDescriptionModule("Test Model Description Master"), + new SoftwareVersionModule(0x3234, $"Dummy Software"), + new BootSoftwareVersionModule(12359,$"Dummy Software"), + new DMX_StartAddressModule(1), + new DMX_PersonalityModule(1,PERSONALITYS), + new SlotsModule(), + new SensorsModule(SENSORS), + new StatusMessagesModule() + }; + } - private static readonly Sensor[] SENSORS = new Sensor[] { - new MockSensorTemp(0, 1, 3000)}; + private static MockGeneratedDeviceWithSubDeviceSub1[] getSubDevices(UID uid, ushort count) + { + var subDevice = new MockGeneratedDeviceWithSubDeviceSub1[count]; + for (ushort i = 0; i < count; i++) + subDevice[i] = new MockGeneratedDeviceWithSubDeviceSub1(uid, (ushort)(i + 1)); + return subDevice; + } + private class MockSensorTemp : Sensor + { + public MockSensorTemp(in byte sensorId, byte number, short initValue) : base(sensorId, ERDM_SensorType.TEMPERATURE, ERDM_SensorUnit.CENTIGRADE, ERDM_UnitPrefix.CENTI, $"Mock Ambient Temp. {number}", -2000, 10000, 2000, 5000, true, true) + { + UpdateValue(initValue); + } + } +} +internal sealed class MockGeneratedDeviceWithSubDeviceSub1 : MockGeneratedDeviceWithSubDevice1 +{ + private static readonly GeneratedPersonality[] PERSONALITYS = new GeneratedPersonality[] { + new GeneratedPersonality(1, "1CH", + new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer" ))}; - public override GeneratedPersonality[] Personalities => PERSONALITYS; + private static readonly Sensor[] SENSORS = new Sensor[] { + new MockSensorTemp(0, 1, 3000)}; - public override bool SupportQueued => true; - public override bool SupportStatus => true; + public override bool SupportQueued => true; - public MockGeneratedDeviceWithSubDeviceSub1(UID uid, ushort subDeviceID) : base(uid, getSubDevice(subDeviceID), SENSORS) - { - } - private static SubDevice getSubDevice(ushort subDeviceID) - { - var subDevice = new SubDevice(subDeviceID); - if (subDevice == SubDevice.Root) - throw new ArgumentException("SubDeviceID must not be Root", nameof(subDeviceID)); - if (subDevice == SubDevice.Broadcast) - throw new ArgumentException("SubDeviceID must not be Broadcast", nameof(subDeviceID)); + public MockGeneratedDeviceWithSubDeviceSub1(UID uid, ushort subDeviceID) : base(uid, getSubDevice(subDeviceID), GetModulesSubDevice()) + { + } + private static IReadOnlyCollection GetModulesSubDevice() + { + return new IModule[] { + new DeviceLabelModule("Dummy Device SubDevice"), + new ManufacturerLabelModule("Dummy Manufacturer 9FEF"), + new DeviceModelDescriptionModule("Test Model Description SubDevice"), + new SoftwareVersionModule(0x3234, $"Dummy Software"), + new BootSoftwareVersionModule(12359,$"Dummy Software"), + new DMX_StartAddressModule(1), + new DMX_PersonalityModule(1,PERSONALITYS), + new SlotsModule(), + new SensorsModule(SENSORS), + new StatusMessagesModule() + }; + } + private static SubDevice getSubDevice(ushort subDeviceID) + { + var subDevice = new SubDevice(subDeviceID); + if (subDevice == SubDevice.Root) + throw new ArgumentException("SubDeviceID must not be Root", nameof(subDeviceID)); + if (subDevice == SubDevice.Broadcast) + throw new ArgumentException("SubDeviceID must not be Broadcast", nameof(subDeviceID)); - return subDevice; - } - private class MockSensorTemp : Sensor + return subDevice; + } + private class MockSensorTemp : Sensor + { + public MockSensorTemp(in byte sensorId, byte number, short initValue) : base(sensorId, ERDM_SensorType.TEMPERATURE, ERDM_SensorUnit.CENTIGRADE, ERDM_UnitPrefix.CENTI, $"Mock Channel Temp. {number}", -2000, 10000, 2000, 5000, true, true) { - public MockSensorTemp(in byte sensorId, byte number, short initValue) : base(sensorId, ERDM_SensorType.TEMPERATURE, ERDM_SensorUnit.CENTIGRADE, ERDM_UnitPrefix.CENTI, $"Mock Channel Temp. {number}", -2000, 10000, 2000, 5000, true, true) - { - UpdateValue(initValue); - } + UpdateValue(initValue); } } } \ No newline at end of file diff --git a/RDMSharpTests/Devices/Mock/MockGeneratedDevice_SlotOverflow.cs b/RDMSharpTests/Devices/Mock/MockGeneratedDevice_SlotOverflow.cs index e862d7a4..cacc59d6 100644 --- a/RDMSharpTests/Devices/Mock/MockGeneratedDevice_SlotOverflow.cs +++ b/RDMSharpTests/Devices/Mock/MockGeneratedDevice_SlotOverflow.cs @@ -1,93 +1,94 @@ using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; -namespace RDMSharpTests.Devices.Mock +namespace RDMSharpTests.Devices.Mock; + +internal class MockGeneratedDevice_SlotOverflow : AbstractMockGeneratedDevice { - internal class MockGeneratedDevice_SlotOverflow : AbstractMockGeneratedDevice + public override EManufacturer ManufacturerID { - public override EManufacturer ManufacturerID + get { - get - { - return (EManufacturer)UID.ManufacturerID; - } + return (EManufacturer)UID.ManufacturerID; } - public override ushort DeviceModelID => 20; - public override ERDM_ProductCategoryCoarse ProductCategoryCoarse => ERDM_ProductCategoryCoarse.CONTROL; - public override ERDM_ProductCategoryFine ProductCategoryFine => ERDM_ProductCategoryFine.DATA_CONVERSION; - public override uint SoftwareVersionID => 0x1234; - public override string DeviceModelDescription => "Test Model Description"; - public override bool SupportDMXAddress => true; - - private static byte[] SLOT_INFO_RAW = new byte[] { - 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, 0x00, - 0x03, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x05, - 0x03, 0x00, 0x05, 0x00, 0x05, 0x02, 0x00, 0x06, - 0x00, 0x91, 0x00, 0x00, 0x07, 0x00, 0x91, 0x01, - 0x00, 0x08, 0x00, 0x05, 0x02, 0x00, 0x09, 0x00, - 0x02, 0x01, 0x00, 0x0a, 0x01, 0x00, 0x09, 0x00, - 0x0b, 0x00, 0x02, 0x01, 0x00, 0x0c, 0x01, 0x00, - 0x0b, 0x00, 0x0d, 0x00, 0x02, 0x02, 0x00, 0x0e, - 0x00, 0x02, 0x04, 0x00, 0x0f, 0x00, 0x02, 0x03, - 0x00, 0x10, 0x00, 0x02, 0x08, 0x00, 0x11, 0x00, - 0x02, 0x08, 0x00, 0x12, 0x00, 0x05, 0x04, 0x00, - 0x13, 0x00, 0x05, 0x03, 0x00, 0x14, 0x00, 0xff, - 0xff, 0x00, 0x15, 0x00, 0xff, 0xff, 0x00, 0x16, - 0x00, 0x03, 0x04, 0x00, 0x17, 0x06, 0x00, 0x16, - 0x00, 0x18, 0x04, 0x00, 0x17, - 0x00, 0x19, 0x00, 0x03, 0x02, 0x00, 0x1a, 0x07, - 0x00, 0x19, 0x00, 0x1b, 0x01, 0x00, 0x1a, 0x00, - 0x1c, 0x00, 0x03, 0x02, 0x00, 0x1d, 0x07, 0x00, - 0x1c, 0x00, 0x1e, 0x01, 0x00, 0x1d, 0x00, 0x1f, - 0x00, 0x03, 0x03, 0x00, 0x20, 0x06, 0x00, 0x1f, - 0x00, 0x21, 0x00, 0x03, 0x03, 0x00, 0x22, 0x06, - 0x00, 0x21, 0x00, 0x23, 0x00, 0x04, 0x03, 0x00, - 0x24, 0x00, 0x04, 0x01, 0x00, 0x25, 0x01, 0x00, - 0x24, 0x00, 0x26, 0x00, 0x04, 0x05, 0x00, 0x27, - 0x01, 0x00, 0x26, 0x00, 0x28, 0x00, 0x04, 0x02, - 0x00, 0x29, 0x01, 0x00, 0x28, 0x00, 0x2a, 0x00, - 0x04, 0x06, 0x00, 0x2b, 0x00, 0x04, 0x06, 0x00, - 0x2c, 0x06, 0x00, 0x2b, 0x00, 0x2d, 0x00, 0x04, - 0x06, 0x00, 0x2e, 0x06, 0x00, 0x2d, 0x00, 0x2f, - 0x00, 0x04, 0x06, 0x00, 0x30, 0x06, 0x00, 0x2f, - 0x00, 0x31, 0x00, 0x04, 0x06, 0x00, 0x32, 0x06, - 0x00, 0x31, 0x00, 0x33, 0x00, 0x04, 0x04, 0x00, - 0x34, 0x00, 0x00, 0x02, 0x00, 0x35, 0x01, 0x00, - 0x34 - }; + } + public override ushort DeviceModelID => 20; + public override ERDM_ProductCategoryCoarse ProductCategoryCoarse => ERDM_ProductCategoryCoarse.CONTROL; + public override ERDM_ProductCategoryFine ProductCategoryFine => ERDM_ProductCategoryFine.DATA_CONVERSION; - private static readonly GeneratedPersonality[] PERSONALITYS = new GeneratedPersonality[] { PersonalityFromRawData(SLOT_INFO_RAW) }; + private static byte[] SLOT_INFO_RAW = new byte[] { + 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, 0x00, + 0x03, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x05, + 0x03, 0x00, 0x05, 0x00, 0x05, 0x02, 0x00, 0x06, + 0x00, 0x91, 0x00, 0x00, 0x07, 0x00, 0x91, 0x01, + 0x00, 0x08, 0x00, 0x05, 0x02, 0x00, 0x09, 0x00, + 0x02, 0x01, 0x00, 0x0a, 0x01, 0x00, 0x09, 0x00, + 0x0b, 0x00, 0x02, 0x01, 0x00, 0x0c, 0x01, 0x00, + 0x0b, 0x00, 0x0d, 0x00, 0x02, 0x02, 0x00, 0x0e, + 0x00, 0x02, 0x04, 0x00, 0x0f, 0x00, 0x02, 0x03, + 0x00, 0x10, 0x00, 0x02, 0x08, 0x00, 0x11, 0x00, + 0x02, 0x08, 0x00, 0x12, 0x00, 0x05, 0x04, 0x00, + 0x13, 0x00, 0x05, 0x03, 0x00, 0x14, 0x00, 0xff, + 0xff, 0x00, 0x15, 0x00, 0xff, 0xff, 0x00, 0x16, + 0x00, 0x03, 0x04, 0x00, 0x17, 0x06, 0x00, 0x16, + 0x00, 0x18, 0x04, 0x00, 0x17, + 0x00, 0x19, 0x00, 0x03, 0x02, 0x00, 0x1a, 0x07, + 0x00, 0x19, 0x00, 0x1b, 0x01, 0x00, 0x1a, 0x00, + 0x1c, 0x00, 0x03, 0x02, 0x00, 0x1d, 0x07, 0x00, + 0x1c, 0x00, 0x1e, 0x01, 0x00, 0x1d, 0x00, 0x1f, + 0x00, 0x03, 0x03, 0x00, 0x20, 0x06, 0x00, 0x1f, + 0x00, 0x21, 0x00, 0x03, 0x03, 0x00, 0x22, 0x06, + 0x00, 0x21, 0x00, 0x23, 0x00, 0x04, 0x03, 0x00, + 0x24, 0x00, 0x04, 0x01, 0x00, 0x25, 0x01, 0x00, + 0x24, 0x00, 0x26, 0x00, 0x04, 0x05, 0x00, 0x27, + 0x01, 0x00, 0x26, 0x00, 0x28, 0x00, 0x04, 0x02, + 0x00, 0x29, 0x01, 0x00, 0x28, 0x00, 0x2a, 0x00, + 0x04, 0x06, 0x00, 0x2b, 0x00, 0x04, 0x06, 0x00, + 0x2c, 0x06, 0x00, 0x2b, 0x00, 0x2d, 0x00, 0x04, + 0x06, 0x00, 0x2e, 0x06, 0x00, 0x2d, 0x00, 0x2f, + 0x00, 0x04, 0x06, 0x00, 0x30, 0x06, 0x00, 0x2f, + 0x00, 0x31, 0x00, 0x04, 0x06, 0x00, 0x32, 0x06, + 0x00, 0x31, 0x00, 0x33, 0x00, 0x04, 0x04, 0x00, + 0x34, 0x00, 0x00, 0x02, 0x00, 0x35, 0x01, 0x00, + 0x34 + }; - private static Sensor[] GetSensors() { - return new Sensor[] {}; - } - public override GeneratedPersonality[] Personalities => PERSONALITYS; + private static readonly GeneratedPersonality[] PERSONALITYS = new GeneratedPersonality[] { PersonalityFromRawData(SLOT_INFO_RAW) }; - private static GeneratedPersonality PersonalityFromRawData(byte[] bytes) + private static GeneratedPersonality PersonalityFromRawData(byte[] bytes) + { + List slots = new List(); + var bag = new ParameterBag(ERDM_Parameter.SLOT_INFO); + RDMSlotInfo[] slotInfos = (RDMSlotInfo[])MetadataFactory.ParseDataToPayload(MetadataFactory.GetDefine(bag), RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, bytes).ParsedObject; + foreach (RDMSlotInfo slotInfo in slotInfos) { - List slots = new List(); - var bag = new ParameterBag(ERDM_Parameter.SLOT_INFO); - RDMSlotInfo[] slotInfos = (RDMSlotInfo[])MetadataFactory.ParseDataToPayload(MetadataFactory.GetDefine(bag), RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, bytes).ParsedObject; - foreach (RDMSlotInfo slotInfo in slotInfos) - { - Slot slot = new Slot(slotInfo.SlotOffset, slotInfo.SlotLabelId, "Dummy Slot", 1); - slots.Add(slot); - } - return new GeneratedPersonality(1, "Generated", slots.ToArray()); + Slot slot = new Slot(slotInfo.SlotOffset, slotInfo.SlotLabelId, "Dummy Slot", 1); + slots.Add(slot); } + return new GeneratedPersonality(1, "Generated", slots.ToArray()); + } - public override bool SupportQueued => true; + public override bool SupportQueued => true; - public override bool SupportStatus => true; - - public MockGeneratedDevice_SlotOverflow(UID uid) : base(uid, SubDevice.Root, new ERDM_Parameter[] { ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL }, "Dummy Manufacturer 9FFF", GetSensors()) - { - this.DeviceLabel = "Dummy Device 1"; - this.SoftwareVersionLabel = $"Dummy Software"; - this.BootSoftwareVersionLabel = $"Dummy Bootloader Software"; - } - protected sealed override void OnDispose() - { - } + public MockGeneratedDevice_SlotOverflow(UID uid) : base(uid, SubDevice.Root, GetModules()) + { + } + private static IReadOnlyCollection GetModules() + { + return new IModule[] { + new DeviceLabelModule("Dummy Device 1"), + new ManufacturerLabelModule("Dummy Manufacturer 9FFF"), + new DeviceModelDescriptionModule("Test Model Description"), + new SoftwareVersionModule(0x1234, $"Dummy Software"), + new BootSoftwareVersionModule(123, $"Dummy Bootloader Software"), + new DMX_StartAddressModule(1), + new DMX_PersonalityModule(1,PERSONALITYS), + new SlotsModule() + }; + } + protected sealed override void OnDispose() + { } } \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestBootSoftwareVersionModule.cs b/RDMSharpTests/Devices/Modules/TestBootSoftwareVersionModule.cs new file mode 100644 index 00000000..10d3d220 --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestBootSoftwareVersionModule.cs @@ -0,0 +1,122 @@ +using RDMSharp.Metadata; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestBootSoftwareVersionModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + const string BOOT_SOFTWARE_VERSION_LABEL = "Dummy Bootloader Software"; + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(30)] + public void TestGetBOOT_SOFTWARE_VERSION_ID() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + var bootSoftwareVersionModule = generated.Modules.OfType().Single(); + Assert.That(bootSoftwareVersionModule, Is.Not.Null); + Assert.That(bootSoftwareVersionModule.BootSoftwareVersionId, Is.EqualTo(123)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(4)); + Assert.That(response.Value, Is.EqualTo(bootSoftwareVersionModule.BootSoftwareVersionId)); + #endregion + } + [Test, Order(31)] + public void TestGetBOOT_SOFTWARE_VERSION_LABEL() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + var bootSoftwareVersionModule = generated.Modules.OfType().Single(); + Assert.That(bootSoftwareVersionModule, Is.Not.Null); + Assert.That(bootSoftwareVersionModule.BootSoftwareVersionLabel, Is.EqualTo(BOOT_SOFTWARE_VERSION_LABEL)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(BOOT_SOFTWARE_VERSION_LABEL.Length)); + Assert.That(response.Value, Is.EqualTo(BOOT_SOFTWARE_VERSION_LABEL)); + #endregion + + #region Test Label changed + bootSoftwareVersionModule.BootSoftwareVersionLabel = "Rem x Ram"; + Assert.That(bootSoftwareVersionModule.BootSoftwareVersionLabel, Is.EqualTo("Rem x Ram")); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(bootSoftwareVersionModule.BootSoftwareVersionLabel.Length)); + Assert.That(response.Value, Is.EqualTo(bootSoftwareVersionModule.BootSoftwareVersionLabel)); + #endregion + } + + [Test, Order(301)] + public async Task TestRemoteDevice() + { + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module, Is.Not.Null); + Assert.That(module.BootSoftwareVersionLabel, Is.EqualTo(BOOT_SOFTWARE_VERSION_LABEL)); + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestCurveModule.cs b/RDMSharpTests/Devices/Modules/TestCurveModule.cs new file mode 100644 index 00000000..c6b6be3e --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestCurveModule.cs @@ -0,0 +1,164 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestCurveModule +{ + private CurveModuleMockDevice? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(871, 5215198); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public async Task Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new CurveModuleMockDevice(DEVCIE_UID); + while (!generated.IsInitialized) + await Task.Delay(100); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + [Test, Order(10)] + public void TestGetCURVE_DESCRIPTION() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + + var curveModule = generated.Modules.OfType().Single(); + Assert.That(curveModule, Is.Not.Null); + Assert.That(curveModule.CurrentId, Is.EqualTo(1)); + Assert.That(curveModule.Count, Is.EqualTo(4)); + + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CURVE_DESCRIPTION, + SubDevice = SubDevice.Root, + ParameterData = new byte[] { 0x00 } // Requesting invalid 0 + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CURVE_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + for (byte b = 0; b < curveModule.Count; b++) + { + byte id = (byte)(b + 1); + request.ParameterData = new byte[] { id }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CURVE_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + var expected = curveModule._generatedCurves.FirstOrDefault(gen => gen.CurveId == id); + Assert.That(response.ParameterData, Has.Length.EqualTo(expected.ToPayloadData().Length)); + Assert.That(response.Value, Is.EqualTo(expected)); + Assert.That(((RDMCurveDescription)response.Value).Index, Is.EqualTo(expected.Index)); + Assert.That(((RDMCurveDescription)response.Value).Description, Is.EqualTo(expected.Description)); + } + #endregion + } + [Test, Order(11)] + public async Task TestGetCURVE() + { + await Task.Delay(500); + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Parameters.Contains(ERDM_Parameter.CURVE), Is.True); + await Task.Delay(1000); + var curveModule = generated.Modules.OfType().FirstOrDefault(); + Assert.That(curveModule, Is.Not.Null); + Assert.That(curveModule.CurrentId, Is.Not.Null); + Assert.That(curveModule.CurrentId.Value, Is.EqualTo(1)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CURVE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CURVE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(2)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMCurve))); + RDMCurve curve = (RDMCurve)response.Value; + Assert.That(curve.CurrentCurveId, Is.EqualTo(1)); + Assert.That(curve.Curves, Is.EqualTo(4)); + + #endregion + + } + [Test, Retry(3), Order(101)] + public async Task TestRemoteDevice() + { + Assert.That(generated, Is.Not.Null); + var generatedModule = generated.Modules.OfType().Single(); + Assert.That(generatedModule, Is.Not.Null); + Assert.That(generatedModule.CurrentId, Is.EqualTo(1)); + + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + while (!mockDevice.AllDataPulled) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.CurrentId, Is.EqualTo(1)); + SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 1); + module.PropertyChanged += (o, e) => + { + semaphoreSlim.Release(); + }; + await module.SetCurve(2); + await semaphoreSlim.WaitAsync(); + await Task.Delay(1000); + + Assert.That(generatedModule.CurrentId, Is.EqualTo(2)); + Assert.That(module.CurrentId, Is.EqualTo(2)); + } + + class CurveModuleMockDevice : MockGeneratedDevice1 + { + public CurveModuleMockDevice(UID uid) : base(uid, new IModule[] { new CurveModule(1, + new RDMCurveDescription(1, "Linear"), + new RDMCurveDescription(2, "Logarithmic"), + new RDMCurveDescription(3, "Exponential"), + new RDMCurveDescription(4, "S-Curve")) }) + { + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestDMX_PersonalityModule.cs b/RDMSharpTests/Devices/Modules/TestDMX_PersonalityModule.cs new file mode 100644 index 00000000..98cea046 --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestDMX_PersonalityModule.cs @@ -0,0 +1,174 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestDMX_PersonalityModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(10)] + public void TestGetDMX_PERSONALITY_DESCRIPTION() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + + var dmxPersonalityModuleModule = generated.Modules.OfType().Single(); + Assert.That(dmxPersonalityModuleModule, Is.Not.Null); + Assert.That(dmxPersonalityModuleModule.CurrentPersonality.ID, Is.EqualTo(1)); + Assert.That(dmxPersonalityModuleModule.CurrentPersonality.SlotCount, Is.EqualTo(5)); + + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, + SubDevice = SubDevice.Root, + ParameterData = new byte[] { 0x00 } // Requesting invalid 0 + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + for (byte b = 0; b < generated.Personalities.Count; b++) + { + request.ParameterData = new byte[] { (byte)(b + 1) }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + var pers = generated.Personalities.ElementAt(b); + var expected = new RDMDMXPersonalityDescription(pers.ID, pers.SlotCount, pers.Description); + Assert.That(response.ParameterData, Has.Length.EqualTo(expected.ToPayloadData().Length)); + Assert.That(response.Value, Is.EqualTo(expected)); + Assert.That(((RDMDMXPersonalityDescription)response.Value).Index, Is.EqualTo(expected.Index)); + } + #endregion + } + [Test, Order(11)] + public void TestGetDMX_PERSONALITY() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.That(generated.CurrentPersonalityId, Is.EqualTo(1)); + + var dmxPersonalityModule = generated.Modules.OfType().Single(); + Assert.That(dmxPersonalityModule, Is.Not.Null); + Assert.That(dmxPersonalityModule.CurrentPersonality.ID, Is.EqualTo(1)); + Assert.That(dmxPersonalityModule.CurrentPersonality.SlotCount, Is.EqualTo(5)); + + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.DMX_PERSONALITY, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + var pers = generated.Personalities.ElementAt(0); + var expected = new RDMDMXPersonality(pers.ID, (byte)generated.Personalities.Count()); + Assert.That(response.ParameterData, Has.Length.EqualTo(expected.ToPayloadData().Length)); + Assert.That(response.Value, Is.EqualTo(expected)); + Assert.That(((RDMDMXPersonality)response.Value).MinIndex, Is.EqualTo(1)); + Assert.That(((RDMDMXPersonality)response.Value).Index, Is.EqualTo(1)); + Assert.That(((RDMDMXPersonality)response.Value).Count, Is.EqualTo(3)); + #endregion + + #region Test Label changed + Assert.That(generated.CurrentPersonalityId, Is.EqualTo(1)); + generated.CurrentPersonalityId = 2; + Assert.That(generated.CurrentPersonalityId, Is.EqualTo(2)); + Assert.That(dmxPersonalityModule.CurrentPersonality.SlotCount, Is.EqualTo(8)); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + pers = generated.Personalities.ElementAt(1); + expected = new RDMDMXPersonality(pers.ID, (byte)generated.Personalities.Count()); + Assert.That(response.ParameterData, Has.Length.EqualTo(expected.ToPayloadData().Length)); + Assert.That(response.Value, Is.EqualTo(expected)); + #endregion + } + + [Test, Order(301), MaxTime(120000)] + public async Task TestRemoteDevice() + { + Assert.That(generated, Is.Not.Null); + var generatedModule = generated.Modules.OfType().Single(); + Assert.That(generatedModule, Is.Not.Null); + Assert.That(generatedModule.CurrentPersonality.ID, Is.EqualTo(1)); + Assert.That(generatedModule.CurrentPersonality.SlotCount, Is.EqualTo(5)); + + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.CurrentPersonality, Is.Not.Null); + Assert.That(module.CurrentPersonality.ID, Is.EqualTo(1)); + Assert.That(module.CurrentPersonality.SlotCount, Is.EqualTo(5)); + + SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 1); + module.PropertyChanged += (o, e) => + { + semaphoreSlim.Release(); + }; + await module.SetPersonality(2); + await semaphoreSlim.WaitAsync(); + await Task.Delay(1000); + + Assert.That(generatedModule.CurrentPersonality.ID, Is.EqualTo(2)); + Assert.That(module.CurrentPersonality.ID, Is.EqualTo(2)); + Assert.That(generatedModule.CurrentPersonality.SlotCount, Is.EqualTo(8)); + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestDMX_StartAddressModule.cs b/RDMSharpTests/Devices/Modules/TestDMX_StartAddressModule.cs new file mode 100644 index 00000000..58ddcf41 --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestDMX_StartAddressModule.cs @@ -0,0 +1,104 @@ +using RDMSharp.Metadata; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestDMX_StartAddressModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(7)] + public void TestGetDMX_START_ADDRESS() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + + var dmxStartAddressModule = generated.Modules.OfType().Single(); + Assert.That(dmxStartAddressModule, Is.Not.Null); + Assert.That(dmxStartAddressModule.DMXAddress, Is.EqualTo(1)); + + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.DMX_START_ADDRESS, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_START_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(2)); + Assert.That(response.Value, Is.EqualTo(generated.DMXAddress)); + #endregion + + + #region Test Address changed + generated.DMXAddress = 40; + Assert.That(generated.DMXAddress, Is.EqualTo(40)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_START_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(2)); + Assert.That(response.Value, Is.EqualTo(generated.DMXAddress)); + #endregion + } + + [Test, Order(301)] + public async Task TestRemoteDevice() + { + Assert.That(generated, Is.Not.Null); + var generatedModule = generated.Modules.OfType().Single(); + Assert.That(generatedModule, Is.Not.Null); + Assert.That(generatedModule.DMXAddress, Is.EqualTo(1)); + + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.DMXAddress, Is.EqualTo(1)); + + module.DMXAddress = 222; + await Task.Delay(1000); + + Assert.That(generatedModule.DMXAddress, Is.EqualTo(222)); + Assert.That(module.DMXAddress, Is.EqualTo(222)); + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestDeviceInfoModule.cs b/RDMSharpTests/Devices/Modules/TestDeviceInfoModule.cs new file mode 100644 index 00000000..92e114a1 --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestDeviceInfoModule.cs @@ -0,0 +1,76 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestDeviceInfoModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(5)] + public void TestGetDEVICE_INFO() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.DEVICE_INFO, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(19)); + Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); + RDMDeviceInfo? deviceInfo = response!.Value as RDMDeviceInfo; + Assert.That(deviceInfo, Is.Not.Null); + Assert.That(deviceInfo.SensorCount, Is.EqualTo(5)); + #endregion + } + + [Test, Order(11)] + public async Task TestRemoteDevice() + { + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.DeviceInfo, Is.Not.Null); + Assert.That(module.DeviceInfo.SensorCount, Is.EqualTo(5)); + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestDeviceLabelModule.cs b/RDMSharpTests/Devices/Modules/TestDeviceLabelModule.cs new file mode 100644 index 00000000..9e2b28cf --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestDeviceLabelModule.cs @@ -0,0 +1,106 @@ +using RDMSharp.Metadata; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestDeviceLabelModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(9)] + public void TestGetDEVICE_LABEL() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + var deviceLabelModule = generated.Modules.OfType().Single(); + Assert.That(deviceLabelModule, Is.Not.Null); + Assert.That(deviceLabelModule.DeviceLabel, Is.EqualTo("Dummy Device 1")); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.DEVICE_LABEL, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(deviceLabelModule.DeviceLabel.Length)); + Assert.That(response.Value, Is.EqualTo(deviceLabelModule.DeviceLabel)); + #endregion + + #region Test Label changed + Assert.That(deviceLabelModule.DeviceLabel, Is.EqualTo("Dummy Device 1")); + deviceLabelModule.DeviceLabel = "Rem x Ram"; + Assert.That(deviceLabelModule.DeviceLabel, Is.EqualTo("Rem x Ram")); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(deviceLabelModule.DeviceLabel.Length)); + Assert.That(response.Value, Is.EqualTo(deviceLabelModule.DeviceLabel)); + #endregion + } + + [Test, Order(301)] + public async Task TestRemoteDevice() + { + var generatedModule = generated.Modules.OfType().Single(); + Assert.That(generatedModule, Is.Not.Null); + Assert.That(generatedModule.DeviceLabel, Is.EqualTo("Dummy Device 1")); + + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.DeviceLabel, Is.EqualTo("Dummy Device 1")); + + SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 1); + module.PropertyChanged += (o, e) => + { + semaphoreSlim.Release(); + }; + module.DeviceLabel = "Test Label"; + await semaphoreSlim.WaitAsync(); + await Task.Delay(1000); + + Assert.That(generatedModule.DeviceLabel, Is.EqualTo("Test Label")); + Assert.That(module.DeviceLabel, Is.EqualTo("Test Label")); + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestDeviceModelDescriptionModule.cs b/RDMSharpTests/Devices/Modules/TestDeviceModelDescriptionModule.cs new file mode 100644 index 00000000..cb94731d --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestDeviceModelDescriptionModule.cs @@ -0,0 +1,74 @@ +using RDMSharp.Metadata; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestDeviceModelDescriptionModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(16)] + public void TestGetDEVICE_MODEL_DESCRIPTION() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + var deviceModelDescriptionModule = generated.Modules.OfType().Single(); + Assert.That(deviceModelDescriptionModule, Is.Not.Null); + Assert.That(deviceModelDescriptionModule.DeviceModelDescription, Is.EqualTo("Test Model Description")); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.DEVICE_MODEL_DESCRIPTION, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_MODEL_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(deviceModelDescriptionModule.DeviceModelDescription.Length)); + Assert.That(response.Value, Is.EqualTo(deviceModelDescriptionModule.DeviceModelDescription)); + #endregion + } + + [Test, Order(301)] + public async Task TestRemoteDevice() + { + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.DeviceModelDescription, Is.EqualTo("Test Model Description")); + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestEndpointsModlue.cs b/RDMSharpTests/Devices/Modules/TestEndpointsModlue.cs new file mode 100644 index 00000000..f0151220 --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestEndpointsModlue.cs @@ -0,0 +1,2060 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestEndpointsModlue +{ + private EndpointsMockDevice? generated; + private EndpointsModule? endpointsModule; + + private static UID CONTROLLER_UID = new UID(0x1fff, 876545); + private static UID DEVCIE_UID = new UID(9031, 45862713); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new EndpointsMockDevice(DEVCIE_UID); + endpointsModule = generated.Modules.OfType().FirstOrDefault(); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + endpointsModule = null; + } + + [Test, Order(1)] + public void TestGetENDPOINT_LIST() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_LIST, + SubDevice = SubDevice.Root, + }; + RDMMessage requestChangede = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_LIST_CHANGE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(requestChangede); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LIST_CHANGE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(4)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(uint))); + Assert.That(response.Value, Is.EqualTo(0)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LIST)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(40)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetEndpointListResponse))); + var getEndpointListResponse = (GetEndpointListResponse)response.Value; + Assert.That(getEndpointListResponse.ListChangedNumber, Is.EqualTo(0)); + var endpoints = getEndpointListResponse.Endpoints; + Assert.That(endpoints, Has.Length.EqualTo(12)); + + for (int i = 0; i < endpoints.Length; i++) + { + Assert.That(endpoints[i].EndpointId, Is.EqualTo(i + 1)); + Assert.That(endpoints[i].EndpointType, Is.EqualTo(ERDM_EndpointType.VIRTUAL)); + } + + endpointsModule.AddEndpoint(new EndpointOutputMock(13, 2)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LIST)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(43)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetEndpointListResponse))); + getEndpointListResponse = (GetEndpointListResponse)response.Value; + Assert.That(getEndpointListResponse.ListChangedNumber, Is.EqualTo(1)); + endpoints = getEndpointListResponse.Endpoints; + Assert.That(endpoints, Has.Length.EqualTo(13)); + + for (int i = 0; i < endpoints.Length; i++) + { + Assert.That(endpoints[i].EndpointId, Is.EqualTo(i + 1)); + Assert.That(endpoints[i].EndpointType, Is.EqualTo(ERDM_EndpointType.VIRTUAL)); + } + + endpointsModule.RemoveEndpoint(13); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LIST)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(40)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetEndpointListResponse))); + getEndpointListResponse = (GetEndpointListResponse)response.Value; + Assert.That(getEndpointListResponse.ListChangedNumber, Is.EqualTo(2)); + endpoints = getEndpointListResponse.Endpoints; + Assert.That(endpoints, Has.Length.EqualTo(12)); + + for (int i = 0; i < endpoints.Length; i++) + { + Assert.That(endpoints[i].EndpointId, Is.EqualTo(i + 1)); + Assert.That(endpoints[i].EndpointType, Is.EqualTo(ERDM_EndpointType.VIRTUAL)); + } + + response = generated.ProcessRequestMessage_Internal(requestChangede); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LIST_CHANGE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(4)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(uint))); + Assert.That(response.Value, Is.EqualTo(2)); + + #endregion + + } + + [Test, Order(21)] + public void TestGetIDENTIFY_ENDPOINT() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.IDENTIFY_ENDPOINT, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_ENDPOINT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_ENDPOINT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIdentifyEndpoint))); + var getSetEndpointLable = (GetSetIdentifyEndpoint)response.Value; + Assert.That(getSetEndpointLable.EndpointId, Is.EqualTo(1)); + Assert.That(getSetEndpointLable.IdentifyState, Is.EqualTo(false)); + #endregion + + endpointsModule.Endpoints[1].Identify = true; + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_ENDPOINT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIdentifyEndpoint))); + getSetEndpointLable = (GetSetIdentifyEndpoint)response.Value; + Assert.That(getSetEndpointLable.EndpointId, Is.EqualTo(1)); + Assert.That(getSetEndpointLable.IdentifyState, Is.EqualTo(true)); + } + [Test, Order(22)] + public void TestGetENDPOINT_TO_UNIVERSE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_TO_UNIVERSE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TO_UNIVERSE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TO_UNIVERSE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(4)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointToUniverse))); + var getSetEndpointToUniverse = (GetSetEndpointToUniverse)response.Value; + Assert.That(getSetEndpointToUniverse.EndpointId, Is.EqualTo(1)); + Assert.That(getSetEndpointToUniverse.Universe, Is.EqualTo(1)); + #endregion + + request.ParameterData = Tools.ValueToData((ushort)9); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TO_UNIVERSE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(4)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointToUniverse))); + getSetEndpointToUniverse = (GetSetEndpointToUniverse)response.Value; + Assert.That(getSetEndpointToUniverse.EndpointId, Is.EqualTo(9)); + Assert.That(getSetEndpointToUniverse.Universe, Is.EqualTo(2)); + + endpointsModule.Endpoints[9].Universe = 1; + + request.ParameterData = Tools.ValueToData((ushort)9); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TO_UNIVERSE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(4)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointToUniverse))); + getSetEndpointToUniverse = (GetSetEndpointToUniverse)response.Value; + Assert.That(getSetEndpointToUniverse.EndpointId, Is.EqualTo(9)); + Assert.That(getSetEndpointToUniverse.Universe, Is.EqualTo(1)); + + endpointsModule.Endpoints[9].Universe = 2; + } + [Test, Order(23)] + public void TestGetENDPOINT_MODE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_MODE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointMode))); + var getSetEndpointMode = (GetSetEndpointMode)response.Value; + Assert.That(getSetEndpointMode.EndpointId, Is.EqualTo(1)); + Assert.That(getSetEndpointMode.EndpointMode, Is.EqualTo(ERDM_EndpointMode.INPUT)); + #endregion + + request.ParameterData = Tools.ValueToData((ushort)9); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointMode))); + getSetEndpointMode = (GetSetEndpointMode)response.Value; + Assert.That(getSetEndpointMode.EndpointId, Is.EqualTo(9)); + Assert.That(getSetEndpointMode.EndpointMode, Is.EqualTo(ERDM_EndpointMode.OUTPUT)); + + endpointsModule.Endpoints[9].Mode = ERDM_EndpointMode.DISABLED; + + request.ParameterData = Tools.ValueToData((ushort)9); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointMode))); + getSetEndpointMode = (GetSetEndpointMode)response.Value; + Assert.That(getSetEndpointMode.EndpointId, Is.EqualTo(9)); + Assert.That(getSetEndpointMode.EndpointMode, Is.EqualTo(ERDM_EndpointMode.DISABLED)); + + endpointsModule.Endpoints[9].Mode = ERDM_EndpointMode.OUTPUT; + } + [Test, Order(24)] + public void TestGetENDPOINT_LABEL() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_LABEL, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(23)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointLabel))); + var getSetEndpointLable = (GetSetEndpointLabel)response.Value; + Assert.That(getSetEndpointLable.EndpointId, Is.EqualTo(1)); + Assert.That(getSetEndpointLable.EndpointLabel, Is.EqualTo("Test Endpoint Input 1")); + #endregion + + request.ParameterData = Tools.ValueToData((ushort)4); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(24)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointLabel))); + getSetEndpointLable = (GetSetEndpointLabel)response.Value; + Assert.That(getSetEndpointLable.EndpointId, Is.EqualTo(4)); + Assert.That(getSetEndpointLable.EndpointLabel, Is.EqualTo("Test Endpoint Output 4")); + + endpointsModule.Endpoints[4].Lable = "Test Endpoint Output 4 renamed"; + + request.ParameterData = Tools.ValueToData((ushort)4); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(32)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointLabel))); + getSetEndpointLable = (GetSetEndpointLabel)response.Value; + Assert.That(getSetEndpointLable.EndpointId, Is.EqualTo(4)); + Assert.That(getSetEndpointLable.EndpointLabel, Is.EqualTo("Test Endpoint Output 4 renamed")); + } + [Test, Order(25)] + public void TestGetRDM_TRAFFIC_ENABLE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.RDM_TRAFFIC_ENABLE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RDM_TRAFFIC_ENABLE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RDM_TRAFFIC_ENABLE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointRDMTrafficEnable))); + var getSetEndpointRDMTrafficEnable = (GetSetEndpointRDMTrafficEnable)response.Value; + Assert.That(getSetEndpointRDMTrafficEnable.EndpointId, Is.EqualTo(1)); + Assert.That(getSetEndpointRDMTrafficEnable.RDMTrafficEnabled, Is.EqualTo(true)); + #endregion + + endpointsModule.Endpoints[1].RDMTraffic = false; + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RDM_TRAFFIC_ENABLE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointRDMTrafficEnable))); + getSetEndpointRDMTrafficEnable = (GetSetEndpointRDMTrafficEnable)response.Value; + Assert.That(getSetEndpointRDMTrafficEnable.EndpointId, Is.EqualTo(1)); + Assert.That(getSetEndpointRDMTrafficEnable.RDMTrafficEnabled, Is.EqualTo(false)); + + endpointsModule.Endpoints[1].RDMTraffic = true; + } + + [Test, Order(26)] + public void TestGetDISCOVERY_STATE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.DISCOVERY_STATE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DISCOVERY_STATE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DISCOVERY_STATE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetDiscoveryStateResponse))); + var getDiscoveryStateResponse = (GetDiscoveryStateResponse)response.Value; + Assert.That(getDiscoveryStateResponse.EndpointId, Is.EqualTo(1)); + Assert.That(getDiscoveryStateResponse.DiscoveryState, Is.EqualTo(ERDM_DiscoveryState.INCOMPLETE)); + Assert.That(getDiscoveryStateResponse.DeviceCount, Is.EqualTo(0)); + #endregion + + endpointsModule.Endpoints[1].DiscoveryState = ERDM_DiscoveryState.FULL; + endpointsModule.Endpoints[1].DiscoveryStateCount = 4; + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DISCOVERY_STATE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetDiscoveryStateResponse))); + getDiscoveryStateResponse = (GetDiscoveryStateResponse)response.Value; + Assert.That(getDiscoveryStateResponse.EndpointId, Is.EqualTo(1)); + Assert.That(getDiscoveryStateResponse.DiscoveryState, Is.EqualTo(ERDM_DiscoveryState.FULL)); + Assert.That(getDiscoveryStateResponse.DeviceCount, Is.EqualTo(4)); + + endpointsModule.Endpoints[1].DiscoveryState = ERDM_DiscoveryState.INCOMPLETE; + endpointsModule.Endpoints[1].DiscoveryStateCount = 0; + } + [Test, Order(27)] + public void TestGetBACKGROUND_DISCOVERY() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.BACKGROUND_DISCOVERY, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_DISCOVERY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_DISCOVERY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointBackgroundDiscovery))); + var getSetEndpointBackgroundDiscovery = (GetSetEndpointBackgroundDiscovery)response.Value; + Assert.That(getSetEndpointBackgroundDiscovery.EndpointId, Is.EqualTo(1)); + Assert.That(getSetEndpointBackgroundDiscovery.BackgroundDiscovery, Is.EqualTo(false)); + #endregion + + endpointsModule.Endpoints[1].BackgroundDiscovery = true; + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_DISCOVERY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetEndpointBackgroundDiscovery))); + getSetEndpointBackgroundDiscovery = (GetSetEndpointBackgroundDiscovery)response.Value; + Assert.That(getSetEndpointBackgroundDiscovery.EndpointId, Is.EqualTo(1)); + Assert.That(getSetEndpointBackgroundDiscovery.BackgroundDiscovery, Is.EqualTo(true)); + + endpointsModule.Endpoints[1].BackgroundDiscovery = false; + } + [Test, Order(28)] + public void TestGetENDPOINT_TIMING() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_TIMING, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(4)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetEndpointTimingResponse))); + var getEndpointTimingResponse = (GetEndpointTimingResponse)response.Value; + Assert.That(getEndpointTimingResponse.EndpointId, Is.EqualTo(1)); + Assert.That(getEndpointTimingResponse.TimingId, Is.EqualTo(2)); + Assert.That(getEndpointTimingResponse.Timings, Is.EqualTo(5)); + #endregion + + endpointsModule.Endpoints[1].Timing = 1; + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(4)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetEndpointTimingResponse))); + getEndpointTimingResponse = (GetEndpointTimingResponse)response.Value; + Assert.That(getEndpointTimingResponse.EndpointId, Is.EqualTo(1)); + Assert.That(getEndpointTimingResponse.TimingId, Is.EqualTo(1)); + Assert.That(getEndpointTimingResponse.Timings, Is.EqualTo(5)); + + endpointsModule.Endpoints[1].Timing = 2; + } + [Test, Order(29)] + public void TestGetENDPOINT_TIMING_DESCRIPTION() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + foreach (var timing in endpointsModule.TimingDescriptions) + { + request.ParameterData = Tools.ValueToData(timing.Key); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(14)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetEndpointTimingDescriptionResponse))); + var etEndpointTimingDescriptionResponse = (GetEndpointTimingDescriptionResponse)response.Value; + Assert.That(etEndpointTimingDescriptionResponse.TimingId, Is.EqualTo(timing.Key)); + Assert.That(etEndpointTimingDescriptionResponse.Description, Is.EqualTo(timing.Value)); + } + #endregion + } + [Test, Order(30)] + public void TestGetENDPOINT_RESPONDERS() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_RESPONDERS, + SubDevice = SubDevice.Root, + }; + RDMMessage requestChange = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_RESPONDERS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + requestChange.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(requestChange); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(6)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetEndpointResponderListChangeResponse))); + var getEndpointResponderListChangeResponse = (GetEndpointResponderListChangeResponse)response.Value; + Assert.That(getEndpointResponderListChangeResponse.EndpointId, Is.EqualTo(1)); + Assert.That(getEndpointResponderListChangeResponse.ListChangeNumber, Is.EqualTo(0)); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_RESPONDERS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(6)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetEndpointRespondersResponse))); + var getEndpointRespondersResponse = (GetEndpointRespondersResponse)response.Value; + Assert.That(getEndpointRespondersResponse.EndpointId, Is.EqualTo(1)); + Assert.That(getEndpointRespondersResponse.ListChangedNumber, Is.EqualTo(0)); + Assert.That(getEndpointRespondersResponse.UIDs, Is.EqualTo(new UID[0])); + #endregion + + ((EndpointMock)endpointsModule.Endpoints[1]).AddResponder(new UID(0x123456789ABC)); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_RESPONDERS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(12)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetEndpointRespondersResponse))); + getEndpointRespondersResponse = (GetEndpointRespondersResponse)response.Value; + Assert.That(getEndpointRespondersResponse.EndpointId, Is.EqualTo(1)); + Assert.That(getEndpointRespondersResponse.ListChangedNumber, Is.EqualTo(1)); + Assert.That(getEndpointRespondersResponse.UIDs, Is.EqualTo(new UID[] { new UID(0x123456789ABC) })); + + ((EndpointMock)endpointsModule.Endpoints[1]).RemoveResponder(new UID(0x123456789ABC)); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_RESPONDERS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(6)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetEndpointRespondersResponse))); + getEndpointRespondersResponse = (GetEndpointRespondersResponse)response.Value; + Assert.That(getEndpointRespondersResponse.EndpointId, Is.EqualTo(1)); + Assert.That(getEndpointRespondersResponse.ListChangedNumber, Is.EqualTo(2)); + Assert.That(getEndpointRespondersResponse.UIDs, Is.EqualTo(new UID[0])); + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(requestChange); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(6)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetEndpointResponderListChangeResponse))); + getEndpointResponderListChangeResponse = (GetEndpointResponderListChangeResponse)response.Value; + Assert.That(getEndpointResponderListChangeResponse.EndpointId, Is.EqualTo(1)); + Assert.That(getEndpointResponderListChangeResponse.ListChangeNumber, Is.EqualTo(2)); + } + [Test, Order(31)] + public void TestGetBINDING_CONTROL_FIELDS() + { + UID uid = new UID(0x123456789ABC); + UID bindingUid = new UID(0xABCDEF123456); + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.BINDING_CONTROL_FIELDS, + SubDevice = SubDevice.Root, + }; + + ((EndpointMock)endpointsModule.Endpoints[6]).SetBindingControlField(uid, 5, bindingUid); + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BINDING_CONTROL_FIELDS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((ushort)6).Concat(Tools.ValueToData(uid)).ToArray(); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BINDING_CONTROL_FIELDS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(16)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetBindingAndControlFieldsResponse))); + var getBindingAndControlFieldsResponse = (GetBindingAndControlFieldsResponse)response.Value; + Assert.That(getBindingAndControlFieldsResponse.EndpointId, Is.EqualTo(6)); + Assert.That(getBindingAndControlFieldsResponse.UID, Is.EqualTo(uid)); + Assert.That(getBindingAndControlFieldsResponse.ControlField, Is.EqualTo(5)); + Assert.That(getBindingAndControlFieldsResponse.BindingUID, Is.EqualTo(bindingUid)); + #endregion + + ((EndpointMock)endpointsModule.Endpoints[6]).SetBindingControlField(uid, 4, bindingUid); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BINDING_CONTROL_FIELDS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(16)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetBindingAndControlFieldsResponse))); + getBindingAndControlFieldsResponse = (GetBindingAndControlFieldsResponse)response.Value; + Assert.That(getBindingAndControlFieldsResponse.EndpointId, Is.EqualTo(6)); + Assert.That(getBindingAndControlFieldsResponse.UID, Is.EqualTo(uid)); + Assert.That(getBindingAndControlFieldsResponse.ControlField, Is.EqualTo(4)); + Assert.That(getBindingAndControlFieldsResponse.BindingUID, Is.EqualTo(bindingUid)); + + ((EndpointMock)endpointsModule.Endpoints[6]).RemoveBindingControlField(uid); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BINDING_CONTROL_FIELDS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(16)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetBindingAndControlFieldsResponse))); + getBindingAndControlFieldsResponse = (GetBindingAndControlFieldsResponse)response.Value; + Assert.That(getBindingAndControlFieldsResponse.EndpointId, Is.EqualTo(6)); + Assert.That(getBindingAndControlFieldsResponse.UID, Is.EqualTo(uid)); + Assert.That(getBindingAndControlFieldsResponse.ControlField, Is.EqualTo(0)); + Assert.That(getBindingAndControlFieldsResponse.BindingUID, Is.EqualTo(UID.Empty)); + + + request.ParameterData = Tools.ValueToData((ushort)60).Concat(Tools.ValueToData(uid)).ToArray(); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BINDING_CONTROL_FIELDS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + [Test, Order(32)] + public void TestGetBACKGROUND_QUEUED_STATUS_POLICY() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(2)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetBackgroundQueuedStatusPolicyResponse))); + var getBackgroundQueuedStatusPolicyResponse = (GetBackgroundQueuedStatusPolicyResponse)response.Value; + Assert.That(getBackgroundQueuedStatusPolicyResponse.PolicyId, Is.EqualTo(1)); + Assert.That(getBackgroundQueuedStatusPolicyResponse.Policies, Is.EqualTo(5)); + #endregion + + endpointsModule.BackgroundQueuedStatusPolicy = 2; + + request.ParameterData = Tools.ValueToData((ushort)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(2)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetBackgroundQueuedStatusPolicyResponse))); + getBackgroundQueuedStatusPolicyResponse = (GetBackgroundQueuedStatusPolicyResponse)response.Value; + Assert.That(getBackgroundQueuedStatusPolicyResponse.PolicyId, Is.EqualTo(2)); + Assert.That(getBackgroundQueuedStatusPolicyResponse.Policies, Is.EqualTo(5)); + + endpointsModule.BackgroundQueuedStatusPolicy = 1; + } + [Test, Order(33)] + public void TestGetBACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + foreach (var timing in endpointsModule.BackgroundQueuedStatusPolicyDescriptions) + { + request.ParameterData = Tools.ValueToData(timing.Key); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(14)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetBackgroundQueuedStatusPolicyDescriptionResponse))); + var getBackgroundQueuedStatusPolicyDescriptionResponse = (GetBackgroundQueuedStatusPolicyDescriptionResponse)response.Value; + Assert.That(getBackgroundQueuedStatusPolicyDescriptionResponse.PolicyId, Is.EqualTo(timing.Key)); + Assert.That(getBackgroundQueuedStatusPolicyDescriptionResponse.Description, Is.EqualTo(timing.Value)); + } + #endregion + } + + + [Test, Order(51)] + public void TestSetIDENTIFY_ENDPOINT() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.IDENTIFY_ENDPOINT, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_ENDPOINT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + Assert.That(endpointsModule.Endpoints[1].Identify, Is.EqualTo(false)); + + bool changed = false; + endpointsModule.Endpoints[1].PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(Endpoint.Identify)) + changed = true; + }; + + var payload = new GetSetIdentifyEndpoint(1, true); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_ENDPOINT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].Identify, Is.EqualTo(true)); + Assert.That(changed, Is.EqualTo(true)); + #endregion + + changed = false; + payload = new GetSetIdentifyEndpoint(1, false); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_ENDPOINT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].Identify, Is.EqualTo(false)); + Assert.That(changed, Is.EqualTo(true)); + + payload = new GetSetIdentifyEndpoint(20, false); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_ENDPOINT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + request.SourceUID = new UID(0xeeee, 0xf0f0f0f0); //Hardware Failure trigger + payload = new GetSetIdentifyEndpoint(1, false); + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_ENDPOINT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + } + [Test, Order(52)] + public void TestSetENDPOINT_TO_UNIVERSE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_TO_UNIVERSE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TO_UNIVERSE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + Assert.That(endpointsModule.Endpoints[1].Universe, Is.EqualTo(1)); + + bool changed = false; + endpointsModule.Endpoints[1].PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(Endpoint.Universe)) + changed = true; + }; + + var payload = new GetSetEndpointToUniverse(1, 99); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TO_UNIVERSE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].Universe, Is.EqualTo(99)); + Assert.That(changed, Is.EqualTo(true)); + #endregion + + changed = false; + payload = new GetSetEndpointToUniverse(1, 1); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TO_UNIVERSE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].Universe, Is.EqualTo(1)); + Assert.That(changed, Is.EqualTo(true)); + + payload = new GetSetEndpointToUniverse(20, 1); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TO_UNIVERSE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + request.SourceUID = new UID(0xeeee, 0xf0f0f0f0); //Hardware Failure trigger + payload = new GetSetEndpointToUniverse(1, 1); + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TO_UNIVERSE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + } + [Test, Order(53)] + public void TestSetENDPOINT_MODE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_MODE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + Assert.That(endpointsModule.Endpoints[1].Mode, Is.EqualTo(ERDM_EndpointMode.INPUT)); + + bool changed = false; + endpointsModule.Endpoints[1].PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(Endpoint.Mode)) + changed = true; + }; + + var payload = new GetSetEndpointMode(1, ERDM_EndpointMode.DISABLED); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].Mode, Is.EqualTo(ERDM_EndpointMode.DISABLED)); + Assert.That(changed, Is.EqualTo(true)); + #endregion + + changed = false; + payload = new GetSetEndpointMode(1, ERDM_EndpointMode.INPUT); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].Mode, Is.EqualTo(ERDM_EndpointMode.INPUT)); + Assert.That(changed, Is.EqualTo(true)); + + payload = new GetSetEndpointMode(20, ERDM_EndpointMode.INPUT); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + request.SourceUID = new UID(0xeeee, 0xf0f0f0f0); //Hardware Failure trigger + payload = new GetSetEndpointMode(1, ERDM_EndpointMode.INPUT); + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + } + [Test, Order(54)] + public void TestSetENDPOINT_LABEL() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_LABEL, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + Assert.That(endpointsModule.Endpoints[1].Lable, Is.EqualTo("Test Endpoint Input 1")); + + bool changed = false; + endpointsModule.Endpoints[1].PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(Endpoint.Lable)) + changed = true; + }; + + var payload = new GetSetEndpointLabel(1, "Test Endpoint Input 1 renamed"); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].Lable, Is.EqualTo("Test Endpoint Input 1 renamed")); + Assert.That(changed, Is.EqualTo(true)); + #endregion + + changed = false; + payload = new GetSetEndpointLabel(1, "Test Endpoint Input 1"); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].Lable, Is.EqualTo("Test Endpoint Input 1")); + Assert.That(changed, Is.EqualTo(true)); + + payload = new GetSetEndpointLabel(20, "Test Endpoint Input 20"); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + request.SourceUID = new UID(0xeeee, 0xf0f0f0f0); //Hardware Failure trigger + payload = new GetSetEndpointLabel(1, "Test Endpoint Input 1"); + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + } + [Test, Order(55)] + public void TestSetRDM_TRAFFIC_ENABLE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.RDM_TRAFFIC_ENABLE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RDM_TRAFFIC_ENABLE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + Assert.That(endpointsModule.Endpoints[1].RDMTraffic, Is.EqualTo(true)); + + bool changed = false; + endpointsModule.Endpoints[1].PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(Endpoint.RDMTraffic)) + changed = true; + }; + + var payload = new GetSetEndpointRDMTrafficEnable(1, false); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RDM_TRAFFIC_ENABLE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].RDMTraffic, Is.EqualTo(false)); + Assert.That(changed, Is.EqualTo(true)); + #endregion + + changed = false; + payload = new GetSetEndpointRDMTrafficEnable(1, true); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RDM_TRAFFIC_ENABLE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].RDMTraffic, Is.EqualTo(true)); + Assert.That(changed, Is.EqualTo(true)); + + payload = new GetSetEndpointRDMTrafficEnable(20, true); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RDM_TRAFFIC_ENABLE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + request.SourceUID = new UID(0xeeee, 0xf0f0f0f0); //Hardware Failure trigger + payload = new GetSetEndpointRDMTrafficEnable(1, true); + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RDM_TRAFFIC_ENABLE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + } + [Test, Order(56)] + public void TestSetDISCOVERY_STATE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.DISCOVERY_STATE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DISCOVERY_STATE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + Assert.That(endpointsModule.Endpoints[1].DiscoveryState, Is.EqualTo(ERDM_DiscoveryState.INCOMPLETE)); + + bool changed = false; + endpointsModule.Endpoints[1].PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(Endpoint.DiscoveryState)) + changed = true; + }; + + var payload = new SetDiscoveryStateRequest(1, ERDM_DiscoveryState.FULL); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DISCOVERY_STATE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].DiscoveryState, Is.EqualTo(ERDM_DiscoveryState.FULL)); + Assert.That(changed, Is.EqualTo(true)); + #endregion + + changed = false; + payload = new SetDiscoveryStateRequest(1, ERDM_DiscoveryState.INCOMPLETE); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DISCOVERY_STATE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].DiscoveryState, Is.EqualTo(ERDM_DiscoveryState.INCOMPLETE)); + Assert.That(changed, Is.EqualTo(true)); + + payload = new SetDiscoveryStateRequest(20, ERDM_DiscoveryState.INCOMPLETE); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DISCOVERY_STATE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + request.SourceUID = new UID(0xeeee, 0xf0f0f0f0); //Hardware Failure trigger + payload = new SetDiscoveryStateRequest(1, ERDM_DiscoveryState.INCOMPLETE); + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DISCOVERY_STATE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + } + [Test, Order(57)] + public void TestSetBACKGROUND_DISCOVERY() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.BACKGROUND_DISCOVERY, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_DISCOVERY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + Assert.That(endpointsModule.Endpoints[1].BackgroundDiscovery, Is.EqualTo(false)); + + bool changed = false; + endpointsModule.Endpoints[1].PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(Endpoint.BackgroundDiscovery)) + changed = true; + }; + + var payload = new GetSetEndpointBackgroundDiscovery(1, true); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_DISCOVERY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].BackgroundDiscovery, Is.EqualTo(true)); + Assert.That(changed, Is.EqualTo(true)); + #endregion + + changed = false; + payload = new GetSetEndpointBackgroundDiscovery(1, false); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_DISCOVERY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].BackgroundDiscovery, Is.EqualTo(false)); + Assert.That(changed, Is.EqualTo(true)); + + payload = new GetSetEndpointBackgroundDiscovery(20, false); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_DISCOVERY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + request.SourceUID = new UID(0xeeee, 0xf0f0f0f0); //Hardware Failure trigger + payload = new GetSetEndpointBackgroundDiscovery(1, false); + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_DISCOVERY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + } + [Test, Order(58)] + public void TestSetENDPOINT_TIMING() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ENDPOINT_TIMING, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + Assert.That(endpointsModule.Endpoints[1].Timing, Is.EqualTo(2)); + + bool changed = false; + endpointsModule.Endpoints[1].PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(Endpoint.Timing)) + changed = true; + }; + + var payload = new SetEndpointTimingRequest(1, 4); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].Timing, Is.EqualTo(4)); + Assert.That(changed, Is.EqualTo(true)); + #endregion + + changed = false; + payload = new SetEndpointTimingRequest(1, 2); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.Endpoints[1].Timing, Is.EqualTo(2)); + Assert.That(changed, Is.EqualTo(true)); + + payload = new SetEndpointTimingRequest(20, 3); + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + request.SourceUID = new UID(0xeeee, 0xf0f0f0f0); //Hardware Failure trigger + payload = new SetEndpointTimingRequest(1, 2); + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + } + [Test, Order(58)] + public void TestSetBACKGROUND_QUEUED_STATUS_POLICY() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(endpointsModule, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Is.Not.Null); + Assert.That(endpointsModule.Endpoints, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + Assert.That(endpointsModule.BackgroundQueuedStatusPolicy, Is.EqualTo(1)); + + bool changed = false; + endpointsModule.PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(EndpointsModule.BackgroundQueuedStatusPolicy)) + changed = true; + }; + + var payload = (byte)3; + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.BackgroundQueuedStatusPolicy, Is.EqualTo(3)); + Assert.That(changed, Is.EqualTo(true)); + #endregion + + changed = false; + payload = (byte)1; + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + Assert.That(endpointsModule.BackgroundQueuedStatusPolicy, Is.EqualTo(1)); + Assert.That(changed, Is.EqualTo(true)); + + payload = (byte)100; + + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + + + payload = (byte)1; + request.SourceUID = new UID(0xeeee, 0xf0f0f0f0); //Hardware Failure trigger + request.ParameterData = Tools.ValueToData(payload); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + } + + class EndpointsMockDevice : MockGeneratedDevice1 + { + public EndpointsMockDevice(UID uid) : base(uid, new IModule[] { new EndpointsModule( + 1, + getPolicys(), + getTimings(), + new Endpoint[] { + new EndpointInputMock(1, 1), + new EndpointInputMock(2, 2), + new EndpointOutputMock(3, 1), + new EndpointOutputMock(4, 1), + new EndpointOutputMock(5, 1), + new EndpointOutputMock(6, 1), + new EndpointOutputMock(7, 1), + new EndpointOutputMock(8, 2), + new EndpointOutputMock(9, 2), + new EndpointOutputMock(10, 2), + new EndpointOutputMock(11, 2), + new EndpointOutputMock(12, 2) + }) }) + { + } + + private static IDictionary getPolicys() + { + var dict = new Dictionary(); + dict.Add(1, "Test Policy 1"); + dict.Add(2, "Test Policy 2"); + dict.Add(3, "Test Policy 3"); + dict.Add(4, "Test Policy 4"); + dict.Add(5, "Test Policy 5"); + return dict; + } + private static IDictionary getTimings() + { + var dict = new Dictionary(); + dict.Add(1, "Test Timing 1"); + dict.Add(2, "Test Timing 2"); + dict.Add(3, "Test Timing 3"); + dict.Add(4, "Test Timing 4"); + dict.Add(5, "Test Timing 5"); + return dict; + } + } + class EndpointMock : Endpoint + { + public EndpointMock(ushort endpointId, ushort universe) + : base(endpointId, ERDM_EndpointType.VIRTUAL) + { + this.Universe = universe; + base.RDMTraffic = true; + } + + public new void AddResponder(UID uid) + { + base.AddResponder(uid); + } + public new void RemoveResponder(UID uid) + { + base.RemoveResponder(uid); + } + + + public new void SetBindingControlField(UID uid, ushort controlField, UID bindingUid) + { + base.SetBindingControlField(uid, controlField, bindingUid); + } + public new void RemoveBindingControlField(UID uid) + { + base.RemoveBindingControlField(uid); + } + } + class EndpointInputMock : EndpointMock + { + public EndpointInputMock(ushort endpointId, ushort universe) + : base(endpointId, universe) + { + this.Mode = ERDM_EndpointMode.INPUT; + base.Lable = $"Test Endpoint Input {endpointId}"; + base.Timing = 2; + } + } + class EndpointOutputMock : EndpointMock + { + public EndpointOutputMock(ushort endpointId, ushort universe) + : base(endpointId, universe) + { + this.Mode = ERDM_EndpointMode.OUTPUT; + base.Lable = $"Test Endpoint Output {endpointId}"; ; + base.Timing = 3; + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestIdentifyDeviceModule.cs b/RDMSharpTests/Devices/Modules/TestIdentifyDeviceModule.cs new file mode 100644 index 00000000..ebd6cdae --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestIdentifyDeviceModule.cs @@ -0,0 +1,158 @@ +using RDMSharp.Metadata; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestIdentifyDeviceModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + [Test, Order(6)] + public void TestGetIDENTIFY_DEVICE() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Identify, Is.False); + + var identifyDeviceModule = generated.Modules.OfType().Single(); + Assert.That(identifyDeviceModule, Is.Not.Null); + Assert.That(identifyDeviceModule.Identify, Is.False); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.IDENTIFY_DEVICE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(1)); + Assert.That(response.Value, Is.EqualTo(generated.Identify)); + #endregion + + #region Test Identify changed (GET) + Assert.That(generated.Identify, Is.False); + generated.Identify = true; + Assert.That(generated.Identify, Is.True); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(1)); + Assert.That(response.Value, Is.EqualTo(generated.Identify)); + #endregion + + + #region Test Identify changed (SET) + Assert.That(generated.Identify, Is.True); + request.ParameterData = new byte[] { 0x00 }; // Requesting Identify OFF + request.Command = ERDM_Command.SET_COMMAND; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + + Assert.That(generated.Identify, Is.False); + request.Command = ERDM_Command.GET_COMMAND; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(1)); + Assert.That(response.Value, Is.EqualTo(generated.Identify)); + + request.ParameterData = new byte[] { 0x01 }; // Requesting Identify OFF + request.Command = ERDM_Command.SET_COMMAND; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + + Assert.That(generated.Identify, Is.True); + + request.Command = ERDM_Command.GET_COMMAND; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(1)); + Assert.That(response.Value, Is.EqualTo(generated.Identify)); + + #endregion + } + + [Test, Order(301)] + public async Task TestRemoteDevice() + { + Assert.That(generated, Is.Not.Null); + var generatedModule = generated.Modules.OfType().Single(); + Assert.That(generatedModule, Is.Not.Null); + Assert.That(generatedModule.Identify, Is.False); + + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.Identify, Is.False); + + module.Identify = true; + await Task.Delay(1000); + + Assert.That(generatedModule.Identify, Is.True); + Assert.That(module.Identify, Is.True); + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestInterfaceModlue.cs b/RDMSharpTests/Devices/Modules/TestInterfaceModlue.cs new file mode 100644 index 00000000..fc368acb --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestInterfaceModlue.cs @@ -0,0 +1,1058 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestInterfaceModlue +{ + private InterfaceMockDevice? generated; + private InterfaceModule? interfaceModule; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(9231, 555); + private const string TEST_INTERFACE_NAME = "Test Interface"; + private const string TEST_INTERFACE_HARDWARE_ADDRESS = "e0:63:da:5a:c4:fb"; + private const EARP_HardwareTypes TEST_INTERFACE_HARDWARE_TYPE = EARP_HardwareTypes.Ethernet; + private const string TEST_INTERFACE_IP_ADDRESS = "2.3.4.5"; + private static RDMMessage APPLY_CONFIG_MESSAGE = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION, + SubDevice = SubDevice.Root, + ParameterData = Tools.ValueToData((uint)1) + }; + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new InterfaceMockDevice(DEVCIE_UID); + interfaceModule = generated.Modules.OfType().FirstOrDefault(); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + interfaceModule = null; + } + + [Test, Order(1)] + public void TestGetLIST_INTERFACES() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.LIST_INTERFACES, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.LIST_INTERFACES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(6)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(InterfaceDescriptor[]))); + var interfaces = (InterfaceDescriptor[])response.Value; + Assert.That(interfaces, Has.Length.EqualTo(1)); + Assert.That(interfaces[0].InterfaceId, Is.EqualTo(1)); + Assert.That(interfaces[0].HardwareType, Is.EqualTo(EARP_HardwareTypes.Ethernet)); + + #endregion + + } + [Test, Order(2)] + public void TestGetINTERFACE_LABEL() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.INTERFACE_LABEL, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(18)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetInterfaceNameResponse))); + var interfaceNameResponse = (GetInterfaceNameResponse)response.Value; + Assert.That(interfaceNameResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceNameResponse.Label, Is.EqualTo(TEST_INTERFACE_NAME)); + #endregion + + request.ParameterData = Tools.ValueToData((uint)2); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + [Test, Order(3)] + public void TestGetINTERFACE_HARDWARE_ADDRESS_TYPE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(10)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetHardwareAddressResponse))); + var interfaceHardwareAddressResponse = (GetHardwareAddressResponse)response.Value; + Assert.That(interfaceHardwareAddressResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceHardwareAddressResponse.HardwareAddress, Is.EqualTo(new MACAddress(TEST_INTERFACE_HARDWARE_ADDRESS))); + #endregion + + request.ParameterData = Tools.ValueToData((uint)2); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + [Test, Order(4)] + public void TestGetIPV4_CURRENT_ADDRESS() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.IPV4_CURRENT_ADDRESS, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_CURRENT_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_CURRENT_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(10)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetIPv4CurrentAddressResponse))); + var interfaceIPv4CurrentAddressResponse = (GetIPv4CurrentAddressResponse)response.Value; + Assert.That(interfaceIPv4CurrentAddressResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceIPv4CurrentAddressResponse.IPAddress, Is.EqualTo(new IPv4Address(TEST_INTERFACE_IP_ADDRESS))); + Assert.That(interfaceIPv4CurrentAddressResponse.Netmask, Is.EqualTo(8)); + Assert.That(interfaceIPv4CurrentAddressResponse.DHCPStatus, Is.EqualTo(ERDM_DHCPStatusMode.INACTIVE)); + #endregion + + request.ParameterData = Tools.ValueToData((uint)2); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_CURRENT_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + + [Test, Order(5)] + public void TestGetIPV4_DHCP_MODE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.IPV4_DHCP_MODE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_DHCP_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_DHCP_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPV4_xxx_Mode))); + var interfaceResponse = (GetSetIPV4_xxx_Mode)response.Value; + Assert.That(interfaceResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceResponse.Enabled, Is.False); + + interfaceModule.Interfaces.First().DHCP = true; + interfaceModule.Interfaces.First().DHCP = true; //For Coverage + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_DHCP_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPV4_xxx_Mode))); + interfaceResponse = (GetSetIPV4_xxx_Mode)response.Value; + Assert.That(interfaceResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceResponse.Enabled, Is.True); + #endregion + + request.ParameterData = Tools.ValueToData((uint)2); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_DHCP_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + [Test, Order(6)] + public void TestSetIPV4_DHCP_MODE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.IPV4_DHCP_MODE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_DHCP_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData(new GetSetIPV4_xxx_Mode(1, true)); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_DHCP_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + + request.Command = ERDM_Command.GET_COMMAND; + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_DHCP_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPV4_xxx_Mode))); + var interfaceResponse = (GetSetIPV4_xxx_Mode)response.Value; + Assert.That(interfaceResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceResponse.Enabled, Is.False); + + response = generated.ProcessRequestMessage_Internal(APPLY_CONFIG_MESSAGE); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_DHCP_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPV4_xxx_Mode))); + interfaceResponse = (GetSetIPV4_xxx_Mode)response.Value; + Assert.That(interfaceResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceResponse.Enabled, Is.True); + #endregion + + request.Command = ERDM_Command.SET_COMMAND; + request.ParameterData = Tools.ValueToData(new GetSetIPV4_xxx_Mode(2, true)); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_DHCP_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + + [Test, Order(7)] + public void TestGetIPV4_ZEROCONF_MODE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.IPV4_ZEROCONF_MODE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_ZEROCONF_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_ZEROCONF_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPV4_xxx_Mode))); + var interfaceResponse = (GetSetIPV4_xxx_Mode)response.Value; + Assert.That(interfaceResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceResponse.Enabled, Is.True); + + + interfaceModule.Interfaces.First().ZeroConf = false; + interfaceModule.Interfaces.First().ZeroConf = false; //For Coverage + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_ZEROCONF_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPV4_xxx_Mode))); + interfaceResponse = (GetSetIPV4_xxx_Mode)response.Value; + Assert.That(interfaceResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceResponse.Enabled, Is.False); + #endregion + + request.ParameterData = Tools.ValueToData((uint)2); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_ZEROCONF_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + + [Test, Order(8)] + public void TestSetIPV4_ZEROCONF_MODE() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.IPV4_ZEROCONF_MODE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_ZEROCONF_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData(new GetSetIPV4_xxx_Mode(1, false)); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_ZEROCONF_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + + request.Command = ERDM_Command.GET_COMMAND; + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_ZEROCONF_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPV4_xxx_Mode))); + var interfaceResponse = (GetSetIPV4_xxx_Mode)response.Value; + Assert.That(interfaceResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceResponse.Enabled, Is.True); + + + response = generated.ProcessRequestMessage_Internal(APPLY_CONFIG_MESSAGE); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_ZEROCONF_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPV4_xxx_Mode))); + interfaceResponse = (GetSetIPV4_xxx_Mode)response.Value; + Assert.That(interfaceResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceResponse.Enabled, Is.False); + + #endregion + + request.Command = ERDM_Command.SET_COMMAND; + request.ParameterData = Tools.ValueToData(new GetSetIPV4_xxx_Mode(2, true)); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_ZEROCONF_MODE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + + [Test, Order(9)] + public void TestGetIPV4_STATIC_ADDRESS() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.IPV4_STATIC_ADDRESS, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_STATIC_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_STATIC_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPv4StaticAddress))); + var interfaceIPv4StaticAddressResponse = (GetSetIPv4StaticAddress)response.Value; + Assert.That(interfaceIPv4StaticAddressResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceIPv4StaticAddressResponse.IPAddress, Is.EqualTo(new IPv4Address(TEST_INTERFACE_IP_ADDRESS))); + Assert.That(interfaceIPv4StaticAddressResponse.Netmask, Is.EqualTo(8)); + + IPv4Address oneDotOneDotOneDotOne = new IPv4Address("1.1.1.1"); + var iface = interfaceModule.Interfaces.First(); + iface.SetStaticIP(oneDotOneDotOneDotOne, 24); + Assert.That(iface.CurrentIP, Is.EqualTo(oneDotOneDotOneDotOne)); + Assert.That(iface.CurrentSubnetMask, Is.EqualTo(24)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_STATIC_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPv4StaticAddress))); + interfaceIPv4StaticAddressResponse = (GetSetIPv4StaticAddress)response.Value; + Assert.That(interfaceIPv4StaticAddressResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceIPv4StaticAddressResponse.IPAddress, Is.EqualTo(oneDotOneDotOneDotOne)); + Assert.That(interfaceIPv4StaticAddressResponse.Netmask, Is.EqualTo(24)); + #endregion + + request.ParameterData = Tools.ValueToData((uint)2); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_STATIC_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + [Test, Order(10)] + public void TestSetIPV4_STATIC_ADDRESS() + { + IPv4Address oneDotOneDotOneDotOne = new IPv4Address("1.1.1.1"); + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.IPV4_STATIC_ADDRESS, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_STATIC_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData(new GetSetIPv4StaticAddress(1, oneDotOneDotOneDotOne, 24)); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_STATIC_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + + request.Command = ERDM_Command.GET_COMMAND; + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_STATIC_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPv4StaticAddress))); + var interfaceResponse = (GetSetIPv4StaticAddress)response.Value; + Assert.That(interfaceResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceResponse.IPAddress, Is.EqualTo(new IPv4Address(TEST_INTERFACE_IP_ADDRESS))); + Assert.That(interfaceResponse.Netmask, Is.EqualTo(8)); + + + response = generated.ProcessRequestMessage_Internal(APPLY_CONFIG_MESSAGE); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_STATIC_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9)); + Assert.That(response.Value, Is.Not.Null); + Assert.That(response.Value, Is.TypeOf(typeof(GetSetIPv4StaticAddress))); + interfaceResponse = (GetSetIPv4StaticAddress)response.Value; + Assert.That(interfaceResponse.InterfaceId, Is.EqualTo(1)); + Assert.That(interfaceResponse.IPAddress, Is.EqualTo(oneDotOneDotOneDotOne)); + Assert.That(interfaceResponse.Netmask, Is.EqualTo(24)); + + #endregion + + request.Command = ERDM_Command.SET_COMMAND; + request.ParameterData = Tools.ValueToData(new GetSetIPv4StaticAddress(2, oneDotOneDotOneDotOne, 31)); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IPV4_STATIC_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + + [Test, Order(11)] + public void TestSetINTERFACE_APPLY_CONFIGURATION() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + + #endregion + + request.ParameterData = Tools.ValueToData((uint)2); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_APPLY_CONFIGURATION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + + [Test, Order(11)] + public void TestSetINTERFACE_RENEW_DHCP() + { + var iface = interfaceModule.Interfaces.First(); + iface.DHCP = true; + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.INTERFACE_RENEW_DHCP, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_RENEW_DHCP)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_RENEW_DHCP)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.ACTION_NOT_SUPPORTED)); + Assert.That(response.Value, Is.Null); + + iface.SetStaticIP(IPv4Address.Empty, 0); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_RENEW_DHCP)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + + Assert.That(iface.CurrentIP, Is.EqualTo(InterfaceMock.DHCP_ADDRESS_1)); + + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_RENEW_DHCP)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + + Assert.That(iface.CurrentIP, Is.EqualTo(InterfaceMock.DHCP_ADDRESS_2)); + + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_RENEW_DHCP)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + + Assert.That(iface.CurrentIP, Is.EqualTo(InterfaceMock.DHCP_ADDRESS_3)); + + #endregion + + request.ParameterData = Tools.ValueToData((uint)2); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_RENEW_DHCP)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + [Test, Order(12)] + public void TestSetINTERFACE_RELEASE_DHCP() + { + var iface = interfaceModule.Interfaces.First(); + iface.DHCP = true; + iface.SetStaticIP(IPv4Address.Empty, 0); + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + Assert.That(interfaceModule, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Is.Not.Null); + Assert.That(interfaceModule.Interfaces, Has.Count.Not.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.INTERFACE_RENEW_DHCP, + SubDevice = SubDevice.Root, + ParameterData = Tools.ValueToData((uint)1) + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(iface.CurrentIP, Is.EqualTo(InterfaceMock.DHCP_ADDRESS_1)); + + request.Parameter = ERDM_Parameter.INTERFACE_RELEASE_DHCP; + request.ParameterData = null; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_RELEASE_DHCP)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + Assert.That(response.Value, Is.Null); + + request.ParameterData = Tools.ValueToData((uint)1); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_RELEASE_DHCP)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + Assert.That(response.Value, Is.Null); + + Assert.That(iface.CurrentIP, Is.EqualTo(IPv4Address.Empty)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_RELEASE_DHCP)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.ACTION_NOT_SUPPORTED)); + Assert.That(response.Value, Is.Null); + #endregion + + request.ParameterData = Tools.ValueToData((uint)2); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.INTERFACE_RELEASE_DHCP)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + Assert.That(response.Value, Is.Null); + } + + class InterfaceMockDevice : MockGeneratedDevice1 + { + public InterfaceMockDevice(UID uid) : base(uid, new IModule[] { new InterfaceModule(new Interface[] { new InterfaceMock() }) }) + { + } + } + class InterfaceMock : Interface + { + public static IPv4Address DHCP_ADDRESS_1 = new IPv4Address("2.5.5.5"); + public static IPv4Address DHCP_ADDRESS_2 = new IPv4Address("2.6.6.6"); + public static IPv4Address DHCP_ADDRESS_3 = new IPv4Address("2.7.7.7"); + public InterfaceMock() + : base(1, + TEST_INTERFACE_NAME, + new IPv4Address(TEST_INTERFACE_IP_ADDRESS), + 8, + new MACAddress(TEST_INTERFACE_HARDWARE_ADDRESS), + TEST_INTERFACE_HARDWARE_TYPE) + { + } + public override void RenewDHCP() + { + switch (this.CurrentIP.B2) + { + default: + case 0: + this.SetCurrentIP(DHCP_ADDRESS_1, 8, true); + break; + case 5: + this.SetCurrentIP(DHCP_ADDRESS_2, 8, true); + break; + case 6: + this.SetCurrentIP(DHCP_ADDRESS_3, 8, true); + break; + } + } + public override void ReleaseDHCP() + { + this.SetCurrentIP(IPv4Address.Empty, 8, false); + base.ReleaseDHCP(); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestManufacturerLabelModule.cs b/RDMSharpTests/Devices/Modules/TestManufacturerLabelModule.cs new file mode 100644 index 00000000..fd4c12ea --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestManufacturerLabelModule.cs @@ -0,0 +1,74 @@ +using RDMSharp.Metadata; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestManufacturerLabelModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(15)] + public void TestGetMANUFACTURER_LABEL() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + var manufacturerLabelModule = generated.Modules.OfType().Single(); + Assert.That(manufacturerLabelModule, Is.Not.Null); + Assert.That(manufacturerLabelModule.ManufacturerLabel, Is.EqualTo("Dummy Manufacturer 9FFF")); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.MANUFACTURER_LABEL, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.MANUFACTURER_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(manufacturerLabelModule.ManufacturerLabel.Length)); + Assert.That(response.Value, Is.EqualTo(manufacturerLabelModule.ManufacturerLabel)); + #endregion + } + + [Test, Order(301)] + public async Task TestRemoteDevice() + { + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.ManufacturerLabel, Is.EqualTo("Dummy Manufacturer 9FFF")); + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestModulationFrequencyModule.cs b/RDMSharpTests/Devices/Modules/TestModulationFrequencyModule.cs new file mode 100644 index 00000000..d188ba20 --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestModulationFrequencyModule.cs @@ -0,0 +1,165 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestModulationFrequencyModule +{ + private ModulationFrequencyModuleMockDevice? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(873, 5215200); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public async Task Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new ModulationFrequencyModuleMockDevice(DEVCIE_UID); + while (!generated.IsInitialized) + await Task.Delay(100); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + [Test, Order(10)] + public void TestGetMODULATION_FREQUENCY_DESCRIPTION() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + + var modulationFrequencyModule = generated.Modules.OfType().Single(); + Assert.That(modulationFrequencyModule, Is.Not.Null); + Assert.That(modulationFrequencyModule.CurrentId, Is.EqualTo(1)); + Assert.That(modulationFrequencyModule.Count, Is.EqualTo(4)); + + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, + SubDevice = SubDevice.Root, + ParameterData = new byte[] { 0x00 } // Requesting invalid 0 + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + for (byte b = 0; b < modulationFrequencyModule.Count; b++) + { + byte id = (byte)(b + 1); + request.ParameterData = new byte[] { id }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + var expected = modulationFrequencyModule._generatedModulationFrequencys.FirstOrDefault(gen => gen.ModulationFrequencyId == id); + Assert.That(response.ParameterData, Has.Length.EqualTo(expected.ToPayloadData().Length)); + Assert.That(response.Value, Is.EqualTo(expected)); + Assert.That(((RDMModulationFrequencyDescription)response.Value).Index, Is.EqualTo(expected.Index)); + Assert.That(((RDMModulationFrequencyDescription)response.Value).Frequency, Is.EqualTo(expected.Frequency)); + Assert.That(((RDMModulationFrequencyDescription)response.Value).Description, Is.EqualTo(expected.Description)); + } + #endregion + } + [Test, Order(11)] + public async Task TestGetMODULATION_FREQUENCY() + { + await Task.Delay(500); + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Parameters.Contains(ERDM_Parameter.MODULATION_FREQUENCY), Is.True); + await Task.Delay(1000); + var modulationFrequencyModule = generated.Modules.OfType().FirstOrDefault(); + Assert.That(modulationFrequencyModule, Is.Not.Null); + Assert.That(modulationFrequencyModule.CurrentId, Is.Not.Null); + Assert.That(modulationFrequencyModule.CurrentId.Value, Is.EqualTo(1)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.MODULATION_FREQUENCY, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.MODULATION_FREQUENCY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(2)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMModulationFrequency))); + RDMModulationFrequency modulationFrequency = (RDMModulationFrequency)response.Value; + Assert.That(modulationFrequency.ModulationFrequencyId, Is.EqualTo(1)); + Assert.That(modulationFrequency.ModulationFrequencys, Is.EqualTo(4)); + + #endregion + + } + [Test, Retry(3), Order(101)] + public async Task TestRemoteDevice() + { + Assert.That(generated, Is.Not.Null); + var generatedModule = generated.Modules.OfType().Single(); + Assert.That(generatedModule, Is.Not.Null); + Assert.That(generatedModule.CurrentId, Is.EqualTo(1)); + + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + while (!mockDevice.AllDataPulled) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.CurrentId, Is.EqualTo(1)); + SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 1); + module.PropertyChanged += (o, e) => + { + semaphoreSlim.Release(); + }; + await module.SetModulationFrequency(2); + await semaphoreSlim.WaitAsync(); + await Task.Delay(1000); + + Assert.That(generatedModule.CurrentId, Is.EqualTo(2)); + Assert.That(module.CurrentId, Is.EqualTo(2)); + } + + class ModulationFrequencyModuleMockDevice : MockGeneratedDevice1 + { + public ModulationFrequencyModuleMockDevice(UID uid) : base(uid, new IModule[] { new ModulationFrequencyModule(1, + new RDMModulationFrequencyDescription(1, 2000, "2kHz"), + new RDMModulationFrequencyDescription(2, 4000, "4kHz"), + new RDMModulationFrequencyDescription(3, 8000, "8kHz"), + new RDMModulationFrequencyDescription(4, 16000, "16kHz")) }) + { + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestOutputResponseTimeModule.cs b/RDMSharpTests/Devices/Modules/TestOutputResponseTimeModule.cs new file mode 100644 index 00000000..f1a0dbdd --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestOutputResponseTimeModule.cs @@ -0,0 +1,164 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestOutputResponseTimeModule +{ + private OutputResponseTimeModuleMockDevice? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(875, 5215199); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public async Task Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new OutputResponseTimeModuleMockDevice(DEVCIE_UID); + while (!generated.IsInitialized) + await Task.Delay(100); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + [Test, Order(10)] + public void TestGetOUTPUT_RESPONSE_TIME_DESCRIPTION() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + + var outputResponseTimeModule = generated.Modules.OfType().Single(); + Assert.That(outputResponseTimeModule, Is.Not.Null); + Assert.That(outputResponseTimeModule.CurrentId, Is.EqualTo(1)); + Assert.That(outputResponseTimeModule.Count, Is.EqualTo(4)); + + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, + SubDevice = SubDevice.Root, + ParameterData = new byte[] { 0x00 } // Requesting invalid 0 + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + for (byte b = 0; b < outputResponseTimeModule.Count; b++) + { + byte id = (byte)(b + 1); + request.ParameterData = new byte[] { id }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + var expected = outputResponseTimeModule._generatedOutputResponseTimes.FirstOrDefault(gen => gen.OutputResponseTimeId == id); + Assert.That(response.ParameterData, Has.Length.EqualTo(expected.ToPayloadData().Length)); + Assert.That(response.Value, Is.EqualTo(expected)); + Assert.That(((RDMOutputResponseTimeDescription)response.Value).Index, Is.EqualTo(expected.Index)); + Assert.That(((RDMOutputResponseTimeDescription)response.Value).Description, Is.EqualTo(expected.Description)); + } + #endregion + } + [Test, Order(11)] + public async Task TestGetOUTPUT_RESPONSE_TIME() + { + await Task.Delay(500); + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Parameters.Contains(ERDM_Parameter.OUTPUT_RESPONSE_TIME), Is.True); + await Task.Delay(1000); + var outputResponseTimeModule = generated.Modules.OfType().FirstOrDefault(); + Assert.That(outputResponseTimeModule, Is.Not.Null); + Assert.That(outputResponseTimeModule.CurrentId, Is.Not.Null); + Assert.That(outputResponseTimeModule.CurrentId.Value, Is.EqualTo(1)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.OUTPUT_RESPONSE_TIME, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.OUTPUT_RESPONSE_TIME)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(2)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMOutputResponseTime))); + RDMOutputResponseTime outputResponseTime = (RDMOutputResponseTime)response.Value; + Assert.That(outputResponseTime.CurrentResponseTimeId, Is.EqualTo(1)); + Assert.That(outputResponseTime.ResponseTimes, Is.EqualTo(4)); + + #endregion + + } + [Test, Retry(3), Order(101)] + public async Task TestRemoteDevice() + { + Assert.That(generated, Is.Not.Null); + var generatedModule = generated.Modules.OfType().Single(); + Assert.That(generatedModule, Is.Not.Null); + Assert.That(generatedModule.CurrentId, Is.EqualTo(1)); + + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + while (!mockDevice.AllDataPulled) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.CurrentId, Is.EqualTo(1)); + SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 1); + module.PropertyChanged += (o, e) => + { + semaphoreSlim.Release(); + }; + await module.SetOutputResponseTime(2); + await semaphoreSlim.WaitAsync(); + await Task.Delay(1000); + + Assert.That(generatedModule.CurrentId, Is.EqualTo(2)); + Assert.That(module.CurrentId, Is.EqualTo(2)); + } + + class OutputResponseTimeModuleMockDevice : MockGeneratedDevice1 + { + public OutputResponseTimeModuleMockDevice(UID uid) : base(uid, new IModule[] { new OutputResponseTimeModule(1, + new RDMOutputResponseTimeDescription(1, "Very Slow"), + new RDMOutputResponseTimeDescription(2, "Slow"), + new RDMOutputResponseTimeDescription(3, "Normal"), + new RDMOutputResponseTimeDescription(4, "Fast")) }) + { + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestProxiedDevicesModlue.cs b/RDMSharpTests/Devices/Modules/TestProxiedDevicesModlue.cs new file mode 100644 index 00000000..3223eed3 --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestProxiedDevicesModlue.cs @@ -0,0 +1,242 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestProxiedDevicesModlue +{ + private ProxiedDevicesMockDevice? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 3453); + private static UID DEVCIE_UID = new UID(765, 5225); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new ProxiedDevicesMockDevice(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + + [Test, Retry(3), Order(1)] + public void TestGetPROXIED_DEVICES_COUNT() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + var proxiedDevicesModule = generated.Modules.OfType().FirstOrDefault(); + Assert.That(proxiedDevicesModule, Is.Not.Null); + Assert.That(proxiedDevicesModule.DeviceUIDs, Is.Not.Null); + Assert.That(proxiedDevicesModule.DeviceUIDs, Has.Count.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.PROXIED_DEVICES_COUNT, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.PROXIED_DEVICES_COUNT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.EqualTo(new RDMProxiedDeviceCount(0, false))); + #endregion + + proxiedDevicesModule.AddProxiedDevices(new UID(12, 3456), new UID(12, 2345)); + + for (int i = 0; i < 5; i++) + { + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.PROXIED_DEVICES_COUNT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.EqualTo(new RDMProxiedDeviceCount(2, true))); + } + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.PROXIED_DEVICES, + SubDevice = SubDevice.Root, + }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.PROXIED_DEVICES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(12)); + Assert.That(response.Value, Is.EqualTo(new RDMProxiedDevices(new UID(12, 3456), new UID(12, 2345)))); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.PROXIED_DEVICES_COUNT, + SubDevice = SubDevice.Root, + }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.PROXIED_DEVICES_COUNT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.EqualTo(new RDMProxiedDeviceCount(2, false))); + + + proxiedDevicesModule.RemoveProxiedDevices(new UID(12, 3456)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.PROXIED_DEVICES_COUNT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.EqualTo(new RDMProxiedDeviceCount(1, true))); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.PROXIED_DEVICES, + SubDevice = SubDevice.Root, + }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.PROXIED_DEVICES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(6)); + Assert.That(response.Value, Is.EqualTo(new RDMProxiedDevices(new UID(12, 2345)))); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.PROXIED_DEVICES_COUNT, + SubDevice = SubDevice.Root, + }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.PROXIED_DEVICES_COUNT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.EqualTo(new RDMProxiedDeviceCount(1, false))); + + List uidsToAdd = new List(); + uidsToAdd.Add(new UID(12, 2345)); + for (int i = 0; i < 134; i++) + uidsToAdd.Add(new UID(12, (ushort)(3456 + i))); + + proxiedDevicesModule.AddProxiedDevices(uidsToAdd.ToArray()); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.PROXIED_DEVICES_COUNT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.EqualTo(new RDMProxiedDeviceCount(135, true))); + + var chunks = uidsToAdd.Chunk(38); + int totalResponses = 0; + for (int i = 0; i < chunks.Count(); i++) + { + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.PROXIED_DEVICES, + SubDevice = SubDevice.Root, + }; + response = generated.ProcessRequestMessage_Internal(request); + totalResponses++; + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.PROXIED_DEVICES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.MessageCounter, Is.EqualTo(chunks.Count() - totalResponses)); + Assert.That(response.ParameterData, Has.Length.EqualTo(chunks.ElementAt(i).Count() * 6)); + Assert.That(response.Value, Is.EqualTo(new RDMProxiedDevices(chunks.ElementAt(i).ToArray()))); + } + Assert.That(totalResponses, Is.EqualTo(chunks.Count())); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.PROXIED_DEVICES_COUNT, + SubDevice = SubDevice.Root, + }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.PROXIED_DEVICES_COUNT)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3)); + Assert.That(response.Value, Is.EqualTo(new RDMProxiedDeviceCount(135, false))); + } + + class ProxiedDevicesMockDevice : MockGeneratedDevice1 + { + public ProxiedDevicesMockDevice(UID uid) : base(uid, new IModule[] { new ProxiedDevicesModule() }) + { + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestQueuedMessageModule.cs b/RDMSharpTests/Devices/Modules/TestQueuedMessageModule.cs new file mode 100644 index 00000000..a4497c2f --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestQueuedMessageModule.cs @@ -0,0 +1,315 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestQueuedMessageModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test] + public void TestGetQUEUED_MESSAGE() + { + #region Test Empty queue + Assert.That(generated, Is.Not.Null); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.QUEUED_MESSAGE, + SubDevice = SubDevice.Root, + ParameterData = new byte[] { (byte)ERDM_Status.ADVISORY } + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + #endregion + + #region Test set DMX-Address (single value changed) + Assert.That(generated.DMXAddress, Is.EqualTo(1)); + generated.DMXAddress = 42; + Assert.That(generated.DMXAddress, Is.EqualTo(42)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_START_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(1)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(2)); + Assert.That(response.Value, Is.EqualTo(generated.DMXAddress)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(0)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(19)); + Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); + #endregion + + #region Test Get last Message + request.ParameterData = new byte[] { (byte)ERDM_Status.GET_LAST_MESSAGE }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(0)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(19)); + Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); + #endregion + + #region Test set DMX-Address (multiple value changed) + Assert.That(generated.DMXAddress, Is.EqualTo(42)); + generated.DMXAddress = 50; + Assert.That(generated.DMXAddress, Is.EqualTo(50)); + generated.DMXAddress = 60; + Assert.That(generated.DMXAddress, Is.EqualTo(60)); + generated.DMXAddress = 70; + Assert.That(generated.DMXAddress, Is.EqualTo(70)); + generated.DMXAddress = 80; + Assert.That(generated.DMXAddress, Is.EqualTo(80)); + + request.ParameterData = new byte[] { (byte)ERDM_Status.ERROR }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_START_ADDRESS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(1)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(2)); + Assert.That(response.Value, Is.EqualTo(generated.DMXAddress)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(0)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(19)); + Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); + #endregion + + #region Test set DeviceLabel (single value changed) + var deviceLabelModule = generated.Modules.OfType().FirstOrDefault(); + Assert.That(deviceLabelModule, Is.Not.Null); + Assert.That(deviceLabelModule.DeviceLabel, Is.EqualTo("Dummy Device 1")); + deviceLabelModule.DeviceLabel = "Test Device Queued Message 1"; + Assert.That(deviceLabelModule.DeviceLabel, Is.EqualTo("Test Device Queued Message 1")); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(0)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(deviceLabelModule.DeviceLabel.Length)); + Assert.That(response.Value, Is.EqualTo(deviceLabelModule.DeviceLabel)); + #endregion + + #region Test set Multiple Parameter at once + deviceLabelModule.DeviceLabel = "GG"; + Assert.That(deviceLabelModule.DeviceLabel, Is.EqualTo("GG")); + generated.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, true); + generated.CurrentPersonalityId = 2; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(13)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(deviceLabelModule.DeviceLabel.Length)); + Assert.That(response.Value, Is.EqualTo(deviceLabelModule.DeviceLabel)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(12)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(1)); + Assert.That(response.Value, Is.EqualTo(true)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(11)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(2)); + Assert.That(response.Value, Is.EqualTo(new RDMDMXPersonality(2, 3))); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(10)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(19)); + Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_INFO)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(9)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(40)); + Assert.That(response.Value, Is.EqualTo(generated.Personalities.ElementAt(1).Slots.Select(s => new RDMSlotInfo(s.Value.SlotId, s.Value.Type, s.Value.Category)))); + + for (byte b = 0; b < generated.Personalities.ElementAt(1).SlotCount; b++) + { + var slot = generated.Personalities.ElementAt(1).Slots[b]; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(8 - b)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(generated.Personalities.ElementAt(1).Slots[b].Description.Length + 2)); + Assert.That(response.Value, Is.EqualTo(new RDMSlotDescription(slot.SlotId, slot.Description))); + } + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEFAULT_SLOT_VALUE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(0)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3 * generated.Personalities.ElementAt(1).Slots.Count)); + Assert.That(response.Value, Is.EqualTo(generated.Personalities.ElementAt(1).Slots.Select(s => new RDMDefaultSlotValue(s.Value.SlotId, s.Value.DefaultValue)))); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(0)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + #endregion + + request.ParameterData = new byte[] { (byte)ERDM_Status.ADVISORY }; + var sm = new RDMStatusMessage(0, ERDM_Status.ADVISORY, ERDM_StatusMessage.AMPS, 222); + generated.AddStatusMessage(sm); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(0)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); + RDMStatusMessage[] messages = (RDMStatusMessage[])response.Value; + Assert.That(messages[0], Is.EqualTo(sm)); + + #region + request.ParameterData = new byte[] { (byte)ERDM_Status.NONE }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.QUEUED_MESSAGE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(0)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + #endregion + + #region CLEAR_STATUS_ID + request.ParameterData = new byte[] { }; + request.Parameter = ERDM_Parameter.CLEAR_STATUS_ID; + request.Command = ERDM_Command.SET_COMMAND; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CLEAR_STATUS_ID)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(0)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + #endregion + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestRealTimeClockModule.cs b/RDMSharpTests/Devices/Modules/TestRealTimeClockModule.cs new file mode 100644 index 00000000..0b3a1a4d --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestRealTimeClockModule.cs @@ -0,0 +1,115 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestRealTimeClockModule +{ + private RealTimeClockModuleMockDevice? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(876, 555198); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public async Task Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new RealTimeClockModuleMockDevice(DEVCIE_UID); + while (!generated.IsInitialized) + await Task.Delay(100); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Retry(3), Order(1)] + public async Task TestGetREAL_TIME_CLOCK() + { + await Task.Delay(500); + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Parameters.Contains(ERDM_Parameter.REAL_TIME_CLOCK), Is.True); + await Task.Delay(1000); + var realTimeClockModule = generated.Modules.OfType().FirstOrDefault(); + Assert.That(realTimeClockModule, Is.Not.Null); + Assert.That(realTimeClockModule.RealTimeClock, Is.Not.Null); + Assert.That(realTimeClockModule.RealTimeClock.Value.Minute, Is.EqualTo(DateTime.Now.Minute)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.REAL_TIME_CLOCK, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.REAL_TIME_CLOCK)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(7)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMRealTimeClock))); + var timeGen = new RDMRealTimeClock(realTimeClockModule.RealTimeClock.Value); + var timeRem = (RDMRealTimeClock)response.Value; + Assert.That(timeRem.Year, Is.EqualTo(timeGen.Year)); + Assert.That(timeRem.Month, Is.EqualTo(timeGen.Month)); + Assert.That(timeRem.Day, Is.EqualTo(timeGen.Day)); + Assert.That(timeRem.Minute, Is.EqualTo(timeGen.Minute)); + Assert.That(timeRem.Second, Is.AtLeast(timeGen.Second - 2).And.AtMost(timeGen.Second + 2)); + #endregion + + } + + [Test, Retry(3), Order(301)] + public async Task TestRemoteDevice() + { + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Parameters.Contains(ERDM_Parameter.REAL_TIME_CLOCK), Is.True); + var generatedModule = generated.Modules.OfType().Single(); + Assert.That(generatedModule, Is.Not.Null); + Assert.That(generatedModule.RealTimeClock, Is.Not.Null); + Assert.That(generatedModule.RealTimeClock.Value.Minute, Is.EqualTo(DateTime.Now.Minute)); + + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + + bool parameterPresent = mockDevice.DeviceModel.GetSupportedParameters().Any(sp => sp.Parameter == ERDM_Parameter.REAL_TIME_CLOCK); + Assert.That(parameterPresent, Is.True); + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.RealTimeClock, Is.Not.Null); + Assert.That(module.RealTimeClock.Value.Minute, Is.EqualTo(DateTime.Now.Minute)); + + SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 1); + module.PropertyChanged += (o, e) => + { + semaphoreSlim.Release(); + }; + DateTime newDate = new DateTime(2026, 12, 30, 23, 29, 45); + module.RealTimeClock = newDate; + await semaphoreSlim.WaitAsync(); + } + + class RealTimeClockModuleMockDevice : MockGeneratedDevice1 + { + public RealTimeClockModuleMockDevice(UID uid) : base(uid, new IModule[] { new RealTimeClockModule() }) + { + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestSensorsModule.cs b/RDMSharpTests/Devices/Modules/TestSensorsModule.cs new file mode 100644 index 00000000..252c08e2 --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestSensorsModule.cs @@ -0,0 +1,333 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestSensorsModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(51)] + public void TestGetSENSOR_DEFINITION() + { + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.SENSOR_DEFINITION, + SubDevice = SubDevice.Root, + }; + RDMMessage? response = null; + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Sensors, Has.Count.EqualTo(5)); + doTests(generated.Sensors.Values.ToArray()); + #endregion + + void doTests(Sensor[] sensors) + { + foreach (Sensor sensor in sensors) + { + request.ParameterData = new byte[] { sensor.SensorId }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_DEFINITION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(13 + sensor.Description.Length)); + Assert.That(response.Value, Is.EqualTo(new RDMSensorDefinition(sensor.SensorId, sensor.Type, sensor.Unit, sensor.Prefix, sensor.RangeMinimum, sensor.RangeMaximum, sensor.NormalMinimum, sensor.NormalMaximum, sensor.LowestHighestValueSupported, sensor.RecordedValueSupported, sensor.Description))); + } + } + } + + [Test, Order(52)] + public void TestGetSENSOR_VALUE() + { + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.SENSOR_VALUE, + SubDevice = SubDevice.Root, + }; + RDMMessage? response = null; + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.Multiple(() => + { + Assert.That(generated.Sensors, Has.Count.EqualTo(5)); + + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(3000)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(8000)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(12000)); + + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); + + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(0)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(0)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(0)); + }); + + doTests(generated.Sensors.Values.ToArray()); + #endregion + + #region Test New Sensor Values + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Sensors, Has.Count.EqualTo(5)); + ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(99); + ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(122); + ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(155); + + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(99)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(122)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(155)); + + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(99)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(122)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(155)); + + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); + }); + doTests(generated.Sensors.Values.ToArray()); + #endregion + + #region Test Recorded Sensor Values + Assert.Multiple(() => + { + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Sensors, Has.Count.EqualTo(5)); + Assert.That(generated.Sensors[0].RecordedValueSupported, Is.True); + Assert.That(generated.Sensors[1].RecordedValueSupported, Is.True); + Assert.That(generated.Sensors[2].RecordedValueSupported, Is.True); + Assert.That(generated.Sensors[0].LowestHighestValueSupported, Is.True); + Assert.That(generated.Sensors[1].LowestHighestValueSupported, Is.True); + Assert.That(generated.Sensors[2].LowestHighestValueSupported, Is.True); + }); + + ((MockGeneratedSensor)generated.Sensors[0]).RecordValue(); + ((MockGeneratedSensor)generated.Sensors[1]).RecordValue(); + ((MockGeneratedSensor)generated.Sensors[2]).RecordValue(); + + ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(111); + ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(666); + ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(987); + + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(99)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(122)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(155)); + + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(111)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(666)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(987)); + + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(99)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(122)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(155)); + + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); + }); + doTests(generated.Sensors.Values.ToArray()); + #endregion + + #region Test Reset Sensor Values Set_Request + request.Command = ERDM_Command.SET_COMMAND; + for (byte b = 0; b < 2; b++) + { + request.ParameterData = new byte[] { b }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.Multiple(() => + { + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_VALUE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9)); + Assert.That(response.ParameterData[0], Is.EqualTo(b)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMSensorValue))); + }); + } + #endregion + + #region Test Reset Sensor Values Set_Request (Broadcast) + request.ParameterData = new byte[] { 0xff }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.Multiple(() => + { + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_VALUE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9)); + Assert.That(response.ParameterData[0], Is.EqualTo(0xff)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMSensorValue))); + }); + foreach (var generatedSensor in generated.Sensors.Values) + { + Assert.Multiple(() => + { + Assert.That(generatedSensor, Is.Not.Null); + Sensor remoteSensor = generated.Sensors[generatedSensor.SensorId]; + Assert.That(remoteSensor, Is.Not.Null); + Assert.That(remoteSensor.PresentValue, Is.EqualTo(generatedSensor.PresentValue)); + Assert.That(remoteSensor.LowestValue, Is.EqualTo(generatedSensor.LowestValue)); + Assert.That(remoteSensor.HighestValue, Is.EqualTo(generatedSensor.HighestValue)); + Assert.That(remoteSensor.RecordedValue, Is.EqualTo(generatedSensor.RecordedValue)); + }); + } + #endregion + + void doTests(Sensor[] sensors) + { + foreach (Sensor sensor in sensors) + { + request.ParameterData = new byte[] { sensor.SensorId }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.Multiple(() => + { + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_VALUE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9)); + Assert.That(response.Value, Is.EqualTo(new RDMSensorValue(sensor.SensorId, sensor.PresentValue, sensor.LowestValue, sensor.HighestValue, sensor.RecordedValue))); + }); + } + } + } + [Test, Order(53)] + public void TestGetRECORD_SENSORS() + { + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.RECORD_SENSORS, + SubDevice = SubDevice.Root, + }; + RDMMessage? response = null; + + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Sensors, Has.Count.EqualTo(5)); + + #region Test Recorded Sensor Values Set_Request + for (byte b = 0; b < 2; b++) + { + request.ParameterData = new byte[] { b }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.Multiple(() => + { + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RECORD_SENSORS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + }); + } + #endregion + + #region Test Recorded Sensor Values Set_Request (Broadcast) + request.ParameterData = new byte[] { 0xff }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.Multiple(() => + { + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RECORD_SENSORS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + }); + foreach (var generatedSensor in generated.Sensors.Values) + { + Assert.Multiple(() => + { + Assert.That(generatedSensor, Is.Not.Null); + Sensor remoteSensor = generated.Sensors[generatedSensor.SensorId]; + Assert.That(remoteSensor, Is.Not.Null); + Assert.That(remoteSensor.PresentValue, Is.EqualTo(generatedSensor.PresentValue)); + Assert.That(remoteSensor.LowestValue, Is.EqualTo(generatedSensor.LowestValue)); + Assert.That(remoteSensor.HighestValue, Is.EqualTo(generatedSensor.HighestValue)); + Assert.That(remoteSensor.RecordedValue, Is.EqualTo(generatedSensor.RecordedValue)); + }); + } + #endregion + + #region Test Invalid Calls + request.ParameterData = new byte[] { 30 }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RECORD_SENSORS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + request.ParameterData = new byte[] { 2 }; + request.Command = ERDM_Command.GET_COMMAND; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RECORD_SENSORS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS)); + #endregion + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestSlotModule.cs b/RDMSharpTests/Devices/Modules/TestSlotModule.cs new file mode 100644 index 00000000..e9ed9996 --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestSlotModule.cs @@ -0,0 +1,283 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestSlotModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(12538, 619451964); + private static UID DEVCIE_UID = new UID(0x5ab9, 55229915); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(40)] + public void TestGetSLOT_INFO() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Slots, Has.Count.EqualTo(5)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.SLOT_INFO, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_INFO)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5 * generated.Slots.Count)); + Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMSlotInfo(s.Value.SlotId, s.Value.Type, s.Value.Category)))); + #endregion + + #region Test Change Personality + Assert.That(generated, Is.Not.Null); + generated.CurrentPersonalityId = 2; // Change to personality 2 + Assert.That(generated.Slots, Has.Count.EqualTo(8)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_INFO)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5 * generated.Slots.Count)); + Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMSlotInfo(s.Value.SlotId, s.Value.Type, s.Value.Category)))); + #endregion + + #region Test Change Personality + Assert.That(generated, Is.Not.Null); + generated.CurrentPersonalityId = 3; // Change to personality 3 + Assert.That(generated.Slots, Has.Count.EqualTo(9)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_INFO)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(5 * generated.Slots.Count)); + Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMSlotInfo(s.Value.SlotId, s.Value.Type, s.Value.Category)))); + #endregion + + #region Test Invalid Calls + Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonalityId = 0); // Change to personality 0 + Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonalityId = 4); // Change to personality 4 + Assert.DoesNotThrow(() => generated.CurrentPersonalityId = 3); // Change to personality 3 + #endregion + } + + [Test, Order(41)] + public void TestGetDEFAULT_SLOT_VALUE() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Slots, Has.Count.EqualTo(5)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.DEFAULT_SLOT_VALUE, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEFAULT_SLOT_VALUE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3 * generated.Slots.Count)); + Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMDefaultSlotValue(s.Value.SlotId, s.Value.DefaultValue)))); + #endregion + + #region Test Change Personality + Assert.That(generated, Is.Not.Null); + generated.CurrentPersonalityId = 2; // Change to personality 2 + Assert.That(generated.Slots, Has.Count.EqualTo(8)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEFAULT_SLOT_VALUE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3 * generated.Slots.Count)); + Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMDefaultSlotValue(s.Value.SlotId, s.Value.DefaultValue)))); + #endregion + + #region Test Change Personality + Assert.That(generated, Is.Not.Null); + generated.CurrentPersonalityId = 3; // Change to personality 3 + Assert.That(generated.Slots, Has.Count.EqualTo(9)); + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEFAULT_SLOT_VALUE)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(3 * generated.Slots.Count)); + Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMDefaultSlotValue(s.Value.SlotId, s.Value.DefaultValue)))); + #endregion + + #region Test Invalid Calls + Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonalityId = 0); // Change to personality 0 + Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonalityId = 4); // Change to personality 4 + Assert.DoesNotThrow(() => generated.CurrentPersonalityId = 3); // Change to personality 3 + #endregion + } + + [Test, Order(42)] + public void TestGetSLOT_DESCRIPTION() + { + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.SLOT_DESCRIPTION, + SubDevice = SubDevice.Root, + }; + RDMMessage? response = null; + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Slots, Has.Count.EqualTo(5)); + doTests(generated.Slots.Values.ToArray()); + #endregion + + #region Test Change Personality 2 + generated.CurrentPersonalityId = 2; // Change to personality 2 + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Slots, Has.Count.EqualTo(8)); + doTests(generated.Slots.Values.ToArray()); + #endregion + + #region Test Change Personality 3 + generated.CurrentPersonalityId = 3; // Change to personality 3 + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Slots, Has.Count.EqualTo(9)); + doTests(generated.Slots.Values.ToArray()); + #endregion + + #region Test Invalid Calls + Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonalityId = 0); // Change to personality 0 + Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonalityId = 4); // Change to personality 4 + Assert.DoesNotThrow(() => generated.CurrentPersonalityId = 3); // Change to personality 3 + + request.ParameterData = new byte[] { (byte)((10 >> 8) & 0xFF), (byte)(10 & 0xFF) }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + #endregion + + void doTests(Slot[] slots) + { + foreach (Slot slot in slots) + { + request.ParameterData = new byte[] { (byte)((slot.SlotId >> 8) & 0xFF), (byte)(slot.SlotId & 0xFF) }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_DESCRIPTION)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(2 + slot.Description.Length)); + Assert.That(response.Value, Is.EqualTo(new RDMSlotDescription(slot.SlotId, slot.Description))); + } + } + } + + [Test, Order(301)] + public async Task TestRemoteDevice() + { + Assert.That(generated, Is.Not.Null); + var generatedModule = generated.Modules.OfType().Single(); + Assert.That(generatedModule, Is.Not.Null); + Assert.That(generatedModule.Slots, Is.Not.Null); + Assert.That(generatedModule.Slots, Has.Count.EqualTo(5)); + + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + + var module = mockDevice.Modules.OfType().Single(); + var personalityModule = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(module.Slots, Is.Not.Null); + Assert.That(module.Slots, Has.Count.EqualTo(5)); + Assert.That(personalityModule.CurrentPersonality.ID, Is.EqualTo(1)); + Assert.That(personalityModule.CurrentPersonality.SlotCount, Is.EqualTo(5)); + + SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 1); + personalityModule.PropertyChanged += (o, e) => + { + semaphoreSlim.Release(); + }; + await personalityModule.SetPersonality(2); + await semaphoreSlim.WaitAsync(); + await Task.Delay(1000); + + Assert.That(generatedModule.Slots, Has.Count.EqualTo(8)); + Assert.That(generatedModule.Slots, Is.Not.Null); + while (module.CurrentPersonality.ID != generatedModule.CurrentPersonality.ID) + await Task.Delay(100); + + while (!((RemotePersonality)module.CurrentPersonality).AllDataPulled) + await Task.Delay(100); + + await Task.Delay(100); + Assert.That(personalityModule.CurrentPersonality.SlotCount, Is.EqualTo(8)); + + Assert.That(module.CurrentPersonality.ID, Is.EqualTo(generatedModule.CurrentPersonality.ID)); + Assert.That(module.Slots, Is.Not.Null); + Assert.That(module.Slots, Has.Count.EqualTo(8)); + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestSoftwareVersionModule.cs b/RDMSharpTests/Devices/Modules/TestSoftwareVersionModule.cs new file mode 100644 index 00000000..fbf15ec5 --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestSoftwareVersionModule.cs @@ -0,0 +1,78 @@ +using RDMSharp.Metadata; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestSoftwareVersionModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(32)] + public void TestGetSOFTWARE_VERSION_LABEL() + { + const string SOFTWARE_VERSION_LABEL = "Dummy Software"; + #region Test Basic + Assert.That(generated, Is.Not.Null); + var softwareVersionModule = generated.Modules.OfType().Single(); + Assert.That(softwareVersionModule, Is.Not.Null); + Assert.That(softwareVersionModule.SoftwareVersionLabel, Is.EqualTo(SOFTWARE_VERSION_LABEL)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.SOFTWARE_VERSION_LABEL, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SOFTWARE_VERSION_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(SOFTWARE_VERSION_LABEL.Length)); + Assert.That(response.Value, Is.EqualTo(SOFTWARE_VERSION_LABEL)); + #endregion + + #region Test Label changed + softwareVersionModule.SoftwareVersionLabel = "Rem x Ram"; + Assert.That(softwareVersionModule.SoftwareVersionLabel, Is.EqualTo("Rem x Ram")); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SOFTWARE_VERSION_LABEL)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(softwareVersionModule.SoftwareVersionLabel.Length)); + Assert.That(response.Value, Is.EqualTo(softwareVersionModule.SoftwareVersionLabel)); + #endregion + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestStatusMessagesModule.cs b/RDMSharpTests/Devices/Modules/TestStatusMessagesModule.cs new file mode 100644 index 00000000..05448eac --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestStatusMessagesModule.cs @@ -0,0 +1,237 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestStatusMessagesModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(100)] + public void TestGetSTATUS_MESSAGES() + { + #region Test Empty Status Messages + Assert.That(generated, Is.Not.Null); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.STATUS_MESSAGES, + SubDevice = SubDevice.Root, + ParameterData = new byte[] { (byte)ERDM_Status.ERROR } + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + #endregion + + #region Test Basic Status Messages + generated.AddStatusMessage(new RDMStatusMessage( + subDeviceId: 0, + statusType: ERDM_Status.ERROR, + statusMessage: ERDM_StatusMessage.OVERCURRENT, + dataValue1: 1234, + dataValue2: 5678)); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); + RDMStatusMessage[] statusMessages = (RDMStatusMessage[])response.Value; + Assert.That(statusMessages[0], Is.EqualTo(generated.StatusMessages[0])); + + generated.AddStatusMessage(new RDMStatusMessage( + subDeviceId: 0, + statusType: ERDM_Status.ERROR, + statusMessage: ERDM_StatusMessage.UNDERTEMP, + dataValue1: 33, + dataValue2: 12)); + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(18)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); + statusMessages = (RDMStatusMessage[])response.Value; + Assert.That(statusMessages, Has.Length.EqualTo(2)); + Assert.That(statusMessages[0], Is.EqualTo(generated.StatusMessages[0])); + Assert.That(statusMessages[1], Is.EqualTo(generated.StatusMessages[1])); + #endregion + + #region Test Overflow + for (byte i = 0; i < 30; i++) + { + generated.AddStatusMessage(new RDMStatusMessage( + subDeviceId: i, + statusType: ERDM_Status.ADVISORY, + statusMessage: ERDM_StatusMessage.WATTS, + dataValue1: 33, + dataValue2: 12)); + } + + request.ParameterData = new byte[] { (byte)ERDM_Status.ADVISORY }; + response = generated.ProcessRequestMessage_Internal(request); + + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK_OVERFLOW)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9 * 25)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); + statusMessages = (RDMStatusMessage[])response.Value; + Assert.That(statusMessages, Has.Length.EqualTo(25)); + for (int i = 0; i < 25; i++) + Assert.That(statusMessages[i], Is.EqualTo(generated.StatusMessages[i])); + + response = generated.ProcessRequestMessage_Internal(request); + + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9 * 7)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); + statusMessages = (RDMStatusMessage[])response.Value; + Assert.That(statusMessages, Has.Length.EqualTo(7)); + for (int i = 0; i < 7; i++) + Assert.That(statusMessages[i], Is.EqualTo(generated.StatusMessages[i + 25])); + #endregion + + #region Test GET_LAST_MESSAGE + request.ParameterData = new byte[] { (byte)ERDM_Status.GET_LAST_MESSAGE }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(9 * 7)); + Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); + statusMessages = (RDMStatusMessage[])response.Value; + Assert.That(statusMessages, Has.Length.EqualTo(7)); + for (int i = 0; i < 7; i++) + Assert.That(statusMessages[i], Is.EqualTo(generated.StatusMessages[i + 25])); + #endregion + + #region Test filtering by status type + request.ParameterData = new byte[] { (byte)ERDM_Status.ERROR }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(18)); + statusMessages = (RDMStatusMessage[])response.Value; + for (int i = 0; i < 2; i++) + Assert.That(statusMessages[i], Is.EqualTo(generated.StatusMessages[i])); + #endregion + + #region Test Cleared Status Messages + generated.ClearStatusMessage(generated.StatusMessages[0]); + request.ParameterData = new byte[] { (byte)ERDM_Status.ERROR }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(18)); + statusMessages = (RDMStatusMessage[])response.Value; + Assert.That(statusMessages[0].EStatusType, Is.EqualTo(ERDM_Status.ERROR_CLEARED)); + for (int i = 0; i < 2; i++) + Assert.That(statusMessages[i], Is.EqualTo(generated.StatusMessages[i])); + #endregion + + #region Test Remove Status Messages + foreach (RDMStatusMessage statusMessage in generated.StatusMessages.Values.ToArray()) + generated.RemoveStatusMessage(statusMessage); + + request.ParameterData = new byte[] { (byte)ERDM_Status.ADVISORY }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + #endregion + + + #region CLEAR_STATUS_ID + generated.AddStatusMessage(new RDMStatusMessage( + subDeviceId: 0, + statusType: ERDM_Status.ERROR, + statusMessage: ERDM_StatusMessage.OVERCURRENT, + dataValue1: 1234, + dataValue2: 5678)); + request.ParameterData = new byte[] { }; + request.Parameter = ERDM_Parameter.CLEAR_STATUS_ID; + request.Command = ERDM_Command.SET_COMMAND; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CLEAR_STATUS_ID)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.MessageCounter, Is.EqualTo(0)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + #endregion + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestSupportedParametersModule.cs b/RDMSharpTests/Devices/Modules/TestSupportedParametersModule.cs new file mode 100644 index 00000000..13eb54fd --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestSupportedParametersModule.cs @@ -0,0 +1,61 @@ +using RDMSharp.Metadata; +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestSupportedParametersModule +{ + private MockGeneratedDevice1? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(123, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new MockGeneratedDevice1(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + [Test, Order(1)] + public void TestGetSUPPORTED_PARAMETERS() + { + #region Test Basic + Assert.That(generated, Is.Not.Null); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.SUPPORTED_PARAMETERS, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SUPPORTED_PARAMETERS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(generated.Parameters.Count * 2)); + Assert.That(response.Value, Is.TypeOf(typeof(ERDM_Parameter[]))); + var parametersRemote = ((ERDM_Parameter[])response.Value).OrderBy(p => p).ToArray(); + var parametersGenerated = generated.Parameters.OrderBy(p => p).ToArray(); + Assert.That(parametersRemote, Is.EquivalentTo(parametersGenerated)); + #endregion + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/Modules/TestTagModlue.cs b/RDMSharpTests/Devices/Modules/TestTagModlue.cs new file mode 100644 index 00000000..816040ba --- /dev/null +++ b/RDMSharpTests/Devices/Modules/TestTagModlue.cs @@ -0,0 +1,849 @@ +using RDMSharp.Metadata; +using RDMSharp.RDM.Device.Module; +using RDMSharpTests.Devices.Mock; +using System.Text; + +namespace RDMSharpTests.RDM.Devices.Modules; + +public class TestTagModlue +{ + private TagsMockDevice? generated; + + private static UID CONTROLLER_UID = new UID(0x1fff, 333); + private static UID DEVCIE_UID = new UID(0x1e2e, 555); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() + { + var defines = MetadataFactory.GetMetadataDefineVersions(); + generated = new TagsMockDevice(DEVCIE_UID); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + } + + + [Test, Retry(3), Order(1)] + public void TestGetLIST_TAGS() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + var tagsModule = generated.Modules.OfType().FirstOrDefault(); + Assert.That(tagsModule, Is.Not.Null); + Assert.That(tagsModule.Tags, Is.Not.Null); + Assert.That(tagsModule.Tags, Has.Count.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.LIST_TAGS, + SubDevice = SubDevice.Root, + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.LIST_TAGS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + #endregion + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ADD_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.UTF8.GetBytes("Backtruss") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.LIST_TAGS, + SubDevice = SubDevice.Root, + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.LIST_TAGS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(10)); + + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ADD_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.UTF8.GetBytes("Center") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.LIST_TAGS, + SubDevice = SubDevice.Root, + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.LIST_TAGS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(17)); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CHECK_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.UTF8.GetBytes("Center") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CHECK_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(1)); + Assert.That(response.Value, Is.EqualTo(true)); + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.REMOVE_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.UTF8.GetBytes("Center") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.REMOVE_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.LIST_TAGS, + SubDevice = SubDevice.Root, + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.LIST_TAGS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(10)); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CHECK_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.UTF8.GetBytes("Center") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CHECK_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(1)); + Assert.That(response.Value, Is.EqualTo(false)); + + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CLEAR_TAGS, + SubDevice = SubDevice.Root + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CLEAR_TAGS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.LIST_TAGS, + SubDevice = SubDevice.Root, + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.LIST_TAGS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + } + [Test, Retry(3), Order(2)] + public void TestSetADD_TAG() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + var tagsModule = generated.Modules.OfType().FirstOrDefault(); + Assert.That(tagsModule, Is.Not.Null); + Assert.That(tagsModule.Tags, Is.Not.Null); + Assert.That(tagsModule.Tags, Has.Count.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ADD_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes("Backtruss") + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + #endregion + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ADD_TAG, + SubDevice = SubDevice.Root + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ADD_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes(" ") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ADD_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes("asdfghjkljhgfdsdfghjhgfdsdfghjjhgfdsdfghjjhgfdfghjhgfdfghjhgfdfghjhgfdfghjjgfdfghj") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ADD_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes("GeNeRaTeHaRdWaReFaUlT") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.ADD_TAG, + SubDevice = SubDevice.Root, + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS)); + } + [Test, Retry(3), Order(3)] + public void TestSetREMOVE_TAG() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + var tagsModule = generated.Modules.OfType().FirstOrDefault(); + Assert.That(tagsModule, Is.Not.Null); + Assert.That(tagsModule.Tags, Is.Not.Null); + Assert.That(tagsModule.Tags, Has.Count.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.REMOVE_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes("Backtruss") + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.REMOVE_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + #endregion + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.REMOVE_TAG, + SubDevice = SubDevice.Root + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.REMOVE_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.REMOVE_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes(" ") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.REMOVE_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.REMOVE_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes("asdfghjkljhgfdsdfghjhgfdsdfghjjhgfdsdfghjjhgfdfghjhgfdfghjhgfdfghjhgfdfghjjgfdfghj") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.REMOVE_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.REMOVE_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes("GeNeRaTeHaRdWaReFaUlT") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.REMOVE_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.REMOVE_TAG, + SubDevice = SubDevice.Root, + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.REMOVE_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS)); + } + [Test, Retry(3), Order(3)] + public void TestSetCHECK_TAG() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + var tagsModule = generated.Modules.OfType().FirstOrDefault(); + Assert.That(tagsModule, Is.Not.Null); + Assert.That(tagsModule.Tags, Is.Not.Null); + Assert.That(tagsModule.Tags, Has.Count.EqualTo(0)); + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CHECK_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes("Backtruss") + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CHECK_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(1)); + Assert.That(response.Value, Is.False); + #endregion + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CHECK_TAG, + SubDevice = SubDevice.Root + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CHECK_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CHECK_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes(" ") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CHECK_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.FORMAT_ERROR)); + + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CHECK_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes("asdfghjkljhgfdsdfghjhgfdsdfghjjhgfdsdfghjjhgfdfghjhgfdfghjhgfdfghjhgfdfghjjgfdfghj") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CHECK_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.DATA_OUT_OF_RANGE)); + + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CHECK_TAG, + SubDevice = SubDevice.Root, + ParameterData = Encoding.ASCII.GetBytes("GeNeRaTeHaRdWaReFaUlT") + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CHECK_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CHECK_TAG, + SubDevice = SubDevice.Root, + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CHECK_TAG)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS)); + } + + [Test, Retry(3), Order(4)] + public void TestSetCLEAR_TAG() + { + #region Test Basic (Empty) + Assert.That(generated, Is.Not.Null); + var tagsModule = generated.Modules.OfType().FirstOrDefault(); + Assert.That(tagsModule, Is.Not.Null); + Assert.That(tagsModule.Tags, Is.Not.Null); + Assert.That(tagsModule.Tags, Has.Count.EqualTo(0)); + + RDMMessage request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CLEAR_TAGS, + SubDevice = SubDevice.Root + }; + + RDMMessage? response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CLEAR_TAGS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); + Assert.That(response.ParameterData, Has.Length.EqualTo(0)); + #endregion + + request = new RDMMessage() + { + Command = ERDM_Command.SET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = new UID(0xeeee, 0xf0f0f0f0),//Hardware Failure trigger + Parameter = ERDM_Parameter.CLEAR_TAGS, + SubDevice = SubDevice.Root + }; + + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.Not.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CLEAR_TAGS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.HARDWARE_FAULT)); + + request = new RDMMessage() + { + Command = ERDM_Command.GET_COMMAND, + DestUID = DEVCIE_UID, + SourceUID = CONTROLLER_UID, + Parameter = ERDM_Parameter.CLEAR_TAGS, + SubDevice = SubDevice.Root + }; + response = generated.ProcessRequestMessage_Internal(request); + Assert.That(response, Is.Not.Null); + Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND_RESPONSE)); + Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); + Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); + Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CLEAR_TAGS)); + Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); + Assert.That(response.NackReason, Is.EqualTo(ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS)); + } + + [Test, Retry(3), Order(301)] + public async Task TestRemoteDevice() + { + Assert.That(generated, Is.Not.Null); + Assert.That(generated.Parameters.Contains(ERDM_Parameter.LIST_TAGS), Is.True); + var generatedModule = generated.Modules.OfType().Single(); + Assert.That(generatedModule, Is.Not.Null); + Assert.That(generatedModule.Tags, Is.Not.Null); + + MockDevice mockDevice = new MockDevice(DEVCIE_UID); + while (!mockDevice.IsInitialized) + await Task.Delay(100); + + bool parameterPresent = mockDevice.DeviceModel.GetSupportedParameters().Any(sp => sp.Parameter == ERDM_Parameter.LIST_TAGS); + Assert.That(parameterPresent, Is.True); + var module = mockDevice.Modules.OfType().Single(); + Assert.That(module, Is.Not.Null); + Assert.That(generatedModule.Tags, Is.Not.Null); + + SemaphoreSlim semaphoreSlim = new SemaphoreSlim(0, 1); + module.PropertyChanged += (o, e) => + { + semaphoreSlim.Release(); + }; + const string FRONT_TRUSS = "Front-Truss"; + const string MID_TRUSS = "Mid-Truss"; + const string BACK_TRUSS = "Back-Truss"; + + await module.AddTag(FRONT_TRUSS); + await semaphoreSlim.WaitAsync(); + + Assert.That(generatedModule.Tags.ToArray(), Does.Contain(FRONT_TRUSS)); + Assert.That(module.Tags.ToArray(), Does.Contain(FRONT_TRUSS)); + + semaphoreSlim = new SemaphoreSlim(0, 1); + await module.AddTag(MID_TRUSS); + await semaphoreSlim.WaitAsync(); + + Assert.That(generatedModule.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(MID_TRUSS)); + Assert.That(module.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(MID_TRUSS)); + + semaphoreSlim = new SemaphoreSlim(0, 1); + await module.AddTag(BACK_TRUSS); + await semaphoreSlim.WaitAsync(); + + Assert.That(generatedModule.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(MID_TRUSS).And.Contain(BACK_TRUSS)); + Assert.That(module.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(MID_TRUSS).And.Contain(BACK_TRUSS)); + + + Assert.That(await module.CheckTag(FRONT_TRUSS), Is.True); + Assert.That(await module.CheckTag(MID_TRUSS), Is.True); + Assert.That(await module.CheckTag(BACK_TRUSS), Is.True); + + semaphoreSlim = new SemaphoreSlim(0, 1); + await module.RemoveTag(MID_TRUSS); + await semaphoreSlim.WaitAsync(); + + Assert.That(generatedModule.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(BACK_TRUSS)); + Assert.That(module.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(BACK_TRUSS)); + + Assert.That(await module.CheckTag(FRONT_TRUSS), Is.True); + Assert.That(await module.CheckTag(MID_TRUSS), Is.False); + Assert.That(await module.CheckTag(BACK_TRUSS), Is.True); + + await module.ClearTags(); + + Assert.That(await module.CheckTag(FRONT_TRUSS), Is.False); + Assert.That(await module.CheckTag(MID_TRUSS), Is.False); + Assert.That(await module.CheckTag(BACK_TRUSS), Is.False); + + Assert.That(generatedModule.Tags.ToArray(), Does.Not.Contain(FRONT_TRUSS).And.Not.Contain(MID_TRUSS).And.Not.Contain(BACK_TRUSS)); + + + + await generatedModule.AddTag(FRONT_TRUSS); + await semaphoreSlim.WaitAsync(); + + Assert.That(generatedModule.Tags.ToArray(), Does.Contain(FRONT_TRUSS)); + Assert.That(module.Tags.ToArray(), Does.Contain(FRONT_TRUSS)); + + semaphoreSlim = new SemaphoreSlim(0, 1); + await generatedModule.AddTag(MID_TRUSS); + await semaphoreSlim.WaitAsync(); + + Assert.That(generatedModule.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(MID_TRUSS)); + Assert.That(module.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(MID_TRUSS)); + + semaphoreSlim = new SemaphoreSlim(0, 1); + await generatedModule.AddTag(BACK_TRUSS); + await semaphoreSlim.WaitAsync(); + + Assert.That(generatedModule.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(MID_TRUSS).And.Contain(BACK_TRUSS)); + Assert.That(module.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(MID_TRUSS).And.Contain(BACK_TRUSS)); + + + Assert.That(await generatedModule.CheckTag(FRONT_TRUSS), Is.True); + Assert.That(await generatedModule.CheckTag(MID_TRUSS), Is.True); + Assert.That(await generatedModule.CheckTag(BACK_TRUSS), Is.True); + + semaphoreSlim = new SemaphoreSlim(0, 1); + await generatedModule.RemoveTag(MID_TRUSS); + await semaphoreSlim.WaitAsync(); + + Assert.That(generatedModule.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(BACK_TRUSS)); + Assert.That(module.Tags.ToArray(), Does.Contain(FRONT_TRUSS).And.Contain(BACK_TRUSS)); + + Assert.That(await generatedModule.CheckTag(FRONT_TRUSS), Is.True); + Assert.That(await generatedModule.CheckTag(MID_TRUSS), Is.False); + Assert.That(await generatedModule.CheckTag(BACK_TRUSS), Is.True); + + await generatedModule.ClearTags(); + + Assert.That(await generatedModule.CheckTag(FRONT_TRUSS), Is.False); + Assert.That(await generatedModule.CheckTag(MID_TRUSS), Is.False); + Assert.That(await generatedModule.CheckTag(BACK_TRUSS), Is.False); + + Assert.That(generatedModule.Tags.ToArray(), Does.Not.Contain(FRONT_TRUSS).And.Not.Contain(MID_TRUSS).And.Not.Contain(BACK_TRUSS)); + } + + class TagsMockDevice : MockGeneratedDevice1 + { + public TagsMockDevice(UID uid) : base(uid, new IModule[] { new TagsModule() }) + { + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Devices/TestRDMDiscovery.cs b/RDMSharpTests/Devices/TestRDMDiscovery.cs index 8396b081..f31004d2 100644 --- a/RDMSharpTests/Devices/TestRDMDiscovery.cs +++ b/RDMSharpTests/Devices/TestRDMDiscovery.cs @@ -1,394 +1,402 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; using RDMSharpTests.Devices.Mock; -namespace RDMSharpTests.RDM.Devices +namespace RDMSharpTests.RDM.Devices; + +[SingleThreaded] +public class TestRDMDiscovery { - [SingleThreaded] - public class TestRDMDiscovery + private static readonly Random random = new Random(); + private readonly List mockDevices = new List(); + private MockDiscoveryTool? mockDiscoveryTool; + private List? expected; + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() { - private static readonly Random random = new Random(); - private readonly List mockDevices = new List(); - private MockDiscoveryTool? mockDiscoveryTool; - private List? expected; - [SetUp] - public void Setup() - { - if (GlobalTestSetup.IsRunningOnGitHubActions()) - Assert.Ignore("This test is not supported on GitHub Actions due to the long execution time."); + if (GlobalTestSetup.IsRunningOnGitHubActions()) + Assert.Ignore("This test is not supported on GitHub Actions due to the long execution time."); - GlobalTestSetup.ImitateRealConditions = true; - mockDiscoveryTool = new MockDiscoveryTool(); - } - [TearDown] - public void Teardown() - { - GlobalTestSetup.ImitateRealConditions = false; - foreach (IDisposable m in mockDevices) - m.Dispose(); + GlobalTestSetup.ImitateRealConditions = true; + mockDiscoveryTool = new MockDiscoveryTool(); + } + [TearDown] + public void Teardown() + { + GlobalTestSetup.ImitateRealConditions = false; + foreach (IDisposable m in mockDevices) + m.Dispose(); - mockDevices.Clear(); - mockDiscoveryTool?.Dispose(); - mockDiscoveryTool = null; - expected?.Clear(); - expected = null; - } + mockDevices.Clear(); + mockDiscoveryTool?.Dispose(); + mockDiscoveryTool = null; + expected?.Clear(); + expected = null; + } - private class DiscoveryProgress : IProgress - { - public event EventHandler? ProgressChanged; - public RDMDiscoveryStatus status { get; private set; } = new RDMDiscoveryStatus(); - public void Report(RDMDiscoveryStatus value) - { - status = value; - ProgressChanged?.Invoke(this, value); - } - } - [Test, Retry(3), CancelAfter(120000)] - public void TestDiscoveryProgress() + private class DiscoveryProgress : IProgress + { + public event EventHandler? ProgressChanged; + public RDMDiscoveryStatus status { get; private set; } = new RDMDiscoveryStatus(); + public void Report(RDMDiscoveryStatus value) { - var progress = new DiscoveryProgress(); - progress.Report(new RDMDiscoveryStatus()); - bool wasCalled= false; - progress.ProgressChanged+= (o,e)=>{ wasCalled = true; }; - Assert.That(wasCalled, Is.False); - progress.Report(new RDMDiscoveryStatus()); - Assert.That(wasCalled, Is.True); - } + status = value; + ProgressChanged?.Invoke(this, value); + } + } + [Test, Retry(3), CancelAfter(120000)] + public void TestDiscoveryProgress() + { + var progress = new DiscoveryProgress(); + progress.Report(new RDMDiscoveryStatus()); + bool wasCalled = false; + progress.ProgressChanged += (o, e) => { wasCalled = true; }; + Assert.That(wasCalled, Is.False); + progress.Report(new RDMDiscoveryStatus()); + Assert.That(wasCalled, Is.True); + } - private async Task AssertDiscovery(bool full = true) - { - ArgumentNullException.ThrowIfNull(mockDiscoveryTool); - ArgumentNullException.ThrowIfNull(expected); + private async Task AssertDiscovery(bool full = true) + { + ArgumentNullException.ThrowIfNull(mockDiscoveryTool); + ArgumentNullException.ThrowIfNull(expected); - var progress = new DiscoveryProgress(); - ulong messageCount = 0; - progress.ProgressChanged += (o, e) => - { - if (e.MessageCount <= messageCount) - return; - messageCount = e.MessageCount; - //Console.WriteLine(e.ToString()); - }; - Assert.That(progress.status.RangeDoneInPercent, Is.EqualTo(0)); - var res = await mockDiscoveryTool!.PerformDiscovery(progress, full); - Assert.Multiple(() => - { - Assert.That(res, Is.EquivalentTo(expected!)); - Assert.That(progress.status.MessageCount, Is.AtLeast(expected!.Count * 3)); - Assert.That(progress.status.FoundDevices, Is.EqualTo(expected!.Count)); - Assert.That(progress.status.RangeLeftToSearch, Is.EqualTo(0)); - Assert.That(progress.status.RangeDoneInPercent, Is.EqualTo(1)); - }); - } - - [Test, Retry(3), CancelAfter(30000)] - public async Task TestDiscoveryMute() - { - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4444))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4445))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4446))); - RDMMessage muteBroadcast = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - DestUID = UID.Broadcast, - SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, - SubDevice = SubDevice.Root, - Parameter = ERDM_Parameter.DISC_MUTE, - }; - - var response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Null); - Assert.That(mockDevices[0].DiscoveryMuted, Is.True); - Assert.That(mockDevices[1].DiscoveryMuted, Is.True); - Assert.That(mockDevices[2].DiscoveryMuted, Is.True); - - RDMMessage unmuteBroadcast = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - DestUID = UID.Broadcast, - SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, - SubDevice = SubDevice.Root, - Parameter = ERDM_Parameter.DISC_UN_MUTE, - }; - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(unmuteBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Null); - Assert.That(mockDevices[0].DiscoveryMuted, Is.False); - Assert.That(mockDevices[1].DiscoveryMuted, Is.False); - Assert.That(mockDevices[2].DiscoveryMuted, Is.False); - muteBroadcast = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - DestUID = UID.Broadcast, - SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, - SubDevice = SubDevice.Root, - Parameter = ERDM_Parameter.DISC_MUTE, - }; - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Null); - Assert.That(mockDevices[0].DiscoveryMuted, Is.True); - Assert.That(mockDevices[1].DiscoveryMuted, Is.True); - Assert.That(mockDevices[2].DiscoveryMuted, Is.True); - - unmuteBroadcast.DestUID = new UID(0x9fff, 4444); - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(unmuteBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(mockDevices[0].DiscoveryMuted, Is.False); - Assert.That(mockDevices[1].DiscoveryMuted, Is.True); - Assert.That(mockDevices[2].DiscoveryMuted, Is.True); - - unmuteBroadcast.DestUID = new UID(0x9fff, 4445); - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(unmuteBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(mockDevices[0].DiscoveryMuted, Is.False); - Assert.That(mockDevices[1].DiscoveryMuted, Is.False); - Assert.That(mockDevices[2].DiscoveryMuted, Is.True); - - muteBroadcast.DestUID = new UID(0x9fff, 4444); - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(mockDevices[0].DiscoveryMuted, Is.True); - Assert.That(mockDevices[1].DiscoveryMuted, Is.False); - Assert.That(mockDevices[2].DiscoveryMuted, Is.True); - - muteBroadcast.DestUID = new UID(0x9fff, 4445); - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(mockDevices[0].DiscoveryMuted, Is.True); - Assert.That(mockDevices[1].DiscoveryMuted, Is.True); - Assert.That(mockDevices[2].DiscoveryMuted, Is.True); - } - [Test, Retry(3), CancelAfter(30000)] - public async Task TestDiscovery_UNIQUE_BRANCH() + var progress = new DiscoveryProgress(); + ulong messageCount = 0; + progress.ProgressChanged += (o, e) => { - mockDevices.Add(new MockGeneratedDevice1(new UID(0b0000000100000001, 0b00000001))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0b1000000101000001, 0b00000010))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0b0000000101000001, 0b00000100))); + if (e.MessageCount <= messageCount) + return; + messageCount = e.MessageCount; + //Console.WriteLine(e.ToString()); + }; + Assert.That(progress.status.RangeDoneInPercent, Is.EqualTo(0)); + var res = await mockDiscoveryTool!.PerformDiscovery(progress, full); + Assert.Multiple(() => + { + Assert.That(res, Is.EquivalentTo(expected!)); + Assert.That(progress.status.MessageCount, Is.AtLeast(expected!.Count * 3)); + Assert.That(progress.status.FoundDevices, Is.EqualTo(expected!.Count)); + Assert.That(progress.status.RangeLeftToSearch, Is.EqualTo(0)); + Assert.That(progress.status.RangeDoneInPercent, Is.EqualTo(1)); + }); + } + + [Test, Retry(3), CancelAfter(30000)] + public async Task TestDiscoveryMute() + { + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4444))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4445))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4446))); + RDMMessage muteBroadcast = new RDMMessage() + { + Command = ERDM_Command.DISCOVERY_COMMAND, + DestUID = UID.Broadcast, + SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, + SubDevice = SubDevice.Root, + Parameter = ERDM_Parameter.DISC_MUTE, + }; + + var response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Null); + Assert.That(mockDevices[0].DiscoveryMuted, Is.True); + Assert.That(mockDevices[1].DiscoveryMuted, Is.True); + Assert.That(mockDevices[2].DiscoveryMuted, Is.True); + + RDMMessage unmuteBroadcast = new RDMMessage() + { + Command = ERDM_Command.DISCOVERY_COMMAND, + DestUID = UID.Broadcast, + SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, + SubDevice = SubDevice.Root, + Parameter = ERDM_Parameter.DISC_UN_MUTE, + }; + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(unmuteBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Null); + Assert.That(mockDevices[0].DiscoveryMuted, Is.False); + Assert.That(mockDevices[1].DiscoveryMuted, Is.False); + Assert.That(mockDevices[2].DiscoveryMuted, Is.False); + muteBroadcast = new RDMMessage() + { + Command = ERDM_Command.DISCOVERY_COMMAND, + DestUID = UID.Broadcast, + SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, + SubDevice = SubDevice.Root, + Parameter = ERDM_Parameter.DISC_MUTE, + }; + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Null); + Assert.That(mockDevices[0].DiscoveryMuted, Is.True); + Assert.That(mockDevices[1].DiscoveryMuted, Is.True); + Assert.That(mockDevices[2].DiscoveryMuted, Is.True); + + unmuteBroadcast.DestUID = new UID(0x9fff, 4444); + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(unmuteBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(mockDevices[0].DiscoveryMuted, Is.False); + Assert.That(mockDevices[1].DiscoveryMuted, Is.True); + Assert.That(mockDevices[2].DiscoveryMuted, Is.True); + + unmuteBroadcast.DestUID = new UID(0x9fff, 4445); + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(unmuteBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(mockDevices[0].DiscoveryMuted, Is.False); + Assert.That(mockDevices[1].DiscoveryMuted, Is.False); + Assert.That(mockDevices[2].DiscoveryMuted, Is.True); + + muteBroadcast.DestUID = new UID(0x9fff, 4444); + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(mockDevices[0].DiscoveryMuted, Is.True); + Assert.That(mockDevices[1].DiscoveryMuted, Is.False); + Assert.That(mockDevices[2].DiscoveryMuted, Is.True); + + muteBroadcast.DestUID = new UID(0x9fff, 4445); + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(mockDevices[0].DiscoveryMuted, Is.True); + Assert.That(mockDevices[1].DiscoveryMuted, Is.True); + Assert.That(mockDevices[2].DiscoveryMuted, Is.True); + } + [Test, Retry(3), CancelAfter(30000)] + public async Task TestDiscovery_UNIQUE_BRANCH() + { + mockDevices.Add(new MockGeneratedDevice1(new UID(0b0000000100000001, 0b00000001))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0b1000000101000001, 0b00000010))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0b0000000101000001, 0b00000100))); - RDMMessage unmuteBroadcast = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - DestUID = UID.Broadcast, - SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, - SubDevice = SubDevice.Root, - Parameter = ERDM_Parameter.DISC_UN_MUTE, - }; - var response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(unmuteBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Null); - - RDMMessage branchBroadcast = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - DestUID = UID.Broadcast, - SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, - SubDevice = SubDevice.Root, - Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH, - ParameterData = new DiscUniqueBranchRequest(UID.Empty, UID.Broadcast).ToPayloadData() - }; - - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(branchBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(response.Response.ChecksumValid, Is.False); - - branchBroadcast.ParameterData = new DiscUniqueBranchRequest(UID.Empty, UID.Broadcast / 2).ToPayloadData(); - - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(branchBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(response.Response.ChecksumValid, Is.False); - - branchBroadcast.ParameterData = new DiscUniqueBranchRequest(UID.Empty, new UID(0x0111,0)).ToPayloadData(); - - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(branchBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(response.Response.ChecksumValid, Is.True); - Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[0].UID)); - - RDMMessage muteBroadcast = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - DestUID = response.Response.SourceUID, - SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, - SubDevice = SubDevice.Root, - Parameter = ERDM_Parameter.DISC_MUTE, - }; - Assert.That(mockDevices[0].DiscoveryMuted, Is.False); - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[0].UID)); - Assert.That(mockDevices[0].DiscoveryMuted, Is.True); - - branchBroadcast.ParameterData = new DiscUniqueBranchRequest(UID.Empty, UID.Broadcast / 2).ToPayloadData(); - - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(branchBroadcast); - Assert.That(mockDevices[0].DiscoveryMuted, Is.True); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(response.Response.ChecksumValid, Is.True); - Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[2].UID)); - - muteBroadcast = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - DestUID = response.Response.SourceUID, - SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, - SubDevice = SubDevice.Root, - Parameter = ERDM_Parameter.DISC_MUTE, - }; - Assert.That(mockDevices[2].DiscoveryMuted, Is.False); - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[2].UID)); - Assert.That(mockDevices[2].DiscoveryMuted, Is.True); - - branchBroadcast.ParameterData = new DiscUniqueBranchRequest(UID.Broadcast/2, UID.Broadcast).ToPayloadData(); - - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(branchBroadcast); - Assert.That(mockDevices[2].DiscoveryMuted, Is.True); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(response.Response.ChecksumValid, Is.True); - Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[1].UID)); - - muteBroadcast = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - DestUID = response.Response.SourceUID, - SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, - SubDevice = SubDevice.Root, - Parameter = ERDM_Parameter.DISC_MUTE, - }; - Assert.That(mockDevices[1].DiscoveryMuted, Is.False); - response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); - Assert.That(response.Success, Is.True); - Assert.That(response.Response, Is.Not.Null); - Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[1].UID)); - Assert.That(mockDevices[1].DiscoveryMuted, Is.True); + RDMMessage unmuteBroadcast = new RDMMessage() + { + Command = ERDM_Command.DISCOVERY_COMMAND, + DestUID = UID.Broadcast, + SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, + SubDevice = SubDevice.Root, + Parameter = ERDM_Parameter.DISC_UN_MUTE, + }; + var response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(unmuteBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Null); + + RDMMessage branchBroadcast = new RDMMessage() + { + Command = ERDM_Command.DISCOVERY_COMMAND, + DestUID = UID.Broadcast, + SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, + SubDevice = SubDevice.Root, + Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH, + ParameterData = new DiscUniqueBranchRequest(UID.Empty, UID.Broadcast).ToPayloadData() + }; + + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(branchBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(response.Response.ChecksumValid, Is.False); + + branchBroadcast.ParameterData = new DiscUniqueBranchRequest(UID.Empty, UID.Broadcast / 2).ToPayloadData(); + + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(branchBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(response.Response.ChecksumValid, Is.False); + + branchBroadcast.ParameterData = new DiscUniqueBranchRequest(UID.Empty, new UID(0x0111, 0)).ToPayloadData(); + + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(branchBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(response.Response.ChecksumValid, Is.True); + Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[0].UID)); + + RDMMessage muteBroadcast = new RDMMessage() + { + Command = ERDM_Command.DISCOVERY_COMMAND, + DestUID = response.Response.SourceUID, + SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, + SubDevice = SubDevice.Root, + Parameter = ERDM_Parameter.DISC_MUTE, + }; + Assert.That(mockDevices[0].DiscoveryMuted, Is.False); + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[0].UID)); + Assert.That(mockDevices[0].DiscoveryMuted, Is.True); + + branchBroadcast.ParameterData = new DiscUniqueBranchRequest(UID.Empty, UID.Broadcast / 2).ToPayloadData(); + + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(branchBroadcast); + Assert.That(mockDevices[0].DiscoveryMuted, Is.True); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(response.Response.ChecksumValid, Is.True); + Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[2].UID)); + + muteBroadcast = new RDMMessage() + { + Command = ERDM_Command.DISCOVERY_COMMAND, + DestUID = response.Response.SourceUID, + SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, + SubDevice = SubDevice.Root, + Parameter = ERDM_Parameter.DISC_MUTE, + }; + Assert.That(mockDevices[2].DiscoveryMuted, Is.False); + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[2].UID)); + Assert.That(mockDevices[2].DiscoveryMuted, Is.True); + + branchBroadcast.ParameterData = new DiscUniqueBranchRequest(UID.Broadcast / 2, UID.Broadcast).ToPayloadData(); + + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(branchBroadcast); + Assert.That(mockDevices[2].DiscoveryMuted, Is.True); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(response.Response.ChecksumValid, Is.True); + Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[1].UID)); + + muteBroadcast = new RDMMessage() + { + Command = ERDM_Command.DISCOVERY_COMMAND, + DestUID = response.Response.SourceUID, + SourceUID = RDMSharp.RDMSharp.Instance.ControllerUID, + SubDevice = SubDevice.Root, + Parameter = ERDM_Parameter.DISC_MUTE, + }; + Assert.That(mockDevices[1].DiscoveryMuted, Is.False); + response = await RDMSharp.RDMSharp.Instance.AsyncRDMRequestHelper.RequestMessage(muteBroadcast); + Assert.That(response.Success, Is.True); + Assert.That(response.Response, Is.Not.Null); + Assert.That(response.Response.SourceUID, Is.EqualTo(mockDevices[1].UID)); + Assert.That(mockDevices[1].DiscoveryMuted, Is.True); + + } + + [Test, Retry(3), CancelAfter(30000)] + public async Task TestDiscovery0() + { + mockDevices.Add(new MockGeneratedDevice1(new UID(0b0000000100000001, 0b00000001))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0b1000000101000001, 0b00000010))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0b0000000101000001, 0b00000100))); - } + expected = mockDevices.Select(m => m.UID).ToList(); + await AssertDiscovery(); + } - [Test, Retry(3), CancelAfter(30000)] - public async Task TestDiscovery0() - { - mockDevices.Add(new MockGeneratedDevice1(new UID(0b0000000100000001, 0b00000001))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0b1000000101000001, 0b00000010))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0b0000000101000001, 0b00000100))); + [Test, Retry(3), CancelAfter(30000)] + public async Task TestDiscovery1() + { + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4444))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4445))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4446))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4447))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4448))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 21314))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 25252))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 636436))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 23252525))); + + expected = mockDevices.Select(m => m.UID).ToList(); + await AssertDiscovery(); + } + [Test, Retry(3), CancelAfter(60000)] + public async Task TestDiscovery2() + { + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234254))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234243))); - expected = mockDevices.Select(m => m.UID).ToList(); - await AssertDiscovery(); - } + expected = mockDevices.Select(m => m.UID).ToList(); + await AssertDiscovery(); + + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 0x123400))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 0x567800))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 0x9abc00))); - [Test, Retry(3), CancelAfter(30000)] - public async Task TestDiscovery1() - { - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4444))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4445))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4446))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4447))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4448))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 21314))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 25252))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 636436))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 23252525))); - - expected = mockDevices.Select(m => m.UID).ToList(); - await AssertDiscovery(); - } - [Test, Retry(3), CancelAfter(60000)] - public async Task TestDiscovery2() - { - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234254))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234243))); + expected = mockDevices.Select(m => m.UID).Except(expected).ToList(); + await AssertDiscovery(false); // Discover only new Devices - expected = mockDevices.Select(m => m.UID).ToList(); - await AssertDiscovery(); - - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 0x123400))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 0x567800))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 0x9abc00))); - - expected = mockDevices.Select(m => m.UID).Except(expected).ToList(); - await AssertDiscovery(false); // Discover only new Devices - - expected = mockDevices.Select(m => m.UID).ToList(); - await AssertDiscovery(); - } - [Test, Retry(3), CancelAfter(60000)] - public async Task TestDiscovery3() - { - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234254))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234243))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 124367))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 64687))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 487755))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 9696))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 7474574))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4784757))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 747747))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 7800))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 90789))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 225677856))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 989089))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4))); - mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4757342))); - - expected = mockDevices.Select(m => m.UID).ToList(); - await AssertDiscovery(); - } - [Test, Retry(3), CancelAfter(180000)] - public async Task TestDiscovery4() - { - HashSet ids = new HashSet(); - for (int i = 0; i < 20; i++) + expected = mockDevices.Select(m => m.UID).ToList(); + await AssertDiscovery(); + } + [Test, Retry(3), CancelAfter(60000)] + public async Task TestDiscovery3() + { + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234254))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234243))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 124367))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 64687))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 487755))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 9696))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 7474574))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4784757))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 747747))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 7800))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 90789))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 225677856))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 989089))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4))); + mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4757342))); + + expected = mockDevices.Select(m => m.UID).ToList(); + await AssertDiscovery(); + } + [Test, Retry(3), CancelAfter(180000)] + public async Task TestDiscovery4() + { + HashSet ids = new HashSet(); + for (int i = 0; i < 20; i++) + { + uint id = 0; + do { - uint id = 0; - do - { - id = (uint)random.Next(); - } - while (!ids.Add(id)); - var m = new MockGeneratedDevice1(new UID(0x9fff, id)); - mockDevices.Add(m); + id = (uint)random.Next(); } + while (!ids.Add(id)); + var m = new MockGeneratedDevice1(new UID(0x9fff, id)); + mockDevices.Add(m); + } - expected = mockDevices.Select(m => m.UID).ToList(); - await AssertDiscovery(); - } - [Test, Retry(3), CancelAfter(180000)] - public async Task TestDiscovery5TotalyRandom() - { - HashSet ids = new HashSet(); - HashSet idsMan = new HashSet(); - for (int i = 0; i < 10; i++) + expected = mockDevices.Select(m => m.UID).ToList(); + await AssertDiscovery(); + } + [Test, Retry(3), CancelAfter(180000)] + public async Task TestDiscovery5TotalyRandom() + { + HashSet ids = new HashSet(); + HashSet idsMan = new HashSet(); + for (int i = 0; i < 10; i++) + { + uint id = 0; + ushort idMan = 0; + do + { + id = (uint)random.Next(); + } + while (!ids.Add(id)); + do { - uint id = 0; - ushort idMan = 0; - do - { - id = (uint)random.Next(); - } - while (!ids.Add(id)); - do - { - idMan = (ushort)random.Next(ushort.MinValue + 100, ushort.MaxValue - 100); - } - while (!idsMan.Add(idMan)); - var m = new MockGeneratedDevice1(new UID(idMan, id)); - mockDevices.Add(m); + idMan = (ushort)random.Next(ushort.MinValue + 100, ushort.MaxValue - 100); } + while (!idsMan.Add(idMan)); + var m = new MockGeneratedDevice1(new UID(idMan, id)); + mockDevices.Add(m); + } - expected = mockDevices.Select(m => m.UID).ToList(); - await AssertDiscovery(); - } + expected = mockDevices.Select(m => m.UID).ToList(); + await AssertDiscovery(); } } \ No newline at end of file diff --git a/RDMSharpTests/Devices/TestRDMSendReceive.cs b/RDMSharpTests/Devices/TestRDMSendReceive.cs index f181260a..cc3ba775 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceive.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceive.cs @@ -1,475 +1,500 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; using RDMSharpTests.Devices.Mock; -namespace RDMSharpTests.RDM.Devices +namespace RDMSharpTests.RDM.Devices; + +public class TestRDMSendReceive { - public class TestRDMSendReceive + private MockGeneratedDevice1? generated; + private MockDevice? remote; + private Random random = new Random(); + + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } + + [SetUp] + public void Setup() { - private MockGeneratedDevice1? generated; - private MockDevice? remote; - private Random random = new Random(); - [SetUp] - public void Setup() - { - var uid = new UID((ushort)random.Next(), (uint)random.Next()); - generated = new MockGeneratedDevice1(uid); - remote = new MockDevice(uid); - } - [TearDown] - public void TearDown() + var uid = new UID((ushort)random.Next(), (uint)random.Next()); + generated = new MockGeneratedDevice1(uid); + remote = new MockDevice(uid); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + remote?.Dispose(); + remote = null; + } + + [Test, Retry(3), Order(1)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] + public async Task TestDevice1() + { + var parameterValuesRemote = remote!.GetAllParameterValues(); + var parameterValuesGenerated = generated!.GetAllParameterValues(); + + Console.WriteLine($"Generated: {String.Join(", ", parameterValuesGenerated.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); + Console.WriteLine($"Remote: {String.Join(", ", parameterValuesRemote.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); + + Assert.Multiple(() => { - generated?.Dispose(); - generated = null; - remote?.Dispose(); - remote = null; - } - - [Test, Retry(3), Order(1)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] - public async Task TestDevice1() - { - var parameterValuesRemote = remote!.GetAllParameterValues(); - var parameterValuesGenerated = generated!.GetAllParameterValues(); - - Console.WriteLine($"Generated: {String.Join(", ", parameterValuesGenerated.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); - Console.WriteLine($"Remote: {String.Join(", ", parameterValuesRemote.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); - - Assert.Multiple(() => + Assert.That(parameterValuesGenerated.Keys, Is.EquivalentTo(parameterValuesRemote.Keys)); + foreach (var parameter in parameterValuesGenerated.Keys) { - Assert.That(parameterValuesGenerated.Keys, Is.EquivalentTo(parameterValuesRemote.Keys)); - foreach (var parameter in parameterValuesGenerated.Keys) + Assert.DoesNotThrow(() => { Assert.That(parameterValuesRemote.Keys, Contains.Item(parameter), $"Tested Parameter {parameter}"); if (parameterValuesGenerated[parameter] is Array) Assert.That(parameterValuesGenerated[parameter], Is.EquivalentTo((Array)parameterValuesRemote[parameter]), $"Tested Parameter {parameter}"); else Assert.That(parameterValuesGenerated[parameter], Is.EqualTo(parameterValuesRemote[parameter]), $"Tested Parameter {parameter}"); - } - foreach (var parameter in parameterValuesRemote.Keys) + }); + } + foreach (var parameter in parameterValuesRemote.Keys) + { + Assert.DoesNotThrow(() => { Assert.That(parameterValuesGenerated.Keys, Contains.Item(parameter), $"Tested Parameter {parameter}"); if (parameterValuesRemote[parameter] is Array) Assert.That(parameterValuesRemote[parameter], Is.EquivalentTo((Array)parameterValuesGenerated[parameter]), $"Tested Parameter {parameter}"); else Assert.That(parameterValuesRemote[parameter], Is.EqualTo(parameterValuesGenerated[parameter]), $"Tested Parameter {parameter}"); - } - Assert.That(parameterValuesRemote, Has.Count.EqualTo(parameterValuesGenerated.Count)); - }); - - Assert.Multiple(() => + }); + } + Assert.That(parameterValuesRemote, Has.Count.EqualTo(parameterValuesGenerated.Count)); + }); + + var deviceLabelModule = generated.Modules.OfType().Single(); + var manufacturerLabelModule = generated.Modules.OfType().Single(); + var deviceModelDescriptionModule = generated.Modules.OfType().Single(); + Assert.Multiple(() => { Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DEVICE_INFO], Is.EqualTo(generated.DeviceInfo)); - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DEVICE_LABEL], Is.EqualTo(generated.DeviceLabel)); - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DEVICE_MODEL_DESCRIPTION], Is.EqualTo(generated.DeviceModelDescription)); - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.MANUFACTURER_LABEL], Is.EqualTo(generated.ManufacturerLabel)); - Assert.That(((RDMDMXPersonality)remote.GetAllParameterValues()[ERDM_Parameter.DMX_PERSONALITY]).Index, Is.EqualTo(generated.CurrentPersonality)); - }); - - await remote.SetParameter(ERDM_Parameter.DMX_START_ADDRESS, (ushort)512); - Assert.Multiple(() => - { - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(512)); - Assert.That(generated.DMXAddress, Is.EqualTo(512)); + Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DEVICE_LABEL], Is.EqualTo(deviceLabelModule.DeviceLabel)); + Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DEVICE_MODEL_DESCRIPTION], Is.EqualTo(deviceModelDescriptionModule.DeviceModelDescription)); + Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.MANUFACTURER_LABEL], Is.EqualTo(manufacturerLabelModule.ManufacturerLabel)); + Assert.That(((RDMDMXPersonality)remote.GetAllParameterValues()[ERDM_Parameter.DMX_PERSONALITY]).Index, Is.EqualTo(generated.CurrentPersonalityId)); }); - await remote.SetParameter(ERDM_Parameter.DMX_PERSONALITY, (byte)3); - Assert.Multiple(() => - { - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DMX_PERSONALITY], Is.EqualTo(new RDMDMXPersonality(3, 3))); - Assert.That(generated.CurrentPersonality, Is.EqualTo(3)); - }); - - string label = "Changed Device Label"; - await remote.SetParameter(ERDM_Parameter.DEVICE_LABEL, label); - Assert.Multiple(() => - { - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DEVICE_LABEL], Is.EqualTo(label)); - Assert.That(generated.DeviceLabel, Is.EqualTo(label)); - }); - Assert.Multiple(async () => - { - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); - Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); - await remote.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, true); - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.True); - Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.True); - await remote.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, false); - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); - Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); - }); - Assert.Multiple(() => - { - Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_INFO, new RDMDeviceInfo()); }); - Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, new RDMDMXPersonalityDescription(1, 2, "dasdad")); }); - Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.LANGUAGE, "de"); }); - Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.LANGUAGE, 333); }); - Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_LABEL, "Test"); }); - Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DISC_MUTE, null); }); - Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_LABEL, new RDMDeviceInfo()); }); - }); - } + await remote.SetParameter(ERDM_Parameter.DMX_START_ADDRESS, (ushort)512); + Assert.Multiple(() => + { + Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(512)); + Assert.That(generated.DMXAddress, Is.EqualTo(512)); + }); + + await remote.SetParameter(ERDM_Parameter.DMX_PERSONALITY, (byte)3); + while (remote.PersonalityModel.PersonalityID != generated.CurrentPersonalityId) + await Task.Delay(100); + while (!remote.PersonalityModel.IsInitialized) + await Task.Delay(100); - [Test, Order(2)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] - public void TestDevice1Slots() + Assert.Multiple(() => { - var slotIntensity = remote!.Slots[0]; - var slotStrobe = remote.Slots[1]; - var slotRed = remote.Slots[2]; - var slotGreen = remote.Slots[3]; - var slotBlue = remote.Slots[4]; + Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DMX_PERSONALITY], Is.EqualTo(new RDMDMXPersonality(3, 3))); + Assert.That(generated.CurrentPersonalityId, Is.EqualTo(3)); + }); - Assert.Multiple(() => - { - Assert.That(slotIntensity, Is.EqualTo(generated!.Personalities[0].Slots[0])); - Assert.That(slotStrobe, Is.EqualTo(generated.Personalities[0].Slots[1])); - Assert.That(slotRed, Is.EqualTo(generated.Personalities[0].Slots[2])); - Assert.That(slotGreen, Is.EqualTo(generated.Personalities[0].Slots[3])); - Assert.That(slotBlue, Is.EqualTo(generated.Personalities[0].Slots[4])); - - Assert.That(slotIntensity, Is.Not.EqualTo(slotStrobe)); - Assert.That(slotIntensity, Is.Not.EqualTo(slotRed)); - Assert.That(slotIntensity, Is.Not.EqualTo(slotGreen)); - Assert.That(slotIntensity, Is.Not.EqualTo(slotBlue)); - Assert.That(slotIntensity.DefaultValue, Is.EqualTo(0)); - Assert.That(slotIntensity.Category, Is.EqualTo(ERDM_SlotCategory.INTENSITY)); - Assert.That(slotIntensity.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); - Assert.That(slotIntensity.DefaultValue, Is.EqualTo(0)); - - Assert.That(slotStrobe, Is.Not.EqualTo(slotRed)); - Assert.That(slotStrobe, Is.Not.EqualTo(slotGreen)); - Assert.That(slotStrobe, Is.Not.EqualTo(slotBlue)); - Assert.That(slotStrobe.Category, Is.EqualTo(ERDM_SlotCategory.STROBE)); - Assert.That(slotStrobe.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); - Assert.That(slotStrobe.DefaultValue, Is.EqualTo(33)); - - Assert.That(slotRed, Is.Not.EqualTo(slotGreen)); - Assert.That(slotRed, Is.Not.EqualTo(slotBlue)); - Assert.That(slotRed.Category, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_RED)); - Assert.That(slotRed.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); - Assert.That(slotRed.DefaultValue, Is.EqualTo(0)); - - Assert.That(slotGreen, Is.Not.EqualTo(slotBlue)); - Assert.That(slotGreen.Category, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_GREEN)); - Assert.That(slotGreen.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); - Assert.That(slotGreen.DefaultValue, Is.EqualTo(0)); - - Assert.That(slotBlue.Category, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_BLUE)); - Assert.That(slotBlue.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); - Assert.That(slotBlue.DefaultValue, Is.EqualTo(0)); - - Assert.That(slotIntensity != slotStrobe, Is.True); - Assert.That(slotRed != slotBlue, Is.True); - - Assert.That(slotIntensity == slotStrobe, Is.False); - Assert.That(slotRed == slotBlue, Is.False); - - Assert.That(((object)slotRed).Equals(null), Is.False); - Assert.That(((object)slotRed!).Equals(slotBlue), Is.False); - Assert.That(slotRed.Equals(slotBlue), Is.False); - Assert.That(slotRed.Equals(slotStrobe), Is.False); - - Assert.That(string.IsNullOrWhiteSpace(slotRed.ToString()), Is.False); - HashSet slots = new HashSet(); - Assert.That(slots.Add(slotIntensity), Is.True); - Assert.That(slots.Add(slotIntensity), Is.False); - Assert.That(slots, Does.Contain(slotIntensity)); - Assert.That(slots.Add(slotStrobe), Is.True); - Assert.That(slots.Add(slotStrobe), Is.False); - Assert.That(slots, Does.Contain(slotStrobe)); - Assert.That(slots.Add(slotRed), Is.True); - Assert.That(slots.Add(slotRed), Is.False); - Assert.That(slots, Does.Contain(slotRed)); - Assert.That(slots.Add(slotGreen), Is.True); - Assert.That(slots.Add(slotGreen), Is.False); - Assert.That(slots, Does.Contain(slotGreen)); - Assert.That(slots.Add(slotBlue), Is.True); - Assert.That(slots.Add(slotBlue), Is.False); - Assert.That(slots, Does.Contain(slotBlue)); - }); - } + string label = "Changed Device Label"; + await remote.SetParameter(ERDM_Parameter.DEVICE_LABEL, label); + Assert.Multiple(() => + { + Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DEVICE_LABEL], Is.EqualTo(label)); + Assert.That(deviceLabelModule.DeviceLabel, Is.EqualTo(label)); + }); + Assert.Multiple(async () => + { + Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); + Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); + await remote.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, true); + Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.True); + Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.True); + await remote.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, false); + Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); + Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); + }); + Assert.Multiple(() => + { + Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_INFO, new RDMDeviceInfo()); }); + Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, new RDMDMXPersonalityDescription(1, 2, "dasdad")); }); + Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.LANGUAGE, "de"); }); + Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.LANGUAGE, 333); }); + Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_LABEL, "Test"); }); + Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DISC_MUTE, null); }); + Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_LABEL, new RDMDeviceInfo()); }); + }); + } + + [Test, Order(2)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] + public void TestDevice1Slots() + { + var slotIntensity = remote!.Slots[0]; + var slotStrobe = remote.Slots[1]; + var slotRed = remote.Slots[2]; + var slotGreen = remote.Slots[3]; + var slotBlue = remote.Slots[4]; + + Assert.Multiple(() => + { + Assert.That(slotIntensity, Is.EqualTo(generated!.Personalities.ElementAt(0).Slots[0])); + Assert.That(slotStrobe, Is.EqualTo(generated.Personalities.ElementAt(0).Slots[1])); + Assert.That(slotRed, Is.EqualTo(generated.Personalities.ElementAt(0).Slots[2])); + Assert.That(slotGreen, Is.EqualTo(generated.Personalities.ElementAt(0).Slots[3])); + Assert.That(slotBlue, Is.EqualTo(generated.Personalities.ElementAt(0).Slots[4])); + + Assert.That(slotIntensity, Is.Not.EqualTo(slotStrobe)); + Assert.That(slotIntensity, Is.Not.EqualTo(slotRed)); + Assert.That(slotIntensity, Is.Not.EqualTo(slotGreen)); + Assert.That(slotIntensity, Is.Not.EqualTo(slotBlue)); + Assert.That(slotIntensity.DefaultValue, Is.EqualTo(0)); + Assert.That(slotIntensity.Category, Is.EqualTo(ERDM_SlotCategory.INTENSITY)); + Assert.That(slotIntensity.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); + Assert.That(slotIntensity.DefaultValue, Is.EqualTo(0)); + + Assert.That(slotStrobe, Is.Not.EqualTo(slotRed)); + Assert.That(slotStrobe, Is.Not.EqualTo(slotGreen)); + Assert.That(slotStrobe, Is.Not.EqualTo(slotBlue)); + Assert.That(slotStrobe.Category, Is.EqualTo(ERDM_SlotCategory.STROBE)); + Assert.That(slotStrobe.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); + Assert.That(slotStrobe.DefaultValue, Is.EqualTo(33)); + + Assert.That(slotRed, Is.Not.EqualTo(slotGreen)); + Assert.That(slotRed, Is.Not.EqualTo(slotBlue)); + Assert.That(slotRed.Category, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_RED)); + Assert.That(slotRed.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); + Assert.That(slotRed.DefaultValue, Is.EqualTo(0)); + + Assert.That(slotGreen, Is.Not.EqualTo(slotBlue)); + Assert.That(slotGreen.Category, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_GREEN)); + Assert.That(slotGreen.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); + Assert.That(slotGreen.DefaultValue, Is.EqualTo(0)); + + Assert.That(slotBlue.Category, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_BLUE)); + Assert.That(slotBlue.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); + Assert.That(slotBlue.DefaultValue, Is.EqualTo(0)); + + Assert.That(slotIntensity != slotStrobe, Is.True); + Assert.That(slotRed != slotBlue, Is.True); + + Assert.That(slotIntensity == slotStrobe, Is.False); + Assert.That(slotRed == slotBlue, Is.False); + + Assert.That(((object)slotRed).Equals(null), Is.False); + Assert.That(((object)slotRed!).Equals(slotBlue), Is.False); + Assert.That(slotRed.Equals(slotBlue), Is.False); + Assert.That(slotRed.Equals(slotStrobe), Is.False); + + Assert.That(string.IsNullOrWhiteSpace(slotRed.ToString()), Is.False); + HashSet slots = new HashSet(); + Assert.That(slots.Add(slotIntensity), Is.True); + Assert.That(slots.Add(slotIntensity), Is.False); + Assert.That(slots, Does.Contain(slotIntensity)); + Assert.That(slots.Add(slotStrobe), Is.True); + Assert.That(slots.Add(slotStrobe), Is.False); + Assert.That(slots, Does.Contain(slotStrobe)); + Assert.That(slots.Add(slotRed), Is.True); + Assert.That(slots.Add(slotRed), Is.False); + Assert.That(slots, Does.Contain(slotRed)); + Assert.That(slots.Add(slotGreen), Is.True); + Assert.That(slots.Add(slotGreen), Is.False); + Assert.That(slots, Does.Contain(slotGreen)); + Assert.That(slots.Add(slotBlue), Is.True); + Assert.That(slots.Add(slotBlue), Is.False); + Assert.That(slots, Does.Contain(slotBlue)); + }); + } + + [Test, CancelAfter(10000)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] + public async Task TestDevice1Sensor() + { + var sensorsRemote = remote!.Sensors.Values.ToList(); + var sensorsGenerated = generated!.Sensors.Values.ToList(); + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(3000)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(8000)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(12000)); + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(3000)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(8000)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(12000)); + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(0)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(0)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(0)); + }); + Assert.Multiple(() => + { + Assert.That(remote.DeviceModel.GetSupportedBlueprintModelParameters().Select(spm => spm.Parameter), Contains.Item(ERDM_Parameter.SENSOR_DEFINITION)); + Assert.That(remote.DeviceModel.GetSupportedNonBlueprintParameters().Select(spm => spm.Parameter), Contains.Item(ERDM_Parameter.SENSOR_VALUE)); + }); - [Test, CancelAfter(10000)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] - public async Task TestDevice1Sensor() + Assert.Multiple(() => { - var sensorsRemote = remote!.Sensors.Values.ToList(); - var sensorsGenerated = generated!.Sensors.Values.ToList(); - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(3000)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(8000)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(12000)); - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(3000)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(8000)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(12000)); - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(0)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(0)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(0)); - }); - Assert.Multiple(() => - { - Assert.That(remote.DeviceModel.SupportedBlueprintParameters, Contains.Item(ERDM_Parameter.SENSOR_DEFINITION)); - Assert.That(remote.DeviceModel.SupportedNonBlueprintParameters, Contains.Item(ERDM_Parameter.SENSOR_VALUE)); - }); + Assert.That(sensorsRemote, Has.Count.EqualTo(sensorsGenerated.Count)); + Assert.That(sensorsRemote, Is.EqualTo(sensorsGenerated)); + }); - Assert.Multiple(() => - { - Assert.That(sensorsRemote, Has.Count.EqualTo(sensorsGenerated.Count)); - Assert.That(sensorsRemote, Is.EqualTo(sensorsGenerated)); - }); - - await Task.Delay(100); + await Task.Delay(100); - #region Update Sensor Values - ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(200); - ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(500); - ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(800); - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(200)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(500)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(800)); - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(200)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(500)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(800)); - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(0)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(0)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(0)); - }); - - await Task.Delay(400); - doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); - #endregion - - #region Record Sensor Values (generated) - ((MockGeneratedSensor)generated.Sensors[0]).RecordValue(); - ((MockGeneratedSensor)generated.Sensors[1]).RecordValue(); - ((MockGeneratedSensor)generated.Sensors[2]).RecordValue(); - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(200)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(500)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(800)); - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(200)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(500)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(800)); - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(200)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(500)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(800)); - }); - - await Task.Delay(400); - doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); - #endregion - - #region Record Sensor Values (remote) - ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(4400); - ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(6600); - ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(7700); - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(6600)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(7700)); - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(200)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(500)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(800)); - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(200)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(500)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(800)); - }); - - await Task.WhenAll( - remote.SetParameter(ERDM_Parameter.RECORD_SENSORS, generated.Sensors[0].SensorId), - remote.SetParameter(ERDM_Parameter.RECORD_SENSORS, generated.Sensors[1].SensorId), - remote.SetParameter(ERDM_Parameter.RECORD_SENSORS, generated.Sensors[2].SensorId)); - await Task.Delay(400); - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(6600)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(7700)); - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(200)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(500)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(800)); - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(6600)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(7700)); - }); - - await Task.Delay(400); - doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); - #endregion - - #region Reset Sensors - ((MockGeneratedSensor)generated.Sensors[0]).ResetValues(); - ((MockGeneratedSensor)generated.Sensors[1]).ResetValues(); - ((MockGeneratedSensor)generated.Sensors[2]).ResetValues(); - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(6600)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(7700)); - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(6600)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(7700)); - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(6600)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(7700)); - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(6600)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(7700)); - }); - - await Task.Delay(400); - doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); - #endregion - - #region Record Sensor Values (remote) Broadcast - ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(1); - ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(1); - ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(1); - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(6600)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(7700)); - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(6600)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(7700)); - }); - - await remote.SetParameter(ERDM_Parameter.RECORD_SENSORS, (byte)0xff); - await Task.Delay(400); - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(6600)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(7700)); - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(1)); - }); - - await Task.Delay(400); - doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); - #endregion - - #region Reset Sensor Values (remote) Broadcast - ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(2); - ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(2); - ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(2); - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(6600)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(7700)); - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(1)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(1)); - }); - - await remote.SetParameter(ERDM_Parameter.SENSOR_VALUE, (byte)0xff); - await Task.Delay(400); - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(2)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(2)); - }); - - await Task.Delay(400); - doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); - #endregion - - void doTests(Sensor[] remoteSensors, Sensor[] generatedSensors) + #region Update Sensor Values + ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(200); + ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(500); + ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(800); + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(200)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(500)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(800)); + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(200)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(500)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(800)); + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(0)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(0)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(0)); + }); + + await Task.Delay(400); + doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); + #endregion + + #region Record Sensor Values (generated) + ((MockGeneratedSensor)generated.Sensors[0]).RecordValue(); + ((MockGeneratedSensor)generated.Sensors[1]).RecordValue(); + ((MockGeneratedSensor)generated.Sensors[2]).RecordValue(); + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(200)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(500)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(800)); + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(200)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(500)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(800)); + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(200)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(500)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(800)); + }); + + await Task.Delay(400); + doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); + #endregion + + #region Record Sensor Values (remote) + ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(4400); + ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(6600); + ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(7700); + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(6600)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(7700)); + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(200)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(500)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(800)); + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(200)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(500)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(800)); + }); + + await Task.WhenAll( + remote.SetParameter(ERDM_Parameter.RECORD_SENSORS, generated.Sensors[0].SensorId), + remote.SetParameter(ERDM_Parameter.RECORD_SENSORS, generated.Sensors[1].SensorId), + remote.SetParameter(ERDM_Parameter.RECORD_SENSORS, generated.Sensors[2].SensorId)); + await Task.Delay(400); + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(6600)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(7700)); + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(200)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(500)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(800)); + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(6600)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(7700)); + }); + + await Task.Delay(400); + doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); + #endregion + + #region Reset Sensors + ((MockGeneratedSensor)generated.Sensors[0]).ResetValues(); + ((MockGeneratedSensor)generated.Sensors[1]).ResetValues(); + ((MockGeneratedSensor)generated.Sensors[2]).ResetValues(); + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(6600)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(7700)); + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(6600)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(7700)); + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(6600)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(7700)); + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(6600)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(7700)); + }); + + await Task.Delay(400); + doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); + #endregion + + #region Record Sensor Values (remote) Broadcast + ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(1); + ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(1); + ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(1); + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(6600)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(7700)); + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(6600)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(7700)); + }); + + await remote.SetParameter(ERDM_Parameter.RECORD_SENSORS, (byte)0xff); + await Task.Delay(400); + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(6600)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(7700)); + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(1)); + }); + + await Task.Delay(400); + doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); + #endregion + + #region Reset Sensor Values (remote) Broadcast + ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(2); + ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(2); + ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(2); + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(4400)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(6600)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(7700)); + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(1)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(1)); + }); + + await remote.SetParameter(ERDM_Parameter.SENSOR_VALUE, (byte)0xff); + await Task.Delay(400); + Assert.Multiple(() => + { + Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(2)); + Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(2)); + }); + + await Task.Delay(400); + doTests(remote.Sensors.Values.ToArray(), generated.Sensors.Values.ToArray()); + #endregion + + void doTests(Sensor[] remoteSensors, Sensor[] generatedSensors) + { + for (byte s = 0; s < remoteSensors.Length; s++) { - for (byte s= 0; s { - var remoteSensor = remoteSensors[s]; - var generatedSensor = generatedSensors[s]; - Assert.Multiple(() => - { - Assert.That(remoteSensor.PresentValue, Is.EqualTo(generatedSensor.PresentValue)); - Assert.That(remoteSensor.LowestValue, Is.EqualTo(generatedSensor.LowestValue)); - Assert.That(remoteSensor.HighestValue, Is.EqualTo(generatedSensor.HighestValue)); - Assert.That(remoteSensor.RecordedValue, Is.EqualTo(generatedSensor.RecordedValue)); - Assert.That(remoteSensor, Is.EqualTo(generatedSensor)); - }); - } - } - } - [Test, Order(4), CancelAfter(10000)] - public async Task TestDevice1QueuedUpdates() - { - var parameterValuesRemote = remote!.GetAllParameterValues(); - var parameterValuesGenerated = generated!.GetAllParameterValues(); - Assert.That(parameterValuesRemote[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); - - await Task.Delay(400); - - generated.DMXAddress = 69; - generated.DeviceLabel = "Test Label QUEUE"; - generated.Identify = true; - - await Task.Delay(400); - parameterValuesRemote = remote.GetAllParameterValues(); - - Assert.That(parameterValuesRemote[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(69)); - Assert.That(parameterValuesRemote[ERDM_Parameter.DEVICE_LABEL], Is.EqualTo("Test Label QUEUE")); - Assert.That(parameterValuesRemote[ERDM_Parameter.IDENTIFY_DEVICE], Is.True); - - generated.Identify = false; - generated.DMXAddress = 44; - generated.CurrentPersonality = 2; - - await Task.Delay(400); - parameterValuesRemote = remote.GetAllParameterValues(); - Assert.That(parameterValuesRemote[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); - Assert.That(parameterValuesRemote[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(44)); - Assert.That(parameterValuesRemote[ERDM_Parameter.DMX_PERSONALITY], Is.EqualTo(new RDMDMXPersonality(2, 3))); + Assert.That(remoteSensor.PresentValue, Is.EqualTo(generatedSensor.PresentValue)); + Assert.That(remoteSensor.LowestValue, Is.EqualTo(generatedSensor.LowestValue)); + Assert.That(remoteSensor.HighestValue, Is.EqualTo(generatedSensor.HighestValue)); + Assert.That(remoteSensor.RecordedValue, Is.EqualTo(generatedSensor.RecordedValue)); + Assert.That(remoteSensor, Is.EqualTo(generatedSensor)); + }); + } } - } + } + [Test, Order(4), CancelAfter(10000)] + public async Task TestDevice1QueuedUpdates() + { + var parameterValuesRemote = remote!.GetAllParameterValues(); + var parameterValuesGenerated = generated!.GetAllParameterValues(); + Assert.That(parameterValuesRemote[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); + + await Task.Delay(400); + + var deviceLabelModule = generated.Modules.OfType().Single(); + + generated.DMXAddress = 69; + deviceLabelModule.DeviceLabel = "Test Label QUEUE"; + generated.Identify = true; + + await Task.Delay(400); + parameterValuesRemote = remote.GetAllParameterValues(); + + Assert.That(parameterValuesRemote[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(69)); + Assert.That(parameterValuesRemote[ERDM_Parameter.DEVICE_LABEL], Is.EqualTo("Test Label QUEUE")); + Assert.That(parameterValuesRemote[ERDM_Parameter.IDENTIFY_DEVICE], Is.True); + + generated.Identify = false; + generated.DMXAddress = 44; + generated.CurrentPersonalityId = 2; + + await Task.Delay(400); + parameterValuesRemote = remote.GetAllParameterValues(); + Assert.That(parameterValuesRemote[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); + Assert.That(parameterValuesRemote[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(44)); + Assert.That(parameterValuesRemote[ERDM_Parameter.DMX_PERSONALITY], Is.EqualTo(new RDMDMXPersonality(2, 3))); + } } \ No newline at end of file diff --git a/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs b/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs deleted file mode 100644 index 505e4a2d..00000000 --- a/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs +++ /dev/null @@ -1,1700 +0,0 @@ -using RDMSharpTests.Devices.Mock; - -namespace RDMSharpTests.RDM.Devices -{ - public class TestRDMSendReceiveGeneratedOnly - { - private MockGeneratedDevice1? generated; - - private static UID CONTROLLER_UID = new UID(0x1fff, 333); - private static UID DEVCIE_UID = new UID(123, 555); - [SetUp] - public void Setup() - { - generated = new MockGeneratedDevice1(DEVCIE_UID); - } - [TearDown] - public void TearDown() - { - generated?.Dispose(); - generated = null; - } - - - [Test, Order(1)] - public void TestGetSUPPORTED_PARAMETERS() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.SUPPORTED_PARAMETERS, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SUPPORTED_PARAMETERS)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(generated.Parameters.Count * 2)); - Assert.That(response.Value, Is.TypeOf(typeof(ERDM_Parameter[]))); - var parametersRemote = ((ERDM_Parameter[])response.Value).OrderBy(p => p).ToArray(); - var parametersGenerated = generated.Parameters.OrderBy(p => p).ToArray(); - Assert.That(parametersRemote, Is.EquivalentTo(parametersGenerated)); - #endregion - } - [Test, Order(5)] - public void TestGetDEVICE_INFO() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.DEVICE_INFO, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(19)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); - RDMDeviceInfo? deviceInfo = response!.Value as RDMDeviceInfo; - Assert.That(deviceInfo, Is.Not.Null); - Assert.That(deviceInfo.SensorCount, Is.EqualTo(5)); - #endregion - - #region Test Remove Sensors - List sensors = generated.Sensors.Values.ToList(); - foreach (var sensor in sensors) - generated.RemoveSensors(sensor); - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(19)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); - deviceInfo = response!.Value as RDMDeviceInfo; - Assert.That(deviceInfo, Is.Not.Null); - Assert.That(deviceInfo.SensorCount, Is.EqualTo(0)); - #endregion - - #region Test Add Sensors - foreach (var sensor in sensors) - generated.AddSensors(sensor); - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(19)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); - deviceInfo = response!.Value as RDMDeviceInfo; - Assert.That(deviceInfo, Is.Not.Null); - Assert.That(deviceInfo.SensorCount, Is.EqualTo(5)); - #endregion - } - [Test, Order(6)] - public void TestGetIDENTIFY_DEVICE() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.Identify, Is.False); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.IDENTIFY_DEVICE, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(1)); - Assert.That(response.Value, Is.EqualTo(generated.Identify)); - #endregion - - #region Test Identify changed (GET) - Assert.That(generated.Identify, Is.False); - generated.Identify = true; - Assert.That(generated.Identify, Is.True); - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(1)); - Assert.That(response.Value, Is.EqualTo(generated.Identify)); - #endregion - - - #region Test Identify changed (SET) - Assert.That(generated.Identify, Is.True); - request.ParameterData = new byte[] { 0x00 }; // Requesting Identify OFF - request.Command = ERDM_Command.SET_COMMAND; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - - Assert.That(generated.Identify, Is.False); - request.Command = ERDM_Command.GET_COMMAND; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(1)); - Assert.That(response.Value, Is.EqualTo(generated.Identify)); - - request.ParameterData = new byte[] { 0x01 }; // Requesting Identify OFF - request.Command = ERDM_Command.SET_COMMAND; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - - Assert.That(generated.Identify, Is.True); - - request.Command = ERDM_Command.GET_COMMAND; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(1)); - Assert.That(response.Value, Is.EqualTo(generated.Identify)); - - #endregion - } - [Test, Order(7)] - public void TestGetDMX_START_ADDRESS() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.DMX_START_ADDRESS, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_START_ADDRESS)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(2)); - Assert.That(response.Value, Is.EqualTo(generated.DMXAddress)); - #endregion - - - #region Test Address changed - generated.DMXAddress = 40; - Assert.That(generated.DMXAddress, Is.EqualTo(40)); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_START_ADDRESS)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(2)); - Assert.That(response.Value, Is.EqualTo(generated.DMXAddress)); - #endregion - } - [Test, Order(9)] - public void TestGetDEVICE_LABEL() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.DeviceLabel, Is.EqualTo("Dummy Device 1")); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.DEVICE_LABEL, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_LABEL)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(generated.DeviceLabel.Length)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceLabel)); - #endregion - - #region Test Label changed - Assert.That(generated.DeviceLabel, Is.EqualTo("Dummy Device 1")); - generated.DeviceLabel = "Rem x Ram"; - Assert.That(generated.DeviceLabel, Is.EqualTo("Rem x Ram")); - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_LABEL)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(generated.DeviceLabel.Length)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceLabel)); - #endregion - } - [Test, Order(10)] - public void TestGetDMX_PERSONALITY_DESCRIPTION() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, - SubDevice = SubDevice.Root, - ParameterData = new byte[] { 0x00 } // Requesting invalid 0 - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); - Assert.That(response.NackReason, Is.EqualTo(new ERDM_NackReason[] { ERDM_NackReason.DATA_OUT_OF_RANGE })); - - for (byte b = 0; b < generated.Personalities.Length; b++) - { - request.ParameterData = new byte[] { (byte)(b + 1) }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - var pers = generated.Personalities[b]; - var expected = new RDMDMXPersonalityDescription(pers.ID, pers.SlotCount, pers.Description); - Assert.That(response.ParameterData, Has.Length.EqualTo(expected.ToPayloadData().Length)); - Assert.That(response.Value, Is.EqualTo(expected)); - Assert.That(((RDMDMXPersonalityDescription)response.Value).Index, Is.EqualTo(expected.Index)); - } - #endregion - } - [Test, Order(11)] - public void TestGetDMX_PERSONALITY() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.CurrentPersonality, Is.EqualTo(1)); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.DMX_PERSONALITY, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - var pers = generated.Personalities[0]; - var expected = new RDMDMXPersonality(pers.ID, (byte)generated.Personalities.Count()); - Assert.That(response.ParameterData, Has.Length.EqualTo(expected.ToPayloadData().Length)); - Assert.That(response.Value, Is.EqualTo(expected)); - Assert.That(((RDMDMXPersonality)response.Value).MinIndex, Is.EqualTo(1)); - Assert.That(((RDMDMXPersonality)response.Value).Index, Is.EqualTo(1)); - Assert.That(((RDMDMXPersonality)response.Value).Count, Is.EqualTo(3)); - #endregion - - #region Test Label changed - Assert.That(generated.CurrentPersonality, Is.EqualTo(1)); - generated.CurrentPersonality = 2; - Assert.That(generated.CurrentPersonality, Is.EqualTo(2)); - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - pers = generated.Personalities[1]; - expected = new RDMDMXPersonality(pers.ID, (byte)generated.Personalities.Count()); - Assert.That(response.ParameterData, Has.Length.EqualTo(expected.ToPayloadData().Length)); - Assert.That(response.Value, Is.EqualTo(expected)); - #endregion - } - [Test, Order(15)] - public void TestGetMANUFACTURER_LABEL() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.ManufacturerLabel, Is.EqualTo("Dummy Manufacturer 9FFF")); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.MANUFACTURER_LABEL, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.MANUFACTURER_LABEL)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(generated.ManufacturerLabel.Length)); - Assert.That(response.Value, Is.EqualTo(generated.ManufacturerLabel)); - #endregion - } - [Test, Order(16)] - public void TestGetDEVICE_MODEL_DESCRIPTION() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.DeviceModelDescription, Is.EqualTo("Test Model Description")); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.DEVICE_MODEL_DESCRIPTION, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_MODEL_DESCRIPTION)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(generated.DeviceModelDescription.Length)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceModelDescription)); - #endregion - } - [Test, Order(30)] - public void TestGetBOOT_SOFTWARE_VERSION_ID() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.ParameterValues[ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID], Is.EqualTo(4660)); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(4)); - Assert.That(response.Value, Is.EqualTo(generated.ParameterValues[ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID])); - #endregion - } - [Test, Order(31)] - public void TestGetBOOT_SOFTWARE_VERSION_LABEL() - { - const string BOOT_SOFTWARE_VERSION_LABEL = "Dummy Bootloader Software"; - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.BootSoftwareVersionLabel, Is.EqualTo(BOOT_SOFTWARE_VERSION_LABEL)); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(BOOT_SOFTWARE_VERSION_LABEL.Length)); - Assert.That(response.Value, Is.EqualTo(BOOT_SOFTWARE_VERSION_LABEL)); - #endregion - - #region Test Label changed - generated.BootSoftwareVersionLabel = "Rem x Ram"; - Assert.That(generated.BootSoftwareVersionLabel, Is.EqualTo("Rem x Ram")); - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(generated.BootSoftwareVersionLabel.Length)); - Assert.That(response.Value, Is.EqualTo(generated.BootSoftwareVersionLabel)); - #endregion - } - [Test, Order(32)] - public void TestGetSOFTWARE_VERSION_LABEL() - { - const string SOFTWARE_VERSION_LABEL = "Dummy Software"; - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.SoftwareVersionLabel, Is.EqualTo(SOFTWARE_VERSION_LABEL)); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.SOFTWARE_VERSION_LABEL, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SOFTWARE_VERSION_LABEL)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(SOFTWARE_VERSION_LABEL.Length)); - Assert.That(response.Value, Is.EqualTo(SOFTWARE_VERSION_LABEL)); - #endregion - - #region Test Label changed - generated.SoftwareVersionLabel = "Rem x Ram"; - Assert.That(generated.SoftwareVersionLabel, Is.EqualTo("Rem x Ram")); - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SOFTWARE_VERSION_LABEL)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(generated.SoftwareVersionLabel.Length)); - Assert.That(response.Value, Is.EqualTo(generated.SoftwareVersionLabel)); - #endregion - } - - [Test, Order(40)] - public void TestGetSLOT_INFO() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.Slots, Has.Count.EqualTo(5)); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.SLOT_INFO, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_INFO)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(5 * generated.Slots.Count)); - Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMSlotInfo(s.Value.SlotId, s.Value.Type, s.Value.Category)))); - #endregion - - #region Test Change Personality - Assert.That(generated, Is.Not.Null); - generated.CurrentPersonality = 2; // Change to personality 2 - Assert.That(generated.Slots, Has.Count.EqualTo(8)); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_INFO)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(5 * generated.Slots.Count)); - Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMSlotInfo(s.Value.SlotId, s.Value.Type, s.Value.Category)))); - #endregion - - #region Test Change Personality - Assert.That(generated, Is.Not.Null); - generated.CurrentPersonality = 3; // Change to personality 3 - Assert.That(generated.Slots, Has.Count.EqualTo(9)); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_INFO)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(5 * generated.Slots.Count)); - Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMSlotInfo(s.Value.SlotId, s.Value.Type, s.Value.Category)))); - #endregion - - #region Test Invalid Calls - Assert.Throws(typeof(NullReferenceException), () => generated.CurrentPersonality = null); // Change to personality null - Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonality = 0); // Change to personality 0 - Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonality = 4); // Change to personality 4 - Assert.DoesNotThrow(() => generated.CurrentPersonality = 3); // Change to personality 3 - #endregion - } - - [Test, Order(41)] - public void TestGetDEFAULT_SLOT_VALUE() - { - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.Slots, Has.Count.EqualTo(5)); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.DEFAULT_SLOT_VALUE, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEFAULT_SLOT_VALUE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(3 * generated.Slots.Count)); - Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMDefaultSlotValue(s.Value.SlotId, s.Value.DefaultValue)))); - #endregion - - #region Test Change Personality - Assert.That(generated, Is.Not.Null); - generated.CurrentPersonality = 2; // Change to personality 2 - Assert.That(generated.Slots, Has.Count.EqualTo(8)); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEFAULT_SLOT_VALUE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(3 * generated.Slots.Count)); - Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMDefaultSlotValue(s.Value.SlotId, s.Value.DefaultValue)))); - #endregion - - #region Test Change Personality - Assert.That(generated, Is.Not.Null); - generated.CurrentPersonality = 3; // Change to personality 3 - Assert.That(generated.Slots, Has.Count.EqualTo(9)); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEFAULT_SLOT_VALUE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(3 * generated.Slots.Count)); - Assert.That(response.Value, Is.EqualTo(generated.Slots.Select(s => new RDMDefaultSlotValue(s.Value.SlotId, s.Value.DefaultValue)))); - #endregion - - #region Test Invalid Calls - Assert.Throws(typeof(NullReferenceException), () => generated.CurrentPersonality = null); // Change to personality null - Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonality = 0); // Change to personality 0 - Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonality = 4); // Change to personality 4 - Assert.DoesNotThrow(() => generated.CurrentPersonality = 3); // Change to personality 3 - #endregion - } - - [Test, Order(42)] - public void TestGetSLOT_DESCRIPTION() - { - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.SLOT_DESCRIPTION, - SubDevice = SubDevice.Root, - }; - RDMMessage? response = null; - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.Slots, Has.Count.EqualTo(5)); - doTests(generated.Slots.Values.ToArray()); - #endregion - - #region Test Change Personality 2 - generated.CurrentPersonality = 2; // Change to personality 2 - Assert.That(generated, Is.Not.Null); - Assert.That(generated.Slots, Has.Count.EqualTo(8)); - doTests(generated.Slots.Values.ToArray()); - #endregion - - #region Test Change Personality 3 - generated.CurrentPersonality = 3; // Change to personality 3 - Assert.That(generated, Is.Not.Null); - Assert.That(generated.Slots, Has.Count.EqualTo(9)); - doTests(generated.Slots.Values.ToArray()); - #endregion - - #region Test Invalid Calls - Assert.Throws(typeof(NullReferenceException), () => generated.CurrentPersonality = null); // Change to personality null - Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonality = 0); // Change to personality 0 - Assert.Throws(typeof(ArgumentOutOfRangeException), () => generated.CurrentPersonality = 4); // Change to personality 4 - Assert.DoesNotThrow(() => generated.CurrentPersonality = 3); // Change to personality 3 - - request.ParameterData = new byte[] { (byte)((10 >> 8) & 0xFF), (byte)(10 & 0xFF) }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_DESCRIPTION)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); - Assert.That(response.NackReason, Is.EqualTo(new ERDM_NackReason[] { ERDM_NackReason.DATA_OUT_OF_RANGE })); - #endregion - - void doTests(Slot[] slots) - { - foreach (Slot slot in slots) - { - request.ParameterData = new byte[] { (byte)((slot.SlotId >> 8) & 0xFF), (byte)(slot.SlotId & 0xFF) }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_DESCRIPTION)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(2 + slot.Description.Length)); - Assert.That(response.Value, Is.EqualTo(new RDMSlotDescription(slot.SlotId, slot.Description))); - } - } - } - - [Test, Order(51)] - public void TestGetSENSOR_DEFINITION() - { - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.SENSOR_DEFINITION, - SubDevice = SubDevice.Root, - }; - RDMMessage? response = null; - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.That(generated.Sensors, Has.Count.EqualTo(5)); - doTests(generated.Sensors.Values.ToArray()); - #endregion - - - #region Test Remove Sensors - - foreach (var sensor in generated.Sensors.Values.ToArray()) - generated.RemoveSensors(sensor); - - request.Command = ERDM_Command.SET_COMMAND; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.Multiple(() => - { - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_DEFINITION)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); - Assert.That(response.NackReason, Is.EqualTo(new ERDM_NackReason[] { ERDM_NackReason.UNKNOWN_PID })); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - }); - - request.Command = ERDM_Command.GET_COMMAND; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.Multiple(() => - { - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_DEFINITION)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); - Assert.That(response.NackReason, Is.EqualTo(new ERDM_NackReason[] { ERDM_NackReason.UNKNOWN_PID })); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - }); - #endregion - - void doTests(Sensor[] sensors) - { - foreach (Sensor sensor in sensors) - { - request.ParameterData = new byte[] { sensor.SensorId }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_DEFINITION)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(13 + sensor.Description.Length)); - Assert.That(response.Value, Is.EqualTo(new RDMSensorDefinition(sensor.SensorId, sensor.Type, sensor.Unit, sensor.Prefix, sensor.RangeMinimum, sensor.RangeMaximum, sensor.NormalMinimum, sensor.NormalMaximum, sensor.LowestHighestValueSupported, sensor.RecordedValueSupported, sensor.Description))); - } - } - } - - [Test, Order(52)] - public void TestGetSENSOR_VALUE() - { - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.SENSOR_VALUE, - SubDevice = SubDevice.Root, - }; - RDMMessage? response = null; - #region Test Basic - Assert.That(generated, Is.Not.Null); - Assert.Multiple(() => - { - Assert.That(generated.Sensors, Has.Count.EqualTo(5)); - - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(3000)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(8000)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(12000)); - - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); - - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(0)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(0)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(0)); - }); - - doTests(generated.Sensors.Values.ToArray()); - #endregion - - #region Test New Sensor Values - Assert.That(generated, Is.Not.Null); - Assert.That(generated.Sensors, Has.Count.EqualTo(5)); - ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(99); - ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(122); - ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(155); - - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(99)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(122)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(155)); - - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(99)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(122)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(155)); - - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); - }); - doTests(generated.Sensors.Values.ToArray()); - #endregion - - #region Test Recorded Sensor Values - Assert.Multiple(() => - { - Assert.That(generated, Is.Not.Null); - Assert.That(generated.Sensors, Has.Count.EqualTo(5)); - Assert.That(generated.Sensors[0].RecordedValueSupported, Is.True); - Assert.That(generated.Sensors[1].RecordedValueSupported, Is.True); - Assert.That(generated.Sensors[2].RecordedValueSupported, Is.True); - Assert.That(generated.Sensors[0].LowestHighestValueSupported, Is.True); - Assert.That(generated.Sensors[1].LowestHighestValueSupported, Is.True); - Assert.That(generated.Sensors[2].LowestHighestValueSupported, Is.True); - }); - - ((MockGeneratedSensor)generated.Sensors[0]).RecordValue(); - ((MockGeneratedSensor)generated.Sensors[1]).RecordValue(); - ((MockGeneratedSensor)generated.Sensors[2]).RecordValue(); - - ((MockGeneratedSensor)generated.Sensors[0]).UpdateValue(111); - ((MockGeneratedSensor)generated.Sensors[1]).UpdateValue(666); - ((MockGeneratedSensor)generated.Sensors[2]).UpdateValue(987); - - Assert.Multiple(() => - { - Assert.That(generated.Sensors[0].RecordedValue, Is.EqualTo(99)); - Assert.That(generated.Sensors[1].RecordedValue, Is.EqualTo(122)); - Assert.That(generated.Sensors[2].RecordedValue, Is.EqualTo(155)); - - Assert.That(generated.Sensors[0].PresentValue, Is.EqualTo(111)); - Assert.That(generated.Sensors[1].PresentValue, Is.EqualTo(666)); - Assert.That(generated.Sensors[2].PresentValue, Is.EqualTo(987)); - - Assert.That(generated.Sensors[0].LowestValue, Is.EqualTo(99)); - Assert.That(generated.Sensors[1].LowestValue, Is.EqualTo(122)); - Assert.That(generated.Sensors[2].LowestValue, Is.EqualTo(155)); - - Assert.That(generated.Sensors[0].HighestValue, Is.EqualTo(3000)); - Assert.That(generated.Sensors[1].HighestValue, Is.EqualTo(8000)); - Assert.That(generated.Sensors[2].HighestValue, Is.EqualTo(12000)); - }); - doTests(generated.Sensors.Values.ToArray()); - #endregion - - #region Test Reset Sensor Values Set_Request - request.Command = ERDM_Command.SET_COMMAND; - for (byte b = 0; b < 2; b++) - { - request.ParameterData = new byte[] { b }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.Multiple(() => - { - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_VALUE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(9)); - Assert.That(response.ParameterData[0], Is.EqualTo(b)); - Assert.That(response.Value, Is.TypeOf(typeof(RDMSensorValue))); - }); - } - #endregion - - #region Test Reset Sensor Values Set_Request (Broadcast) - request.ParameterData = new byte[] { 0xff }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.Multiple(() => - { - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_VALUE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(9)); - Assert.That(response.ParameterData[0], Is.EqualTo(0xff)); - Assert.That(response.Value, Is.TypeOf(typeof(RDMSensorValue))); - }); - foreach (var generatedSensor in generated.Sensors.Values) - { - Assert.Multiple(() => - { - Assert.That(generatedSensor, Is.Not.Null); - Sensor remoteSensor = generated.Sensors[generatedSensor.SensorId]; - Assert.That(remoteSensor, Is.Not.Null); - Assert.That(remoteSensor.PresentValue, Is.EqualTo(generatedSensor.PresentValue)); - Assert.That(remoteSensor.LowestValue, Is.EqualTo(generatedSensor.LowestValue)); - Assert.That(remoteSensor.HighestValue, Is.EqualTo(generatedSensor.HighestValue)); - Assert.That(remoteSensor.RecordedValue, Is.EqualTo(generatedSensor.RecordedValue)); - }); - } - #endregion - - #region Test Remove Sensors - foreach (var sensor in generated.Sensors.Values.ToArray()) - generated.RemoveSensors(sensor); - - request.ParameterData = new byte[] { 0 }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.Multiple(() => - { - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_VALUE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); - Assert.That(response.NackReason, Is.EqualTo(new ERDM_NackReason[] { ERDM_NackReason.UNKNOWN_PID })); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - }); - - request.Command = ERDM_Command.GET_COMMAND; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.Multiple(() => - { - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_VALUE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); - Assert.That(response.NackReason, Is.EqualTo(new ERDM_NackReason[] { ERDM_NackReason.UNKNOWN_PID })); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - }); - #endregion - - void doTests(Sensor[] sensors) - { - foreach (Sensor sensor in sensors) - { - request.ParameterData = new byte[] { sensor.SensorId }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.Multiple(() => - { - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_VALUE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(9)); - Assert.That(response.Value, Is.EqualTo(new RDMSensorValue(sensor.SensorId, sensor.PresentValue, sensor.LowestValue, sensor.HighestValue, sensor.RecordedValue))); - }); - } - } - } - [Test, Order(53)] - public void TestGetRECORD_SENSORS() - { - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.SET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.RECORD_SENSORS, - SubDevice = SubDevice.Root, - }; - RDMMessage? response = null; - - Assert.That(generated, Is.Not.Null); - Assert.That(generated.Sensors, Has.Count.EqualTo(5)); - - #region Test Recorded Sensor Values Set_Request - for (byte b = 0; b < 2; b++) - { - request.ParameterData = new byte[] { b }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.Multiple(() => - { - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RECORD_SENSORS)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - }); - } - #endregion - - #region Test Recorded Sensor Values Set_Request (Broadcast) - request.ParameterData = new byte[] { 0xff }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.Multiple(() => - { - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RECORD_SENSORS)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - }); - foreach (var generatedSensor in generated.Sensors.Values) - { - Assert.Multiple(() => - { - Assert.That(generatedSensor, Is.Not.Null); - Sensor remoteSensor = generated.Sensors[generatedSensor.SensorId]; - Assert.That(remoteSensor, Is.Not.Null); - Assert.That(remoteSensor.PresentValue, Is.EqualTo(generatedSensor.PresentValue)); - Assert.That(remoteSensor.LowestValue, Is.EqualTo(generatedSensor.LowestValue)); - Assert.That(remoteSensor.HighestValue, Is.EqualTo(generatedSensor.HighestValue)); - Assert.That(remoteSensor.RecordedValue, Is.EqualTo(generatedSensor.RecordedValue)); - }); - } - #endregion - - #region Test Invalid Calls - request.ParameterData = new byte[] { 30 }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RECORD_SENSORS)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); - Assert.That(response.NackReason, Is.EqualTo(new ERDM_NackReason[] { ERDM_NackReason.DATA_OUT_OF_RANGE })); - - request.ParameterData = new byte[] { 2 }; - request.Command = ERDM_Command.GET_COMMAND; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RECORD_SENSORS)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); - Assert.That(response.NackReason, Is.EqualTo(new ERDM_NackReason[] { ERDM_NackReason.UNSUPPORTED_COMMAND_CLASS })); - #endregion - - #region Test Remove Sensors - foreach (var sensor in generated.Sensors.Values.ToArray()) - generated.RemoveSensors(sensor); - - request.ParameterData = new byte[] { 0 }; - request.Command = ERDM_Command.SET_COMMAND; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.Multiple(() => - { - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.RECORD_SENSORS)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); - Assert.That(response.NackReason, Is.EqualTo(new ERDM_NackReason[] { ERDM_NackReason.UNKNOWN_PID })); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - }); - #endregion - } - - [Test, Order(100)] - public void TestGetSTATUS_MESSAGES() - { - #region Test Empty Status Messages - Assert.That(generated, Is.Not.Null); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.STATUS_MESSAGES, - SubDevice = SubDevice.Root, - ParameterData = new byte[] { (byte)ERDM_Status.ERROR } - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - #endregion - - #region Test Basic Status Messages - generated.AddStatusMessage(new RDMStatusMessage( - subDeviceId: 0, - statusType: ERDM_Status.ERROR, - statusMessage: ERDM_StatusMessage.OVERCURRENT, - dataValue1: 1234, - dataValue2: 5678)); - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(9)); - Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); - RDMStatusMessage[] statusMessages = (RDMStatusMessage[])response.Value; - Assert.That(statusMessages[0], Is.EqualTo(generated.StatusMessages[0])); - - generated.AddStatusMessage(new RDMStatusMessage( - subDeviceId: 0, - statusType: ERDM_Status.ERROR, - statusMessage: ERDM_StatusMessage.UNDERTEMP, - dataValue1: 33, - dataValue2: 12)); - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(18)); - Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); - statusMessages = (RDMStatusMessage[])response.Value; - Assert.That(statusMessages, Has.Length.EqualTo(2)); - Assert.That(statusMessages[0], Is.EqualTo(generated.StatusMessages[0])); - Assert.That(statusMessages[1], Is.EqualTo(generated.StatusMessages[1])); - #endregion - - #region Test Overflow - for (byte i = 0; i < 30; i++) - { - generated.AddStatusMessage(new RDMStatusMessage( - subDeviceId: i, - statusType: ERDM_Status.ADVISORY, - statusMessage: ERDM_StatusMessage.WATTS, - dataValue1: 33, - dataValue2: 12)); - } - - request.ParameterData = new byte[] { (byte)ERDM_Status.ADVISORY }; - response = generated.ProcessRequestMessage_Internal(request); - - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK_OVERFLOW)); - Assert.That(response.ParameterData, Has.Length.EqualTo(9 * 25)); - Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); - statusMessages = (RDMStatusMessage[])response.Value; - Assert.That(statusMessages, Has.Length.EqualTo(25)); - for (int i = 0; i < 25; i++) - Assert.That(statusMessages[i], Is.EqualTo(generated.StatusMessages[i])); - - response = generated.ProcessRequestMessage_Internal(request); - - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(9 * 7)); - Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); - statusMessages = (RDMStatusMessage[])response.Value; - Assert.That(statusMessages, Has.Length.EqualTo(7)); - for (int i = 0; i < 7; i++) - Assert.That(statusMessages[i], Is.EqualTo(generated.StatusMessages[i + 25])); - #endregion - - #region Test GET_LAST_MESSAGE - request.ParameterData = new byte[] { (byte)ERDM_Status.GET_LAST_MESSAGE }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(9 * 7)); - Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); - statusMessages = (RDMStatusMessage[])response.Value; - Assert.That(statusMessages, Has.Length.EqualTo(7)); - for (int i = 0; i < 7; i++) - Assert.That(statusMessages[i], Is.EqualTo(generated.StatusMessages[i + 25])); - #endregion - - #region Test filtering by status type - request.ParameterData = new byte[] { (byte)ERDM_Status.ERROR }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(18)); - statusMessages = (RDMStatusMessage[])response.Value; - for (int i = 0; i < 2; i++) - Assert.That(statusMessages[i], Is.EqualTo(generated.StatusMessages[i])); - #endregion - - #region Test Cleared Status Messages - generated.ClearStatusMessage(generated.StatusMessages[0]); - request.ParameterData = new byte[] { (byte)ERDM_Status.ERROR }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(18)); - statusMessages = (RDMStatusMessage[])response.Value; - Assert.That(statusMessages[0].EStatusType, Is.EqualTo(ERDM_Status.ERROR_CLEARED)); - for (int i = 0; i < 2; i++) - Assert.That(statusMessages[i], Is.EqualTo(generated.StatusMessages[i])); - #endregion - - #region Test Remove Status Messages - foreach (RDMStatusMessage statusMessage in generated.StatusMessages.Values.ToArray()) - generated.RemoveStatusMessage(statusMessage); - - request.ParameterData = new byte[] { (byte)ERDM_Status.ADVISORY }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - #endregion - - - #region CLEAR_STATUS_ID - generated.AddStatusMessage(new RDMStatusMessage( - subDeviceId: 0, - statusType: ERDM_Status.ERROR, - statusMessage: ERDM_StatusMessage.OVERCURRENT, - dataValue1: 1234, - dataValue2: 5678)); - request.ParameterData = new byte[] { }; - request.Parameter = ERDM_Parameter.CLEAR_STATUS_ID; - request.Command = ERDM_Command.SET_COMMAND; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CLEAR_STATUS_ID)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(0)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - #endregion - } - [Test, Order(1000)] - public void TestGetQUEUED_MESSAGE() - { - #region Test Empty queue - Assert.That(generated, Is.Not.Null); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.QUEUED_MESSAGE, - SubDevice = SubDevice.Root, - ParameterData = new byte[] { (byte)ERDM_Status.ADVISORY } - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - #endregion - - #region Test set DMX-Address (single value changed) - Assert.That(generated.DMXAddress, Is.EqualTo(1)); - generated.DMXAddress = 42; - Assert.That(generated.DMXAddress, Is.EqualTo(42)); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_START_ADDRESS)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(1)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(2)); - Assert.That(response.Value, Is.EqualTo(generated.DMXAddress)); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(0)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(19)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); - #endregion - - #region Test Get last Message - request.ParameterData = new byte[] { (byte)ERDM_Status.GET_LAST_MESSAGE }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(0)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(19)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); - #endregion - - #region Test set DMX-Address (multiple value changed) - Assert.That(generated.DMXAddress, Is.EqualTo(42)); - generated.DMXAddress = 50; - Assert.That(generated.DMXAddress, Is.EqualTo(50)); - generated.DMXAddress = 60; - Assert.That(generated.DMXAddress, Is.EqualTo(60)); - generated.DMXAddress = 70; - Assert.That(generated.DMXAddress, Is.EqualTo(70)); - generated.DMXAddress = 80; - Assert.That(generated.DMXAddress, Is.EqualTo(80)); - - request.ParameterData = new byte[] { (byte)ERDM_Status.ERROR }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_START_ADDRESS)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(1)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(2)); - Assert.That(response.Value, Is.EqualTo(generated.DMXAddress)); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(0)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(19)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); - #endregion - - #region Test set DeviceLabel (single value changed) - Assert.That(generated.DeviceLabel, Is.EqualTo("Dummy Device 1")); - generated.DeviceLabel = "Test Device Queued Message 1"; - Assert.That(generated.DeviceLabel, Is.EqualTo("Test Device Queued Message 1")); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_LABEL)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(0)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(generated.DeviceLabel.Length)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceLabel)); - #endregion - - #region Test set Multiple Parameter at once - generated.DeviceLabel = "GG"; - Assert.That(generated.DeviceLabel, Is.EqualTo("GG")); - generated.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, true); - generated.CurrentPersonality = 2; - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_LABEL)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(13)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(generated.DeviceLabel.Length)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceLabel)); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.IDENTIFY_DEVICE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(12)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(1)); - Assert.That(response.Value, Is.EqualTo(true)); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(11)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(2)); - Assert.That(response.Value, Is.EqualTo(new RDMDMXPersonality(2, 3))); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_INFO)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(10)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(40)); - Assert.That(response.Value, Is.EqualTo(generated.Personalities[1].Slots.Select(s => new RDMSlotInfo(s.Value.SlotId, s.Value.Type, s.Value.Category)))); - - for (byte b = 0; b < generated.Personalities[1].SlotCount; b++) - { - var slot = generated.Personalities[1].Slots[b]; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.SLOT_DESCRIPTION)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(9 - b)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(generated.Personalities[1].Slots[b].Description.Length + 2)); - Assert.That(response.Value, Is.EqualTo(new RDMSlotDescription(slot.SlotId, slot.Description))); - } - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEFAULT_SLOT_VALUE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(1)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(3 * generated.Personalities[1].Slots.Count)); - Assert.That(response.Value, Is.EqualTo(generated.Personalities[1].Slots.Select(s => new RDMDefaultSlotValue(s.Value.SlotId, s.Value.DefaultValue)))); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(0)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(19)); - Assert.That(response.Value, Is.EqualTo(generated.DeviceInfo)); - - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(0)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - #endregion - - request.ParameterData = new byte[] { (byte)ERDM_Status.ADVISORY }; - var sm = new RDMStatusMessage(0, ERDM_Status.ADVISORY, ERDM_StatusMessage.AMPS, 222); - generated.AddStatusMessage(sm); - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.STATUS_MESSAGES)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(0)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(9)); - Assert.That(response.Value, Is.TypeOf(typeof(RDMStatusMessage[]))); - RDMStatusMessage[] messages = (RDMStatusMessage[])response.Value; - Assert.That(messages[0], Is.EqualTo(sm)); - - #region - request.ParameterData = new byte[] { (byte)ERDM_Status.NONE }; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.QUEUED_MESSAGE)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(0)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.NACK_REASON)); - Assert.That(response.NackReason, Is.EqualTo(new ERDM_NackReason[] { ERDM_NackReason.FORMAT_ERROR })); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - #endregion - - #region CLEAR_STATUS_ID - request.ParameterData = new byte[] { }; - request.Parameter = ERDM_Parameter.CLEAR_STATUS_ID; - request.Command = ERDM_Command.SET_COMMAND; - response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.SET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.CLEAR_STATUS_ID)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.MessageCounter, Is.EqualTo(0)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(0)); - #endregion - } - - [Test, Retry(3), Order(61)] - public async Task TestGetREAL_TIME_CLOCK() - { - TearDown(); - generated = new RealTimeMockDevice(DEVCIE_UID); - await Task.Delay(500); - #region Test Basic - Assert.That(generated, Is.Not.Null); - await Task.Delay(1000); - Assert.That(generated.RealTimeClock.Minute, Is.EqualTo(DateTime.Now.Minute)); - RDMMessage request = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - DestUID = DEVCIE_UID, - SourceUID = CONTROLLER_UID, - Parameter = ERDM_Parameter.REAL_TIME_CLOCK, - SubDevice = SubDevice.Root, - }; - - RDMMessage? response = generated.ProcessRequestMessage_Internal(request); - Assert.That(response, Is.Not.Null); - Assert.That(response.Command, Is.EqualTo(ERDM_Command.GET_COMMAND | ERDM_Command.RESPONSE)); - Assert.That(response.DestUID, Is.EqualTo(CONTROLLER_UID)); - Assert.That(response.SourceUID, Is.EqualTo(DEVCIE_UID)); - Assert.That(response.Parameter, Is.EqualTo(ERDM_Parameter.REAL_TIME_CLOCK)); - Assert.That(response.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(response.ResponseType, Is.EqualTo(ERDM_ResponseType.ACK)); - Assert.That(response.ParameterData, Has.Length.EqualTo(7)); - Assert.That(response.Value, Is.TypeOf(typeof(RDMRealTimeClock))); - var timeGen = new RDMRealTimeClock(generated.RealTimeClock); - var timeRem = (RDMRealTimeClock)response.Value; - Assert.That(timeRem.Year, Is.EqualTo(timeGen.Year)); - Assert.That(timeRem.Month, Is.EqualTo(timeGen.Month)); - Assert.That(timeRem.Day, Is.EqualTo(timeGen.Day)); - Assert.That(timeRem.Minute, Is.EqualTo(timeGen.Minute)); - Assert.That(timeRem.Second, Is.AtLeast(timeGen.Second - 2).And.AtMost(timeGen.Second + 2)); - #endregion - - } - class RealTimeMockDevice : MockGeneratedDevice1 - { - public RealTimeMockDevice(UID uid) : base(uid) - { - } - - public override bool SupportRealTimeClock => true; - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/Devices/TestRDMSendReceiveSubDevices.cs b/RDMSharpTests/Devices/TestRDMSendReceiveSubDevices.cs index e9fd8f82..008b79a4 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceiveSubDevices.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceiveSubDevices.cs @@ -1,154 +1,166 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; +using RDMSharp.RDM.Device.Module; using RDMSharpTests.Devices.Mock; -using System; -namespace RDMSharpTests.RDM.Devices -{ - public class TestRDMSendReceiveSubDevices - { - private MockGeneratedDeviceWithSubDeviceMaster1 generated; - private MockDevice remote; - private Random random = new Random(); +namespace RDMSharpTests.RDM.Devices; - private const ushort SUBDEVICE_COUNT = 12; +public class TestRDMSendReceiveSubDevices +{ + private MockGeneratedDeviceWithSubDeviceMaster1 generated; + private MockDevice remote; + private Random random = new Random(); - [SetUp] - public void Setup() - { - var uid = new UID((ushort)random.Next(), (uint)random.Next()); - generated = new MockGeneratedDeviceWithSubDeviceMaster1(uid, SUBDEVICE_COUNT); - remote = new MockDevice(uid); - } - [TearDown] - public void TearDown() - { - generated.Dispose(); - remote.Dispose(); - } + private const ushort SUBDEVICE_COUNT = 12; - [Test, CancelAfter(100000)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] - public async Task TestDevice1() - { - while (!remote.IsInitialized) - await Task.Delay(10); + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } - while (remote.SubDevices.Count < SUBDEVICE_COUNT) - await Task.Delay(100); - while (!remote.SubDevices.Cast().All(sd => sd.AllDataPulled)) - await Task.Delay(100); + [SetUp] + public void Setup() + { + var uid = new UID((ushort)random.Next(), (uint)random.Next()); + generated = new MockGeneratedDeviceWithSubDeviceMaster1(uid, SUBDEVICE_COUNT); + remote = new MockDevice(uid); + } + [TearDown] + public void TearDown() + { + generated.Dispose(); + remote.Dispose(); + } - SubDevice[] subDeviceIDs_generated = generated.SubDevices.Select(x => x.Subdevice).ToArray(); - SubDevice[] subDeviceIDs_remote = remote.SubDevices.Select(x => x.Subdevice).ToArray(); + [Test, CancelAfter(100000)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] + public async Task TestDevice1() + { + while (!remote.IsInitialized) + await Task.Delay(10); - Assert.That(generated.DeviceInfo.SubDeviceCount, Is.EqualTo(SUBDEVICE_COUNT)); - Assert.That(generated.SubDevices.Count, Is.EqualTo(SUBDEVICE_COUNT + 1)); - Assert.That(generated.DeviceInfo.Dmx512StartAddress, Is.EqualTo(1)); + while (remote.SubDevices.Count < SUBDEVICE_COUNT) + await Task.Delay(100); - Assert.That(remote.DeviceInfo.SubDeviceCount, Is.EqualTo(SUBDEVICE_COUNT)); - Assert.That(remote.SubDevices.Count, Is.EqualTo(SUBDEVICE_COUNT + 1)); - Assert.That(remote.DeviceInfo.Dmx512StartAddress, Is.EqualTo(1)); + while (!remote.SubDevices.Cast().All(sd => sd.AllDataPulled)) + await Task.Delay(100); - Assert.That(remote.SubDevices, Has.Count.EqualTo(SUBDEVICE_COUNT + 1)); + SubDevice[] subDeviceIDs_generated = generated.SubDevices.Select(x => x.Subdevice).ToArray(); + SubDevice[] subDeviceIDs_remote = remote.SubDevices.Select(x => x.Subdevice).ToArray(); - Assert.That(subDeviceIDs_remote, Is.EquivalentTo(subDeviceIDs_generated)); + Assert.That(generated.DeviceInfo.SubDeviceCount, Is.EqualTo(SUBDEVICE_COUNT)); + Assert.That(generated.SubDevices.Count, Is.EqualTo(SUBDEVICE_COUNT + 1)); + Assert.That(generated.DeviceInfo.Dmx512StartAddress, Is.EqualTo(1)); - Assert.That(subDeviceIDs_generated, Has.ItemAt(0).EqualTo(SubDevice.Root)); - Assert.That(subDeviceIDs_remote, Has.ItemAt(0).EqualTo(SubDevice.Root)); + Assert.That(remote.DeviceInfo.SubDeviceCount, Is.EqualTo(SUBDEVICE_COUNT)); + Assert.That(remote.SubDevices.Count, Is.EqualTo(SUBDEVICE_COUNT + 1)); + Assert.That(remote.DeviceInfo.Dmx512StartAddress, Is.EqualTo(1)); - foreach(AbstractGeneratedRDMDevice gen in generated.SubDevices) - { - var rem = (AbstractRemoteRDMDevice)remote.SubDevices.First(sd => sd.Subdevice == gen.Subdevice); - Assert.That(rem.DeviceInfo.Dmx512StartAddress, Is.EqualTo(1)); - Assert.That(gen.DeviceInfo.Dmx512StartAddress, Is.EqualTo(1)); - await PerformTests(rem, gen); - } + Assert.That(remote.SubDevices, Has.Count.EqualTo(SUBDEVICE_COUNT + 1)); - } - private async Task PerformTests(AbstractRemoteRDMDevice remote, AbstractGeneratedRDMDevice generated) - { - var parameterValuesRemote = remote.GetAllParameterValues(); - var parameterValuesGenerated = generated.GetAllParameterValues(); + Assert.That(subDeviceIDs_remote, Is.EquivalentTo(subDeviceIDs_generated)); + Assert.That(subDeviceIDs_generated, Has.ItemAt(0).EqualTo(SubDevice.Root)); + Assert.That(subDeviceIDs_remote, Has.ItemAt(0).EqualTo(SubDevice.Root)); - Console.WriteLine($"SD: [{generated.Subdevice.ID}] Generated: {String.Join(", ", parameterValuesGenerated.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); - Console.WriteLine($"SD: [{remote.Subdevice.ID }] Remote: {String.Join(", ", parameterValuesRemote.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); - //Assert.Multiple(() => - //{ - Assert.That(parameterValuesGenerated.Keys, Is.EquivalentTo(parameterValuesRemote.Keys)); - foreach (var parameter in parameterValuesGenerated.Keys) - { - Assert.That(parameterValuesRemote.Keys, Contains.Item(parameter), $"Tested Parameter {parameter}"); - if (parameterValuesGenerated[parameter] is Array) - Assert.That(parameterValuesGenerated[parameter], Is.EquivalentTo((Array)parameterValuesRemote[parameter]), $"Tested Parameter {parameter}"); - else - Assert.That(parameterValuesGenerated[parameter], Is.EqualTo(parameterValuesRemote[parameter]), $"Tested Parameter {parameter}"); - } - foreach (var parameter in parameterValuesRemote.Keys) - { - Assert.That(parameterValuesGenerated.Keys, Contains.Item(parameter), $"Tested Parameter {parameter}"); - if (parameterValuesRemote[parameter] is Array) - Assert.That(parameterValuesRemote[parameter], Is.EquivalentTo((Array)parameterValuesGenerated[parameter]), $"Tested Parameter {parameter}"); - else - Assert.That(parameterValuesRemote[parameter], Is.EqualTo(parameterValuesGenerated[parameter]), $"Tested Parameter {parameter}"); - } - Assert.That(parameterValuesRemote, Has.Count.EqualTo(parameterValuesGenerated.Count)); - //}); + foreach (AbstractGeneratedRDMDevice gen in generated.SubDevices) + { + var rem = (AbstractRemoteRDMDevice)remote.SubDevices.First(sd => sd.Subdevice == gen.Subdevice); + Assert.That(rem.DeviceInfo.Dmx512StartAddress, Is.EqualTo(1)); + Assert.That(gen.DeviceInfo.Dmx512StartAddress, Is.EqualTo(1)); + await PerformTests(rem, gen); + } - //Assert.Multiple(() => - //{ - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DEVICE_INFO], Is.EqualTo(generated.DeviceInfo)); - Assert.That(remote.ParameterValues[ERDM_Parameter.DEVICE_LABEL], Is.EqualTo(generated.DeviceLabel)); - Assert.That(remote.ParameterValues[ERDM_Parameter.DEVICE_MODEL_DESCRIPTION], Is.EqualTo(generated.DeviceModelDescription)); - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.MANUFACTURER_LABEL], Is.EqualTo(generated.ManufacturerLabel)); - Assert.That(((RDMDMXPersonality)remote.ParameterValues[ERDM_Parameter.DMX_PERSONALITY]).Index, Is.EqualTo(generated.CurrentPersonality)); - //}); + } + private async Task PerformTests(AbstractRemoteRDMDevice remote, AbstractGeneratedRDMDevice generated) + { + var parameterValuesRemote = remote.GetAllParameterValues(); + var parameterValuesGenerated = generated.GetAllParameterValues(); - await remote.SetParameter(ERDM_Parameter.DMX_START_ADDRESS, (ushort)512); - //Assert.Multiple(() => - //{ - Assert.That(remote.ParameterValues[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(512)); - Assert.That(generated.DMXAddress, Is.EqualTo(512)); - //}); - if (generated.Personalities.Any(p => p.ID == 3)) - { - await remote.SetParameter(ERDM_Parameter.DMX_PERSONALITY, (byte)3); - //Assert.Multiple(() => - //{ - Assert.That(remote.ParameterValues[ERDM_Parameter.DMX_PERSONALITY], Is.EqualTo(3)); - Assert.That(generated.CurrentPersonality, Is.EqualTo(3)); - //}); - } - - string label = "Changed Device Label"; - await remote.SetParameter(ERDM_Parameter.DEVICE_LABEL, label); + Console.WriteLine($"SD: [{generated.Subdevice.ID}] Generated: {String.Join(", ", parameterValuesGenerated.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); + Console.WriteLine($"SD: [{remote.Subdevice.ID}] Remote: {String.Join(", ", parameterValuesRemote.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); + //Assert.Multiple(() => + //{ + Assert.That(parameterValuesGenerated.Keys, Is.EquivalentTo(parameterValuesRemote.Keys)); + foreach (var parameter in parameterValuesGenerated.Keys) + { + Assert.That(parameterValuesRemote.Keys, Contains.Item(parameter), $"Tested Parameter {parameter}"); + if (parameterValuesGenerated[parameter] is Array) + Assert.That(parameterValuesGenerated[parameter], Is.EquivalentTo((Array)parameterValuesRemote[parameter]), $"Tested Parameter {parameter}"); + else + Assert.That(parameterValuesGenerated[parameter], Is.EqualTo(parameterValuesRemote[parameter]), $"Tested Parameter {parameter}"); + } + foreach (var parameter in parameterValuesRemote.Keys) + { + Assert.That(parameterValuesGenerated.Keys, Contains.Item(parameter), $"Tested Parameter {parameter}"); + if (parameterValuesRemote[parameter] is Array) + Assert.That(parameterValuesRemote[parameter], Is.EquivalentTo((Array)parameterValuesGenerated[parameter]), $"Tested Parameter {parameter}"); + else + Assert.That(parameterValuesRemote[parameter], Is.EqualTo(parameterValuesGenerated[parameter]), $"Tested Parameter {parameter}"); + } + Assert.That(parameterValuesRemote, Has.Count.EqualTo(parameterValuesGenerated.Count)); + //}); + + var deviceLabelModule = generated.Modules.OfType().Single(); + var manufacturerLabelModule = generated.Modules.OfType().Single(); + var deviceModelDescriptionModule = generated.Modules.OfType().Single(); + + //Assert.Multiple(() => + //{ + Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DEVICE_INFO], Is.EqualTo(generated.DeviceInfo)); + Assert.That(remote.ParameterValues[ERDM_Parameter.DEVICE_LABEL], Is.EqualTo(deviceLabelModule.DeviceLabel)); + Assert.That(remote.ParameterValues[ERDM_Parameter.DEVICE_MODEL_DESCRIPTION], Is.EqualTo(deviceModelDescriptionModule.DeviceModelDescription)); + Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.MANUFACTURER_LABEL], Is.EqualTo(manufacturerLabelModule.ManufacturerLabel)); + Assert.That(((RDMDMXPersonality)remote.ParameterValues[ERDM_Parameter.DMX_PERSONALITY]).Index, Is.EqualTo(generated.CurrentPersonalityId)); + //}); + + await remote.SetParameter(ERDM_Parameter.DMX_START_ADDRESS, (ushort)512); + //Assert.Multiple(() => + //{ + Assert.That(remote.ParameterValues[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(512)); + Assert.That(generated.DMXAddress, Is.EqualTo(512)); + //}); + + if (generated.Personalities.Any(p => p.ID == 3)) + { + await remote.SetParameter(ERDM_Parameter.DMX_PERSONALITY, (byte)3); //Assert.Multiple(() => //{ - Assert.That(remote.ParameterValues[ERDM_Parameter.DEVICE_LABEL], Is.EqualTo(label)); - Assert.That(generated.DeviceLabel, Is.EqualTo(label)); + Assert.That(remote.ParameterValues[ERDM_Parameter.DMX_PERSONALITY], Is.EqualTo(3)); + Assert.That(generated.CurrentPersonalityId, Is.EqualTo(3)); //}); - //Assert.Multiple(async () => - //{ - Assert.That(remote.ParameterValues[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); - Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); - await remote.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, true); - Assert.That(remote.ParameterValues[ERDM_Parameter.IDENTIFY_DEVICE], Is.True); - Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.True); - await remote.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, false); - Assert.That(remote.ParameterValues[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); - Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); - //}); - //Assert.Multiple(() => - ////{ - //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_INFO, new RDMDeviceInfo()); }); - //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, new RDMDMXPersonalityDescription(1, 2, "dasdad")); }); - //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.LANGUAGE, "de"); }); - //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.LANGUAGE, 333); }); - //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_LABEL, "Test"); }); - //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DISC_MUTE, null); }); - //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_LABEL, new RDMDeviceInfo()); }); - ////}); } + + string label = "Changed Device Label"; + await remote.SetParameter(ERDM_Parameter.DEVICE_LABEL, label); + //Assert.Multiple(() => + //{ + Assert.That(remote.ParameterValues[ERDM_Parameter.DEVICE_LABEL], Is.EqualTo(label)); + Assert.That(deviceLabelModule.DeviceLabel, Is.EqualTo(label)); + //}); + //Assert.Multiple(async () => + //{ + Assert.That(remote.ParameterValues[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); + Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); + await remote.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, true); + Assert.That(remote.ParameterValues[ERDM_Parameter.IDENTIFY_DEVICE], Is.True); + Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.True); + await remote.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, false); + Assert.That(remote.ParameterValues[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); + Assert.That(generated.GetAllParameterValues()[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); + //}); + //Assert.Multiple(() => + ////{ + //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_INFO, new RDMDeviceInfo()); }); + //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, new RDMDMXPersonalityDescription(1, 2, "dasdad")); }); + //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.LANGUAGE, "de"); }); + //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.LANGUAGE, 333); }); + //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_LABEL, "Test"); }); + //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DISC_MUTE, null); }); + //Assert.Throws(typeof(NotSupportedException), () => { generated.TrySetParameter(ERDM_Parameter.DEVICE_LABEL, new RDMDeviceInfo()); }); + ////}); } } \ No newline at end of file diff --git a/RDMSharpTests/Devices/TestRDMSendReceive_SlotOverflow.cs b/RDMSharpTests/Devices/TestRDMSendReceive_SlotOverflow.cs index b7e19512..bbf299b5 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceive_SlotOverflow.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceive_SlotOverflow.cs @@ -1,59 +1,66 @@ +using RDMSharp.Metadata; using RDMSharpTests.Devices.Mock; -namespace RDMSharpTests.RDM.Devices +namespace RDMSharpTests.RDM.Devices; + +public class TestRDMSendReceive_SlotOverflow { - public class TestRDMSendReceive_SlotOverflow + private MockGeneratedDevice_SlotOverflow? generated; + private MockDevice? remote; + private Random random = new Random(); + + [OneTimeSetUp] + public async Task OneTimeSetup() { - private MockGeneratedDevice_SlotOverflow? generated; - private MockDevice? remote; - private Random random = new Random(); - [SetUp] - public void Setup() - { - var uid = new UID((ushort)random.Next(), (uint)random.Next()); - generated = new MockGeneratedDevice_SlotOverflow(uid); - remote = new MockDevice(uid); - } - [TearDown] - public void TearDown() - { - generated?.Dispose(); - generated = null; - remote?.Dispose(); - remote = null; - } + await MetadataFactory.AwaitInitialize(); + } - [Test, Retry(3), Order(1)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] - public async Task TestDevice1() - { - var parameterValuesRemote = remote!.GetAllParameterValues(); - var parameterValuesGenerated = generated!.GetAllParameterValues(); + [SetUp] + public void Setup() + { + var uid = new UID((ushort)random.Next(), (uint)random.Next()); + generated = new MockGeneratedDevice_SlotOverflow(uid); + remote = new MockDevice(uid); + } + [TearDown] + public void TearDown() + { + generated?.Dispose(); + generated = null; + remote?.Dispose(); + remote = null; + } - Console.WriteLine($"Generated: {String.Join(", ", parameterValuesGenerated.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); - Console.WriteLine($"Remote: {String.Join(", ", parameterValuesRemote.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); + [Test, Retry(3), Order(1)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] + public async Task TestDevice1() + { + var parameterValuesRemote = remote!.GetAllParameterValues(); + var parameterValuesGenerated = generated!.GetAllParameterValues(); - Assert.Multiple(() => + Console.WriteLine($"Generated: {String.Join(", ", parameterValuesGenerated.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); + Console.WriteLine($"Remote: {String.Join(", ", parameterValuesRemote.OrderBy(p => p.Key).Select(x => $"{x.Key}"))}"); + + Assert.Multiple(() => + { + Assert.That(parameterValuesGenerated.Keys, Is.EquivalentTo(parameterValuesRemote.Keys)); + foreach (var parameter in parameterValuesGenerated.Keys) + { + Assert.That(parameterValuesRemote.Keys, Contains.Item(parameter), $"Tested Parameter {parameter}"); + if (parameterValuesGenerated[parameter] is Array) + Assert.That(parameterValuesGenerated[parameter], Is.EquivalentTo((Array)parameterValuesRemote[parameter]), $"Tested Parameter {parameter}"); + else + Assert.That(parameterValuesGenerated[parameter], Is.EqualTo(parameterValuesRemote[parameter]), $"Tested Parameter {parameter}"); + } + foreach (var parameter in parameterValuesRemote.Keys) { - Assert.That(parameterValuesGenerated.Keys, Is.EquivalentTo(parameterValuesRemote.Keys)); - foreach (var parameter in parameterValuesGenerated.Keys) - { - Assert.That(parameterValuesRemote.Keys, Contains.Item(parameter), $"Tested Parameter {parameter}"); - if (parameterValuesGenerated[parameter] is Array) - Assert.That(parameterValuesGenerated[parameter], Is.EquivalentTo((Array)parameterValuesRemote[parameter]), $"Tested Parameter {parameter}"); - else - Assert.That(parameterValuesGenerated[parameter], Is.EqualTo(parameterValuesRemote[parameter]), $"Tested Parameter {parameter}"); - } - foreach (var parameter in parameterValuesRemote.Keys) - { - Assert.That(parameterValuesGenerated.Keys, Contains.Item(parameter), $"Tested Parameter {parameter}"); - if (parameterValuesRemote[parameter] is Array) - Assert.That(parameterValuesRemote[parameter], Is.EquivalentTo((Array)parameterValuesGenerated[parameter]), $"Tested Parameter {parameter}"); - else - Assert.That(parameterValuesRemote[parameter], Is.EqualTo(parameterValuesGenerated[parameter]), $"Tested Parameter {parameter}"); - } - Assert.That(parameterValuesRemote, Has.Count.EqualTo(parameterValuesGenerated.Count)); - }); - } + Assert.That(parameterValuesGenerated.Keys, Contains.Item(parameter), $"Tested Parameter {parameter}"); + if (parameterValuesRemote[parameter] is Array) + Assert.That(parameterValuesRemote[parameter], Is.EquivalentTo((Array)parameterValuesGenerated[parameter]), $"Tested Parameter {parameter}"); + else + Assert.That(parameterValuesRemote[parameter], Is.EqualTo(parameterValuesGenerated[parameter]), $"Tested Parameter {parameter}"); + } + Assert.That(parameterValuesRemote, Has.Count.EqualTo(parameterValuesGenerated.Count)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs index 2433e972..5dc2e993 100644 --- a/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs +++ b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs @@ -5,252 +5,250 @@ using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; using System.Text.Json; -using System.Text.Json.Nodes; -namespace RDMSharpTests.Metadata.JSON +namespace RDMSharpTests.Metadata.JSON; + +[TestFixtureSource(typeof(MetadataJSONObjectDefineTestSubject), nameof(MetadataJSONObjectDefineTestSubject.TestSubjects))] +public class MetadataJSONObjectDefineTests { - [TestFixtureSource(typeof(MetadataJSONObjectDefineTestSubject), nameof(MetadataJSONObjectDefineTestSubject.TestSubjects))] - public class MetadataJSONObjectDefineTests - { - private readonly MetadataJSONObjectDefineTestSubject testSubject; + private readonly MetadataJSONObjectDefineTestSubject testSubject; - public MetadataJSONObjectDefineTests(MetadataJSONObjectDefineTestSubject _TestSubject) - { - testSubject = _TestSubject; - } + public MetadataJSONObjectDefineTests(MetadataJSONObjectDefineTestSubject _TestSubject) + { + testSubject = _TestSubject; + } - [Test] - public void TestValidateAgainstSchema() - { - JsonSchema jsonSchema = JsonSchema.FromText(testSubject.Schema.Content); - var result = jsonSchema.Evaluate(JsonNode.Parse(testSubject.Define.Content)); - Assert.That(result, Is.Not.Null); - if (!testSubject.Define.Name.ToLower().Contains("invalid")) - Assert.That(result.IsValid, Is.True); - else if (testSubject.Define.Name.ToLower().Contains("invalid_but_schema_is_valid")) - Assert.That(result.IsValid, Is.True); - else - Assert.That(result.IsValid, Is.False); - } - [Test] - public void TestDeseriaizeAndSerialize() + [Test] + public void TestValidateAgainstSchema() + { + JsonSchema jsonSchema = JsonSchema.FromText(testSubject.Schema.Content); + var result = jsonSchema.Evaluate(JsonDocument.Parse(testSubject.Define.Content).RootElement); + Assert.That(result, Is.Not.Null); + if (!testSubject.Define.Name.ToLower().Contains("invalid")) + Assert.That(result.IsValid, Is.True); + else if (testSubject.Define.Name.ToLower().Contains("invalid_but_schema_is_valid")) + Assert.That(result.IsValid, Is.True); + else + Assert.That(result.IsValid, Is.False); + } + [Test] + public void TestDeseriaizeAndSerialize() + { + try { - try - { - MetadataJSONObjectDefine? deserialized = JsonSerializer.Deserialize(testSubject.Define.Content); - Assert.That(deserialized, Is.Not.Null); - Assert.That(deserialized!.Version, Is.AtLeast(1)); - Assert.That(deserialized.Name, Is.Not.WhiteSpace); - Assert.That(deserialized.Name, Is.Not.Empty); - string serialized = JsonSerializer.Serialize(deserialized); + MetadataJSONObjectDefine? deserialized = JsonSerializer.Deserialize(testSubject.Define.Content); + Assert.That(deserialized, Is.Not.Null); + Assert.That(deserialized!.Version, Is.AtLeast(1)); + Assert.That(deserialized.Name, Is.Not.WhiteSpace); + Assert.That(deserialized.Name, Is.Not.Empty); + string serialized = JsonSerializer.Serialize(deserialized); - var original = JToken.Parse(PrittyJSON(testSubject.Define.Content)); - var smashed = JToken.Parse(PrittyJSON(serialized)); + var original = JToken.Parse(PrittyJSON(testSubject.Define.Content)); + var smashed = JToken.Parse(PrittyJSON(serialized)); - Assert.Multiple(() => - { - Assert.That(JToken.DeepEquals(smashed, original)); + Assert.Multiple(() => + { + Assert.That(JToken.DeepEquals(smashed, original)); - Warn.Unless(PrittyJSON(serialized), Is.EqualTo(PrittyJSON(testSubject.Define.Content))); - }); - } - catch (JsonException ex) - { - if (testSubject.Define.Name.ToLower().Contains("invalid")) - return; + Warn.Unless(PrittyJSON(serialized), Is.EqualTo(PrittyJSON(testSubject.Define.Content))); + }); + } + catch (JsonException ex) + { + if (testSubject.Define.Name.ToLower().Contains("invalid")) + return; #if !NET7_0_OR_GREATER - Warn.If(ex.Message, Is.EqualTo("Unexpected JSON format Type: int128 for FieldContainer.").Or.EqualTo("Unexpected JSON format Type: uint128 for FieldContainer."), "Due to .NET6 limitations"); - return; + Warn.If(ex.Message, Is.EqualTo("Unexpected JSON format Type: int128 for FieldContainer.").Or.EqualTo("Unexpected JSON format Type: uint128 for FieldContainer."), "Due to .NET6 limitations"); + return; #else #pragma warning disable CA2200 - throw ex; + throw ex; #pragma warning restore CA2200 #endif - } } - [Test] - public void TestDeserializedObject() + } + [Test] + public void TestDeserializedObject() + { + MetadataJSONObjectDefine? deserialized = null; + testString(testSubject.Define.ToString()); + try { - MetadataJSONObjectDefine? deserialized = null; - testString(testSubject.Define.ToString()); - try - { - deserialized = JsonSerializer.Deserialize(testSubject.Define.Content); - } - catch (JsonException ex) - { - if (testSubject.Define.Name.ToLower().Contains("invalid")) - return; -#if !NET7_0_OR_GREATER - Warn.If(ex.Message, Is.EqualTo("Unexpected JSON format Type: int128 for FieldContainer.").Or.EqualTo("Unexpected JSON format Type: uint128 for FieldContainer."), "Due to .NET6 limitations"); + deserialized = JsonSerializer.Deserialize(testSubject.Define.Content); + } + catch (JsonException ex) + { + if (testSubject.Define.Name.ToLower().Contains("invalid")) return; +#if !NET7_0_OR_GREATER + Warn.If(ex.Message, Is.EqualTo("Unexpected JSON format Type: int128 for FieldContainer.").Or.EqualTo("Unexpected JSON format Type: uint128 for FieldContainer."), "Due to .NET6 limitations"); + return; #else #pragma warning disable CA2200 - throw ex; + throw ex; #pragma warning restore CA2200 #endif - } - Assert.That(deserialized, Is.Not.Null); - Assert.That(deserialized.Version, Is.AtLeast(1)); - Assert.That(deserialized.Name, Is.Not.WhiteSpace); - Assert.That(deserialized.Name, Is.Not.Empty); + } + Assert.That(deserialized, Is.Not.Null); + Assert.That(deserialized.Version, Is.AtLeast(1)); + Assert.That(deserialized.Name, Is.Not.WhiteSpace); + Assert.That(deserialized.Name, Is.Not.Empty); - testString(deserialized.ToString()); + testString(deserialized.ToString()); - if (deserialized.GetRequestSubdeviceRange != null) - { - testString(string.Join("; ", deserialized.GetRequestSubdeviceRange.Select(r => r.ToString()))!); - } - if (deserialized.GetResponseSubdeviceRange != null) - { - testString(string.Join("; ", deserialized.GetResponseSubdeviceRange.Select(r => r.ToString()))!); - } - if (deserialized.SetRequestsSubdeviceRange != null) - { - testString(string.Join("; ", deserialized.SetRequestsSubdeviceRange.Select(r => r.ToString()))!); - } - if (deserialized.SetResponseSubdeviceRange != null) - { - testString(string.Join("; ", deserialized.SetResponseSubdeviceRange.Select(r => r.ToString()))!); - } + if (deserialized.GetRequestSubdeviceRange != null) + { + testString(string.Join("; ", deserialized.GetRequestSubdeviceRange.Select(r => r.ToString()))!); + } + if (deserialized.GetResponseSubdeviceRange != null) + { + testString(string.Join("; ", deserialized.GetResponseSubdeviceRange.Select(r => r.ToString()))!); + } + if (deserialized.SetRequestsSubdeviceRange != null) + { + testString(string.Join("; ", deserialized.SetRequestsSubdeviceRange.Select(r => r.ToString()))!); + } + if (deserialized.SetResponseSubdeviceRange != null) + { + testString(string.Join("; ", deserialized.SetResponseSubdeviceRange.Select(r => r.ToString()))!); + } - if (deserialized.GetRequest != null) - { - testCommand(deserialized.GetRequest.Value); - deserialized.GetCommand(Command.ECommandDublicate.GetRequest, out Command? command); - if (command != null) - testCommand(command.Value); - } + if (deserialized.GetRequest != null) + { + testCommand(deserialized.GetRequest.Value); + deserialized.GetCommand(Command.ECommandDublicate.GetRequest, out Command? command); + if (command != null) + testCommand(command.Value); + } - if (deserialized.GetResponse != null) - { - testCommand(deserialized.GetResponse.Value); - deserialized.GetCommand(Command.ECommandDublicate.GetResponse, out Command? command); - if (command != null) - testCommand(command.Value); - } + if (deserialized.GetResponse != null) + { + testCommand(deserialized.GetResponse.Value); + deserialized.GetCommand(Command.ECommandDublicate.GetResponse, out Command? command); + if (command != null) + testCommand(command.Value); + } - if (deserialized.SetRequest != null) - { - testCommand(deserialized.SetRequest.Value); - deserialized.GetCommand(Command.ECommandDublicate.SetRequest, out Command? command); - if (command != null) - testCommand(command.Value); - } + if (deserialized.SetRequest != null) + { + testCommand(deserialized.SetRequest.Value); + deserialized.GetCommand(Command.ECommandDublicate.SetRequest, out Command? command); + if (command != null) + testCommand(command.Value); + } - if (deserialized.SetResponse != null) + if (deserialized.SetResponse != null) + { + testCommand(deserialized.SetResponse.Value); + deserialized.GetCommand(Command.ECommandDublicate.SetResponse, out Command? command); + if (command != null) + testCommand(command.Value); + } + + + static void testString(string str) + { + Assert.That(str, Is.Not.WhiteSpace); + Assert.That(str, Is.Not.Empty); + Assert.That(str, Does.Not.Contain("{")); + Assert.That(str, Does.Not.Contain("}")); + } + static void testCommand(Command command) + { + testString(command.ToString()!); + PDL? pdl = null; + if (command.EnumValue is Command.ECommandDublicate _enum) { - testCommand(deserialized.SetResponse.Value); - deserialized.GetCommand(Command.ECommandDublicate.SetResponse, out Command? command); - if (command != null) - testCommand(command.Value); + Assert.That(command.GetIsEmpty(), Is.False); + testString(_enum.ToString()!); + return; } + Assert.DoesNotThrow(() => { pdl = command.GetDataLength(); }); + Assert.That(pdl.HasValue, Is.True); - static void testString(string str) + if (command.SingleField is OneOfTypes singleField) { - Assert.That(str, Is.Not.WhiteSpace); - Assert.That(str, Is.Not.Empty); - Assert.That(str, Does.Not.Contain("{")); - Assert.That(str, Does.Not.Contain("}")); + Assert.That(command.GetIsEmpty(), Is.False); + testString(singleField.ToString()!); + if (singleField.ObjectType is CommonPropertiesForNamed common) + testCommon(common); + else if (singleField.ReferenceType is ReferenceType reference) + testReference(reference); + return; } - static void testCommand(Command command) + else if (command.ListOfFields is OneOfTypes[] listOfFields) { - testString(command.ToString()!); - PDL? pdl = null; - if (command.EnumValue is Command.ECommandDublicate _enum) - { - Assert.That(command.GetIsEmpty(), Is.False); - testString(_enum.ToString()!); - return; - } - - Assert.DoesNotThrow(() => { pdl = command.GetDataLength(); }); - Assert.That(pdl.HasValue, Is.True); - - if (command.SingleField is OneOfTypes singleField) + if (listOfFields.Length != 0) { Assert.That(command.GetIsEmpty(), Is.False); - testString(singleField.ToString()!); - if (singleField.ObjectType is CommonPropertiesForNamed common) - testCommon(common); - else if (singleField.ReferenceType is ReferenceType reference) - testReference(reference); - return; - } - else if (command.ListOfFields is OneOfTypes[] listOfFields) - { - if (listOfFields.Length != 0) + testString(string.Join("; ", listOfFields.Select(r => r.ToString()))!); + foreach (var field in listOfFields) { - Assert.That(command.GetIsEmpty(), Is.False); - testString(string.Join("; ", listOfFields.Select(r => r.ToString()))!); - foreach (var field in listOfFields) - { - if (field.ObjectType is CommonPropertiesForNamed common) - testCommon(common); - else if (field.ReferenceType is ReferenceType reference) - testReference(reference); - } - return; + if (field.ObjectType is CommonPropertiesForNamed common) + testCommon(common); + else if (field.ReferenceType is ReferenceType reference) + testReference(reference); } + return; } - Assert.That(command.GetIsEmpty(), Is.True); } - static void testCommon(CommonPropertiesForNamed common) - { - testString(common.ToString()!); - if (common is IntegerType integerByte) - testIntegerType(integerByte); - else if (common is IntegerType integerSByte) - testIntegerType(integerSByte); - else if (common is IntegerType integerShort) - testIntegerType(integerShort); - else if (common is IntegerType integerUShort) - testIntegerType(integerUShort); - else if (common is IntegerType integerInt) - testIntegerType(integerInt); - else if (common is IntegerType integerUInt) - testIntegerType(integerUInt); - else if (common is IntegerType integerLong) - testIntegerType(integerLong); - else if (common is IntegerType integerULong) - testIntegerType(integerULong); + Assert.That(command.GetIsEmpty(), Is.True); + } + static void testCommon(CommonPropertiesForNamed common) + { + testString(common.ToString()!); + if (common is IntegerType integerByte) + testIntegerType(integerByte); + else if (common is IntegerType integerSByte) + testIntegerType(integerSByte); + else if (common is IntegerType integerShort) + testIntegerType(integerShort); + else if (common is IntegerType integerUShort) + testIntegerType(integerUShort); + else if (common is IntegerType integerInt) + testIntegerType(integerInt); + else if (common is IntegerType integerUInt) + testIntegerType(integerUInt); + else if (common is IntegerType integerLong) + testIntegerType(integerLong); + else if (common is IntegerType integerULong) + testIntegerType(integerULong); #if NET7_0_OR_GREATER - else if (common is IntegerType integerInt128) - testIntegerType(integerInt128); - else if (common is IntegerType integerUInt128) - testIntegerType(integerUInt128); + else if (common is IntegerType integerInt128) + testIntegerType(integerInt128); + else if (common is IntegerType integerUInt128) + testIntegerType(integerUInt128); #endif - } - static void testReference(ReferenceType reference) - { - testString(reference.ToString()); - Assert.That(reference.Command, Is.EqualTo(Command.ECommandDublicate.GetRequest).Or.EqualTo(Command.ECommandDublicate.GetResponse).Or.EqualTo(Command.ECommandDublicate.SetRequest).Or.EqualTo(Command.ECommandDublicate.SetResponse)); - Assert.That(reference.Pointer, Is.AtLeast(0)); - } - static void testIntegerType(IntegerType integerType) - { - testString(integerType.ToString()!); - if (integerType.Ranges != null) - foreach (Range range in integerType.Ranges) - testString(range.ToString()!); - } } - - private static string PrittyJSON(string jsonString) + static void testReference(ReferenceType reference) { - var jsonObject = JsonSerializer.Deserialize(jsonString); + testString(reference.ToString()); + Assert.That(reference.Command, Is.EqualTo(Command.ECommandDublicate.GetRequest).Or.EqualTo(Command.ECommandDublicate.GetResponse).Or.EqualTo(Command.ECommandDublicate.SetRequest).Or.EqualTo(Command.ECommandDublicate.SetResponse)); + Assert.That(reference.Pointer, Is.AtLeast(0)); + } + static void testIntegerType(IntegerType integerType) + { + testString(integerType.ToString()!); + if (integerType.Ranges != null) + foreach (Range range in integerType.Ranges) + testString(range.ToString()!); + } + } - var options = new JsonSerializerOptions - { - WriteIndented = false, - }; + private static string PrittyJSON(string jsonString) + { + var jsonObject = JsonSerializer.Deserialize(jsonString); - string formattedJson = JsonSerializer.Serialize(jsonObject, options); - return formattedJson; - } + var options = new JsonSerializerOptions + { + WriteIndented = false, + }; + + string formattedJson = JsonSerializer.Serialize(jsonObject, options); + return formattedJson; } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestBytesType.cs b/RDMSharpTests/Metadata/JSON/TestBytesType.cs index d6b2a810..57db6f32 100644 --- a/RDMSharpTests/Metadata/JSON/TestBytesType.cs +++ b/RDMSharpTests/Metadata/JSON/TestBytesType.cs @@ -1,339 +1,389 @@ -using RDMSharp.Metadata; +using RDMSharp.Extensions.BytesParser; +using RDMSharp.Extensions.BytesParser.StringFormats; +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; -namespace RDMSharpTests.Metadata.JSON +namespace RDMSharpTests.Metadata.JSON; + +public class TestBytesType { - public class TestBytesType + [Test] + public void TestMany() { - [Test] - public void TestMany() + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, null, null); + Assert.That(bytesType.MinLength, Is.Null); + Assert.That(bytesType.MaxLength, Is.Null); + + bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 1, null); + Assert.That(bytesType.MinLength, Is.EqualTo(1)); + Assert.That(bytesType.MaxLength, Is.Null); + + Assert.DoesNotThrow(() => { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, null, null); - Assert.That(bytesType.MinLength, Is.Null); - Assert.That(bytesType.MaxLength, Is.Null); + PDL pdl = bytesType.GetDataLength(); + Assert.That(pdl.Value, Is.Null); + Assert.That(pdl.MinLength, Is.EqualTo(1)); + Assert.That(pdl.MaxLength, Is.EqualTo(PDL.MAX_LENGTH)); + }); - bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 1, null); - Assert.That(bytesType.MinLength, Is.EqualTo(1)); - Assert.That(bytesType.MaxLength, Is.Null); + bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 1, 3); + Assert.That(bytesType.MinLength, Is.EqualTo(1)); + Assert.That(bytesType.MaxLength, Is.EqualTo(3)); - Assert.DoesNotThrow(() => - { - PDL pdl = bytesType.GetDataLength(); - Assert.That(pdl.Value, Is.Null); - Assert.That(pdl.MinLength, Is.EqualTo(1)); - Assert.That(pdl.MaxLength, Is.EqualTo(PDL.MAX_LENGTH)); - }); + Assert.DoesNotThrow(() => + { + PDL pdl = bytesType.GetDataLength(); + Assert.That(pdl.Value, Is.Null); + Assert.That(pdl.MinLength, Is.EqualTo(1)); + Assert.That(pdl.MaxLength, Is.EqualTo(3)); + }); - bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 1, 3); - Assert.That(bytesType.MinLength, Is.EqualTo(1)); - Assert.That(bytesType.MaxLength, Is.EqualTo(3)); + Assert.Throws(typeof(ArgumentException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bites", null, 1, 5)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 6, 5)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 4294567890, null)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 2, 4294567890)); + } + [Test] + public void TestParseUID() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "uid", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(6)); + var uid = new UID(0x4646, 0x12345678); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, uid)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 0x46, 0x46, 0x12, 0x34, 0x56, 0x78 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(uid)); - Assert.DoesNotThrow(() => - { - PDL pdl = bytesType.GetDataLength(); - Assert.That(pdl.Value, Is.Null); - Assert.That(pdl.MinLength, Is.EqualTo(1)); - Assert.That(pdl.MaxLength, Is.EqualTo(3)); - }); + byte[] lessBytes = new byte[] { 0 }; + Assert.Throws(typeof(ArgumentException), () => new UIDBytesParser().ParseToObject(ref lessBytes)); + Assert.Throws(typeof(ArgumentException), () => new UIDBytesParser().ParseToData("WrongType")); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "uid", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseUIDArrayEmpty() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "uid[]", null, null); + Assert.That(bytesType.GetDataLength().MinLength, Is.EqualTo(0)); + var uidArray = new UID[0]; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, uidArray)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[0])); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Null); + } + [Test] + public void TestParseUIDArray() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "uid[]", null, null); + Assert.That(bytesType.GetDataLength().MinLength, Is.EqualTo(0)); + var uidArray = new UID[] { new UID(0x4646, 0x12345678), new UID(0x4646, 0x12345678) }; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, uidArray)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 0x46, 0x46, 0x12, 0x34, 0x56, 0x78, 0x46, 0x46, 0x12, 0x34, 0x56, 0x78 })); + var corrupData = new List(); + corrupData.AddRange(data); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.EqualTo(uidArray)); - Assert.Throws(typeof(ArgumentException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bites", null, 1, 5)); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 6, 5)); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 4294567890, null)); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 2, 4294567890)); - } - [Test] - public void TestParseUID() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "uid", null, null); - Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(6)); - var uid = new UID(0x4646, 0x12345678); - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, uid)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 0x46, 0x46, 0x12, 0x34, 0x56, 0x78 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(uid)); + corrupData.Add(1); + corrupData.Add(2); + data = corrupData.ToArray(); + dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(2)); + Assert.That(data, Is.EqualTo(new byte[] { 1, 2 })); + Assert.That(dataTree.Value, Is.EqualTo(uidArray)); + Assert.That(dataTree.Issues, Has.Length.EqualTo(2)); + } - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "uid", null, null).ParsePayloadToData(dataTree)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParseUIDArrayEmpty() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "uid[]", null, null); - Assert.That(bytesType.GetDataLength().MinLength, Is.EqualTo(0)); - var uidArray = new UID[0]; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, uidArray)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[0])); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Null); - } - [Test] - public void TestParseUIDArray() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "uid[]", null, null); - Assert.That(bytesType.GetDataLength().MinLength, Is.EqualTo(0)); - var uidArray = new UID[] { new UID(0x4646, 0x12345678) , new UID(0x4646, 0x12345678) }; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, uidArray)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 0x46, 0x46, 0x12, 0x34, 0x56, 0x78, 0x46, 0x46, 0x12, 0x34, 0x56, 0x78 })); - var corrupData = new List(); - corrupData.AddRange(data); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.EqualTo(uidArray)); + [Test] + public void TestParseIPv4() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv4", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(4)); + var ipv4 = new IPv4Address(192, 168, 178, 254); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, ipv4)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 192, 168, 178, 254 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(ipv4)); - corrupData.Add(1); - corrupData.Add(2); - data= corrupData.ToArray(); - dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(2)); - Assert.That(data, Is.EqualTo(new byte[] { 1, 2 })); - Assert.That(dataTree.Value, Is.EqualTo(uidArray)); - Assert.That(dataTree.Issues, Has.Length.EqualTo(2)); - } + byte[] lessBytes = new byte[] { 0 }; + Assert.Throws(typeof(ArgumentException), () => new IPv4AddressBytesParser().ParseToObject(ref lessBytes)); + Assert.Throws(typeof(ArgumentException), () => new IPv4AddressBytesParser().ParseToData("WrongType")); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv4", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseIPv6() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv6", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(16)); + var ipv6 = IPv6Address.LocalHost; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, ipv6)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(ipv6)); - [Test] - public void TestParseIPv4() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv4", null, null); - Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(4)); - var ipv4 = new IPv4Address(192,168,178,254); - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, ipv4)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 192, 168, 178, 254 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(ipv4)); + byte[] lessBytes = new byte[] { 0 }; + Assert.Throws(typeof(ArgumentException), () => new IPv6AddressBytesParser().ParseToObject(ref lessBytes)); + Assert.Throws(typeof(ArgumentException), () => new IPv6AddressBytesParser().ParseToData("WrongType")); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv6", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseMAC() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "mac-address", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(6)); + var mac = new MACAddress(new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC }); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, mac)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(mac)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv4", null, null).ParsePayloadToData(dataTree)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParseIPv6() + byte[] lessBytes = new byte[] { 0 }; + Assert.Throws(typeof(ArgumentException), () => new MACAddressBytesParser().ParseToObject(ref lessBytes)); + Assert.Throws(typeof(ArgumentException), () => new MACAddressBytesParser().ParseToData("WrongType")); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "mac-address", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseGUID() + { + string[] formates = new string[] { "uuid", "guid" }; + foreach (var formate in formates) { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv6", null, null); + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", formate, null, null); Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(16)); - var ipv6 = IPv6Address.LocalHost; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, ipv6)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(ipv6)); - - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv6", null, null).ParsePayloadToData(dataTree)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParseMAC() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "mac-address", null, null); - Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(6)); - var mac = new MACAddress(new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC }); - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, mac)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC })); + var guid = new Guid(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, guid)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 })); var dataTree = bytesType.ParseDataToPayload(ref data); Assert.That(data, Has.Length.EqualTo(0)); Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(mac)); + Assert.That(dataTree.Value, Is.EqualTo(guid)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "mac-address", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", formate, null, null).ParsePayloadToData(dataTree)); Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); } - [Test] - public void TestParseGUID() - { - string[] formates = new string[] { "uuid", "guid" }; - foreach (var formate in formates) - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", formate, null, null); - Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(16)); - var guid = new Guid(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }); - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, guid)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(guid)); + byte[] lessBytes = new byte[] { 0 }; + Assert.Throws(typeof(ArgumentException), () => new GuidBytesParser().ParseToObject(ref lessBytes)); + Assert.Throws(typeof(ArgumentException), () => new GuidBytesParser().ParseToData("WrongType")); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", formate, null, null).ParsePayloadToData(dataTree)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); - } - } - [Test] - public void TestParseDouble() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "double", null, null); - Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(8)); - var _double = 0.252536d; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, _double)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 142, 2, 68, 193, 140, 41, 208, 63 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(_double)); + Assert.Throws(typeof(ArgumentException), () => new UuidBytesParser().ParseToObject(ref lessBytes)); + Assert.Throws(typeof(ArgumentException), () => new UuidBytesParser().ParseToData("WrongType")); + } + [Test] + public void TestParseDouble() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "double", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(8)); + var _double = 0.252536d; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, _double)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 142, 2, 68, 193, 140, 41, 208, 63 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(_double)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "double", null, null).ParsePayloadToData(dataTree)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParseFloat() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "float", null, null); - Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(4)); - var _float = 0.252536f; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, _float)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 102, 76, 129, 62 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(_float)); + byte[] lessBytes = new byte[] { 0 }; + Assert.Throws(typeof(ArgumentException), () => new DoubleBytesParser().ParseToObject(ref lessBytes)); + Assert.Throws(typeof(ArgumentException), () => new DoubleBytesParser().ParseToData("WrongType")); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "double", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseFloat() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "float", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(4)); + var _float = 0.252536f; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, _float)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 102, 76, 129, 62 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(_float)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "float", null, null).ParsePayloadToData(dataTree)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParsePID() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "pid", null, null); - Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(2)); - var pid = ERDM_Parameter.CURVE; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, pid)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 0x03, 0x043 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(pid)); + byte[] lessBytes = new byte[] { 0 }; + Assert.Throws(typeof(ArgumentException), () => new FloatBytesParser().ParseToObject(ref lessBytes)); + Assert.Throws(typeof(ArgumentException), () => new FloatBytesParser().ParseToData("WrongType")); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "float", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParsePID() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "pid", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(2)); + var pid = ERDM_Parameter.CURVE; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, pid)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 0x03, 0x043 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(pid)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "pid", null, null).ParsePayloadToData(dataTree)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParseASCII() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "ascii", null, null); - var ascii = "This is ASCII"; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, ascii)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 84, 104, 105, 115, 32, 105, 115, 32, 65, 83, 67, 73, 73 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(ascii)); + byte[] lessBytes = new byte[] { 0 }; + Assert.Throws(typeof(ArgumentException), () => new PIDBytesParser().ParseToObject(ref lessBytes)); + Assert.Throws(typeof(ArgumentException), () => new PIDBytesParser().ParseToData("WrongType")); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "pid", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseASCII() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "ascii", null, null); + var ascii = "This is ASCII"; + var pdl = bytesType.GetDataLength(); + Assert.That(pdl, Is.EqualTo(new PDL(1, PDL.MAX_LENGTH))); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, ascii)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 84, 104, 105, 115, 32, 105, 115, 32, 65, 83, 67, 73, 73 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(ascii)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "ascii", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParseUTF8() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "utf8", null, null); - var utf8 = "äöü߀!"; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, utf8)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(utf8)); + Assert.Throws(typeof(ArgumentException), () => new ASCIIBytesParser().ParseToData(0x44)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "ascii", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseUTF8() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "utf8", null, null); + var utf8 = "äöü߀!"; + var pdl = bytesType.GetDataLength(); + Assert.That(pdl, Is.EqualTo(new PDL(1, PDL.MAX_LENGTH))); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, utf8)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(utf8)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "utf8", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParseUTF32() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "utf32", null, null); - var utf32 = "😊🚀🌍💡📚✈️"; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, utf32)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 10, 246, 1, 0, 128, 246, 1, 0, 13, 243, 1, 0, 161, 244, 1, 0, 218, 244, 1, 0, 8, 39, 0, 0, 15, 254, 0, 0 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(utf32)); + Assert.Throws(typeof(ArgumentException), () => new UTF8BytesParser().ParseToData(0x44)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "utf8", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseUTF32() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "utf32", null, null); + var utf32 = "😊🚀🌍💡📚✈️"; + var pdl = bytesType.GetDataLength(); + Assert.That(pdl, Is.EqualTo(new PDL(1, PDL.MAX_LENGTH))); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, utf32)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 10, 246, 1, 0, 128, 246, 1, 0, 13, 243, 1, 0, 161, 244, 1, 0, 218, 244, 1, 0, 8, 39, 0, 0, 15, 254, 0, 0 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(utf32)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "utf32", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParseUnicode() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "unicode", null, null); - var unicode = "ÄÖÜß😊"; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, unicode)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 196, 0, 214, 0, 220, 0, 223, 0, 61, 216, 10, 222 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(unicode)); + Assert.Throws(typeof(ArgumentException), () => new UTF32BytesParser().ParseToData(0x44)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "utf32", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseUnicode() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "unicode", null, null); + var unicode = "ÄÖÜß😊"; + var pdl = bytesType.GetDataLength(); + Assert.That(pdl, Is.EqualTo(new PDL(1, PDL.MAX_LENGTH))); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, unicode)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 196, 0, 214, 0, 220, 0, 223, 0, 61, 216, 10, 222 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(unicode)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "unicode", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParseBigEndianUnicode() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "big_edian_unicode", null, null); - var big_edian_unicode = "ÄÖÜß😊"; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, big_edian_unicode)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 0, 196, 0, 214, 0, 220, 0, 223, 216, 61, 222, 10 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(big_edian_unicode)); + Assert.Throws(typeof(ArgumentException), () => new UnicodeBytesParser().ParseToData(0x44)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "unicode", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseBigEndianUnicode() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "big_edian_unicode", null, null); + var big_edian_unicode = "ÄÖÜß😊"; + var pdl = bytesType.GetDataLength(); + Assert.That(pdl, Is.EqualTo(new PDL(1, PDL.MAX_LENGTH))); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, big_edian_unicode)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 0, 196, 0, 214, 0, 220, 0, 223, 216, 61, 222, 10 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(big_edian_unicode)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "big_edian_unicode", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParseLatin1() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "latin1", null, null); - var latin1 = "Café"; ; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, latin1)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 67, 97, 102, 233 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(latin1)); + Assert.Throws(typeof(ArgumentException), () => new BigEndianUnicodeBytesParser().ParseToData(0x44)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "big_edian_unicode", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseLatin1() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "latin1", null, null); + var latin1 = "Café"; + var pdl = bytesType.GetDataLength(); + Assert.That(pdl, Is.EqualTo(new PDL(1, PDL.MAX_LENGTH))); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, latin1)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 67, 97, 102, 233 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(latin1)); - Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "latin1", null, null).ParsePayloadToData(dataTree)); - } - [Test] - public void TestParseFallbackString() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, null, null); - var utf8 = "äöü߀!"; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, utf8)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - } - [Test] - public void TestParseFallbackUTF8Array() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "utf8[]", null, null); - var utf8 = "äöü߀!"; - var array = new string[] { utf8, utf8 }; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, array)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(new byte[] { 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33, 0, 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33, 0 })); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - } - [Test] - public void TestParseFallbackByteArray() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, null, null); - var bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; - var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, bytes)).SelectMany(en => en).ToArray(); - Assert.That(data, Is.EqualTo(bytes)); - var dataTree = bytesType.ParseDataToPayload(ref data); - Assert.That(data, Has.Length.EqualTo(0)); - Assert.That(dataTree.Value, Is.Not.Null); - Assert.That(dataTree.Value, Is.EqualTo(bytes)); - } - [Test] - public void TestParseFallbackUnknownType() - { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "UNKNOWN", null, null); - Assert.Throws(typeof(ArithmeticException), () => bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, DateTime.Now))); - } + Assert.Throws(typeof(ArgumentException), () => new Latin1BytesParser().ParseToData(0x44)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "latin1", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseFallbackString() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, null, null); + var utf8 = "äöü߀!"; + var pdl = bytesType.GetDataLength(); + Assert.That(pdl, Is.EqualTo(new PDL(1, PDL.MAX_LENGTH))); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, utf8)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 63, 63, 63, 63, 63, 33 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + } + [Test] + public void TestParseFallbackUTF8Array() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "utf8[]", null, null); + var utf8 = "äöü߀!"; + var pdl = bytesType.GetDataLength(); + Assert.That(pdl, Is.EqualTo(new PDL(1, PDL.MAX_LENGTH))); + var array = new string[] { utf8, utf8 }; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, array)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(new byte[] { 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33, 0, 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33, 0 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + } + [Test] + public void TestParseFallbackByteArray() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, null, null); + var bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, bytes)).SelectMany(en => en).ToArray(); + Assert.That(data, Is.EqualTo(bytes)); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(bytes)); + } + [Test] + public void TestParseFallbackUnknownType() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "UNKNOWN", null, null); + Assert.Throws(typeof(ArithmeticException), () => bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, DateTime.Now))); } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/Parser/PayloadToParsedObjectTestSubject.cs b/RDMSharpTests/Metadata/Parser/PayloadToParsedObjectTestSubject.cs new file mode 100644 index 00000000..a5789813 --- /dev/null +++ b/RDMSharpTests/Metadata/Parser/PayloadToParsedObjectTestSubject.cs @@ -0,0 +1,3323 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.Metadata.Parser; + +public class PayloadToParsedObjectTestSubject +{ + public static readonly object[] TestSubjects = getTestSubjects(); + + private static object[] getTestSubjects() + { + List instances = new List(); + + MetadataFactory.AwaitInitialize().GetAwaiter().GetResult(); + var payloadList = getPayloadList(); + foreach (ERDM_Parameter parameter in Enum.GetValues(typeof(ERDM_Parameter))) + { + try + { + switch (parameter) + { + case ERDM_Parameter.NONE: + case ERDM_Parameter.DISC_UNIQUE_BRANCH: + case ERDM_Parameter.DISC_MUTE: + case ERDM_Parameter.DISC_UN_MUTE: + continue; + } + MetadataJSONObjectDefine define = MetadataFactory.GetDefine(new ParameterBag(parameter)); + foreach (PayloadToParseBagData payloadToParseBagData in payloadList.Where(ppbd => ppbd.Parameter == parameter)) + instances.Add(new PayloadToParsedObjectTestSubject(define, payloadToParseBagData)); + } + catch (Exception ex) + { + Console.WriteLine($"Error processing parameter {parameter}: {ex.Message}"); + } + } + return instances.ToArray(); + } + + private static IEnumerable getPayloadList() + { + List list = new List(); + + #region PROXIED_DEVICES + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PROXIED_DEVICES, + new byte[] { 0x53, 0x47, 0x94, 0x71, 0xaf, 0x2f }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMProxiedDevices))); + + var obj = dataTreeBranch.ParsedObject as RDMProxiedDevices; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Devices, Is.Not.Null); + Assert.That(obj.Devices.Length, Is.EqualTo(1)); + Assert.That(obj.Devices[0], Is.EqualTo(new UID(0x5347, 0x9471af2f))); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PROXIED_DEVICES, + new byte[] { + 0x53, 0x47, 0x94, 0x71, 0xaf, 0x2f, + 0x53, 0x47, 0x94, 0x03, 0x02, 0x01 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMProxiedDevices))); + + var obj = dataTreeBranch.ParsedObject as RDMProxiedDevices; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Devices, Is.Not.Null); + Assert.That(obj.Devices.Length, Is.EqualTo(2)); + Assert.That(obj.Devices[0], Is.EqualTo(new UID(0x5347, 0x9471af2f))); + Assert.That(obj.Devices[1], Is.EqualTo(new UID(0x5347, 0x94030201))); + })); + #endregion + + #region PROXIED_DEVICES_COUNT + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PROXIED_DEVICES_COUNT, + new byte[] { 0x00, 0x05, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMProxiedDeviceCount))); + var obj = dataTreeBranch.ParsedObject as RDMProxiedDeviceCount; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.DeviceCount, Is.EqualTo(5)); + Assert.That(obj.ListChange, Is.EqualTo(true)); + })); + #endregion + + #region COMMS_STATUS + #endregion + + #region QUEUED_MESSAGE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.QUEUED_MESSAGE, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_Status))); + + var obj = (ERDM_Status)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_Status.GET_LAST_MESSAGE)); + })); + #endregion + + #region STATUS_MESSAGES + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.STATUS_MESSAGES, + new byte[] { 0x02 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_Status))); + + var obj = (ERDM_Status)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_Status.ADVISORY)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.STATUS_MESSAGES, + new RDMStatusMessage(0, ERDM_Status.ERROR, ERDM_StatusMessage.UNDERCURRENT, 2, 20).ToPayloadData(), + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMStatusMessage[]))); + var obj = dataTreeBranch.ParsedObject as RDMStatusMessage[]; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Length, Is.EqualTo(1)); + Assert.That(obj[0].SubDeviceId, Is.EqualTo(0)); + Assert.That(obj[0].EStatusType, Is.EqualTo(ERDM_Status.ERROR)); + Assert.That(obj[0].EStatusMessage, Is.EqualTo(ERDM_StatusMessage.UNDERCURRENT)); + Assert.That(obj[0].DataValue1, Is.EqualTo(2)); + Assert.That(obj[0].DataValue2, Is.EqualTo(20)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.STATUS_MESSAGES, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMStatusMessage[]))); + })); + #endregion + + #region STATUS_ID_DESCRIPTION + #endregion + + #region CLEAR_STATUS_ID + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.CLEAR_STATUS_ID, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND_RESPONSE, + ERDM_Parameter.CLEAR_STATUS_ID, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + #endregion + + #region SUB_DEVICE_STATUS_REPORT_THRESHOLD + #endregion + + #region QUEDUED_MESSAGE_SENSOR_SUBSCRIBE + #endregion + + #region SUPPORTED_PARAMETERS + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.SUPPORTED_PARAMETERS, + new byte[] { 0x00, 0x60, 0x00, 0xE0 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_Parameter[]))); + var obj = dataTreeBranch.ParsedObject as ERDM_Parameter[]; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Length, Is.EqualTo(2)); + Assert.That(obj[0], Is.EqualTo(ERDM_Parameter.DEVICE_INFO)); + Assert.That(obj[1], Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY)); + })); + #endregion + + #region PARAMETER_DESCRIPTION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PARAMETER_DESCRIPTION, + new byte[] { + 0xa0, 0x51, 0x02, 0x05, 0x01, 0x7f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x20, 0x4c, + 0x45, 0x44, 0x73, 0x20, 0x68, 0x6f, 0x75, 0x72, + 0x73 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMParameterDescription))); + + var obj = dataTreeBranch.ParsedObject as RDMParameterDescription; + Assert.That(obj, Is.Not.Null); + Assert.That(obj.ParameterId, Is.EqualTo(0xa051)); + Assert.That(obj.PDLSize, Is.EqualTo(0x02)); + Assert.That(obj.DataType, Is.EqualTo(ERDM_DataType.UINT16)); + Assert.That(obj.CommandClass, Is.EqualTo(ERDM_CommandClass.GET)); + Assert.That(obj.Type, Is.EqualTo(127)); + Assert.That(obj.Unit, Is.EqualTo(ERDM_SensorUnit.NONE)); + Assert.That(obj.Prefix, Is.EqualTo(ERDM_UnitPrefix.NONE)); + Assert.That(obj.MinValidValue, Is.EqualTo(0)); + Assert.That(obj.MaxValidValue, Is.EqualTo(255)); + Assert.That(obj.DefaultValue, Is.EqualTo(0)); + Assert.That(obj.Description, Is.EqualTo("TE LEDs hours")); + })); + #endregion + + #region SUPPORTED_PARAMETERS_ENHANCED + #endregion + + #region CONTROLLER_FLAG_SUPPORT + #endregion + + #region NACK_DESCRIPTION + #endregion + + #region PACKED_PID_SUB + #endregion + + #region PACKED_PID_INDEX + #endregion + + #region ENUM_LABLE + #endregion + + #region DEVICE_INFO + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DEVICE_INFO, + new byte[] { + 0x01, 0x00, 0x00, 0x05, 0x06, 0x01, 0x02, 0x00, + 0x01, 0x01, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, + 0x00, 0x04, 0x00 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDeviceInfo))); + + var obj = dataTreeBranch.ParsedObject as RDMDeviceInfo; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.RdmProtocolVersionMajor, Is.EqualTo(1)); + Assert.That(obj.RdmProtocolVersionMinor, Is.EqualTo(0)); + Assert.That(obj.DeviceModelId, Is.EqualTo(0x0005)); + Assert.That(obj.ProductCategoryCoarse, Is.EqualTo(ERDM_ProductCategoryCoarse.POWER)); + Assert.That(obj.ProductCategoryFine, Is.EqualTo(ERDM_ProductCategoryFine.POWER_CONTROL)); + Assert.That(obj.SoftwareVersionId, Is.EqualTo(0x02000101)); + Assert.That(obj.Dmx512Footprint, Is.EqualTo(1)); + Assert.That(obj.Dmx512CurrentPersonality, Is.EqualTo(1)); + Assert.That(obj.Dmx512NumberOfPersonalities, Is.EqualTo(3)); + Assert.That(obj.Dmx512StartAddress, Is.EqualTo(1)); + Assert.That(obj.SubDeviceCount, Is.EqualTo(4)); + Assert.That(obj.SensorCount, Is.EqualTo(0)); + })); + #endregion + + #region PRODUCT_DETAIL_ID_LIST + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PRODUCT_DETAIL_ID_LIST, + new byte[] { 0x00, 0x01, 0x00, 0x02 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_ProductDetail[]))); + + var obj = (ERDM_ProductDetail[])dataTreeBranch.ParsedObject; + Assert.That(obj.Length, Is.EqualTo(2)); + Assert.That(obj[0], Is.EqualTo(ERDM_ProductDetail.ARC)); + Assert.That(obj[1], Is.EqualTo(ERDM_ProductDetail.METAL_HALIDE)); + })); + #endregion + + #region DEVICE_MODEL_DESCRIPTION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DEVICE_MODEL_DESCRIPTION, + new byte[] { 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x45 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + + var obj = (string)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo("SEQUENCE")); + })); + #endregion + + #region MANUFACTURER_LABEL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.MANUFACTURER_LABEL, + new byte[] { 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x45 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + + var obj = (string)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo("SEQUENCE")); + })); + #endregion + + #region DEVICE_LABEL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DEVICE_LABEL, + new byte[] { 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x45 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + + var obj = (string)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo("SEQUENCE")); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.DEVICE_LABEL, + new byte[] { 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x45 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + var obj = (string)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo("SEQUENCE")); + })); + #endregion + + #region FACTORY_DEFAULTS + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.FACTORY_DEFAULTS, + new byte[] { 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(bool))); + + var obj = (bool)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(false)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.FACTORY_DEFAULTS, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + #endregion + + #region LANGUAGE_CAPABILITIES + #endregion + + #region LANGUAGE + #endregion + + #region SOFTWARE_VERSION_LABEL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.SOFTWARE_VERSION_LABEL, + new byte[] { 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x45 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + + var obj = (string)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo("SEQUENCE")); + })); + #endregion + + #region BOOT_SOFTWARE_VERSION_ID + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID, + new byte[] { 0x01, 0x02, 0x03, 0x04 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + + var obj = (uint)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(0x01020304)); + })); + #endregion + + #region BOOT_SOFTWARE_VERSION_LABEL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL, + new byte[] { 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x45 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + + var obj = (string)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo("SEQUENCE")); + })); + #endregion + + #region DMX_PERSONALITY + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DMX_PERSONALITY, + new byte[] { 0x01, 0x03 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDMXPersonality))); + + var obj = dataTreeBranch.ParsedObject as RDMDMXPersonality; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.CurrentPersonality, Is.EqualTo(1)); + Assert.That(obj.OfPersonalities, Is.EqualTo(3)); + })); + #endregion + + #region DMX_PERSONALITY_DESCRIPTION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, + new byte[] { + 0x01, 0x00, 0x01, 0x53, 0x45, 0x51, 0x55, 0x45, + 0x4e, 0x43, 0x45 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDMXPersonalityDescription))); + + var obj = dataTreeBranch.ParsedObject as RDMDMXPersonalityDescription; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.PersonalityId, Is.EqualTo(1)); + Assert.That(obj.Slots, Is.EqualTo(1)); + Assert.That(obj.Description, Is.EqualTo("SEQUENCE")); + })); + #endregion + + #region DMX_START_ADDRESS + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DMX_START_ADDRESS, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = (ushort)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(1)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.DMX_START_ADDRESS, + new byte[] { 0x00, 0x03 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = (ushort)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(3)); + })); + #endregion + + #region SLOT_INFO + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.SLOT_INFO, + new byte[] { + 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x01, 0x00, 0x04, 0x04, + 0x00, 0x02, 0x00, 0x02, 0x05, + 0x00, 0x03, 0x00, 0x02, 0x06, + 0x00, 0x04, 0x00, 0x02, 0x07 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSlotInfo[]))); + + var obj = dataTreeBranch.ParsedObject as RDMSlotInfo[]; + Assert.That(obj, Is.Not.Null); + Assert.That(obj![0].SlotOffset, Is.EqualTo(0)); + Assert.That(obj[0].SlotType, Is.EqualTo(ERDM_SlotType.PRIMARY)); + Assert.That(obj[0].SlotLabelId, Is.EqualTo(ERDM_SlotCategory.INTENSITY)); + + Assert.That(obj[1].SlotOffset, Is.EqualTo(1)); + Assert.That(obj[1].SlotType, Is.EqualTo(ERDM_SlotType.PRIMARY)); + Assert.That(obj[1].SlotLabelId, Is.EqualTo(ERDM_SlotCategory.STROBE)); + + Assert.That(obj[2].SlotOffset, Is.EqualTo(2)); + Assert.That(obj[2].SlotType, Is.EqualTo(ERDM_SlotType.PRIMARY)); + Assert.That(obj[2].SlotLabelId, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_RED)); + + Assert.That(obj[3].SlotOffset, Is.EqualTo(3)); + Assert.That(obj[3].SlotType, Is.EqualTo(ERDM_SlotType.PRIMARY)); + Assert.That(obj[3].SlotLabelId, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_GREEN)); + + Assert.That(obj[4].SlotOffset, Is.EqualTo(4)); + Assert.That(obj[4].SlotType, Is.EqualTo(ERDM_SlotType.PRIMARY)); + Assert.That(obj[4].SlotLabelId, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_BLUE)); + })); + #endregion + + #region SLOT_DESCRIPTION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.SLOT_DESCRIPTION, + new byte[] { 0x00, 0x00, 0x53, 0x41, 0x46, 0x45, 0x54, 0x59 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSlotDescription))); + + var obj = dataTreeBranch.ParsedObject as RDMSlotDescription; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.SlotId, Is.EqualTo(0)); + Assert.That(obj.Description, Is.EqualTo("SAFETY")); + })); + #endregion + + #region DEFAULT_SLOT_VALUE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DEFAULT_SLOT_VALUE, + new byte[] { + 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x02, + 0x80, 0x00, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x06, 0x0a, 0x00, 0x07, 0x80, + 0x00, 0x08, 0x00, 0x00, 0x09, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x0b, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x11, 0x80, 0x00, 0x12, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x14, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x16, 0x00, 0x00, 0x17, 0x80, + 0x00, 0x18, 0x00, 0x00, 0x19, 0x00, 0x00, 0x1a, + 0x80, 0x00, 0x1b, 0x00, 0x00, 0x1c, 0x00, 0x00, + 0x1d, 0x80, 0x00, 0x1e, 0x00, 0x00, 0x1f, 0x00, + 0x00, 0x20, 0x80, 0x00, 0x21, 0x00, 0x00, 0x22, + 0x80, 0x00, 0x23, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x26, 0x80, 0x00, 0x27, 0x00, + 0x00, 0x28, 0x80, 0x00, 0x29, 0x00, 0x00, 0x2a, + 0x80, 0x00, 0x2b, 0x00, 0x00, 0x2c, 0x80, 0x00, + 0x2d, 0x00, 0x00, 0x2e, 0x80, 0x00, 0x2f, 0x00, + 0x00, 0x30, 0x80, 0x00, 0x31, 0x00, 0x00, 0x32, + 0x80, 0x00, 0x33, 0x20, 0x00, 0x34, 0x00, 0x00, + 0x35, 0x00 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDefaultSlotValue[]))); + var obj = dataTreeBranch.ParsedObject as RDMDefaultSlotValue[]; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Length, Is.EqualTo(54)); + Assert.That(obj[0].SlotOffset, Is.EqualTo(0)); + Assert.That(obj[0].DefaultSlotValue, Is.EqualTo(128)); + Assert.That(obj[1].SlotOffset, Is.EqualTo(1)); + Assert.That(obj[1].DefaultSlotValue, Is.EqualTo(0)); + Assert.That(obj[2].SlotOffset, Is.EqualTo(2)); + Assert.That(obj[2].DefaultSlotValue, Is.EqualTo(128)); + Assert.That(obj[3].SlotOffset, Is.EqualTo(3)); + Assert.That(obj[3].DefaultSlotValue, Is.EqualTo(0)); + Assert.That(obj[4].SlotOffset, Is.EqualTo(4)); + Assert.That(obj[4].DefaultSlotValue, Is.EqualTo(0)); + })); + #endregion + + #region SENDOR_DEFINITION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.SENSOR_DEFINITION, + new byte[] { + 0x01, 0x00, 0x01, 0x00, 0xff, 0xe0, 0x00, 0xde, + 0x00, 0x00, 0x00, 0x64, 0x02, 0x44, 0x72, 0x69, + 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x6d, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSensorDefinition))); + + var obj = (RDMSensorDefinition)dataTreeBranch.ParsedObject; + Assert.That(obj!.SensorId, Is.EqualTo(1)); + Assert.That(obj.Index, Is.EqualTo(1)); + Assert.That(obj.MinIndex, Is.EqualTo(0)); + Assert.That(obj.Type, Is.EqualTo(ERDM_SensorType.TEMPERATURE)); + Assert.That(obj.Unit, Is.EqualTo(ERDM_SensorUnit.CENTIGRADE)); + Assert.That(obj.Prefix, Is.EqualTo(ERDM_UnitPrefix.NONE)); + Assert.That(obj.RangeMinimum, Is.EqualTo(-32)); + Assert.That(obj.RangeMaximum, Is.EqualTo(222)); + Assert.That(obj.NormalMinimum, Is.EqualTo(0)); + Assert.That(obj.NormalMaximum, Is.EqualTo(100)); + Assert.That(obj.RecordedValueSupported, Is.EqualTo(false)); + Assert.That(obj.LowestHighestValueSupported, Is.EqualTo(true)); + Assert.That(obj.Description, Is.EqualTo("Driver Temperature")); + })); + #endregion + + #region SENSOR_VALUE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.SENSOR_VALUE, + new byte[] { + 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x39, 0x00, + 0x00 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSensorValue))); + + var obj = (RDMSensorValue)dataTreeBranch.ParsedObject; + Assert.That(obj!.SensorId, Is.EqualTo(0)); + Assert.That(obj.Index, Is.EqualTo(0)); + Assert.That(obj.MinIndex, Is.EqualTo(0)); + Assert.That(obj.PresentValue, Is.EqualTo(31)); + Assert.That(obj.LowestValue, Is.EqualTo(0)); + Assert.That(obj.HighestValue, Is.EqualTo(57)); + Assert.That(obj.RecordedValue, Is.EqualTo(0)); + })); + #endregion + + #region RECORD_SENSORS + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.RECORD_SENSORS, + new byte[] { 0x05 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(5)); + })); + #endregion + + #region DEVICE_HOURS + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DEVICE_HOURS, + new byte[] { 0x00, 0x00, 0x00, 0x05 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + var obj = (uint)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(5)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.DEVICE_HOURS, + new byte[] { 0x00, 0x00, 0x00, 0x05 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + var obj = (uint)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(5)); + })); + #endregion + + #region LAMP_HOURS + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.LAMP_HOURS, + new byte[] { 0x00, 0x00, 0x00, 0x05 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + var obj = (uint)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(5)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.LAMP_HOURS, + new byte[] { 0x00, 0x00, 0x00, 0x05 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + var obj = (uint)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(5)); + })); + #endregion + + #region LAMP_STRIKES + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.LAMP_STRIKES, + new byte[] { 0x00, 0x00, 0x00, 0x05 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + var obj = (uint)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(5)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.LAMP_STRIKES, + new byte[] { 0x00, 0x00, 0x00, 0x05 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + var obj = (uint)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(5)); + })); + #endregion + + #region LAMP_STATE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.LAMP_STATE, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_LampState))); + var obj = (ERDM_LampState)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_LampState.ON)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.LAMP_STATE, + new byte[] { 0x02 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_LampState))); + var obj = (ERDM_LampState)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_LampState.STRIKE)); + })); + #endregion + + #region LAMP_ON_MODE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.LAMP_ON_MODE, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_LampMode))); + + var obj = (ERDM_LampMode)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_LampMode.ON_MODE_DMX)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.LAMP_ON_MODE, + new byte[] { 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_LampMode))); + var obj = (ERDM_LampMode)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_LampMode.ON_MODE_OFF)); + })); + #endregion + + #region DEVICE_POWER_CYCLES + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DEVICE_POWER_CYCLES, + new byte[] { 0x00, 0x00, 0x00, 0x05 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + var obj = (uint)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(5)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.DEVICE_POWER_CYCLES, + new byte[] { 0x00, 0x00, 0x00, 0x05 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + var obj = (uint)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(5)); + })); + #endregion + + #region DISPLAY_INVERT + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DISPLAY_INVERT, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_DisplayInvert))); + + var obj = (ERDM_DisplayInvert)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_DisplayInvert.ON)); + })); + #endregion + + #region DISPLAY_LEVEL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DISPLAY_LEVEL, + new byte[] { 0x7f }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(0x7f)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.DISPLAY_LEVEL, + new byte[] { 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(0x00)); + })); + #endregion + + #region PAN_INVERT + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PAN_INVERT, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(bool))); + var obj = (bool)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(true)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.PAN_INVERT, + new byte[] { 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(bool))); + var obj = (bool)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(false)); + })); + #endregion + + #region TILT_INVERT + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.TILT_INVERT, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(bool))); + var obj = (bool)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(true)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.TILT_INVERT, + new byte[] { 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(bool))); + var obj = (bool)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(false)); + })); + #endregion + + #region PAN_TILT_SWAP + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PAN_TILT_SWAP, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(bool))); + var obj = (bool)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(true)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.PAN_TILT_SWAP, + new byte[] { 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(bool))); + var obj = (bool)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(false)); + })); + #endregion + + #region REAL_TIME_CLOCK + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.REAL_TIME_CLOCK, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.REAL_TIME_CLOCK, + new byte[] { 0x07, 0xea, 0x01, 0x0e, 0x0f, 0x2f, 0x07 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMRealTimeClock))); + + var obj = (RDMRealTimeClock)dataTreeBranch.ParsedObject; + Assert.That(obj!.Year, Is.EqualTo(2026)); + Assert.That(obj.Month, Is.EqualTo(1)); + Assert.That(obj.Day, Is.EqualTo(14)); + Assert.That(obj.Hour, Is.EqualTo(15)); + Assert.That(obj.Minute, Is.EqualTo(47)); + Assert.That(obj.Second, Is.EqualTo(7)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.REAL_TIME_CLOCK, + new byte[] { 0x07, 0xea, 0x01, 0x0e, 0x0f, 0x2f, 0x07 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMRealTimeClock))); + + var obj = (RDMRealTimeClock)dataTreeBranch.ParsedObject; + Assert.That(obj!.Year, Is.EqualTo(2026)); + Assert.That(obj.Month, Is.EqualTo(1)); + Assert.That(obj.Day, Is.EqualTo(14)); + Assert.That(obj.Hour, Is.EqualTo(15)); + Assert.That(obj.Minute, Is.EqualTo(47)); + Assert.That(obj.Second, Is.EqualTo(7)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND_RESPONSE, + ERDM_Parameter.REAL_TIME_CLOCK, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + #endregion + + #region IDENTIFY_DEVICE + #endregion + + #region RESET_DEVICE + #endregion + + #region POWER_STATE + #endregion + + #region PERFORM_SELFTEST + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PERFORM_SELFTEST, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(bool))); + + var obj = (bool)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.True); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.PERFORM_SELFTEST, + new byte[] { 0x03 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(3)); + })); + #endregion + + #region SELF_TEST_DESCRIPTION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.SELF_TEST_DESCRIPTION, + new byte[] { 0x03 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(3)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.SELF_TEST_DESCRIPTION, + new byte[] { 0x03, 0x53, 0x45, 0x4c, 0x46 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSelfTestDescription))); + + var obj = (RDMSelfTestDescription)dataTreeBranch.ParsedObject; + Assert.That(obj.SelfTestRequester, Is.EqualTo(3)); + Assert.That(obj.Description, Is.EqualTo("SELF")); + })); + #endregion + + #region SELFTEST_ENHANCED + #endregion + + #region CAPTURE_PRESET + #endregion + + #region PRESET_PLAYBACK + #endregion + + #region DMX_BLOCK_ADDRESS + #endregion + + #region DMX_FAIL_MODE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DMX_FAIL_MODE, + new byte[] { 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDMX_xxxx_Mode))); + + var obj = dataTreeBranch.ParsedObject as RDMDMX_xxxx_Mode; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Scene, Is.EqualTo(0)); + Assert.That(obj.Delay, Is.EqualTo(0.1).Within(1e-9).Percent); + Assert.That(obj.HoldTime, Is.EqualTo(6553.5).Within(1e-9).Percent); + Assert.That(obj.Level, Is.EqualTo(byte.MaxValue)); + })); + #endregion + + #region DMX_STARTUP_MODE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DMX_STARTUP_MODE, + new byte[] { 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDMX_xxxx_Mode))); + + var obj = dataTreeBranch.ParsedObject as RDMDMX_xxxx_Mode; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Scene, Is.EqualTo(0)); + Assert.That(obj.Delay, Is.EqualTo(0.1).Within(1e-9).Percent); + Assert.That(obj.HoldTime, Is.EqualTo(6553.5).Within(1e-9).Percent); + Assert.That(obj.Level, Is.EqualTo(byte.MaxValue)); + })); + #endregion + + #region DIMMER_INFO + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DIMMER_INFO, + new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x01, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDimmerInfo))); + var obj = (RDMDimmerInfo)dataTreeBranch.ParsedObject; + Assert.That(obj.MinimumLevelLowerLimit, Is.EqualTo(0xffff)); + Assert.That(obj.MinimumLevelUpperLimit, Is.EqualTo(0xffff)); + Assert.That(obj.MaximumLevelLowerLimit, Is.EqualTo(0xffff)); + Assert.That(obj.MaximumLevelUpperLimit, Is.EqualTo(0xffff)); + Assert.That(obj.NumberOfSupportedCurves, Is.EqualTo(3)); + Assert.That(obj.LevelsResolution, Is.EqualTo(1)); + Assert.That(obj.MinimumLevelSplitLevelsSupported, Is.EqualTo(true)); + })); + #endregion + + #region MINIMUM_LEVEL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.MINIMUM_LEVEL, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.MINIMUM_LEVEL, + new byte[] { 0x00, 0x01, 0x00, 0x01, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMMinimumLevel))); + + var obj = (RDMMinimumLevel)dataTreeBranch.ParsedObject; + Assert.That(obj.MinimumLevelIncrease, Is.EqualTo(1)); + Assert.That(obj.MinimumLevelDecrease, Is.EqualTo(1)); + Assert.That(obj.OnBelowMinimum, Is.EqualTo(true)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.MINIMUM_LEVEL, + new byte[] { 0x00, 0x02, 0x00, 0x01, 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMMinimumLevel))); + + var obj = (RDMMinimumLevel)dataTreeBranch.ParsedObject; + Assert.That(obj.MinimumLevelIncrease, Is.EqualTo(2)); + Assert.That(obj.MinimumLevelDecrease, Is.EqualTo(1)); + Assert.That(obj.OnBelowMinimum, Is.EqualTo(false)); + })); + #endregion + + #region MAXIMUM_LEVEL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.MAXIMUM_LEVEL, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.MAXIMUM_LEVEL, + new byte[] { 0x00, 0xff }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = (ushort)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(255)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.MAXIMUM_LEVEL, + new byte[] { 0x00, 0xff }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + var obj = (ushort)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(255)); + })); + #endregion + + #region CURVE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.CURVE, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.CURVE, + new byte[] { 0x01, 0x04 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMCurve))); + + var obj = (RDMCurve)dataTreeBranch.ParsedObject; + Assert.That(obj.CurrentCurveId, Is.EqualTo(1)); + Assert.That(obj.Index, Is.EqualTo(1)); + Assert.That(obj.Curves, Is.EqualTo(4)); + Assert.That(obj.Count, Is.EqualTo(4)); + Assert.That(obj.MinIndex, Is.EqualTo(1)); + Assert.That(obj.IndexType, Is.EqualTo(typeof(byte))); + Assert.That(obj.DescriptorParameter, Is.EqualTo(ERDM_Parameter.CURVE_DESCRIPTION)); + })); + #endregion + + #region CURVE_DESCRIPTION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.CURVE_DESCRIPTION, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.CURVE_DESCRIPTION, + new byte[] { 0x01, 0x4C, 0x69, 0x6E, 0x65, 0x61, 0x72 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMCurveDescription))); + + var obj = (RDMCurveDescription)dataTreeBranch.ParsedObject; + Assert.That(obj.CurveId, Is.EqualTo(1)); + Assert.That(obj.Description, Is.EqualTo("Linear")); + })); + #endregion + + #region OUTPUT_RESPONSE_TIME + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.OUTPUT_RESPONSE_TIME, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.OUTPUT_RESPONSE_TIME, + new byte[] { 0x01, 0x05 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMOutputResponseTime))); + + var obj = (RDMOutputResponseTime)dataTreeBranch.ParsedObject; + Assert.That(obj!.CurrentResponseTimeId, Is.EqualTo(1)); + Assert.That(obj.Index, Is.EqualTo(1)); + Assert.That(obj.ResponseTimes, Is.EqualTo(5)); + Assert.That(obj.Count, Is.EqualTo(5)); + Assert.That(obj.MinIndex, Is.EqualTo(1)); + Assert.That(obj.IndexType, Is.EqualTo(typeof(byte))); + Assert.That(obj.DescriptorParameter, Is.EqualTo(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION)); + })); + #endregion + + #region OUTPUT_RESPONSE_TIME_DESCRIPTION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, + new byte[] { 0x01, 0x46, 0x61, 0x73, 0x74 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMOutputResponseTimeDescription))); + + var obj = (RDMOutputResponseTimeDescription)dataTreeBranch.ParsedObject; + Assert.That(obj.OutputResponseTimeId, Is.EqualTo(1)); + Assert.That(obj.Description, Is.EqualTo("Fast")); + })); + #endregion + + #region MODULATION_FREQUENCY + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.MODULATION_FREQUENCY, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.MODULATION_FREQUENCY, + new byte[] { 0x01, 0x05 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMModulationFrequency))); + + var obj = (RDMModulationFrequency)dataTreeBranch.ParsedObject; + Assert.That(obj.ModulationFrequencyId, Is.EqualTo(1)); + Assert.That(obj.Index, Is.EqualTo(1)); + Assert.That(obj.ModulationFrequencys, Is.EqualTo(5)); + Assert.That(obj.Count, Is.EqualTo(5)); + Assert.That(obj.MinIndex, Is.EqualTo(1)); + Assert.That(obj.IndexType, Is.EqualTo(typeof(byte))); + Assert.That(obj.DescriptorParameter, Is.EqualTo(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION)); + })); + #endregion + + #region MODULATION_FREQUENCY_DESCRIPTION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, + new byte[] { 0x01, 0x00, 0x00, 0x00, 0xFF, 0x46, 0x61, 0x73, 0x74 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMModulationFrequencyDescription))); + + var obj = (RDMModulationFrequencyDescription)dataTreeBranch.ParsedObject; + Assert.That(obj.ModulationFrequencyId, Is.EqualTo(1)); + Assert.That(obj.Frequency, Is.EqualTo(255)); + Assert.That(obj.Description, Is.EqualTo("Fast")); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, + new byte[] { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x46, 0x61, 0x73, 0x74 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMModulationFrequencyDescription))); + + var obj = (RDMModulationFrequencyDescription)dataTreeBranch.ParsedObject; + Assert.That(obj.ModulationFrequencyId, Is.EqualTo(1)); + Assert.That(obj.Frequency, Is.Null); + Assert.That(obj.Description, Is.EqualTo("Fast")); + })); + #endregion + + #region BURN_IN + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.BURN_IN, + new byte[] { 0x09 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(9)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.BURN_IN, + new byte[] { 0xff }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(255)); + })); + #endregion + + #region LOCK_PIN + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.LOCK_PIN, + new byte[] { 0x01, 0x02 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = (ushort)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(258)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.LOCK_PIN, + new byte[] { 0x01, 0x02, 0x03, 0x04 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(SetLockPinRequest))); + + var obj = (SetLockPinRequest)dataTreeBranch.ParsedObject; + Assert.That(obj.NewPinCode, Is.EqualTo(0258)); + Assert.That(obj.CurrentPinCode, Is.EqualTo(0772)); + })); + #endregion + + #region LOCK_STATE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.LOCK_STATE, + new byte[] { 0x01, 0x08 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetLockStateResponse))); + + var obj = (GetLockStateResponse)dataTreeBranch.ParsedObject; + Assert.That(obj.CurrentLockStateId, Is.EqualTo(1)); + Assert.That(obj.Index, Is.EqualTo(1)); + Assert.That(obj.LockStates, Is.EqualTo(8)); + Assert.That(obj.Count, Is.EqualTo(8)); + Assert.That(obj.MinIndex, Is.EqualTo(0)); + Assert.That(obj.IndexType, Is.EqualTo(typeof(byte))); + Assert.That(obj.DescriptorParameter, Is.EqualTo(ERDM_Parameter.LOCK_STATE_DESCRIPTION)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.LOCK_STATE, + new byte[] { 0x01, 0x02, 0x03 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(SetLockStateRequest))); + + var obj = (SetLockStateRequest)dataTreeBranch.ParsedObject; + Assert.That(obj.LockStateId, Is.EqualTo(3)); + Assert.That(obj.PinCode, Is.EqualTo(0258)); + })); + #endregion + + #region LOCK_STATE_DESCRIPTION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.LOCK_STATE_DESCRIPTION, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(1)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.LOCK_STATE_DESCRIPTION, + new byte[] { 0x01, 0x4C, 0x6F, 0x63, 0x6B, 0x65, 0x64 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMLockStateDescription))); + + var obj = (RDMLockStateDescription)dataTreeBranch.ParsedObject; + Assert.That(obj.LockStateId, Is.EqualTo(1)); + Assert.That(obj.Description, Is.EqualTo("Locked")); + })); + #endregion + + #region IDENTIFY_MODE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.IDENTIFY_MODE, + new byte[] { 0xff }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_IdentifyMode))); + + var obj = (ERDM_IdentifyMode)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_IdentifyMode.LOUD)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.IDENTIFY_MODE, + new byte[] { 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_IdentifyMode))); + + var obj = (ERDM_IdentifyMode)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_IdentifyMode.QUIET)); + })); + #endregion + + #region PRESET_INFO + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PRESET_INFO, + new byte[] { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xfe, + 0x00, 0x01, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xfe + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMPresetInfo))); + + var obj = dataTreeBranch.ParsedObject as RDMPresetInfo; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.LevelFieldSupported, Is.EqualTo(true)); + Assert.That(obj!.PresetSequenceSupported, Is.EqualTo(true)); + Assert.That(obj!.SplitTimesSupported, Is.EqualTo(true)); + Assert.That(obj!.DMX512FailInfiniteDelayTimeSupported, Is.EqualTo(true)); + Assert.That(obj!.DMX512FailInfiniteHoldTimeSupported, Is.EqualTo(true)); + Assert.That(obj!.StartupInfiniteHoldTimeSupported, Is.EqualTo(true)); + Assert.That(obj!.MaximumSceneNumber, Is.EqualTo(2)); + Assert.That(obj!.MinimumPresetFadeTimeSupported, Is.EqualTo(6553.5).Within(1e-9).Percent); + Assert.That(obj!.MaximumPresetFadeTimeSupported, Is.EqualTo(6553.5).Within(1e-9).Percent); + Assert.That(obj!.MinimumPresetWaitTimeSupported, Is.EqualTo(6553.5).Within(1e-9).Percent); + Assert.That(obj!.MaximumPresetWaitTimeSupported, Is.EqualTo(6553.5).Within(1e-9).Percent); + Assert.That(obj!.MinimumDMX512FailDelayTimeSupported, Is.EqualTo(0).Within(1e-9).Percent); + Assert.That(obj!.MaximumDMX512FailDelayTimeSupported, Is.EqualTo(6553.4).Within(1e-9).Percent); + Assert.That(obj!.MinimumDMX512FailDelayHoldSupported, Is.EqualTo(0.1).Within(1e-9).Percent); + Assert.That(obj!.MaximumDMX512FailDelayHoldSupported, Is.EqualTo(6553.4).Within(1e-9).Percent); + Assert.That(obj!.MinimumStartupDelayTimeSupported, Is.EqualTo(0.1).Within(1e-9).Percent); + Assert.That(obj!.MaximumStartupDelayTimeSupported, Is.EqualTo(6553.4).Within(1e-9).Percent); + Assert.That(obj!.MinimumStartupDelayHoldSupported, Is.EqualTo(0.1).Within(1e-9).Percent); + Assert.That(obj!.MaximumStartupDelayHoldSupported, Is.EqualTo(6553.4).Within(1e-9).Percent); + })); + #endregion + + #region PRESET_STATUS + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PRESET_STATUS, + new byte[] { + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMPresetStatus))); + + var obj = dataTreeBranch.ParsedObject as RDMPresetStatus; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.SceneId, Is.EqualTo(1)); + Assert.That(obj!.UpFadeTime, Is.EqualTo(0)); + Assert.That(obj!.DownFadeTime, Is.EqualTo(0)); + Assert.That(obj!.WaitTime, Is.EqualTo(0)); + Assert.That(obj!.EProgrammed, Is.EqualTo(ERDM_PresetProgrammed.PROGRAMMED_READ_ONLY)); + })); + #endregion + + #region PRESET_MERGEMODE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PRESET_MERGEMODE, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_MergeMode))); + var obj = (ERDM_MergeMode)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_MergeMode.HTP)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.PRESET_MERGEMODE, + new byte[] { 0x02 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_MergeMode))); + var obj = (ERDM_MergeMode)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_MergeMode.LTP)); + })); + #endregion + + #region POWER_ON_SELF_TEST + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.POWER_ON_SELF_TEST, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(1)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.POWER_ON_SELF_TEST, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + + var obj = (byte)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(1)); + })); + #endregion + + #region LIST_INTERFACES + #endregion + + #region INTERFACE_LABEL + #endregion + + #region INTERFACE_HARDWARE_ADDRESS_TYPE + #endregion + + #region IPV4_DHCP_MODE + #endregion + + #region IPV4_ZEROCONF_MODE + #endregion + + #region IPV4_CURRENT_ADDRESS + #endregion + + #region IPV4_STATIC_ADDRESS + #endregion + + #region INTERFACE_RENEW_DHCP + #endregion + + #region INTERFACE_RELEASE_DHCP + #endregion + + #region INTERFACE_APPLY_CONFIGURATION + #endregion + + #region IPV4_DEFAULT_ROUTE + #endregion + + #region DNS_IPV4_NAME_SERVER + #endregion + + #region DNS_HOSTNAME + #endregion + + #region DNS_DOMAIN_NAME + #endregion + + #region COMPONENT_SCOPE + #endregion + + #region SEARCH_DOMAIN + #endregion + + #region TCP_COMMS_STATUS + #endregion + + #region BROKER_STATUS + #endregion + + #region ENDPOINT_LIST + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_LIST, + new byte[] { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, + 0x03, 0x01, 0x00, 0x04, 0x01, 0x00, 0x05, 0x01, + 0x00, 0x06, 0x01, 0x00, 0x07, 0x01, 0x00, 0x08, + 0x01 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetEndpointListResponse))); + + var obj = dataTreeBranch.ParsedObject as GetEndpointListResponse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Endpoints.Length, Is.EqualTo(7)); + Assert.That(obj.Endpoints, Is.Not.Null); + })); + #endregion + + #region ENDPOINT_LIST_CHANGE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_LIST_CHANGE, + new byte[] { 0x00, 0x00, 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + + var obj = dataTreeBranch.ParsedObject as uint?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + #endregion + + #region IDENTIFY_ENDPOINT + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.IDENTIFY_ENDPOINT, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.IDENTIFY_ENDPOINT, + new byte[] { 0x00, 0x01, 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetIdentifyEndpoint))); + + var obj = dataTreeBranch.ParsedObject as GetSetIdentifyEndpoint; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.IdentifyState, Is.EqualTo(false)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.IDENTIFY_ENDPOINT, + new byte[] { 0x00, 0x01, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetIdentifyEndpoint))); + + var obj = dataTreeBranch.ParsedObject as GetSetIdentifyEndpoint; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.IdentifyState, Is.EqualTo(true)); + })); + #endregion + + #region ENDPOINT_TO_UNIVERSE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.ENDPOINT_TO_UNIVERSE, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_TO_UNIVERSE, + new byte[] { 0x00, 0x01, 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetEndpointToUniverse))); + + var obj = dataTreeBranch.ParsedObject as GetSetEndpointToUniverse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.Universe, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.ENDPOINT_TO_UNIVERSE, + new byte[] { 0x00, 0x01, 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetEndpointToUniverse))); + + var obj = dataTreeBranch.ParsedObject as GetSetEndpointToUniverse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.Universe, Is.EqualTo(1)); + })); + #endregion + + #region ENDPOINT_MODE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.ENDPOINT_MODE, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_MODE, + new byte[] { 0x00, 0x01, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetEndpointMode))); + + var obj = dataTreeBranch.ParsedObject as GetSetEndpointMode; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.EndpointMode, Is.EqualTo(ERDM_EndpointMode.INPUT)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.ENDPOINT_MODE, + new byte[] { 0x00, 0x01, 0x02 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetEndpointMode))); + + var obj = dataTreeBranch.ParsedObject as GetSetEndpointMode; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.EndpointMode, Is.EqualTo(ERDM_EndpointMode.OUTPUT)); + })); + #endregion + + #region ENDPOINT_LABEL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.ENDPOINT_LABEL, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_LABEL, + new byte[] { 0x00, 0x08, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x36 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetEndpointLabel))); + + var obj = dataTreeBranch.ParsedObject as GetSetEndpointLabel; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(8)); + Assert.That(obj!.EndpointLabel, Is.EqualTo("Port 6")); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.ENDPOINT_LABEL, + new byte[] { 0x00, 0x08, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x36 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetEndpointLabel))); + + var obj = dataTreeBranch.ParsedObject as GetSetEndpointLabel; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(8)); + Assert.That(obj!.EndpointLabel, Is.EqualTo("Port 6")); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_LABEL, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + #endregion + + #region RDM_TRAFFIC_ENABLE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.RDM_TRAFFIC_ENABLE, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.RDM_TRAFFIC_ENABLE, + new byte[] { 0x00, 0x01, 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetEndpointRDMTrafficEnable))); + + var obj = dataTreeBranch.ParsedObject as GetSetEndpointRDMTrafficEnable; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.RDMTrafficEnabled, Is.EqualTo(false)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.RDM_TRAFFIC_ENABLE, + new byte[] { 0x00, 0x01, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetEndpointRDMTrafficEnable))); + + var obj = dataTreeBranch.ParsedObject as GetSetEndpointRDMTrafficEnable; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.RDMTrafficEnabled, Is.EqualTo(true)); + })); + #endregion + + #region DISCOVERY_STATE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.DISCOVERY_STATE, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DISCOVERY_STATE, + new byte[] { 0x00, 0x01, 0x00, 0x02, 0x04 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetDiscoveryStateResponse))); + + var obj = dataTreeBranch.ParsedObject as GetDiscoveryStateResponse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.DeviceCount, Is.EqualTo(2)); + Assert.That(obj!.DiscoveryState, Is.EqualTo(ERDM_DiscoveryState.NOT_ACTIVE)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.DISCOVERY_STATE, + new byte[] { 0x00, 0x01, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(SetDiscoveryStateRequest))); + + var obj = dataTreeBranch.ParsedObject as SetDiscoveryStateRequest; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.DiscoveryState, Is.EqualTo(ERDM_DiscoveryState.INCREMENTAL)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND_RESPONSE, + ERDM_Parameter.DISCOVERY_STATE, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + #endregion + + #region BACKGROUND_DISCOVERY + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.BACKGROUND_DISCOVERY, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.BACKGROUND_DISCOVERY, + new byte[] { 0x00, 0x01, 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetEndpointBackgroundDiscovery))); + + var obj = dataTreeBranch.ParsedObject as GetSetEndpointBackgroundDiscovery; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.BackgroundDiscovery, Is.EqualTo(false)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.BACKGROUND_DISCOVERY, + new byte[] { 0x00, 0x01, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetSetEndpointBackgroundDiscovery))); + + var obj = dataTreeBranch.ParsedObject as GetSetEndpointBackgroundDiscovery; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.BackgroundDiscovery, Is.EqualTo(true)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND_RESPONSE, + ERDM_Parameter.BACKGROUND_DISCOVERY, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + #endregion + + #region ENDPOINT_TIMING + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.ENDPOINT_TIMING, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_TIMING, + new byte[] { 0x00, 0x01, 0x02, 0x03 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetEndpointTimingResponse))); + + var obj = dataTreeBranch.ParsedObject as GetEndpointTimingResponse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.TimingId, Is.EqualTo(2)); + Assert.That(obj!.Count, Is.EqualTo(3)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.ENDPOINT_TIMING, + new byte[] { 0x00, 0x01, 0x02 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(SetEndpointTimingRequest))); + + var obj = dataTreeBranch.ParsedObject as SetEndpointTimingRequest; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.TimingId, Is.EqualTo(2)); + })); + #endregion + + #region ENDPOINT_TIMING_DESCRIPTION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, + new byte[] { 0x03 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + + var obj = dataTreeBranch.ParsedObject as byte?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(3)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, + new byte[] { + 0x03, 0x53, 0x6c, 0x6f, 0x77, 0x20, 0x28, 0x32, + 0x30, 0x30, 0x75, 0x53, 0x2f, 0x32, 0x35, 0x46, + 0x50, 0x53, 0x29 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetEndpointTimingDescriptionResponse))); + + var obj = dataTreeBranch.ParsedObject as GetEndpointTimingDescriptionResponse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.TimingId, Is.EqualTo(3)); + Assert.That(obj.Description, Is.EqualTo("Slow (200uS/25FPS)")); + })); + #endregion + + #region ENDPOINT_RESPONDERS + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_RESPONDERS, + new byte[] { + 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetEndpointRespondersResponse))); + + var obj = dataTreeBranch.ParsedObject as GetEndpointRespondersResponse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(3)); + Assert.That(obj.ListChangedNumber, Is.EqualTo(9)); + Assert.That(obj.UIDs, Is.Not.Null); + Assert.That(obj.UIDs.Length, Is.EqualTo(0)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_RESPONDERS, + new byte[] { + 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x53, 0x47, + 0x94, 0x71, 0xaf, 0x2f + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetEndpointRespondersResponse))); + + var obj = dataTreeBranch.ParsedObject as GetEndpointRespondersResponse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(3)); + Assert.That(obj.ListChangedNumber, Is.EqualTo(9)); + Assert.That(obj.UIDs, Is.Not.Null); + Assert.That(obj.UIDs.Length, Is.EqualTo(1)); + Assert.That(obj.UIDs[0], Is.EqualTo(new UID(0x5347, 0x9471af2f))); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_RESPONDERS, + new byte[] { + 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x53, 0x47, + 0x94, 0x71, 0xaf, 0x2f, 0x53, 0x47, 0x94, 0x03, + 0x02, 0x01 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetEndpointRespondersResponse))); + + var obj = dataTreeBranch.ParsedObject as GetEndpointRespondersResponse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(3)); + Assert.That(obj.ListChangedNumber, Is.EqualTo(9)); + Assert.That(obj.UIDs, Is.Not.Null); + Assert.That(obj.UIDs.Length, Is.EqualTo(2)); + Assert.That(obj.UIDs[0], Is.EqualTo(new UID(0x5347, 0x9471af2f))); + Assert.That(obj.UIDs[1], Is.EqualTo(new UID(0x5347, 0x94030201))); + })); + #endregion + + #region ENDPOINT_RESPONDER_LIST_CHANGE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = dataTreeBranch.ParsedObject as ushort?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, + new byte[] { 0x00, 0x01, 0x02, 0x03, 0x02, 0x03 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetEndpointResponderListChangeResponse))); + + var obj = dataTreeBranch.ParsedObject as GetEndpointResponderListChangeResponse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.ListChangeNumber, Is.EqualTo(33751555)); + })); + #endregion + + #region BINDING_CONTROL_FIELDS + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.BINDING_CONTROL_FIELDS, + new byte[] { 0x00, 0x01, 0x53, 0x47, 0x94, 0x71, 0xaf, 0x2f }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetBindingAndControlFieldsRequest))); + + var obj = dataTreeBranch.ParsedObject as GetBindingAndControlFieldsRequest; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.UID, Is.EqualTo(new UID(0x5347, 0x9471af2f))); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.BINDING_CONTROL_FIELDS, + new byte[] { + 0x00, 0x01, 0x53, 0x47, 0x94, 0x71, 0xaf, 0x2f, + 0x00, 0x00, 0x52, 0x46, 0x93, 0x72, 0xad, 0x21, + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetBindingAndControlFieldsResponse))); + + var obj = dataTreeBranch.ParsedObject as GetBindingAndControlFieldsResponse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.EndpointId, Is.EqualTo(1)); + Assert.That(obj!.UID, Is.EqualTo(new UID(0x5347, 0x9471af2f))); + Assert.That(obj!.ControlField, Is.EqualTo(0)); + Assert.That(obj!.BindingUID, Is.EqualTo(new UID(0x5246, 0x9372ad21))); + })); + #endregion + + #region BACKGROUND_QUEUED_STATUS_POLICY + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, + new byte[] { }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, + new byte[] { 0x01, 0x02 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetBackgroundQueuedStatusPolicyResponse))); + + var obj = dataTreeBranch.ParsedObject as GetBackgroundQueuedStatusPolicyResponse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.PolicyId, Is.EqualTo(1)); + Assert.That(obj!.Count, Is.EqualTo(2)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, + new byte[] { 0x02 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + + var obj = dataTreeBranch.ParsedObject as byte?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(2)); + })); + #endregion + + #region BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, + new byte[] { 0x03 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + + var obj = dataTreeBranch.ParsedObject as byte?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(3)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, + new byte[] { + 0x03, 0x53, 0x6c, 0x6f, 0x77, 0x20, 0x28, 0x32, + 0x30, 0x30, 0x75, 0x53, 0x2f, 0x32, 0x35, 0x46, + 0x50, 0x53, 0x29 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetBackgroundQueuedStatusPolicyDescriptionResponse))); + + var obj = dataTreeBranch.ParsedObject as GetBackgroundQueuedStatusPolicyDescriptionResponse; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.PolicyId, Is.EqualTo(3)); + Assert.That(obj.Description, Is.EqualTo("Slow (200uS/25FPS)")); + })); + #endregion + + #region MANUFACTURER_URL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.MANUFACTURER_URL, + new byte[] { 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + var obj = dataTreeBranch.ParsedObject as string; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!, Is.EqualTo("https://example.com")); + })); + #endregion + + #region PRODUCT_URL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.PRODUCT_URL, + new byte[] { 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + var obj = dataTreeBranch.ParsedObject as string; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!, Is.EqualTo("https://example.com")); + })); + #endregion + + #region FIRMWARE_URL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.FIRMWARE_URL, + new byte[] { 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + var obj = dataTreeBranch.ParsedObject as string; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!, Is.EqualTo("https://example.com")); + })); + #endregion + + #region SERIAL_NUMBER + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.SERIAL_NUMBER, + new byte[] { + 0x31, 0x41, 0x46, 0x33, 0x38, 0x36, 0x37, 0x38, + 0x30, 0x30, 0x33, 0x30 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + var obj = dataTreeBranch.ParsedObject as string; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!, Is.EqualTo("1AF386780030")); + })); + + #endregion + + #region DEVICE_INFO_OFFSTAGE + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.DEVICE_INFO_OFFSTAGE, + new byte[] { 0x04, 0x00, 0x08, 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetDeviceInfoOffstageRequest))); + var obj = dataTreeBranch.ParsedObject as GetDeviceInfoOffstageRequest; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.RootPersonality, Is.EqualTo(4)); + Assert.That(obj!.SubDeviceRequested, Is.EqualTo(8)); + Assert.That(obj!.SubDevicePersonalityRequested, Is.EqualTo(0)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DEVICE_INFO_OFFSTAGE, + new byte[] { + 0x04, 0x00, 0x08, 0x00, + 0x01, 0x00, 0x00, 0x05, 0x06, 0x01, 0x02, 0x00, + 0x01, 0x01, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, + 0x00, 0x04, 0x00 + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetDeviceInfoOffstageResponse))); + + var obj = (GetDeviceInfoOffstageResponse)dataTreeBranch.ParsedObject; + Assert.That(obj.RootPersonality, Is.EqualTo(4)); + Assert.That(obj.SubDeviceRequested, Is.EqualTo(8)); + Assert.That(obj.SubDevicePersonalityRequested, Is.EqualTo(0)); + + var deviceInfo = obj.DeviceInfo; + Assert.That(deviceInfo, Is.Not.Null); + Assert.That(deviceInfo.RdmProtocolVersionMajor, Is.EqualTo(1)); + Assert.That(deviceInfo.RdmProtocolVersionMinor, Is.EqualTo(0)); + Assert.That(deviceInfo.DeviceModelId, Is.EqualTo(0x0005)); + Assert.That(deviceInfo.ProductCategoryCoarse, Is.EqualTo(ERDM_ProductCategoryCoarse.POWER)); + Assert.That(deviceInfo.ProductCategoryFine, Is.EqualTo(ERDM_ProductCategoryFine.POWER_CONTROL)); + Assert.That(deviceInfo.SoftwareVersionId, Is.EqualTo(0x02000101)); + Assert.That(deviceInfo.Dmx512Footprint, Is.EqualTo(1)); + Assert.That(deviceInfo.Dmx512CurrentPersonality, Is.EqualTo(1)); + Assert.That(deviceInfo.Dmx512NumberOfPersonalities, Is.EqualTo(3)); + Assert.That(deviceInfo.Dmx512StartAddress, Is.EqualTo(1)); + Assert.That(deviceInfo.SubDeviceCount, Is.EqualTo(4)); + Assert.That(deviceInfo.SensorCount, Is.EqualTo(0)); + })); + #endregion + + #region TEST_DATA + #endregion + + #region COMMS_STATUS_NSC + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.COMMS_STATUS_NSC, + new byte[] { 0b00111111, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(GetCommunicationStatusNullStartCodeResponse))); + + var obj = (GetCommunicationStatusNullStartCodeResponse)dataTreeBranch.ParsedObject; + Assert.That(obj.AdditiveChecksumOfMostRecentPacket, Is.EqualTo(1)); + Assert.That(obj.PacketCount, Is.EqualTo(1)); + Assert.That(obj.MostRecentSlotCount, Is.EqualTo(1)); + Assert.That(obj.MinimumSlotCount, Is.EqualTo(1)); + Assert.That(obj.MaximumSlotCount, Is.EqualTo(1)); + Assert.That(obj.NumberOfPacketsWithAnError, Is.EqualTo(1)); + })); + #endregion + + #region IDENTIFY_TIMEOUT + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.IDENTIFY_TIMEOUT, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = (ushort)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(1)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.IDENTIFY_TIMEOUT, + new byte[] { 0x00, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ushort))); + + var obj = (ushort)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(1)); + })); + #endregion + + #region POWER_OFF_READY + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.POWER_OFF_READY, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(bool))); + + var obj = (bool)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.True); + })); + #endregion + + #region SHIPPING_LOCK + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.SHIPPING_LOCK, + new byte[] { 0x02 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_ShippingLockState))); + + var obj = (ERDM_ShippingLockState)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_ShippingLockState.PARTIALLY_LOCKED)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.SHIPPING_LOCK, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_ShippingLockState))); + + var obj = (ERDM_ShippingLockState)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_ShippingLockState.LOCKED)); + })); + #endregion + + #region LIST_TAGS + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.LIST_TAGS, + new byte[] { + 0x42, 0x41, 0x43, 0x4B, 0x54, 0x52, 0x55, 0x53, 0x53, + 0x00, + 0x4D, 0x49, 0x44, 0x54, 0x52, 0x55, 0x53, 0x53, + 0x00, + 0x46, 0x52, 0x4F, 0x4E, 0x54, 0x54, 0x52, 0x55, 0x53, 0x53 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string[]))); + + var obj = (string[])dataTreeBranch.ParsedObject; + Assert.That(obj.Length, Is.EqualTo(3)); + Assert.That(obj[0], Is.EqualTo("BACKTRUSS")); + Assert.That(obj[1], Is.EqualTo("MIDTRUSS")); + Assert.That(obj[2], Is.EqualTo("FRONTTRUSS")); + })); + #endregion + + #region ADD_TAG + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.ADD_TAG, + new byte[] { 0x42, 0x41, 0x43, 0x4B, 0x54, 0x52, 0x55, 0x53, 0x53 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + + var obj = (string)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo("BACKTRUSS")); + + })); + #endregion + + #region REMOVE_TAG + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.REMOVE_TAG, + new byte[] { 0x42, 0x41, 0x43, 0x4B, 0x54, 0x52, 0x55, 0x53, 0x53 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + + var obj = (string)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo("BACKTRUSS")); + + })); + #endregion + + #region CHECK_TAG + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.CHECK_TAG, + new byte[] { 0x42, 0x41, 0x43, 0x4B, 0x54, 0x52, 0x55, 0x53, 0x53 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + var obj = (string)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo("BACKTRUSS")); + })); + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.CHECK_TAG, + new byte[] { 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(bool))); + + var obj = (bool)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.True); + })); + #endregion + + #region CLEAR_TAGS + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.CLEAR_TAGS, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND_RESPONSE, + ERDM_Parameter.CLEAR_TAGS, + new byte[0], + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.True); + Assert.That(dataTreeBranch.ParsedObject, Is.Null); + })); + #endregion + + #region DEVICE_UNIT_NUMBER + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DEVICE_UNIT_NUMBER, + new byte[] { 0x00, 0x00, 0x01, 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + + var obj = (uint)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(256)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.SET_COMMAND, + ERDM_Parameter.DEVICE_UNIT_NUMBER, + new byte[] { 0x00, 0x00, 0x01, 0x00 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(uint))); + + var obj = (uint)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(256)); + })); + #endregion + + #region DMX_PERSONALITY_ID + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.DMX_PERSONALITY_ID, + new byte[] { 0x10 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + + var obj = dataTreeBranch.ParsedObject as byte?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!, Is.EqualTo(0x10)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.DMX_PERSONALITY_ID, + new byte[] { 0x10, 0x53, 0x4D, 0x61, 0x72, 0x00, 0x00, 0x00, 0x0F }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMPersonalityId))); + + var obj = dataTreeBranch.ParsedObject as RDMPersonalityId; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.PersonalityId, Is.EqualTo(0x10)); + Assert.That(obj!.Index, Is.EqualTo(0x10)); + Assert.That(obj!.MajorPersonalityId, Is.EqualTo(1397580146)); + Assert.That(obj!.MinorPersonalityId, Is.EqualTo(15)); + Assert.That(obj!.MinIndex, Is.EqualTo(1)); + })); + #endregion + + #region SENSOR_TYPE_CUSTOM + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.SENSOR_TYPE_CUSTOM, + new byte[] { 0xee, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(byte))); + + var obj = dataTreeBranch.ParsedObject as byte?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(0xee)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.SENSOR_TYPE_CUSTOM, + new byte[] { 0xee, 0x45, 0x75, 0x72, 0x6F }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSensorTypeCustomDefine))); + + var obj = dataTreeBranch.ParsedObject as RDMSensorTypeCustomDefine; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Id, Is.EqualTo(0xee)); + Assert.That(obj!.Index, Is.EqualTo(0xee)); + Assert.That(obj!.MinIndex, Is.EqualTo(0x80)); + Assert.That(obj!.Label, Is.EqualTo("Euro")); + })); + #endregion + + #region SENSOR_UNIT_CUSTOM + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.SENSOR_UNIT_CUSTOM, + new byte[] { 0xee, 0x45, 0x75, 0x72, 0x6F }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSensorUnitCustomDefine))); + + var obj = dataTreeBranch.ParsedObject as RDMSensorUnitCustomDefine; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Id, Is.EqualTo(0xee)); + Assert.That(obj!.Index, Is.EqualTo(0xee)); + Assert.That(obj!.MinIndex, Is.EqualTo(0x80)); + Assert.That(obj!.Label, Is.EqualTo("Euro")); + })); + #endregion + + #region METADATA_PARAMETER_VERSION + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.METADATA_PARAMETER_VERSION, + new byte[] { 0x06, 0x53 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_Parameter))); + + var obj = dataTreeBranch.ParsedObject as ERDM_Parameter?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(ERDM_Parameter.REMOVE_TAG)); + })); + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.METADATA_PARAMETER_VERSION, + new byte[] { 0x06, 0x53, 0x02, 0x01 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMMetadataParameterVersion))); + + var obj = dataTreeBranch.ParsedObject as RDMMetadataParameterVersion; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.ParameterId, Is.EqualTo(ERDM_Parameter.REMOVE_TAG)); + Assert.That(obj.Version, Is.EqualTo(513)); + })); + #endregion + + #region METADATA_JSON + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND, + ERDM_Parameter.METADATA_JSON, + new byte[] { 0x06, 0x53 }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_Parameter))); + + var obj = dataTreeBranch.ParsedObject as ERDM_Parameter?; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.Value, Is.EqualTo(ERDM_Parameter.REMOVE_TAG)); + })); + + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.METADATA_JSON, + new byte[] { + 0x81, 0x0d, + 0x7B, 0x22, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x3A, 0x22, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x6C, + 0x6F, 0x6E, 0x65, 0x20, 0x43, 0x6F, 0x6E, 0x74, 0x72, 0x6F, 0x6C, 0x20, 0x4D, 0x6F, 0x64, + 0x65, 0x22, 0x2C, 0x22, 0x6D, 0x61, 0x6E, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, 0x65, + 0x72, 0x5F, 0x69, 0x64, 0x22, 0x3A, 0x31, 0x39, 0x37, 0x39, 0x32, 0x2C, 0x22, 0x70, 0x69, + 0x64, 0x22, 0x3A, 0x33, 0x33, 0x30, 0x33, 0x37, 0x2C, 0x22, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6F, 0x6E, 0x22, 0x3A, 0x31, 0x2C, 0x22, 0x6E, 0x6F, 0x74, 0x65, 0x73, 0x22, 0x3A, 0x22, + 0x54, 0x6F, 0x64, 0x6F, 0x3A, 0x20, 0x41, 0x64, 0x64, 0x20, 0x6E, 0x6F, 0x74, 0x65, 0x73, + 0x20, 0x66, 0x6F, 0x72, 0x20, 0x4D, 0x61, 0x72, 0x74, 0x69, 0x6E, 0x20, 0x53, 0x74, 0x61, + 0x6E, 0x64, 0x61, 0x6C, 0x6F, 0x6E, 0x65, 0x20, 0x43, 0x6F, 0x6E, 0x74, 0x72, 0x6F, 0x6C, + 0x20, 0x4D, 0x6F, 0x64, 0x65, 0x20, 0x28, 0x30, 0x78, 0x38, 0x31, 0x30, 0x44, 0x29, 0x22, + 0x2C, 0x22, 0x67, 0x65, 0x74, 0x5F, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5F, 0x73, + 0x75, 0x62, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5F, 0x72, 0x61, 0x6E, 0x67, 0x65, 0x22, + 0x3A, 0x5B, 0x22, 0x72, 0x6F, 0x6F, 0x74, 0x22, 0x2C, 0x22, 0x73, 0x75, 0x62, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x5D, 0x2C, 0x22, 0x67, 0x65, 0x74, 0x5F, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3A, 0x5B, 0x5D, 0x2C, 0x22, 0x67, 0x65, 0x74, 0x5F, + 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, 0x22, 0x3A, 0x5B, 0x7B, 0x22, 0x6E, 0x61, + 0x6D, 0x65, 0x22, 0x3A, 0x22, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x2C, 0x22, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x3A, 0x22, 0x75, 0x69, 0x6E, 0x74, 0x38, 0x22, 0x7D, 0x5D, 0x2C, 0x22, + 0x73, 0x65, 0x74, 0x5F, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5F, 0x73, 0x75, 0x62, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5F, 0x72, 0x61, 0x6E, 0x67, 0x65, 0x22, 0x3A, 0x5B, + 0x22, 0x72, 0x6F, 0x6F, 0x74, 0x22, 0x2C, 0x22, 0x73, 0x75, 0x62, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x22, 0x2C, 0x22, 0x62, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, + 0x22, 0x5D, 0x2C, 0x22, 0x73, 0x65, 0x74, 0x5F, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0x3A, 0x22, 0x67, 0x65, 0x74, 0x5F, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, + 0x22, 0x2C, 0x22, 0x73, 0x65, 0x74, 0x5F, 0x72, 0x65, 0x73, 0x70, 0x6F, 0x6E, 0x73, 0x65, + 0x22, 0x3A, 0x5B, 0x5D, 0x7D + }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMMetadataJson))); + + var obj = dataTreeBranch.ParsedObject as RDMMetadataJson; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.ParameterId, Is.EqualTo((ERDM_Parameter)0x810D)); + Assert.That(obj!.Index, Is.EqualTo((ERDM_Parameter)0x810D)); + Assert.That(obj!.JSON, Is.EqualTo("{\"name\":\"Standalone Control Mode\",\"manufacturer_id\":19792,\"pid\":33037,\"version\":1,\"notes\":\"Todo: Add notes for Martin Standalone Control Mode (0x810D)\",\"get_request_subdevice_range\":[\"root\",\"subdevices\"],\"get_request\":[],\"get_response\":[{\"name\":\"state\",\"type\":\"uint8\"}],\"set_request_subdevice_range\":[\"root\",\"subdevices\",\"broadcast\"],\"set_request\":\"get_response\",\"set_response\":[]}")); + })); + #endregion + + #region METADATA_JSON_URL + yield return new PayloadToParseBagData( + ERDM_Command.GET_COMMAND_RESPONSE, + ERDM_Parameter.METADATA_JSON_URL, + new byte[] { 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d }, + new Action((dataTreeBranch) => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(string))); + var obj = dataTreeBranch.ParsedObject as string; + Assert.That(obj, Is.Not.Null); + Assert.That(obj!, Is.EqualTo("https://example.com")); + })); + #endregion + } + + public PayloadToParseBagData PayloadToParseBag { get; private set; } + public MetadataJSONObjectDefine Define { get; private set; } + public override string ToString() => PayloadToParseBag.ToString(); + + public PayloadToParsedObjectTestSubject(MetadataJSONObjectDefine define, PayloadToParseBagData payloadToParseBagData) + { + this.Define = define; + this.PayloadToParseBag = payloadToParseBagData; + } + + public readonly struct PayloadToParseBagData + { + public readonly ERDM_Command Command; + public readonly RDMSharp.Metadata.JSON.Command.ECommandDublicate CommandDublicate; + public readonly ERDM_Parameter Parameter; + public readonly byte[] Payload; + public readonly Action TestPayload; + + internal PayloadToParseBagData(in ERDM_Command command, in ERDM_Parameter parameter, in byte[] payload, Action testPayload) + { + this.Command = command; + switch (command) + { + case ERDM_Command.GET_COMMAND: + this.CommandDublicate = RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetRequest; + break; + case ERDM_Command.GET_COMMAND_RESPONSE: + this.CommandDublicate = RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse; + break; + case ERDM_Command.SET_COMMAND: + this.CommandDublicate = RDMSharp.Metadata.JSON.Command.ECommandDublicate.SetRequest; + break; + case ERDM_Command.SET_COMMAND_RESPONSE: + this.CommandDublicate = RDMSharp.Metadata.JSON.Command.ECommandDublicate.SetResponse; + break; + } + this.Parameter = parameter; + this.Payload = payload; + this.TestPayload = testPayload; + } + + public override string ToString() + { + return $"{Parameter} ({CommandDublicate}), Payload: {BitConverter.ToString(Payload)}"; + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/Parser/PayloadToParsedObjectTests.cs b/RDMSharpTests/Metadata/Parser/PayloadToParsedObjectTests.cs new file mode 100644 index 00000000..4348e2cf --- /dev/null +++ b/RDMSharpTests/Metadata/Parser/PayloadToParsedObjectTests.cs @@ -0,0 +1,52 @@ +using RDMSharp.Metadata; +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.Metadata.Parser; + +[TestFixtureSource(typeof(PayloadToParsedObjectTestSubject), nameof(PayloadToParsedObjectTestSubject.TestSubjects))] +public class PayloadToParsedObjectTests +{ + private readonly PayloadToParsedObjectTestSubject testSubject; + + private DataTreeBranch dataTreeBranch; + + public PayloadToParsedObjectTests(PayloadToParsedObjectTestSubject _TestSubject) + { + testSubject = _TestSubject; + } + + [Test, Order(1)] + public void PayloadDataToObject() + { + Assert.DoesNotThrow(() => + { + dataTreeBranch = MetadataFactory.ParseDataToPayload(testSubject.Define, testSubject.PayloadToParseBag.CommandDublicate, testSubject.PayloadToParseBag.Payload); + }); + + + } + [Test, Order(2)] + public void TestPayloadAction() + { + testSubject.PayloadToParseBag.TestPayload.Invoke(dataTreeBranch); + } + + [Test, Order(3)] + public void ToPayloadDataTest() + { + if (dataTreeBranch.ParsedObject is IRDMPayloadObject obj) + Assert.That(obj.ToPayloadData(), Is.EqualTo(testSubject.PayloadToParseBag.Payload)); + } + [Test, Order(4)] + public void ToStringTest() + { + if (dataTreeBranch.ParsedObject is IRDMPayloadObject obj) + Assert.That(obj.ToString(), Is.Not.Null); + } + [Test, Order(5)] + public void Reverse() + { + var reversed = DataTreeBranch.FromObject(dataTreeBranch.ParsedObject, null, new ParameterBag(testSubject.PayloadToParseBag.Parameter), testSubject.PayloadToParseBag.Command); + Assert.That(reversed, Is.EqualTo(dataTreeBranch)); + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs b/RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs index de8472bf..c521fc22 100644 --- a/RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs +++ b/RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs @@ -7,6 +7,11 @@ namespace RDMSharpTests.Metadata.Parser; public class TestDefinedDataTreeObjects { + [OneTimeSetUp] + public async Task OneTimeSetup() + { + await MetadataFactory.AwaitInitialize(); + } [Test] public void Test_AllDefinedDataTreeObjectsForValidility() { @@ -26,7 +31,7 @@ public void Test_AllDefinedDataTreeObjectsForValidility() { StringBuilder stringBuilder3 = new StringBuilder(); var parameters = constructor.GetParameters(); - foreach (var para in parameters.Where(p => !p.GetCustomAttributes().Any(a=>a is DataTreeObjectParameterAttribute))) + foreach (var para in parameters.Where(p => !p.GetCustomAttributes().Any(a => a is DataTreeObjectParameterAttribute))) stringBuilder3.AppendLine($"\t{para.Name}"); if (stringBuilder3.Length > 0) { @@ -40,237 +45,4 @@ public void Test_AllDefinedDataTreeObjectsForValidility() if (stringBuilder.Length > 0) Assert.Fail(stringBuilder.ToString().Trim()); } - - [Test] - public void Test_DeviceInfo() - { - byte[] data = { - 0x01, 0x00, 0x00, 0x05, 0x06, 0x01, 0x02, 0x00, - 0x01, 0x01, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, - 0x00, 0x04, 0x00 - }; - - var parameterBag = new ParameterBag(ERDM_Parameter.DEVICE_INFO); - var define = MetadataFactory.GetDefine(parameterBag); - - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, data); - - Assert.Multiple(() => - { - Assert.That(dataTreeBranch.IsUnset, Is.False); - Assert.That(dataTreeBranch.IsEmpty, Is.False); - Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); - Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDeviceInfo))); - - var obj = dataTreeBranch.ParsedObject as RDMDeviceInfo; - Assert.That(obj, Is.Not.Null); - Assert.That(obj!.RdmProtocolVersionMajor, Is.EqualTo(1)); - Assert.That(obj.RdmProtocolVersionMinor, Is.EqualTo(0)); - Assert.That(obj.DeviceModelId, Is.EqualTo(0x0005)); - Assert.That(obj.ProductCategoryCoarse, Is.EqualTo(ERDM_ProductCategoryCoarse.POWER)); - Assert.That(obj.ProductCategoryFine, Is.EqualTo(ERDM_ProductCategoryFine.POWER_CONTROL)); - Assert.That(obj.SoftwareVersionId, Is.EqualTo(0x02000101)); - Assert.That(obj.Dmx512Footprint, Is.EqualTo(1)); - Assert.That(obj.Dmx512CurrentPersonality, Is.EqualTo(1)); - Assert.That(obj.Dmx512NumberOfPersonalities, Is.EqualTo(3)); - Assert.That(obj.Dmx512StartAddress, Is.EqualTo(1)); - Assert.That(obj.SubDeviceCount, Is.EqualTo(4)); - Assert.That(obj.SensorCount, Is.EqualTo(0)); - }); - - var reversed = DataTreeBranch.FromObject(dataTreeBranch.ParsedObject, null, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DEVICE_INFO); - Assert.That(reversed, Is.EqualTo(dataTreeBranch)); - } - - [Test] - public void Test_Personality() - { - byte[] data = { - 0x01, 0x03 - }; - - var parameterBag = new ParameterBag(ERDM_Parameter.DMX_PERSONALITY); - var define = MetadataFactory.GetDefine(parameterBag); - - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, data); - - Assert.Multiple(() => - { - Assert.That(dataTreeBranch.IsUnset, Is.False); - Assert.That(dataTreeBranch.IsEmpty, Is.False); - Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); - Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDMXPersonality))); - - var obj = dataTreeBranch.ParsedObject as RDMDMXPersonality; - Assert.That(obj, Is.Not.Null); - Assert.That(obj!.CurrentPersonality, Is.EqualTo(1)); - Assert.That(obj.OfPersonalities, Is.EqualTo(3)); - }); - - var reversed = DataTreeBranch.FromObject(dataTreeBranch.ParsedObject, null, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_PERSONALITY); - Assert.That(reversed, Is.EqualTo(dataTreeBranch)); - } - - [Test] - public void Test_Personality_Description() - { - byte[] data = { - 0x01, 0x00, 0x01, 0x53, 0x45, 0x51, 0x55, 0x45, - 0x4e, 0x43, 0x45 - }; - - var parameterBag = new ParameterBag(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION); - var define = MetadataFactory.GetDefine(parameterBag); - - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, data); - - Assert.Multiple(() => - { - Assert.That(dataTreeBranch.IsUnset, Is.False); - Assert.That(dataTreeBranch.IsEmpty, Is.False); - Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); - Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDMXPersonalityDescription))); - - var obj = dataTreeBranch.ParsedObject as RDMDMXPersonalityDescription; - Assert.That(obj, Is.Not.Null); - Assert.That(obj!.PersonalityId, Is.EqualTo(1)); - Assert.That(obj.Slots, Is.EqualTo(1)); - Assert.That(obj.Description, Is.EqualTo("SEQUENCE")); - }); - - var reversed = DataTreeBranch.FromObject(dataTreeBranch.ParsedObject, null, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION); - Assert.That(reversed, Is.EqualTo(dataTreeBranch)); - } - - [Test] - public void Test_Slot_Description() - { - byte[] data = { - 0x00, 0x00, 0x53, 0x41, 0x46, 0x45, 0x54, 0x59 - }; - - var parameterBag = new ParameterBag(ERDM_Parameter.SLOT_DESCRIPTION); - var define = MetadataFactory.GetDefine(parameterBag); - - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, data); - - Assert.Multiple(() => - { - Assert.That(dataTreeBranch.IsUnset, Is.False); - Assert.That(dataTreeBranch.IsEmpty, Is.False); - Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); - Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSlotDescription))); - - var obj = dataTreeBranch.ParsedObject as RDMSlotDescription; - Assert.That(obj, Is.Not.Null); - Assert.That(obj!.SlotId, Is.EqualTo(0)); - Assert.That(obj.Description, Is.EqualTo("SAFETY")); - }); - - var reversed = DataTreeBranch.FromObject(dataTreeBranch.ParsedObject, null, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.SLOT_DESCRIPTION); - Assert.That(reversed, Is.EqualTo(dataTreeBranch)); - } - [Test] - public void Test_Slot_Info() - { - byte[] data = { - 0,0,0,0,1, - 0,1,0,4,4, - 0,2,0,2,5, - 0,3,0,2,6, - 0,4,0,2,7 - }; - - var parameterBag = new ParameterBag(ERDM_Parameter.SLOT_INFO); - var define = MetadataFactory.GetDefine(parameterBag); - - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, data); - - Assert.Multiple(() => - { - Assert.That(dataTreeBranch.IsUnset, Is.False); - Assert.That(dataTreeBranch.IsEmpty, Is.False); - Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); - Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSlotInfo[]))); - - var obj = dataTreeBranch.ParsedObject as RDMSlotInfo[]; - Assert.That(obj, Is.Not.Null); - Assert.That(obj![0].SlotOffset, Is.EqualTo(0)); - Assert.That(obj[0].SlotType, Is.EqualTo(ERDM_SlotType.PRIMARY)); - Assert.That(obj[0].SlotLabelId, Is.EqualTo(ERDM_SlotCategory.INTENSITY)); - - Assert.That(obj[1].SlotOffset, Is.EqualTo(1)); - Assert.That(obj[1].SlotType, Is.EqualTo(ERDM_SlotType.PRIMARY)); - Assert.That(obj[1].SlotLabelId, Is.EqualTo(ERDM_SlotCategory.STROBE)); - - Assert.That(obj[2].SlotOffset, Is.EqualTo(2)); - Assert.That(obj[2].SlotType, Is.EqualTo(ERDM_SlotType.PRIMARY)); - Assert.That(obj[2].SlotLabelId, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_RED)); - - Assert.That(obj[3].SlotOffset, Is.EqualTo(3)); - Assert.That(obj[3].SlotType, Is.EqualTo(ERDM_SlotType.PRIMARY)); - Assert.That(obj[3].SlotLabelId, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_GREEN)); - - Assert.That(obj[4].SlotOffset, Is.EqualTo(4)); - Assert.That(obj[4].SlotType, Is.EqualTo(ERDM_SlotType.PRIMARY)); - Assert.That(obj[4].SlotLabelId, Is.EqualTo(ERDM_SlotCategory.COLOR_ADD_BLUE)); - }); - - var reversed = DataTreeBranch.FromObject(dataTreeBranch.ParsedObject, null, ERDM_Command.GET_COMMAND_RESPONSE, ERDM_Parameter.SLOT_INFO); - Assert.That(reversed, Is.EqualTo(dataTreeBranch)); - } - - [Test] - public void Test_Display_Invert() - { - byte[] data = { - 0x01 - }; - - var parameterBag = new ParameterBag(ERDM_Parameter.DISPLAY_INVERT); - var define = MetadataFactory.GetDefine(parameterBag); - - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.SetRequest, data); - - Assert.Multiple(() => - { - Assert.That(dataTreeBranch.IsUnset, Is.False); - Assert.That(dataTreeBranch.IsEmpty, Is.False); - Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); - Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_DisplayInvert))); - - var obj = (ERDM_DisplayInvert)dataTreeBranch.ParsedObject; - Assert.That(obj, Is.EqualTo(ERDM_DisplayInvert.ON)); - }); - - var reversed = DataTreeBranch.FromObject(dataTreeBranch.ParsedObject, null, ERDM_Command.SET_COMMAND, ERDM_Parameter.DISPLAY_INVERT); - Assert.That(reversed, Is.EqualTo(dataTreeBranch)); - } - - [Test] - public void Test_Status_Messages() - { - byte[] data = { - 0x02 - }; - - var parameterBag = new ParameterBag(ERDM_Parameter.STATUS_MESSAGES); - var define = MetadataFactory.GetDefine(parameterBag); - - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetRequest, data); - - Assert.Multiple(() => - { - Assert.That(dataTreeBranch.IsUnset, Is.False); - Assert.That(dataTreeBranch.IsEmpty, Is.False); - Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); - Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_Status))); - - var obj = (ERDM_Status)dataTreeBranch.ParsedObject; - Assert.That(obj, Is.EqualTo(ERDM_Status.ADVISORY)); - }); - - var reversed = DataTreeBranch.FromObject(dataTreeBranch.ParsedObject, null, ERDM_Command.GET_COMMAND, ERDM_Parameter.STATUS_MESSAGES); - Assert.That(reversed, Is.EqualTo(dataTreeBranch)); - } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/TestMetadataFactoryStuff.cs b/RDMSharpTests/Metadata/TestMetadataFactoryStuff.cs index d54e3a58..0e95d9ca 100644 --- a/RDMSharpTests/Metadata/TestMetadataFactoryStuff.cs +++ b/RDMSharpTests/Metadata/TestMetadataFactoryStuff.cs @@ -1,85 +1,84 @@ using RDMSharp.Metadata; -namespace RDMSharpTests.Metadata +namespace RDMSharpTests.Metadata; + +public class TestMetadataFactoryStuff { - public class TestMetadataFactoryStuff + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - Console.OutputEncoding = System.Text.Encoding.Unicode; - } - [TearDown] - public void Teardown() - { - Console.OutputEncoding = System.Text.Encoding.Default; - } + Console.OutputEncoding = System.Text.Encoding.Unicode; + } + [TearDown] + public void Teardown() + { + Console.OutputEncoding = System.Text.Encoding.Default; + } - //[Test] - //public void TestMetadataFactory() - //{ - // var schemas = MetadataFactory.GetMetadataSchemaVersions(); - // Assert.That(schemas, Has.Count.EqualTo(1)); - // var defines = MetadataFactory.GetMetadataDefineVersions(); - // Assert.That(defines, Has.Count.EqualTo(122)); - // foreach (var define in defines) - // testString(define.ToString()); - //} - [Test] - public void TestMetadataFactoryESTAParameterHaseDefine() + //[Test] + //public void TestMetadataFactory() + //{ + // var schemas = MetadataFactory.GetMetadataSchemaVersions(); + // Assert.That(schemas, Has.Count.EqualTo(1)); + // var defines = MetadataFactory.GetMetadataDefineVersions(); + // Assert.That(defines, Has.Count.EqualTo(122)); + // foreach (var define in defines) + // testString(define.ToString()); + //} + [Test] + public void TestMetadataFactoryESTAParameterHaseDefine() + { + var parameters = Enum.GetValues().Where(p => (ushort)p >= 30).ToList().AsReadOnly(); + Assert.Multiple(() => { - var parameters = Enum.GetValues().Where(p => (ushort)p >= 30).ToList().AsReadOnly(); - Assert.Multiple(() => + foreach (var parameter in parameters) { - foreach (var parameter in parameters) + switch (parameter) { - switch (parameter) - { - case ERDM_Parameter.COMPONENT_SCOPE: - case ERDM_Parameter.SEARCH_DOMAIN: - case ERDM_Parameter.TCP_COMMS_STATUS: - case ERDM_Parameter.BROKER_STATUS: - Assert.Warn("Implement E1.33 Defines!!!"); - continue; - } - var define = MetadataFactory.GetDefine(new ParameterBag(parameter)); - Assert.That(define, Is.Not.Null, $"Parameter: {parameter} has no matchig Define"); + case ERDM_Parameter.COMPONENT_SCOPE: + case ERDM_Parameter.SEARCH_DOMAIN: + case ERDM_Parameter.TCP_COMMS_STATUS: + case ERDM_Parameter.BROKER_STATUS: + Assert.Warn($"Implement Parameter: {parameter}"); + continue; } - }); - } + var define = MetadataFactory.GetDefine(new ParameterBag(parameter)); + Assert.That(define, Is.Not.Null, $"Parameter: {parameter} has no matchig Define"); + } + }); + } - [Test] - public void TestMetadataVersion() + [Test] + public void TestMetadataVersion() + { + var mv = new MetadataVersion("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.json", typeof(MetadataFactory).Assembly); + testString(mv.ToString()); + Assert.Multiple(() => { - var mv = new MetadataVersion("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.json", typeof(MetadataFactory).Assembly); - testString(mv.ToString()); - Assert.Multiple(() => - { - Assert.Throws(typeof(ArgumentNullException), () => MetadataVersion.getVersion(null)); - Assert.Throws(typeof(ArgumentNullException), () => MetadataVersion.getName(null)); - Assert.Throws(typeof(ArgumentNullException), () => MetadataVersion.getIsSchema(null)); + Assert.Throws(typeof(ArgumentNullException), () => MetadataVersion.getVersion(null)); + Assert.Throws(typeof(ArgumentNullException), () => MetadataVersion.getName(null)); + Assert.Throws(typeof(ArgumentNullException), () => MetadataVersion.getIsSchema(null)); - Assert.Throws(typeof(FormatException), () => MetadataVersion.getVersion("RDMSharp.Resources.JSON_Defines.1.0.0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.json")); - Assert.Throws(typeof(FormatException), () => MetadataVersion.getVersion("RDMSharp.Resources.JSON_Defines._1._X._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.json")); - Assert.Throws(typeof(ArgumentException), () => MetadataVersion.getVersion("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.jsan")); - Assert.Throws(typeof(FormatException), () => MetadataVersion.getName("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.jsan")); - Assert.Throws(typeof(ArgumentException), () => MetadataVersion.getIsSchema("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.jsan")); - }); - } + Assert.Throws(typeof(FormatException), () => MetadataVersion.getVersion("RDMSharp.Resources.JSON_Defines.1.0.0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.json")); + Assert.Throws(typeof(FormatException), () => MetadataVersion.getVersion("RDMSharp.Resources.JSON_Defines._1._X._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.json")); + Assert.Throws(typeof(ArgumentException), () => MetadataVersion.getVersion("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.jsan")); + Assert.Throws(typeof(FormatException), () => MetadataVersion.getName("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.jsan")); + Assert.Throws(typeof(ArgumentException), () => MetadataVersion.getIsSchema("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.jsan")); + }); + } - [Test] - public void TestMetadataBag() - { - var bag = new MetadataBag("1.0.2", "NAME.json", false, "content", "Path"); - testString(bag.ToString()); - Assert.Throws(typeof(ArgumentNullException), () => MetadataBag.getContent(null, typeof(MetadataFactory).Assembly)); - } - static void testString(string str) - { - Assert.That(str, Is.Not.WhiteSpace); - Assert.That(str, Is.Not.Empty); - Assert.That(str, Does.Not.Contain("{")); - Assert.That(str, Does.Not.Contain("}")); - } + [Test] + public void TestMetadataBag() + { + var bag = new MetadataBag("1.0.2", "NAME.json", false, "content", "Path"); + testString(bag.ToString()); + Assert.Throws(typeof(ArgumentNullException), () => MetadataBag.getContent(null, typeof(MetadataFactory).Assembly)); + } + static void testString(string str) + { + Assert.That(str, Is.Not.WhiteSpace); + Assert.That(str, Is.Not.Empty); + Assert.That(str, Does.Not.Contain("{")); + Assert.That(str, Does.Not.Contain("}")); } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs b/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs index 9f9cddb5..0003c4ff 100644 --- a/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs +++ b/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs @@ -1,293 +1,303 @@ using RDMSharp.Metadata; +using RDMSharp.PayloadObject; -namespace RDMSharpTests.Metadata +namespace RDMSharpTests.Metadata; + +public class TestPeerToPeerProcess { - public class TestPeerToPeerProcess + + [Test, MaxTime(6000)] + public async Task Test_Get_DMX_START_ADDRESS() { + var command = ERDM_Command.GET_COMMAND; + var uid = new UID(1234, 123456); + var subdevice = SubDevice.Root; + var parameterBag = new ParameterBag(ERDM_Parameter.DMX_START_ADDRESS); + const ushort DMX_ADDRESS = 33; + PeerToPeerProcess peerToPeerProcess = new PeerToPeerProcess(command, uid, subdevice, parameterBag); + + Assert.That(peerToPeerProcess.Define, Is.Not.Null); + Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); + Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); + Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); + + AsyncRDMRequestHelper? helper = null; + helper = new AsyncRDMRequestHelper(sendMessage); + + try + { + await peerToPeerProcess.Run(helper); - [Test, MaxTime(6000)] - public async Task Test_Get_DMX_START_ADDRESS() + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTreeBranch))); + Assert.That(peerToPeerProcess.ResponsePayloadObject.Children[0].Value, Is.EqualTo(DMX_ADDRESS)); + Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.EqualTo(DMX_ADDRESS)); + Assert.That(peerToPeerProcess.Exception, Is.Null); + } + finally { - var command = ERDM_Command.GET_COMMAND; - var uid = new UID(1234, 123456); - var subdevice = SubDevice.Root; - var parameterBag = new ParameterBag(ERDM_Parameter.DMX_START_ADDRESS); - const ushort DMX_ADDRESS = 33; - PeerToPeerProcess peerToPeerProcess = new PeerToPeerProcess(command, uid, subdevice, parameterBag); - - Assert.That(peerToPeerProcess.Define, Is.Not.Null); - Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); - Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); - Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); - - AsyncRDMRequestHelper? helper = null; - helper = new AsyncRDMRequestHelper(sendMessage); + helper?.Dispose(); + helper = null; + } - try - { - await peerToPeerProcess.Run(helper); - - Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTreeBranch))); - Assert.That(peerToPeerProcess.ResponsePayloadObject.Children[0].Value, Is.EqualTo(DMX_ADDRESS)); - Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.EqualTo(DMX_ADDRESS)); - Assert.That(peerToPeerProcess.Exception, Is.Null); - } - finally - { - helper?.Dispose(); - helper = null; - } + async Task sendMessage(RDMMessage message) + { + Assert.That(message.Command, Is.EqualTo(command)); + Assert.That(message.DestUID, Is.EqualTo(uid)); + Assert.That(message.SubDevice, Is.EqualTo(subdevice)); + Assert.That(message.Parameter, Is.EqualTo(parameterBag.PID)); - async Task sendMessage(RDMMessage message) + RDMMessage response = new RDMMessage() { - Assert.That(message.Command, Is.EqualTo(command)); - Assert.That(message.DestUID, Is.EqualTo(uid)); - Assert.That(message.SubDevice, Is.EqualTo(subdevice)); - Assert.That(message.Parameter, Is.EqualTo(parameterBag.PID)); - - RDMMessage response = new RDMMessage() - { - Command = message.Command | ERDM_Command.RESPONSE, - DestUID = message.SourceUID, - SourceUID = message.DestUID, - Parameter = message.Parameter, - SubDevice = message.SubDevice, - TransactionCounter = message.TransactionCounter, - ParameterData = MetadataFactory.GetResponseMessageData(parameterBag, new DataTreeBranch(new DataTree[] { new DataTree("dmx_address", 0, DMX_ADDRESS) })).First() - }; + Command = message.Command | ERDM_Command.RESPONSE, + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + SubDevice = message.SubDevice, + TransactionCounter = message.TransactionCounter, + ParameterData = MetadataFactory.GetResponseMessageData(parameterBag, new DataTreeBranch(new DataTree[] { new DataTree("dmx_address", 0, DMX_ADDRESS) })).First() + }; - await Task.Delay(10); - helper?.ReceiveMessage(response); - } + await Task.Delay(10); + helper?.ReceiveMessage(response); } + } - [Test, MaxTime(6000)] - public async Task Test_Get_PROXIED_DEVICES() + [Test, MaxTime(6000)] + public async Task Test_Get_PROXIED_DEVICES() + { + var command = ERDM_Command.GET_COMMAND; + var uid = new UID(1234, 123456); + var subdevice = SubDevice.Root; + var parameterBag = new ParameterBag(ERDM_Parameter.PROXIED_DEVICES); + DataTree[] children = new DataTree[500]; + Random rnd = new Random(); + for (int i = 0; i < children.Length; i++) + children[i] = new DataTree("device_uid", (uint)i, new UID(0x1234, (uint)rnd.Next(1, int.MaxValue))); + + PeerToPeerProcess peerToPeerProcess = new PeerToPeerProcess(command, uid, subdevice, parameterBag); + + Assert.That(peerToPeerProcess.Define, Is.Not.Null); + Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); + Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); + Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); + Assert.That(peerToPeerProcess.Exception, Is.Null); + + AsyncRDMRequestHelper? helper = null; + byte[] parameterData = MetadataFactory.GetResponseMessageData(parameterBag, new DataTreeBranch(new DataTree[] { new DataTree("device_uids", 0, children: children) })).SelectMany(en => en).ToArray(); + helper = new AsyncRDMRequestHelper(sendMessage); + + try { - var command = ERDM_Command.GET_COMMAND; - var uid = new UID(1234, 123456); - var subdevice = SubDevice.Root; - var parameterBag = new ParameterBag(ERDM_Parameter.PROXIED_DEVICES); - DataTree[] children = new DataTree[500]; - Random rnd = new Random(); - for (int i = 0; i < children.Length; i++) - children[i] = new DataTree("device_uid", (uint)i, new UID(0x1234, (uint)rnd.Next(1, int.MaxValue))); - - PeerToPeerProcess peerToPeerProcess = new PeerToPeerProcess(command, uid, subdevice, parameterBag); - - Assert.That(peerToPeerProcess.Define, Is.Not.Null); - Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); - Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); - Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); - Assert.That(peerToPeerProcess.Exception, Is.Null); + await peerToPeerProcess.Run(helper); - AsyncRDMRequestHelper? helper = null; - byte[] parameterData = MetadataFactory.GetResponseMessageData(parameterBag, new DataTreeBranch(new DataTree[] { new DataTree("device_uids", 0, children: children) })).SelectMany(en=>en).ToArray(); - helper = new AsyncRDMRequestHelper(sendMessage); + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTreeBranch))); + Assert.That(peerToPeerProcess.ResponsePayloadObject.Children[0].Children, Is.EqualTo(children)); + Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.EqualTo(new RDMProxiedDevices(children.Select(dt => (UID)dt.Value!).ToArray()))); + } + finally + { + helper?.Dispose(); + helper = null; + } - try + async Task sendMessage(RDMMessage message) + { + Assert.That(message.Command, Is.EqualTo(command)); + Assert.That(message.DestUID, Is.EqualTo(uid)); + Assert.That(message.SubDevice, Is.EqualTo(subdevice)); + Assert.That(message.Parameter, Is.EqualTo(parameterBag.PID)); + + var count = Math.Min(parameterData.Length, 0xE4); + var _parameterData = parameterData.Take(count).ToArray(); + parameterData = parameterData.Skip(count).ToArray(); + RDMMessage response = new RDMMessage() { - await peerToPeerProcess.Run(helper); + Command = message.Command | ERDM_Command.RESPONSE, + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + SubDevice = message.SubDevice, + TransactionCounter = message.TransactionCounter, + ParameterData = _parameterData, + PortID_or_Responsetype = parameterData.Length == 0 ? (byte)ERDM_ResponseType.ACK : (byte)ERDM_ResponseType.ACK_OVERFLOW + }; - Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTreeBranch))); - Assert.That(peerToPeerProcess.ResponsePayloadObject.Children[0].Children, Is.EqualTo(children)); - Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.EqualTo(children.Select(dt => dt.Value).ToList())); - } - finally - { - helper?.Dispose(); - helper = null; - } + await Task.Delay(10); + helper?.ReceiveMessage(response); + } + } + [Test, MaxTime(6000)] + public async Task Test_Get_LAMP_STRIKES() + { + var command = ERDM_Command.GET_COMMAND; + var uid = new UID(1234, 123456); + var subdevice = SubDevice.Root; + var parameterBag = new ParameterBag(ERDM_Parameter.LAMP_STRIKES); + const uint LAMP_STRIKES = 33; + PeerToPeerProcess peerToPeerProcess = new PeerToPeerProcess(command, uid, subdevice, parameterBag); + + Assert.That(peerToPeerProcess.Define, Is.Not.Null); + Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); + Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); + Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); + Assert.That(peerToPeerProcess.Exception, Is.Null); + + AsyncRDMRequestHelper? helper = null; + byte count = 0; + + try + { + helper = new AsyncRDMRequestHelper(sendMessage); - async Task sendMessage(RDMMessage message) - { - Assert.That(message.Command, Is.EqualTo(command)); - Assert.That(message.DestUID, Is.EqualTo(uid)); - Assert.That(message.SubDevice, Is.EqualTo(subdevice)); - Assert.That(message.Parameter, Is.EqualTo(parameterBag.PID)); + await peerToPeerProcess.Run(helper); - var count = Math.Min(parameterData.Length, 0xE4); - var _parameterData = parameterData.Take(count).ToArray(); - parameterData= parameterData.Skip(count).ToArray(); - RDMMessage response = new RDMMessage() + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTreeBranch))); + Assert.That(peerToPeerProcess.ResponsePayloadObject.Children[0].Value, Is.EqualTo(LAMP_STRIKES)); + Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.EqualTo(LAMP_STRIKES)); + Assert.That(peerToPeerProcess.Exception, Is.Null); + } + finally + { + helper?.Dispose(); + helper = null; + } + async Task sendMessage(RDMMessage message) + { + Assert.That(count, Is.LessThan(2)); + if (count == 0) + Assert.That(message.Parameter, Is.EqualTo(parameterBag.PID)); + else if (count == 1) + Assert.That(message.Parameter, Is.EqualTo(ERDM_Parameter.QUEUED_MESSAGE)); + Assert.That(message.Command, Is.EqualTo(command)); + Assert.That(message.DestUID, Is.EqualTo(uid)); + Assert.That(message.SubDevice, Is.EqualTo(subdevice)); + + RDMMessage response = count == 0 ? + new RDMMessage(new AcknowledgeTimer(TimeSpan.FromSeconds(3))) { Command = message.Command | ERDM_Command.RESPONSE, DestUID = message.SourceUID, SourceUID = message.DestUID, - Parameter = message.Parameter, + Parameter = parameterBag.PID, SubDevice = message.SubDevice, TransactionCounter = message.TransactionCounter, - ParameterData = _parameterData, - PortID_or_Responsetype = parameterData.Length == 0 ? (byte)ERDM_ResponseType.ACK : (byte)ERDM_ResponseType.ACK_OVERFLOW - }; + } : + new RDMMessage() + { + Command = message.Command | ERDM_Command.RESPONSE, + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = parameterBag.PID, + SubDevice = message.SubDevice, + TransactionCounter = message.TransactionCounter, + ParameterData = MetadataFactory.GetResponseMessageData(parameterBag, new DataTreeBranch(new DataTree[] { new DataTree("strikes", 0, LAMP_STRIKES) })).First(), + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK + }; - await Task.Delay(10); - helper?.ReceiveMessage(response); - } + await Task.Delay(10); + count++; + helper?.ReceiveMessage(response); } - [Test, MaxTime(6000)] - public async Task Test_Get_LAMP_STRIKES() + } + [Test, MaxTime(6000)] + public async Task Test_Get_SLOT_INFO() + { + var command = ERDM_Command.GET_COMMAND; + var uid = new UID(1234, 123456); + var subdevice = SubDevice.Root; + var parameterBag = new ParameterBag(ERDM_Parameter.SLOT_INFO); + byte[] SLOT_INFO_1 = new byte[] { + 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, 0x00, + 0x03, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x05, + 0x03, 0x00, 0x05, 0x00, 0x05, 0x02, 0x00, 0x06, + 0x00, 0x91, 0x00, 0x00, 0x07, 0x00, 0x91, 0x01, + 0x00, 0x08, 0x00, 0x05, 0x02, 0x00, 0x09, 0x00, + 0x02, 0x01, 0x00, 0x0a, 0x01, 0x00, 0x09, 0x00, + 0x0b, 0x00, 0x02, 0x01, 0x00, 0x0c, 0x01, 0x00, + 0x0b, 0x00, 0x0d, 0x00, 0x02, 0x02, 0x00, 0x0e, + 0x00, 0x02, 0x04, 0x00, 0x0f, 0x00, 0x02, 0x03, + 0x00, 0x10, 0x00, 0x02, 0x08, 0x00, 0x11, 0x00, + 0x02, 0x08, 0x00, 0x12, 0x00, 0x05, 0x04, 0x00, + 0x13, 0x00, 0x05, 0x03, 0x00, 0x14, 0x00, 0xff, + 0xff, 0x00, 0x15, 0x00, 0xff, 0xff, 0x00, 0x16, + 0x00, 0x03, 0x04, 0x00, 0x17, 0x06, 0x00, 0x16, + 0x00, 0x18, 0x04, 0x00, 0x17 + }; + byte[] SLOT_INFO_2 = new byte[] { + 0x00, 0x19, 0x00, 0x03, 0x02, 0x00, 0x1a, 0x07, + 0x00, 0x19, 0x00, 0x1b, 0x01, 0x00, 0x1a, 0x00, + 0x1c, 0x00, 0x03, 0x02, 0x00, 0x1d, 0x07, 0x00, + 0x1c, 0x00, 0x1e, 0x01, 0x00, 0x1d, 0x00, 0x1f, + 0x00, 0x03, 0x03, 0x00, 0x20, 0x06, 0x00, 0x1f, + 0x00, 0x21, 0x00, 0x03, 0x03, 0x00, 0x22, 0x06, + 0x00, 0x21, 0x00, 0x23, 0x00, 0x04, 0x03, 0x00, + 0x24, 0x00, 0x04, 0x01, 0x00, 0x25, 0x01, 0x00, + 0x24, 0x00, 0x26, 0x00, 0x04, 0x05, 0x00, 0x27, + 0x01, 0x00, 0x26, 0x00, 0x28, 0x00, 0x04, 0x02, + 0x00, 0x29, 0x01, 0x00, 0x28, 0x00, 0x2a, 0x00, + 0x04, 0x06, 0x00, 0x2b, 0x00, 0x04, 0x06, 0x00, + 0x2c, 0x06, 0x00, 0x2b, 0x00, 0x2d, 0x00, 0x04, + 0x06, 0x00, 0x2e, 0x06, 0x00, 0x2d, 0x00, 0x2f, + 0x00, 0x04, 0x06, 0x00, 0x30, 0x06, 0x00, 0x2f, + 0x00, 0x31, 0x00, 0x04, 0x06, 0x00, 0x32, 0x06, + 0x00, 0x31, 0x00, 0x33, 0x00, 0x04, 0x04, 0x00, + 0x34, 0x00, 0x00, 0x02, 0x00, 0x35, 0x01, 0x00, + 0x34 + }; + PeerToPeerProcess peerToPeerProcess = new PeerToPeerProcess(command, uid, subdevice, parameterBag); + + Assert.That(peerToPeerProcess.Define, Is.Not.Null); + Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); + Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); + Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); + Assert.That(peerToPeerProcess.Exception, Is.Null); + + AsyncRDMRequestHelper? helper = null; + byte count = 0; + + try { - var command = ERDM_Command.GET_COMMAND; - var uid = new UID(1234, 123456); - var subdevice = SubDevice.Root; - var parameterBag = new ParameterBag(ERDM_Parameter.LAMP_STRIKES); - const uint LAMP_STRIKES = 33; - PeerToPeerProcess peerToPeerProcess = new PeerToPeerProcess(command, uid, subdevice, parameterBag); - - Assert.That(peerToPeerProcess.Define, Is.Not.Null); - Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); - Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); - Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); - Assert.That(peerToPeerProcess.Exception, Is.Null); - - AsyncRDMRequestHelper? helper = null; - byte count = 0; - - try - { - helper = new AsyncRDMRequestHelper(sendMessage); + helper = new AsyncRDMRequestHelper(sendMessage); - await peerToPeerProcess.Run(helper); + await peerToPeerProcess.Run(helper); - Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTreeBranch))); - Assert.That(peerToPeerProcess.ResponsePayloadObject.Children[0].Value, Is.EqualTo(LAMP_STRIKES)); - Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.EqualTo(LAMP_STRIKES)); - Assert.That(peerToPeerProcess.Exception, Is.Null); - } - finally - { - helper?.Dispose(); - helper = null; - } - async Task sendMessage(RDMMessage message) - { - Assert.That(count, Is.LessThan(2)); - if(count==0) - Assert.That(message.Parameter, Is.EqualTo(parameterBag.PID)); - else if(count==1) - Assert.That(message.Parameter, Is.EqualTo(ERDM_Parameter.QUEUED_MESSAGE)); - Assert.That(message.Command, Is.EqualTo(command)); - Assert.That(message.DestUID, Is.EqualTo(uid)); - Assert.That(message.SubDevice, Is.EqualTo(subdevice)); - - RDMMessage response = new RDMMessage() - { - Command = message.Command | ERDM_Command.RESPONSE, - DestUID = message.SourceUID, - SourceUID = message.DestUID, - Parameter = parameterBag.PID, - SubDevice = message.SubDevice, - TransactionCounter= message.TransactionCounter, - ParameterData = count == 0 ? new AcknowledgeTimer(TimeSpan.FromSeconds(3)).ToPayloadData() : MetadataFactory.GetResponseMessageData(parameterBag, new DataTreeBranch(new DataTree[] { new DataTree("strikes", 0, LAMP_STRIKES) })).First(), - PortID_or_Responsetype = count == 0 ? (byte)ERDM_ResponseType.ACK_TIMER : (byte)ERDM_ResponseType.ACK - }; - - await Task.Delay(10); - count++; - helper?.ReceiveMessage(response); - } + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTreeBranch))); + Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.Not.Null); + Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.TypeOf(typeof(RDMSlotInfo[]))); + RDMSlotInfo[] slotInfos = (RDMSlotInfo[])peerToPeerProcess.ResponsePayloadObject.ParsedObject; + Assert.That(slotInfos, Has.Length.EqualTo(54)); + Assert.That(peerToPeerProcess.Exception, Is.Null); } - [Test, MaxTime(6000)] - public async Task Test_Get_SLOT_INFO() + finally { - var command = ERDM_Command.GET_COMMAND; - var uid = new UID(1234, 123456); - var subdevice = SubDevice.Root; - var parameterBag = new ParameterBag(ERDM_Parameter.SLOT_INFO); - byte[] SLOT_INFO_1 = new byte[] { - 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, 0x00, - 0x03, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x05, - 0x03, 0x00, 0x05, 0x00, 0x05, 0x02, 0x00, 0x06, - 0x00, 0x91, 0x00, 0x00, 0x07, 0x00, 0x91, 0x01, - 0x00, 0x08, 0x00, 0x05, 0x02, 0x00, 0x09, 0x00, - 0x02, 0x01, 0x00, 0x0a, 0x01, 0x00, 0x09, 0x00, - 0x0b, 0x00, 0x02, 0x01, 0x00, 0x0c, 0x01, 0x00, - 0x0b, 0x00, 0x0d, 0x00, 0x02, 0x02, 0x00, 0x0e, - 0x00, 0x02, 0x04, 0x00, 0x0f, 0x00, 0x02, 0x03, - 0x00, 0x10, 0x00, 0x02, 0x08, 0x00, 0x11, 0x00, - 0x02, 0x08, 0x00, 0x12, 0x00, 0x05, 0x04, 0x00, - 0x13, 0x00, 0x05, 0x03, 0x00, 0x14, 0x00, 0xff, - 0xff, 0x00, 0x15, 0x00, 0xff, 0xff, 0x00, 0x16, - 0x00, 0x03, 0x04, 0x00, 0x17, 0x06, 0x00, 0x16, - 0x00, 0x18, 0x04, 0x00, 0x17 - }; - byte[] SLOT_INFO_2 = new byte[] { - 0x00, 0x19, 0x00, 0x03, 0x02, 0x00, 0x1a, 0x07, - 0x00, 0x19, 0x00, 0x1b, 0x01, 0x00, 0x1a, 0x00, - 0x1c, 0x00, 0x03, 0x02, 0x00, 0x1d, 0x07, 0x00, - 0x1c, 0x00, 0x1e, 0x01, 0x00, 0x1d, 0x00, 0x1f, - 0x00, 0x03, 0x03, 0x00, 0x20, 0x06, 0x00, 0x1f, - 0x00, 0x21, 0x00, 0x03, 0x03, 0x00, 0x22, 0x06, - 0x00, 0x21, 0x00, 0x23, 0x00, 0x04, 0x03, 0x00, - 0x24, 0x00, 0x04, 0x01, 0x00, 0x25, 0x01, 0x00, - 0x24, 0x00, 0x26, 0x00, 0x04, 0x05, 0x00, 0x27, - 0x01, 0x00, 0x26, 0x00, 0x28, 0x00, 0x04, 0x02, - 0x00, 0x29, 0x01, 0x00, 0x28, 0x00, 0x2a, 0x00, - 0x04, 0x06, 0x00, 0x2b, 0x00, 0x04, 0x06, 0x00, - 0x2c, 0x06, 0x00, 0x2b, 0x00, 0x2d, 0x00, 0x04, - 0x06, 0x00, 0x2e, 0x06, 0x00, 0x2d, 0x00, 0x2f, - 0x00, 0x04, 0x06, 0x00, 0x30, 0x06, 0x00, 0x2f, - 0x00, 0x31, 0x00, 0x04, 0x06, 0x00, 0x32, 0x06, - 0x00, 0x31, 0x00, 0x33, 0x00, 0x04, 0x04, 0x00, - 0x34, 0x00, 0x00, 0x02, 0x00, 0x35, 0x01, 0x00, - 0x34 - }; - PeerToPeerProcess peerToPeerProcess = new PeerToPeerProcess(command, uid, subdevice, parameterBag); - - Assert.That(peerToPeerProcess.Define, Is.Not.Null); - Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); - Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); - Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); - Assert.That(peerToPeerProcess.Exception, Is.Null); + helper?.Dispose(); + helper = null; + } + async Task sendMessage(RDMMessage message) + { + Assert.That(count, Is.LessThan(2)); - AsyncRDMRequestHelper? helper = null; - byte count = 0; + Assert.That(message.Command, Is.EqualTo(command)); + Assert.That(message.DestUID, Is.EqualTo(uid)); + Assert.That(message.SubDevice, Is.EqualTo(subdevice)); - try - { - helper = new AsyncRDMRequestHelper(sendMessage); - - await peerToPeerProcess.Run(helper); - - Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTreeBranch))); - Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.Not.Null); - Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.TypeOf(typeof(RDMSlotInfo[]))); - RDMSlotInfo[] slotInfos = (RDMSlotInfo[])peerToPeerProcess.ResponsePayloadObject.ParsedObject; - Assert.That(slotInfos, Has.Length.EqualTo(54)); - Assert.That(peerToPeerProcess.Exception, Is.Null); - } - finally - { - helper?.Dispose(); - helper = null; - } - async Task sendMessage(RDMMessage message) + RDMMessage response = new RDMMessage() { - Assert.That(count, Is.LessThan(2)); - - Assert.That(message.Command, Is.EqualTo(command)); - Assert.That(message.DestUID, Is.EqualTo(uid)); - Assert.That(message.SubDevice, Is.EqualTo(subdevice)); + Command = message.Command | ERDM_Command.RESPONSE, + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = parameterBag.PID, + SubDevice = message.SubDevice, + TransactionCounter = message.TransactionCounter, + ParameterData = count % 2 == 0 ? SLOT_INFO_1 : SLOT_INFO_2, + PortID_or_Responsetype = count % 2 == 0 ? (byte)ERDM_ResponseType.ACK_OVERFLOW : (byte)ERDM_ResponseType.ACK + }; - RDMMessage response = new RDMMessage() - { - Command = message.Command | ERDM_Command.RESPONSE, - DestUID = message.SourceUID, - SourceUID = message.DestUID, - Parameter = parameterBag.PID, - SubDevice = message.SubDevice, - TransactionCounter = message.TransactionCounter, - ParameterData = count % 2 == 0 ? SLOT_INFO_1 : SLOT_INFO_2, - PortID_or_Responsetype = count % 2 == 0 ? (byte)ERDM_ResponseType.ACK_OVERFLOW : (byte)ERDM_ResponseType.ACK - }; - - await Task.Delay(10); - count++; - helper?.ReceiveMessage(response); - } + await Task.Delay(10); + count++; + helper?.ReceiveMessage(response); } } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/AcknowledgeTimerTest.cs b/RDMSharpTests/RDM/PayloadObject/AcknowledgeTimerTest.cs index 49b5edeb..dcc459de 100644 --- a/RDMSharpTests/RDM/PayloadObject/AcknowledgeTimerTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/AcknowledgeTimerTest.cs @@ -1,43 +1,42 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class AcknowledgeTimerTest { - public class AcknowledgeTimerTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - var time = TimeSpan.FromSeconds(3); - AcknowledgeTimer acknowledgeTimer = new AcknowledgeTimer(time); - byte[] data = acknowledgeTimer.ToPayloadData(); + [Test] + public void ToPayloadAndFromMessageTest() + { + var time = TimeSpan.FromSeconds(3); + AcknowledgeTimer acknowledgeTimer = new AcknowledgeTimer(time); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK_TIMER, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.LAMP_STRIKES, - ParameterData = data, - }; + RDMMessage message = new RDMMessage(acknowledgeTimer) + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK_TIMER, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.LAMP_STRIKES, + }; - AcknowledgeTimer resultAcknowledgeTimer = AcknowledgeTimer.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { AcknowledgeTimer.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + AcknowledgeTimer resultAcknowledgeTimer = AcknowledgeTimer.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { AcknowledgeTimer.FromPayloadData(new byte[2].ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultAcknowledgeTimer, Is.EqualTo(acknowledgeTimer)); - Assert.That(resultAcknowledgeTimer.EstimidatedResponseTime, Is.EqualTo(time)); + Assert.That(resultAcknowledgeTimer, Is.EqualTo(acknowledgeTimer)); + Assert.That(resultAcknowledgeTimer.EstimidatedResponseTime, Is.EqualTo(time)); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new AcknowledgeTimer(TimeSpan.FromSeconds(3600000)); }); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new AcknowledgeTimer(TimeSpan.FromSeconds(3600000)); }); - var res = resultAcknowledgeTimer.ToString(); - var src = acknowledgeTimer.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - Assert.That(res, Is.EqualTo(src)); - }); - } + var res = resultAcknowledgeTimer.ToString(); + var src = acknowledgeTimer.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + Assert.That(res, Is.EqualTo(src)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/DiscMuteUnmuteResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/DiscMuteUnmuteResponseTest.cs index f15f78c7..39036e20 100644 --- a/RDMSharpTests/RDM/PayloadObject/DiscMuteUnmuteResponseTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/DiscMuteUnmuteResponseTest.cs @@ -1,115 +1,116 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class DiscMuteUnmuteResponseTest { - public class DiscMuteUnmuteResponseTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() + } + + [Test] + public void ToPayloadAndFromMessageTest() + { + DiscMuteUnmuteResponse discMute = new DiscMuteUnmuteResponse(true, bindingUID: new UID(223, 434)); + + byte[] data = discMute.ToPayloadData(); + + RDMMessage message = new RDMMessage() { - } + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.DISC_MUTE, + ParameterData = data, + }; - [Test] - public void ToPayloadAndFromMessageTest() + DiscMuteUnmuteResponse resultDiscMute = DiscMuteUnmuteResponse.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { DiscMuteUnmuteResponse.FromPayloadData(data.ToList().Concat(new byte[2]).ToArray()); }); + + Assert.That(resultDiscMute, Is.EqualTo(discMute)); + + var res = resultDiscMute.ToString(); + var src = discMute.ToString(); + Assert.Multiple(() => { - DiscMuteUnmuteResponse discMute = new DiscMuteUnmuteResponse(true, bindingUID: new UID(223, 434)); - - byte[] data = discMute.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DISC_MUTE, - ParameterData = data, - }; - - DiscMuteUnmuteResponse resultDiscMute = DiscMuteUnmuteResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { DiscMuteUnmuteResponse.FromPayloadData(data.ToList().Concat(new byte[2]).ToArray()); }); - - Assert.That(resultDiscMute, Is.EqualTo(discMute)); - - var res = resultDiscMute.ToString(); - var src = discMute.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - Assert.That(res, Is.EqualTo(src)); - }); - - discMute = new DiscMuteUnmuteResponse(false, true, bindingUID: new UID(223, 434)); - - data = discMute.ToPayloadData(); - - message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DISC_UN_MUTE, - ParameterData = data, - }; - - resultDiscMute = DiscMuteUnmuteResponse.FromMessage(message); - - Assert.That(resultDiscMute, Is.EqualTo(discMute)); - - res = resultDiscMute.ToString(); - src = discMute.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - Assert.That(res, Is.EqualTo(src)); - }); - - discMute = new DiscMuteUnmuteResponse(false, false, true, bindingUID: new UID(223, 434)); - - data = discMute.ToPayloadData(); - - message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DISC_UN_MUTE, - ParameterData = data, - }; - - resultDiscMute = DiscMuteUnmuteResponse.FromMessage(message); - - Assert.That(resultDiscMute, Is.EqualTo(discMute)); - - res = resultDiscMute.ToString(); - src = discMute.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); Assert.That(res, Is.EqualTo(src)); + }); - discMute = new DiscMuteUnmuteResponse(false, false, false, true); + discMute = new DiscMuteUnmuteResponse(false, true, bindingUID: new UID(223, 434)); - data = discMute.ToPayloadData(); + data = discMute.ToPayloadData(); - message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DISC_UN_MUTE, - ParameterData = data, - }; + message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.DISC_UN_MUTE, + ParameterData = data, + }; - resultDiscMute = DiscMuteUnmuteResponse.FromMessage(message); + resultDiscMute = DiscMuteUnmuteResponse.FromMessage(message); - Assert.That(resultDiscMute, Is.EqualTo(discMute)); + Assert.That(resultDiscMute, Is.EqualTo(discMute)); - res = resultDiscMute.ToString(); - src = discMute.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); + res = resultDiscMute.ToString(); + src = discMute.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); Assert.That(res, Is.EqualTo(src)); - } + }); + + discMute = new DiscMuteUnmuteResponse(false, false, true, bindingUID: new UID(223, 434)); + + data = discMute.ToPayloadData(); + + message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.DISC_UN_MUTE, + ParameterData = data, + }; + + resultDiscMute = DiscMuteUnmuteResponse.FromMessage(message); + + Assert.That(resultDiscMute, Is.EqualTo(discMute)); + + res = resultDiscMute.ToString(); + src = discMute.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); + + discMute = new DiscMuteUnmuteResponse(false, false, false, true); + + data = discMute.ToPayloadData(); + + message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.DISCOVERY_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.DISC_UN_MUTE, + ParameterData = data, + }; + + resultDiscMute = DiscMuteUnmuteResponse.FromMessage(message); + + Assert.That(resultDiscMute, Is.EqualTo(discMute)); + + res = resultDiscMute.ToString(); + src = discMute.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/DiscUniqueBranchRequestTest.cs b/RDMSharpTests/RDM/PayloadObject/DiscUniqueBranchRequestTest.cs index 0a67b064..7e0d0d39 100644 --- a/RDMSharpTests/RDM/PayloadObject/DiscUniqueBranchRequestTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/DiscUniqueBranchRequestTest.cs @@ -1,39 +1,40 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class DiscUniqueBranchRequestTest { - public class DiscUniqueBranchRequestTest + [SetUp] + public void Setup() + { + } + + [Test] + public void ToPayloadAndFromMessageTest() { - [SetUp] - public void Setup() + DiscUniqueBranchRequest discUniqueBranch = new DiscUniqueBranchRequest(new UID(223, 434), new UID(3333, 99999)); + + byte[] data = discUniqueBranch.ToPayloadData(); + + RDMMessage message = new RDMMessage() { - } + Command = ERDM_Command.DISCOVERY_COMMAND, + Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH, + ParameterData = data, + }; + + DiscUniqueBranchRequest resultDiscMute = DiscUniqueBranchRequest.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { DiscUniqueBranchRequest.FromPayloadData(data.ToList().Concat(new byte[2]).ToArray()); }); + + Assert.That(resultDiscMute, Is.EqualTo(discUniqueBranch)); - [Test] - public void ToPayloadAndFromMessageTest() + var res = resultDiscMute.ToString(); + var src = discUniqueBranch.ToString(); + Assert.Multiple(() => { - DiscUniqueBranchRequest discUniqueBranch = new DiscUniqueBranchRequest(new UID(223, 434), new UID(3333, 99999)); - - byte[] data = discUniqueBranch.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - Command = ERDM_Command.DISCOVERY_COMMAND, - Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH, - ParameterData = data, - }; - - DiscUniqueBranchRequest resultDiscMute = DiscUniqueBranchRequest.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { DiscUniqueBranchRequest.FromPayloadData(data.ToList().Concat(new byte[2]).ToArray()); }); - - Assert.That(resultDiscMute, Is.EqualTo(discUniqueBranch)); - - var res = resultDiscMute.ToString(); - var src = discUniqueBranch.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - Assert.That(res, Is.EqualTo(src)); - }); - } + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + Assert.That(res, Is.EqualTo(src)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponseTest.cs index 0e81b94d..b4d5a312 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponseTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponseTest.cs @@ -1,53 +1,33 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetBackgroundQueuedStatusPolicyDescriptionResponseTest { - public class GetBackgroundQueuedStatusPolicyDescriptionResponseTest + [Test] + public void InterfaceTests() { - [SetUp] - public void Setup() - { - } + GetBackgroundQueuedStatusPolicyDescriptionResponse getBackgroundQueuedStatusPolicyDescriptionResponse = new GetBackgroundQueuedStatusPolicyDescriptionResponse(1, "Pseudo Background Queued/Status Message Policy Description"); - [Test] - public void ToPayloadAndFromMessageTest() + Assert.Multiple(() => { - GetBackgroundQueuedStatusPolicyDescriptionResponse getBackgroundQueuedStatusPolicyDescriptionResponse = new GetBackgroundQueuedStatusPolicyDescriptionResponse(1, "Pseudo Background Queued/Status Message Policy Description"); - byte[] data = getBackgroundQueuedStatusPolicyDescriptionResponse.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, - ParameterData = data, - }; - - GetBackgroundQueuedStatusPolicyDescriptionResponse resultGetBackgroundQueuedStatusPolicyDescriptionResponse = GetBackgroundQueuedStatusPolicyDescriptionResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetBackgroundQueuedStatusPolicyDescriptionResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetBackgroundQueuedStatusPolicyDescriptionResponse, Is.EqualTo(getBackgroundQueuedStatusPolicyDescriptionResponse)); + Assert.That(getBackgroundQueuedStatusPolicyDescriptionResponse.Index, Is.EqualTo(1)); + Assert.That(getBackgroundQueuedStatusPolicyDescriptionResponse.MinIndex, Is.EqualTo(1)); + Assert.That(getBackgroundQueuedStatusPolicyDescriptionResponse.Description, Is.EqualTo("Pseudo Background Queued/Status ")); + }); + } + [Test] + public void DescriptionCharLimitTest() + { + GetBackgroundQueuedStatusPolicyDescriptionResponse resultGetBackgroundQueuedStatusPolicyDescriptionResponse = new GetBackgroundQueuedStatusPolicyDescriptionResponse(description: "Pseudo Background Queued/Status Message Policy Description 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.That(resultGetBackgroundQueuedStatusPolicyDescriptionResponse.Description, Has.Length.EqualTo(32)); - var res = resultGetBackgroundQueuedStatusPolicyDescriptionResponse.ToString(); - var src = getBackgroundQueuedStatusPolicyDescriptionResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - Assert.That(res, Is.EqualTo(src)); - }); - } - [Test] - public void DescriptionCharLimitTest() + resultGetBackgroundQueuedStatusPolicyDescriptionResponse = new GetBackgroundQueuedStatusPolicyDescriptionResponse(5, description: ""); + Assert.Multiple(() => { - GetBackgroundQueuedStatusPolicyDescriptionResponse resultGetBackgroundQueuedStatusPolicyDescriptionResponse = new GetBackgroundQueuedStatusPolicyDescriptionResponse(description: "Pseudo Background Queued/Status Message Policy Description 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.That(resultGetBackgroundQueuedStatusPolicyDescriptionResponse.Description, Has.Length.EqualTo(32)); - - resultGetBackgroundQueuedStatusPolicyDescriptionResponse = new GetBackgroundQueuedStatusPolicyDescriptionResponse(5, description: ""); - Assert.Multiple(() => - { - Assert.That(string.IsNullOrEmpty(resultGetBackgroundQueuedStatusPolicyDescriptionResponse.Description), Is.True); - Assert.That(resultGetBackgroundQueuedStatusPolicyDescriptionResponse.MinIndex, Is.EqualTo(1)); - Assert.That(resultGetBackgroundQueuedStatusPolicyDescriptionResponse.Index, Is.EqualTo(5)); - }); - } + Assert.That(string.IsNullOrEmpty(resultGetBackgroundQueuedStatusPolicyDescriptionResponse.Description), Is.True); + Assert.That(resultGetBackgroundQueuedStatusPolicyDescriptionResponse.MinIndex, Is.EqualTo(1)); + Assert.That(resultGetBackgroundQueuedStatusPolicyDescriptionResponse.Index, Is.EqualTo(5)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponseTest.cs index 4717b7df..83157afa 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponseTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponseTest.cs @@ -1,47 +1,23 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetBackgroundQueuedStatusPolicyResponseTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetBackgroundQueuedStatusPolicyResponse getBackgroundQueuedStatusPolicyResponse = new GetBackgroundQueuedStatusPolicyResponse(9, 123); - byte[] data = getBackgroundQueuedStatusPolicyResponse.ToPayloadData(); +using RDMSharp.PayloadObject; - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, - ParameterData = data, - }; +namespace RDMSharpTests.RDM.PayloadObject; - GetBackgroundQueuedStatusPolicyResponse resultGetBackgroundQueuedStatusPolicyResponse = GetBackgroundQueuedStatusPolicyResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetBackgroundQueuedStatusPolicyResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetBackgroundQueuedStatusPolicyResponse, Is.EqualTo(getBackgroundQueuedStatusPolicyResponse)); - Assert.Multiple(() => - { - Assert.That(resultGetBackgroundQueuedStatusPolicyResponse.IndexType, Is.EqualTo(typeof(byte))); - Assert.That(resultGetBackgroundQueuedStatusPolicyResponse.MinIndex, Is.EqualTo(1)); - Assert.That(resultGetBackgroundQueuedStatusPolicyResponse.Index, Is.EqualTo(9)); - Assert.That(resultGetBackgroundQueuedStatusPolicyResponse.Count, Is.EqualTo(123)); - Assert.That(resultGetBackgroundQueuedStatusPolicyResponse.DescriptorParameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION)); - }); +public class GetBackgroundQueuedStatusPolicyResponseTest +{ + [Test] + public void InterfaceTests() + { + GetBackgroundQueuedStatusPolicyResponse getBackgroundQueuedStatusPolicyResponse = new GetBackgroundQueuedStatusPolicyResponse(9, 123); - var res = resultGetBackgroundQueuedStatusPolicyResponse.ToString(); - var src = getBackgroundQueuedStatusPolicyResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + Assert.Multiple(() => + { + Assert.That(getBackgroundQueuedStatusPolicyResponse.Count, Is.EqualTo(123)); + Assert.That(getBackgroundQueuedStatusPolicyResponse.Policies, Is.EqualTo(123)); + Assert.That(getBackgroundQueuedStatusPolicyResponse.Index, Is.EqualTo(9)); + Assert.That(getBackgroundQueuedStatusPolicyResponse.PolicyId, Is.EqualTo(9)); + Assert.That(getBackgroundQueuedStatusPolicyResponse.MinIndex, Is.EqualTo(1)); + Assert.That(getBackgroundQueuedStatusPolicyResponse.IndexType, Is.EqualTo(typeof(byte))); + Assert.That(getBackgroundQueuedStatusPolicyResponse.DescriptorParameter, Is.EqualTo(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetBindingAndControlFieldsTest.cs b/RDMSharpTests/RDM/PayloadObject/GetBindingAndControlFieldsTest.cs deleted file mode 100644 index ea6a0c4e..00000000 --- a/RDMSharpTests/RDM/PayloadObject/GetBindingAndControlFieldsTest.cs +++ /dev/null @@ -1,63 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetBindingAndControlFieldsTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetBindingAndControlFieldsRequest getBindingAndControlFieldsRequest = new GetBindingAndControlFieldsRequest(1, new UID(1233, 4231414)); - byte[] data = getBindingAndControlFieldsRequest.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - Command = ERDM_Command.GET_COMMAND, - Parameter = ERDM_Parameter.BINDING_CONTROL_FIELDS, - ParameterData = data, - }; - - GetBindingAndControlFieldsRequest resultGetBindingAndControlFieldsRequest = GetBindingAndControlFieldsRequest.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetBindingAndControlFieldsRequest.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetBindingAndControlFieldsRequest, Is.EqualTo(getBindingAndControlFieldsRequest)); - - var res = getBindingAndControlFieldsRequest.ToString(); - var src = resultGetBindingAndControlFieldsRequest.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - - GetBindingAndControlFieldsResponse getBindingAndControlFieldsResponse = new GetBindingAndControlFieldsResponse(1, new UID(1213, 34444), 1234, new UID(542, 476436)); - data = getBindingAndControlFieldsResponse.ToPayloadData(); - - message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.BINDING_CONTROL_FIELDS, - ParameterData = data, - }; - - GetBindingAndControlFieldsResponse resultGetBindingAndControlFieldsResponse = GetBindingAndControlFieldsResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetBindingAndControlFieldsResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetBindingAndControlFieldsResponse, Is.EqualTo(getBindingAndControlFieldsResponse)); - - res = getBindingAndControlFieldsResponse.ToString(); - src = resultGetBindingAndControlFieldsResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetBrokerStatusResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetBrokerStatusResponseTest.cs index ed3837ce..3406b4da 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetBrokerStatusResponseTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetBrokerStatusResponseTest.cs @@ -1,39 +1,40 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetBrokerStatusResponseTest { - public class GetBrokerStatusResponseTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - GetBrokerStatusResponse getBrokerStatusResponse = new GetBrokerStatusResponse(true, ERDM_BrokerStatus.STANDBY); - byte[] data = getBrokerStatusResponse.ToPayloadData(); + [Test] + public void ToPayloadAndFromMessageTest() + { + GetBrokerStatusResponse getBrokerStatusResponse = new GetBrokerStatusResponse(true, ERDM_BrokerStatus.STANDBY); + byte[] data = getBrokerStatusResponse.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.BROKER_STATUS, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.BROKER_STATUS, + ParameterData = data, + }; - GetBrokerStatusResponse resultGetBrokerStatusResponse = GetBrokerStatusResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetBrokerStatusResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + GetBrokerStatusResponse resultGetBrokerStatusResponse = GetBrokerStatusResponse.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetBrokerStatusResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultGetBrokerStatusResponse, Is.EqualTo(getBrokerStatusResponse)); + Assert.That(resultGetBrokerStatusResponse, Is.EqualTo(getBrokerStatusResponse)); - var res = resultGetBrokerStatusResponse.ToString(); - var src = getBrokerStatusResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + var res = resultGetBrokerStatusResponse.ToString(); + var src = getBrokerStatusResponse.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetEndpointListResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetEndpointListResponseTest.cs deleted file mode 100644 index 46060808..00000000 --- a/RDMSharpTests/RDM/PayloadObject/GetEndpointListResponseTest.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetEndpointListResponseTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetEndpointListResponse getEndpointListResponse = new GetEndpointListResponse(0x12345678, - new EndpointDescriptor(), - new EndpointDescriptor(1, ERDM_EndpointType.PHYSICAL), - new EndpointDescriptor(1), - new EndpointDescriptor(1, ERDM_EndpointType.PHYSICAL), - new EndpointDescriptor(2), - new EndpointDescriptor(2, ERDM_EndpointType.PHYSICAL), - new EndpointDescriptor(2), - new EndpointDescriptor(3, ERDM_EndpointType.PHYSICAL), - new EndpointDescriptor(3), - new EndpointDescriptor(3, ERDM_EndpointType.PHYSICAL)); - - byte[] data = getEndpointListResponse.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.ENDPOINT_LIST, - ParameterData = data, - }; - - GetEndpointListResponse resultGetEndpointListResponse = GetEndpointListResponse.FromMessage(message); - Assert.Throws(typeof(Exception), () => { GetEndpointListResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetEndpointListResponse.FromPayloadData(data.ToList().Concat(new byte[220]).ToArray()); }); - - Assert.That(resultGetEndpointListResponse, Is.EqualTo(getEndpointListResponse)); - - var res = resultGetEndpointListResponse.ToString(); - var src = getEndpointListResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetEndpointResponderListChangeResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetEndpointResponderListChangeResponseTest.cs deleted file mode 100644 index ae57381f..00000000 --- a/RDMSharpTests/RDM/PayloadObject/GetEndpointResponderListChangeResponseTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetEndpointResponderListChangeResponseTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetEndpointResponderListChangeResponse getEndpointResponderListChangeResponse = new GetEndpointResponderListChangeResponse(1, 1234); - byte[] data = getEndpointResponderListChangeResponse.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, - ParameterData = data, - }; - - GetEndpointResponderListChangeResponse resultGetEndpointResponderListChangeResponse = GetEndpointResponderListChangeResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetEndpointResponderListChangeResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetEndpointResponderListChangeResponse, Is.EqualTo(getEndpointResponderListChangeResponse)); - - var res = resultGetEndpointResponderListChangeResponse.ToString(); - var src = getEndpointResponderListChangeResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetEndpointRespondersResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetEndpointRespondersResponseTest.cs deleted file mode 100644 index 36bd35cf..00000000 --- a/RDMSharpTests/RDM/PayloadObject/GetEndpointRespondersResponseTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetEndpointRespondersResponseTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetEndpointRespondersResponse getEndpointRespondersResponse = new GetEndpointRespondersResponse(0x12345678, - new UID(123, 34567872), - new UID(654, 26323133), - new UID(932, 14567542), - new UID(923, 79812414), - new UID(124, 29836472), - new UID(986, 79832421)); - - byte[] data = getEndpointRespondersResponse.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.ENDPOINT_RESPONDERS, - ParameterData = data, - }; - - GetEndpointRespondersResponse resultGetEndpointRespondersResponse = GetEndpointRespondersResponse.FromMessage(message); - Assert.Throws(typeof(Exception), () => { GetEndpointRespondersResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetEndpointRespondersResponse.FromPayloadData(data.ToList().Concat(new byte[220]).ToArray()); }); - - Assert.That(resultGetEndpointRespondersResponse, Is.EqualTo(getEndpointRespondersResponse)); - - var res = resultGetEndpointRespondersResponse.ToString(); - var src = getEndpointRespondersResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetEndpointTimingDescriptionResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetEndpointTimingDescriptionResponseTest.cs index 5b308a5e..d093df9d 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetEndpointTimingDescriptionResponseTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetEndpointTimingDescriptionResponseTest.cs @@ -1,58 +1,39 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetEndpointTimingDescriptionResponseTest { - public class GetEndpointTimingDescriptionResponseTest + [Test] + public void InterfaceTests() { - [SetUp] - public void Setup() - { - } + GetEndpointTimingDescriptionResponse getGetEndpointTimingDescriptionResponse = new GetEndpointTimingDescriptionResponse(1, "Pseudo Endpoint Timing Description"); - [Test] - public void ToPayloadAndFromMessageTest() + Assert.Multiple(() => { - GetEndpointTimingDescriptionResponse getGetEndpointTimingDescriptionResponse = new GetEndpointTimingDescriptionResponse(1, "Pseudo Endpoint Timing Description"); - byte[] data = getGetEndpointTimingDescriptionResponse.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, - ParameterData = data, - }; - - GetEndpointTimingDescriptionResponse resultGetEndpointTimingDescriptionResponse = GetEndpointTimingDescriptionResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetEndpointTimingDescriptionResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetEndpointTimingDescriptionResponse, Is.EqualTo(getGetEndpointTimingDescriptionResponse)); - - var res = resultGetEndpointTimingDescriptionResponse.ToString(); - var src = getGetEndpointTimingDescriptionResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - [Test] - public void DescriptionCharLimitTest() + Assert.That(getGetEndpointTimingDescriptionResponse.Index, Is.EqualTo(1)); + Assert.That(getGetEndpointTimingDescriptionResponse.TimingId, Is.EqualTo(1)); + Assert.That(getGetEndpointTimingDescriptionResponse.MinIndex, Is.EqualTo(1)); + Assert.That(getGetEndpointTimingDescriptionResponse.Description, Is.EqualTo("Pseudo Endpoint Timing Descripti")); + }); + } + [Test] + public void DescriptionCharLimitTest() + { + GetEndpointTimingDescriptionResponse resultGetEndpointTimingDescriptionResponse = new GetEndpointTimingDescriptionResponse(description: "Pseudo Endpoint Timing Description 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.Multiple(() => { - GetEndpointTimingDescriptionResponse resultGetEndpointTimingDescriptionResponse = new GetEndpointTimingDescriptionResponse(description: "Pseudo Endpoint Timing Description 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.Multiple(() => - { - Assert.That(resultGetEndpointTimingDescriptionResponse.Description, Has.Length.EqualTo(32)); - Assert.That(resultGetEndpointTimingDescriptionResponse.MinIndex, Is.EqualTo(1)); - Assert.That(resultGetEndpointTimingDescriptionResponse.Index, Is.EqualTo(1)); - }); + Assert.That(resultGetEndpointTimingDescriptionResponse.Description, Has.Length.EqualTo(32)); + Assert.That(resultGetEndpointTimingDescriptionResponse.MinIndex, Is.EqualTo(1)); + Assert.That(resultGetEndpointTimingDescriptionResponse.Index, Is.EqualTo(1)); + }); - resultGetEndpointTimingDescriptionResponse = new GetEndpointTimingDescriptionResponse(10, description: ""); - Assert.Multiple(() => - { - Assert.That(string.IsNullOrWhiteSpace(resultGetEndpointTimingDescriptionResponse.Description), Is.True); - Assert.That(resultGetEndpointTimingDescriptionResponse.MinIndex, Is.EqualTo(1)); - Assert.That(resultGetEndpointTimingDescriptionResponse.Index, Is.EqualTo(10)); - }); - } + resultGetEndpointTimingDescriptionResponse = new GetEndpointTimingDescriptionResponse(10, description: ""); + Assert.Multiple(() => + { + Assert.That(string.IsNullOrWhiteSpace(resultGetEndpointTimingDescriptionResponse.Description), Is.True); + Assert.That(resultGetEndpointTimingDescriptionResponse.MinIndex, Is.EqualTo(1)); + Assert.That(resultGetEndpointTimingDescriptionResponse.Index, Is.EqualTo(10)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetEndpointTimingResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetEndpointTimingResponseTest.cs new file mode 100644 index 00000000..4632ac65 --- /dev/null +++ b/RDMSharpTests/RDM/PayloadObject/GetEndpointTimingResponseTest.cs @@ -0,0 +1,24 @@ +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetEndpointTimingResponseTest +{ + [Test] + public void InterfaceTests() + { + GetEndpointTimingResponse getEndpointTimingResponse = new GetEndpointTimingResponse(1, 123, 254); + + Assert.Multiple(() => + { + Assert.That(getEndpointTimingResponse.EndpointId, Is.EqualTo(1)); + Assert.That(getEndpointTimingResponse.Index, Is.EqualTo(123)); + Assert.That(getEndpointTimingResponse.TimingId, Is.EqualTo(123)); + Assert.That(getEndpointTimingResponse.Timings, Is.EqualTo(254)); + Assert.That(getEndpointTimingResponse.Count, Is.EqualTo(254)); + Assert.That(getEndpointTimingResponse.DescriptorParameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION)); + Assert.That(getEndpointTimingResponse.IndexType, Is.EqualTo(typeof(byte))); + Assert.That(getEndpointTimingResponse.MinIndex, Is.EqualTo(1)); + }); + } +} diff --git a/RDMSharpTests/RDM/PayloadObject/GetHardwareAddressResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetHardwareAddressResponseTest.cs index 5a132307..fb6072ef 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetHardwareAddressResponseTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetHardwareAddressResponseTest.cs @@ -1,39 +1,40 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetHardwareAddressResponseTest { - public class GetHardwareAddressResponseTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - GetHardwareAddressResponse getHardwareAddressResponse = new GetHardwareAddressResponse(1, new MACAddress("02:42:c0:a8:01:09")); - byte[] data = getHardwareAddressResponse.ToPayloadData(); + [Test] + public void ToPayloadAndFromMessageTest() + { + GetHardwareAddressResponse getHardwareAddressResponse = new GetHardwareAddressResponse(1, new MACAddress("02:42:c0:a8:01:09")); + byte[] data = getHardwareAddressResponse.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, + ParameterData = data, + }; - GetHardwareAddressResponse resultGetHardwareAddressResponse = GetHardwareAddressResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetHardwareAddressResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + GetHardwareAddressResponse resultGetHardwareAddressResponse = GetHardwareAddressResponse.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetHardwareAddressResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultGetHardwareAddressResponse, Is.EqualTo(getHardwareAddressResponse)); + Assert.That(resultGetHardwareAddressResponse, Is.EqualTo(getHardwareAddressResponse)); - var res = resultGetHardwareAddressResponse.ToString(); - var src = getHardwareAddressResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + var res = resultGetHardwareAddressResponse.ToString(); + var src = getHardwareAddressResponse.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetIPv4CurrentAddressResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetIPv4CurrentAddressResponseTest.cs index 538626f0..9a476f59 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetIPv4CurrentAddressResponseTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetIPv4CurrentAddressResponseTest.cs @@ -1,42 +1,42 @@ +using RDMSharp.PayloadObject; using System.Net; -namespace RDMSharpTests.RDM.PayloadObject +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetIPv4CurrentAddressResponseTest { - public class GetIPv4CurrentAddressResponseTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - GetIPv4CurrentAddressResponse getIPv4CurrentAddressResponse = new GetIPv4CurrentAddressResponse(1, IPAddress.Parse("192.168.0.1"), 24, ERDM_DHCPStatusMode.INACTIVE); - byte[] data = getIPv4CurrentAddressResponse.ToPayloadData(); + [Test] + public void ToPayloadAndFromMessageTest() + { + GetIPv4CurrentAddressResponse getIPv4CurrentAddressResponse = new GetIPv4CurrentAddressResponse(1, IPAddress.Parse("192.168.0.1"), 24, ERDM_DHCPStatusMode.INACTIVE); + byte[] data = getIPv4CurrentAddressResponse.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.IPV4_CURRENT_ADDRESS, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.IPV4_CURRENT_ADDRESS, + ParameterData = data, + }; - GetIPv4CurrentAddressResponse resultGetIPv4CurrentAddressResponse = GetIPv4CurrentAddressResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetIPv4CurrentAddressResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.Throws(typeof(Exception), () => { new GetIPv4CurrentAddressResponse(1, IPAddress.Parse("192.168.0.1"), 33, ERDM_DHCPStatusMode.INACTIVE); }); + GetIPv4CurrentAddressResponse resultGetIPv4CurrentAddressResponse = GetIPv4CurrentAddressResponse.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetIPv4CurrentAddressResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + Assert.Throws(typeof(Exception), () => { new GetIPv4CurrentAddressResponse(1, IPAddress.Parse("192.168.0.1"), 33, ERDM_DHCPStatusMode.INACTIVE); }); - Assert.That(resultGetIPv4CurrentAddressResponse, Is.EqualTo(getIPv4CurrentAddressResponse)); + Assert.That(resultGetIPv4CurrentAddressResponse, Is.EqualTo(getIPv4CurrentAddressResponse)); - var res = resultGetIPv4CurrentAddressResponse.ToString(); - var src = getIPv4CurrentAddressResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + var res = resultGetIPv4CurrentAddressResponse.ToString(); + var src = getIPv4CurrentAddressResponse.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetInterfaceListResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetInterfaceListResponseTest.cs index d0cc63c3..82d481c4 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetInterfaceListResponseTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetInterfaceListResponseTest.cs @@ -1,51 +1,51 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetInterfaceListResponseTest - { - [SetUp] - public void Setup() - { - } +//namespace RDMSharpTests.RDM.PayloadObject +//{ +// public class GetInterfaceListResponseTest +// { +// [SetUp] +// public void Setup() +// { +// } - [Test] - public void ToPayloadAndFromMessageTest() - { - GetInterfaceListResponse getInterfaceListResponse = new GetInterfaceListResponse( - new InterfaceDescriptor(), - new InterfaceDescriptor(1, 1), - new InterfaceDescriptor(1, 2), - new InterfaceDescriptor(1, 3), - new InterfaceDescriptor(2, 1), - new InterfaceDescriptor(2, 2), - new InterfaceDescriptor(2, 3), - new InterfaceDescriptor(3, 1), - new InterfaceDescriptor(3, 2), - new InterfaceDescriptor(3, 3)); +// [Test] +// public void ToPayloadAndFromMessageTest() +// { +// GetInterfaceListResponse getInterfaceListResponse = new GetInterfaceListResponse( +// new InterfaceDescriptor(), +// new InterfaceDescriptor(1, 1), +// new InterfaceDescriptor(1, 2), +// new InterfaceDescriptor(1, 3), +// new InterfaceDescriptor(2, 1), +// new InterfaceDescriptor(2, 2), +// new InterfaceDescriptor(2, 3), +// new InterfaceDescriptor(3, 1), +// new InterfaceDescriptor(3, 2), +// new InterfaceDescriptor(3, 3)); - byte[] data = getInterfaceListResponse.ToPayloadData(); +// byte[] data = getInterfaceListResponse.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.LIST_INTERFACES, - ParameterData = data, - }; +// RDMMessage message = new RDMMessage() +// { +// PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, +// Command = ERDM_Command.GET_COMMAND_RESPONSE, +// Parameter = ERDM_Parameter.LIST_INTERFACES, +// ParameterData = data, +// }; - GetInterfaceListResponse resultGetInterfaceListResponse = GetInterfaceListResponse.FromMessage(message); - Assert.Throws(typeof(Exception), () => { GetInterfaceListResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetInterfaceListResponse.FromPayloadData(data.ToList().Concat(new byte[220]).ToArray()); }); +// GetInterfaceListResponse resultGetInterfaceListResponse = GetInterfaceListResponse.FromMessage(message); +// Assert.Throws(typeof(Exception), () => { GetInterfaceListResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); +// Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetInterfaceListResponse.FromPayloadData(data.ToList().Concat(new byte[220]).ToArray()); }); - Assert.That(resultGetInterfaceListResponse, Is.EqualTo(getInterfaceListResponse)); +// Assert.That(resultGetInterfaceListResponse, Is.EqualTo(getInterfaceListResponse)); - var res = resultGetInterfaceListResponse.ToString(); - var src = getInterfaceListResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file +// var res = resultGetInterfaceListResponse.ToString(); +// var src = getInterfaceListResponse.ToString(); +// Assert.Multiple(() => +// { +// Assert.That(res, Is.Not.Null); +// Assert.That(src, Is.Not.Null); +// }); +// Assert.That(res, Is.EqualTo(src)); +// } +// } +//} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetInterfaceNameResponseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetInterfaceNameResponseTest.cs index ff30c169..4e80b789 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetInterfaceNameResponseTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetInterfaceNameResponseTest.cs @@ -1,43 +1,44 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetInterfaceNameResponseTest { - public class GetInterfaceNameResponseTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - GetInterfaceNameResponse getInterfaceNameResponse = new GetInterfaceNameResponse(1, "Pseude Interface 123456789123456789123456789123456"); - byte[] data = getInterfaceNameResponse.ToPayloadData(); + [Test] + public void ToPayloadAndFromMessageTest() + { + GetInterfaceNameResponse getInterfaceNameResponse = new GetInterfaceNameResponse(1, "Pseude Interface 123456789123456789123456789123456"); + byte[] data = getInterfaceNameResponse.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.INTERFACE_LABEL, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.INTERFACE_LABEL, + ParameterData = data, + }; - GetInterfaceNameResponse resultGetInterfaceNameResponse = GetInterfaceNameResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetInterfaceNameResponse.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); + GetInterfaceNameResponse resultGetInterfaceNameResponse = GetInterfaceNameResponse.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetInterfaceNameResponse.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); - Assert.That(resultGetInterfaceNameResponse, Is.EqualTo(getInterfaceNameResponse)); + Assert.That(resultGetInterfaceNameResponse, Is.EqualTo(getInterfaceNameResponse)); - var res = resultGetInterfaceNameResponse.ToString(); - var src = getInterfaceNameResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); + var res = resultGetInterfaceNameResponse.ToString(); + var src = getInterfaceNameResponse.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); - getInterfaceNameResponse = new GetInterfaceNameResponse(1, ""); - Assert.That(string.IsNullOrWhiteSpace(getInterfaceNameResponse.Label), Is.True); - } + getInterfaceNameResponse = new GetInterfaceNameResponse(1, ""); + Assert.That(string.IsNullOrWhiteSpace(getInterfaceNameResponse.Label), Is.True); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetComponentScopeTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetComponentScopeTest.cs index 7b10a369..561ae7b8 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetSetComponentScopeTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetSetComponentScopeTest.cs @@ -1,86 +1,86 @@ +using RDMSharp.PayloadObject; using System.Net; -namespace RDMSharpTests.RDM.PayloadObject +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetSetComponentScopeTest { - public class GetSetComponentScopeTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() + } + + [Test] + public void ToPayloadAndFromMessageTest() + { + GetSetComponentScope sensorValue = new GetSetComponentScope(0, "Pseudo Scope String", IPAddress.Parse("192.168.2.1"), 2347); + + byte[] data = sensorValue.ToPayloadData(); + + RDMMessage message = new RDMMessage() { - } + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.COMPONENT_SCOPE, + ParameterData = data, + }; + + GetSetComponentScope resultSensorValue = GetSetComponentScope.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetComponentScope.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + + Assert.That(resultSensorValue, Is.EqualTo(sensorValue)); + sensorValue = new GetSetComponentScope(0, "Pseudo Scope String", IPAddress.Parse("2001:db8:0:0:0:0:1428:57ab"), 2347); + + data = sensorValue.ToPayloadData(); - [Test] - public void ToPayloadAndFromMessageTest() + message = new RDMMessage() { - GetSetComponentScope sensorValue = new GetSetComponentScope(0, "Pseudo Scope String", IPAddress.Parse("192.168.2.1"), 2347); - - byte[] data = sensorValue.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.COMPONENT_SCOPE, - ParameterData = data, - }; - - GetSetComponentScope resultSensorValue = GetSetComponentScope.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetComponentScope.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultSensorValue, Is.EqualTo(sensorValue)); - sensorValue = new GetSetComponentScope(0, "Pseudo Scope String", IPAddress.Parse("2001:db8:0:0:0:0:1428:57ab"), 2347); - - data = sensorValue.ToPayloadData(); - - message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.COMPONENT_SCOPE, - ParameterData = data, - }; - - resultSensorValue = GetSetComponentScope.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetComponentScope.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultSensorValue, Is.EqualTo(sensorValue)); - sensorValue = new GetSetComponentScope(0, string.Empty, null, 2347); - - data = sensorValue.ToPayloadData(); - - message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.COMPONENT_SCOPE, - ParameterData = data, - }; - - resultSensorValue = GetSetComponentScope.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetComponentScope.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultSensorValue, Is.EqualTo(sensorValue)); - - var res = resultSensorValue.ToString(); - var src = sensorValue.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - [Test] - public void DescriptionCharLimitTest() + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.COMPONENT_SCOPE, + ParameterData = data, + }; + + resultSensorValue = GetSetComponentScope.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetComponentScope.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + + Assert.That(resultSensorValue, Is.EqualTo(sensorValue)); + sensorValue = new GetSetComponentScope(0, string.Empty, null, 2347); + + data = sensorValue.ToPayloadData(); + + message = new RDMMessage() { - GetSetComponentScope resultGetSetComponentScope = new GetSetComponentScope(0, "Pseudo Scope String 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0", IPAddress.Parse("192.168.2.1"), 2347); - Assert.That(resultGetSetComponentScope.ScopeString, Has.Length.EqualTo(62)); + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.COMPONENT_SCOPE, + ParameterData = data, + }; + + resultSensorValue = GetSetComponentScope.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetComponentScope.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + + Assert.That(resultSensorValue, Is.EqualTo(sensorValue)); + + var res = resultSensorValue.ToString(); + var src = sensorValue.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); + } + [Test] + public void DescriptionCharLimitTest() + { + GetSetComponentScope resultGetSetComponentScope = new GetSetComponentScope(0, "Pseudo Scope String 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0", IPAddress.Parse("192.168.2.1"), 2347); + Assert.That(resultGetSetComponentScope.ScopeString, Has.Length.EqualTo(62)); - resultGetSetComponentScope = new GetSetComponentScope(0, "Pseudo Scope String", null, 2347); - Assert.That(resultGetSetComponentScope.StaticConfigType, Is.EqualTo(ERDM_StaticConfig.NO)); + resultGetSetComponentScope = new GetSetComponentScope(0, "Pseudo Scope String", null, 2347); + Assert.That(resultGetSetComponentScope.StaticConfigType, Is.EqualTo(ERDM_StaticConfig.NO)); - Assert.Throws(typeof(ArgumentException), () => { new GetSetComponentScope(0, "Pseudo Scope String", ERDM_StaticConfig.IPv4, staticBrokerIPv4: IPAddress.Parse("2001:db8:0:0:0:0:1428:57ab")); }); - Assert.Throws(typeof(ArgumentException), () => { new GetSetComponentScope(0, "Pseudo Scope String", ERDM_StaticConfig.IPv6, staticBrokerIPv6: IPAddress.Parse("192.168.2.1")); }); - } + Assert.Throws(typeof(ArgumentException), () => { new GetSetComponentScope(0, "Pseudo Scope String", ERDM_StaticConfig.IPv4, staticBrokerIPv4: IPAddress.Parse("2001:db8:0:0:0:0:1428:57ab")); }); + Assert.Throws(typeof(ArgumentException), () => { new GetSetComponentScope(0, "Pseudo Scope String", ERDM_StaticConfig.IPv6, staticBrokerIPv6: IPAddress.Parse("192.168.2.1")); }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetDiscoveryStateTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetDiscoveryStateTest.cs deleted file mode 100644 index bbe966aa..00000000 --- a/RDMSharpTests/RDM/PayloadObject/GetSetDiscoveryStateTest.cs +++ /dev/null @@ -1,64 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetSetDiscoveryStateTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetDiscoveryStateResponse getDiscoveryStateResponse = new GetDiscoveryStateResponse(1, 123, ERDM_DiscoveryState.FULL); - byte[] data = getDiscoveryStateResponse.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DISCOVERY_STATE, - ParameterData = data, - }; - - GetDiscoveryStateResponse resultGetDiscoveryStateResponse = GetDiscoveryStateResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetDiscoveryStateResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetDiscoveryStateResponse, Is.EqualTo(getDiscoveryStateResponse)); - - var res = resultGetDiscoveryStateResponse.ToString(); - var src = getDiscoveryStateResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - - SetDiscoveryStateRequest setDiscoveryStateRequest = new SetDiscoveryStateRequest(1, ERDM_DiscoveryState.INCREMENTAL); - data = setDiscoveryStateRequest.ToPayloadData(); - - message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DISCOVERY_STATE, - ParameterData = data, - }; - - SetDiscoveryStateRequest resultSetDiscoveryStateRequest = SetDiscoveryStateRequest.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { SetDiscoveryStateRequest.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultSetDiscoveryStateRequest, Is.EqualTo(setDiscoveryStateRequest)); - - res = resultSetDiscoveryStateRequest.ToString(); - src = setDiscoveryStateRequest.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointBackgroundDiscoveryTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetEndpointBackgroundDiscoveryTest.cs deleted file mode 100644 index 05452479..00000000 --- a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointBackgroundDiscoveryTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetSetEndpointBackgroundDiscoveryTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetSetEndpointBackgroundDiscovery getSetEndpointBackgroundDiscovery = new GetSetEndpointBackgroundDiscovery(1, true); - byte[] data = getSetEndpointBackgroundDiscovery.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.BACKGROUND_DISCOVERY, - ParameterData = data, - }; - - GetSetEndpointBackgroundDiscovery resultGetSetEndpointBackgroundDiscovery = GetSetEndpointBackgroundDiscovery.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetEndpointBackgroundDiscovery.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetSetEndpointBackgroundDiscovery, Is.EqualTo(getSetEndpointBackgroundDiscovery)); - - var res = resultGetSetEndpointBackgroundDiscovery.ToString(); - var src = getSetEndpointBackgroundDiscovery.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointLabelTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetEndpointLabelTest.cs index aea7b046..7fb64ca8 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointLabelTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetSetEndpointLabelTest.cs @@ -1,47 +1,15 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetSetEndpointLabelTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetSetEndpointLabel getSetEndpointLabel = new GetSetEndpointLabel(1, "Pseudo Endpoint Label"); - byte[] data = getSetEndpointLabel.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.ENDPOINT_LABEL, - ParameterData = data, - }; +using RDMSharp.PayloadObject; - GetSetEndpointLabel resultGetSetEndpointLabel = GetSetEndpointLabel.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetEndpointLabel.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); +namespace RDMSharpTests.RDM.PayloadObject; - Assert.That(resultGetSetEndpointLabel, Is.EqualTo(getSetEndpointLabel)); - - var res = resultGetSetEndpointLabel.ToString(); - var src = getSetEndpointLabel.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - [Test] - public void DescriptionCharLimitTest() - { - GetSetEndpointLabel resultGetSetEndpointLabel = new GetSetEndpointLabel(endpointLabel: "Pseudo Endpoint Label 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.That(resultGetSetEndpointLabel.EndpointLabel, Has.Length.EqualTo(32)); - resultGetSetEndpointLabel = new GetSetEndpointLabel(endpointLabel: ""); - Assert.That(string.IsNullOrWhiteSpace(resultGetSetEndpointLabel.EndpointLabel), Is.True); - } +public class GetSetEndpointLabelTest +{ + [Test] + public void DescriptionCharLimitTest() + { + GetSetEndpointLabel resultGetSetEndpointLabel = new GetSetEndpointLabel(endpointLabel: "Pseudo Endpoint Label 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.That(resultGetSetEndpointLabel.EndpointLabel, Has.Length.EqualTo(32)); + resultGetSetEndpointLabel = new GetSetEndpointLabel(endpointLabel: ""); + Assert.That(string.IsNullOrWhiteSpace(resultGetSetEndpointLabel.EndpointLabel), Is.True); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointModeTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetEndpointModeTest.cs deleted file mode 100644 index b8cf125f..00000000 --- a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointModeTest.cs +++ /dev/null @@ -1,61 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetSetEndpointModeTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetSetEndpointMode getSetEndpointMode = new GetSetEndpointMode(1, ERDM_EndpointMode.OUTPUT); - byte[] data = getSetEndpointMode.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.ENDPOINT_MODE, - ParameterData = data, - }; - - GetSetEndpointMode resultGetSetEndpointMode = GetSetEndpointMode.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetEndpointMode.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetSetEndpointMode, Is.EqualTo(getSetEndpointMode)); - - var res = resultGetSetEndpointMode.ToString(); - var src = getSetEndpointMode.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - - getSetEndpointMode = new GetSetEndpointMode((ushort)1, (byte)ERDM_EndpointMode.INPUT); - data = getSetEndpointMode.ToPayloadData(); - message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.ENDPOINT_MODE, - ParameterData = data, - }; - - resultGetSetEndpointMode = GetSetEndpointMode.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetEndpointMode.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - res = resultGetSetEndpointMode.ToString(); - src = getSetEndpointMode.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointRDMTrafficEnableTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetEndpointRDMTrafficEnableTest.cs deleted file mode 100644 index ebdd3eeb..00000000 --- a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointRDMTrafficEnableTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetSetEndpointRDMTrafficEnableTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetSetEndpointRDMTrafficEnable getSetEndpointRDMTrafficEnabled = new GetSetEndpointRDMTrafficEnable(1, true); - byte[] data = getSetEndpointRDMTrafficEnabled.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.RDM_TRAFFIC_ENABLE, - ParameterData = data, - }; - - GetSetEndpointRDMTrafficEnable resultGetSetEndpointRDMTrafficEnable = GetSetEndpointRDMTrafficEnable.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetEndpointRDMTrafficEnable.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetSetEndpointRDMTrafficEnable, Is.EqualTo(getSetEndpointRDMTrafficEnabled)); - - var res = resultGetSetEndpointRDMTrafficEnable.ToString(); - var src = getSetEndpointRDMTrafficEnabled.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointTimingTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetEndpointTimingTest.cs deleted file mode 100644 index 5da323bb..00000000 --- a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointTimingTest.cs +++ /dev/null @@ -1,88 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetSetEndpointTimingTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetEndpointTimingResponse getEndpointTimingResponse = new GetEndpointTimingResponse(1, 123, 254); - byte[] data = getEndpointTimingResponse.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.ENDPOINT_TIMING, - ParameterData = data, - }; - - GetEndpointTimingResponse resultGetEndpointTimingResponse = GetEndpointTimingResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetEndpointTimingResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetEndpointTimingResponse, Is.EqualTo(getEndpointTimingResponse)); - Assert.Multiple(() => - { - Assert.That(resultGetEndpointTimingResponse.EndpointId, Is.EqualTo(1)); - Assert.That(resultGetEndpointTimingResponse.TimingId, Is.EqualTo(123)); - Assert.That(resultGetEndpointTimingResponse.Timings, Is.EqualTo(254)); - }); - - var res = resultGetEndpointTimingResponse.ToString(); - var src = getEndpointTimingResponse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - - SetEndpointTimingRequest setEndpointTimingRequest = new SetEndpointTimingRequest(1, 42); - data = setEndpointTimingRequest.ToPayloadData(); - - message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.ENDPOINT_TIMING, - ParameterData = data, - }; - - SetEndpointTimingRequest resultSetEndpointTimingRequest = SetEndpointTimingRequest.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { SetEndpointTimingRequest.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultSetEndpointTimingRequest, Is.EqualTo(setEndpointTimingRequest)); - Assert.Multiple(() => - { - Assert.That(resultSetEndpointTimingRequest.Timings, Is.EqualTo(setEndpointTimingRequest.Timings)); - Assert.That(resultSetEndpointTimingRequest.TimingId, Is.EqualTo(setEndpointTimingRequest.TimingId)); - Assert.That(resultSetEndpointTimingRequest.EndpointId, Is.EqualTo(setEndpointTimingRequest.EndpointId)); - }); - - res = resultSetEndpointTimingRequest.ToString(); - src = setEndpointTimingRequest.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - - - getEndpointTimingResponse = new GetEndpointTimingResponse(31, 123, 254); - Assert.Multiple(() => - { - Assert.That(getEndpointTimingResponse.IndexType, Is.EqualTo(typeof(byte))); - Assert.That(getEndpointTimingResponse.MinIndex, Is.EqualTo(1)); - Assert.That(getEndpointTimingResponse.EndpointId, Is.EqualTo(31)); - Assert.That(getEndpointTimingResponse.Index, Is.EqualTo(123)); - Assert.That(getEndpointTimingResponse.Count, Is.EqualTo(254)); - Assert.That(getEndpointTimingResponse.DescriptorParameter, Is.EqualTo(ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION)); - }); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointToUniverseTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetEndpointToUniverseTest.cs deleted file mode 100644 index f42ff4ea..00000000 --- a/RDMSharpTests/RDM/PayloadObject/GetSetEndpointToUniverseTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetSetEndpointToUniverseTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetSetEndpointToUniverse getSetEndpointToUniverse = new GetSetEndpointToUniverse(1, 1234); - byte[] data = getSetEndpointToUniverse.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.ENDPOINT_TO_UNIVERSE, - ParameterData = data, - }; - - GetSetEndpointToUniverse resultGetSetEndpointToUniverse = GetSetEndpointToUniverse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetEndpointToUniverse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetSetEndpointToUniverse, Is.EqualTo(getSetEndpointToUniverse)); - - var res = resultGetSetEndpointToUniverse.ToString(); - var src = getSetEndpointToUniverse.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetIPV4_xxx_ModeTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetIPV4_xxx_ModeTest.cs index 7086d2b9..3027e0c5 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetSetIPV4_xxx_ModeTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetSetIPV4_xxx_ModeTest.cs @@ -1,39 +1,40 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetSetIPV4_xxx_ModeTest { - public class GetSetIPV4_xxx_ModeTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - GetSetIPV4_xxx_Mode getSetDHCPMode = new GetSetIPV4_xxx_Mode(1, true); - byte[] data = getSetDHCPMode.ToPayloadData(); + [Test] + public void ToPayloadAndFromMessageTest() + { + GetSetIPV4_xxx_Mode getSetDHCPMode = new GetSetIPV4_xxx_Mode(1, true); + byte[] data = getSetDHCPMode.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.IPV4_DHCP_MODE, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.IPV4_DHCP_MODE, + ParameterData = data, + }; - GetSetIPV4_xxx_Mode resultGetSetDHCPMode = GetSetIPV4_xxx_Mode.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetIPV4_xxx_Mode.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + GetSetIPV4_xxx_Mode resultGetSetDHCPMode = GetSetIPV4_xxx_Mode.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetIPV4_xxx_Mode.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultGetSetDHCPMode, Is.EqualTo(getSetDHCPMode)); + Assert.That(resultGetSetDHCPMode, Is.EqualTo(getSetDHCPMode)); - var res = resultGetSetDHCPMode.ToString(); - var src = getSetDHCPMode.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } + var res = resultGetSetDHCPMode.ToString(); + var src = getSetDHCPMode.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); + } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetIPv4DefaultRouteTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetIPv4DefaultRouteTest.cs index 7dc8ea2e..84bb2b96 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetSetIPv4DefaultRouteTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetSetIPv4DefaultRouteTest.cs @@ -1,41 +1,41 @@ +using RDMSharp.PayloadObject; using System.Net; -namespace RDMSharpTests.RDM.PayloadObject +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetSetIPv4DefaultRouteTest { - public class GetSetIPv4DefaultRouteTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - GetSetIPv4DefaultRoute getSetIPv4DefaultRoute = new GetSetIPv4DefaultRoute(1, IPAddress.Parse("2.0.0.1")); - byte[] data = getSetIPv4DefaultRoute.ToPayloadData(); + [Test] + public void ToPayloadAndFromMessageTest() + { + GetSetIPv4DefaultRoute getSetIPv4DefaultRoute = new GetSetIPv4DefaultRoute(1, IPAddress.Parse("2.0.0.1")); + byte[] data = getSetIPv4DefaultRoute.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.IPV4_DEFAULT_ROUTE, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.IPV4_DEFAULT_ROUTE, + ParameterData = data, + }; - GetSetIPv4DefaultRoute resultGetSetIPv4DefaultRoute = GetSetIPv4DefaultRoute.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetIPv4DefaultRoute.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + GetSetIPv4DefaultRoute resultGetSetIPv4DefaultRoute = GetSetIPv4DefaultRoute.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetIPv4DefaultRoute.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultGetSetIPv4DefaultRoute, Is.EqualTo(getSetIPv4DefaultRoute)); + Assert.That(resultGetSetIPv4DefaultRoute, Is.EqualTo(getSetIPv4DefaultRoute)); - var res = resultGetSetIPv4DefaultRoute.ToString(); - var src = getSetIPv4DefaultRoute.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + var res = resultGetSetIPv4DefaultRoute.ToString(); + var src = getSetIPv4DefaultRoute.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetIPv4NameServerTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetIPv4NameServerTest.cs index d2373581..c28fea04 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetSetIPv4NameServerTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetSetIPv4NameServerTest.cs @@ -1,41 +1,41 @@ -using System.Net; +using RDMSharp.PayloadObject; +using System.Net; -namespace RDMSharpTests.RDM.PayloadObject +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetSetIPv4NameServerTest { - public class GetSetIPv4NameServerTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - GetSetIPv4NameServer getSetIPv4NameServer = new GetSetIPv4NameServer(1, IPAddress.Parse("2.0.0.1")); - byte[] data = getSetIPv4NameServer.ToPayloadData(); + [Test] + public void ToPayloadAndFromMessageTest() + { + GetSetIPv4NameServer getSetIPv4NameServer = new GetSetIPv4NameServer(1, IPAddress.Parse("2.0.0.1")); + byte[] data = getSetIPv4NameServer.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DNS_IPV4_NAME_SERVER, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.DNS_IPV4_NAME_SERVER, + ParameterData = data, + }; - GetSetIPv4NameServer resultGetSetIPv4NameServer = GetSetIPv4NameServer.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetIPv4NameServer.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + GetSetIPv4NameServer resultGetSetIPv4NameServer = GetSetIPv4NameServer.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetIPv4NameServer.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultGetSetIPv4NameServer, Is.EqualTo(getSetIPv4NameServer)); + Assert.That(resultGetSetIPv4NameServer, Is.EqualTo(getSetIPv4NameServer)); - var res = resultGetSetIPv4NameServer.ToString(); - var src = getSetIPv4NameServer.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + var res = resultGetSetIPv4NameServer.ToString(); + var src = getSetIPv4NameServer.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetIPv4StaticAddressTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetIPv4StaticAddressTest.cs index 534747f8..51dbfd07 100644 --- a/RDMSharpTests/RDM/PayloadObject/GetSetIPv4StaticAddressTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/GetSetIPv4StaticAddressTest.cs @@ -1,42 +1,42 @@ +using RDMSharp.PayloadObject; using System.Net; -namespace RDMSharpTests.RDM.PayloadObject +namespace RDMSharpTests.RDM.PayloadObject; + +public class GetSetIPv4StaticAddressTest { - public class GetSetIPv4StaticAddressTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - GetSetIPv4StaticAddress getSetIPv4StaticAddress = new GetSetIPv4StaticAddress(1, IPAddress.Parse("2.0.0.1"), 8); - byte[] data = getSetIPv4StaticAddress.ToPayloadData(); + [Test] + public void ToPayloadAndFromMessageTest() + { + GetSetIPv4StaticAddress getSetIPv4StaticAddress = new GetSetIPv4StaticAddress(1, IPAddress.Parse("2.0.0.1"), 8); + byte[] data = getSetIPv4StaticAddress.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.IPV4_STATIC_ADDRESS, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.IPV4_STATIC_ADDRESS, + ParameterData = data, + }; - GetSetIPv4StaticAddress resultGetSetIPv4StaticAddress = GetSetIPv4StaticAddress.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetIPv4StaticAddress.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.Throws(typeof(Exception), () => { new GetSetIPv4StaticAddress(1, IPAddress.Parse("2.0.0.1"), 33); }); + GetSetIPv4StaticAddress resultGetSetIPv4StaticAddress = GetSetIPv4StaticAddress.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetIPv4StaticAddress.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + Assert.Throws(typeof(Exception), () => { new GetSetIPv4StaticAddress(1, IPAddress.Parse("2.0.0.1"), 33); }); - Assert.That(resultGetSetIPv4StaticAddress, Is.EqualTo(getSetIPv4StaticAddress)); + Assert.That(resultGetSetIPv4StaticAddress, Is.EqualTo(getSetIPv4StaticAddress)); - var res = resultGetSetIPv4StaticAddress.ToString(); - var src = getSetIPv4StaticAddress.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + var res = resultGetSetIPv4StaticAddress.ToString(); + var src = getSetIPv4StaticAddress.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/GetSetIdentifyEndpointTest.cs b/RDMSharpTests/RDM/PayloadObject/GetSetIdentifyEndpointTest.cs deleted file mode 100644 index b90e7a18..00000000 --- a/RDMSharpTests/RDM/PayloadObject/GetSetIdentifyEndpointTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class GetSetIdentifyEndpointTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetSetIdentifyEndpoint getSetIPv4StaticAddress = new GetSetIdentifyEndpoint(1, true); - byte[] data = getSetIPv4StaticAddress.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.IDENTIFY_ENDPOINT, - ParameterData = data, - }; - - GetSetIdentifyEndpoint resultGetSetIPv4StaticAddress = GetSetIdentifyEndpoint.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetSetIdentifyEndpoint.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultGetSetIPv4StaticAddress, Is.EqualTo(getSetIPv4StaticAddress)); - - var res = resultGetSetIPv4StaticAddress.ToString(); - var src = getSetIPv4StaticAddress.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMCommunicationStatusTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMCommunicationStatusTest.cs index 9e90aedc..aaff2488 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMCommunicationStatusTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMCommunicationStatusTest.cs @@ -1,40 +1,41 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class RDMCommunicationStatusTest { - public class RDMCommunicationStatusTest + [SetUp] + public void Setup() + { + } + + [Test] + public void ToPayloadAndFromMessageTest() { - [SetUp] - public void Setup() + RDMCommunicationStatus communicationStatus = new RDMCommunicationStatus(55, 42, 11880); + + byte[] data = communicationStatus.ToPayloadData(); + + RDMMessage message = new RDMMessage() { - } + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.COMMS_STATUS, + ParameterData = data, + }; + + RDMCommunicationStatus resultCommunicationStatus = RDMCommunicationStatus.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMCommunicationStatus.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + + Assert.That(resultCommunicationStatus, Is.EqualTo(communicationStatus)); - [Test] - public void ToPayloadAndFromMessageTest() + var res = resultCommunicationStatus.ToString(); + var src = communicationStatus.ToString(); + Assert.Multiple(() => { - RDMCommunicationStatus communicationStatus = new RDMCommunicationStatus(55, 42, 11880); - - byte[] data = communicationStatus.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.COMMS_STATUS, - ParameterData = data, - }; - - RDMCommunicationStatus resultCommunicationStatus = RDMCommunicationStatus.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMCommunicationStatus.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultCommunicationStatus, Is.EqualTo(communicationStatus)); - - var res = resultCommunicationStatus.ToString(); - var src = communicationStatus.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMCurveDescriptionTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMCurveDescriptionTest.cs index 17e13576..e3f6f355 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMCurveDescriptionTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMCurveDescriptionTest.cs @@ -1,53 +1,21 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMCurveDescriptionTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMCurveDescription curveDescription = new RDMCurveDescription(1, "Pseudo Curve"); - byte[] data = curveDescription.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.CURVE_DESCRIPTION, - ParameterData = data, - }; +using RDMSharp.PayloadObject; - RDMCurveDescription resultCurveDescription = RDMCurveDescription.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMCurveDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); +namespace RDMSharpTests.RDM.PayloadObject; - Assert.That(resultCurveDescription, Is.EqualTo(curveDescription)); - - var res = resultCurveDescription.ToString(); - var src = curveDescription.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - [Test] - public void DescriptionCharLimitTest() - { - RDMCurveDescription resultCurveDescription = new RDMCurveDescription(description: "Pseudo Curve 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.That(resultCurveDescription.Description, Has.Length.EqualTo(32)); +public class RDMCurveDescriptionTest +{ + [Test] + public void DescriptionCharLimitTest() + { + RDMCurveDescription resultCurveDescription = new RDMCurveDescription(description: "Pseudo Curve 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.That(resultCurveDescription.Description, Has.Length.EqualTo(32)); - resultCurveDescription = new RDMCurveDescription(6, description: ""); - Assert.Multiple(() => - { - Assert.That(string.IsNullOrEmpty(resultCurveDescription.Description), Is.True); - Assert.That(resultCurveDescription.MinIndex, Is.EqualTo(1)); - Assert.That(resultCurveDescription.Index, Is.EqualTo(6)); - }); - } + resultCurveDescription = new RDMCurveDescription(6, description: ""); + Assert.Multiple(() => + { + Assert.That(string.IsNullOrEmpty(resultCurveDescription.Description), Is.True); + Assert.That(resultCurveDescription.MinIndex, Is.EqualTo(1)); + Assert.That(resultCurveDescription.Index, Is.EqualTo(6)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMCurveTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMCurveTest.cs deleted file mode 100644 index 35a5cd83..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMCurveTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMCurveTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMCurve curve = new RDMCurve(1, 5); - byte[] data = curve.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.CURVE, - ParameterData = data, - }; - - RDMCurve resultCurve = RDMCurve.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMCurve.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultCurve, Is.EqualTo(curve)); - Assert.Multiple(() => - { - Assert.That(resultCurve.IndexType, Is.EqualTo(typeof(byte))); - Assert.That(resultCurve.MinIndex, Is.EqualTo(1)); - Assert.That(resultCurve.Index, Is.EqualTo(1)); - Assert.That(resultCurve.Count, Is.EqualTo(5)); - Assert.That(resultCurve.DescriptorParameter, Is.EqualTo(ERDM_Parameter.CURVE_DESCRIPTION)); - }); - - var res = resultCurve.ToString(); - var src = curve.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMDMXBlockAddressTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMDMXBlockAddressTest.cs index f970b304..7bd247db 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMDMXBlockAddressTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMDMXBlockAddressTest.cs @@ -1,40 +1,41 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class RDMDMXBlockAddressTEst { - public class RDMDMXBlockAddressTEst + [SetUp] + public void Setup() + { + } + + [Test] + public void ToPayloadAndFromMessageTest() { - [SetUp] - public void Setup() + RDMDMXBlockAddress dmxBlockAddress = new RDMDMXBlockAddress(3, 443); + + byte[] data = dmxBlockAddress.ToPayloadData(); + + RDMMessage message = new RDMMessage() { - } + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.DMX_BLOCK_ADDRESS, + ParameterData = data, + }; + + RDMDMXBlockAddress resultDMXBlockAddress = RDMDMXBlockAddress.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMDMXBlockAddress.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + + Assert.That(resultDMXBlockAddress, Is.EqualTo(dmxBlockAddress)); - [Test] - public void ToPayloadAndFromMessageTest() + var res = resultDMXBlockAddress.ToString(); + var src = dmxBlockAddress.ToString(); + Assert.Multiple(() => { - RDMDMXBlockAddress dmxBlockAddress = new RDMDMXBlockAddress(3, 443); - - byte[] data = dmxBlockAddress.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DMX_BLOCK_ADDRESS, - ParameterData = data, - }; - - RDMDMXBlockAddress resultDMXBlockAddress = RDMDMXBlockAddress.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMDMXBlockAddress.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultDMXBlockAddress, Is.EqualTo(dmxBlockAddress)); - - var res = resultDMXBlockAddress.ToString(); - var src = dmxBlockAddress.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMDMXPersonalityDescriptionTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMDMXPersonalityDescriptionTest.cs index 91358452..bc3a6b0d 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMDMXPersonalityDescriptionTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMDMXPersonalityDescriptionTest.cs @@ -1,52 +1,53 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class RDMDMXPersonalityDescriptionTest { - public class RDMDMXPersonalityDescriptionTest + [SetUp] + public void Setup() + { + } + + [Test] + public void ToPayloadAndFromMessageTest() { - [SetUp] - public void Setup() + RDMDMXPersonalityDescription rdmDmxPersonalityDescription = new RDMDMXPersonalityDescription(42, 5, "Pseudo Personality"); + byte[] data = rdmDmxPersonalityDescription.ToPayloadData(); + + RDMMessage message = new RDMMessage() { - } + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, + ParameterData = data, + }; - [Test] - public void ToPayloadAndFromMessageTest() + RDMDMXPersonalityDescription resultRdmDmxPersonalityDescription = RDMDMXPersonalityDescription.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMDMXPersonalityDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); + + Assert.That(resultRdmDmxPersonalityDescription, Is.EqualTo(rdmDmxPersonalityDescription)); + + var res = resultRdmDmxPersonalityDescription.ToString(); + var src = rdmDmxPersonalityDescription.ToString(); + Assert.Multiple(() => { - RDMDMXPersonalityDescription rdmDmxPersonalityDescription = new RDMDMXPersonalityDescription(42, 5, "Pseudo Personality"); - byte[] data = rdmDmxPersonalityDescription.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, - ParameterData = data, - }; - - RDMDMXPersonalityDescription resultRdmDmxPersonalityDescription = RDMDMXPersonalityDescription.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMDMXPersonalityDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); - - Assert.That(resultRdmDmxPersonalityDescription, Is.EqualTo(rdmDmxPersonalityDescription)); - - var res = resultRdmDmxPersonalityDescription.ToString(); - var src = rdmDmxPersonalityDescription.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - - [Test] - public void DescriptionCharLimitTest() + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); + } + + [Test] + public void DescriptionCharLimitTest() + { + RDMDMXPersonalityDescription rdmDmxPersonalityDescription = new RDMDMXPersonalityDescription(description: "Pseudo Personality 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.That(rdmDmxPersonalityDescription.Description, Has.Length.EqualTo(32)); + rdmDmxPersonalityDescription = new RDMDMXPersonalityDescription(description: ""); + Assert.Multiple(() => { - RDMDMXPersonalityDescription rdmDmxPersonalityDescription = new RDMDMXPersonalityDescription(description: "Pseudo Personality 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.That(rdmDmxPersonalityDescription.Description, Has.Length.EqualTo(32)); - rdmDmxPersonalityDescription = new RDMDMXPersonalityDescription(description: ""); - Assert.Multiple(() => - { - Assert.That(string.IsNullOrWhiteSpace(rdmDmxPersonalityDescription.Description), Is.True); - Assert.That(rdmDmxPersonalityDescription.MinIndex, Is.EqualTo(1)); - }); - } + Assert.That(string.IsNullOrWhiteSpace(rdmDmxPersonalityDescription.Description), Is.True); + Assert.That(rdmDmxPersonalityDescription.MinIndex, Is.EqualTo(1)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMDMXPersonalityTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMDMXPersonalityTest.cs index 83334a69..cf3386ff 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMDMXPersonalityTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMDMXPersonalityTest.cs @@ -1,46 +1,47 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class RDMDMXPersonalityTest { - public class RDMDMXPersonalityTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMDMXPersonality rdmDmxPersonality = new RDMDMXPersonality(1, 5); - byte[] data = rdmDmxPersonality.ToPayloadData(); + [Test] + public void ToPayloadAndFromMessageTest() + { + RDMDMXPersonality rdmDmxPersonality = new RDMDMXPersonality(1, 5); + byte[] data = rdmDmxPersonality.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DMX_PERSONALITY, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.DMX_PERSONALITY, + ParameterData = data, + }; - RDMDMXPersonality resultRdmDmxPersonality = RDMDMXPersonality.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMDMXPersonality.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + RDMDMXPersonality resultRdmDmxPersonality = RDMDMXPersonality.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMDMXPersonality.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultRdmDmxPersonality, Is.EqualTo(rdmDmxPersonality)); - Assert.Multiple(() => - { - Assert.That(resultRdmDmxPersonality.MinIndex, Is.EqualTo(1)); - Assert.That(resultRdmDmxPersonality.Index, Is.EqualTo(1)); - Assert.That(resultRdmDmxPersonality.DescriptorParameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION)); - Assert.That(resultRdmDmxPersonality.IndexType, Is.EqualTo(typeof(byte))); - }); + Assert.That(resultRdmDmxPersonality, Is.EqualTo(rdmDmxPersonality)); + Assert.Multiple(() => + { + Assert.That(resultRdmDmxPersonality.MinIndex, Is.EqualTo(1)); + Assert.That(resultRdmDmxPersonality.Index, Is.EqualTo(1)); + Assert.That(resultRdmDmxPersonality.DescriptorParameter, Is.EqualTo(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION)); + Assert.That(resultRdmDmxPersonality.IndexType, Is.EqualTo(typeof(byte))); + }); - var res = resultRdmDmxPersonality.ToString(); - var src = rdmDmxPersonality.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + var res = resultRdmDmxPersonality.ToString(); + var src = rdmDmxPersonality.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMDMX_xxxx_ModeTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMDMX_xxxx_ModeTest.cs index 3a5f9662..80481d60 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMDMX_xxxx_ModeTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMDMX_xxxx_ModeTest.cs @@ -1,40 +1,40 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMDMX_xxxx_ModeTest - { - [SetUp] - public void Setup() - { - } +//namespace RDMSharpTests.RDM.PayloadObject +//{ +// public class RDMDMX_xxxx_ModeTest +// { +// [SetUp] +// public void Setup() +// { +// } - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMDMX_xxxx_Mode dmxFailMode = new RDMDMX_xxxx_Mode(55, 42, 11880); +// [Test] +// public void ToPayloadAndFromMessageTest() +// { +// RDMDMX_xxxx_Mode dmxFailMode = new RDMDMX_xxxx_Mode(55, 42, 11880); - byte[] data = dmxFailMode.ToPayloadData(); +// byte[] data = dmxFailMode.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DMX_FAIL_MODE, - ParameterData = data, - }; +// RDMMessage message = new RDMMessage() +// { +// PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, +// Command = ERDM_Command.GET_COMMAND_RESPONSE, +// Parameter = ERDM_Parameter.DMX_FAIL_MODE, +// ParameterData = data, +// }; - RDMDMX_xxxx_Mode resultDMXFailMode = RDMDMX_xxxx_Mode.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMDMX_xxxx_Mode.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); +// RDMDMX_xxxx_Mode resultDMXFailMode = RDMDMX_xxxx_Mode.FromMessage(message); +// Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMDMX_xxxx_Mode.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultDMXFailMode, Is.EqualTo(dmxFailMode)); +// Assert.That(resultDMXFailMode, Is.EqualTo(dmxFailMode)); - var res = resultDMXFailMode.ToString(); - var src = dmxFailMode.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file +// var res = resultDMXFailMode.ToString(); +// var src = dmxFailMode.ToString(); +// Assert.Multiple(() => +// { +// Assert.That(res, Is.Not.Null); +// Assert.That(src, Is.Not.Null); +// }); +// Assert.That(res, Is.EqualTo(src)); +// } +// } +//} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMDefaultSlotValueTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMDefaultSlotValueTest.cs deleted file mode 100644 index 9c728a02..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMDefaultSlotValueTest.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMDefaultSlotValueTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMDefaultSlotValue defaultSlotValue = new RDMDefaultSlotValue(3, 250); - - byte[] data = defaultSlotValue.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DEFAULT_SLOT_VALUE, - ParameterData = data, - }; - - RDMDefaultSlotValue resultDefaultSlotValue = RDMDefaultSlotValue.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMDefaultSlotValue.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultDefaultSlotValue, Is.EqualTo(defaultSlotValue)); - - var res = resultDefaultSlotValue.ToString(); - var src = defaultSlotValue.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMDeviceInfoTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMDeviceInfoTest.cs deleted file mode 100644 index ada03ed7..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMDeviceInfoTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMDeviceInfoTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMDeviceInfo deviceInfo = new RDMDeviceInfo(1, 12, 333, ERDM_ProductCategoryCoarse.FIXTURE, ERDM_ProductCategoryFine.FIXTURE_MOVING_YOKE, 2344777890, 30, 8, 27, 6, 99, 42); - byte[] data = deviceInfo.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DEVICE_INFO, - ParameterData = data, - }; - - RDMDeviceInfo resultDeviceInfo = RDMDeviceInfo.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMDeviceInfo.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultDeviceInfo, Is.EqualTo(deviceInfo)); - - var res = resultDeviceInfo.ToString(); - var src = deviceInfo.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMDimmerInfoTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMDimmerInfoTest.cs index 76973712..909f8a49 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMDimmerInfoTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMDimmerInfoTest.cs @@ -1,42 +1,13 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMDimmerInfoTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMDimmerInfo dimmerInfo = new RDMDimmerInfo(numberOfSupportedCurves: 4, levelsResolution: 6, minimumLevelSplitLevelsSupported: true); - byte[] data = dimmerInfo.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.DIMMER_INFO, - ParameterData = data, - }; +using RDMSharp.PayloadObject; - RDMDimmerInfo resultDimmerInfo = RDMDimmerInfo.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMDimmerInfo.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); +namespace RDMSharpTests.RDM.PayloadObject; - Assert.That(resultDimmerInfo, Is.EqualTo(dimmerInfo)); - - var res = resultDimmerInfo.ToString(); - var src = dimmerInfo.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - - Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMDimmerInfo(numberOfSupportedCurves: 4, levelsResolution: 0, minimumLevelSplitLevelsSupported: true); }); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMDimmerInfo(numberOfSupportedCurves: 4, levelsResolution: 36, minimumLevelSplitLevelsSupported: true); }); - } +public class RDMDimmerInfoTest +{ + [Test] + public void ExceptionTests() + { + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMDimmerInfo(numberOfSupportedCurves: 4, levelsResolution: 0, minimumLevelSplitLevelsSupported: true); }); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMDimmerInfo(numberOfSupportedCurves: 4, levelsResolution: 36, minimumLevelSplitLevelsSupported: true); }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMLockStateDescriptionTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMLockStateDescriptionTest.cs index b451f20c..8831e2a6 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMLockStateDescriptionTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMLockStateDescriptionTest.cs @@ -1,53 +1,21 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMLockStateDescriptionTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMLockStateDescription lockStateDescription = new RDMLockStateDescription(1, "Pseudo LockState"); - byte[] data = lockStateDescription.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.LOCK_STATE_DESCRIPTION, - ParameterData = data, - }; +using RDMSharp.PayloadObject; - RDMLockStateDescription resultLockStateDescription = RDMLockStateDescription.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMLockStateDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); +namespace RDMSharpTests.RDM.PayloadObject; - Assert.That(resultLockStateDescription, Is.EqualTo(lockStateDescription)); - - var res = resultLockStateDescription.ToString(); - var src = lockStateDescription.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - [Test] - public void DescriptionCharLimitTest() - { - RDMLockStateDescription resultLockStateDescription = new RDMLockStateDescription(description: "Pseudo LockState 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.That(resultLockStateDescription.Description, Has.Length.EqualTo(32)); +public class RDMLockStateDescriptionTest +{ + [Test] + public void DescriptionCharLimitTest() + { + RDMLockStateDescription resultLockStateDescription = new RDMLockStateDescription(description: "Pseudo LockState 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.That(resultLockStateDescription.Description, Has.Length.EqualTo(32)); - resultLockStateDescription = new RDMLockStateDescription(7, description: ""); - Assert.Multiple(() => - { - Assert.That(string.IsNullOrEmpty(resultLockStateDescription.Description), Is.True); - Assert.That(resultLockStateDescription.MinIndex, Is.EqualTo(1)); - Assert.That(resultLockStateDescription.Index, Is.EqualTo(7)); - }); - } + resultLockStateDescription = new RDMLockStateDescription(7, description: ""); + Assert.Multiple(() => + { + Assert.That(string.IsNullOrEmpty(resultLockStateDescription.Description), Is.True); + Assert.That(resultLockStateDescription.MinIndex, Is.EqualTo(1)); + Assert.That(resultLockStateDescription.Index, Is.EqualTo(7)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMLockStateTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMLockStateTest.cs deleted file mode 100644 index 5f81be29..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMLockStateTest.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMLockStateTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - GetLockStateResponse lockState = new GetLockStateResponse(1, 5); - byte[] data = lockState.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.LOCK_STATE, - ParameterData = data, - }; - - GetLockStateResponse resultLockState = GetLockStateResponse.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { GetLockStateResponse.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultLockState, Is.EqualTo(lockState)); - - var res = resultLockState.ToString(); - var src = lockState.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - - lockState = new GetLockStateResponse(10, 5); - Assert.Multiple(() => - { - Assert.That(lockState.IndexType, Is.EqualTo(typeof(byte))); - Assert.That(lockState.MinIndex, Is.EqualTo(1)); - Assert.That(lockState.Index, Is.EqualTo(10)); - Assert.That(lockState.Count, Is.EqualTo(5)); - Assert.That(lockState.DescriptorParameter, Is.EqualTo(ERDM_Parameter.LOCK_STATE_DESCRIPTION)); - }); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMMinimumLevelTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMMinimumLevelTest.cs deleted file mode 100644 index 14a604d8..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMMinimumLevelTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMMinimumLevelTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMMinimumLevel minimumLevel = new RDMMinimumLevel(10303, 43211, true); - byte[] data = minimumLevel.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.MINIMUM_LEVEL, - ParameterData = data, - }; - - RDMMinimumLevel resultMinimumLevel = RDMMinimumLevel.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMMinimumLevel.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultMinimumLevel, Is.EqualTo(minimumLevel)); - - var res = resultMinimumLevel.ToString(); - var src = minimumLevel.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMModulationFrequencyDescriptionTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMModulationFrequencyDescriptionTest.cs index 903d1081..ecc7efbf 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMModulationFrequencyDescriptionTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMModulationFrequencyDescriptionTest.cs @@ -1,106 +1,21 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMModulationFrequencyDescriptionTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTestWithoutFrequency() - { - RDMModulationFrequencyDescription modulationFrequencyDescription = new RDMModulationFrequencyDescription(1, null, "Pseudo ModulationFrequency"); - byte[] data = modulationFrequencyDescription.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, - ParameterData = data, - }; - - RDMModulationFrequencyDescription resultModulationFrequencyDescription = RDMModulationFrequencyDescription.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMModulationFrequencyDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); - - Assert.That(resultModulationFrequencyDescription, Is.EqualTo(modulationFrequencyDescription)); - - var res = resultModulationFrequencyDescription.ToString(); - var src = modulationFrequencyDescription.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - - modulationFrequencyDescription = new RDMModulationFrequencyDescription(1, uint.MaxValue, "Pseudo ModulationFrequency"); - data = modulationFrequencyDescription.ToPayloadData(); - - message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, - ParameterData = data, - }; +using RDMSharp.PayloadObject; - resultModulationFrequencyDescription = RDMModulationFrequencyDescription.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMModulationFrequencyDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); +namespace RDMSharpTests.RDM.PayloadObject; - Assert.That(resultModulationFrequencyDescription, Is.EqualTo(modulationFrequencyDescription)); - - res = resultModulationFrequencyDescription.ToString(); - src = modulationFrequencyDescription.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMModulationFrequencyDescription modulationFrequencyDescription = new RDMModulationFrequencyDescription(1, 3456543131, "Pseudo ModulationFrequency"); - byte[] data = modulationFrequencyDescription.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, - ParameterData = data, - }; - - RDMModulationFrequencyDescription resultModulationFrequencyDescription = RDMModulationFrequencyDescription.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMModulationFrequencyDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); - - Assert.That(resultModulationFrequencyDescription, Is.EqualTo(modulationFrequencyDescription)); - - var res = resultModulationFrequencyDescription.ToString(); - var src = modulationFrequencyDescription.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - [Test] - public void DescriptionCharLimitTest() - { - RDMModulationFrequencyDescription resultModulationFrequencyDescription = new RDMModulationFrequencyDescription(description: "Pseudo ModulationFrequency 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.That(resultModulationFrequencyDescription.Description, Has.Length.EqualTo(32)); - - resultModulationFrequencyDescription = new RDMModulationFrequencyDescription(5, description: ""); - Assert.Multiple(() => - { - Assert.That(string.IsNullOrEmpty(resultModulationFrequencyDescription.Description), Is.True); - Assert.That(resultModulationFrequencyDescription.MinIndex, Is.EqualTo(1)); - Assert.That(resultModulationFrequencyDescription.Index, Is.EqualTo(5)); - }); - } +public class RDMModulationFrequencyDescriptionTest +{ + [Test] + public void DescriptionCharLimitTest() + { + RDMModulationFrequencyDescription resultModulationFrequencyDescription = new RDMModulationFrequencyDescription(description: "Pseudo ModulationFrequency 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.That(resultModulationFrequencyDescription.Description, Has.Length.EqualTo(32)); + + resultModulationFrequencyDescription = new RDMModulationFrequencyDescription(5, description: ""); + Assert.Multiple(() => + { + Assert.That(string.IsNullOrEmpty(resultModulationFrequencyDescription.Description), Is.True); + Assert.That(resultModulationFrequencyDescription.MinIndex, Is.EqualTo(1)); + Assert.That(resultModulationFrequencyDescription.Index, Is.EqualTo(5)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMModulationFrequencyTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMModulationFrequencyTest.cs deleted file mode 100644 index f112e1ec..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMModulationFrequencyTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMModulationFrequencyTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMModulationFrequency modulationFrequency = new RDMModulationFrequency(233, 234); - byte[] data = modulationFrequency.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.MODULATION_FREQUENCY, - ParameterData = data, - }; - - RDMModulationFrequency resultModulationFrequency = RDMModulationFrequency.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMModulationFrequency.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultModulationFrequency, Is.EqualTo(modulationFrequency)); - Assert.Multiple(() => - { - Assert.That(resultModulationFrequency.IndexType, Is.EqualTo(typeof(byte))); - Assert.That(resultModulationFrequency.MinIndex, Is.EqualTo(1)); - Assert.That(resultModulationFrequency.Index, Is.EqualTo(233)); - Assert.That(resultModulationFrequency.Count, Is.EqualTo(234)); - Assert.That(resultModulationFrequency.DescriptorParameter, Is.EqualTo(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION)); - }); - - var res = resultModulationFrequency.ToString(); - var src = modulationFrequency.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMOutputResponseTimeDescriptionTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMOutputResponseTimeDescriptionTest.cs index a201bf14..a9026138 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMOutputResponseTimeDescriptionTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMOutputResponseTimeDescriptionTest.cs @@ -1,53 +1,21 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMOutputResponseTimeDescriptionTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMOutputResponseTimeDescription outputResponseTimeDescription = new RDMOutputResponseTimeDescription(255, "Pseudo OutputResponseTime"); - byte[] data = outputResponseTimeDescription.ToPayloadData(); +using RDMSharp.PayloadObject; - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, - ParameterData = data, - }; +namespace RDMSharpTests.RDM.PayloadObject; - RDMOutputResponseTimeDescription resultOutputResponseTimeDescription = RDMOutputResponseTimeDescription.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMOutputResponseTimeDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); - - Assert.That(resultOutputResponseTimeDescription, Is.EqualTo(outputResponseTimeDescription)); +public class RDMOutputResponseTimeDescriptionTest +{ + [Test] + public void DescriptionCharLimitTest() + { + RDMOutputResponseTimeDescription resultOutputResponseTimeDescription = new RDMOutputResponseTimeDescription(description: "Pseudo OutputResponseTime 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.That(resultOutputResponseTimeDescription.Description, Has.Length.EqualTo(32)); - var res = resultOutputResponseTimeDescription.ToString(); - var src = outputResponseTimeDescription.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - [Test] - public void DescriptionCharLimitTest() + resultOutputResponseTimeDescription = new RDMOutputResponseTimeDescription(3, description: ""); + Assert.Multiple(() => { - RDMOutputResponseTimeDescription resultOutputResponseTimeDescription = new RDMOutputResponseTimeDescription(description: "Pseudo OutputResponseTime 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.That(resultOutputResponseTimeDescription.Description, Has.Length.EqualTo(32)); - - resultOutputResponseTimeDescription = new RDMOutputResponseTimeDescription(3, description: ""); - Assert.Multiple(() => - { - Assert.That(string.IsNullOrWhiteSpace(resultOutputResponseTimeDescription.Description), Is.True); - Assert.That(resultOutputResponseTimeDescription.MinIndex, Is.EqualTo(1)); - Assert.That(resultOutputResponseTimeDescription.Index, Is.EqualTo(3)); - }); - } + Assert.That(string.IsNullOrWhiteSpace(resultOutputResponseTimeDescription.Description), Is.True); + Assert.That(resultOutputResponseTimeDescription.MinIndex, Is.EqualTo(1)); + Assert.That(resultOutputResponseTimeDescription.Index, Is.EqualTo(3)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMOutputResponseTimeTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMOutputResponseTimeTest.cs deleted file mode 100644 index 54a8e0c6..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMOutputResponseTimeTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMOutputResponseTimeTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMOutputResponseTime outputResponseTime = new RDMOutputResponseTime(14, 5); - byte[] data = outputResponseTime.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.OUTPUT_RESPONSE_TIME, - ParameterData = data, - }; - - RDMOutputResponseTime resultOutputResponseTime = RDMOutputResponseTime.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMOutputResponseTime.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultOutputResponseTime, Is.EqualTo(outputResponseTime)); - Assert.Multiple(() => - { - Assert.That(resultOutputResponseTime.IndexType, Is.EqualTo(typeof(byte))); - Assert.That(resultOutputResponseTime.MinIndex, Is.EqualTo(1)); - Assert.That(resultOutputResponseTime.Index, Is.EqualTo(14)); - Assert.That(resultOutputResponseTime.Count, Is.EqualTo(5)); - Assert.That(resultOutputResponseTime.DescriptorParameter, Is.EqualTo(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION)); - }); - - var res = resultOutputResponseTime.ToString(); - var src = outputResponseTime.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMParameterDescriptionTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMParameterDescriptionTest.cs index 5d5818fd..41931083 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMParameterDescriptionTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMParameterDescriptionTest.cs @@ -1,59 +1,26 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMParameterDescriptionTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMParameterDescription parameterDescription = new RDMParameterDescription(32, 0, ERDM_DataType.INT16, ERDM_CommandClass.GET | ERDM_CommandClass.SET, 0, ERDM_SensorUnit.NEWTON, ERDM_UnitPrefix.KILO, 0, 5666669, 100, "Pseudo Parameter"); - byte[] data = parameterDescription.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.PARAMETER_DESCRIPTION, - ParameterData = data, - }; - - RDMParameterDescription resultParameterDescription = RDMParameterDescription.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMParameterDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); +using RDMSharp.PayloadObject; - Assert.That(resultParameterDescription, Is.EqualTo(parameterDescription)); +namespace RDMSharpTests.RDM.PayloadObject; - var res = resultParameterDescription.ToString(); - var src = parameterDescription.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - - [Test] - public void DescriptionCharLimitTest() - { - RDMParameterDescription parameterDescription = new RDMParameterDescription(2, description: "Pseudo Parameter 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.That(parameterDescription.Description, Has.Length.EqualTo(32)); +public class RDMParameterDescriptionTest +{ + [Test] + public void DescriptionCharLimitTest() + { + RDMParameterDescription parameterDescription = new RDMParameterDescription(2, description: "Pseudo Parameter 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.That(parameterDescription.Description, Has.Length.EqualTo(32)); - parameterDescription = new RDMParameterDescription(4, description: ""); - Assert.That(string.IsNullOrEmpty(parameterDescription.Description), Is.True); - } + parameterDescription = new RDMParameterDescription(4, description: ""); + Assert.That(string.IsNullOrEmpty(parameterDescription.Description), Is.True); + } - [Test] - public void SecoundConstructor() - { - RDMParameterDescription parameterDescription = new RDMParameterDescription((ushort)ERDM_Parameter.MINIMUM_LEVEL, 2, ERDM_DataType.UINT32, ERDM_CommandClass.GET, 1, ERDM_SensorUnit.CANDELA, ERDM_UnitPrefix.TERRA, 2, 4, 5, "dadsad"); - Assert.That(parameterDescription.Description, Has.Length.EqualTo(6)); - Assert.That(parameterDescription.ParameterId, Is.EqualTo((ushort)ERDM_Parameter.MINIMUM_LEVEL)); - Assert.That(parameterDescription.DataType, Is.EqualTo(ERDM_DataType.UINT32)); - Assert.That(parameterDescription.CommandClass, Is.EqualTo(ERDM_CommandClass.GET)); - } + [Test] + public void SecoundConstructor() + { + RDMParameterDescription parameterDescription = new RDMParameterDescription((ushort)ERDM_Parameter.MINIMUM_LEVEL, 2, ERDM_DataType.UINT32, ERDM_CommandClass.GET, 1, ERDM_SensorUnit.CANDELA, ERDM_UnitPrefix.TERRA, 2, 4, 5, "dadsad"); + Assert.That(parameterDescription.Description, Has.Length.EqualTo(6)); + Assert.That(parameterDescription.ParameterId, Is.EqualTo((ushort)ERDM_Parameter.MINIMUM_LEVEL)); + Assert.That(parameterDescription.DataType, Is.EqualTo(ERDM_DataType.UINT32)); + Assert.That(parameterDescription.CommandClass, Is.EqualTo(ERDM_CommandClass.GET)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMPresetInfoTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMPresetInfoTest.cs deleted file mode 100644 index 9d7e44e2..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMPresetInfoTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMPresetInfoTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMPresetInfo presetInfo = new RDMPresetInfo(true, true, true, true, true, true, 12354, 21567, 7432, 23467, 7632, 24567, 7532, 23456, ushort.MaxValue, 23456, 6543, ushort.MaxValue, 5432); - byte[] data = presetInfo.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.PRESET_INFO, - ParameterData = data, - }; - - RDMPresetInfo resultPresetInfo = RDMPresetInfo.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMPresetInfo.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultPresetInfo, Is.EqualTo(presetInfo)); - - var res = resultPresetInfo.ToString(); - var src = presetInfo.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMPresetPlaybackTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMPresetPlaybackTest.cs index 6c003e22..bd74995a 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMPresetPlaybackTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMPresetPlaybackTest.cs @@ -1,39 +1,40 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class RDMPresetPlaybackTest { - public class RDMPresetPlaybackTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMPresetPlayback presetPlayback = new RDMPresetPlayback(3333, 125); - byte[] data = presetPlayback.ToPayloadData(); + [Test] + public void ToPayloadAndFromMessageTest() + { + RDMPresetPlayback presetPlayback = new RDMPresetPlayback(3333, 125); + byte[] data = presetPlayback.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.PRESET_PLAYBACK, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.PRESET_PLAYBACK, + ParameterData = data, + }; - RDMPresetPlayback resultPresetPlayback = RDMPresetPlayback.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMPresetPlayback.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + RDMPresetPlayback resultPresetPlayback = RDMPresetPlayback.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMPresetPlayback.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultPresetPlayback, Is.EqualTo(presetPlayback)); + Assert.That(resultPresetPlayback, Is.EqualTo(presetPlayback)); - var res = resultPresetPlayback.ToString(); - var src = presetPlayback.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + var res = resultPresetPlayback.ToString(); + var src = presetPlayback.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMPresetStatusTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMPresetStatusTest.cs deleted file mode 100644 index 7bb24550..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMPresetStatusTest.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMPresetStatusTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMPresetStatus presetStatus = new RDMPresetStatus(12354, 21567, 7432, 23467, ERDM_PresetProgrammed.PROGRAMMED_READ_ONLY); - byte[] data = presetStatus.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.PRESET_STATUS, - ParameterData = data, - }; - - RDMPresetStatus resultPresetStatus = RDMPresetStatus.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMPresetStatus.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultPresetStatus, Is.EqualTo(presetStatus)); - - var res = resultPresetStatus.ToString(); - var src = presetStatus.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMProxiedDeviceCountTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMProxiedDeviceCountTest.cs deleted file mode 100644 index ee19f982..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMProxiedDeviceCountTest.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMProxiedDeviceCountTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMProxiedDeviceCount proxiedDeviceCount = new RDMProxiedDeviceCount(10, true); - - byte[] data = proxiedDeviceCount.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.PROXIED_DEVICES_COUNT, - ParameterData = data, - }; - - RDMProxiedDeviceCount resultProxiedDeviceCount = RDMProxiedDeviceCount.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMProxiedDeviceCount.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultProxiedDeviceCount, Is.EqualTo(proxiedDeviceCount)); - - var res = resultProxiedDeviceCount.ToString(); - var src = proxiedDeviceCount.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMProxiedDevicesTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMProxiedDevicesTest.cs deleted file mode 100644 index 6838aaa3..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMProxiedDevicesTest.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMProxiedDevicesTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMProxiedDevices proxiedDevices = new RDMProxiedDevices( - new UID(214567834), - new UID(2723737), - new UID(5959076060), - new UID(067060), - new UID(32490538486848484)); - - byte[] data = proxiedDevices.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.PROXIED_DEVICES, - ParameterData = data, - }; - - RDMProxiedDevices resultproxiedDevices = RDMProxiedDevices.FromMessage(message); - Assert.Throws(typeof(Exception), () => { RDMProxiedDevices.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMProxiedDevices.FromPayloadData(data.ToList().Concat(new byte[220]).ToArray()); }); - - Assert.That(resultproxiedDevices, Is.EqualTo(proxiedDevices)); - - var res = resultproxiedDevices.ToString(); - var src = proxiedDevices.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMRealTimeClockTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMRealTimeClockTest.cs index 0f36e366..e66a4d15 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMRealTimeClockTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMRealTimeClockTest.cs @@ -1,48 +1,32 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMRealTimeClockTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMRealTimeClock realTimeClock = new RDMRealTimeClock(DateTime.Now); - - byte[] data = realTimeClock.ToPayloadData(); +using RDMSharp.PayloadObject; - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.REAL_TIME_CLOCK, - ParameterData = data, - }; +namespace RDMSharpTests.RDM.PayloadObject; - RDMRealTimeClock resultRealTimeClock = RDMRealTimeClock.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMRealTimeClock.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultRealTimeClock, Is.EqualTo(realTimeClock)); - - var res = resultRealTimeClock.ToString(); - var src = realTimeClock.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); +public class RDMRealTimeClockTest +{ + [Test] + public void CompareTests() + { + RDMRealTimeClock rtc1 = new RDMRealTimeClock(year: 2023, month: 5, day: 20, hour: 15, minute: 30, second: 45); + RDMRealTimeClock rtc2 = new RDMRealTimeClock(year: 2023, month: 4, day: 20, hour: 15, minute: 30, second: 45); + RDMRealTimeClock rtc3 = new RDMRealTimeClock(year: 2024, month: 6, day: 21, hour: 16, minute: 31, second: 46); + Assert.That(rtc1.CompareTo(rtc2), Is.EqualTo(1)); + Assert.That(rtc1.CompareTo(rtc3), Is.EqualTo(-1)); + Assert.That(rtc1.CompareTo(rtc1), Is.EqualTo(0)); + } - Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(year: 2000); }); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(month: 13); }); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(day: 32); }); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(hour: 25); }); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(minute: 60); }); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(second: 60); }); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(year: 2000, month: 2, day: 30); }); - } + [Test] + public void ExceptionTests() + { + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(year: 2000); }); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(month: 13); }); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(month: 0); }); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(day: 32); }); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(day: 0); }); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(hour: 25); }); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(minute: 60); }); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(second: 60); }); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { new RDMRealTimeClock(year: 2000, month: 2, day: 30); }); + Assert.Throws(typeof(ArgumentException), () => { new RDMRealTimeClock(year: 2023, month: 5, day: 20, hour: 15, minute: 30, second: 45).CompareTo(DateTime.Now); }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMSelfTestDescriptionTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMSelfTestDescriptionTest.cs index ebeda5d2..f7944603 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMSelfTestDescriptionTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMSelfTestDescriptionTest.cs @@ -1,49 +1,50 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class RDMSelfTestDescriptionTest { - public class RDMSelfTestDescriptionTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } + + [Test] + public void ToPayloadAndFromMessageTest() + { + RDMSelfTestDescription selfTestDescription = new RDMSelfTestDescription(1, "Pseudo Selftest"); + byte[] data = selfTestDescription.ToPayloadData(); - [Test] - public void ToPayloadAndFromMessageTest() + RDMMessage message = new RDMMessage() { - RDMSelfTestDescription selfTestDescription = new RDMSelfTestDescription(1, "Pseudo Selftest"); - byte[] data = selfTestDescription.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.SELF_TEST_DESCRIPTION, - ParameterData = data, - }; - - RDMSelfTestDescription resultSelfTestDescription = RDMSelfTestDescription.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMSelfTestDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); - - Assert.That(resultSelfTestDescription, Is.EqualTo(selfTestDescription)); - - var res = resultSelfTestDescription.ToString(); - var src = selfTestDescription.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - - [Test] - public void DescriptionCharLimitTest() + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.SELF_TEST_DESCRIPTION, + ParameterData = data, + }; + + RDMSelfTestDescription resultSelfTestDescription = RDMSelfTestDescription.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMSelfTestDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); + + Assert.That(resultSelfTestDescription, Is.EqualTo(selfTestDescription)); + + var res = resultSelfTestDescription.ToString(); + var src = selfTestDescription.ToString(); + Assert.Multiple(() => { - RDMSelfTestDescription parameterDescription = new RDMSelfTestDescription(description: "Pseudo Selftest 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.That(parameterDescription.Description, Has.Length.EqualTo(32)); + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); + } + + [Test] + public void DescriptionCharLimitTest() + { + RDMSelfTestDescription parameterDescription = new RDMSelfTestDescription(description: "Pseudo Selftest 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.That(parameterDescription.Description, Has.Length.EqualTo(32)); - parameterDescription = new RDMSelfTestDescription(4, description: ""); - Assert.That(string.IsNullOrEmpty(parameterDescription.Description), Is.True); - } + parameterDescription = new RDMSelfTestDescription(4, description: ""); + Assert.That(string.IsNullOrEmpty(parameterDescription.Description), Is.True); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMSensorDefinitionTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMSensorDefinitionTest.cs index be1ad6dd..2c3640db 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMSensorDefinitionTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMSensorDefinitionTest.cs @@ -1,55 +1,21 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMSensorDefinitionTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMSensorDefinition sensorDefinition = new RDMSensorDefinition(0, ERDM_SensorType.ACCELERATION, ERDM_SensorUnit.DEGREE, ERDM_UnitPrefix.ATTO, short.MinValue, short.MaxValue, short.MinValue, short.MaxValue, true, false, "Pseudo Sensor"); - - byte[] data = sensorDefinition.ToPayloadData(); +using RDMSharp.PayloadObject; - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.SENSOR_DEFINITION, - ParameterData = data, - }; +namespace RDMSharpTests.RDM.PayloadObject; - RDMSensorDefinition resultSensorDefinition = RDMSensorDefinition.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMSensorDefinition.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); - - Assert.That(resultSensorDefinition, Is.EqualTo(sensorDefinition)); - - var res = resultSensorDefinition.ToString(); - var src = sensorDefinition.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } +public class RDMSensorDefinitionTest +{ + [Test] + public void DescriptionCharLimitTest() + { + RDMSensorDefinition sensorDefinition = new RDMSensorDefinition(description: "Pseudo Sensor 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.That(sensorDefinition.Description, Has.Length.EqualTo(32)); - [Test] - public void DescriptionCharLimitTest() + sensorDefinition = new RDMSensorDefinition(3, description: ""); + Assert.Multiple(() => { - RDMSensorDefinition sensorDefinition = new RDMSensorDefinition(description: "Pseudo Sensor 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.That(sensorDefinition.Description, Has.Length.EqualTo(32)); - - sensorDefinition = new RDMSensorDefinition(3, description: ""); - Assert.Multiple(() => - { - Assert.That(string.IsNullOrEmpty(sensorDefinition.Description), Is.True); - Assert.That(sensorDefinition.MinIndex, Is.EqualTo(0)); - Assert.That(sensorDefinition.Index, Is.EqualTo(3)); - }); - } + Assert.That(string.IsNullOrEmpty(sensorDefinition.Description), Is.True); + Assert.That(sensorDefinition.MinIndex, Is.EqualTo(0)); + Assert.That(sensorDefinition.Index, Is.EqualTo(3)); + }); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMSensorValueTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMSensorValueTest.cs deleted file mode 100644 index 126f864c..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMSensorValueTest.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMSensorValueTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMSensorValue sensorValue = new RDMSensorValue(5, 12359, 12347, 10101, 11880); - - byte[] data = sensorValue.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.SENSOR_VALUE, - ParameterData = data, - }; - - RDMSensorValue resultSensorValue = RDMSensorValue.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMSensorValue.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultSensorValue, Is.EqualTo(sensorValue)); - Assert.Multiple(() => - { - Assert.That(resultSensorValue.MinIndex, Is.EqualTo(0)); - Assert.That(resultSensorValue.Index, Is.EqualTo(5)); - }); - - var res = resultSensorValue.ToString(); - var src = sensorValue.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMSlotDescriptionTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMSlotDescriptionTest.cs index fcd3073c..4529332e 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMSlotDescriptionTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMSlotDescriptionTest.cs @@ -1,49 +1,16 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMSlotDescriptionTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMSlotDescription slotDescription = new RDMSlotDescription(3, "Pseudo Desctiption"); - - byte[] data = slotDescription.ToPayloadData(); +using RDMSharp.PayloadObject; - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.SLOT_DESCRIPTION, - ParameterData = data, - }; +namespace RDMSharpTests.RDM.PayloadObject; - RDMSlotDescription resultSlotDescription = RDMSlotDescription.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMSlotDescription.FromPayloadData(data.ToList().Concat(new byte[30]).ToArray()); }); - - Assert.That(resultSlotDescription, Is.EqualTo(slotDescription)); - - var res = resultSlotDescription.ToString(); - var src = slotDescription.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - [Test] - public void DescriptionCharLimitTest() - { - RDMSlotDescription resultSlotDescription = new RDMSlotDescription(description: "Pseudo SlotDescription 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); - Assert.That(resultSlotDescription.Description, Has.Length.EqualTo(32)); +public class RDMSlotDescriptionTest +{ + [Test] + public void DescriptionCharLimitTest() + { + RDMSlotDescription resultSlotDescription = new RDMSlotDescription(description: "Pseudo SlotDescription 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0"); + Assert.That(resultSlotDescription.Description, Has.Length.EqualTo(32)); - resultSlotDescription = new RDMSlotDescription(7, description: ""); - Assert.That(string.IsNullOrEmpty(resultSlotDescription.Description), Is.True); - } + resultSlotDescription = new RDMSlotDescription(7, description: ""); + Assert.That(string.IsNullOrEmpty(resultSlotDescription.Description), Is.True); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMSlotInfoTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMSlotInfoTest.cs deleted file mode 100644 index b339f79e..00000000 --- a/RDMSharpTests/RDM/PayloadObject/RDMSlotInfoTest.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class RDMSlotInfoTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMSlotInfo slotInfo = new RDMSlotInfo(3, ERDM_SlotType.SEC_ROTATION, ERDM_SlotCategory.INTENSITY); - - byte[] data = slotInfo.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.SLOT_INFO, - ParameterData = data, - }; - - RDMSlotInfo resultSlotInfo = RDMSlotInfo.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMSlotInfo.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultSlotInfo, Is.EqualTo(slotInfo)); - - var res = resultSlotInfo.ToString(); - var src = slotInfo.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/RDMStatusMessageTest.cs b/RDMSharpTests/RDM/PayloadObject/RDMStatusMessageTest.cs index d36d0ca2..71af1519 100644 --- a/RDMSharpTests/RDM/PayloadObject/RDMStatusMessageTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/RDMStatusMessageTest.cs @@ -1,40 +1,41 @@ -namespace RDMSharpTests.RDM.PayloadObject +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class RDMStatusMessageTest { - public class RDMStatusMessageTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - RDMStatusMessage statusMessage = new RDMStatusMessage(0, ERDM_Status.ERROR, ERDM_StatusMessage.UNDERCURRENT, 2, 20); + [Test] + public void ToPayloadAndFromMessageTest() + { + RDMStatusMessage statusMessage = new RDMStatusMessage(0, ERDM_Status.ERROR, ERDM_StatusMessage.UNDERCURRENT, 2, 20); - byte[] data = statusMessage.ToPayloadData(); + byte[] data = statusMessage.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.STATUS_MESSAGES, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.STATUS_MESSAGES, + ParameterData = data, + }; - RDMStatusMessage resultStatusMessage = RDMStatusMessage.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMStatusMessage.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + RDMStatusMessage resultStatusMessage = RDMStatusMessage.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { RDMStatusMessage.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultStatusMessage, Is.EqualTo(statusMessage)); + Assert.That(resultStatusMessage, Is.EqualTo(statusMessage)); - var res = resultStatusMessage.ToString(); - var src = statusMessage.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } + var res = resultStatusMessage.ToString(); + var src = statusMessage.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/SetEndpointTimingRequestTest.cs b/RDMSharpTests/RDM/PayloadObject/SetEndpointTimingRequestTest.cs new file mode 100644 index 00000000..57415c0d --- /dev/null +++ b/RDMSharpTests/RDM/PayloadObject/SetEndpointTimingRequestTest.cs @@ -0,0 +1,18 @@ +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM.PayloadObject; + +public class SetEndpointTimingRequestTest +{ + [Test] + public void InterfaceTests() + { + SetEndpointTimingRequest setEndpointTimingRequest = new SetEndpointTimingRequest(1, 123); + + Assert.Multiple(() => + { + Assert.That(setEndpointTimingRequest.EndpointId, Is.EqualTo(1)); + Assert.That(setEndpointTimingRequest.TimingId, Is.EqualTo(123)); + }); + } +} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/SetLockPinRequestTest.cs b/RDMSharpTests/RDM/PayloadObject/SetLockPinRequestTest.cs deleted file mode 100644 index ea7ce1b6..00000000 --- a/RDMSharpTests/RDM/PayloadObject/SetLockPinRequestTest.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class SetLockPinRequestTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - SetLockPinRequest setLockPinRequest = new SetLockPinRequest(11880, 0815); - - byte[] data = setLockPinRequest.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.SET_COMMAND, - Parameter = ERDM_Parameter.LOCK_PIN, - ParameterData = data, - }; - - SetLockPinRequest resultSetLockPinRequest = SetLockPinRequest.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { SetLockPinRequest.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultSetLockPinRequest, Is.EqualTo(setLockPinRequest)); - - var res = resultSetLockPinRequest.ToString(); - var src = setLockPinRequest.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/SetLockStateRequestTest.cs b/RDMSharpTests/RDM/PayloadObject/SetLockStateRequestTest.cs deleted file mode 100644 index 852e6b62..00000000 --- a/RDMSharpTests/RDM/PayloadObject/SetLockStateRequestTest.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace RDMSharpTests.RDM.PayloadObject -{ - public class SetLockStateRequestTest - { - [SetUp] - public void Setup() - { - } - - [Test] - public void ToPayloadAndFromMessageTest() - { - SetLockStateRequest setLockStateRequest = new SetLockStateRequest(11880, 1); - - byte[] data = setLockStateRequest.ToPayloadData(); - - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.SET_COMMAND, - Parameter = ERDM_Parameter.LOCK_STATE, - ParameterData = data, - }; - - SetLockStateRequest resultSetLockStateRequest = SetLockStateRequest.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { SetLockStateRequest.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - - Assert.That(resultSetLockStateRequest, Is.EqualTo(setLockStateRequest)); - - var res = resultSetLockStateRequest.ToString(); - var src = setLockStateRequest.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/TCPCommsEntryTest.cs b/RDMSharpTests/RDM/PayloadObject/TCPCommsEntryTest.cs index 0fb66164..8b7925cf 100644 --- a/RDMSharpTests/RDM/PayloadObject/TCPCommsEntryTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/TCPCommsEntryTest.cs @@ -1,77 +1,77 @@ +using RDMSharp.PayloadObject; using System.Net; -namespace RDMSharpTests.RDM.PayloadObject +namespace RDMSharpTests.RDM.PayloadObject; + +public class TCPCommsEntryTest { - public class TCPCommsEntryTest + [SetUp] + public void Setup() { - [SetUp] - public void Setup() - { - } + } - [Test] - public void ToPayloadAndFromMessageTest() - { - TCPCommsEntry tcpCommsEntryTest = new TCPCommsEntry("Pseudo TCPCommsEntryTest", IPAddress.Parse("192.168.2.1"), 2347, 77); + [Test] + public void ToPayloadAndFromMessageTest() + { + TCPCommsEntry tcpCommsEntryTest = new TCPCommsEntry("Pseudo TCPCommsEntryTest", IPAddress.Parse("192.168.2.1"), 2347, 77); - byte[] data = tcpCommsEntryTest.ToPayloadData(); + byte[] data = tcpCommsEntryTest.ToPayloadData(); - RDMMessage message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.TCP_COMMS_STATUS, - ParameterData = data, - }; + RDMMessage message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.TCP_COMMS_STATUS, + ParameterData = data, + }; - TCPCommsEntry resultTCPCommsEntryTest = TCPCommsEntry.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { TCPCommsEntry.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + TCPCommsEntry resultTCPCommsEntryTest = TCPCommsEntry.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { TCPCommsEntry.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultTCPCommsEntryTest, Is.EqualTo(tcpCommsEntryTest)); + Assert.That(resultTCPCommsEntryTest, Is.EqualTo(tcpCommsEntryTest)); - var res = resultTCPCommsEntryTest.ToString(); - var src = tcpCommsEntryTest.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); + var res = resultTCPCommsEntryTest.ToString(); + var src = tcpCommsEntryTest.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); - tcpCommsEntryTest = new TCPCommsEntry("Pseudo TCPCommsEntryTest", IPAddress.Parse("2001:db8:0:0:0:0:1428:57ab"), 2347, 99); + tcpCommsEntryTest = new TCPCommsEntry("Pseudo TCPCommsEntryTest", IPAddress.Parse("2001:db8:0:0:0:0:1428:57ab"), 2347, 99); - data = tcpCommsEntryTest.ToPayloadData(); + data = tcpCommsEntryTest.ToPayloadData(); - message = new RDMMessage() - { - PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, - Command = ERDM_Command.GET_COMMAND_RESPONSE, - Parameter = ERDM_Parameter.TCP_COMMS_STATUS, - ParameterData = data, - }; + message = new RDMMessage() + { + PortID_or_Responsetype = (byte)ERDM_ResponseType.ACK, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.TCP_COMMS_STATUS, + ParameterData = data, + }; - resultTCPCommsEntryTest = TCPCommsEntry.FromMessage(message); - Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { TCPCommsEntry.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); + resultTCPCommsEntryTest = TCPCommsEntry.FromMessage(message); + Assert.Throws(typeof(RDMMessageInvalidPDLException), () => { TCPCommsEntry.FromPayloadData(data.ToList().Concat(new byte[1]).ToArray()); }); - Assert.That(resultTCPCommsEntryTest, Is.EqualTo(tcpCommsEntryTest)); + Assert.That(resultTCPCommsEntryTest, Is.EqualTo(tcpCommsEntryTest)); - res = resultTCPCommsEntryTest.ToString(); - src = tcpCommsEntryTest.ToString(); - Assert.Multiple(() => - { - Assert.That(res, Is.Not.Null); - Assert.That(src, Is.Not.Null); - }); - Assert.That(res, Is.EqualTo(src)); - } - [Test] - public void DescriptionCharLimitTest() - { - TCPCommsEntry resultGetSetComponentScope = new TCPCommsEntry("Pseudo TCPCommsEntryTest 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0", IPAddress.Parse("192.168.2.1"), 2347); - Assert.That(resultGetSetComponentScope.ScopeString, Has.Length.EqualTo(62)); + res = resultTCPCommsEntryTest.ToString(); + src = tcpCommsEntryTest.ToString(); + Assert.Multiple(() => + { + Assert.That(res, Is.Not.Null); + Assert.That(src, Is.Not.Null); + }); + Assert.That(res, Is.EqualTo(src)); + } + [Test] + public void DescriptionCharLimitTest() + { + TCPCommsEntry resultGetSetComponentScope = new TCPCommsEntry("Pseudo TCPCommsEntryTest 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0", IPAddress.Parse("192.168.2.1"), 2347); + Assert.That(resultGetSetComponentScope.ScopeString, Has.Length.EqualTo(62)); - resultGetSetComponentScope = new TCPCommsEntry("", IPAddress.Parse("192.168.2.1"), 2347); - Assert.That(string.IsNullOrEmpty(resultGetSetComponentScope.ScopeString), Is.True); - } + resultGetSetComponentScope = new TCPCommsEntry("", IPAddress.Parse("192.168.2.1"), 2347); + Assert.That(string.IsNullOrEmpty(resultGetSetComponentScope.ScopeString), Is.True); } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/TestAbstractRDMPayloadObjectDataTreeObjectAttribute.cs b/RDMSharpTests/RDM/PayloadObject/TestAbstractRDMPayloadObjectDataTreeObjectAttribute.cs index 2b98c72c..918adc17 100644 --- a/RDMSharpTests/RDM/PayloadObject/TestAbstractRDMPayloadObjectDataTreeObjectAttribute.cs +++ b/RDMSharpTests/RDM/PayloadObject/TestAbstractRDMPayloadObjectDataTreeObjectAttribute.cs @@ -1,58 +1,57 @@ -using Newtonsoft.Json.Linq; -using RDMSharp.Metadata; +using RDMSharp.Metadata; using System.Reflection; -namespace RDMSharpTests.RDM.PayloadObject.Attribute -{ - [TestFixtureSource(typeof(TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject), nameof(TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject.TestSubjects))] - public class TestAbstractRDMPayloadObjectDataTreeObjectAttribute - { - private readonly TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject testSubject; +namespace RDMSharpTests.RDM.PayloadObject.Attribute; - public TestAbstractRDMPayloadObjectDataTreeObjectAttribute(TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject _TestSubject) - { - testSubject = _TestSubject; - } - [Test] - public void TestDataTreeObjectParameter_And_DataTreeObjectProperty() - { - Assert.That(testSubject.Type.GetCustomAttributes().ToArray(), Has.Length.AtLeast(1)); +[TestFixtureSource(typeof(TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject), nameof(TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject.TestSubjects))] +public class TestAbstractRDMPayloadObjectDataTreeObjectAttribute +{ + private readonly TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject testSubject; - List propertyAttributes = new List(); - List parameterAttributes = new List(); - var properties = testSubject.Type.GetProperties().Where(p => p.GetCustomAttributes().Count() != 0).ToArray(); - foreach (var prop in properties) - if (prop.GetCustomAttributes() is IEnumerable pAttributes) - propertyAttributes.AddRange(pAttributes); + public TestAbstractRDMPayloadObjectDataTreeObjectAttribute(TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject _TestSubject) + { + testSubject = _TestSubject; + } + [Test] + public void TestDataTreeObjectParameter_And_DataTreeObjectProperty() + { + Assert.That(testSubject.Type.GetCustomAttributes().ToArray(), Has.Length.AtLeast(1)); - foreach (var constructor in testSubject.Type.GetConstructors()) - foreach (var param in constructor.GetParameters()) - { - if (param.GetCustomAttributes() is IEnumerable pAttributes) - parameterAttributes.AddRange(pAttributes); - } - Assert.That(parameterAttributes, Has.Count.EqualTo(propertyAttributes.Count)); + List propertyAttributes = new List(); + List parameterAttributes = new List(); + var properties = testSubject.Type.GetProperties().Where(p => p.GetCustomAttributes().Count() != 0).ToArray(); + foreach (var prop in properties) + if (prop.GetCustomAttributes() is IEnumerable pAttributes) + propertyAttributes.AddRange(pAttributes); - foreach(var para in parameterAttributes) - { - var prop = propertyAttributes.FirstOrDefault(prop=>string.Equals(prop.Name, para.Name)); - Assert.That(prop, Is.Not.Null, $"No Property found using{nameof(DataTreeObjectPropertyAttribute)} with {nameof(DataTreeObjectPropertyAttribute.Name)}: {para.Name}"); - } - foreach (var prop in propertyAttributes) + foreach (var constructor in testSubject.Type.GetConstructors()) + foreach (var param in constructor.GetParameters()) { - var para = parameterAttributes.FirstOrDefault(para => string.Equals(prop.Name, para.Name)); - Assert.That(para, Is.Not.Null, $"No Parameter found using{nameof(DataTreeObjectParameterAttribute)} with {nameof(DataTreeObjectParameterAttribute.Name)}: {prop.Name}"); - } - foreach (var prop in propertyAttributes) - { - var para = parameterAttributes.FirstOrDefault(para => string.Equals(prop.Name, para.Name)); - Assert.That(para, Is.Not.Null, $"No Parameter found using{nameof(DataTreeObjectParameterAttribute)} with {nameof(DataTreeObjectParameterAttribute.Name)}: {prop.Name}"); - } - foreach (var item in propertyAttributes.Where(p => !p.Name.Contains('/')).GroupBy(p => p.Parameter)) - { - foreach (var item1 in item) - Assert.That(item.Where(i => i.Index == item1.Index).ToList(), Has.Count.EqualTo(1)); + if (param.GetCustomAttributes() is IEnumerable pAttributes) + parameterAttributes.AddRange(pAttributes); } + Assert.That(parameterAttributes, Has.Count.EqualTo(propertyAttributes.Count), testSubject.Name); + + foreach (var para in parameterAttributes) + { + var prop = propertyAttributes.FirstOrDefault(prop => string.Equals(prop.Name, para.Name)); + if (prop is null) + prop = propertyAttributes.FirstOrDefault(prop => prop.Name.Contains(para.Name + "/")); + Assert.That(prop, Is.Not.Null, $"No Property found using{nameof(DataTreeObjectPropertyAttribute)} with {nameof(DataTreeObjectPropertyAttribute.Name)}: {para.Name}"); + } + foreach (var prop in propertyAttributes) + { + DataTreeObjectParameterAttribute para = null; + if (!prop.Name.Contains("/")) + para = parameterAttributes.FirstOrDefault(para => string.Equals(prop.Name, para.Name)); + else + para = parameterAttributes.FirstOrDefault(para => prop.Name.StartsWith(para.Name)); + Assert.That(para, Is.Not.Null, $"No Parameter found using{nameof(DataTreeObjectParameterAttribute)} with {nameof(DataTreeObjectParameterAttribute.Name)}: {prop.Name}"); + } + foreach (var item in propertyAttributes.Where(p => !p.Name.Contains('/')).GroupBy(p => p.Parameter)) + { + foreach (var item1 in item) + Assert.That(item.Where(i => i.Index == item1.Index).ToList(), Has.Count.EqualTo(1)); } } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject.cs b/RDMSharpTests/RDM/PayloadObject/TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject.cs index 4709a020..65ed6b12 100644 --- a/RDMSharpTests/RDM/PayloadObject/TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject.cs +++ b/RDMSharpTests/RDM/PayloadObject/TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject.cs @@ -1,38 +1,38 @@ using RDMSharp.Metadata; +using RDMSharp.PayloadObject; using System.Reflection; -namespace RDMSharpTests.RDM.PayloadObject.Attribute +namespace RDMSharpTests.RDM.PayloadObject.Attribute; + +public class TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject { - public class TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject + public static readonly object[] TestSubjects = getTestSubjects(); + private static object[] getTestSubjects() { - public static readonly object[] TestSubjects = getTestSubjects(); - private static object[] getTestSubjects() - { - var baseType = typeof(AbstractRDMPayloadObject); - var assembly = Assembly.GetAssembly(baseType); - - var types = assembly.GetTypes() - .Where(t => baseType.IsAssignableFrom(t) && !t.IsAbstract) - .ToArray(); + var baseType = typeof(AbstractRDMPayloadObject); + var assembly = Assembly.GetAssembly(baseType); - List result = new List(); - foreach (var type in types) - { - if (type.GetCustomAttributes().Count() != 0) - result.Add(new TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject(type, type.Name)); - } - return result.ToArray(); - - } + var types = assembly.GetTypes() + .Where(t => baseType.IsAssignableFrom(t) && !t.IsAbstract) + .ToArray(); - public readonly Type Type; - public readonly string Name; - public TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject(Type type, string name) + List result = new List(); + foreach (var type in types) { - Type = type; - Name = name; + if (type.GetCustomAttributes().Count() != 0) + result.Add(new TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject(type, type.Name)); } + return result.ToArray(); - public override string ToString() => Name; } + + public readonly Type Type; + public readonly string Name; + public TestAbstractRDMPayloadObjectDataTreeObjectAttributeTestSubject(Type type, string name) + { + Type = type; + Name = name; + } + + public override string ToString() => Name; } \ No newline at end of file diff --git a/RDMSharpTests/RDM/RDMMessageTest.cs b/RDMSharpTests/RDM/RDMMessageTest.cs index 5381ac46..c5ba1308 100644 --- a/RDMSharpTests/RDM/RDMMessageTest.cs +++ b/RDMSharpTests/RDM/RDMMessageTest.cs @@ -1,132 +1,235 @@ -namespace RDMSharpTests.RDM +using RDMSharp.PayloadObject; + +namespace RDMSharpTests.RDM; + +public class RDMMessageTest { - public class RDMMessageTest + [Test] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] + public void RDMMessageParameterData_Exception() { - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] - public void RDMMessageParameterData_Exception() - { - RDMMessage? m = new RDMMessage(); + RDMMessage? m = new RDMMessage(); - Assert.Multiple(() => - { - Assert.That(m.ParameterData, Is.Empty); - Assert.That(m.PDL, Is.EqualTo(0)); - Assert.That(m.MessageLength, Is.EqualTo(24)); - - m.ParameterData = new byte[5]; - Assert.That(m.ParameterData, Has.Length.EqualTo(5)); - Assert.That(m.PDL, Is.EqualTo(5)); - Assert.That(m.MessageLength, Is.EqualTo(29)); - - m.ParameterData = new byte[231]; - Assert.That(m.ParameterData, Has.Length.EqualTo(231)); - Assert.That(m.PDL, Is.EqualTo(231)); - Assert.That(m.MessageLength, Is.EqualTo(255)); - - Assert.Throws(() => m.ParameterData = new byte[232]); - - m = new RDMMessage - { - Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH, - Command = ERDM_Command.DISCOVERY_COMMAND, - ParameterData = new DiscUniqueBranchRequest(UID.Empty, UID.Broadcast - 1).ToPayloadData() - }; - - Assert.That(m.Equals(m), Is.True); - Assert.That(m.Equals((object)m), Is.True); - Assert.That(m.GetHashCode(), Is.EqualTo(m!.GetHashCode())); - var m2 = new RDMMessage(m.BuildMessage()); - Assert.That(m2, Is.EqualTo(m)); - Assert.That(m2.GetHashCode(), Is.EqualTo(m.GetHashCode())); - }); - } - - [Test] - public void RDMMessageLengthTest() - { - RDMMessage m = new RDMMessage - { - ParameterData = new byte[17] - }; + Assert.Multiple(() => + { + Assert.That(m.ParameterData, Is.Empty); + Assert.That(m.PDL, Is.EqualTo(0)); + Assert.That(m.MessageLength, Is.EqualTo(24)); + + m.ParameterData = new byte[5]; + Assert.That(m.ParameterData, Has.Length.EqualTo(5)); + Assert.That(m.PDL, Is.EqualTo(5)); + Assert.That(m.MessageLength, Is.EqualTo(29)); + + m.ParameterData = new byte[231]; + Assert.That(m.ParameterData, Has.Length.EqualTo(231)); + Assert.That(m.PDL, Is.EqualTo(231)); + Assert.That(m.MessageLength, Is.EqualTo(255)); - Assert.Multiple(() => + Assert.Throws(() => m.ParameterData = new byte[232]); + + m = new RDMMessage { - Assert.That(m.PDL, Is.EqualTo(17)); - Assert.That(m.MessageLength, Is.EqualTo(24 + 17)); - }); - } + Parameter = ERDM_Parameter.DISC_UNIQUE_BRANCH, + Command = ERDM_Command.DISCOVERY_COMMAND, + ParameterData = new DiscUniqueBranchRequest(UID.Empty, UID.Broadcast - 1).ToPayloadData() + }; + + Assert.That(m.Equals(m), Is.True); + Assert.That(m.Equals((object)m), Is.True); + Assert.That(m.GetHashCode(), Is.EqualTo(m!.GetHashCode())); + var m2 = new RDMMessage(m.BuildMessage()); + Assert.That(m2, Is.EqualTo(m)); + Assert.That(m2.GetHashCode(), Is.EqualTo(m.GetHashCode())); + }); + } + + [Test] + public void RDMMessageLengthTest() + { + RDMMessage m = new RDMMessage + { + ParameterData = new byte[17] + }; + + Assert.Multiple(() => + { + Assert.That(m.PDL, Is.EqualTo(17)); + Assert.That(m.MessageLength, Is.EqualTo(24 + 17)); + }); + } - [Test] - public void RDMMessageChecksumTest() + [Test] + public void RDMMessageChecksumTest() + { + //Example taken from RDM Spec + RDMMessage m = new RDMMessage { - //Example taken from RDM Spec - RDMMessage m = new RDMMessage - { - DestUID = new UID(0x1234, 0x56789abc), - SourceUID = new UID(0xcba9, 0x87654321), - PortID_or_Responsetype = 1, - Command = ERDM_Command.GET_COMMAND, - Parameter = ERDM_Parameter.STATUS_MESSAGES, - ParameterData = new byte[] { 0x04 } - }; - - Assert.That(m.Checksum, Is.EqualTo(0x66A)); - } - - [Test] - public void RDMMessageChecksumTest2() + DestUID = new UID(0x1234, 0x56789abc), + SourceUID = new UID(0xcba9, 0x87654321), + PortID_or_Responsetype = 1, + Command = ERDM_Command.GET_COMMAND, + Parameter = ERDM_Parameter.STATUS_MESSAGES, + ParameterData = new byte[] { 0x04 } + }; + + Assert.That(m.Checksum, Is.EqualTo(0x66A)); + } + + [Test] + public void RDMMessageChecksumTest2() + { + RDMMessage m = new RDMMessage { - RDMMessage m = new RDMMessage - { - DestUID = new UID(0x1234, 0x56789abc), - SourceUID = new UID(0x02B0, 0x00112233), - PortID_or_Responsetype = 1, - Command = ERDM_Command.SET_COMMAND, - Parameter = ERDM_Parameter.DMX_START_ADDRESS, - ParameterData = new byte[] { 0x00, 0x42 } - }; - - Assert.That(m.Checksum, Is.EqualTo(0x5CE)); - } - - [Test] - public void RDMMessageChecksumTest3() + DestUID = new UID(0x1234, 0x56789abc), + SourceUID = new UID(0x02B0, 0x00112233), + PortID_or_Responsetype = 1, + Command = ERDM_Command.SET_COMMAND, + Parameter = ERDM_Parameter.DMX_START_ADDRESS, + ParameterData = new byte[] { 0x00, 0x42 } + }; + + Assert.That(m.Checksum, Is.EqualTo(0x5CE)); + } + + [Test] + public void RDMMessageChecksumTest3() + { + RDMMessage m = new RDMMessage { - RDMMessage m = new RDMMessage - { - DestUID = new UID(0x1234, 0x56789abc), - SourceUID = new UID(0xcba9, 0x87654321), - PortID_or_Responsetype = 1, - Command = ERDM_Command.SET_COMMAND, - Parameter = ERDM_Parameter.DMX_START_ADDRESS, - ParameterData = Enumerable.Range(0, 200).Select(c => (byte)0xFE).ToArray() - }; - - Assert.That(m.Checksum, Is.EqualTo(0xCF34)); - } - - [Test] - public void RDMMessageDiscoveryBuildMessage() + DestUID = new UID(0x1234, 0x56789abc), + SourceUID = new UID(0xcba9, 0x87654321), + PortID_or_Responsetype = 1, + Command = ERDM_Command.SET_COMMAND, + Parameter = ERDM_Parameter.DMX_START_ADDRESS, + ParameterData = Enumerable.Range(0, 200).Select(c => (byte)0xFE).ToArray() + }; + + Assert.That(m.Checksum, Is.EqualTo(0xCF34)); + } + + [Test] + public void RDMMessageDiscoveryBuildMessage() + { + RDMMessage m = new RDMMessage { - RDMMessage m = new RDMMessage - { - DestUID = new UID(0x1234, 0x56789abc), - SourceUID = new UID(0x02B0, 0x00112233), - Command = ERDM_Command.DISCOVERY_COMMAND, - Parameter = ERDM_Parameter.DISC_MUTE - }; + DestUID = new UID(0x1234, 0x56789abc), + SourceUID = new UID(0x02B0, 0x00112233), + Command = ERDM_Command.DISCOVERY_COMMAND, + Parameter = ERDM_Parameter.DISC_MUTE + }; + + byte[] erg = m.BuildMessage(); - byte[] erg = m.BuildMessage(); - byte[] expected = new byte[] - { - 0xcc, 0x01, 0x18, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x02, 0xb0, 0x00, 0x11, - 0x22, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x04, 0x79 - }; + byte[] expected = new byte[] + { + 0xcc, 0x01, 0x18, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x02, 0xb0, 0x00, 0x11, + 0x22, 0x33, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x04, 0x7a + }; + var eM = new RDMMessage(expected); + Assert.That(m.DestUID, Is.EqualTo(eM.DestUID)); + Assert.That(m.SourceUID, Is.EqualTo(eM.SourceUID)); + Assert.That(m.Command, Is.EqualTo(eM.Command)); + Assert.That(m.Parameter, Is.EqualTo(eM.Parameter)); + Assert.That(m.PortID_or_Responsetype, Is.EqualTo(eM.PortID_or_Responsetype)); + Assert.That(m.Checksum, Is.EqualTo(eM.Checksum)); - Assert.That(erg.SequenceEqual(expected), Is.True); - } + Assert.That(expected, Is.EquivalentTo(erg)); + } + + + [Test] + public void RDMMessageNACKBuildMessage() + { + RDMMessage m = new RDMMessage(ERDM_NackReason.DATA_OUT_OF_RANGE) + { + DestUID = new UID(0x1234, 0x56789abc), + SourceUID = new UID(0x02B0, 0x00112233), + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.ENDPOINT_TO_UNIVERSE, + }; + + + byte[] erg = m.BuildMessage(); + + byte[] expected = new byte[] + { + 0xcc, 0x01, 0x1a, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x02, 0xb0, 0x00, 0x11, + 0x22, 0x33, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x09, 0x03, 0x02, 0x00, 0x06, + 0x04, 0xa0 + }; + + RDMMessage m2 = new RDMMessage(erg); + + Assert.That(m2.ResponseType, Is.EqualTo(m.ResponseType)); + Assert.That(m2.NackReason, Is.EqualTo(m.NackReason)); + Assert.That(m2.PDL, Is.EqualTo(m.PDL)); + Assert.That(m2.Command, Is.EqualTo(m.Command)); + Assert.That(erg, Is.EqualTo(expected)); + } + + + + [Test] + public void RDMMessageAckBuildMessage() + { + var ackTimer = new AcknowledgeTimer(TimeSpan.FromMilliseconds(5000)); + RDMMessage m = new RDMMessage(ackTimer) + { + DestUID = new UID(0x1234, 0x56789abc), + SourceUID = new UID(0x02B0, 0x00112233), + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.LAMP_STATE, + }; + + + byte[] erg = m.BuildMessage(); + + byte[] expected = new byte[] + { + 0xcc, 0x01, 0x1a, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x02, 0xb0, 0x00, 0x11, + 0x22, 0x33, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x04, 0x03, 0x02, 0x00, 0x32, + 0x04, 0xc6 + }; + + RDMMessage m2 = new RDMMessage(erg); + + Assert.That(m2.ResponseType, Is.EqualTo(m.ResponseType)); + Assert.That(m2.AcknowledgeTimer, Is.EqualTo(ackTimer)); + Assert.That(m2.PDL, Is.EqualTo(m.PDL)); + Assert.That(m2.Command, Is.EqualTo(m.Command)); + Assert.That(erg, Is.EqualTo(expected)); + } + [Test] + public void RDMMessageAckHighResBuildMessage() + { + var ackTimer = new AcknowledgeTimerHighRes(TimeSpan.FromMilliseconds(520)); + RDMMessage m = new RDMMessage(ackTimer) + { + DestUID = new UID(0x1234, 0x56789abc), + SourceUID = new UID(0x02B0, 0x00112233), + Command = ERDM_Command.GET_COMMAND_RESPONSE, + Parameter = ERDM_Parameter.LAMP_STATE, + }; + + + byte[] erg = m.BuildMessage(); + + byte[] expected = new byte[] + { + 0xcc, 0x01, 0x1a, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x02, 0xb0, 0x00, 0x11, + 0x22, 0x33, 0x00, 0x04, 0x00, 0x00, 0x00, 0x21, 0x04, 0x03, 0x02, 0x02, 0x08, + 0x04, 0xa1 + }; + + RDMMessage m2 = new RDMMessage(erg); + + Assert.That(m2.ResponseType, Is.EqualTo(m.ResponseType)); + Assert.That(m2.AcknowledgeTimer, Is.EqualTo(ackTimer)); + Assert.That(m2.PDL, Is.EqualTo(m.PDL)); + Assert.That(m2.Command, Is.EqualTo(m.Command)); + Assert.That(erg, Is.EqualTo(expected)); } } diff --git a/RDMSharpTests/RDMSharpTests.csproj b/RDMSharpTests/RDMSharpTests.csproj index 7135d0a8..ee7848bd 100644 --- a/RDMSharpTests/RDMSharpTests.csproj +++ b/RDMSharpTests/RDMSharpTests.csproj @@ -1,7 +1,7 @@  - net6.0;net7.0;net8.0;net9.0 + net7.0;net8.0;net9.0;net10.0 enable enable diff --git a/RDMSharpTests/Setup.cs b/RDMSharpTests/Setup.cs index cff9f609..ae8bea06 100644 --- a/RDMSharpTests/Setup.cs +++ b/RDMSharpTests/Setup.cs @@ -1,87 +1,88 @@ using RDMSharpTests.Devices.Mock; -using System; using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace RDMSharpTests +namespace RDMSharpTests; + +[SetUpFixture] +public class GlobalTestSetup { - [SetUpFixture] - public class GlobalTestSetup + private readonly ConcurrentDictionary identifyer = new ConcurrentDictionary(); + private Random rnd = new Random(); + public static bool ImitateRealConditions { get; set; } = false; // Set to false to use the Mock SendReceivePipeline + [OneTimeSetUp] + public async Task GlobalSetUp() { - private readonly ConcurrentDictionary identifyer = new ConcurrentDictionary(); - private Random rnd = new Random(); - public static bool ImitateRealConditions { get; set; } = false; // Set to false to use the Mock SendReceivePipeline - [OneTimeSetUp] - public void GlobalSetUp() + //Logging.LoggerFactory = LoggerFactory.Create(builder => + //{ + // builder + // .ClearProviders() + // .AddConsole(options => { options.TimestampFormat = "[HH:mm:ss.fff] "; }) + // .SetMinimumLevel(LogLevel.Trace); + //}); + GlobalTimers.Instance.InternalAllTimersToTestSpeed(); + await RDMSharp.RDMSharp.Initialize(new UID(), async (rdmMessage) => { - GlobalTimers.Instance.InternalAllTimersToTestSpeed(); - RDMSharp.RDMSharp.Initialize(new UID(), async (rdmMessage) => - { - await SendRDMMessage(rdmMessage); - }); - SendReceivePipelineImitateRealConditions.RDMMessageReceivedResponse += (sender, data) => - { - if (!ImitateRealConditions) - return; - if (data == null) - return; - RDMMessage rdmMessage = new RDMMessage(data); - if (rdmMessage == null) - return; - - RDMSharp.RDMSharp.Instance.ResponseReceived(rdmMessage); - }; - SendReceivePipelineImitateRealConditions.RDMMessageReceivedRequest += async (sender, rdmMessage) => - { - if (!ImitateRealConditions) - return; - if (rdmMessage == null) - return; + await SendRDMMessage(rdmMessage); + }); + SendReceivePipelineImitateRealConditions.RDMMessageReceivedResponse += (sender, data) => + { + if (!ImitateRealConditions) + return; + if (data == null) + return; + RDMMessage rdmMessage = new RDMMessage(data); + if (rdmMessage == null) + return; - if (RDMSharp.RDMSharp.Instance.RequestReceived(rdmMessage, out RDMMessage response)) - await SendRDMMessage(response); - }; - SendReceivePipeline.RDMMessageReceived += (sender, tuple) => - { - if (ImitateRealConditions) - return; - if (tuple == null) - return; - RDMMessage rdmMessage = tuple.Item2; - if (rdmMessage == null) - return; - if (rdmMessage.Command.HasFlag(ERDM_Command.RESPONSE)) - RDMSharp.RDMSharp.Instance.ResponseReceived(rdmMessage); - else - if (RDMSharp.RDMSharp.Instance.RequestReceived(rdmMessage, out RDMMessage response)) - _ = SendRDMMessage(response); - }; - } + RDMSharp.RDMSharp.Instance.ResponseReceived(rdmMessage); + }; + SendReceivePipelineImitateRealConditions.RDMMessageReceivedRequest += async (sender, rdmMessage) => + { + if (!ImitateRealConditions) + return; + if (rdmMessage == null) + return; - private async Task SendRDMMessage(RDMMessage rdmMessage) + if (RDMSharp.RDMSharp.Instance.RequestReceived(rdmMessage, out RDMMessage response)) + await SendRDMMessage(response); + }; + SendReceivePipeline.RDMMessageReceived += (sender, tuple) => { - await Task.CompletedTask; if (ImitateRealConditions) - _ = SendReceivePipelineImitateRealConditions.RDMMessageSend(rdmMessage); // in this case as responder we don't wait for comlpletion of the send, we just send it and forget it + return; + if (tuple == null) + return; + RDMMessage rdmMessage = tuple.Item2; + if (rdmMessage == null) + return; + if (rdmMessage.Command.HasFlag(ERDM_Command.RESPONSE)) + RDMSharp.RDMSharp.Instance.ResponseReceived(rdmMessage); else - { - long i = rnd.Next(); // Generate a random identifier for the message - SendReceivePipeline.RDMMessageSend(i, rdmMessage); - } - } + if (RDMSharp.RDMSharp.Instance.RequestReceived(rdmMessage, out RDMMessage response)) + _ = SendRDMMessage(response); + }; + } - [OneTimeTearDown] - public void GlobalTearDown() - { - // Wird einmal nach allen Tests ausgeführt - Console.WriteLine("Global TearDown läuft"); - } - public static bool IsRunningOnGitHubActions() + private async Task SendRDMMessage(RDMMessage rdmMessage) + { + await Task.CompletedTask; + if (ImitateRealConditions) + _ = SendReceivePipelineImitateRealConditions.RDMMessageSend(rdmMessage); // in this case as responder we don't wait for comlpletion of the send, we just send it and forget it + else { - return Environment.GetEnvironmentVariable("GITHUB_ACTIONS") == "true"; + long i = rnd.Next(); // Generate a random identifier for the message + SendReceivePipeline.RDMMessageSend(i, rdmMessage); } } + + [OneTimeTearDown] + public void GlobalTearDown() + { + // Wird einmal nach allen Tests ausgeführt + Console.WriteLine("Global TearDown läuft"); + } + public static bool IsRunningOnGitHubActions() + { + return Environment.GetEnvironmentVariable("GITHUB_ACTIONS") == "true"; + } } diff --git a/RDMSharpTests/TestAsyncRDMRequestHelper.cs b/RDMSharpTests/TestAsyncRDMRequestHelper.cs index 5dc12225..29e6308e 100644 --- a/RDMSharpTests/TestAsyncRDMRequestHelper.cs +++ b/RDMSharpTests/TestAsyncRDMRequestHelper.cs @@ -1,181 +1,180 @@ -namespace RDMSharpTests +namespace RDMSharpTests; + +public class TestAsyncRDMRequestHelper { - public class TestAsyncRDMRequestHelper + private AsyncRDMRequestHelper? asyncRDMRequestHelper; + private bool hold = false; + private SemaphoreSlim? hold_Semaphore; + + [SetUp] + public void Setup() + { + asyncRDMRequestHelper = new AsyncRDMRequestHelper(sendMethode); + hold_Semaphore = new SemaphoreSlim(1); + } + [TearDown] + public void Teardown() { - private AsyncRDMRequestHelper? asyncRDMRequestHelper; - private bool hold = false; - private SemaphoreSlim? hold_Semaphore; + asyncRDMRequestHelper?.Dispose(); + asyncRDMRequestHelper = null; + hold_Semaphore?.Dispose(); + hold_Semaphore = null; + } - [SetUp] - public void Setup() - { - asyncRDMRequestHelper = new AsyncRDMRequestHelper(sendMethode); - hold_Semaphore = new SemaphoreSlim(1); - } - [TearDown] - public void Teardown() - { - asyncRDMRequestHelper?.Dispose(); - asyncRDMRequestHelper = null; - hold_Semaphore?.Dispose(); - hold_Semaphore = null; - } + private async Task sendMethode(RDMMessage rdmMessage) + { + if (!hold || hold_Semaphore == null) + return; - private async Task sendMethode(RDMMessage rdmMessage) + if (hold_Semaphore.CurrentCount == 0) { - if (!hold || hold_Semaphore == null) - return; - - if(hold_Semaphore.CurrentCount==0) - { - await hold_Semaphore.WaitAsync(5000); - hold_Semaphore.Release(); - } - // Do nothing, just simulating sending a message + await hold_Semaphore.WaitAsync(5000); + hold_Semaphore.Release(); } + // Do nothing, just simulating sending a message + } - [Test, Order(1)] - public async Task TestSimpleBackAndForth() - { - await testPackage(new UID(3, 56), new UID(55, 90), 1, SubDevice.Root, ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.GET_COMMAND, new byte[] { 0x00, 0x01 }); - await testPackage(new UID(3, 56), new UID(55, 90), 1, new SubDevice(34), ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.GET_COMMAND, new byte[] { 0x00, 0x04 }); - await testPackage(new UID(3, 56), new UID(55, 90), 1, SubDevice.Root, ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.SET_COMMAND, new byte[] { 0x00, 0x04 }); - await testPackage(new UID(3, 56), new UID(55, 90), 1, SubDevice.Broadcast, ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.SET_COMMAND, new byte[] { 0x00, 0x04 }); + [Test, Order(1)] + public async Task TestSimpleBackAndForth() + { + await testPackage(new UID(3, 56), new UID(55, 90), 1, SubDevice.Root, ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.GET_COMMAND, new byte[] { 0x00, 0x01 }); + await testPackage(new UID(3, 56), new UID(55, 90), 1, new SubDevice(34), ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.GET_COMMAND, new byte[] { 0x00, 0x04 }); + await testPackage(new UID(3, 56), new UID(55, 90), 1, SubDevice.Root, ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.SET_COMMAND, new byte[] { 0x00, 0x04 }); + await testPackage(new UID(3, 56), new UID(55, 90), 1, SubDevice.Broadcast, ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.SET_COMMAND, new byte[] { 0x00, 0x04 }); - await testPackage(new UID(3, 56), new UID(55, 90), 1, SubDevice.Root, ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.GET_COMMAND, new byte[] { 0x00, 0x01 },1000); - } - [Test, Order(3), CancelAfter(10000)] - public async Task TestDelayedResponse() - { - await testPackage(new UID(3, 56), new UID(55, 90), 1, SubDevice.Root, ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.GET_COMMAND, new byte[] { 0x00, 0x01 }, 8000); - } + await testPackage(new UID(3, 56), new UID(55, 90), 1, SubDevice.Root, ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.GET_COMMAND, new byte[] { 0x00, 0x01 }, 1000); + } + [Test, Order(3), CancelAfter(10000)] + public async Task TestDelayedResponse() + { + await testPackage(new UID(3, 56), new UID(55, 90), 1, SubDevice.Root, ERDM_Parameter.DMX_START_ADDRESS, ERDM_Command.GET_COMMAND, new byte[] { 0x00, 0x01 }, 8000); + } - [Test, Order(6)] - public async Task TestSimultanRequests() - { - await hold_Semaphore!.WaitAsync(); - hold=true; - const int delay = 1000; - UID[] sourceUIDs = new UID[] { new UID(3, 56), new UID(3, 33), new UID(40, 33) }; - UID[] destUIDs = new UID[] { new UID(65, 90), new UID(55, 2), new UID(55, 82) }; - SubDevice[] subDevices = new SubDevice[] { SubDevice.Root, new SubDevice(34), new SubDevice(59) }; - ERDM_Parameter[] parameters = new ERDM_Parameter[] { ERDM_Parameter.DMX_START_ADDRESS, ERDM_Parameter.DMX_PERSONALITY, ERDM_Parameter.DISPLAY_INVERT }; - ERDM_Command[] commands = new ERDM_Command[] { ERDM_Command.GET_COMMAND, ERDM_Command.SET_COMMAND }; - - List tasks = new List(); - - foreach (UID sourceUID in sourceUIDs) - foreach (UID destUID in destUIDs) - foreach (SubDevice subDevice in subDevices) - foreach (ERDM_Parameter parameter in parameters) - foreach (ERDM_Command command in commands) - { - byte[]? parameterData = null; - if(parameter == ERDM_Parameter.DMX_START_ADDRESS && command == ERDM_Command.GET_COMMAND) - parameterData = new byte[] { 0x00, 0x01 }; - else if (parameter == ERDM_Parameter.DMX_PERSONALITY && command == ERDM_Command.GET_COMMAND) - parameterData = new byte[] { 0x01, 0x02 }; - else if (parameter == ERDM_Parameter.DISPLAY_INVERT && command == ERDM_Command.GET_COMMAND) - parameterData = new byte[] { 0x01 }; - tasks.Add(testPackage(sourceUID, destUID, (byte)(tasks.Count % byte.MaxValue), subDevice, parameter, command, new byte[] { 0x00, 0x01 }, delay)); - } - hold_Semaphore?.Release(); - await Task.WhenAll(tasks); - } + [Test, Order(6)] + public async Task TestSimultanRequests() + { + await hold_Semaphore!.WaitAsync(); + hold = true; + const int delay = 1000; + UID[] sourceUIDs = new UID[] { new UID(3, 56), new UID(3, 33), new UID(40, 33) }; + UID[] destUIDs = new UID[] { new UID(65, 90), new UID(55, 2), new UID(55, 82) }; + SubDevice[] subDevices = new SubDevice[] { SubDevice.Root, new SubDevice(34), new SubDevice(59) }; + ERDM_Parameter[] parameters = new ERDM_Parameter[] { ERDM_Parameter.DMX_START_ADDRESS, ERDM_Parameter.DMX_PERSONALITY, ERDM_Parameter.DISPLAY_INVERT }; + ERDM_Command[] commands = new ERDM_Command[] { ERDM_Command.GET_COMMAND, ERDM_Command.SET_COMMAND }; + + List tasks = new List(); + + foreach (UID sourceUID in sourceUIDs) + foreach (UID destUID in destUIDs) + foreach (SubDevice subDevice in subDevices) + foreach (ERDM_Parameter parameter in parameters) + foreach (ERDM_Command command in commands) + { + byte[]? parameterData = null; + if (parameter == ERDM_Parameter.DMX_START_ADDRESS && command == ERDM_Command.GET_COMMAND) + parameterData = new byte[] { 0x00, 0x01 }; + else if (parameter == ERDM_Parameter.DMX_PERSONALITY && command == ERDM_Command.GET_COMMAND) + parameterData = new byte[] { 0x01, 0x02 }; + else if (parameter == ERDM_Parameter.DISPLAY_INVERT && command == ERDM_Command.GET_COMMAND) + parameterData = new byte[] { 0x01 }; + tasks.Add(testPackage(sourceUID, destUID, (byte)(tasks.Count % byte.MaxValue), subDevice, parameter, command, new byte[] { 0x00, 0x01 }, delay)); + } + hold_Semaphore?.Release(); + await Task.WhenAll(tasks); + } - [Test, Order(7)] - public async Task TestSimultanRequestsSameTransactionID() - { - await hold_Semaphore!.WaitAsync(); - hold = true; - const int delay = 1000; - UID[] sourceUIDs = new UID[] { new UID(3, 56), new UID(3, 33), new UID(40, 33) }; - UID[] destUIDs = new UID[] { new UID(65, 90), new UID(55, 2), new UID(55, 82) }; - SubDevice[] subDevices = new SubDevice[] { SubDevice.Root, new SubDevice(34), new SubDevice(59) }; - ERDM_Parameter[] parameters = new ERDM_Parameter[] { ERDM_Parameter.DMX_START_ADDRESS, ERDM_Parameter.DMX_PERSONALITY, ERDM_Parameter.DISPLAY_INVERT }; - ERDM_Command[] commands = new ERDM_Command[] { ERDM_Command.GET_COMMAND, ERDM_Command.SET_COMMAND }; - - List tasks = new List(); - - foreach (UID sourceUID in sourceUIDs) - foreach (UID destUID in destUIDs) - foreach (SubDevice subDevice in subDevices) - foreach (ERDM_Parameter parameter in parameters) - foreach (ERDM_Command command in commands) - { - byte[]? parameterData = null; - if (parameter == ERDM_Parameter.DMX_START_ADDRESS && command == ERDM_Command.GET_COMMAND) - parameterData = new byte[] { 0x00, 0x01 }; - else if (parameter == ERDM_Parameter.DMX_PERSONALITY && command == ERDM_Command.GET_COMMAND) - parameterData = new byte[] { 0x01, 0x02 }; - else if (parameter == ERDM_Parameter.DISPLAY_INVERT && command == ERDM_Command.GET_COMMAND) - parameterData = new byte[] { 0x01 }; - tasks.Add(testPackage(sourceUID, destUID, 1, subDevice, parameter, command, new byte[] { 0x00, 0x01 }, delay)); - } - hold_Semaphore?.Release(); - await Task.WhenAll(tasks); - } + [Test, Order(7)] + public async Task TestSimultanRequestsSameTransactionID() + { + await hold_Semaphore!.WaitAsync(); + hold = true; + const int delay = 1000; + UID[] sourceUIDs = new UID[] { new UID(3, 56), new UID(3, 33), new UID(40, 33) }; + UID[] destUIDs = new UID[] { new UID(65, 90), new UID(55, 2), new UID(55, 82) }; + SubDevice[] subDevices = new SubDevice[] { SubDevice.Root, new SubDevice(34), new SubDevice(59) }; + ERDM_Parameter[] parameters = new ERDM_Parameter[] { ERDM_Parameter.DMX_START_ADDRESS, ERDM_Parameter.DMX_PERSONALITY, ERDM_Parameter.DISPLAY_INVERT }; + ERDM_Command[] commands = new ERDM_Command[] { ERDM_Command.GET_COMMAND, ERDM_Command.SET_COMMAND }; + + List tasks = new List(); + + foreach (UID sourceUID in sourceUIDs) + foreach (UID destUID in destUIDs) + foreach (SubDevice subDevice in subDevices) + foreach (ERDM_Parameter parameter in parameters) + foreach (ERDM_Command command in commands) + { + byte[]? parameterData = null; + if (parameter == ERDM_Parameter.DMX_START_ADDRESS && command == ERDM_Command.GET_COMMAND) + parameterData = new byte[] { 0x00, 0x01 }; + else if (parameter == ERDM_Parameter.DMX_PERSONALITY && command == ERDM_Command.GET_COMMAND) + parameterData = new byte[] { 0x01, 0x02 }; + else if (parameter == ERDM_Parameter.DISPLAY_INVERT && command == ERDM_Command.GET_COMMAND) + parameterData = new byte[] { 0x01 }; + tasks.Add(testPackage(sourceUID, destUID, 1, subDevice, parameter, command, new byte[] { 0x00, 0x01 }, delay)); + } + hold_Semaphore?.Release(); + await Task.WhenAll(tasks); + } - #region - private async Task testPackage(UID sourceUID, UID destUID, byte transactionCounter, SubDevice subDevice, ERDM_Parameter parameter, ERDM_Command command, byte[] parameterData, int responseDelay = 100) - { - Assert.That(sourceUID, Is.Not.EqualTo(destUID)); - Assert.That(command.HasFlag(ERDM_Command.RESPONSE), Is.False); - await testPackage( - new RDMMessage() - { - SourceUID = sourceUID, - DestUID = destUID, - TransactionCounter = transactionCounter, - SubDevice = subDevice, - Parameter = parameter, - Command = command - }, new RDMMessage() - { - DestUID = sourceUID, - SourceUID = destUID, - TransactionCounter = transactionCounter, - SubDevice = subDevice, - Parameter = parameter, - Command = command | ERDM_Command.RESPONSE, - ParameterData = parameterData - }, responseDelay); - } - private async Task testPackage(RDMMessage request, RDMMessage response, int responseDelay = 100) - { - Task task = Task.Run(async () => + #region + private async Task testPackage(UID sourceUID, UID destUID, byte transactionCounter, SubDevice subDevice, ERDM_Parameter parameter, ERDM_Command command, byte[] parameterData, int responseDelay = 100) + { + Assert.That(sourceUID, Is.Not.EqualTo(destUID)); + Assert.That(command.HasFlag(ERDM_Command.RESPONSE), Is.False); + await testPackage( + new RDMMessage() { - var result = await asyncRDMRequestHelper!.RequestMessage(request, false); - validate(request, result); - }); - await Task.Delay(responseDelay); // Simulate some delay before the next task - - asyncRDMRequestHelper!.ReceiveMessage(response); - - await task; - } - private void validate(RDMMessage request, RequestResult result) + SourceUID = sourceUID, + DestUID = destUID, + TransactionCounter = transactionCounter, + SubDevice = subDevice, + Parameter = parameter, + Command = command + }, new RDMMessage() + { + DestUID = sourceUID, + SourceUID = destUID, + TransactionCounter = transactionCounter, + SubDevice = subDevice, + Parameter = parameter, + Command = command | ERDM_Command.RESPONSE, + ParameterData = parameterData + }, responseDelay); + } + private async Task testPackage(RDMMessage request, RDMMessage response, int responseDelay = 100) + { + Task task = Task.Run(async () => { - string failMessage = $"Request: {request.ToString()} Response: {result.Response?.ToString()}"; + var result = await asyncRDMRequestHelper!.RequestMessage(request, false); + validate(request, result); + }); + await Task.Delay(responseDelay); // Simulate some delay before the next task - if (request.Command == ERDM_Command.SET_COMMAND && request.SubDevice.IsBroadcast) - { - Assert.That(result.Success, Is.True, failMessage); - Assert.That(result.Response, Is.Null, failMessage); - return; - } + asyncRDMRequestHelper!.ReceiveMessage(response); + await task; + } + private void validate(RDMMessage request, RequestResult result) + { + string failMessage = $"Request: {request.ToString()} Response: {result.Response?.ToString()}"; + + if (request.Command == ERDM_Command.SET_COMMAND && request.SubDevice.IsBroadcast) + { Assert.That(result.Success, Is.True, failMessage); - Assert.That(result.Response, Is.Not.Null, failMessage); - Assert.That(result.Response.DestUID, Is.EqualTo(request.SourceUID), failMessage); - Assert.That(result.Response.SourceUID, Is.EqualTo(request.DestUID), failMessage); - Assert.That(result.Response.SubDevice, Is.EqualTo(request.SubDevice), failMessage); - Assert.That(result.Response.TransactionCounter, Is.EqualTo(request.TransactionCounter), failMessage); - Assert.That(result.Response.Command, Is.EqualTo(request.Command | ERDM_Command.RESPONSE), failMessage); - - if (request.Command == ERDM_Command.GET_COMMAND && request.Parameter != ERDM_Parameter.QUEUED_MESSAGE) - Assert.That(result.Response.Parameter, Is.EqualTo(request.Parameter), failMessage); + Assert.That(result.Response, Is.Null, failMessage); + return; } - #endregion + + Assert.That(result.Success, Is.True, failMessage); + Assert.That(result.Response, Is.Not.Null, failMessage); + Assert.That(result.Response.DestUID, Is.EqualTo(request.SourceUID), failMessage); + Assert.That(result.Response.SourceUID, Is.EqualTo(request.DestUID), failMessage); + Assert.That(result.Response.SubDevice, Is.EqualTo(request.SubDevice), failMessage); + Assert.That(result.Response.TransactionCounter, Is.EqualTo(request.TransactionCounter), failMessage); + Assert.That(result.Response.Command, Is.EqualTo(request.Command | ERDM_Command.RESPONSE), failMessage); + + if (request.Command == ERDM_Command.GET_COMMAND && request.Parameter != ERDM_Parameter.QUEUED_MESSAGE) + Assert.That(result.Response.Parameter, Is.EqualTo(request.Parameter), failMessage); } + #endregion } \ No newline at end of file diff --git a/RDMSharpTests/TestManyObjects.cs b/RDMSharpTests/TestManyObjects.cs index 9af4ff6f..2412b78f 100644 --- a/RDMSharpTests/TestManyObjects.cs +++ b/RDMSharpTests/TestManyObjects.cs @@ -1,488 +1,488 @@ using RDMSharp.Metadata; +using RDMSharp.PayloadObject; using RDMSharp.RDM; using System.Collections.Concurrent; using System.Reflection; -namespace RDMSharpTests +namespace RDMSharpTests; + +public class TestManyObjects { - public class TestManyObjects + private static readonly Random rnd = new Random(); + [SetUp] + public void Setup() { - private static readonly Random rnd = new Random(); - [SetUp] - public void Setup() - { - } + } - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] - public void TestRDMDiscoveryStatus() + [Test] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] + public void TestRDMDiscoveryStatus() + { + RDMDiscoveryStatus status1 = new RDMDiscoveryStatus(3, (ulong)(UID.Broadcast - 1), "Test", new UID(0x1234, 0x56789fab), 11); + RDMDiscoveryStatus status2 = new RDMDiscoveryStatus(6, (ulong)(UID.Broadcast - 1) / 2, "Test2", new UID(0x1234, 0x56789fab), 22); + Assert.Multiple(() => { - RDMDiscoveryStatus status1 = new RDMDiscoveryStatus(3, (ulong)(UID.Broadcast - 1), "Test", new UID(0x1234, 0x56789fab), 11); - RDMDiscoveryStatus status2 = new RDMDiscoveryStatus(6, (ulong)(UID.Broadcast - 1) / 2, "Test2", new UID(0x1234, 0x56789fab), 22); - Assert.Multiple(() => - { - Assert.That(status1, Is.Not.EqualTo(status2)); - Assert.That((object)status1, Is.Not.EqualTo(status2)); - Assert.That((object)status1, Is.Not.EqualTo((object)status2)); - Assert.That(((object)status1).Equals((object)status2), Is.False); - Assert.That(((object)status1).Equals(status2.LastFoundUid), Is.False); - Assert.That(((object)status1).Equals(null), Is.False); - Assert.That(status1 == status2, Is.False); - Assert.That(status1 != status2, Is.True); - Assert.That(status1.GetHashCode(), Is.Not.EqualTo(status2.GetHashCode())); - var str1 = status1.ToString(); - var str2 = status2.ToString(); - Assert.That(str1, Is.Not.EqualTo(str2)); - Assert.That(str1, Has.Length.AtLeast(10)); - Assert.That(str2, Has.Length.AtLeast(10)); - }); - } - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2043:Use ComparisonConstraint for better assertion messages in case of failure", Justification = "")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] - public void TestSubDevice() + Assert.That(status1, Is.Not.EqualTo(status2)); + Assert.That((object)status1, Is.Not.EqualTo(status2)); + Assert.That((object)status1, Is.Not.EqualTo((object)status2)); + Assert.That(((object)status1).Equals((object)status2), Is.False); + Assert.That(((object)status1).Equals(status2.LastFoundUid), Is.False); + Assert.That(((object)status1).Equals(null), Is.False); + Assert.That(status1 == status2, Is.False); + Assert.That(status1 != status2, Is.True); + Assert.That(status1.GetHashCode(), Is.Not.EqualTo(status2.GetHashCode())); + var str1 = status1.ToString(); + var str2 = status2.ToString(); + Assert.That(str1, Is.Not.EqualTo(str2)); + Assert.That(str1, Has.Length.AtLeast(10)); + Assert.That(str2, Has.Length.AtLeast(10)); + }); + } + [Test] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2043:Use ComparisonConstraint for better assertion messages in case of failure", Justification = "")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] + public void TestSubDevice() + { + Assert.Multiple(() => { - Assert.Multiple(() => + List subdevices = new List(); + subdevices.Add(SubDevice.Root); + for (ushort i = 1; i <= 0x0200; i++) + subdevices.Add(new SubDevice(i)); + subdevices.Add(SubDevice.Broadcast); + + SubDevice? prev = null; + HashSet hashSet = new HashSet(); + foreach (SubDevice sd in subdevices) { - List subdevices = new List(); - subdevices.Add(SubDevice.Root); - for (ushort i = 1; i <= 0x0200; i++) - subdevices.Add(new SubDevice(i)); - subdevices.Add(SubDevice.Broadcast); - - SubDevice? prev = null; - HashSet hashSet = new HashSet(); - foreach (SubDevice sd in subdevices) + if (!prev.HasValue) { - if (!prev.HasValue) - { - prev = sd; - hashSet.Add(sd); - continue; - } - - Assert.That(prev, Is.Not.EqualTo(sd)); - Assert.That(prev, Is.Not.EqualTo(null)); - Assert.That(prev.Equals(sd), Is.False); - Assert.That(prev.Equals((object)sd), Is.False); - Assert.That(prev.Equals(null), Is.False); - Assert.That(prev.Equals((object)sd), Is.False); - Assert.That(prev.Equals(null), Is.False); - - if (!(prev!.Value.IsRoot || prev.Value.IsBroadcast || sd.IsRoot || sd.IsBroadcast)) - { - Assert.That(prev <= sd, Is.True); - Assert.That(sd >= prev, Is.True); - Assert.That(sd <= prev, Is.False); - Assert.That(prev >= sd, Is.False); - } - else - { - Assert.That(prev <= sd, Is.False); - Assert.That(sd >= prev, Is.False); - Assert.That(sd <= prev, Is.False); - Assert.That(prev >= sd, Is.False); - } - - Assert.That(prev != sd, Is.True); - Assert.That(prev == sd, Is.False); - Assert.That(string.IsNullOrWhiteSpace(prev.ToString()), Is.False); - Assert.That(string.IsNullOrWhiteSpace(sd.ToString()), Is.False); - prev = sd; - Assert.That(hashSet.Add(sd), Is.True); - Assert.That(hashSet, Does.Contain(prev.Value)); - } - for (ushort i = 0; i < 1000; i++) - { - ushort id = (ushort)rnd.Next((ushort)0x0201, (ushort)(0xFFFF - 1)); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => new SubDevice(id)); + hashSet.Add(sd); + continue; } - }); - } - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] - public void TestIPv4Address() - { - var address = IPv4Address.LocalHost; - Assert.Multiple(() => - { - Assert.That(address.ToString(), Is.EqualTo("127.0.0.1")); - Assert.That(address, Is.EqualTo(new IPv4Address(address.ToString()))); - Assert.Throws(typeof(FormatException), () => new IPv4Address("1.2.3.")); - - address = new IPv4Address(1, 1, 1, 1); - - Assert.That(address, Is.EqualTo(new IPv4Address(new byte[] { 1, 1, 1, 1 }))); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => new IPv4Address(new byte[] { 1 })); - Assert.That(address, Is.EqualTo(new IPv4Address(new List() { 1, 1, 1, 1 }))); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => new IPv4Address(new List() { 1 })); - - - byte[] bytes = new byte[] { 8, 7, 6, 5 }; - System.Net.IPAddress ip = new System.Net.IPAddress(bytes); - address = (IPv4Address)bytes; - Assert.That(ip, Is.EqualTo((System.Net.IPAddress)address)); - Assert.That(address, Is.EqualTo((IPv4Address)ip)); - - bytes = new byte[] { 1, 1, 1, 1 }; - Assert.That(bytes, Is.EqualTo((byte[])new IPv4Address(bytes))); - Assert.That(new IPv4Address(3, 4, 5, 6) == new IPv4Address("3.4.5.6"), Is.True); - Assert.That(new IPv4Address(3, 4, 5, 6) != new IPv4Address("3.4.5.6"), Is.False); - Assert.That(((object)new IPv4Address(3, 4, 5, 6)).Equals(new IPv4Address("3.4.5.6")), Is.True); - Assert.That(((object)new IPv4Address(3, 4, 5, 6)).Equals("3"), Is.False); + Assert.That(prev, Is.Not.EqualTo(sd)); + Assert.That(prev, Is.Not.EqualTo(null)); + Assert.That(prev.Equals(sd), Is.False); + Assert.That(prev.Equals((object)sd), Is.False); + Assert.That(prev.Equals(null), Is.False); + Assert.That(prev.Equals((object)sd), Is.False); + Assert.That(prev.Equals(null), Is.False); + if (!(prev!.Value.IsRoot || prev.Value.IsBroadcast || sd.IsRoot || sd.IsBroadcast)) + { + Assert.That(prev <= sd, Is.True); + Assert.That(sd >= prev, Is.True); + Assert.That(sd <= prev, Is.False); + Assert.That(prev >= sd, Is.False); + } + else + { + Assert.That(prev <= sd, Is.False); + Assert.That(sd >= prev, Is.False); + Assert.That(sd <= prev, Is.False); + Assert.That(prev >= sd, Is.False); + } - address = new IPv4Address(8, 8, 8, 8); - Assert.That(address, Is.Not.EqualTo(new IPv4Address(2, 3, 4, 5))); - Assert.That(address, Is.Not.EqualTo(new IPv4Address(8, 3, 4, 5))); - Assert.That(address, Is.Not.EqualTo(new IPv4Address(8, 8, 4, 5))); - Assert.That(address, Is.Not.EqualTo(new IPv4Address(8, 8, 8, 5))); - Assert.That(address, Is.EqualTo(new IPv4Address(8, 8, 8, 8))); - - ConcurrentDictionary dict = new ConcurrentDictionary(); - - for (byte i1 = 1; i1 < 246; i1 += 8) - for (byte i2 = 1; i2 < 246; i2 += 8) - for (byte i3 = 1; i3 < 246; i3 += 8) - for (byte i4 = 1; i4 < 246; i4 += 8) - { - address = new IPv4Address(i1, i2, i3, i4); - var res = dict.TryAdd(address, address.ToString()); - Assert.That(res, Is.True); - } + Assert.That(prev != sd, Is.True); + Assert.That(prev == sd, Is.False); + Assert.That(string.IsNullOrWhiteSpace(prev.ToString()), Is.False); + Assert.That(string.IsNullOrWhiteSpace(sd.ToString()), Is.False); - Assert.Throws(typeof(ArgumentException), () => { var ip = (IPv4Address)System.Net.IPAddress.IPv6Any; }); - }); - } - [Test] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] - public void TestMACAddress() - { - Assert.Multiple(() => - { - var address = MACAddress.Empty; - Assert.That(address.ToString(), Is.EqualTo("00:00:00:00:00:00")); - var bytes = new byte[6] { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; - address = new MACAddress(bytes); - Assert.That((byte[])address, Is.EqualTo(bytes)); - Assert.That((MACAddress)bytes, Is.EqualTo(address)); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => new MACAddress(new byte[] { 1, 2, 3, 4, 5, 6, 7 })); - Assert.That(address, Is.EqualTo(new MACAddress(new List(bytes)))); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => new MACAddress(new List() { 1, 2, 3, 4, 5 })); - Assert.That(address, Is.EqualTo(new MACAddress("11:22:33:44:55:66"))); - Assert.That(address, Is.EqualTo(new MACAddress("11-22-33-44-55-66"))); - Assert.That(address, Is.EqualTo(new MACAddress("1122.3344.5566"))); - Assert.That(address, Is.EqualTo(new MACAddress("112233445566"))); - Assert.Throws(typeof(FormatException), () => new MACAddress("0123456789AG")); - - Assert.That(new MACAddress(0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff) == new MACAddress("AA:BB:CC:DD:EE:FF"), Is.True); - Assert.That(new MACAddress(0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff) != new MACAddress("AA:BB:CC:DD:EE:FF"), Is.False); - Assert.That(((object)new MACAddress(0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff)).Equals(new MACAddress("aa:bb:cc:dD:Ee:fF")), Is.True); - Assert.That(((object)new MACAddress(0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff)).Equals("3"), Is.False); - - address = new MACAddress(8, 8, 8, 8, 8, 8); - Assert.That(address, Is.Not.EqualTo(new MACAddress(2, 3, 4, 5, 6, 7))); - Assert.That(address, Is.Not.EqualTo(new MACAddress(8, 3, 4, 5, 6, 7))); - Assert.That(address, Is.Not.EqualTo(new MACAddress(8, 8, 4, 5, 6, 7))); - Assert.That(address, Is.Not.EqualTo(new MACAddress(8, 8, 8, 5, 6, 7))); - Assert.That(address, Is.Not.EqualTo(new MACAddress(8, 8, 8, 8, 6, 7))); - Assert.That(address, Is.Not.EqualTo(new MACAddress(8, 8, 8, 8, 8, 7))); - Assert.That(address, Is.EqualTo(new MACAddress(8, 8, 8, 8, 8, 8))); - - ConcurrentDictionary dict = new ConcurrentDictionary(); - for (byte i1 = 1; i1 < 200; i1 += 24) - for (byte i2 = 1; i2 < 200; i2 += 24) - for (byte i3 = 1; i3 < 200; i3 += 24) - for (byte i4 = 1; i4 < 200; i4 += 24) - for (byte i5 = 1; i5 < 200; i5 += 24) - for (byte i6 = 1; i6 < 200; i6 += 24) - { - address = new MACAddress(i1, i2, i3, i4, i5, i6); - var res = dict.TryAdd(address, address.ToString()); - Assert.That(res, Is.True); - } - }); - } - [Test] - public void TestSlot() - { - var slot = new Slot(1); - Assert.That(slot.SlotId, Is.EqualTo(1)); - - MethodInfo updateSlotDefaultValue = slot.GetType().GetMethod("UpdateSlotDefaultValue", BindingFlags.NonPublic | BindingFlags.Instance)!; - MethodInfo updateSlotInfo = slot.GetType().GetMethod("UpdateSlotInfo", BindingFlags.NonPublic | BindingFlags.Instance)!; - MethodInfo updateSlotDescription = slot.GetType().GetMethod("UpdateSlotDescription", BindingFlags.NonPublic | BindingFlags.Instance)!; - Assert.Multiple(() => - { - Assert.Throws(typeof(InvalidOperationException), () => Helper.ThrowInnerException(() => updateSlotDefaultValue.Invoke(slot, new object[] { new RDMDefaultSlotValue(2) }))); - Assert.Throws(typeof(InvalidOperationException), () => Helper.ThrowInnerException(() => updateSlotInfo.Invoke(slot, new object[] { new RDMSlotInfo(2) }))); - Assert.Throws(typeof(InvalidOperationException), () => Helper.ThrowInnerException(() => updateSlotDescription.Invoke(slot, new object[] { new RDMSlotDescription(2) }))); - }); - Assert.Multiple(() => - { - Assert.DoesNotThrow(() => { updateSlotDefaultValue.Invoke(slot, new object[] { new RDMDefaultSlotValue(1, 200) }); }); - Assert.DoesNotThrow(() => { updateSlotInfo.Invoke(slot, new object[] { new RDMSlotInfo(1, ERDM_SlotType.SEC_TIMING, ERDM_SlotCategory.CIE_X) }); }); - Assert.DoesNotThrow(() => { updateSlotDescription.Invoke(slot, new object[] { new RDMSlotDescription(1, "rrrr") }); }); - Assert.That(slot.DefaultValue, Is.EqualTo(200)); - Assert.That(slot.Type, Is.EqualTo(ERDM_SlotType.SEC_TIMING)); - Assert.That(slot.Category, Is.EqualTo(ERDM_SlotCategory.CIE_X)); - Assert.That(slot.Description, Is.EqualTo("rrrr")); - }); - byte fired = 0; - slot.PropertyChanged += (o, e) => { fired++; }; - for (int i = 0; i < 2; i++)// To Cover Unnessicerry Updates run two times + prev = sd; + Assert.That(hashSet.Add(sd), Is.True); + Assert.That(hashSet, Does.Contain(prev.Value)); + } + for (ushort i = 0; i < 1000; i++) { - Assert.Multiple(() => - { - Assert.DoesNotThrow(() => { updateSlotDefaultValue.Invoke(slot, new object[] { new RDMDefaultSlotValue(1, 100) }); }); - Assert.DoesNotThrow(() => { updateSlotInfo.Invoke(slot, new object[] { new RDMSlotInfo(1, ERDM_SlotType.PRIMARY, ERDM_SlotCategory.COLOR_SCROLL) }); }); - Assert.DoesNotThrow(() => { updateSlotDescription.Invoke(slot, new object[] { new RDMSlotDescription(1, "aaa") }); }); - Assert.That(fired, Is.EqualTo(4)); - Assert.That(slot.DefaultValue, Is.EqualTo(100)); - Assert.That(slot.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); - Assert.That(slot.Category, Is.EqualTo(ERDM_SlotCategory.COLOR_SCROLL)); - Assert.That(slot.Description, Is.EqualTo("aaa")); - }); + ushort id = (ushort)rnd.Next((ushort)0x0201, (ushort)(0xFFFF - 1)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new SubDevice(id)); } - } - [Test] - public void TestGeneratedPersonality() + }); + } + [Test] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] + public void TestIPv4Address() + { + var address = IPv4Address.LocalHost; + Assert.Multiple(() => { - Assert.Throws(typeof(ArgumentOutOfRangeException), () => new GeneratedPersonality(0, "5CH RGB", - new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer"), - new Slot(1, ERDM_SlotCategory.STROBE, "Strobe", 33), - new Slot(2, ERDM_SlotCategory.COLOR_ADD_RED, "Red"), - new Slot(3, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green"), - new Slot(4, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue"))); - Assert.Throws(typeof(Exception), () => new GeneratedPersonality(1, "5CH RGB", - new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer"), - new Slot(1, ERDM_SlotCategory.STROBE, "Strobe", 33), - new Slot(2, ERDM_SlotCategory.COLOR_ADD_RED, "Red"), - new Slot(3, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green"), - new Slot(3, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue"))); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => new GeneratedPersonality(1, "5CH RGB", - new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer"), - new Slot(2, ERDM_SlotCategory.STROBE, "Strobe", 33), - new Slot(4, ERDM_SlotCategory.COLOR_ADD_RED, "Red"), - new Slot(6, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green"), - new Slot(8, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue"))); - - var pers = new GeneratedPersonality(1, "5CH RGB", - new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer"), - new Slot(1, ERDM_SlotCategory.STROBE, "Strobe", 33), - new Slot(2, ERDM_SlotCategory.COLOR_ADD_RED, "Red"), - new Slot(3, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green"), - new Slot(4, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue")); - - Assert.Multiple(() => - { - Assert.That(pers.ToString(), Contains.Substring(pers.ID.ToString())); - Assert.That(pers.ToString(), Contains.Substring(pers.SlotCount.ToString())); - Assert.That(pers.ToString(), Contains.Substring(pers.Description)); - Assert.That(pers.SlotCount, Is.EqualTo(5)); - Assert.That(pers.Description, Is.EqualTo("5CH RGB")); - Assert.That(pers.ID, Is.EqualTo(1)); - }); - } - [Test] - public void TestPDL() + Assert.That(address.ToString(), Is.EqualTo("127.0.0.1")); + Assert.That(address, Is.EqualTo(new IPv4Address(address.ToString()))); + Assert.Throws(typeof(FormatException), () => new IPv4Address("1.2.3.")); + + address = new IPv4Address(1, 1, 1, 1); + + Assert.That(address, Is.EqualTo(new IPv4Address(new byte[] { 1, 1, 1, 1 }))); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new IPv4Address(new byte[] { 1 })); + Assert.That(address, Is.EqualTo(new IPv4Address(new List() { 1, 1, 1, 1 }))); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new IPv4Address(new List() { 1 })); + + + byte[] bytes = new byte[] { 8, 7, 6, 5 }; + System.Net.IPAddress ip = new System.Net.IPAddress(bytes); + address = (IPv4Address)bytes; + Assert.That(ip, Is.EqualTo((System.Net.IPAddress)address)); + Assert.That(address, Is.EqualTo((IPv4Address)ip)); + + bytes = new byte[] { 1, 1, 1, 1 }; + Assert.That(bytes, Is.EqualTo((byte[])new IPv4Address(bytes))); + + Assert.That(new IPv4Address(3, 4, 5, 6) == new IPv4Address("3.4.5.6"), Is.True); + Assert.That(new IPv4Address(3, 4, 5, 6) != new IPv4Address("3.4.5.6"), Is.False); + Assert.That(((object)new IPv4Address(3, 4, 5, 6)).Equals(new IPv4Address("3.4.5.6")), Is.True); + Assert.That(((object)new IPv4Address(3, 4, 5, 6)).Equals("3"), Is.False); + + + address = new IPv4Address(8, 8, 8, 8); + Assert.That(address, Is.Not.EqualTo(new IPv4Address(2, 3, 4, 5))); + Assert.That(address, Is.Not.EqualTo(new IPv4Address(8, 3, 4, 5))); + Assert.That(address, Is.Not.EqualTo(new IPv4Address(8, 8, 4, 5))); + Assert.That(address, Is.Not.EqualTo(new IPv4Address(8, 8, 8, 5))); + Assert.That(address, Is.EqualTo(new IPv4Address(8, 8, 8, 8))); + + ConcurrentDictionary dict = new ConcurrentDictionary(); + + for (byte i1 = 1; i1 < 246; i1 += 8) + for (byte i2 = 1; i2 < 246; i2 += 8) + for (byte i3 = 1; i3 < 246; i3 += 8) + for (byte i4 = 1; i4 < 246; i4 += 8) + { + address = new IPv4Address(i1, i2, i3, i4); + var res = dict.TryAdd(address, address.ToString()); + Assert.That(res, Is.True); + } + + Assert.Throws(typeof(ArgumentException), () => { var ip = (IPv4Address)System.Net.IPAddress.IPv6Any; }); + }); + } + [Test] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] + public void TestMACAddress() + { + Assert.Multiple(() => + { + var address = MACAddress.Empty; + Assert.That(address.ToString(), Is.EqualTo("00:00:00:00:00:00")); + var bytes = new byte[6] { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; + address = new MACAddress(bytes); + Assert.That((byte[])address, Is.EqualTo(bytes)); + Assert.That((MACAddress)bytes, Is.EqualTo(address)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new MACAddress(new byte[] { 1, 2, 3, 4, 5, 6, 7 })); + Assert.That(address, Is.EqualTo(new MACAddress(new List(bytes)))); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new MACAddress(new List() { 1, 2, 3, 4, 5 })); + Assert.That(address, Is.EqualTo(new MACAddress("11:22:33:44:55:66"))); + Assert.That(address, Is.EqualTo(new MACAddress("11-22-33-44-55-66"))); + Assert.That(address, Is.EqualTo(new MACAddress("1122.3344.5566"))); + Assert.That(address, Is.EqualTo(new MACAddress("112233445566"))); + Assert.Throws(typeof(FormatException), () => new MACAddress("0123456789AG")); + + Assert.That(new MACAddress(0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff) == new MACAddress("AA:BB:CC:DD:EE:FF"), Is.True); + Assert.That(new MACAddress(0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff) != new MACAddress("AA:BB:CC:DD:EE:FF"), Is.False); + Assert.That(((object)new MACAddress(0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff)).Equals(new MACAddress("aa:bb:cc:dD:Ee:fF")), Is.True); + Assert.That(((object)new MACAddress(0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff)).Equals("3"), Is.False); + + address = new MACAddress(8, 8, 8, 8, 8, 8); + Assert.That(address, Is.Not.EqualTo(new MACAddress(2, 3, 4, 5, 6, 7))); + Assert.That(address, Is.Not.EqualTo(new MACAddress(8, 3, 4, 5, 6, 7))); + Assert.That(address, Is.Not.EqualTo(new MACAddress(8, 8, 4, 5, 6, 7))); + Assert.That(address, Is.Not.EqualTo(new MACAddress(8, 8, 8, 5, 6, 7))); + Assert.That(address, Is.Not.EqualTo(new MACAddress(8, 8, 8, 8, 6, 7))); + Assert.That(address, Is.Not.EqualTo(new MACAddress(8, 8, 8, 8, 8, 7))); + Assert.That(address, Is.EqualTo(new MACAddress(8, 8, 8, 8, 8, 8))); + + ConcurrentDictionary dict = new ConcurrentDictionary(); + for (byte i1 = 1; i1 < 200; i1 += 24) + for (byte i2 = 1; i2 < 200; i2 += 24) + for (byte i3 = 1; i3 < 200; i3 += 24) + for (byte i4 = 1; i4 < 200; i4 += 24) + for (byte i5 = 1; i5 < 200; i5 += 24) + for (byte i6 = 1; i6 < 200; i6 += 24) + { + address = new MACAddress(i1, i2, i3, i4, i5, i6); + var res = dict.TryAdd(address, address.ToString()); + Assert.That(res, Is.True); + } + }); + } + [Test] + public void TestSlot() + { + var slot = new Slot(1); + Assert.That(slot.SlotId, Is.EqualTo(1)); + + MethodInfo updateSlotDefaultValue = slot.GetType().GetMethod("UpdateSlotDefaultValue", BindingFlags.NonPublic | BindingFlags.Instance)!; + MethodInfo updateSlotInfo = slot.GetType().GetMethod("UpdateSlotInfo", BindingFlags.NonPublic | BindingFlags.Instance)!; + MethodInfo updateSlotDescription = slot.GetType().GetMethod("UpdateSlotDescription", BindingFlags.NonPublic | BindingFlags.Instance)!; + Assert.Multiple(() => + { + Assert.Throws(typeof(InvalidOperationException), () => Helper.ThrowInnerException(() => updateSlotDefaultValue.Invoke(slot, new object[] { new RDMDefaultSlotValue(2) }))); + Assert.Throws(typeof(InvalidOperationException), () => Helper.ThrowInnerException(() => updateSlotInfo.Invoke(slot, new object[] { new RDMSlotInfo(2) }))); + Assert.Throws(typeof(InvalidOperationException), () => Helper.ThrowInnerException(() => updateSlotDescription.Invoke(slot, new object[] { new RDMSlotDescription(2) }))); + }); + Assert.Multiple(() => + { + Assert.DoesNotThrow(() => { updateSlotDefaultValue.Invoke(slot, new object[] { new RDMDefaultSlotValue(1, 200) }); }); + Assert.DoesNotThrow(() => { updateSlotInfo.Invoke(slot, new object[] { new RDMSlotInfo(1, ERDM_SlotType.SEC_TIMING, ERDM_SlotCategory.CIE_X) }); }); + Assert.DoesNotThrow(() => { updateSlotDescription.Invoke(slot, new object[] { new RDMSlotDescription(1, "rrrr") }); }); + Assert.That(slot.DefaultValue, Is.EqualTo(200)); + Assert.That(slot.Type, Is.EqualTo(ERDM_SlotType.SEC_TIMING)); + Assert.That(slot.Category, Is.EqualTo(ERDM_SlotCategory.CIE_X)); + Assert.That(slot.Description, Is.EqualTo("rrrr")); + }); + byte fired = 0; + slot.PropertyChanged += (o, e) => { fired++; }; + for (int i = 0; i < 2; i++)// To Cover Unnessicerry Updates run two times { Assert.Multiple(() => { - PDL pdl = new PDL(); - Assert.That(pdl.Value.HasValue, Is.True); - Assert.That(pdl.MinLength.HasValue, Is.False); - Assert.That(pdl.MaxLength.HasValue, Is.False); - Assert.That(pdl.Value, Is.Not.Null); - Assert.That(pdl.Value!.Value, Is.EqualTo(0)); - - pdl = new PDL(13); - Assert.That(pdl.Value.HasValue, Is.True); - Assert.That(pdl.MinLength.HasValue, Is.False); - Assert.That(pdl.MaxLength.HasValue, Is.False); - Assert.That(pdl.Value, Is.Not.Null); - Assert.That(pdl.Value!.Value, Is.EqualTo(13)); - Assert.That(pdl.IsValid(13), Is.True); - Assert.That(pdl.IsValid(14), Is.False); - - - pdl = new PDL(3, 5); - Assert.That(pdl.Value.HasValue, Is.False); - Assert.That(pdl.MinLength.HasValue, Is.True); - Assert.That(pdl.MaxLength.HasValue, Is.True); - Assert.That(pdl.MinLength!.Value, Is.EqualTo(3)); - Assert.That(pdl.MaxLength!.Value, Is.EqualTo(5)); - Assert.That(pdl.IsValid(2), Is.False); - Assert.That(pdl.IsValid(3), Is.True); - Assert.That(pdl.IsValid(4), Is.True); - Assert.That(pdl.IsValid(5), Is.True); - Assert.That(pdl.IsValid(6), Is.False); - - pdl = new PDL(5, 5); - Assert.That(pdl.Value.HasValue, Is.True); - Assert.That(pdl.MinLength.HasValue, Is.False); - Assert.That(pdl.MaxLength.HasValue, Is.False); - Assert.That(pdl.Value, Is.Not.Null); - Assert.That(pdl.Value!.Value, Is.EqualTo(5)); - Assert.That(pdl.IsValid(4), Is.False); - Assert.That(pdl.IsValid(5), Is.True); - Assert.That(pdl.IsValid(6), Is.False); - - - List list = new List(); - list.Add(new PDL(1)); - list.Add(new PDL(2)); - list.Add(new PDL(3)); - pdl = new PDL(list.ToArray()); - Assert.That(pdl.Value.HasValue, Is.True); - Assert.That(pdl.MinLength.HasValue, Is.False); - Assert.That(pdl.MaxLength.HasValue, Is.False); - Assert.That(pdl.Value, Is.Not.Null); - Assert.That(pdl.Value!.Value, Is.EqualTo(6)); - - list.Clear(); - list.Add(new PDL(1, 2)); - list.Add(new PDL(1, 2)); - list.Add(new PDL(3, 4)); - pdl = new PDL(list.ToArray()); - Assert.That(pdl.Value.HasValue, Is.False); - Assert.That(pdl.MinLength.HasValue, Is.True); - Assert.That(pdl.MaxLength.HasValue, Is.True); - Assert.That(pdl.MinLength!.Value, Is.EqualTo(5)); - Assert.That(pdl.MaxLength!.Value, Is.EqualTo(8)); - - - Assert.Throws(typeof(ArgumentOutOfRangeException), () => new PDL(uint.MaxValue)); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => new PDL(uint.MaxValue, 9)); - Assert.Throws(typeof(ArgumentOutOfRangeException), () => new PDL(1, uint.MaxValue)); + Assert.DoesNotThrow(() => { updateSlotDefaultValue.Invoke(slot, new object[] { new RDMDefaultSlotValue(1, 100) }); }); + Assert.DoesNotThrow(() => { updateSlotInfo.Invoke(slot, new object[] { new RDMSlotInfo(1, ERDM_SlotType.PRIMARY, ERDM_SlotCategory.COLOR_SCROLL) }); }); + Assert.DoesNotThrow(() => { updateSlotDescription.Invoke(slot, new object[] { new RDMSlotDescription(1, "aaa") }); }); + Assert.That(fired, Is.EqualTo(4)); + Assert.That(slot.DefaultValue, Is.EqualTo(100)); + Assert.That(slot.Type, Is.EqualTo(ERDM_SlotType.PRIMARY)); + Assert.That(slot.Category, Is.EqualTo(ERDM_SlotCategory.COLOR_SCROLL)); + Assert.That(slot.Description, Is.EqualTo("aaa")); }); } - - [Test] - public void TestParameterUpdatedBag() + } + [Test] + public void TestGeneratedPersonality() + { + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new GeneratedPersonality(0, "5CH RGB", + new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer"), + new Slot(1, ERDM_SlotCategory.STROBE, "Strobe", 33), + new Slot(2, ERDM_SlotCategory.COLOR_ADD_RED, "Red"), + new Slot(3, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green"), + new Slot(4, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue"))); + Assert.Throws(typeof(Exception), () => new GeneratedPersonality(1, "5CH RGB", + new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer"), + new Slot(1, ERDM_SlotCategory.STROBE, "Strobe", 33), + new Slot(2, ERDM_SlotCategory.COLOR_ADD_RED, "Red"), + new Slot(3, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green"), + new Slot(3, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue"))); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new GeneratedPersonality(1, "5CH RGB", + new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer"), + new Slot(2, ERDM_SlotCategory.STROBE, "Strobe", 33), + new Slot(4, ERDM_SlotCategory.COLOR_ADD_RED, "Red"), + new Slot(6, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green"), + new Slot(8, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue"))); + + var pers = new GeneratedPersonality(1, "5CH RGB", + new Slot(0, ERDM_SlotCategory.INTENSITY, "Dimmer"), + new Slot(1, ERDM_SlotCategory.STROBE, "Strobe", 33), + new Slot(2, ERDM_SlotCategory.COLOR_ADD_RED, "Red"), + new Slot(3, ERDM_SlotCategory.COLOR_ADD_GREEN, "Green"), + new Slot(4, ERDM_SlotCategory.COLOR_ADD_BLUE, "Blue")); + + Assert.Multiple(() => + { + Assert.That(pers.ToString(), Contains.Substring(pers.ID.ToString())); + Assert.That(pers.ToString(), Contains.Substring(pers.SlotCount.ToString())); + Assert.That(pers.ToString(), Contains.Substring(pers.Description)); + Assert.That(pers.SlotCount, Is.EqualTo(5)); + Assert.That(pers.Description, Is.EqualTo("5CH RGB")); + Assert.That(pers.ID, Is.EqualTo(1)); + }); + } + [Test] + public void TestPDL() + { + Assert.Multiple(() => + { + PDL pdl = new PDL(); + Assert.That(pdl.Value.HasValue, Is.True); + Assert.That(pdl.MinLength.HasValue, Is.False); + Assert.That(pdl.MaxLength.HasValue, Is.False); + Assert.That(pdl.Value, Is.Not.Null); + Assert.That(pdl.Value!.Value, Is.EqualTo(0)); + + pdl = new PDL(13); + Assert.That(pdl.Value.HasValue, Is.True); + Assert.That(pdl.MinLength.HasValue, Is.False); + Assert.That(pdl.MaxLength.HasValue, Is.False); + Assert.That(pdl.Value, Is.Not.Null); + Assert.That(pdl.Value!.Value, Is.EqualTo(13)); + Assert.That(pdl.IsValid(13), Is.True); + Assert.That(pdl.IsValid(14), Is.False); + + + pdl = new PDL(3, 5); + Assert.That(pdl.Value.HasValue, Is.False); + Assert.That(pdl.MinLength.HasValue, Is.True); + Assert.That(pdl.MaxLength.HasValue, Is.True); + Assert.That(pdl.MinLength!.Value, Is.EqualTo(3)); + Assert.That(pdl.MaxLength!.Value, Is.EqualTo(5)); + Assert.That(pdl.IsValid(2), Is.False); + Assert.That(pdl.IsValid(3), Is.True); + Assert.That(pdl.IsValid(4), Is.True); + Assert.That(pdl.IsValid(5), Is.True); + Assert.That(pdl.IsValid(6), Is.False); + + pdl = new PDL(5, 5); + Assert.That(pdl.Value.HasValue, Is.True); + Assert.That(pdl.MinLength.HasValue, Is.False); + Assert.That(pdl.MaxLength.HasValue, Is.False); + Assert.That(pdl.Value, Is.Not.Null); + Assert.That(pdl.Value!.Value, Is.EqualTo(5)); + Assert.That(pdl.IsValid(4), Is.False); + Assert.That(pdl.IsValid(5), Is.True); + Assert.That(pdl.IsValid(6), Is.False); + + + List list = new List(); + list.Add(new PDL(1)); + list.Add(new PDL(2)); + list.Add(new PDL(3)); + pdl = new PDL(list.ToArray()); + Assert.That(pdl.Value.HasValue, Is.True); + Assert.That(pdl.MinLength.HasValue, Is.False); + Assert.That(pdl.MaxLength.HasValue, Is.False); + Assert.That(pdl.Value, Is.Not.Null); + Assert.That(pdl.Value!.Value, Is.EqualTo(6)); + + list.Clear(); + list.Add(new PDL(1, 2)); + list.Add(new PDL(1, 2)); + list.Add(new PDL(3, 4)); + pdl = new PDL(list.ToArray()); + Assert.That(pdl.Value.HasValue, Is.False); + Assert.That(pdl.MinLength.HasValue, Is.True); + Assert.That(pdl.MaxLength.HasValue, Is.True); + Assert.That(pdl.MinLength!.Value, Is.EqualTo(5)); + Assert.That(pdl.MaxLength!.Value, Is.EqualTo(8)); + + + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new PDL(uint.MaxValue)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new PDL(uint.MaxValue, 9)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new PDL(1, uint.MaxValue)); + }); + } + + [Test] + public void TestParameterUpdatedBag() + { + Assert.Multiple(() => { - Assert.Multiple(() => - { - ParameterUpdatedBag bag = new ParameterUpdatedBag(ERDM_Parameter.SENSOR_DEFINITION, 1); - Assert.That(bag.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_DEFINITION)); - Assert.That(bag.Index, Is.EqualTo(1)); - var secounds = DateTime.UtcNow.TimeOfDay.TotalSeconds; - var utc = DateTime.UtcNow; - Assert.That(bag.Timestamp.TimeOfDay.TotalSeconds, Is.InRange(secounds - 2, secounds + 2)); - Assert.That(bag.ToString(), Contains.Substring("SENSOR_DEFINITION")); - Assert.That(bag.ToString(), Contains.Substring("(1)")); + ParameterUpdatedBag bag = new ParameterUpdatedBag(ERDM_Parameter.SENSOR_DEFINITION, 1); + Assert.That(bag.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_DEFINITION)); + Assert.That(bag.Index, Is.EqualTo(1)); + var secounds = DateTime.UtcNow.TimeOfDay.TotalSeconds; + var utc = DateTime.UtcNow; + Assert.That(bag.Timestamp.TimeOfDay.TotalSeconds, Is.InRange(secounds - 2, secounds + 2)); + Assert.That(bag.ToString(), Contains.Substring("SENSOR_DEFINITION")); + Assert.That(bag.ToString(), Contains.Substring("(1)")); - string formattedDate = utc.ToString("d", System.Globalization.CultureInfo.CurrentCulture); - Assert.That(bag.ToString(), Contains.Substring(formattedDate)); + string formattedDate = utc.ToString("d", System.Globalization.CultureInfo.CurrentCulture); + Assert.That(bag.ToString(), Contains.Substring(formattedDate)); - bag = new ParameterUpdatedBag(ERDM_Parameter.ADD_TAG); - Assert.That(bag.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); - Assert.That(bag.Index, Is.Null); - Assert.That(bag.ToString(), Contains.Substring("ADD_TAG")); - formattedDate = utc.ToString("d", System.Globalization.CultureInfo.CurrentCulture); - Assert.That(bag.ToString(), Contains.Substring(formattedDate)); - }); - } - [Test] - public void TestParameterDataCacheBag() + bag = new ParameterUpdatedBag(ERDM_Parameter.ADD_TAG); + Assert.That(bag.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); + Assert.That(bag.Index, Is.Null); + Assert.That(bag.ToString(), Contains.Substring("ADD_TAG")); + formattedDate = utc.ToString("d", System.Globalization.CultureInfo.CurrentCulture); + Assert.That(bag.ToString(), Contains.Substring(formattedDate)); + }); + } + [Test] + public void TestParameterDataCacheBag() + { + Assert.Multiple(() => { - Assert.Multiple(() => - { - ParameterDataCacheBag bag = new ParameterDataCacheBag(ERDM_Parameter.SENSOR_DEFINITION, 1); - Assert.That(bag.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_DEFINITION)); - Assert.That(bag.Index, Is.EqualTo(1)); - Assert.That(bag.ToString(), Contains.Substring("SENSOR_DEFINITION")); - Assert.That(bag.ToString(), Contains.Substring("(1)")); - - bag = new ParameterDataCacheBag(ERDM_Parameter.ADD_TAG); - Assert.That(bag.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); - Assert.That(bag.Index, Is.Null); - Assert.That(bag.ToString(), Is.EqualTo("ADD_TAG")); - }); - } - [Test] - public void TestPeerToPeerProcess() + ParameterDataCacheBag bag = new ParameterDataCacheBag(ERDM_Parameter.SENSOR_DEFINITION, 1); + Assert.That(bag.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_DEFINITION)); + Assert.That(bag.Index, Is.EqualTo(1)); + Assert.That(bag.ToString(), Contains.Substring("SENSOR_DEFINITION")); + Assert.That(bag.ToString(), Contains.Substring("(1)")); + + bag = new ParameterDataCacheBag(ERDM_Parameter.ADD_TAG); + Assert.That(bag.Parameter, Is.EqualTo(ERDM_Parameter.ADD_TAG)); + Assert.That(bag.Index, Is.Null); + Assert.That(bag.ToString(), Is.EqualTo("ADD_TAG")); + }); + } + [Test] + public void TestPeerToPeerProcess() + { + + ParameterBag bag = new ParameterBag(ERDM_Parameter.DMX_START_ADDRESS, 1234, 333, 4); + PeerToPeerProcess ptp = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, new UID(1234, 5678), SubDevice.Root, bag); + Assert.Multiple(() => { - - ParameterBag bag = new ParameterBag(ERDM_Parameter.DMX_START_ADDRESS, 1234, 333, 4); - PeerToPeerProcess ptp = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, new UID(1234, 5678), SubDevice.Root, bag); - Assert.Multiple(() => - { - Assert.That(ptp.Command, Is.EqualTo(ERDM_Command.GET_COMMAND)); - Assert.That(ptp.SubDevice, Is.EqualTo(SubDevice.Root)); - Assert.That(ptp.RequestPayloadObject, Is.EqualTo(DataTreeBranch.Unset)); - }); - Assert.Multiple(() => - { - Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.DISCOVERY_COMMAND, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); - Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.DISCOVERY_COMMAND_RESPONSE, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); - Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.GET_COMMAND_RESPONSE, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); - Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.SET_COMMAND_RESPONSE, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); - Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.NONE, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); - Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.RESPONSE, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); - }); - } - - [Test] - public void TestSensor() + Assert.That(ptp.Command, Is.EqualTo(ERDM_Command.GET_COMMAND)); + Assert.That(ptp.SubDevice, Is.EqualTo(SubDevice.Root)); + Assert.That(ptp.RequestPayloadObject, Is.EqualTo(DataTreeBranch.Unset)); + }); + Assert.Multiple(() => { - ConcurrentDictionary dict = new ConcurrentDictionary(); - Sensor sensor = new Sensor(2); - Assert.DoesNotThrow(() => { sensor.PropertyChanged += Sensor_PropertyChanged; }); - sensor.UpdateDescription(new RDMSensorDefinition(2, 1, 2, 3, 4, 5, 6, 7, true, true, "test")); - sensor.UpdateValue(new RDMSensorValue(2, 44, 33, 55, 40)); - Assert.Multiple(() => - { - Assert.That(sensor, Is.Not.Null); - Assert.That(Sensor.Equals(sensor, null), Is.False); - Assert.That(Object.Equals(sensor, null), Is.False); - Assert.That(sensor!.Equals(null), Is.False); - Assert.That(sensor!.SensorId, Is.EqualTo(2)); - Assert.That(sensor.Description, Is.Not.Null); - Assert.That(sensor.Description, Is.EqualTo("test")); - Assert.That(sensor.PresentValue, Is.EqualTo(44)); - Assert.That(sensor.LowestValue, Is.EqualTo(33)); - Assert.That(sensor.HighestValue, Is.EqualTo(55)); - Assert.That(sensor.RecordedValue, Is.EqualTo(40)); - Assert.That(sensor.Type, Is.EqualTo(ERDM_SensorType.VOLTAGE)); - Assert.That(sensor.Unit, Is.EqualTo(ERDM_SensorUnit.VOLTS_DC)); - Assert.That(sensor.Prefix, Is.EqualTo(ERDM_UnitPrefix.MILLI)); - Assert.That(sensor.RangeMaximum, Is.EqualTo(5)); - Assert.That(sensor.RangeMinimum, Is.EqualTo(4)); - Assert.That(sensor.NormalMaximum, Is.EqualTo(7)); - Assert.That(sensor.NormalMinimum, Is.EqualTo(6)); - Assert.That(sensor.LowestHighestValueSupported, Is.True); - Assert.That(sensor.RecordedValueSupported, Is.True); - Assert.That(sensor.ToString(), Contains.Substring("Sensor: 2")); - Assert.That(sensor.ToString(), Contains.Substring("PresentValue: 44")); - Assert.That(sensor.ToString(), Contains.Substring("LowestValue: 33")); - Assert.That(sensor.ToString(), Contains.Substring("HighestValue: 55")); - Assert.That(sensor.ToString(), Contains.Substring("RecordedValue: 40")); - Assert.That(sensor.ToString(), Contains.Substring("Description: test")); - Assert.DoesNotThrow(() => { sensor.PropertyChanged -= Sensor_PropertyChanged; }); - }); - Assert.Throws(typeof(InvalidOperationException), () => sensor.UpdateDescription(new RDMSensorDefinition(5, 1, 2, 3, 4, 5, 6, 7, true, true, "test"))); - Assert.Throws(typeof(InvalidOperationException), () => sensor.UpdateValue(new RDMSensorValue(9, 44, 33, 55, 40))); - Assert.Throws(typeof(ArgumentNullException), () => new Sensor(1, ERDM_SensorType.TIME, ERDM_SensorUnit.NEWTON, ERDM_UnitPrefix.PETA, null, 1, 2, 3, 4, true, false)); - - //Test again to cover the Update methods and CodeCoverage - sensor.UpdateDescription(new RDMSensorDefinition(2, 1, 2, 3, 4, 5, 6, 7, true, true, "test")); - sensor.UpdateValue(new RDMSensorValue(2, 44, 33, 55, 40)); - - sensor.UpdateDescription(new RDMSensorDefinition(2, 1, 2, 3, 4, 5, 6, 7, false, false, "test")); - sensor.UpdateValue(new RDMSensorValue(2, 44, 33, 55, 40)); - - Assert.That(sensor.LowestHighestValueSupported, Is.False); - Assert.That(sensor.RecordedValueSupported, Is.False); - Assert.That(dict, Has.Count.EqualTo(14)); - Assert.That(sensor.GetHashCode(), Is.Not.EqualTo(0)); - - void Sensor_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) - { - dict.AddOrUpdate(e!.PropertyName!, 1, (key, oldValue) => null!); - } + Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.DISCOVERY_COMMAND, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); + Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.DISCOVERY_COMMAND_RESPONSE, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); + Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.GET_COMMAND_RESPONSE, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); + Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.SET_COMMAND_RESPONSE, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); + Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.NONE, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); + Assert.Throws(typeof(ArgumentException), () => new PeerToPeerProcess(ERDM_Command.RESPONSE, new UID(1234, 5678), SubDevice.Root, bag, DataTreeBranch.Unset)); + }); + } + + [Test] + public void TestSensor() + { + ConcurrentDictionary dict = new ConcurrentDictionary(); + Sensor sensor = new Sensor(2); + Assert.DoesNotThrow(() => { sensor.PropertyChanged += Sensor_PropertyChanged; }); + sensor.UpdateDescription(new RDMSensorDefinition(2, 1, 2, 3, 4, 5, 6, 7, true, true, "test")); + sensor.UpdateValue(new RDMSensorValue(2, 44, 33, 55, 40)); + Assert.Multiple(() => + { + Assert.That(sensor, Is.Not.Null); + Assert.That(Sensor.Equals(sensor, null), Is.False); + Assert.That(Object.Equals(sensor, null), Is.False); + Assert.That(sensor!.Equals(null), Is.False); + Assert.That(sensor!.SensorId, Is.EqualTo(2)); + Assert.That(sensor.Description, Is.Not.Null); + Assert.That(sensor.Description, Is.EqualTo("test")); + Assert.That(sensor.PresentValue, Is.EqualTo(44)); + Assert.That(sensor.LowestValue, Is.EqualTo(33)); + Assert.That(sensor.HighestValue, Is.EqualTo(55)); + Assert.That(sensor.RecordedValue, Is.EqualTo(40)); + Assert.That(sensor.Type, Is.EqualTo(ERDM_SensorType.VOLTAGE)); + Assert.That(sensor.Unit, Is.EqualTo(ERDM_SensorUnit.VOLTS_DC)); + Assert.That(sensor.Prefix, Is.EqualTo(ERDM_UnitPrefix.MILLI)); + Assert.That(sensor.RangeMaximum, Is.EqualTo(5)); + Assert.That(sensor.RangeMinimum, Is.EqualTo(4)); + Assert.That(sensor.NormalMaximum, Is.EqualTo(7)); + Assert.That(sensor.NormalMinimum, Is.EqualTo(6)); + Assert.That(sensor.LowestHighestValueSupported, Is.True); + Assert.That(sensor.RecordedValueSupported, Is.True); + Assert.That(sensor.ToString(), Contains.Substring("Sensor: 2")); + Assert.That(sensor.ToString(), Contains.Substring("PresentValue: 44")); + Assert.That(sensor.ToString(), Contains.Substring("LowestValue: 33")); + Assert.That(sensor.ToString(), Contains.Substring("HighestValue: 55")); + Assert.That(sensor.ToString(), Contains.Substring("RecordedValue: 40")); + Assert.That(sensor.ToString(), Contains.Substring("Description: test")); + Assert.DoesNotThrow(() => { sensor.PropertyChanged -= Sensor_PropertyChanged; }); + }); + Assert.Throws(typeof(InvalidOperationException), () => sensor.UpdateDescription(new RDMSensorDefinition(5, 1, 2, 3, 4, 5, 6, 7, true, true, "test"))); + Assert.Throws(typeof(InvalidOperationException), () => sensor.UpdateValue(new RDMSensorValue(9, 44, 33, 55, 40))); + Assert.Throws(typeof(ArgumentNullException), () => new Sensor(1, ERDM_SensorType.TIME, ERDM_SensorUnit.NEWTON, ERDM_UnitPrefix.PETA, null, 1, 2, 3, 4, true, false)); + + //Test again to cover the Update methods and CodeCoverage + sensor.UpdateDescription(new RDMSensorDefinition(2, 1, 2, 3, 4, 5, 6, 7, true, true, "test")); + sensor.UpdateValue(new RDMSensorValue(2, 44, 33, 55, 40)); + + sensor.UpdateDescription(new RDMSensorDefinition(2, 1, 2, 3, 4, 5, 6, 7, false, false, "test")); + sensor.UpdateValue(new RDMSensorValue(2, 44, 33, 55, 40)); + + Assert.That(sensor.LowestHighestValueSupported, Is.False); + Assert.That(sensor.RecordedValueSupported, Is.False); + Assert.That(dict, Has.Count.EqualTo(14)); + Assert.That(sensor.GetHashCode(), Is.Not.EqualTo(0)); + + void Sensor_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) + { + dict.AddOrUpdate(e!.PropertyName!, 1, (key, oldValue) => null!); } - } + } } \ No newline at end of file diff --git a/README.md b/README.md index 12171554..76b8a01e 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ RDMSharp is a C# library that abstracts the communication using Remote Device Ma - **Device discovery** and management - **Support for all major RDM commands** - **Extensible architecture** for custom device types and parameters -- **Cross-platform**: Works on .NET 6, .NET 7, .NET 8, .NET 9 and in future upcomming versions +- **Cross-platform**: Works on .NET 6, .NET 7, .NET 8, .NET 9, .NET 10 and in future upcomming versions - **Comprehensive error handling** and logging - **Unit tested** for reliability @@ -37,7 +37,7 @@ Or via the NuGet Package Manager in Visual Studio. - [![.NET 7](https://img.shields.io/badge/.NET%207-5C2D91?logo=.net&logoColor=white)](https://dotnet.microsoft.com/download/dotnet/7.0) (not recommended) - [![.NET 8](https://img.shields.io/badge/.NET%208-5C2D91?logo=.net&logoColor=white)](https://dotnet.microsoft.com/download/dotnet/8.0) - [![.NET 9](https://img.shields.io/badge/.NET%209-5C2D91?logo=.net&logoColor=white)](https://dotnet.microsoft.com/download/dotnet/9.0) -- [![.NET 10](https://img.shields.io/badge/.NET%2010-5C2D91?logo=.net&logoColor=white)](https://dotnet.microsoft.com/download/dotnet/10.0) (upcoming) +- [![.NET 10](https://img.shields.io/badge/.NET%2010-5C2D91?logo=.net&logoColor=white)](https://dotnet.microsoft.com/download/dotnet/10.0) ## Contributing