From f01d98b08317f343d890b51644ce29c0d4861d23 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 22 May 2025 17:58:16 +0200 Subject: [PATCH 01/20] Add Tests for AsyncRDMRequestHelper --- RDMSharp/RDM/AsyncRDMRequestHelper.cs | 131 +++++++++++++-- RDMSharp/RDM/RDMMessage.cs | 10 +- RDMSharp/RDM/RequestResult.cs | 9 +- RDMSharpTests/TestAsyncRDMRequestHelper.cs | 181 +++++++++++++++++++++ 4 files changed, 310 insertions(+), 21 deletions(-) create mode 100644 RDMSharpTests/TestAsyncRDMRequestHelper.cs diff --git a/RDMSharp/RDM/AsyncRDMRequestHelper.cs b/RDMSharp/RDM/AsyncRDMRequestHelper.cs index ad86b04..607b4eb 100644 --- a/RDMSharp/RDM/AsyncRDMRequestHelper.cs +++ b/RDMSharp/RDM/AsyncRDMRequestHelper.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Logging; using System; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -11,7 +12,7 @@ public class AsyncRDMRequestHelper : IDisposable { private static readonly ILogger Logger = null; private static readonly Random random = new Random(); - private readonly ConcurrentDictionary> buffer = new ConcurrentDictionary>(); + private readonly ConcurrentDictionary buffer = new ConcurrentDictionary(); private readonly Func _sendMethode; private CancellationTokenSource _cts; public bool IsDisposing, IsDisposed; @@ -40,29 +41,42 @@ public bool ReceiveMessage(RDMMessage rdmMessage) if (rdmMessage.Command == ERDM_Command.DISCOVERY_COMMAND_RESPONSE) { - var o = buffer.FirstOrDefault(b => b.Value.Item1.Parameter == rdmMessage.Parameter); + var o = buffer.FirstOrDefault(b => b.Value.Request.Parameter == rdmMessage.Parameter); if (o.Value == null) return false; - var tuple = new Tuple(o.Value.Item1, rdmMessage); - buffer.AddOrUpdate(o.Key, tuple, (x, y) => tuple); + + updateBag(o.Value, 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.Item1.Parameter != ERDM_Parameter.QUEUED_MESSAGE).FirstOrDefault(b => b.Value.Item2 == null && checkNonQueued(b.Value.Item1, rdmMessage)); + 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) { - var tuple = new Tuple(obj.Value.Item1, rdmMessage); - buffer.AddOrUpdate(obj.Key, tuple, (x, y) => tuple); + updateBag(obj.Value, rdmMessage); return true; } //Queued Parameters - obj = buffer.Where(b => b.Value.Item1.Parameter == ERDM_Parameter.QUEUED_MESSAGE).FirstOrDefault(b => b.Value.Item2 == null && rdmMessage.TransactionCounter == b.Value.Item1.TransactionCounter && b.Value.Item1.DestUID == rdmMessage.SourceUID && b.Value.Item1.SourceUID == rdmMessage.DestUID); + 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) { - var tuple = new Tuple(obj.Value.Item1, rdmMessage); - buffer.AddOrUpdate(obj.Key, tuple, (x, y) => tuple); + 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; bool checkNonQueued(RDMMessage request, RDMMessage response) @@ -77,6 +91,23 @@ bool checkNonQueued(RDMMessage request, RDMMessage response) 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; } @@ -87,14 +118,20 @@ public async Task RequestMessage(RDMMessage requerst) { try { - int key = random.Next(); + int key = generateKey(requerst); if (requerst.SubDevice.IsBroadcast) { + Logger?.LogTrace($"Send Subdevice-Broadcast Request: {requerst.ToString()}"); await _sendMethode.Invoke(requerst); - return new RequestResult(requerst, null); // Broadcasts are not expected to return a response. + return new RequestResult(requerst, null, TimeSpan.Zero); // Broadcasts are not expected to return a response. + } + if (!buffer.TryAdd(key, new AsyncBufferBag(key, requerst))) + { + key += random.Next(); + buffer.TryAdd(key, new AsyncBufferBag(key, requerst)); } - buffer.TryAdd(key, new Tuple(requerst, null)); RDMMessage response = null; + Logger?.LogTrace($"Send Request: {requerst.ToString()}"); await _sendMethode.Invoke(requerst); int count = 0; do @@ -102,8 +139,8 @@ public async Task RequestMessage(RDMMessage requerst) if (this.IsDisposing || this.IsDisposed) return new RequestResult(requerst); - buffer.TryGetValue(key, out Tuple tuple1); - response = tuple1.Item2; + buffer.TryGetValue(key, out AsyncBufferBag bag); + response = bag?.Response; if (response != null) break; await Task.Delay(5, _cts.Token); @@ -115,6 +152,7 @@ public async Task RequestMessage(RDMMessage requerst) if (count % 300 == 299) { await Task.Delay(TimeSpan.FromTicks(random.Next(33, 777)), _cts.Token); + Logger?.LogTrace($"Retry Request: {requerst.ToString()} ElapsedTime: {bag.ElapsedTime}"); await _sendMethode.Invoke(requerst); await Task.Delay(TimeSpan.FromTicks(random.Next(33, 777)), _cts.Token); } @@ -122,12 +160,17 @@ public async Task RequestMessage(RDMMessage requerst) break; if (count == 3000) + { + Logger?.LogTrace($"Timeout Request: {requerst.ToString()} ElapsedTime: {bag.ElapsedTime}"); return new RequestResult(requerst); + } } while (response == null); - buffer.TryRemove(key, out Tuple tuple2); - response = tuple2.Item2; - return new RequestResult(requerst, response); + buffer.TryRemove(key, out AsyncBufferBag bag2); + response = bag2.Response; + var result = new RequestResult(requerst, response, bag2.ElapsedTime); + Logger?.LogTrace($"Successful Request: {requerst.ToString()} Response: {response.ToString()} ElapsedTime: {bag2.ElapsedTime}"); + return result; } catch (Exception ex) { @@ -135,5 +178,57 @@ public async Task RequestMessage(RDMMessage requerst) } return new RequestResult(requerst); } + private int generateKey(RDMMessage request) + { + var command = (ERDM_Command)((byte)request.Command & ~(byte)ERDM_Command.RESPONSE); + + 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; + + public RDMMessage Response { get; private set; } + public DateTime? ResponseTimeStamp { get; private set; } + + private TimeSpan? elapsedTime; + public TimeSpan ElapsedTime + { + get + { + 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/RDMMessage.cs b/RDMSharp/RDM/RDMMessage.cs index 4a1938d..87ce8de 100644 --- a/RDMSharp/RDM/RDMMessage.cs +++ b/RDMSharp/RDM/RDMMessage.cs @@ -448,7 +448,15 @@ public override string ToString() Command == ERDM_Command.SET_COMMAND_RESPONSE || Command.HasFlag(ERDM_Command.DISCOVERY_COMMAND)) { - var val = this.Value; + object val = null; + try + { + val = this.Value; + } + catch + { + + } if (val != null) b.AppendLine("Value: " + valueString()); diff --git a/RDMSharp/RDM/RequestResult.cs b/RDMSharp/RDM/RequestResult.cs index a93e0b5..cd40d0d 100644 --- a/RDMSharp/RDM/RequestResult.cs +++ b/RDMSharp/RDM/RequestResult.cs @@ -1,4 +1,6 @@ -namespace RDMSharp +using System; + +namespace RDMSharp { public readonly struct RequestResult { @@ -6,6 +8,7 @@ public readonly struct RequestResult public readonly RDMMessage Response; public readonly bool Success; public readonly bool Cancel; + public readonly TimeSpan? ElapsedTime; public RequestResult(in RDMMessage request, in bool cancle = false) { @@ -13,13 +16,15 @@ public RequestResult(in RDMMessage request, in bool cancle = false) Response = null; Success = false; Cancel = cancle; + ElapsedTime = null; } - public RequestResult(in RDMMessage request, in RDMMessage response) + 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/RDMSharpTests/TestAsyncRDMRequestHelper.cs b/RDMSharpTests/TestAsyncRDMRequestHelper.cs new file mode 100644 index 0000000..688e14d --- /dev/null +++ b/RDMSharpTests/TestAsyncRDMRequestHelper.cs @@ -0,0 +1,181 @@ +namespace RDMSharpTests +{ + 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() + { + asyncRDMRequestHelper?.Dispose(); + asyncRDMRequestHelper = null; + hold_Semaphore?.Dispose(); + hold_Semaphore = null; + } + + private async Task sendMethode(RDMMessage rdmMessage) + { + if (!hold) + return; + + if(hold_Semaphore.CurrentCount==0) + { + 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 }); + + 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(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 = 10) + { + 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 = 10) + { + Task task = Task.Run(async () => + { + var result = await asyncRDMRequestHelper!.RequestMessage(request); + 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) + { + string faliMessage = $"Request: {request.ToString()} Response: {result.Response?.ToString()}"; + + if (request.Command == ERDM_Command.SET_COMMAND && request.SubDevice.IsBroadcast) + { + Assert.That(result.Success, Is.True, faliMessage); + Assert.That(result.Response, Is.Null, faliMessage); + return; + } + + Assert.That(result.Success, Is.True, faliMessage); + Assert.That(result.Response, Is.Not.Null, faliMessage); + Assert.That(result.Response.DestUID, Is.EqualTo(request.SourceUID), faliMessage); + Assert.That(result.Response.SourceUID, Is.EqualTo(request.DestUID), faliMessage); + Assert.That(result.Response.SubDevice, Is.EqualTo(request.SubDevice), faliMessage); + Assert.That(result.Response.TransactionCounter, Is.EqualTo(request.TransactionCounter), faliMessage); + Assert.That(result.Response.Command, Is.EqualTo(request.Command | ERDM_Command.RESPONSE), faliMessage); + + if (request.Command == ERDM_Command.GET_COMMAND && request.Parameter != ERDM_Parameter.QUEUED_MESSAGE) + Assert.That(result.Response.Parameter, Is.EqualTo(request.Parameter), faliMessage); + } + #endregion + } +} \ No newline at end of file From 9baefbe10dabf1e541a89ea0290a682d804e0798 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 22 May 2025 18:09:43 +0200 Subject: [PATCH 02/20] grr --- RDMSharpTests/TestAsyncRDMRequestHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RDMSharpTests/TestAsyncRDMRequestHelper.cs b/RDMSharpTests/TestAsyncRDMRequestHelper.cs index 688e14d..66fcd70 100644 --- a/RDMSharpTests/TestAsyncRDMRequestHelper.cs +++ b/RDMSharpTests/TestAsyncRDMRequestHelper.cs @@ -117,7 +117,7 @@ public async Task TestSimultanRequestsSameTransactionID() } #region - private async Task testPackage(UID sourceUID, UID destUID, byte transactionCounter, SubDevice subDevice, ERDM_Parameter parameter, ERDM_Command command, byte[] parameterData, int responseDelay = 10) + 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); @@ -141,7 +141,7 @@ await testPackage( ParameterData = parameterData }, responseDelay); } - private async Task testPackage(RDMMessage request, RDMMessage response, int responseDelay = 10) + private async Task testPackage(RDMMessage request, RDMMessage response, int responseDelay = 100) { Task task = Task.Run(async () => { From 9ceadf75469b559f0fd9b8e671aeeda6cb445fd8 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 22 May 2025 18:48:13 +0200 Subject: [PATCH 03/20] Grr --- RDMSharp/RDM/AsyncRDMRequestHelper.cs | 2 ++ .../RDM/Discovery/AbstractDiscoveryTool.cs | 19 ++++++++++++++----- RDMSharpTests/Devices/TestRDMDiscovery.cs | 11 ++++++----- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/RDMSharp/RDM/AsyncRDMRequestHelper.cs b/RDMSharp/RDM/AsyncRDMRequestHelper.cs index 607b4eb..67c183f 100644 --- a/RDMSharp/RDM/AsyncRDMRequestHelper.cs +++ b/RDMSharp/RDM/AsyncRDMRequestHelper.cs @@ -181,6 +181,8 @@ public async Task RequestMessage(RDMMessage requerst) 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 diff --git a/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs b/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs index 826bdee..3d191c2 100644 --- a/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs +++ b/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs @@ -3,14 +3,16 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace RDMSharp { - public abstract class AbstractDiscoveryTool : INotifyPropertyChanged + public abstract class AbstractDiscoveryTool : INotifyPropertyChanged, IDisposable { private protected static ILogger Logger = null; private readonly AsyncRDMRequestHelper asyncRDMRequestHelper; + private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); public event PropertyChangedEventHandler PropertyChanged; public bool discoveryInProgress; public bool DiscoveryInProgress @@ -34,7 +36,7 @@ public AbstractDiscoveryTool() protected void ReceiveRDMMessage(RDMMessage rdmMessage) { - asyncRDMRequestHelper.ReceiveMessage(rdmMessage); + asyncRDMRequestHelper?.ReceiveMessage(rdmMessage); } public async Task> PerformDiscovery(IProgress progress = null, bool full = true) @@ -54,7 +56,7 @@ public async Task> PerformDiscovery(IProgress> PerformDiscovery(IProgress m.UID).ToList(); await AssertDiscovery(); } - [Test] + [Test, Retry(3)] public async Task TestDiscovery2() { mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234254))); @@ -110,7 +111,7 @@ public async Task TestDiscovery2() expected = mockDevices.Select(m => m.UID).ToList(); await AssertDiscovery(); } - [Test] + [Test, Retry(3)] public async Task TestDiscovery3() { mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234254))); @@ -132,7 +133,7 @@ public async Task TestDiscovery3() expected = mockDevices.Select(m => m.UID).ToList(); await AssertDiscovery(); } - [Test] + [Test, Retry(3)] public async Task TestDiscovery4() { HashSet ids = new HashSet(); From 168b82c75f52a3273fcf099b3f9bc8f9e061b69c Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 22 May 2025 18:54:09 +0200 Subject: [PATCH 04/20] Grrr --- .../Devices/Mock/SendReceivePipelineImitateRealConditions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs b/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs index 995aa15..32877dc 100644 --- a/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs +++ b/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs @@ -40,7 +40,7 @@ public static async Task RDMMessageSend(RDMMessage rdmMessage) if (semaphoreSlim.CurrentCount == 1) { await semaphoreSlim.WaitAsync(); - await Task.Delay(3); + await Task.Delay(10); await semaphoreSlim2.WaitAsync(); RDMMessageRereivedResponse?.InvokeFailSafe(null, data); From 8e162de96cf56e64083430ba613d0097a528eef0 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 22 May 2025 19:09:56 +0200 Subject: [PATCH 05/20] Grrr --- RDMSharp/RDM/Discovery/RDMDiscoveryContext.cs | 2 +- RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RDMSharp/RDM/Discovery/RDMDiscoveryContext.cs b/RDMSharp/RDM/Discovery/RDMDiscoveryContext.cs index 308969c..993ac74 100644 --- a/RDMSharp/RDM/Discovery/RDMDiscoveryContext.cs +++ b/RDMSharp/RDM/Discovery/RDMDiscoveryContext.cs @@ -133,7 +133,7 @@ private RDMDiscoveryStatus GetStatus() { if (_status.FoundDevices.Equals(FoundCount) && _status.RangeLeftToSearch.Equals(rangeToSearch) && - _status.CurrentStatus.Equals(_statusString) && + string.Equals(_status.CurrentStatus, _statusString) && _status.LastFoundUid.Equals(lastFoundUid) && _status.MessageCount.Equals(messageCount)) return _status; diff --git a/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs b/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs index 365764a..cfa6ae0 100644 --- a/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs +++ b/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs @@ -64,7 +64,7 @@ protected override async Task SendRDMMessage(RDMMessage rdmMessage) var i = SendReceivePipeline.GetNewIdentifyer(); identifyer.TryAdd(i, rdmMessage); if (ImitateRealConditions) - await SendReceivePipelineImitateRealConditions.RDMMessageSend(rdmMessage); + SendReceivePipelineImitateRealConditions.RDMMessageSend(rdmMessage); else SendReceivePipeline.RDMMessageSend(i, rdmMessage); } From eef9a1fe9ce9bbcd5a0aa378ea07eface5f85161 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 22 May 2025 19:13:09 +0200 Subject: [PATCH 06/20] Grrr --- RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs | 2 +- .../Devices/Mock/SendReceivePipelineImitateRealConditions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs b/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs index cfa6ae0..d7f20d5 100644 --- a/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs +++ b/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs @@ -64,7 +64,7 @@ protected override async Task SendRDMMessage(RDMMessage rdmMessage) var i = SendReceivePipeline.GetNewIdentifyer(); identifyer.TryAdd(i, rdmMessage); if (ImitateRealConditions) - SendReceivePipelineImitateRealConditions.RDMMessageSend(rdmMessage); + _ = SendReceivePipelineImitateRealConditions.RDMMessageSend(rdmMessage); // in this case as responder we dont wait for comlpletion of the send, we just send it and forget it else SendReceivePipeline.RDMMessageSend(i, rdmMessage); } diff --git a/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs b/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs index 32877dc..995aa15 100644 --- a/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs +++ b/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs @@ -40,7 +40,7 @@ public static async Task RDMMessageSend(RDMMessage rdmMessage) if (semaphoreSlim.CurrentCount == 1) { await semaphoreSlim.WaitAsync(); - await Task.Delay(10); + await Task.Delay(3); await semaphoreSlim2.WaitAsync(); RDMMessageRereivedResponse?.InvokeFailSafe(null, data); From 4e89c6f6cca1b6edcbed8db3fe9c6cd8a1fcb537 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 22 May 2025 19:19:59 +0200 Subject: [PATCH 07/20] Another try --- RDMSharp/RDM/AsyncRDMRequestHelper.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RDMSharp/RDM/AsyncRDMRequestHelper.cs b/RDMSharp/RDM/AsyncRDMRequestHelper.cs index 67c183f..fe6b6e1 100644 --- a/RDMSharp/RDM/AsyncRDMRequestHelper.cs +++ b/RDMSharp/RDM/AsyncRDMRequestHelper.cs @@ -156,8 +156,11 @@ public async Task RequestMessage(RDMMessage requerst) await _sendMethode.Invoke(requerst); await Task.Delay(TimeSpan.FromTicks(random.Next(33, 777)), _cts.Token); } - if (count > 1 && requerst.Command == ERDM_Command.DISCOVERY_COMMAND) + if (count > 3 && requerst.Command == ERDM_Command.DISCOVERY_COMMAND) + { + Logger?.LogTrace($"Discovery request exceeded timeout"); break; + } if (count == 3000) { From 72e1b78860a21b3f2d3d5d33ef69efcd1a9b58ac Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 22 May 2025 19:29:51 +0200 Subject: [PATCH 08/20] Another try --- .../Mock/SendReceivePipelineImitateRealConditions.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs b/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs index 995aa15..60ec650 100644 --- a/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs +++ b/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs @@ -1,10 +1,13 @@ -namespace RDMSharpTests.Devices.Mock +using System.Collections.Concurrent; + +namespace RDMSharpTests.Devices.Mock { internal static class SendReceivePipelineImitateRealConditions { private static byte[]? data; private static SemaphoreSlim? semaphoreSlim; private static SemaphoreSlim? semaphoreSlim2; + private static ConcurrentQueue queue = new ConcurrentQueue(); public static async Task RDMMessageSend(RDMMessage rdmMessage) { if (!rdmMessage.Command.HasFlag(ERDM_Command.RESPONSE)) @@ -22,6 +25,9 @@ public static async Task RDMMessageSend(RDMMessage rdmMessage) else { await semaphoreSlim2.WaitAsync(); + if (semaphoreSlim.CurrentCount == 0) + queue.Enqueue(Task.Delay(1)); + var newData = rdmMessage.BuildMessage(); var oldData = data; var combined = new byte[Math.Max(newData.Length, oldData?.Length ?? 0)]; @@ -41,10 +47,13 @@ public static async Task RDMMessageSend(RDMMessage rdmMessage) { await semaphoreSlim.WaitAsync(); await Task.Delay(3); + while (queue.TryDequeue(out Task waifOnMee)) + await waifOnMee; await semaphoreSlim2.WaitAsync(); RDMMessageRereivedResponse?.InvokeFailSafe(null, data); data = null; + queue.Clear(); semaphoreSlim2.Release(); semaphoreSlim.Release(); } From e8e48cd8f2dc9b60d20c3c42e5a8ea02e50c2900 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 22 May 2025 19:52:36 +0200 Subject: [PATCH 09/20] Add More Discovery Tests --- .../Devices/Mock/MockGeneratedDevice1.cs | 8 ++++- ...endReceivePipelineImitateRealConditions.cs | 32 +++++++++---------- RDMSharpTests/Devices/TestRDMDiscovery.cs | 26 +++++++++++++++ 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs b/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs index 59d3cb8..a7b047c 100644 --- a/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs +++ b/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs @@ -2,7 +2,13 @@ { internal sealed class MockGeneratedDevice1 : AbstractMockGeneratedDevice { - public override EManufacturer ManufacturerID => (EManufacturer)0x9fff; + public override EManufacturer ManufacturerID + { + get + { + 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; diff --git a/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs b/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs index 60ec650..9107baa 100644 --- a/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs +++ b/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs @@ -23,24 +23,24 @@ public static async Task RDMMessageSend(RDMMessage rdmMessage) if (data == null) data = rdmMessage.BuildMessage(); else - { - await semaphoreSlim2.WaitAsync(); - if (semaphoreSlim.CurrentCount == 0) - queue.Enqueue(Task.Delay(1)); - - var newData = rdmMessage.BuildMessage(); - var oldData = data; - var combined = new byte[Math.Max(newData.Length, oldData?.Length ?? 0)]; - for (int i = 0; i < combined.Length; i++) - { - byte n = (byte)(newData.Length > i ? newData[i] : 0); + { + queue.Enqueue(Task.Run(async () => + { + await semaphoreSlim2.WaitAsync(); + var newData = rdmMessage.BuildMessage(); + var oldData = data; + var combined = new byte[Math.Max(newData.Length, oldData?.Length ?? 0)]; + for (int i = 0; i < combined.Length; i++) + { + byte n = (byte)(newData.Length > i ? newData[i] : 0); #pragma warning disable CS8602 // Dereferenzierung eines möglichen Nullverweises. - byte o = (byte)((oldData?.Length ?? 0) > i ? oldData[i] : 0); + byte o = (byte)((oldData?.Length ?? 0) > i ? oldData[i] : 0); #pragma warning restore CS8602 // Dereferenzierung eines möglichen Nullverweises. - combined[i] = (byte)(n | o); - } - data = combined; - semaphoreSlim2.Release(); + combined[i] = (byte)(n | o); + } + data = combined; + semaphoreSlim2.Release(); + })); } if (semaphoreSlim.CurrentCount == 1) diff --git a/RDMSharpTests/Devices/TestRDMDiscovery.cs b/RDMSharpTests/Devices/TestRDMDiscovery.cs index 5a0a1f9..383b770 100644 --- a/RDMSharpTests/Devices/TestRDMDiscovery.cs +++ b/RDMSharpTests/Devices/TestRDMDiscovery.cs @@ -149,6 +149,32 @@ public async Task TestDiscovery4() mockDevices.Add(m); } + expected = mockDevices.Select(m => m.UID).ToList(); + await AssertDiscovery(); + } + [Test, Retry(3)] + public async Task TestDiscovery5TotalyRandom() + { + HashSet ids = new HashSet(); + HashSet idsMan = new HashSet(); + for (int i = 0; i < 150; i++) + { + 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); + } + expected = mockDevices.Select(m => m.UID).ToList(); await AssertDiscovery(); } From 683d436f496a45116e7d3b00155e8a750c83eedc Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 22 May 2025 22:02:58 +0200 Subject: [PATCH 10/20] Fix many Compiler Warnings Fix Typos --- RDMSharp/Metadata/DataTree.cs | 4 +- RDMSharp/Metadata/DataTreeBranch.cs | 33 +++--- RDMSharp/Metadata/DataTreeObjectAttribute.cs | 10 +- ...taTreeObjectDependeciePropertyAttribute.cs | 4 +- .../DataTreeObjectDependeciePropertyBag.cs | 4 +- RDMSharp/Metadata/JSON/Command.cs | 10 +- .../Metadata/JSON/CommonPropertiesForNamed.cs | 3 + .../JSON/Converter/CommandConverter.cs | 2 +- .../Metadata/JSON/OneOfTypes/IntegerType.cs | 10 +- .../Metadata/JSON/OneOfTypes/ReferenceType.cs | 12 +- RDMSharp/Metadata/MetadataFactory.cs | 26 +++-- RDMSharp/Metadata/MetadataJSONObjectDefine.cs | 21 ++-- RDMSharp/RDM/AsyncRDMRequestHelper.cs | 52 ++++----- .../RDM/Device/AbstractGeneratedRDMDevice.cs | 16 +-- RDMSharp/RDM/Device/AbstractRDMCache.cs | 14 ++- RDMSharp/RDM/Device/AbstractRDMDevice.cs | 6 +- .../RDM/Device/AbstractRemoteRDMDevice.cs | 5 +- RDMSharp/RDM/Device/RDMDeviceModel.cs | 11 +- .../RDM/Discovery/AbstractDiscoveryTool.cs | 12 +- RDMSharp/RDM/Enum/ERDM_BrokerStatus.cs | 2 +- RDMSharp/RDM/Enum/ERDM_DisplayInvert.cs | 4 +- RDMSharp/RDM/Enum/ERDM_IdentifyMode.cs | 4 +- RDMSharp/RDM/Enum/ERDM_LampMode.cs | 4 +- RDMSharp/RDM/Enum/ERDM_LampState.cs | 4 +- RDMSharp/RDM/Enum/ERDM_MergeMode.cs | 4 +- RDMSharp/RDM/Enum/ERDM_Parameter.cs | 10 +- RDMSharp/RDM/Enum/ERDM_PowerState.cs | 4 +- RDMSharp/RDM/Enum/ERDM_ProductDetail.cs | 2 +- RDMSharp/RDM/Enum/ERDM_ResetType.cs | 2 +- RDMSharp/RDM/Enum/ERDM_ShippingLockState.cs | 4 +- RDMSharp/RDM/Enum/ERDM_Status.cs | 6 +- ...ndQueuedStatusPolicyDescriptionResponse.cs | 2 +- ...GetBackgroundQueuedStatusPolicyResponse.cs | 2 +- .../GetBindingAndControlFieldsRequest.cs | 2 +- .../GetBindingAndControlFieldsResponse.cs | 2 +- .../PayloadObject/GetBrokerStatusResponse.cs | 2 +- ...ommunicationStatusNullStartCodeResponse.cs | 2 +- .../GetDeviceInfoOffstageRequest.cs | 2 +- .../GetDeviceInfoOffstageResponse.cs | 2 +- .../GetDiscoveryStateResponse.cs | 2 +- .../PayloadObject/GetEndpointListResponse.cs | 2 +- .../GetEndpointResponderListChangeResponse.cs | 2 +- .../GetEndpointRespondersResponse.cs | 2 +- .../GetEndpointTimingDescriptionResponse.cs | 2 +- .../GetEndpointTimingResponse.cs | 2 +- .../GetHardwareAddressResponse.cs | 2 +- .../GetIPv4CurrentAddressResponse.cs | 2 +- .../PayloadObject/GetInterfaceListResponse.cs | 2 +- .../PayloadObject/GetInterfaceNameResponse.cs | 2 +- .../RDM/PayloadObject/GetLockStateResponse.cs | 2 +- .../RDM/PayloadObject/GetSetComponentScope.cs | 4 +- .../GetSetEndpointBackgroundDiscovery.cs | 4 +- .../PayloadObject/GetSetEndpointIdentify.cs | 4 +- .../RDM/PayloadObject/GetSetEndpointLabel.cs | 4 +- .../RDM/PayloadObject/GetSetEndpointMode.cs | 4 +- .../GetSetEndpointRDMTrafficEnable.cs | 4 +- .../PayloadObject/GetSetEndpointToUniverse.cs | 4 +- .../RDM/PayloadObject/GetSetIPV4_xxx_Mode.cs | 8 +- .../PayloadObject/GetSetIPv4DefaultRoute.cs | 4 +- .../RDM/PayloadObject/GetSetIPv4NameServer.cs | 4 +- .../PayloadObject/GetSetIPv4StaticAddress.cs | 4 +- .../PayloadObject/RDMCommunicationStatus.cs | 2 +- RDMSharp/RDM/PayloadObject/RDMCurve.cs | 2 +- .../RDM/PayloadObject/RDMCurveDescription.cs | 2 +- .../RDM/PayloadObject/RDMDMXBlockAddress.cs | 2 +- .../RDM/PayloadObject/RDMDMXPersonality.cs | 2 +- .../RDMDMXPersonalityDescription.cs | 4 +- .../RDM/PayloadObject/RDMDMX_xxxx_Mode.cs | 8 +- .../RDM/PayloadObject/RDMDefaultSlotValue.cs | 2 +- RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs | 12 +- RDMSharp/RDM/PayloadObject/RDMDimmerInfo.cs | 2 +- .../PayloadObject/RDMLockStateDescription.cs | 2 +- RDMSharp/RDM/PayloadObject/RDMMetadataJson.cs | 2 +- .../RDMMetadataParameterVersion.cs | 2 +- RDMSharp/RDM/PayloadObject/RDMMinimumLevel.cs | 4 +- .../PayloadObject/RDMModulationFrequency.cs | 2 +- .../RDMModulationFrequencyDescription.cs | 2 +- .../PayloadObject/RDMOutputResponseTime.cs | 2 +- .../RDMOutputResponseTimeDescription.cs | 2 +- .../PayloadObject/RDMParameterDescription.cs | 2 +- .../RDM/PayloadObject/RDMPersonalityId.cs | 2 +- RDMSharp/RDM/PayloadObject/RDMPresetInfo.cs | 2 +- .../RDM/PayloadObject/RDMPresetPlayback.cs | 4 +- RDMSharp/RDM/PayloadObject/RDMPresetStatus.cs | 6 +- .../PayloadObject/RDMProxiedDeviceCount.cs | 2 +- .../RDM/PayloadObject/RDMRealTimeClock.cs | 4 +- .../PayloadObject/RDMSelfTestDescription.cs | 2 +- .../RDM/PayloadObject/RDMSensorDefinition.cs | 2 +- .../RDMSensorTypeCustomDefine.cs | 2 +- .../RDMSensorUnitCustomDefine.cs | 2 +- RDMSharp/RDM/PayloadObject/RDMSensorValue.cs | 4 +- .../RDM/PayloadObject/RDMSlotDescription.cs | 2 +- RDMSharp/RDM/PayloadObject/RDMSlotInfo.cs | 2 +- .../RDM/PayloadObject/RDMStatusMessage.cs | 2 +- .../PayloadObject/SetDiscoveryStateRequest.cs | 2 +- .../PayloadObject/SetEndpointTimingRequest.cs | 2 +- .../RDM/PayloadObject/SetLockPinRequest.cs | 2 +- .../RDM/PayloadObject/SetLockStateRequest.cs | 2 +- RDMSharp/RDM/PayloadObject/TCPCommsEntry.cs | 2 +- RDMSharp/RDM/PeerToPeerProcess.cs | 8 +- RDMSharp/RDM/RDMMessage.cs | 3 +- RDMSharp/RDM/Sensor.cs | 4 +- RDMSharp/RDM/Tools.cs | 10 +- RDMSharp/RDMSharp.csproj | 11 +- .../Devices/Mock/AbstractMockDevice.cs | 18 +-- .../Mock/AbstractMockGeneratedDevice.cs | 29 ++--- .../Devices/Mock/MockDiscoveryTool.cs | 4 +- .../Mock/MockGeneratedDeviceWithSubDevice1.cs | 4 +- .../Devices/Mock/SendReceivePipeline.cs | 4 +- ...endReceivePipelineImitateRealConditions.cs | 13 ++- .../MetadataJSONObjectDefineTestSubject.cs | 11 +- .../JSON/MetadataJSONObjectDefineTests.cs | 30 +++-- .../Metadata/JSON/TestBitFieldType.cs | 16 +-- .../Metadata/JSON/TestBooleanType.cs | 22 ++-- RDMSharpTests/Metadata/JSON/TestCommand.cs | 2 +- .../Metadata/JSON/TestIntegerType.cs | 38 ++++--- .../Metadata/JSON/TestReferenceType.cs | 3 +- RDMSharpTests/Metadata/JSON/TestStringType.cs | 2 +- .../Parser/TestDefinedDataTreeObjects.cs | 43 +++---- .../Metadata/TestPeerToPeerProcess.cs | 107 +++++++++++------- RDMSharpTests/TestAsyncRDMRequestHelper.cs | 38 +++---- RDMSharpTests/TestManyObjects.cs | 20 ++-- 122 files changed, 515 insertions(+), 422 deletions(-) diff --git a/RDMSharp/Metadata/DataTree.cs b/RDMSharp/Metadata/DataTree.cs index fc7cd47..a8d2f25 100644 --- a/RDMSharp/Metadata/DataTree.cs +++ b/RDMSharp/Metadata/DataTree.cs @@ -4,6 +4,7 @@ namespace RDMSharp.Metadata { +#pragma warning disable CS8632 public readonly struct DataTree : IEquatable { public readonly string Name; @@ -97,4 +98,5 @@ public override int GetHashCode() return !(left == right); } } -} \ No newline at end of file +} +#pragma warning restore CS8632 \ No newline at end of file diff --git a/RDMSharp/Metadata/DataTreeBranch.cs b/RDMSharp/Metadata/DataTreeBranch.cs index 0fcf5fa..7144fb6 100644 --- a/RDMSharp/Metadata/DataTreeBranch.cs +++ b/RDMSharp/Metadata/DataTreeBranch.cs @@ -1,4 +1,5 @@ -using RDMSharp.Metadata.JSON; +using Microsoft.Extensions.Logging; +using RDMSharp.Metadata.JSON; using RDMSharp.Metadata.JSON.OneOfTypes; using System; using System.Collections; @@ -13,6 +14,7 @@ namespace RDMSharp.Metadata { public readonly struct DataTreeBranch : IEquatable { + private static ILogger Logger = null; public static readonly DataTreeBranch Empty = new DataTreeBranch(); public static readonly DataTreeBranch Unset = new DataTreeBranch(true); @@ -43,7 +45,7 @@ private DataTreeBranch(object parsedObject, params DataTree[] children) : this(c { ParsedObject = parsedObject; } - public DataTreeBranch(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType, params DataTree[] children) : this(children) + public DataTreeBranch(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType, params DataTree[] children) : this(children) { if (define == null) throw new ArgumentNullException(); @@ -51,13 +53,13 @@ public DataTreeBranch(MetadataJSONObjectDefine define, Command.ECommandDublicte ParsedObject = this.getParsedObject(define, commandType); } - private object getParsedObject(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType) + private object getParsedObject(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType) { ushort pid = define.PID; var definedDataTreeObjectType = MetadataFactory.GetDefinedDataTreeObjectType(define, commandType); return getParsedObject(pid, definedDataTreeObjectType, commandType); } - private object getParsedObject(ushort pid, Type definedDataTreeObjectType, Command.ECommandDublicte commandType) + private object getParsedObject(ushort pid, Type definedDataTreeObjectType, Command.ECommandDublicate commandType) { if (IsEmpty || IsUnset) return null; @@ -176,7 +178,10 @@ object createObjectFromDataTree(DataTree[] children) } catch (Exception e) { + Logger.LogError(e); +#pragma warning disable CA2200 throw e; +#pragma warning restore CA2200 } throw new NotImplementedException(); @@ -216,16 +221,16 @@ public static DataTreeBranch FromObject(object obj, object key, ParameterBag par switch (cmd.Value.EnumValue) { - case Command.ECommandDublicte.GetRequest: + case Command.ECommandDublicate.GetRequest: cmd = define.GetRequest; break; - case Command.ECommandDublicte.GetResponse: + case Command.ECommandDublicate.GetResponse: cmd = define.GetResponse; break; - case Command.ECommandDublicte.SetRequest: + case Command.ECommandDublicate.SetRequest: cmd = define.SetRequest; break; - case Command.ECommandDublicte.SetResponse: + case Command.ECommandDublicate.SetResponse: cmd = define.SetResponse; break; } @@ -291,7 +296,7 @@ public static DataTreeBranch FromObject(object obj, object key, ERDM_Command com if (isArray) type = type.GetElementType(); - if (type.GetCustomAttributes().FirstOrDefault(a => a.Parameter == parameter && a.Command == Tools.ConvertCommandDublicteToCommand(command) && a.IsArray == isArray) is not DataTreeObjectAttribute dataTreeObjectAttribute) + if (type.GetCustomAttributes().FirstOrDefault(a => a.Parameter == parameter && a.Command == Tools.ConvertCommandDublicateToCommand(command) && a.IsArray == isArray) is not DataTreeObjectAttribute dataTreeObjectAttribute) return DataTreeBranch.Unset; List children = new List(); @@ -342,7 +347,7 @@ public static DataTreeBranch FromObject(object obj, object key, ERDM_Command com static DataTree[] convertToDataTree(object value, PropertyInfo[] properties, ERDM_Parameter parameter) { - List innetChildren = new List(); + List innerChildren = new List(); Dictionary> deeperChildren = new Dictionary>(); foreach (var property in properties) { @@ -368,15 +373,15 @@ static DataTree[] convertToDataTree(object value, PropertyInfo[] properties, ERD ddc.Add(new DataTree(path[1], attribute.Index, val)); } else - innetChildren.Add(new DataTree(attribute.Name, attribute.Index, val)); + innerChildren.Add(new DataTree(attribute.Name, attribute.Index, val)); } } foreach (var dC in deeperChildren) { - var index = FindMissingNumbers(innetChildren.Select(ic => (int)ic.Index)).FirstOrDefault(); - innetChildren.Add(new DataTree(dC.Key, (uint)index, children: dC.Value.OrderBy(c => c.Index).ToArray())); + 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 innetChildren.OrderBy(iC => iC.Index).ToArray(); + return innerChildren.OrderBy(iC => iC.Index).ToArray(); static IEnumerable FindMissingNumbers(IEnumerable numbers) { diff --git a/RDMSharp/Metadata/DataTreeObjectAttribute.cs b/RDMSharp/Metadata/DataTreeObjectAttribute.cs index 28bae10..892bbd1 100644 --- a/RDMSharp/Metadata/DataTreeObjectAttribute.cs +++ b/RDMSharp/Metadata/DataTreeObjectAttribute.cs @@ -7,20 +7,20 @@ namespace RDMSharp.Metadata; public class DataTreeObjectAttribute : Attribute { public readonly ERDM_Parameter Parameter; - public readonly Command.ECommandDublicte Command; + public readonly Command.ECommandDublicate Command; public readonly EManufacturer Manufacturer = EManufacturer.ESTA; public readonly bool IsArray; public readonly string Path; - public DataTreeObjectAttribute(ERDM_Parameter parameter, Command.ECommandDublicte command, bool isArray = false, string path = null) + public DataTreeObjectAttribute(ERDM_Parameter parameter, Command.ECommandDublicate command, bool isArray = false, string path = null) { Parameter = parameter; Command = command; IsArray = isArray; Path = path; } - public DataTreeObjectAttribute(EManufacturer manufacturer, ERDM_Parameter parameter, Command.ECommandDublicte command, bool isArray = false, string path = null) + public DataTreeObjectAttribute(EManufacturer manufacturer, ERDM_Parameter parameter, Command.ECommandDublicate command, bool isArray = false, string path = null) : this(parameter, command, isArray, path) { Manufacturer = manufacturer; @@ -30,12 +30,12 @@ public DataTreeObjectAttribute(EManufacturer manufacturer, ERDM_Parameter parame public class DataTreeEnumAttribute : DataTreeObjectAttribute { public readonly string Name; - public DataTreeEnumAttribute(ERDM_Parameter parameter, Command.ECommandDublicte command, string name, bool isArray = false, string path = null) + public DataTreeEnumAttribute(ERDM_Parameter parameter, Command.ECommandDublicate command, string name, bool isArray = false, string path = null) : base(parameter, command, isArray, path) { Name = name; } - public DataTreeEnumAttribute(EManufacturer manufacturer, ERDM_Parameter parameter, Command.ECommandDublicte command, string name, bool isArray = false, string path = null) + public DataTreeEnumAttribute(EManufacturer manufacturer, ERDM_Parameter parameter, Command.ECommandDublicate command, string name, bool isArray = false, string path = null) : base(manufacturer, parameter, command, isArray, path) { Name = name; diff --git a/RDMSharp/Metadata/DataTreeObjectDependeciePropertyAttribute.cs b/RDMSharp/Metadata/DataTreeObjectDependeciePropertyAttribute.cs index 3aa2c85..88e9b8f 100644 --- a/RDMSharp/Metadata/DataTreeObjectDependeciePropertyAttribute.cs +++ b/RDMSharp/Metadata/DataTreeObjectDependeciePropertyAttribute.cs @@ -8,10 +8,10 @@ public class DataTreeObjectDependeciePropertyAttribute : Attribute { public readonly string Name; public readonly ERDM_Parameter Parameter; - public readonly Command.ECommandDublicte Command; + public readonly Command.ECommandDublicate Command; public readonly DataTreeObjectDependeciePropertyBag Bag; - public DataTreeObjectDependeciePropertyAttribute(string name, ERDM_Parameter parameter, Command.ECommandDublicte command) + public DataTreeObjectDependeciePropertyAttribute(string name, ERDM_Parameter parameter, Command.ECommandDublicate command) { Name = name; Parameter = parameter; diff --git a/RDMSharp/Metadata/DataTreeObjectDependeciePropertyBag.cs b/RDMSharp/Metadata/DataTreeObjectDependeciePropertyBag.cs index 5acd64e..c78e1c2 100644 --- a/RDMSharp/Metadata/DataTreeObjectDependeciePropertyBag.cs +++ b/RDMSharp/Metadata/DataTreeObjectDependeciePropertyBag.cs @@ -6,10 +6,10 @@ public readonly struct DataTreeObjectDependeciePropertyBag { public readonly string Name; public readonly ERDM_Parameter Parameter; - public readonly Command.ECommandDublicte Command; + public readonly Command.ECommandDublicate Command; public readonly object Value; - internal DataTreeObjectDependeciePropertyBag(string name, ERDM_Parameter parameter, Command.ECommandDublicte command) + internal DataTreeObjectDependeciePropertyBag(string name, ERDM_Parameter parameter, Command.ECommandDublicate command) { Name = name; Parameter = parameter; diff --git a/RDMSharp/Metadata/JSON/Command.cs b/RDMSharp/Metadata/JSON/Command.cs index 1e06429..57adb9c 100644 --- a/RDMSharp/Metadata/JSON/Command.cs +++ b/RDMSharp/Metadata/JSON/Command.cs @@ -8,11 +8,12 @@ namespace RDMSharp.Metadata.JSON { +#pragma warning disable CS8632 [JsonConverter(typeof(CommandConverter))] public readonly struct Command { - [JsonConverter(typeof(CustomEnumConverter))] - public enum ECommandDublicte + [JsonConverter(typeof(CustomEnumConverter))] + public enum ECommandDublicate { [JsonPropertyName("get_request")] GetRequest, @@ -26,7 +27,7 @@ public enum ECommandDublicte DifferentDid } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public readonly ECommandDublicte? EnumValue { get; } + public readonly ECommandDublicate? EnumValue { get; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly OneOf? SingleField { get; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -43,7 +44,7 @@ public bool GetIsEmpty() return true; } - public Command(ECommandDublicte enumValue) + public Command(ECommandDublicate enumValue) { EnumValue = enumValue; } @@ -92,3 +93,4 @@ public override string ToString() } } } +#pragma warning restore CS8632 \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs index 841cd9d..3898f31 100644 --- a/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs +++ b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs @@ -3,6 +3,7 @@ namespace RDMSharp.Metadata.JSON { +#pragma warning disable CS8632 public abstract class CommonPropertiesForNamed { [JsonPropertyName("name")] @@ -14,6 +15,7 @@ public abstract class CommonPropertiesForNamed [JsonPropertyName("notes")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public abstract string? Notes { get; } + [JsonPropertyName("resources")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public abstract string[]? Resources { get; } @@ -32,3 +34,4 @@ public override string ToString() } } } +#pragma warning restore CS8632 \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs b/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs index a083696..edd6a92 100644 --- a/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs @@ -11,7 +11,7 @@ public override Command Read(ref Utf8JsonReader reader, Type typeToConvert, Json { if (reader.TokenType == JsonTokenType.String) { - var enumValue = JsonSerializer.Deserialize(ref reader, options); + var enumValue = JsonSerializer.Deserialize(ref reader, options); return new Command(enumValue); } else if (reader.TokenType == JsonTokenType.StartObject) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index dc12f66..6262e37 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -85,7 +85,7 @@ public IntegerType(string name, PrefixMultiplyer = Math.Pow(PrefixBase ?? 10, PrefixPower ?? 0); } - private static void validateType(EIntegerType type, T dummy = default) + private static void validateType(EIntegerType type, T_In dummy = default) { switch (dummy) { @@ -153,10 +153,10 @@ public override PDL GetDataLength() return new PDL(16); } - private T convertFormatedValueToRaw(object formated) + private TOutput convertFormatedValueToRaw(object formated) where TOutput: T { if (PrefixMultiplyer == 1) - return (T)formated; + return (TOutput)formated; object rawValue = null; switch (formated) @@ -172,11 +172,11 @@ private T convertFormatedValueToRaw(object formated) break; default: - return (T)formated; + return (TOutput)formated; } if (rawValue is not null) - return (T)Convert.ChangeType(rawValue, typeof(T)); + return (TOutput)Convert.ChangeType(rawValue, typeof(T)); throw new NotImplementedException(); } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs index c3d58ac..5dd294e 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs @@ -9,11 +9,13 @@ public readonly struct ReferenceType [JsonPropertyName("$ref")] public readonly string URI { get; } [JsonIgnore(Condition = JsonIgnoreCondition.Always)] - public readonly Command.ECommandDublicte Command { get; } + public readonly Command.ECommandDublicate Command { get; } [JsonIgnore(Condition = JsonIgnoreCondition.Always)] public readonly ushort Pointer { get; } [JsonIgnore(Condition = JsonIgnoreCondition.Always)] +#pragma warning disable CS8632 public readonly CommonPropertiesForNamed? ReferencedObject { get; } +#pragma warning restore CS8632 [JsonConstructor] public ReferenceType(string uri) @@ -28,16 +30,16 @@ public ReferenceType(string uri) switch (segments[0]) { case "get_request": - Command = JSON.Command.ECommandDublicte.GetRequest; + Command = JSON.Command.ECommandDublicate.GetRequest; break; case "get_response": - Command = JSON.Command.ECommandDublicte.GetResponse; + Command = JSON.Command.ECommandDublicate.GetResponse; break; case "set_request": - Command = JSON.Command.ECommandDublicte.SetRequest; + Command = JSON.Command.ECommandDublicate.SetRequest; break; case "set_response": - Command = JSON.Command.ECommandDublicte.SetResponse; + Command = JSON.Command.ECommandDublicate.SetResponse; break; } Pointer = ushort.Parse(segments[1]); diff --git a/RDMSharp/Metadata/MetadataFactory.cs b/RDMSharp/Metadata/MetadataFactory.cs index faed3b8..dfa3f0c 100644 --- a/RDMSharp/Metadata/MetadataFactory.cs +++ b/RDMSharp/Metadata/MetadataFactory.cs @@ -1,4 +1,5 @@ using Json.Schema; +using Microsoft.Extensions.Logging; using RDMSharp.Metadata.JSON; using System; using System.Collections.Concurrent; @@ -15,6 +16,7 @@ namespace RDMSharp.Metadata { public static class MetadataFactory { + private static readonly ILogger Logger = null; private const string SCHEMA_FILE_NAME = "schema.json"; private const string JSON_ENDING = ".json"; private static List metadataVersionList; @@ -96,7 +98,7 @@ internal static MetadataJSONObjectDefine GetDefine(ParameterBag parameter) } catch (Exception ex) { - + Logger.LogError(ex); } throw new DefineNotFoundException($"{parameter}"); } @@ -139,7 +141,7 @@ private static MetadataJSONObjectDefine getDefine(ParameterBag parameter) throw new DefineNotFoundException($"{parameter}"); } - internal static byte[] ParsePayloadToData(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType, DataTreeBranch payload) + internal static byte[] ParsePayloadToData(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType, DataTreeBranch payload) { define.GetCommand(commandType, out Command? _command); if (_command is not Command command) @@ -163,7 +165,7 @@ internal static byte[] ParsePayloadToData(MetadataJSONObjectDefine define, Comma throw new ArithmeticException(); } - internal static DataTreeBranch ParseDataToPayload(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType, byte[] data) + internal static DataTreeBranch ParseDataToPayload(MetadataJSONObjectDefine define, Command.ECommandDublicate commandType, byte[] data) { define.GetCommand(commandType, out Command? _command); if (_command is not Command command) @@ -175,7 +177,7 @@ internal static DataTreeBranch ParseDataToPayload(MetadataJSONObjectDefine defin } catch (Exception e) { - + Logger.LogError(e); } if (command.SingleField.HasValue) @@ -193,19 +195,19 @@ internal static DataTreeBranch ParseDataToPayload(MetadataJSONObjectDefine defin } internal static byte[] GetRequestMessageData(ParameterBag parameter, DataTreeBranch payloadData) { - return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.GetRequest, payloadData); + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.GetRequest, payloadData); } internal static byte[] GetResponseMessageData(ParameterBag parameter, DataTreeBranch payloadData) { - return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.GetResponse, payloadData); + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.GetResponse, payloadData); } internal static byte[] SetRequestMessageData(ParameterBag parameter, DataTreeBranch payloadData) { - return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.SetRequest, payloadData); + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.SetRequest, payloadData); } internal static byte[] SetResponseMessageData(ParameterBag parameter, DataTreeBranch payloadData) { - return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.SetResponse, payloadData); + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicate.SetResponse, payloadData); } private static List definedDataTreeObjects; @@ -228,21 +230,21 @@ private static void fillDefinedDataTreeObjects() definedDataTreeObjects.AddRange(Tools.FindClassesWithAttribute()); } - public static Type GetDefinedDataTreeObjectType(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType) + 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.ECommandDublicte commandType = Tools.ConvertCommandDublicteToCommand(command); + Command.ECommandDublicate commandType = Tools.ConvertCommandDublicateToCommand(command); return GetDefinedDataTreeObjectType((ERDM_Parameter)define.PID, commandType); } public static Type GetDefinedDataTreeObjectType(ERDM_Parameter parameter, ERDM_Command command) { - Command.ECommandDublicte commandType = Tools.ConvertCommandDublicteToCommand(command); + Command.ECommandDublicate commandType = Tools.ConvertCommandDublicateToCommand(command); return GetDefinedDataTreeObjectType(parameter, commandType); } - public static Type GetDefinedDataTreeObjectType(ERDM_Parameter parameter, Command.ECommandDublicte commandType) + public static Type GetDefinedDataTreeObjectType(ERDM_Parameter parameter, Command.ECommandDublicate commandType) { return DefinedDataTreeObjects.Where(t => { diff --git a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs index d43fd18..9882086 100644 --- a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs +++ b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs @@ -10,6 +10,7 @@ namespace RDMSharp.Metadata { public class MetadataJSONObjectDefine { +#pragma warning disable CS8632 [JsonPropertyName("name")] public string Name { get; } @@ -160,25 +161,25 @@ OneOfTypes setReferenceObjects(OneOfTypes oneOf) switch (reference.Command) { - case Command.ECommandDublicte.GetRequest: + case Command.ECommandDublicate.GetRequest: if (!getRequest.HasValue) throw new JsonException($"The Referenced Command ({reference.Command.ToString()})is not defined"); reference = new ReferenceType(reference.URI, getRequest.Value.ListOfFields[reference.Pointer].ObjectType); break; - case Command.ECommandDublicte.GetResponse: + case Command.ECommandDublicate.GetResponse: if (!getResponse.HasValue) throw new JsonException($"The Referenced Command ({reference.Command.ToString()})is not defined"); reference = new ReferenceType(reference.URI, getResponse.Value.ListOfFields[reference.Pointer].ObjectType); break; - case Command.ECommandDublicte.SetRequest: + case Command.ECommandDublicate.SetRequest: if (!setRequest.HasValue) throw new JsonException($"The Referenced Command ({reference.Command.ToString()})is not defined"); reference = new ReferenceType(reference.URI, setRequest.Value.ListOfFields[reference.Pointer].ObjectType); break; - case Command.ECommandDublicte.SetResponse: + case Command.ECommandDublicate.SetResponse: if (!setResponse.HasValue) throw new JsonException($"The Referenced Command ({reference.Command.ToString()})is not defined"); reference = new ReferenceType(reference.URI, setResponse.Value.ListOfFields[reference.Pointer].ObjectType); @@ -189,21 +190,21 @@ OneOfTypes setReferenceObjects(OneOfTypes oneOf) } } - public void GetCommand(Command.ECommandDublicte eCommand, out Command? command) + public void GetCommand(Command.ECommandDublicate eCommand, out Command? command) { command = null; switch (eCommand) { - case Command.ECommandDublicte.GetRequest: + case Command.ECommandDublicate.GetRequest: command = GetRequest.Value; break; - case Command.ECommandDublicte.GetResponse: + case Command.ECommandDublicate.GetResponse: command = GetResponse.Value; break; - case Command.ECommandDublicte.SetRequest: + case Command.ECommandDublicate.SetRequest: command = SetRequest.Value; break; - case Command.ECommandDublicte.SetResponse: + case Command.ECommandDublicate.SetResponse: command = SetResponse.Value; break; } @@ -222,3 +223,5 @@ public override string ToString() } } } + +#pragma warning restore CS8632 \ No newline at end of file diff --git a/RDMSharp/RDM/AsyncRDMRequestHelper.cs b/RDMSharp/RDM/AsyncRDMRequestHelper.cs index fe6b6e1..e6ba0ef 100644 --- a/RDMSharp/RDM/AsyncRDMRequestHelper.cs +++ b/RDMSharp/RDM/AsyncRDMRequestHelper.cs @@ -114,37 +114,37 @@ bool checkQueued(RDMMessage request, RDMMessage response) } - public async Task RequestMessage(RDMMessage requerst) + public async Task RequestMessage(RDMMessage request) { try { - int key = generateKey(requerst); - if (requerst.SubDevice.IsBroadcast) + int key = generateKey(request); + if (request.SubDevice.IsBroadcast) { - Logger?.LogTrace($"Send Subdevice-Broadcast Request: {requerst.ToString()}"); - await _sendMethode.Invoke(requerst); - return new RequestResult(requerst, null, TimeSpan.Zero); // Broadcasts are not expected to return a response. + 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, requerst))) + if (!buffer.TryAdd(key, new AsyncBufferBag(key, request))) { key += random.Next(); - buffer.TryAdd(key, new AsyncBufferBag(key, requerst)); + buffer.TryAdd(key, new AsyncBufferBag(key, request)); } RDMMessage response = null; - Logger?.LogTrace($"Send Request: {requerst.ToString()}"); - await _sendMethode.Invoke(requerst); + Logger?.LogTrace($"Send Request: {request.ToString()}"); + await _sendMethode.Invoke(request); int count = 0; do { if (this.IsDisposing || this.IsDisposed) - return new RequestResult(requerst); + return new RequestResult(request); buffer.TryGetValue(key, out AsyncBufferBag bag); response = bag?.Response; if (response != null) break; await Task.Delay(5, _cts.Token); - if (requerst.Command == ERDM_Command.NONE) + if (request.Command == ERDM_Command.NONE) { throw new Exception("Command is not set"); } @@ -152,11 +152,11 @@ public async Task RequestMessage(RDMMessage requerst) if (count % 300 == 299) { await Task.Delay(TimeSpan.FromTicks(random.Next(33, 777)), _cts.Token); - Logger?.LogTrace($"Retry Request: {requerst.ToString()} ElapsedTime: {bag.ElapsedTime}"); - await _sendMethode.Invoke(requerst); + 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 && requerst.Command == ERDM_Command.DISCOVERY_COMMAND) + if (count > 3 && request.Command == ERDM_Command.DISCOVERY_COMMAND) { Logger?.LogTrace($"Discovery request exceeded timeout"); break; @@ -164,22 +164,22 @@ public async Task RequestMessage(RDMMessage requerst) if (count == 3000) { - Logger?.LogTrace($"Timeout Request: {requerst.ToString()} ElapsedTime: {bag.ElapsedTime}"); - return new RequestResult(requerst); + Logger?.LogTrace($"Timeout Request: {request.ToString()} ElapsedTime: {bag.ElapsedTime}"); + return new RequestResult(request); } } while (response == null); buffer.TryRemove(key, out AsyncBufferBag bag2); response = bag2.Response; - var result = new RequestResult(requerst, response, bag2.ElapsedTime); - Logger?.LogTrace($"Successful Request: {requerst.ToString()} Response: {response.ToString()} ElapsedTime: {bag2.ElapsedTime}"); + 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(requerst); + return new RequestResult(request); } private int generateKey(RDMMessage request) { @@ -200,10 +200,10 @@ private class AsyncBufferBag public readonly int Key; public readonly RDMMessage Request; - public readonly DateTime RequestTimeStamp; + public readonly DateTime RequestTimestamp; public RDMMessage Response { get; private set; } - public DateTime? ResponseTimeStamp { get; private set; } + public DateTime? ResponseTimestamp { get; private set; } private TimeSpan? elapsedTime; public TimeSpan ElapsedTime @@ -213,7 +213,7 @@ public TimeSpan ElapsedTime if (elapsedTime.HasValue) return elapsedTime.Value; - return DateTime.UtcNow - RequestTimeStamp; ; + return DateTime.UtcNow - RequestTimestamp; ; } private set { @@ -226,13 +226,13 @@ public AsyncBufferBag(int key, RDMMessage request) Request = request; Response = null; Key = key; - RequestTimeStamp = DateTime.UtcNow; + RequestTimestamp = DateTime.UtcNow; } public void SetResponse(RDMMessage response) { Response = response; - ResponseTimeStamp = DateTime.UtcNow; - ElapsedTime = ResponseTimeStamp.Value - RequestTimeStamp; + ResponseTimestamp = DateTime.UtcNow; + ElapsedTime = ResponseTimestamp.Value - RequestTimestamp; } } } diff --git a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs index 5447894..1e0c1d7 100644 --- a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs @@ -195,7 +195,7 @@ private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[ if (Personalities != null) { if (Personalities.Length >= byte.MaxValue) - throw new ArgumentOutOfRangeException($"There to many {Personalities}! Maxumum is {byte.MaxValue - 1}"); + throw new ArgumentOutOfRangeException($"There to many {Personalities}! Maximum is {byte.MaxValue - 1}"); if (Personalities.Length != 0) { @@ -215,7 +215,7 @@ private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[ { var _sensors = Sensors.Values.ToArray(); if (_sensors.Length >= byte.MaxValue) - throw new ArgumentOutOfRangeException($"There to many {Sensors}! Maxumum is {byte.MaxValue - 1}"); + throw new ArgumentOutOfRangeException($"There to many {Sensors}! Maximum is {byte.MaxValue - 1}"); 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)})"); @@ -399,8 +399,8 @@ public bool TrySetParameter(ERDM_Parameter parameter, object value, bool throwEx throw new NotSupportedException($"The Protocoll not allow to set the Parameter: {parameter}"); else { - byte[] data = MetadataFactory.ParsePayloadToData(define, Metadata.JSON.Command.ECommandDublicte.SetRequest, DataTreeBranch.FromObject(value, null, parameterBag, ERDM_Command.SET_COMMAND)); - var obj = MetadataFactory.ParseDataToPayload(define, Metadata.JSON.Command.ECommandDublicte.SetRequest, data); + byte[] data = MetadataFactory.ParsePayloadToData(define, Metadata.JSON.Command.ECommandDublicate.SetRequest, DataTreeBranch.FromObject(value, null, parameterBag, ERDM_Command.SET_COMMAND)); + var obj = MetadataFactory.ParseDataToPayload(define, Metadata.JSON.Command.ECommandDublicate.SetRequest, data); if (!object.Equals(value, obj)) return false; } @@ -537,7 +537,7 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) } if (rdmMessage.Command == ERDM_Command.GET_COMMAND) { - if (rdmMessage.SubDevice == SubDevice.Broadcast) // no Response on Broadcast Subdevice, because this cant work on a if there are more then one Device responding on a singel line. + 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 }; goto FAIL; @@ -564,13 +564,14 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) } catch (Exception e) { + Logger.LogError(e); goto FAIL; } } else if (rdmMessage.Command == ERDM_Command.SET_COMMAND) { bool success = false; - //Handle set Requerst + //Handle set Request if (parameterValues.TryGetValue(rdmMessage.Parameter, out object comparisonValue) && parameterValues.TryUpdate(rdmMessage.Parameter, rdmMessage.Value, comparisonValue)) { success = true; @@ -597,6 +598,7 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) } catch (Exception e) { + Logger.LogError(e); goto FAIL; } } @@ -614,7 +616,7 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) Logger?.LogError(e, string.Empty); } FAIL: - if (rdmMessage.SubDevice == SubDevice.Broadcast) // no Response on Broadcast Subdevice, because this cant work on a if there are more then one Device responding on a singel line. + 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; diff --git a/RDMSharp/RDM/Device/AbstractRDMCache.cs b/RDMSharp/RDM/Device/AbstractRDMCache.cs index 6fb0008..916985c 100644 --- a/RDMSharp/RDM/Device/AbstractRDMCache.cs +++ b/RDMSharp/RDM/Device/AbstractRDMCache.cs @@ -1,4 +1,5 @@ -using RDMSharp.Metadata; +using Microsoft.Extensions.Logging; +using RDMSharp.Metadata; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -10,6 +11,7 @@ namespace RDMSharp { public abstract class AbstractRDMCache : IDisposable { + protected static ILogger Logger = null; protected bool IsDisposed { get; private set; } protected bool IsDisposing { get; private set; } internal ConcurrentDictionary parameterValuesDataTreeBranch { get; private set; } = new ConcurrentDictionary(); @@ -168,7 +170,7 @@ protected async Task requestSetParameterWithEmptyPayload(ParameterBag parameterB } protected async Task requestSetParameterWithPayload(ParameterBag parameterBag, MetadataJSONObjectDefine define, UID uid, SubDevice subDevice, object value) { - define.GetCommand(Metadata.JSON.Command.ECommandDublicte.SetRequest, out var cmd); + define.GetCommand(Metadata.JSON.Command.ECommandDublicate.SetRequest, out var cmd); var req = cmd.Value.GetRequiredProperties(); if (req.Length == 1) { @@ -201,12 +203,12 @@ protected async Task requestGetParameterWithEmptyPayload(ParameterBag parameterB } 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) { - define.GetCommand(Metadata.JSON.Command.ECommandDublicte.GetRequest, out var cmd); + 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) { @@ -214,7 +216,7 @@ protected async Task requestGetParameterWithPayload(ParameterBag parameterBag, M { string name = intType.Name; - IComparable dependecyValue = (IComparable)parameterValuesDependeciePropertyBag.FirstOrDefault(bag => bag.Key.Parameter == parameterBag.PID && bag.Key.Command == Metadata.JSON.Command.ECommandDublicte.GetRequest && string.Equals(bag.Key.Name, name)).Value; + IComparable dependecyValue = (IComparable)parameterValuesDependeciePropertyBag.FirstOrDefault(bag => bag.Key.Parameter == parameterBag.PID && bag.Key.Command == Metadata.JSON.Command.ECommandDublicate.GetRequest && string.Equals(bag.Key.Name, name)).Value; object i = intType.GetMinimum(); object max = intType.GetMaximum(); @@ -239,7 +241,7 @@ protected async Task requestGetParameterWithPayload(ParameterBag parameterBag, M } catch (Exception e) { - + Logger.LogError(e, $"Failed to get parameter {parameterBag.PID} with Bag: {parameterBag}"); } } } diff --git a/RDMSharp/RDM/Device/AbstractRDMDevice.cs b/RDMSharp/RDM/Device/AbstractRDMDevice.cs index ff8f359..7a562bb 100644 --- a/RDMSharp/RDM/Device/AbstractRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractRDMDevice.cs @@ -10,8 +10,6 @@ namespace RDMSharp { public abstract class AbstractRDMDevice : AbstractRDMCache, IRDMDevice { - private protected static readonly ILogger Logger = null; - public event PropertyChangedEventHandler PropertyChanged; private readonly UID uid; @@ -39,10 +37,10 @@ protected AbstractRDMDevice(UID uid, SubDevice? subDevice = null, IRDMDevice[] s this.uid = uid; this.subdevice = subDevice ?? SubDevice.Root; if (subDevices != null && !this.Subdevice.IsRoot) - throw new NotSupportedException($"A SubDevice {this.Subdevice} cannot have SubDevices."); + throw new NotSupportedException($"A SubDevice {this.Subdevice} can't have SubDevices."); if (this.Subdevice.IsBroadcast) - throw new NotSupportedException($"A SubDevice cannot be Broadcast."); + throw new NotSupportedException($"A SubDevice can't be Broadcast."); if (this.Subdevice == SubDevice.Root) diff --git a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs index 9d150a9..c0aad17 100644 --- a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs @@ -118,7 +118,7 @@ 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 cannot be Broadcast."); + throw new NotSupportedException("A SubDevice can't be Broadcast."); } protected override async void initialize(RDMDeviceInfo deviceInfo = null) { @@ -316,10 +316,11 @@ protected sealed override async Task OnReceiveRDMMessage(RDMMessage rdmMessage) try { if (deviceModel != null) - await deviceModel?.ReceiveRDMMessage(rdmMessage); + deviceModel?.ReceiveRDMMessage(rdmMessage); } catch (Exception e) { + await Task.CompletedTask; Logger?.LogError(e, string.Empty); } diff --git a/RDMSharp/RDM/Device/RDMDeviceModel.cs b/RDMSharp/RDM/Device/RDMDeviceModel.cs index d27af58..fea1376 100644 --- a/RDMSharp/RDM/Device/RDMDeviceModel.cs +++ b/RDMSharp/RDM/Device/RDMDeviceModel.cs @@ -1,4 +1,5 @@ -using RDMSharp.Metadata; +using Microsoft.Extensions.Logging; +using RDMSharp.Metadata; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -65,7 +66,7 @@ internal async Task getPersonalityModel(IRDMRemoteDevice re } catch (Exception ex) { - + Logger.LogError(ex); } return null; } @@ -152,12 +153,12 @@ public IReadOnlyCollection KnownNotSupportedParameters private readonly Func sendRdmFunktion; - internal RDMDeviceModel(UID uid, SubDevice sudevice, RDMDeviceInfo deviceInfo, Func sendRdmFunktion) + internal RDMDeviceModel(UID uid, SubDevice subdevice, RDMDeviceInfo deviceInfo, Func sendRdmFunktion) { this.sendRdmFunktion = sendRdmFunktion; DeviceInfo = deviceInfo; CurrentUsedUID = uid; - CurrentUsedSubDevice = sudevice; + CurrentUsedSubDevice = subdevice; ManufacturerID = uid.ManufacturerID; Manufacturer = (EManufacturer)uid.ManufacturerID; } @@ -265,7 +266,7 @@ private async Task sendRDMMessage(RDMMessage rdmMessage) await sendRdmFunktion.Invoke(rdmMessage); } - internal async Task ReceiveRDMMessage(RDMMessage rdmMessage) + internal void ReceiveRDMMessage(RDMMessage rdmMessage) { if (rdmMessage.SourceUID != CurrentUsedUID) return; diff --git a/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs b/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs index 3d191c2..cf44924 100644 --- a/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs +++ b/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs @@ -12,7 +12,7 @@ public abstract class AbstractDiscoveryTool : INotifyPropertyChanged, IDisposabl { private protected static ILogger Logger = null; private readonly AsyncRDMRequestHelper asyncRDMRequestHelper; - private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); + private readonly CancellationTokenSource cts = new CancellationTokenSource(); public event PropertyChangedEventHandler PropertyChanged; public bool discoveryInProgress; public bool DiscoveryInProgress @@ -56,7 +56,7 @@ public async Task> PerformDiscovery(IProgress> PerformDiscovery(IProgress /// https://www.rdmprotocol.org/rdm/developers/developer-resources/ /// - [DataTreeEnum(ERDM_Parameter.SUPPORTED_PARAMETERS, Command.ECommandDublicte.GetResponse, "pid", true, "pids")] - [DataTreeEnum(ERDM_Parameter.PARAMETER_DESCRIPTION, Command.ECommandDublicte.GetRequest, "pid")] - [DataTreeEnum(ERDM_Parameter.METADATA_JSON, Command.ECommandDublicte.GetRequest, "pid")] - [DataTreeEnum(ERDM_Parameter.METADATA_PARAMETER_VERSION, Command.ECommandDublicte.GetRequest, "pid")] + [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, @@ -120,7 +120,7 @@ public enum ERDM_Parameter : ushort DNS_HOSTNAME = 0x070C, DNS_DOMAIN_NAME = 0x070D, - //E1.33 - 2019 RDMnet + //E1.33 - 2019 RDM-Net COMPONENT_SCOPE = 0x0800, SEARCH_DOMAIN = 0x0801, TCP_COMMS_STATUS = 0x0802, diff --git a/RDMSharp/RDM/Enum/ERDM_PowerState.cs b/RDMSharp/RDM/Enum/ERDM_PowerState.cs index df40f43..f191f14 100644 --- a/RDMSharp/RDM/Enum/ERDM_PowerState.cs +++ b/RDMSharp/RDM/Enum/ERDM_PowerState.cs @@ -3,8 +3,8 @@ namespace RDMSharp { - [DataTreeEnum(ERDM_Parameter.POWER_STATE, Command.ECommandDublicte.GetResponse, "state")] - [DataTreeEnum(ERDM_Parameter.POWER_STATE, Command.ECommandDublicte.SetRequest, "state")] + [DataTreeEnum(ERDM_Parameter.POWER_STATE, Command.ECommandDublicate.GetResponse, "state")] + [DataTreeEnum(ERDM_Parameter.POWER_STATE, Command.ECommandDublicate.SetRequest, "state")] public enum ERDM_PowerState : byte { FULL_OFF = 0x00, diff --git a/RDMSharp/RDM/Enum/ERDM_ProductDetail.cs b/RDMSharp/RDM/Enum/ERDM_ProductDetail.cs index c351c53..f3c9760 100644 --- a/RDMSharp/RDM/Enum/ERDM_ProductDetail.cs +++ b/RDMSharp/RDM/Enum/ERDM_ProductDetail.cs @@ -3,7 +3,7 @@ namespace RDMSharp { - [DataTreeEnum(ERDM_Parameter.PRODUCT_DETAIL_ID_LIST, Command.ECommandDublicte.GetResponse, "product_detail_id", true, "product_detail_ids")] + [DataTreeEnum(ERDM_Parameter.PRODUCT_DETAIL_ID_LIST, Command.ECommandDublicate.GetResponse, "product_detail_id", true, "product_detail_ids")] public enum ERDM_ProductDetail : ushort { NONE = 0x0000, diff --git a/RDMSharp/RDM/Enum/ERDM_ResetType.cs b/RDMSharp/RDM/Enum/ERDM_ResetType.cs index ce8422a..c26921f 100644 --- a/RDMSharp/RDM/Enum/ERDM_ResetType.cs +++ b/RDMSharp/RDM/Enum/ERDM_ResetType.cs @@ -3,7 +3,7 @@ namespace RDMSharp { - [DataTreeEnum(ERDM_Parameter.RESET_DEVICE, Command.ECommandDublicte.SetRequest, "state")] + [DataTreeEnum(ERDM_Parameter.RESET_DEVICE, Command.ECommandDublicate.SetRequest, "state")] public enum ERDM_ResetType : byte { Warm = 0x01, diff --git a/RDMSharp/RDM/Enum/ERDM_ShippingLockState.cs b/RDMSharp/RDM/Enum/ERDM_ShippingLockState.cs index cfe0d5c..de4b408 100644 --- a/RDMSharp/RDM/Enum/ERDM_ShippingLockState.cs +++ b/RDMSharp/RDM/Enum/ERDM_ShippingLockState.cs @@ -4,8 +4,8 @@ namespace RDMSharp { //E1.37-5 - [DataTreeEnum(ERDM_Parameter.SHIPPING_LOCK, Command.ECommandDublicte.GetResponse, "lock_state")] - [DataTreeEnum(ERDM_Parameter.SHIPPING_LOCK, Command.ECommandDublicte.SetRequest, "lock_state")] + [DataTreeEnum(ERDM_Parameter.SHIPPING_LOCK, Command.ECommandDublicate.GetResponse, "lock_state")] + [DataTreeEnum(ERDM_Parameter.SHIPPING_LOCK, Command.ECommandDublicate.SetRequest, "lock_state")] public enum ERDM_ShippingLockState : byte { /// diff --git a/RDMSharp/RDM/Enum/ERDM_Status.cs b/RDMSharp/RDM/Enum/ERDM_Status.cs index e2e286b..8509cfd 100644 --- a/RDMSharp/RDM/Enum/ERDM_Status.cs +++ b/RDMSharp/RDM/Enum/ERDM_Status.cs @@ -3,9 +3,9 @@ namespace RDMSharp { - [DataTreeEnum(ERDM_Parameter.STATUS_MESSAGES, Command.ECommandDublicte.GetRequest, "status_type")] - [DataTreeEnum(ERDM_Parameter.SUB_DEVICE_STATUS_REPORT_THRESHOLD, Command.ECommandDublicte.GetResponse, "status_type")] - [DataTreeEnum(ERDM_Parameter.SUB_DEVICE_STATUS_REPORT_THRESHOLD, Command.ECommandDublicte.SetRequest, "status_type")] + [DataTreeEnum(ERDM_Parameter.STATUS_MESSAGES, Command.ECommandDublicate.GetRequest, "status_type")] + [DataTreeEnum(ERDM_Parameter.SUB_DEVICE_STATUS_REPORT_THRESHOLD, Command.ECommandDublicate.GetResponse, "status_type")] + [DataTreeEnum(ERDM_Parameter.SUB_DEVICE_STATUS_REPORT_THRESHOLD, Command.ECommandDublicate.SetRequest, "status_type")] public enum ERDM_Status : byte { NONE = 0x00, diff --git a/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponse.cs b/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponse.cs index 85b5b94..9d62ffd 100644 --- a/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyDescriptionResponse.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION, Command.ECommandDublicate.GetResponse)] public class GetBackgroundQueuedStatusPolicyDescriptionResponse : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponse.cs b/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponse.cs index f08b0a6..16c8464 100644 --- a/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetBackgroundQueuedStatusPolicyResponse.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.BACKGROUND_QUEUED_STATUS_POLICY, Command.ECommandDublicate.GetResponse)] public class GetBackgroundQueuedStatusPolicyResponse : AbstractRDMPayloadObjectOneOf { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsRequest.cs b/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsRequest.cs index a455989..34eaf86 100644 --- a/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsRequest.cs +++ b/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsRequest.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.BINDING_CONTROL_FIELDS, Command.ECommandDublicte.GetRequest)] + [DataTreeObject(ERDM_Parameter.BINDING_CONTROL_FIELDS, Command.ECommandDublicate.GetRequest)] public class GetBindingAndControlFieldsRequest : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsResponse.cs b/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsResponse.cs index e78fe35..fcc93a6 100644 --- a/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetBindingAndControlFieldsResponse.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.BINDING_CONTROL_FIELDS, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.BINDING_CONTROL_FIELDS, Command.ECommandDublicate.GetResponse)] public class GetBindingAndControlFieldsResponse : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetBrokerStatusResponse.cs b/RDMSharp/RDM/PayloadObject/GetBrokerStatusResponse.cs index a0303fe..cb025f7 100644 --- a/RDMSharp/RDM/PayloadObject/GetBrokerStatusResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetBrokerStatusResponse.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.BROKER_STATUS, Command.ECommandDublicte.GetRequest)] + [DataTreeObject(ERDM_Parameter.BROKER_STATUS, Command.ECommandDublicate.GetRequest)] public class GetBrokerStatusResponse : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetCommunicationStatusNullStartCodeResponse.cs b/RDMSharp/RDM/PayloadObject/GetCommunicationStatusNullStartCodeResponse.cs index 6045738..548cec0 100644 --- a/RDMSharp/RDM/PayloadObject/GetCommunicationStatusNullStartCodeResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetCommunicationStatusNullStartCodeResponse.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.COMMS_STATUS_NSC, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.COMMS_STATUS_NSC, Command.ECommandDublicate.GetResponse)] public class GetCommunicationStatusNullStartCodeResponse : AbstractRDMPayloadObject { public GetCommunicationStatusNullStartCodeResponse( diff --git a/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageRequest.cs b/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageRequest.cs index 8c90cb9..14842ad 100644 --- a/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageRequest.cs +++ b/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageRequest.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DEVICE_INFO_OFFSTAGE, Command.ECommandDublicte.GetRequest)] + [DataTreeObject(ERDM_Parameter.DEVICE_INFO_OFFSTAGE, Command.ECommandDublicate.GetRequest)] public class GetDeviceInfoOffstageRequest : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageResponse.cs b/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageResponse.cs index d5768a0..e102109 100644 --- a/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetDeviceInfoOffstageResponse.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DEVICE_INFO_OFFSTAGE, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.DEVICE_INFO_OFFSTAGE, Command.ECommandDublicate.GetResponse)] public class GetDeviceInfoOffstageResponse : AbstractRDMPayloadObject { public GetDeviceInfoOffstageResponse( diff --git a/RDMSharp/RDM/PayloadObject/GetDiscoveryStateResponse.cs b/RDMSharp/RDM/PayloadObject/GetDiscoveryStateResponse.cs index d877198..95ffad3 100644 --- a/RDMSharp/RDM/PayloadObject/GetDiscoveryStateResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetDiscoveryStateResponse.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DISCOVERY_STATE, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.DISCOVERY_STATE, Command.ECommandDublicate.GetResponse)] public class GetDiscoveryStateResponse : AbstractRDMPayloadObject { public GetDiscoveryStateResponse( diff --git a/RDMSharp/RDM/PayloadObject/GetEndpointListResponse.cs b/RDMSharp/RDM/PayloadObject/GetEndpointListResponse.cs index f23b38a..e2c4025 100644 --- a/RDMSharp/RDM/PayloadObject/GetEndpointListResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetEndpointListResponse.cs @@ -7,7 +7,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.ENDPOINT_LIST, Command.ECommandDublicte.GetResponse, true, "endpoints")] + [DataTreeObject(ERDM_Parameter.ENDPOINT_LIST, Command.ECommandDublicate.GetResponse, true, "endpoints")] public class GetEndpointListResponse : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetEndpointResponderListChangeResponse.cs b/RDMSharp/RDM/PayloadObject/GetEndpointResponderListChangeResponse.cs index 505049d..29a3c60 100644 --- a/RDMSharp/RDM/PayloadObject/GetEndpointResponderListChangeResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetEndpointResponderListChangeResponse.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.ENDPOINT_RESPONDER_LIST_CHANGE, Command.ECommandDublicate.GetResponse)] public class GetEndpointResponderListChangeResponse : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetEndpointRespondersResponse.cs b/RDMSharp/RDM/PayloadObject/GetEndpointRespondersResponse.cs index 82b3e12..90c6463 100644 --- a/RDMSharp/RDM/PayloadObject/GetEndpointRespondersResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetEndpointRespondersResponse.cs @@ -6,7 +6,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.ENDPOINT_RESPONDERS, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.ENDPOINT_RESPONDERS, Command.ECommandDublicate.GetResponse)] public class GetEndpointRespondersResponse : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetEndpointTimingDescriptionResponse.cs b/RDMSharp/RDM/PayloadObject/GetEndpointTimingDescriptionResponse.cs index 7a2221e..2f7a7b3 100644 --- a/RDMSharp/RDM/PayloadObject/GetEndpointTimingDescriptionResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetEndpointTimingDescriptionResponse.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING_DESCRIPTION, Command.ECommandDublicate.GetResponse)] public class GetEndpointTimingDescriptionResponse : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetEndpointTimingResponse.cs b/RDMSharp/RDM/PayloadObject/GetEndpointTimingResponse.cs index c412999..e221040 100644 --- a/RDMSharp/RDM/PayloadObject/GetEndpointTimingResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetEndpointTimingResponse.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicate.GetResponse)] public class GetEndpointTimingResponse : AbstractRDMPayloadObjectOneOf { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetHardwareAddressResponse.cs b/RDMSharp/RDM/PayloadObject/GetHardwareAddressResponse.cs index 5fb2255..87ffe45 100644 --- a/RDMSharp/RDM/PayloadObject/GetHardwareAddressResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetHardwareAddressResponse.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.INTERFACE_HARDWARE_ADDRESS_TYPE, Command.ECommandDublicate.GetResponse)] public class GetHardwareAddressResponse : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetIPv4CurrentAddressResponse.cs b/RDMSharp/RDM/PayloadObject/GetIPv4CurrentAddressResponse.cs index b70c3c1..3d8a412 100644 --- a/RDMSharp/RDM/PayloadObject/GetIPv4CurrentAddressResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetIPv4CurrentAddressResponse.cs @@ -6,7 +6,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.IPV4_CURRENT_ADDRESS, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.IPV4_CURRENT_ADDRESS, Command.ECommandDublicate.GetResponse)] public class GetIPv4CurrentAddressResponse : AbstractRDMPayloadObject { public GetIPv4CurrentAddressResponse( diff --git a/RDMSharp/RDM/PayloadObject/GetInterfaceListResponse.cs b/RDMSharp/RDM/PayloadObject/GetInterfaceListResponse.cs index a71d16f..ac61f3c 100644 --- a/RDMSharp/RDM/PayloadObject/GetInterfaceListResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetInterfaceListResponse.cs @@ -7,7 +7,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.LIST_INTERFACES, Command.ECommandDublicte.GetResponse, true, "interfaces")] + [DataTreeObject(ERDM_Parameter.LIST_INTERFACES, Command.ECommandDublicate.GetResponse, true, "interfaces")] public class GetInterfaceListResponse : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetInterfaceNameResponse.cs b/RDMSharp/RDM/PayloadObject/GetInterfaceNameResponse.cs index 6473df2..0d11c73 100644 --- a/RDMSharp/RDM/PayloadObject/GetInterfaceNameResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetInterfaceNameResponse.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.INTERFACE_LABEL, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.INTERFACE_LABEL, Command.ECommandDublicate.GetResponse)] public class GetInterfaceNameResponse : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetLockStateResponse.cs b/RDMSharp/RDM/PayloadObject/GetLockStateResponse.cs index ad983cd..1d65269 100644 --- a/RDMSharp/RDM/PayloadObject/GetLockStateResponse.cs +++ b/RDMSharp/RDM/PayloadObject/GetLockStateResponse.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.LOCK_STATE, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.LOCK_STATE, Command.ECommandDublicate.GetResponse)] public class GetLockStateResponse : AbstractRDMPayloadObjectOneOf { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetSetComponentScope.cs b/RDMSharp/RDM/PayloadObject/GetSetComponentScope.cs index 40ad163..fa88605 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetComponentScope.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetComponentScope.cs @@ -9,8 +9,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.COMPONENT_SCOPE, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.COMPONENT_SCOPE, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.COMPONENT_SCOPE, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.COMPONENT_SCOPE, Command.ECommandDublicate.SetRequest)] public class GetSetComponentScope : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointBackgroundDiscovery.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointBackgroundDiscovery.cs index 5624868..4c8f807 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointBackgroundDiscovery.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointBackgroundDiscovery.cs @@ -4,8 +4,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.BACKGROUND_DISCOVERY, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.BACKGROUND_DISCOVERY, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.BACKGROUND_DISCOVERY, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.BACKGROUND_DISCOVERY, Command.ECommandDublicate.SetRequest)] public class GetSetEndpointBackgroundDiscovery : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointIdentify.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointIdentify.cs index cdb0248..44a1d73 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointIdentify.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointIdentify.cs @@ -4,8 +4,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.IDENTIFY_ENDPOINT, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.IDENTIFY_ENDPOINT, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.IDENTIFY_ENDPOINT, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.IDENTIFY_ENDPOINT, Command.ECommandDublicate.SetRequest)] public class GetSetIdentifyEndpoint : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointLabel.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointLabel.cs index 9e242b8..60b93a0 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointLabel.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointLabel.cs @@ -4,8 +4,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.ENDPOINT_LABEL, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.ENDPOINT_LABEL, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.ENDPOINT_LABEL, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.ENDPOINT_LABEL, Command.ECommandDublicate.SetRequest)] public class GetSetEndpointLabel : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointMode.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointMode.cs index 8130e0c..f3e9648 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointMode.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointMode.cs @@ -4,8 +4,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.ENDPOINT_MODE, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.ENDPOINT_MODE, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.ENDPOINT_MODE, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.ENDPOINT_MODE, Command.ECommandDublicate.SetRequest)] public class GetSetEndpointMode : AbstractRDMPayloadObject { public GetSetEndpointMode( diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointRDMTrafficEnable.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointRDMTrafficEnable.cs index 31340cb..d79740e 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointRDMTrafficEnable.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointRDMTrafficEnable.cs @@ -4,8 +4,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.RDM_TRAFFIC_ENABLE, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.RDM_TRAFFIC_ENABLE, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.RDM_TRAFFIC_ENABLE, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.RDM_TRAFFIC_ENABLE, Command.ECommandDublicate.SetRequest)] public class GetSetEndpointRDMTrafficEnable : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetSetEndpointToUniverse.cs b/RDMSharp/RDM/PayloadObject/GetSetEndpointToUniverse.cs index 1b43796..623dccf 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetEndpointToUniverse.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetEndpointToUniverse.cs @@ -4,8 +4,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.ENDPOINT_TO_UNIVERSE, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.ENDPOINT_TO_UNIVERSE, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.ENDPOINT_TO_UNIVERSE, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.ENDPOINT_TO_UNIVERSE, Command.ECommandDublicate.SetRequest)] public class GetSetEndpointToUniverse : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetSetIPV4_xxx_Mode.cs b/RDMSharp/RDM/PayloadObject/GetSetIPV4_xxx_Mode.cs index e1a8b21..431650b 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetIPV4_xxx_Mode.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetIPV4_xxx_Mode.cs @@ -4,10 +4,10 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.IPV4_DHCP_MODE, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.IPV4_DHCP_MODE, Command.ECommandDublicte.SetRequest)] - [DataTreeObject(ERDM_Parameter.IPV4_ZEROCONF_MODE, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.IPV4_ZEROCONF_MODE, Command.ECommandDublicte.SetRequest)] + [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] diff --git a/RDMSharp/RDM/PayloadObject/GetSetIPv4DefaultRoute.cs b/RDMSharp/RDM/PayloadObject/GetSetIPv4DefaultRoute.cs index 1826d4b..720d34d 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetIPv4DefaultRoute.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetIPv4DefaultRoute.cs @@ -4,8 +4,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.IPV4_DEFAULT_ROUTE, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.IPV4_DEFAULT_ROUTE, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.IPV4_DEFAULT_ROUTE, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.IPV4_DEFAULT_ROUTE, Command.ECommandDublicate.SetRequest)] public class GetSetIPv4DefaultRoute : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/GetSetIPv4NameServer.cs b/RDMSharp/RDM/PayloadObject/GetSetIPv4NameServer.cs index 9ab8fd3..7a14325 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetIPv4NameServer.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetIPv4NameServer.cs @@ -4,8 +4,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DNS_IPV4_NAME_SERVER, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.DNS_IPV4_NAME_SERVER, Command.ECommandDublicte.SetRequest)] + [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] diff --git a/RDMSharp/RDM/PayloadObject/GetSetIPv4StaticAddress.cs b/RDMSharp/RDM/PayloadObject/GetSetIPv4StaticAddress.cs index fef4493..ea859b4 100644 --- a/RDMSharp/RDM/PayloadObject/GetSetIPv4StaticAddress.cs +++ b/RDMSharp/RDM/PayloadObject/GetSetIPv4StaticAddress.cs @@ -5,8 +5,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.IPV4_STATIC_ADDRESS, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.IPV4_STATIC_ADDRESS, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.IPV4_STATIC_ADDRESS, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.IPV4_STATIC_ADDRESS, Command.ECommandDublicate.SetRequest)] public class GetSetIPv4StaticAddress : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMCommunicationStatus.cs b/RDMSharp/RDM/PayloadObject/RDMCommunicationStatus.cs index 417b56c..93b7cea 100644 --- a/RDMSharp/RDM/PayloadObject/RDMCommunicationStatus.cs +++ b/RDMSharp/RDM/PayloadObject/RDMCommunicationStatus.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.COMMS_STATUS, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.COMMS_STATUS, Command.ECommandDublicate.GetResponse)] public class RDMCommunicationStatus : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMCurve.cs b/RDMSharp/RDM/PayloadObject/RDMCurve.cs index a68a561..b6f6389 100644 --- a/RDMSharp/RDM/PayloadObject/RDMCurve.cs +++ b/RDMSharp/RDM/PayloadObject/RDMCurve.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.CURVE, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.CURVE, Command.ECommandDublicate.GetResponse)] public class RDMCurve : AbstractRDMPayloadObjectOneOf { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMCurveDescription.cs b/RDMSharp/RDM/PayloadObject/RDMCurveDescription.cs index 43fae13..20b9ed0 100644 --- a/RDMSharp/RDM/PayloadObject/RDMCurveDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMCurveDescription.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.CURVE_DESCRIPTION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.CURVE_DESCRIPTION, Command.ECommandDublicate.GetResponse)] public class RDMCurveDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMDMXBlockAddress.cs b/RDMSharp/RDM/PayloadObject/RDMDMXBlockAddress.cs index ba28802..665550b 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDMXBlockAddress.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDMXBlockAddress.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DMX_BLOCK_ADDRESS, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.DMX_BLOCK_ADDRESS, Command.ECommandDublicate.GetResponse)] public class RDMDMXBlockAddress : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs b/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs index dd1e7ad..49b257b 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DMX_PERSONALITY, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.DMX_PERSONALITY, Command.ECommandDublicate.GetResponse)] public class RDMDMXPersonality : AbstractRDMPayloadObjectOneOf { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs b/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs index d267bfb..abaa73b 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, Command.ECommandDublicate.GetResponse)] public class RDMDMXPersonalityDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { [DataTreeObjectConstructor] @@ -29,7 +29,7 @@ public RDMDMXPersonalityDescription( [DataTreeObjectProperty("personality", 0)] public byte PersonalityId { get; private set; } - [DataTreeObjectDependecieProperty("slot", ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicte.GetRequest)] + [DataTreeObjectDependecieProperty("slot", ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicate.GetRequest)] [DataTreeObjectProperty("dmx_slots_required", 1)] public ushort Slots { get; private set; } diff --git a/RDMSharp/RDM/PayloadObject/RDMDMX_xxxx_Mode.cs b/RDMSharp/RDM/PayloadObject/RDMDMX_xxxx_Mode.cs index b06c870..f93ef7f 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDMX_xxxx_Mode.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDMX_xxxx_Mode.cs @@ -5,10 +5,10 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DMX_FAIL_MODE, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.DMX_FAIL_MODE, Command.ECommandDublicte.SetRequest)] - [DataTreeObject(ERDM_Parameter.DMX_STARTUP_MODE, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.DMX_STARTUP_MODE, Command.ECommandDublicte.SetRequest)] + [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] diff --git a/RDMSharp/RDM/PayloadObject/RDMDefaultSlotValue.cs b/RDMSharp/RDM/PayloadObject/RDMDefaultSlotValue.cs index 5f87484..f692fb6 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDefaultSlotValue.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDefaultSlotValue.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DEFAULT_SLOT_VALUE, Command.ECommandDublicte.GetResponse, true, "slots")] + [DataTreeObject(ERDM_Parameter.DEFAULT_SLOT_VALUE, Command.ECommandDublicate.GetResponse, true, "slots")] public class RDMDefaultSlotValue : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs b/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs index 8c5a3ab..0c9fabf 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DEVICE_INFO, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.DEVICE_INFO, Command.ECommandDublicate.GetResponse)] public class RDMDeviceInfo : AbstractRDMPayloadObject { public RDMDeviceInfo( @@ -80,15 +80,15 @@ public RDMDeviceInfo( [DataTreeObjectProperty("software_version_id", 4)] public uint SoftwareVersionId { get; private set; } - [DataTreeObjectDependecieProperty("slot", ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicte.GetRequest)] + [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.ECommandDublicte.GetRequest)] - [DataTreeObjectDependecieProperty("personality", ERDM_Parameter.DMX_PERSONALITY_ID, Command.ECommandDublicte.GetRequest)] + [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; } @@ -98,8 +98,8 @@ public RDMDeviceInfo( [DataTreeObjectProperty("sub_device_count", 9)] public ushort SubDeviceCount { get; private set; } - [DataTreeObjectDependecieProperty("sensor", ERDM_Parameter.SENSOR_DEFINITION, Command.ECommandDublicte.GetRequest)] - [DataTreeObjectDependecieProperty("sensor", ERDM_Parameter.SENSOR_VALUE, Command.ECommandDublicte.GetRequest)] + [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; } diff --git a/RDMSharp/RDM/PayloadObject/RDMDimmerInfo.cs b/RDMSharp/RDM/PayloadObject/RDMDimmerInfo.cs index 7b159b4..a44dac1 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDimmerInfo.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDimmerInfo.cs @@ -6,7 +6,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DIMMER_INFO, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.DIMMER_INFO, Command.ECommandDublicate.GetResponse)] public class RDMDimmerInfo : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMLockStateDescription.cs b/RDMSharp/RDM/PayloadObject/RDMLockStateDescription.cs index df36ff7..7b61dd4 100644 --- a/RDMSharp/RDM/PayloadObject/RDMLockStateDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMLockStateDescription.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.LOCK_STATE_DESCRIPTION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.LOCK_STATE_DESCRIPTION, Command.ECommandDublicate.GetResponse)] public class RDMLockStateDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMMetadataJson.cs b/RDMSharp/RDM/PayloadObject/RDMMetadataJson.cs index 6e9f73c..5e36d16 100644 --- a/RDMSharp/RDM/PayloadObject/RDMMetadataJson.cs +++ b/RDMSharp/RDM/PayloadObject/RDMMetadataJson.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.METADATA_JSON, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.METADATA_JSON, Command.ECommandDublicate.GetResponse)] public class RDMMetadataJson : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMMetadataParameterVersion.cs b/RDMSharp/RDM/PayloadObject/RDMMetadataParameterVersion.cs index dc6c72f..2d58893 100644 --- a/RDMSharp/RDM/PayloadObject/RDMMetadataParameterVersion.cs +++ b/RDMSharp/RDM/PayloadObject/RDMMetadataParameterVersion.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.METADATA_PARAMETER_VERSION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.METADATA_PARAMETER_VERSION, Command.ECommandDublicate.GetResponse)] public class RDMMetadataParameterVersion : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMMinimumLevel.cs b/RDMSharp/RDM/PayloadObject/RDMMinimumLevel.cs index ca11a86..318fb12 100644 --- a/RDMSharp/RDM/PayloadObject/RDMMinimumLevel.cs +++ b/RDMSharp/RDM/PayloadObject/RDMMinimumLevel.cs @@ -5,8 +5,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.MINIMUM_LEVEL, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.MINIMUM_LEVEL, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.MINIMUM_LEVEL, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.MINIMUM_LEVEL, Command.ECommandDublicate.SetRequest)] public class RDMMinimumLevel : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMModulationFrequency.cs b/RDMSharp/RDM/PayloadObject/RDMModulationFrequency.cs index 382a20f..d1c0de5 100644 --- a/RDMSharp/RDM/PayloadObject/RDMModulationFrequency.cs +++ b/RDMSharp/RDM/PayloadObject/RDMModulationFrequency.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.MODULATION_FREQUENCY, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.MODULATION_FREQUENCY, Command.ECommandDublicate.GetResponse)] public class RDMModulationFrequency : AbstractRDMPayloadObjectOneOf { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMModulationFrequencyDescription.cs b/RDMSharp/RDM/PayloadObject/RDMModulationFrequencyDescription.cs index 1fbd6c2..5f87bd9 100644 --- a/RDMSharp/RDM/PayloadObject/RDMModulationFrequencyDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMModulationFrequencyDescription.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.MODULATION_FREQUENCY_DESCRIPTION, Command.ECommandDublicate.GetResponse)] public class RDMModulationFrequencyDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMOutputResponseTime.cs b/RDMSharp/RDM/PayloadObject/RDMOutputResponseTime.cs index d832d56..77ad628 100644 --- a/RDMSharp/RDM/PayloadObject/RDMOutputResponseTime.cs +++ b/RDMSharp/RDM/PayloadObject/RDMOutputResponseTime.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.OUTPUT_RESPONSE_TIME, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.OUTPUT_RESPONSE_TIME, Command.ECommandDublicate.GetResponse)] public class RDMOutputResponseTime : AbstractRDMPayloadObjectOneOf { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMOutputResponseTimeDescription.cs b/RDMSharp/RDM/PayloadObject/RDMOutputResponseTimeDescription.cs index d034517..e488364 100644 --- a/RDMSharp/RDM/PayloadObject/RDMOutputResponseTimeDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMOutputResponseTimeDescription.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.OUTPUT_RESPONSE_TIME_DESCRIPTION, Command.ECommandDublicate.GetResponse)] public class RDMOutputResponseTimeDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMParameterDescription.cs b/RDMSharp/RDM/PayloadObject/RDMParameterDescription.cs index ebdd036..4c11bd6 100644 --- a/RDMSharp/RDM/PayloadObject/RDMParameterDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMParameterDescription.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.PARAMETER_DESCRIPTION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.PARAMETER_DESCRIPTION, Command.ECommandDublicate.GetResponse)] public class RDMParameterDescription : AbstractRDMPayloadObject { [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060")] diff --git a/RDMSharp/RDM/PayloadObject/RDMPersonalityId.cs b/RDMSharp/RDM/PayloadObject/RDMPersonalityId.cs index b22d2d5..a8e54a5 100644 --- a/RDMSharp/RDM/PayloadObject/RDMPersonalityId.cs +++ b/RDMSharp/RDM/PayloadObject/RDMPersonalityId.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DMX_PERSONALITY_ID, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.DMX_PERSONALITY_ID, Command.ECommandDublicate.GetResponse)] public class RDMPersonalityId : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMPresetInfo.cs b/RDMSharp/RDM/PayloadObject/RDMPresetInfo.cs index 8c210ff..6b3eb81 100644 --- a/RDMSharp/RDM/PayloadObject/RDMPresetInfo.cs +++ b/RDMSharp/RDM/PayloadObject/RDMPresetInfo.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.PRESET_INFO, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.PRESET_INFO, Command.ECommandDublicate.GetResponse)] public class RDMPresetInfo : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMPresetPlayback.cs b/RDMSharp/RDM/PayloadObject/RDMPresetPlayback.cs index 51095a9..79749a6 100644 --- a/RDMSharp/RDM/PayloadObject/RDMPresetPlayback.cs +++ b/RDMSharp/RDM/PayloadObject/RDMPresetPlayback.cs @@ -5,8 +5,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.PRESET_PLAYBACK, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.PRESET_PLAYBACK, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.PRESET_PLAYBACK, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.PRESET_PLAYBACK, Command.ECommandDublicate.SetRequest)] public class RDMPresetPlayback : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMPresetStatus.cs b/RDMSharp/RDM/PayloadObject/RDMPresetStatus.cs index a373d94..4558852 100644 --- a/RDMSharp/RDM/PayloadObject/RDMPresetStatus.cs +++ b/RDMSharp/RDM/PayloadObject/RDMPresetStatus.cs @@ -5,9 +5,9 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.PRESET_STATUS, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.PRESET_STATUS, Command.ECommandDublicte.SetRequest)] - [DataTreeObject(ERDM_Parameter.CAPTURE_PRESET, Command.ECommandDublicte.SetRequest)] + [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( diff --git a/RDMSharp/RDM/PayloadObject/RDMProxiedDeviceCount.cs b/RDMSharp/RDM/PayloadObject/RDMProxiedDeviceCount.cs index c9b7665..a736be6 100644 --- a/RDMSharp/RDM/PayloadObject/RDMProxiedDeviceCount.cs +++ b/RDMSharp/RDM/PayloadObject/RDMProxiedDeviceCount.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.PROXIED_DEVICES_COUNT, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.PROXIED_DEVICES_COUNT, Command.ECommandDublicate.GetResponse)] public class RDMProxiedDeviceCount : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMRealTimeClock.cs b/RDMSharp/RDM/PayloadObject/RDMRealTimeClock.cs index 0161580..5dc2995 100644 --- a/RDMSharp/RDM/PayloadObject/RDMRealTimeClock.cs +++ b/RDMSharp/RDM/PayloadObject/RDMRealTimeClock.cs @@ -5,8 +5,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.REAL_TIME_CLOCK, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.REAL_TIME_CLOCK, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.REAL_TIME_CLOCK, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.REAL_TIME_CLOCK, Command.ECommandDublicate.SetRequest)] public class RDMRealTimeClock : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMSelfTestDescription.cs b/RDMSharp/RDM/PayloadObject/RDMSelfTestDescription.cs index 5882723..9b63978 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSelfTestDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSelfTestDescription.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.SELF_TEST_DESCRIPTION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.SELF_TEST_DESCRIPTION, Command.ECommandDublicate.GetResponse)] public class RDMSelfTestDescription : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMSensorDefinition.cs b/RDMSharp/RDM/PayloadObject/RDMSensorDefinition.cs index c5a0fd3..269bf1f 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSensorDefinition.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSensorDefinition.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.SENSOR_DEFINITION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.SENSOR_DEFINITION, Command.ECommandDublicate.GetResponse)] public class RDMSensorDefinition : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { public RDMSensorDefinition( diff --git a/RDMSharp/RDM/PayloadObject/RDMSensorTypeCustomDefine.cs b/RDMSharp/RDM/PayloadObject/RDMSensorTypeCustomDefine.cs index fbd45fb..a59f2df 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSensorTypeCustomDefine.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSensorTypeCustomDefine.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.SENSOR_TYPE_CUSTOM, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.SENSOR_TYPE_CUSTOM, Command.ECommandDublicate.GetResponse)] public class RDMSensorTypeCustomDefine : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMSensorUnitCustomDefine.cs b/RDMSharp/RDM/PayloadObject/RDMSensorUnitCustomDefine.cs index c1bdf5d..4924ae3 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSensorUnitCustomDefine.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSensorUnitCustomDefine.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.SENSOR_UNIT_CUSTOM, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.SENSOR_UNIT_CUSTOM, Command.ECommandDublicate.GetResponse)] public class RDMSensorUnitCustomDefine : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMSensorValue.cs b/RDMSharp/RDM/PayloadObject/RDMSensorValue.cs index b115545..0b31c64 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSensorValue.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSensorValue.cs @@ -5,8 +5,8 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.SENSOR_VALUE, Command.ECommandDublicte.GetResponse)] - [DataTreeObject(ERDM_Parameter.SENSOR_VALUE, Command.ECommandDublicte.SetResponse)] + [DataTreeObject(ERDM_Parameter.SENSOR_VALUE, Command.ECommandDublicate.GetResponse)] + [DataTreeObject(ERDM_Parameter.SENSOR_VALUE, Command.ECommandDublicate.SetResponse)] public class RDMSensorValue : AbstractRDMPayloadObject, IRDMPayloadObjectIndex { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs b/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs index 0af3634..750dfea 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicate.GetResponse)] public class RDMSlotDescription : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/RDMSlotInfo.cs b/RDMSharp/RDM/PayloadObject/RDMSlotInfo.cs index 2c9771c..0ce1107 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSlotInfo.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSlotInfo.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.SLOT_INFO, Command.ECommandDublicte.GetResponse, true, "slots")] + [DataTreeObject(ERDM_Parameter.SLOT_INFO, Command.ECommandDublicate.GetResponse, true, "slots")] public class RDMSlotInfo : AbstractRDMPayloadObject { public RDMSlotInfo( diff --git a/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs b/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs index 185bf9a..5eab0ee 100644 --- a/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs +++ b/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs @@ -5,7 +5,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.STATUS_MESSAGES, Command.ECommandDublicte.GetResponse, true, "slots")] + [DataTreeObject(ERDM_Parameter.STATUS_MESSAGES, Command.ECommandDublicate.GetResponse, true, "slots")] public class RDMStatusMessage : AbstractRDMPayloadObject { public RDMStatusMessage( diff --git a/RDMSharp/RDM/PayloadObject/SetDiscoveryStateRequest.cs b/RDMSharp/RDM/PayloadObject/SetDiscoveryStateRequest.cs index 9f92081..b8b99a0 100644 --- a/RDMSharp/RDM/PayloadObject/SetDiscoveryStateRequest.cs +++ b/RDMSharp/RDM/PayloadObject/SetDiscoveryStateRequest.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.DISCOVERY_STATE, Command.ECommandDublicte.SetResponse)] + [DataTreeObject(ERDM_Parameter.DISCOVERY_STATE, Command.ECommandDublicate.SetResponse)] public class SetDiscoveryStateRequest : AbstractRDMPayloadObject { public SetDiscoveryStateRequest( diff --git a/RDMSharp/RDM/PayloadObject/SetEndpointTimingRequest.cs b/RDMSharp/RDM/PayloadObject/SetEndpointTimingRequest.cs index 8b3130c..bea4f66 100644 --- a/RDMSharp/RDM/PayloadObject/SetEndpointTimingRequest.cs +++ b/RDMSharp/RDM/PayloadObject/SetEndpointTimingRequest.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.ENDPOINT_TIMING, Command.ECommandDublicate.SetRequest)] public class SetEndpointTimingRequest : AbstractRDMPayloadObject { diff --git a/RDMSharp/RDM/PayloadObject/SetLockPinRequest.cs b/RDMSharp/RDM/PayloadObject/SetLockPinRequest.cs index 62304f9..790188a 100644 --- a/RDMSharp/RDM/PayloadObject/SetLockPinRequest.cs +++ b/RDMSharp/RDM/PayloadObject/SetLockPinRequest.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.LOCK_PIN, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.LOCK_PIN, Command.ECommandDublicate.SetRequest)] public class SetLockPinRequest : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/SetLockStateRequest.cs b/RDMSharp/RDM/PayloadObject/SetLockStateRequest.cs index c814540..cf7df13 100644 --- a/RDMSharp/RDM/PayloadObject/SetLockStateRequest.cs +++ b/RDMSharp/RDM/PayloadObject/SetLockStateRequest.cs @@ -4,7 +4,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.LOCK_STATE, Command.ECommandDublicte.SetRequest)] + [DataTreeObject(ERDM_Parameter.LOCK_STATE, Command.ECommandDublicate.SetRequest)] public class SetLockStateRequest : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PayloadObject/TCPCommsEntry.cs b/RDMSharp/RDM/PayloadObject/TCPCommsEntry.cs index 7582513..31f7feb 100644 --- a/RDMSharp/RDM/PayloadObject/TCPCommsEntry.cs +++ b/RDMSharp/RDM/PayloadObject/TCPCommsEntry.cs @@ -8,7 +8,7 @@ namespace RDMSharp { - [DataTreeObject(ERDM_Parameter.TCP_COMMS_STATUS, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.TCP_COMMS_STATUS, Command.ECommandDublicate.GetResponse)] public class TCPCommsEntry : AbstractRDMPayloadObject { [DataTreeObjectConstructor] diff --git a/RDMSharp/RDM/PeerToPeerProcess.cs b/RDMSharp/RDM/PeerToPeerProcess.cs index 5e6d637..8d39f75 100644 --- a/RDMSharp/RDM/PeerToPeerProcess.cs +++ b/RDMSharp/RDM/PeerToPeerProcess.cs @@ -61,13 +61,13 @@ private async Task run(AsyncRDMRequestHelper asyncRDMRequestHelper) State = EPeerToPeerProcessState.Running; - ECommandDublicte commandRequest = ECommandDublicte.GetRequest; + ECommandDublicate commandRequest = ECommandDublicate.GetRequest; if (Command == ERDM_Command.SET_COMMAND) - commandRequest = ECommandDublicte.SetRequest; + commandRequest = ECommandDublicate.SetRequest; - ECommandDublicte commandResponse = ECommandDublicte.GetResponse; + ECommandDublicate commandResponse = ECommandDublicate.GetResponse; if (Command == ERDM_Command.SET_COMMAND) - commandResponse = ECommandDublicte.SetResponse; + commandResponse = ECommandDublicate.SetResponse; byte[] parameterData = MetadataFactory.ParsePayloadToData(Define, commandRequest, RequestPayloadObject); request = new RDMMessage() diff --git a/RDMSharp/RDM/RDMMessage.cs b/RDMSharp/RDM/RDMMessage.cs index 87ce8de..7b91bf4 100644 --- a/RDMSharp/RDM/RDMMessage.cs +++ b/RDMSharp/RDM/RDMMessage.cs @@ -380,6 +380,7 @@ public byte[] BuildMessage() } private object valueCache = null; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2200:Erneut ausführen, um Stapeldetails beizubehalten", Justification = "")] public object Value { get @@ -410,7 +411,7 @@ public object Value manufacturer = DestUID.ManufacturerID; } - return valueCache = MetadataFactory.ParseDataToPayload(MetadataFactory.GetDefine(new ParameterBag(this.Parameter, manufacturer)), Tools.ConvertCommandDublicteToCommand(Command), this.ParameterData).ParsedObject; + return valueCache = MetadataFactory.ParseDataToPayload(MetadataFactory.GetDefine(new ParameterBag(this.Parameter, manufacturer)), Tools.ConvertCommandDublicateToCommand(Command), this.ParameterData).ParsedObject; } diff --git a/RDMSharp/RDM/Sensor.cs b/RDMSharp/RDM/Sensor.cs index 785bf30..4d896fc 100644 --- a/RDMSharp/RDM/Sensor.cs +++ b/RDMSharp/RDM/Sensor.cs @@ -263,9 +263,9 @@ protected virtual void UpdateValue(short value) { PresentValue = value; if (this.LowestHighestValueSupported) - updateLowestHighstValue(value); + updateLowestHighestValue(value); } - private void updateLowestHighstValue(short value) + private void updateLowestHighestValue(short value) { LowestValue = Math.Min(LowestValue, value); HighestValue = Math.Max(HighestValue, value); diff --git a/RDMSharp/RDM/Tools.cs b/RDMSharp/RDM/Tools.cs index 9b025c8..c4ef3b3 100644 --- a/RDMSharp/RDM/Tools.cs +++ b/RDMSharp/RDM/Tools.cs @@ -570,18 +570,18 @@ public static IReadOnlyDictionary AsReadOnly(this IDictionary return new ReadOnlyDictionary(source); } - public static ECommandDublicte ConvertCommandDublicteToCommand(ERDM_Command v) + public static ECommandDublicate ConvertCommandDublicateToCommand(ERDM_Command v) { switch (v) { case ERDM_Command.GET_COMMAND: - return ECommandDublicte.GetRequest; + return ECommandDublicate.GetRequest; case ERDM_Command.GET_COMMAND_RESPONSE: - return ECommandDublicte.GetResponse; + return ECommandDublicate.GetResponse; case ERDM_Command.SET_COMMAND: - return ECommandDublicte.SetRequest; + return ECommandDublicate.SetRequest; case ERDM_Command.SET_COMMAND_RESPONSE: - return ECommandDublicte.SetResponse; + return ECommandDublicate.SetResponse; } throw new NotSupportedException(); } diff --git a/RDMSharp/RDMSharp.csproj b/RDMSharp/RDMSharp.csproj index 8c5d479..0e963fc 100644 --- a/RDMSharp/RDMSharp.csproj +++ b/RDMSharp/RDMSharp.csproj @@ -31,9 +31,14 @@ - - - + + + + + + + + diff --git a/RDMSharpTests/Devices/Mock/AbstractMockDevice.cs b/RDMSharpTests/Devices/Mock/AbstractMockDevice.cs index b7448ae..6c7c8b5 100644 --- a/RDMSharpTests/Devices/Mock/AbstractMockDevice.cs +++ b/RDMSharpTests/Devices/Mock/AbstractMockDevice.cs @@ -29,15 +29,15 @@ private void registerEvent() if (eventRegistered) return; eventRegistered = true; - SendReceivePipeline.RDMMessageRereived -= SendReceivePipeline_RDMMessageRereived; - SendReceivePipelineImitateRealConditions.RDMMessageRereivedRequest -= SendReceivePipelineImitateRealConditions_RDMMessageRereivedRequest; + SendReceivePipeline.RDMMessageReceived -= SendReceivePipeline_RDMMessageReceived; + SendReceivePipelineImitateRealConditions.RDMMessageReceivedRequest -= SendReceivePipelineImitateRealConditions_RDMMessageReceivedRequest; if (ImitateRealConditions) - SendReceivePipelineImitateRealConditions.RDMMessageRereivedRequest += SendReceivePipelineImitateRealConditions_RDMMessageRereivedRequest; + SendReceivePipelineImitateRealConditions.RDMMessageReceivedRequest += SendReceivePipelineImitateRealConditions_RDMMessageReceivedRequest; else - SendReceivePipeline.RDMMessageRereived += SendReceivePipeline_RDMMessageRereived; + SendReceivePipeline.RDMMessageReceived += SendReceivePipeline_RDMMessageReceived; } - private async void SendReceivePipeline_RDMMessageRereived(object? sender, Tuple tuple) + private async void SendReceivePipeline_RDMMessageReceived(object? sender, Tuple tuple) { if (identifyer.TryGetValue(tuple.Item1, out var rdmMessage)) { @@ -51,7 +51,7 @@ private async void SendReceivePipeline_RDMMessageRereived(object? sender, Tuple< await base.ReceiveRDMMessage(tuple.Item2); } - private async void SendReceivePipelineImitateRealConditions_RDMMessageRereivedRequest(object? sender, RDMMessage rdmMessage) + private async void SendReceivePipelineImitateRealConditions_RDMMessageReceivedRequest(object? sender, RDMMessage rdmMessage) { await base.ReceiveRDMMessage(rdmMessage); } @@ -81,14 +81,16 @@ protected sealed override void onDispose() { Logger.LogError(e); } - SendReceivePipeline.RDMMessageRereived -= SendReceivePipeline_RDMMessageRereived; - SendReceivePipelineImitateRealConditions.RDMMessageRereivedRequest -= SendReceivePipelineImitateRealConditions_RDMMessageRereivedRequest; + SendReceivePipeline.RDMMessageReceived -= SendReceivePipeline_RDMMessageReceived; + SendReceivePipelineImitateRealConditions.RDMMessageReceivedRequest -= SendReceivePipelineImitateRealConditions_RDMMessageReceivedRequest; eventRegistered = false; transactionCounter = 0; identifyer.Clear(); ImitateRealConditions = false; } +#pragma warning disable CS0114 protected abstract void OnDispose(); +#pragma warning restore CS0114 } internal abstract class AbstractMockSubDevice : AbstractMockDevice, IRDMRemoteSubDevice diff --git a/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs b/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs index d7f20d5..cfa813d 100644 --- a/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs +++ b/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs @@ -6,7 +6,6 @@ internal abstract class AbstractMockGeneratedDevice : AbstractGeneratedRDMDevice { private readonly ConcurrentDictionary identifyer = new ConcurrentDictionary(); private bool eventRegistered = false; - private byte transactionCounter = 0; private bool imitateRealConditions = false; internal bool ImitateRealConditions { @@ -18,11 +17,11 @@ internal bool ImitateRealConditions registerEvent(); } } - 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, ERDM_Parameter[] parameters, string manufacturer, Sensor[]? sensors = null, IRDMDevice[]? subDevices = null) : base(uid, parameters, manufacturer, sensors: sensors, subDevices: subDevices) { registerEvent(); } - public AbstractMockGeneratedDevice(UID uid, SubDevice subDevice, ERDM_Parameter[] parameters, string manufacturer, Sensor[] sensors = null) : base(uid, subDevice, parameters, manufacturer, sensors: sensors) + public AbstractMockGeneratedDevice(UID uid, SubDevice subDevice, ERDM_Parameter[] parameters, string manufacturer, Sensor[]? sensors = null) : base(uid, subDevice, parameters, manufacturer, sensors: sensors) { registerEvent(); } @@ -32,16 +31,16 @@ private void registerEvent() return; eventRegistered = true; - SendReceivePipeline.RDMMessageRereived -= SendReceivePipeline_RDMMessageRereived; - SendReceivePipelineImitateRealConditions.RDMMessageRereivedRequest -= SendReceivePipelineImitateRealConditions_RDMMessageRereivedRequest; + SendReceivePipeline.RDMMessageReceived -= SendReceivePipeline_RDMMessageReceived; + SendReceivePipelineImitateRealConditions.RDMMessageReceivedRequest -= SendReceivePipelineImitateRealConditions_RDMMessageReceivedRequest; if (ImitateRealConditions) - SendReceivePipelineImitateRealConditions.RDMMessageRereivedRequest += SendReceivePipelineImitateRealConditions_RDMMessageRereivedRequest; + SendReceivePipelineImitateRealConditions.RDMMessageReceivedRequest += SendReceivePipelineImitateRealConditions_RDMMessageReceivedRequest; else - SendReceivePipeline.RDMMessageRereived += SendReceivePipeline_RDMMessageRereived; + SendReceivePipeline.RDMMessageReceived += SendReceivePipeline_RDMMessageReceived; } - private async void SendReceivePipeline_RDMMessageRereived(object? sender, Tuple tuple) + private async void SendReceivePipeline_RDMMessageReceived(object? sender, Tuple tuple) { if (identifyer.TryGetValue(tuple.Item1, out var rdmMessage) && RDMMessage.Equals(rdmMessage, tuple.Item2)) { @@ -51,20 +50,23 @@ private async void SendReceivePipeline_RDMMessageRereived(object? sender, Tuple< await base.ReceiveRDMMessage(tuple.Item2); } - private async void SendReceivePipelineImitateRealConditions_RDMMessageRereivedRequest(object? sender, RDMMessage rdmMessage) + private async void SendReceivePipelineImitateRealConditions_RDMMessageReceivedRequest(object? sender, RDMMessage rdmMessage) { await base.ReceiveRDMMessage(rdmMessage); } protected override async Task SendRDMMessage(RDMMessage rdmMessage) { if (rdmMessage == null) + { + await Task.CompletedTask; return; + } registerEvent(); var i = SendReceivePipeline.GetNewIdentifyer(); identifyer.TryAdd(i, rdmMessage); if (ImitateRealConditions) - _ = SendReceivePipelineImitateRealConditions.RDMMessageSend(rdmMessage); // in this case as responder we dont wait for comlpletion of the send, we just send it and forget it + _ = 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 SendReceivePipeline.RDMMessageSend(i, rdmMessage); } @@ -78,13 +80,14 @@ protected sealed override void onDispose() { Logger.LogError(e); } - SendReceivePipeline.RDMMessageRereived -= SendReceivePipeline_RDMMessageRereived; - SendReceivePipelineImitateRealConditions.RDMMessageRereivedRequest -= SendReceivePipelineImitateRealConditions_RDMMessageRereivedRequest; + SendReceivePipeline.RDMMessageReceived -= SendReceivePipeline_RDMMessageReceived; + SendReceivePipelineImitateRealConditions.RDMMessageReceivedRequest -= SendReceivePipelineImitateRealConditions_RDMMessageReceivedRequest; eventRegistered = false; - transactionCounter = 0; identifyer.Clear(); ImitateRealConditions = false; } +#pragma warning disable CS0114 protected abstract void OnDispose(); +#pragma warning restore CS0114 } } diff --git a/RDMSharpTests/Devices/Mock/MockDiscoveryTool.cs b/RDMSharpTests/Devices/Mock/MockDiscoveryTool.cs index c653cd8..c190d59 100644 --- a/RDMSharpTests/Devices/Mock/MockDiscoveryTool.cs +++ b/RDMSharpTests/Devices/Mock/MockDiscoveryTool.cs @@ -5,10 +5,10 @@ internal sealed class MockDiscoveryTool : AbstractDiscoveryTool { public MockDiscoveryTool() : base() { - SendReceivePipelineImitateRealConditions.RDMMessageRereivedResponse += SendReceivePipelineImitateRealConditions_RDMMessageRereivedResponse; + SendReceivePipelineImitateRealConditions.RDMMessageReceivedResponse += SendReceivePipelineImitateRealConditions_RDMMessageReceivedResponse; } - private void SendReceivePipelineImitateRealConditions_RDMMessageRereivedResponse(object? sender, byte[] e) + private void SendReceivePipelineImitateRealConditions_RDMMessageReceivedResponse(object? sender, byte[] e) { try { diff --git a/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs b/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs index 551da5a..ffd8be8 100644 --- a/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs +++ b/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs @@ -10,12 +10,12 @@ internal abstract class MockGeneratedDeviceWithSubDevice1 : AbstractMockGenerate public override string DeviceModelDescription => "Test Model Description SubDevice"; public override bool SupportDMXAddress => true; - 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) + 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) + 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(); diff --git a/RDMSharpTests/Devices/Mock/SendReceivePipeline.cs b/RDMSharpTests/Devices/Mock/SendReceivePipeline.cs index 4264a6f..61a501c 100644 --- a/RDMSharpTests/Devices/Mock/SendReceivePipeline.cs +++ b/RDMSharpTests/Devices/Mock/SendReceivePipeline.cs @@ -18,8 +18,8 @@ public static void RDMMessageSend(long identifyer, RDMMessage rdmMessage) Console.WriteLine(rdmMessage); #endif - RDMMessageRereived?.InvokeFailSafe(null, new Tuple(identifyer, rdmMessage)); + RDMMessageReceived?.InvokeFailSafe(null, new Tuple(identifyer, rdmMessage)); } - public static event EventHandler>? RDMMessageRereived; + public static event EventHandler>? RDMMessageReceived; } } diff --git a/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs b/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs index 9107baa..f6baa8f 100644 --- a/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs +++ b/RDMSharpTests/Devices/Mock/SendReceivePipelineImitateRealConditions.cs @@ -47,11 +47,12 @@ public static async Task RDMMessageSend(RDMMessage rdmMessage) { await semaphoreSlim.WaitAsync(); await Task.Delay(3); - while (queue.TryDequeue(out Task waifOnMee)) - await waifOnMee; + while (queue.TryDequeue(out Task? waitOnMee)) // wait for all other MockDevices to put their Data on the Line, in real World this would be the time is not nessecary to wait for the other devices because they all act simultan but in the Test-Environment it needs time to itterate throu all Devices + if (waitOnMee != null) + await waitOnMee; await semaphoreSlim2.WaitAsync(); - RDMMessageRereivedResponse?.InvokeFailSafe(null, data); + RDMMessageReceivedResponse?.InvokeFailSafe(null, data); data = null; queue.Clear(); semaphoreSlim2.Release(); @@ -60,10 +61,10 @@ public static async Task RDMMessageSend(RDMMessage rdmMessage) } else { - RDMMessageRereivedRequest?.InvokeFailSafe(null, rdmMessage); + RDMMessageReceivedRequest?.InvokeFailSafe(null, rdmMessage); } } - public static event EventHandler? RDMMessageRereivedRequest; - public static event EventHandler? RDMMessageRereivedResponse; + public static event EventHandler? RDMMessageReceivedRequest; + public static event EventHandler? RDMMessageReceivedResponse; } } diff --git a/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTestSubject.cs b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTestSubject.cs index 7cf019b..f904ec8 100644 --- a/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTestSubject.cs +++ b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTestSubject.cs @@ -42,12 +42,19 @@ private static object[] getTestSubjects() } return instances.ToArray(); } - private static string getContent(string path) + private static string? getContent(string path) { if (string.IsNullOrWhiteSpace(path)) return null; + var assembly = typeof(MetadataJSONObjectDefineTestSubject).Assembly; - using Stream stream = assembly.GetManifestResourceStream(path); + if (assembly == null) + return null; + + using Stream? stream = assembly.GetManifestResourceStream(path); + if (stream == null) + return null; + using StreamReader reader = new StreamReader(stream); return reader.ReadToEnd(); } diff --git a/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs index 26167bf..2433e97 100644 --- a/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs +++ b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs @@ -38,8 +38,9 @@ public void TestDeseriaizeAndSerialize() { try { - MetadataJSONObjectDefine deserialized = JsonSerializer.Deserialize(testSubject.Define.Content); - Assert.That(deserialized.Version, Is.AtLeast(1)); + 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); @@ -64,14 +65,16 @@ public void TestDeseriaizeAndSerialize() 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 - throw; +#pragma warning disable CA2200 + throw ex; +#pragma warning restore CA2200 #endif } } [Test] - public void TestDeseriaizedObject() + public void TestDeserializedObject() { - MetadataJSONObjectDefine deserialized = null; + MetadataJSONObjectDefine? deserialized = null; testString(testSubject.Define.ToString()); try { @@ -85,9 +88,12 @@ public void TestDeseriaizedObject() 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 - throw; +#pragma warning disable CA2200 + 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); @@ -114,7 +120,7 @@ public void TestDeseriaizedObject() if (deserialized.GetRequest != null) { testCommand(deserialized.GetRequest.Value); - deserialized.GetCommand(Command.ECommandDublicte.GetRequest, out Command? command); + deserialized.GetCommand(Command.ECommandDublicate.GetRequest, out Command? command); if (command != null) testCommand(command.Value); } @@ -122,7 +128,7 @@ public void TestDeseriaizedObject() if (deserialized.GetResponse != null) { testCommand(deserialized.GetResponse.Value); - deserialized.GetCommand(Command.ECommandDublicte.GetResponse, out Command? command); + deserialized.GetCommand(Command.ECommandDublicate.GetResponse, out Command? command); if (command != null) testCommand(command.Value); } @@ -130,7 +136,7 @@ public void TestDeseriaizedObject() if (deserialized.SetRequest != null) { testCommand(deserialized.SetRequest.Value); - deserialized.GetCommand(Command.ECommandDublicte.SetRequest, out Command? command); + deserialized.GetCommand(Command.ECommandDublicate.SetRequest, out Command? command); if (command != null) testCommand(command.Value); } @@ -138,7 +144,7 @@ public void TestDeseriaizedObject() if (deserialized.SetResponse != null) { testCommand(deserialized.SetResponse.Value); - deserialized.GetCommand(Command.ECommandDublicte.SetResponse, out Command? command); + deserialized.GetCommand(Command.ECommandDublicate.SetResponse, out Command? command); if (command != null) testCommand(command.Value); } @@ -155,7 +161,7 @@ static void testCommand(Command command) { testString(command.ToString()!); PDL? pdl = null; - if (command.EnumValue is Command.ECommandDublicte _enum) + if (command.EnumValue is Command.ECommandDublicate _enum) { Assert.That(command.GetIsEmpty(), Is.False); testString(_enum.ToString()!); @@ -222,7 +228,7 @@ static void testCommon(CommonPropertiesForNamed common) static void testReference(ReferenceType reference) { testString(reference.ToString()); - Assert.That(reference.Command, Is.EqualTo(Command.ECommandDublicte.GetRequest).Or.EqualTo(Command.ECommandDublicte.GetResponse).Or.EqualTo(Command.ECommandDublicte.SetRequest).Or.EqualTo(Command.ECommandDublicte.SetResponse)); + 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) diff --git a/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs b/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs index f95bf1b..8516068 100644 --- a/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs +++ b/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs @@ -40,14 +40,14 @@ public void TestMany() Assert.That(bitFieldType.ValueForUnspecified, Is.True); DoParseDataTest(bitFieldType, dataTree, new byte[] { 0b11101011, 0b01111111 }); } - private void DoParseDataTest(BitFieldType bitFieldType, DataTree dataTree, byte[] expectedData, string message = null) + private void DoParseDataTest(BitFieldType bitFieldType, DataTree dataTree, byte[] expectedData, string? message = null) { Assert.Multiple(() => { Assert.That(dataTree.Value, Is.Null); Assert.That(dataTree.Children, Is.Not.Null); var data = new byte[0]; - Assert.DoesNotThrow(() => data = bitFieldType.ParsePayloadToData(dataTree), message); + Assert.DoesNotThrow(() => data = bitFieldType.ParsePayloadToData(dataTree), message!); Assert.That(data, Is.EqualTo(expectedData), message); byte[] clonaData = new byte[data.Length]; @@ -66,24 +66,24 @@ private void DoParseDataTest(BitFieldType bitFieldType, DataTree dataTree, byte[ Assert.That(parsedDataTree.Value, Is.Null); Assert.That(parsedDataTree.Children, Is.Not.Null); - Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, children: dataTree.Children)), message); - Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: dataTree.Children?.Take(2).ToArray())), message); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, children: dataTree.Children)), message!); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: dataTree.Children?.Take(2).ToArray())), message!); var children = dataTree.Children!.ToArray(); children[1] = new DataTree("Other Name", children[1].Index, children[1].Value); - Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message!); children = dataTree.Children!.ToArray(); children[1] = new DataTree(children[1].Name, 3, children[1].Value); - Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message!); children = dataTree.Children!.ToArray(); children[1] = new DataTree(children[1].Name, 0, children[1].Value); - Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message!); children = dataTree.Children!.ToArray(); children[1] = new DataTree(children[1].Name, children[1].Index, 3); - Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message!); }); } } diff --git a/RDMSharpTests/Metadata/JSON/TestBooleanType.cs b/RDMSharpTests/Metadata/JSON/TestBooleanType.cs index 79fa755..ddec1c5 100644 --- a/RDMSharpTests/Metadata/JSON/TestBooleanType.cs +++ b/RDMSharpTests/Metadata/JSON/TestBooleanType.cs @@ -45,29 +45,29 @@ public void TestMany() labeledBooleanType[1] = new LabeledBooleanType("NAME22", "DISPLAY_NAME22", "NOTES22", null, false); Assert.Throws(typeof(ArgumentException), () => booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "boolean", labeledBooleanType)); } - private void DoParseDataTest(BooleanType booleanType, bool value, byte[] expectedData, string message = null) + private void DoParseDataTest(BooleanType booleanType, bool value, byte[] expectedData, string? message = null) { var dataTree = new DataTree(booleanType.Name, 0, value); var data = new byte[0]; - Assert.DoesNotThrow(() => data = booleanType.ParsePayloadToData(dataTree), message); + Assert.DoesNotThrow(() => data = booleanType.ParsePayloadToData(dataTree), message!); Assert.That(data, Is.EqualTo(expectedData), message); - byte[] clonaData = new byte[data.Length]; - Array.Copy(data, clonaData, clonaData.Length); - var parsedDataTree = booleanType.ParseDataToPayload(ref clonaData); - Assert.That(clonaData, Has.Length.EqualTo(0), message); + byte[] cloneData = new byte[data.Length]; + Array.Copy(data, cloneData, cloneData.Length); + var parsedDataTree = booleanType.ParseDataToPayload(ref cloneData); + Assert.That(cloneData, Has.Length.EqualTo(0), message); Assert.That(parsedDataTree, Is.EqualTo(dataTree), message); //Test for short Data & PDL Issue - clonaData = new byte[data.Length - 1]; - Array.Copy(data, clonaData, clonaData.Length); - Assert.DoesNotThrow(() => parsedDataTree = booleanType.ParseDataToPayload(ref clonaData)); + cloneData = new byte[data.Length - 1]; + Array.Copy(data, cloneData, cloneData.Length); + Assert.DoesNotThrow(() => parsedDataTree = booleanType.ParseDataToPayload(ref cloneData)); Assert.That(parsedDataTree.Issues, Is.Not.Null); Assert.That(parsedDataTree.Value, Is.Not.Null); - Assert.Throws(typeof(ArithmeticException), () => data = booleanType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, dataTree.Value)), message); - Assert.Throws(typeof(ArithmeticException), () => data = booleanType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, 234)), message); + Assert.Throws(typeof(ArithmeticException), () => data = booleanType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, dataTree.Value)), message!); + Assert.Throws(typeof(ArithmeticException), () => data = booleanType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, 234)), message!); } } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestCommand.cs b/RDMSharpTests/Metadata/JSON/TestCommand.cs index 09bfda6..3a39260 100644 --- a/RDMSharpTests/Metadata/JSON/TestCommand.cs +++ b/RDMSharpTests/Metadata/JSON/TestCommand.cs @@ -7,7 +7,7 @@ public class TestCommand [Test] public void TestMany() { - var command = new Command( Command.ECommandDublicte.GetResponse); + var command = new Command( Command.ECommandDublicate.GetResponse); Assert.That(command.GetIsEmpty(), Is.False); Assert.Throws(typeof(NotSupportedException), () => command.GetDataLength()); } diff --git a/RDMSharpTests/Metadata/JSON/TestIntegerType.cs b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs index 6b2751c..653538d 100644 --- a/RDMSharpTests/Metadata/JSON/TestIntegerType.cs +++ b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs @@ -257,11 +257,15 @@ public void TestPrefix1024() }; foreach (CommonPropertiesForNamed integerType in types) { + Assert.That(integerType, Is.Not.Null); Assert.That(((IIntegerType)integerType).PrefixBase, Is.EqualTo(2)); Assert.That(((IIntegerType)integerType).PrefixPower, Is.EqualTo(10)); Assert.That(((IIntegerType)integerType).PrefixMultiplyer, Is.EqualTo(1024)); - uint pdl = integerType.GetDataLength().Value.Value; + var val = integerType.GetDataLength().Value; + Assert.That(val, Is.Not.Null); + + uint pdl = val.Value; Assert.Multiple(() => { var data = new byte[pdl]; @@ -307,11 +311,15 @@ public void TestPrefix1024Negativ() }; foreach (CommonPropertiesForNamed integerType in types) { + Assert.That(integerType, Is.Not.Null); Assert.That(((IIntegerType)integerType).PrefixBase, Is.EqualTo(-1024)); Assert.That(((IIntegerType)integerType).PrefixPower, Is.EqualTo(1)); Assert.That(((IIntegerType)integerType).PrefixMultiplyer, Is.EqualTo(-1024)); - uint pdl = integerType.GetDataLength().Value.Value; + var val = integerType.GetDataLength().Value; + Assert.That(val, Is.Not.Null); + + uint pdl = val.Value; Assert.Multiple(() => { string message= ((IIntegerType)integerType).Type.ToString(); @@ -358,11 +366,15 @@ public void TestPrefix4Decimals() }; foreach (CommonPropertiesForNamed integerType in types) { + Assert.That(integerType, Is.Not.Null); Assert.That(((IIntegerType)integerType).PrefixBase, Is.EqualTo(10)); Assert.That(((IIntegerType)integerType).PrefixPower, Is.EqualTo(-4)); Assert.That(((IIntegerType)integerType).PrefixMultiplyer, Is.EqualTo(0.0001)); - uint pdl = integerType.GetDataLength().Value.Value; + var val = integerType.GetDataLength().Value; + Assert.That(val, Is.Not.Null); + + uint pdl = val.Value; Assert.Multiple(() => { var data = new byte[pdl]; @@ -393,28 +405,28 @@ public void TestPrefix4Decimals() } } - private void DoParseDataTest(IntegerType integerType, T value, byte[] expectedData, string message = null) + private void DoParseDataTest(IntegerType integerType, T value, byte[] expectedData, string? message = null) { var dataTree = new DataTree(integerType.Name, 0, value); var data = new byte[0]; - Assert.DoesNotThrow(() => data = integerType.ParsePayloadToData(dataTree), message); + Assert.DoesNotThrow(() => data = integerType.ParsePayloadToData(dataTree), message!); Assert.That(data, Is.EqualTo(expectedData), message); - byte[] clonaData = new byte[data.Length]; - Array.Copy(data, clonaData, clonaData.Length); - var parsedDataTree = integerType.ParseDataToPayload(ref clonaData); - Assert.That(clonaData, Has.Length.EqualTo(0), message); + byte[] cloneData = new byte[data.Length]; + Array.Copy(data, cloneData, cloneData.Length); + var parsedDataTree = integerType.ParseDataToPayload(ref cloneData); + Assert.That(cloneData, Has.Length.EqualTo(0), message); Assert.That(parsedDataTree, Is.EqualTo(dataTree), message); //Test for short Data & PDL Issue - clonaData = new byte[data.Length - 1]; - Array.Copy(data, clonaData, clonaData.Length); - Assert.DoesNotThrow(() => parsedDataTree = integerType.ParseDataToPayload(ref clonaData)); + cloneData = new byte[data.Length - 1]; + Array.Copy(data, cloneData, cloneData.Length); + Assert.DoesNotThrow(() => parsedDataTree = integerType.ParseDataToPayload(ref cloneData)); Assert.That(parsedDataTree.Issues, Is.Not.Null); Assert.That(parsedDataTree.Value, Is.Not.Null); - Assert.Throws(typeof(ArithmeticException), () => data = integerType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, dataTree.Value)), message); + Assert.Throws(typeof(ArithmeticException), () => data = integerType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, dataTree.Value)), message!); } } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestReferenceType.cs b/RDMSharpTests/Metadata/JSON/TestReferenceType.cs index 1fe16b6..222de91 100644 --- a/RDMSharpTests/Metadata/JSON/TestReferenceType.cs +++ b/RDMSharpTests/Metadata/JSON/TestReferenceType.cs @@ -11,7 +11,7 @@ public class TestReferenceType public void TestMany() { var referenceType = new ReferenceType("#/get_request/0"); - Assert.That(referenceType.Command, Is.EqualTo(Command.ECommandDublicte.GetRequest)); + Assert.That(referenceType.Command, Is.EqualTo(Command.ECommandDublicate.GetRequest)); Assert.That(referenceType.Pointer, Is.EqualTo(0)); Assert.DoesNotThrow(() => @@ -29,6 +29,7 @@ public void TestParse() { var referenceType = new ReferenceType("#/get_request/0", new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "uid", null, null)); Assert.That(referenceType.GetDataLength().Value, Is.EqualTo(6)); + Assert.That(referenceType.ReferencedObject, Is.Not.Null); var uid = new UID(0x4646, 0x12345678); var data = referenceType.ParsePayloadToData(new DataTree(referenceType.ReferencedObject.Name, 0, uid)); Assert.That(data, Is.EqualTo(new byte[] { 0x46, 0x46, 0x12, 0x34, 0x56, 0x78 })); diff --git a/RDMSharpTests/Metadata/JSON/TestStringType.cs b/RDMSharpTests/Metadata/JSON/TestStringType.cs index bc4aa2b..410a9a1 100644 --- a/RDMSharpTests/Metadata/JSON/TestStringType.cs +++ b/RDMSharpTests/Metadata/JSON/TestStringType.cs @@ -133,7 +133,7 @@ public void TestParseExceptions() { Console.OutputEncoding = Encoding.UTF8; var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 3, 6, 5, 8, null); - string str = "12"; + string? str = "12"; DataTree dataTree = new DataTree("NAME FAIL", 0, str); Assert.Throws(typeof(ArithmeticException), () => stringType.ParsePayloadToData(dataTree)); dataTree = new DataTree("NAME", 0, str); diff --git a/RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs b/RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs index 3916992..de8472b 100644 --- a/RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs +++ b/RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs @@ -42,7 +42,7 @@ public void Test_AllDefinedDataTreeObjectsForValidility() } [Test] - public async Task Test_DeviceInfo() + public void Test_DeviceInfo() { byte[] data = { 0x01, 0x00, 0x00, 0x05, 0x06, 0x01, 0x02, 0x00, @@ -53,7 +53,7 @@ public async Task Test_DeviceInfo() var parameterBag = new ParameterBag(ERDM_Parameter.DEVICE_INFO); var define = MetadataFactory.GetDefine(parameterBag); - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.GetResponse, data); + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, data); Assert.Multiple(() => { @@ -63,7 +63,8 @@ public async Task Test_DeviceInfo() Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDeviceInfo))); var obj = dataTreeBranch.ParsedObject as RDMDeviceInfo; - Assert.That(obj.RdmProtocolVersionMajor, Is.EqualTo(1)); + 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)); @@ -82,7 +83,7 @@ public async Task Test_DeviceInfo() } [Test] - public async Task Test_Personality() + public void Test_Personality() { byte[] data = { 0x01, 0x03 @@ -91,7 +92,7 @@ public async Task Test_Personality() var parameterBag = new ParameterBag(ERDM_Parameter.DMX_PERSONALITY); var define = MetadataFactory.GetDefine(parameterBag); - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.GetResponse, data); + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, data); Assert.Multiple(() => { @@ -101,7 +102,8 @@ public async Task Test_Personality() Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDMXPersonality))); var obj = dataTreeBranch.ParsedObject as RDMDMXPersonality; - Assert.That(obj.CurrentPersonality, Is.EqualTo(1)); + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.CurrentPersonality, Is.EqualTo(1)); Assert.That(obj.OfPersonalities, Is.EqualTo(3)); }); @@ -110,7 +112,7 @@ public async Task Test_Personality() } [Test] - public async Task Test_Personality_Description() + public void Test_Personality_Description() { byte[] data = { 0x01, 0x00, 0x01, 0x53, 0x45, 0x51, 0x55, 0x45, @@ -120,7 +122,7 @@ public async Task Test_Personality_Description() var parameterBag = new ParameterBag(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION); var define = MetadataFactory.GetDefine(parameterBag); - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.GetResponse, data); + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, data); Assert.Multiple(() => { @@ -130,7 +132,8 @@ public async Task Test_Personality_Description() Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDMXPersonalityDescription))); var obj = dataTreeBranch.ParsedObject as RDMDMXPersonalityDescription; - Assert.That(obj.PersonalityId, Is.EqualTo(1)); + 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")); }); @@ -140,7 +143,7 @@ public async Task Test_Personality_Description() } [Test] - public async Task Test_Slot_Description() + public void Test_Slot_Description() { byte[] data = { 0x00, 0x00, 0x53, 0x41, 0x46, 0x45, 0x54, 0x59 @@ -149,7 +152,7 @@ public async Task Test_Slot_Description() var parameterBag = new ParameterBag(ERDM_Parameter.SLOT_DESCRIPTION); var define = MetadataFactory.GetDefine(parameterBag); - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.GetResponse, data); + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, data); Assert.Multiple(() => { @@ -159,7 +162,8 @@ public async Task Test_Slot_Description() Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSlotDescription))); var obj = dataTreeBranch.ParsedObject as RDMSlotDescription; - Assert.That(obj.SlotId, Is.EqualTo(0)); + Assert.That(obj, Is.Not.Null); + Assert.That(obj!.SlotId, Is.EqualTo(0)); Assert.That(obj.Description, Is.EqualTo("SAFETY")); }); @@ -167,7 +171,7 @@ public async Task Test_Slot_Description() Assert.That(reversed, Is.EqualTo(dataTreeBranch)); } [Test] - public async Task Test_Slot_Info() + public void Test_Slot_Info() { byte[] data = { 0,0,0,0,1, @@ -180,7 +184,7 @@ public async Task Test_Slot_Info() var parameterBag = new ParameterBag(ERDM_Parameter.SLOT_INFO); var define = MetadataFactory.GetDefine(parameterBag); - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.GetResponse, data); + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetResponse, data); Assert.Multiple(() => { @@ -190,7 +194,8 @@ public async Task Test_Slot_Info() Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSlotInfo[]))); var obj = dataTreeBranch.ParsedObject as RDMSlotInfo[]; - Assert.That(obj[0].SlotOffset, Is.EqualTo(0)); + 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)); @@ -216,7 +221,7 @@ public async Task Test_Slot_Info() } [Test] - public async Task Test_Display_Invert() + public void Test_Display_Invert() { byte[] data = { 0x01 @@ -225,7 +230,7 @@ public async Task Test_Display_Invert() var parameterBag = new ParameterBag(ERDM_Parameter.DISPLAY_INVERT); var define = MetadataFactory.GetDefine(parameterBag); - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.SetRequest, data); + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.SetRequest, data); Assert.Multiple(() => { @@ -243,7 +248,7 @@ public async Task Test_Display_Invert() } [Test] - public async Task Test_Status_Messages() + public void Test_Status_Messages() { byte[] data = { 0x02 @@ -252,7 +257,7 @@ public async Task Test_Status_Messages() var parameterBag = new ParameterBag(ERDM_Parameter.STATUS_MESSAGES); var define = MetadataFactory.GetDefine(parameterBag); - var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.GetRequest, data); + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicate.GetRequest, data); Assert.Multiple(() => { diff --git a/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs b/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs index 93c2489..a70cce6 100644 --- a/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs +++ b/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs @@ -20,20 +20,28 @@ public async Task Test_Get_DMX_START_ADDRESS() Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); - AsyncRDMRequestHelper helper = null; + AsyncRDMRequestHelper? helper = null; helper = new AsyncRDMRequestHelper(sendMessage); - await Task.WhenAny( - peerToPeerProcess.Run(helper), - Task.Run(async () => - { - while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) - await Task.Delay(100); - })); - - 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)); + try + { + await Task.WhenAny( + peerToPeerProcess.Run(helper), + Task.Run(async () => + { + while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) + await Task.Delay(100); + })); + + 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)); + } + finally + { + helper?.Dispose(); + helper = null; + } async Task sendMessage(RDMMessage message) { @@ -53,7 +61,7 @@ async Task sendMessage(RDMMessage message) }; await Task.Delay(10); - helper.ReceiveMessage(response); + helper?.ReceiveMessage(response); } } @@ -77,22 +85,29 @@ public async Task Test_Get_PROXIED_DEVICES() Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); - AsyncRDMRequestHelper helper = null; + AsyncRDMRequestHelper? helper = null; byte[] parameterData = MetadataFactory.GetResponseMessageData(parameterBag, new DataTreeBranch(new DataTree[] { new DataTree("device_uids", 0, children: children) })); helper = new AsyncRDMRequestHelper(sendMessage); - - await Task.WhenAny( - peerToPeerProcess.Run(helper), - Task.Run(async () => - { - while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) - await Task.Delay(100); - })); - - 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())); + try + { + await Task.WhenAny( + peerToPeerProcess.Run(helper), + Task.Run(async () => + { + while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) + await Task.Delay(100); + })); + + 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; + } async Task sendMessage(RDMMessage message) { @@ -116,7 +131,7 @@ async Task sendMessage(RDMMessage message) }; await Task.Delay(10); - helper.ReceiveMessage(response); + helper?.ReceiveMessage(response); } } [Test] @@ -134,22 +149,30 @@ public async Task Test_Get_LAMP_STRIKES() Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); - AsyncRDMRequestHelper helper = null; + AsyncRDMRequestHelper? helper = null; byte count = 0; - helper = new AsyncRDMRequestHelper(sendMessage); - - await Task.WhenAny( - peerToPeerProcess.Run(helper), - Task.Run(async () => - { - while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) - await Task.Delay(100); - })); - - 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)); + try + { + helper = new AsyncRDMRequestHelper(sendMessage); + + await Task.WhenAny( + peerToPeerProcess.Run(helper), + Task.Run(async () => + { + while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) + await Task.Delay(100); + })); + + 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)); + } + finally + { + helper?.Dispose(); + helper = null; + } async Task sendMessage(RDMMessage message) { Assert.That(count, Is.LessThan(2)); @@ -174,7 +197,7 @@ async Task sendMessage(RDMMessage message) await Task.Delay(10); count++; - helper.ReceiveMessage(response); + helper?.ReceiveMessage(response); } } } diff --git a/RDMSharpTests/TestAsyncRDMRequestHelper.cs b/RDMSharpTests/TestAsyncRDMRequestHelper.cs index 66fcd70..315b27b 100644 --- a/RDMSharpTests/TestAsyncRDMRequestHelper.cs +++ b/RDMSharpTests/TestAsyncRDMRequestHelper.cs @@ -4,7 +4,7 @@ public class TestAsyncRDMRequestHelper { private AsyncRDMRequestHelper? asyncRDMRequestHelper; private bool hold = false; - private SemaphoreSlim hold_Semaphore; + private SemaphoreSlim? hold_Semaphore; [SetUp] public void Setup() @@ -23,7 +23,7 @@ public void Teardown() private async Task sendMethode(RDMMessage rdmMessage) { - if (!hold) + if (!hold || hold_Semaphore == null) return; if(hold_Semaphore.CurrentCount==0) @@ -53,7 +53,7 @@ public async Task TestDelayedResponse() [Test, Order(6)] public async Task TestSimultanRequests() { - await hold_Semaphore.WaitAsync(); + 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) }; @@ -70,7 +70,7 @@ public async Task TestSimultanRequests() foreach (ERDM_Parameter parameter in parameters) foreach (ERDM_Command command in commands) { - byte[] parameterData = null; + 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) @@ -79,14 +79,14 @@ public async Task TestSimultanRequests() 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(); + hold_Semaphore?.Release(); await Task.WhenAll(tasks); } [Test, Order(7)] public async Task TestSimultanRequestsSameTransactionID() { - await hold_Semaphore.WaitAsync(); + 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) }; @@ -103,7 +103,7 @@ public async Task TestSimultanRequestsSameTransactionID() foreach (ERDM_Parameter parameter in parameters) foreach (ERDM_Command command in commands) { - byte[] parameterData = null; + 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) @@ -112,7 +112,7 @@ public async Task TestSimultanRequestsSameTransactionID() parameterData = new byte[] { 0x01 }; tasks.Add(testPackage(sourceUID, destUID, 1, subDevice, parameter, command, new byte[] { 0x00, 0x01 }, delay)); } - hold_Semaphore.Release(); + hold_Semaphore?.Release(); await Task.WhenAll(tasks); } @@ -156,25 +156,25 @@ private async Task testPackage(RDMMessage request, RDMMessage response, int resp } private void validate(RDMMessage request, RequestResult result) { - string faliMessage = $"Request: {request.ToString()} Response: {result.Response?.ToString()}"; + 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, faliMessage); - Assert.That(result.Response, Is.Null, faliMessage); + Assert.That(result.Success, Is.True, failMessage); + Assert.That(result.Response, Is.Null, failMessage); return; } - Assert.That(result.Success, Is.True, faliMessage); - Assert.That(result.Response, Is.Not.Null, faliMessage); - Assert.That(result.Response.DestUID, Is.EqualTo(request.SourceUID), faliMessage); - Assert.That(result.Response.SourceUID, Is.EqualTo(request.DestUID), faliMessage); - Assert.That(result.Response.SubDevice, Is.EqualTo(request.SubDevice), faliMessage); - Assert.That(result.Response.TransactionCounter, Is.EqualTo(request.TransactionCounter), faliMessage); - Assert.That(result.Response.Command, Is.EqualTo(request.Command | ERDM_Command.RESPONSE), faliMessage); + 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), faliMessage); + Assert.That(result.Response.Parameter, Is.EqualTo(request.Parameter), failMessage); } #endregion } diff --git a/RDMSharpTests/TestManyObjects.cs b/RDMSharpTests/TestManyObjects.cs index 2af1335..4960947 100644 --- a/RDMSharpTests/TestManyObjects.cs +++ b/RDMSharpTests/TestManyObjects.cs @@ -294,27 +294,30 @@ public void TestPDL() 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.Value, Is.EqualTo(0)); + 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.Value, Is.EqualTo(13)); + Assert.That(pdl.Value, Is.Not.Null); + Assert.That(pdl.Value!.Value, Is.EqualTo(13)); 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.MinLength!.Value, Is.EqualTo(3)); + Assert.That(pdl.MaxLength!.Value, Is.EqualTo(5)); 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.Value, Is.EqualTo(5)); + Assert.That(pdl.Value, Is.Not.Null); + Assert.That(pdl.Value!.Value, Is.EqualTo(5)); List list = new List(); @@ -325,7 +328,8 @@ public void TestPDL() 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.Value, Is.EqualTo(6)); + Assert.That(pdl.Value, Is.Not.Null); + Assert.That(pdl.Value!.Value, Is.EqualTo(6)); list.Clear(); list.Add(new PDL(1, 2)); @@ -335,8 +339,8 @@ public void TestPDL() 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.That(pdl.MinLength!.Value, Is.EqualTo(5)); + Assert.That(pdl.MaxLength!.Value, Is.EqualTo(8)); Assert.Throws(typeof(ArgumentOutOfRangeException), () => new PDL(uint.MaxValue)); From a0ace64753736803bcaace9695cd781e33b81647 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 23 May 2025 00:59:02 +0200 Subject: [PATCH 11/20] First Draft is working more tests needed --- .../RDM/Device/AbstractGeneratedRDMDevice.cs | 73 +++++++++++++--- RDMSharp/RDM/Device/AbstractRDMCache.cs | 45 ++++++---- RDMSharp/RDM/Device/AbstractRDMDevice.cs | 3 + .../RDM/Device/AbstractRemoteRDMDevice.cs | 84 ++++++++++++++++--- RDMSharp/RDM/Device/ParameterUpdatedBag.cs | 24 ++++++ RDMSharp/RDM/GlobalTimers.cs | 61 ++++++++++++++ RDMSharp/RDM/PeerToPeerProcess.cs | 13 ++- RDMSharp/RDM/Tools.cs | 1 + RDMSharpTests/Devices/TestRDMSendReceive.cs | 16 +++- 9 files changed, 276 insertions(+), 44 deletions(-) create mode 100644 RDMSharp/RDM/Device/ParameterUpdatedBag.cs create mode 100644 RDMSharp/RDM/GlobalTimers.cs diff --git a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs index 1e0c1d7..9f4aa85 100644 --- a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs @@ -127,6 +127,7 @@ private set } } + 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) { @@ -146,6 +147,8 @@ private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[ var _params = parameters.ToList(); _params.Add(ERDM_Parameter.DEVICE_INFO); _params.Add(ERDM_Parameter.SUPPORTED_PARAMETERS); + _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); @@ -252,14 +255,14 @@ private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[ case nameof(Sensor.LowestHighestValueSupported): case nameof(Sensor.RecordedValueSupported): sensorDef.AddOrUpdate(sensor.SensorId, (RDMSensorDefinition)sensor, (o1, o2) => (RDMSensorDefinition)sensor); - setParameterValue(ERDM_Parameter.SENSOR_DEFINITION, sensorDef); + 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); + setParameterValue(ERDM_Parameter.SENSOR_VALUE, sensorValue, sensor.SensorId); break; } }; @@ -277,6 +280,8 @@ private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[ #endregion updateDeviceInfo(); + ParameterUpdatedBag.Clear(); + _initialized = true; } private void updateDeviceInfo() @@ -420,7 +425,7 @@ protected sealed override void OnPropertyChanged(string property) { case nameof(DeviceInfo): trySetParameter(ERDM_Parameter.DEVICE_INFO, this.DeviceInfo); - trySetParameter(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL, this.DeviceInfo.SoftwareVersionId); + trySetParameter(ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID, this.DeviceInfo.SoftwareVersionId); break; case nameof(DeviceModelDescription): trySetParameter(ERDM_Parameter.DEVICE_MODEL_DESCRIPTION, this.DeviceModelDescription); @@ -462,7 +467,7 @@ public bool SetParameter(ERDM_Parameter parameter, object value = null) setParameterValue(parameter, value); return true; } - private void setParameterValue(ERDM_Parameter parameter, object value) + private void setParameterValue(ERDM_Parameter parameter, object value, object index=null) { switch (parameter) { @@ -472,6 +477,7 @@ private void setParameterValue(ERDM_Parameter parameter, object value) default: parameterValues.AddOrUpdate(parameter, value, (o, p) => value); + updateParameterBag(parameter, index); return; } } @@ -537,25 +543,48 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) } 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; } - - parameterValues.TryGetValue(rdmMessage.Parameter, out object responseValue); + if(parameter == ERDM_Parameter.QUEUED_MESSAGE) + { + if (ParameterUpdatedBag.IsEmpty) + { + response = new RDMMessage + { + Parameter = ERDM_Parameter.STATUS_MESSAGES, + Command = ERDM_Command.GET_COMMAND_RESPONSE, + MessageCounter = 0 + }; + goto FAIL; + } + else if (ParameterUpdatedBag.TryDequeue(out var item)) + { + parameter = item.Parameter; + requestValue = item.Index; + messageCounter = (byte)Math.Min(ParameterUpdatedBag.Count, byte.MaxValue); + } + } + + parameterValues.TryGetValue(parameter, out object responseValue); + var parameterBag = new ParameterBag(parameter, UID.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); + var dataTreeBranch = DataTreeBranch.FromObject(responseValue, requestValue, parameterBag, ERDM_Command.GET_COMMAND_RESPONSE); try { - var parameterBag = new ParameterBag(rdmMessage.Parameter, UID.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); - var dataTreeBranch = DataTreeBranch.FromObject(responseValue, rdmMessage.Value, parameterBag, ERDM_Command.GET_COMMAND_RESPONSE); if (!dataTreeBranch.IsUnset) { var data = MetadataFactory.GetResponseMessageData(parameterBag, dataTreeBranch); if (data != null) response = new RDMMessage { - Parameter = rdmMessage.Parameter, + Parameter = parameter, Command = ERDM_Command.GET_COMMAND_RESPONSE, + MessageCounter = messageCounter, ParameterData = data, }; } @@ -649,6 +678,30 @@ private void updateParameterFromRemote(ERDM_Parameter parameter, object value) break; } } + private void updateParameterBag(ERDM_Parameter parameter, object index = null) + { + if (!IsInitialized || !_initialized) + return; + try + { + 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(parameter, index))) + tempQueue.Enqueue(item); + + + while (tempQueue.TryDequeue(out var item)) + ParameterUpdatedBag.Enqueue(item); + } + ParameterUpdatedBag.Enqueue(new ParameterUpdatedBag(parameter, index)); + } + catch(Exception e) + { + + } + } protected sealed override void OnDispose() { try diff --git a/RDMSharp/RDM/Device/AbstractRDMCache.cs b/RDMSharp/RDM/Device/AbstractRDMCache.cs index 916985c..3d22abd 100644 --- a/RDMSharp/RDM/Device/AbstractRDMCache.cs +++ b/RDMSharp/RDM/Device/AbstractRDMCache.cs @@ -189,7 +189,7 @@ protected async Task requestSetParameterWithPayload(ParameterBag parameterBag, M } } - 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 { @@ -197,16 +197,18 @@ protected async Task requestGetParameterWithEmptyPayload(ParameterBag parameterB await runPeerToPeerProcess(ptpProcess); if (!ptpProcess.ResponsePayloadObject.IsUnset) { - updateParameterValuesDependeciePropertyBag(parameterBag.PID, ptpProcess.ResponsePayloadObject); - updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(parameterBag.PID), ptpProcess.ResponsePayloadObject); + updateParameterValuesDependeciePropertyBag(ptpProcess.ParameterBag.PID, ptpProcess.ResponsePayloadObject); + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID), ptpProcess.ResponsePayloadObject); } + return ptpProcess.MessageCounter; } catch(Exception e) { Logger.LogError(e, $"Failed to get parameter {parameterBag.PID} with empty payload"); } + return 0; } - protected async Task requestGetParameterWithPayload(ParameterBag parameterBag, MetadataJSONObjectDefine define, UID uid, SubDevice subDevice) + 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(); @@ -218,25 +220,36 @@ protected async Task requestGetParameterWithPayload(ParameterBag parameterBag, M IComparable dependecyValue = (IComparable)parameterValuesDependeciePropertyBag.FirstOrDefault(bag => bag.Key.Parameter == parameterBag.PID && bag.Key.Command == Metadata.JSON.Command.ECommandDublicate.GetRequest && string.Equals(bag.Key.Name, name)).Value; - object i = intType.GetMinimum(); - object max = intType.GetMaximum(); - object count = Convert.ChangeType(0, i.GetType()); - while (dependecyValue.CompareTo(count) > 0) + if (i == null) { - if (!intType.IsInRange(i)) - continue; + 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 (((IComparable)max).CompareTo(i) == -1) + return; - if (((IComparable)max).CompareTo(i) == -1) - return; + 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); + i = intType.IncrementJumpRange(i); + count = intType.Increment(count); + } + } + 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(parameterBag.PID, i), ptpProcess.ResponsePayloadObject); - - i = intType.IncrementJumpRange(i); - count = intType.Increment(count); + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID, i), ptpProcess.ResponsePayloadObject); } } catch (Exception e) diff --git a/RDMSharp/RDM/Device/AbstractRDMDevice.cs b/RDMSharp/RDM/Device/AbstractRDMDevice.cs index 7a562bb..358773c 100644 --- a/RDMSharp/RDM/Device/AbstractRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractRDMDevice.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.Logging; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Linq; @@ -26,6 +27,8 @@ public abstract class AbstractRDMDevice : AbstractRDMCache, IRDMDevice protected IList SubDevices_Internal { get => subDevices; } public IReadOnlyCollection SubDevices => SubDevices_Internal?.AsReadOnly(); + protected ConcurrentQueue ParameterUpdatedBag = new ConcurrentQueue(); + public new bool IsDisposing { get; private set; } public new bool IsDisposed { get; private set; } public bool IsInitialized { get; private set; } diff --git a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs index c0aad17..6bc1ea6 100644 --- a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs @@ -3,7 +3,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Data.Common; using System.Linq; +using System.Reflection; +using System.Reflection.Metadata; using System.Threading.Tasks; namespace RDMSharp @@ -133,6 +136,8 @@ private async void DeviceModel_Initialized(object sender, EventArgs e) deviceModel.Initialized -= DeviceModel_Initialized; await collectAllParametersOnRoot(); await scanSubDevices(); + AllDataPulled = true; + GlobalTimers.Instance.ParameterUpdateTimerElapsed += Instance_ParameterUpdateTimerElapsed; } private async Task scanSubDevices() @@ -210,18 +215,52 @@ private async Task requestParameters() case ERDM_Parameter.DEVICE_INFO: continue; } - ParameterBag parameterBag = new ParameterBag(parameter, this.DeviceModel.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); + await requestParameter(parameter); + } + } + private async Task requestParameter(ERDM_Parameter parameter, object payload = null) + { + ParameterBag parameterBag = new ParameterBag(parameter, this.DeviceModel.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); + var define = MetadataFactory.GetDefine(parameterBag); + if (define.GetRequest.HasValue) + { + if (define.GetRequest.Value.GetIsEmpty()) + await requestGetParameterWithEmptyPayload(parameterBag, define, UID, Subdevice); + else + await requestGetParameterWithPayload(parameterBag, define, UID, Subdevice, payload); + } + } + + private async Task updateParameters(bool queued = true) + { + if (queued && !deviceModel.KnownNotSupportedParameters.Contains(ERDM_Parameter.QUEUED_MESSAGE)) + { + ParameterBag parameterBag = new ParameterBag(ERDM_Parameter.QUEUED_MESSAGE, this.DeviceModel.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); var define = MetadataFactory.GetDefine(parameterBag); if (define.GetRequest.HasValue) { - if (define.GetRequest.Value.GetIsEmpty()) - await requestGetParameterWithEmptyPayload(parameterBag, define, UID, Subdevice); - else - await requestGetParameterWithPayload(parameterBag, define, UID, Subdevice); + byte mc = 0; + do + { + mc = await requestGetParameterWithEmptyPayload(parameterBag, define, UID, Subdevice); + } + while (mc != 0); } + return; } - } + else + { + while(ParameterUpdatedBag.TryPeek(out ParameterUpdatedBag bag)) + { + if (DateTime.UtcNow - bag.Timestamp < TimeSpan.FromMilliseconds(10000)) + return; + await requestParameter(bag.Parameter, bag.Index); + + ParameterUpdatedBag.TryDequeue(out bag); + } + } + } #endregion private async Task getDeviceModelAndCollectAllParameters() @@ -240,14 +279,8 @@ private async Task getDeviceModelAndCollectAllParameters() private async Task collectAllParametersOnRoot() { await requestParameters(); - AllDataPulled = true; } - private async Task collectAllParametersOnSubDevices() - { - await requestParameters(); - AllDataPulled = true; - } private async Task getPersonalityModelAndCollectAllParameters() { if (personalityModel != null) @@ -262,6 +295,8 @@ private async Task getPersonalityModelAndCollectAllParameters() private async void AbstractRDMDevice_ParameterValueAdded(object sender, ParameterValueAddedEventArgs e) { + if (!Constants.BLUEPRINT_MODEL_PARAMETERS.Contains(e.Parameter) && !Constants.BLUEPRINT_MODEL_PERSONALITY_PARAMETERS.Contains(e.Parameter)) + ParameterUpdatedBag.Enqueue(new ParameterUpdatedBag(e.Parameter, e.Index)); switch (e.Parameter) { case ERDM_Parameter.DMX_PERSONALITY: @@ -277,6 +312,22 @@ private async void AbstractRDMDevice_ParameterValueAdded(object sender, Paramete } private void AbstractRDMDevice_ParameterValueChanged(object sender, ParameterValueChangedEventArgs e) { + if (!Constants.BLUEPRINT_MODEL_PARAMETERS.Contains(e.Parameter) && !Constants.BLUEPRINT_MODEL_PERSONALITY_PARAMETERS.Contains(e.Parameter)) + { + if (ParameterUpdatedBag.Any(p => p.Parameter == e.Parameter && p.Index == e.Index)) + { + var tempQueue = new ConcurrentQueue(); + while (ParameterUpdatedBag.TryDequeue(out var item)) + if (!(item.Parameter.Equals(e.Parameter) && Equals(item.Index, e.Index))) + tempQueue.Enqueue(item); + + + while (tempQueue.TryDequeue(out var item)) + ParameterUpdatedBag.Enqueue(item); + } + ParameterUpdatedBag.Enqueue(new ParameterUpdatedBag(e.Parameter, e.Index)); + } + switch (e.Parameter) { case ERDM_Parameter.SENSOR_VALUE when e.NewValue is RDMSensorValue sensorValue: @@ -350,12 +401,19 @@ public sealed override IReadOnlyDictionary GetAllParamet return base.GetAllParameterValues(); } + + 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.ParameterUpdateTimerElapsed -= Instance_ParameterUpdateTimerElapsed; try { onDispose(); @@ -368,5 +426,7 @@ protected sealed override void OnDispose() ParameterValueChanged -= AbstractRDMDevice_ParameterValueChanged; } protected abstract void onDispose(); + + } } \ No newline at end of file diff --git a/RDMSharp/RDM/Device/ParameterUpdatedBag.cs b/RDMSharp/RDM/Device/ParameterUpdatedBag.cs new file mode 100644 index 0000000..c45907d --- /dev/null +++ b/RDMSharp/RDM/Device/ParameterUpdatedBag.cs @@ -0,0 +1,24 @@ +using System; + +namespace RDMSharp +{ + public readonly struct ParameterUpdatedBag + { + public readonly ERDM_Parameter Parameter; + public readonly object Index; + public readonly DateTime Timestamp; + public ParameterUpdatedBag(in ERDM_Parameter parameter, in object index) + { + Parameter = parameter; + Index = index; + Timestamp = DateTime.UtcNow; + } + public override string ToString() + { + if (Index == null) + return $"{Parameter} [{Timestamp}]"; + + return $"{Parameter} ({Index}) [{Timestamp}]"; + } + } +} \ No newline at end of file diff --git a/RDMSharp/RDM/GlobalTimers.cs b/RDMSharp/RDM/GlobalTimers.cs new file mode 100644 index 0000000..e32f753 --- /dev/null +++ b/RDMSharp/RDM/GlobalTimers.cs @@ -0,0 +1,61 @@ +using System; + +namespace RDMSharp +{ + public class GlobalTimers + { + private static GlobalTimers? instance = null; + public static GlobalTimers Instance + { + get + { + if (instance == null) + instance = new GlobalTimers(); + return instance; + } + } + + public int ParameterUpdateTimerInterval { get; set; } = 1000; + private System.Timers.Timer? parameterUpdateTimer = null; + + private event EventHandler parameterUpdateTimerElapsed; + public event EventHandler ParameterUpdateTimerElapsed + { + add + { + if (parameterUpdateTimer == null) + initializeParameterUpdateTimer(); + parameterUpdateTimerElapsed += value; + } + remove + { + parameterUpdateTimerElapsed -= value; + + if (parameterUpdateTimer != null && parameterUpdateTimerElapsed == null) + destroyParameterUpdateTimer(); + } + } + private void initializeParameterUpdateTimer() + { + if (parameterUpdateTimer != null) + return; + parameterUpdateTimer = new System.Timers.Timer(ParameterUpdateTimerInterval); + parameterUpdateTimer.Elapsed += ParameterUpdateTimer_Elapsed; + parameterUpdateTimer.Enabled = true; + } + + private void destroyParameterUpdateTimer() + { + if (parameterUpdateTimer == null) + return; + parameterUpdateTimer.Enabled = false; + parameterUpdateTimer.Elapsed -= ParameterUpdateTimer_Elapsed; + parameterUpdateTimer.Dispose(); + } + + private void ParameterUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + parameterUpdateTimerElapsed?.InvokeFailSafe(sender, EventArgs.Empty); + } + } +} diff --git a/RDMSharp/RDM/PeerToPeerProcess.cs b/RDMSharp/RDM/PeerToPeerProcess.cs index 8d39f75..e922cd2 100644 --- a/RDMSharp/RDM/PeerToPeerProcess.cs +++ b/RDMSharp/RDM/PeerToPeerProcess.cs @@ -18,7 +18,7 @@ public enum EPeerToPeerProcessState public readonly ERDM_Command Command; public readonly UID UID; public readonly SubDevice SubDevice; - public readonly ParameterBag ParameterBag; + public ParameterBag ParameterBag { get; private set; } public readonly DataTreeBranch RequestPayloadObject; public DataTreeBranch ResponsePayloadObject { get; private set; } = DataTreeBranch.Unset; @@ -29,6 +29,7 @@ public enum EPeerToPeerProcessState private RDMMessage request = null; private RDMMessage response = null; + public byte MessageCounter => response?.MessageCounter ?? 0; public PeerToPeerProcess(ERDM_Command command, UID uid, SubDevice subDevice, ParameterBag parameterBag, DataTreeBranch? payloadObject = null) { if (command != ERDM_Command.GET_COMMAND) @@ -41,7 +42,8 @@ public PeerToPeerProcess(ERDM_Command command, UID uid, SubDevice subDevice, Par ParameterBag = parameterBag; RequestPayloadObject = payloadObject ?? DataTreeBranch.Unset; - Define = MetadataFactory.GetDefine(ParameterBag); + if (ParameterBag.PID != ERDM_Parameter.QUEUED_MESSAGE) + Define = MetadataFactory.GetDefine(ParameterBag); } public async Task Run(AsyncRDMRequestHelper asyncRDMRequestHelper) @@ -69,7 +71,7 @@ private async Task run(AsyncRDMRequestHelper asyncRDMRequestHelper) if (Command == ERDM_Command.SET_COMMAND) commandResponse = ECommandDublicate.SetResponse; - byte[] parameterData = MetadataFactory.ParsePayloadToData(Define, commandRequest, RequestPayloadObject); + byte[] parameterData = ParameterBag.PID != ERDM_Parameter.QUEUED_MESSAGE ? MetadataFactory.ParsePayloadToData(Define, commandRequest, RequestPayloadObject) : null; request = new RDMMessage() { Command = Command, @@ -98,6 +100,11 @@ private async Task run(AsyncRDMRequestHelper asyncRDMRequestHelper) bytes.AddRange(response.ParameterData); if (response.ResponseType == ERDM_ResponseType.ACK) { + if (request.Parameter == ERDM_Parameter.QUEUED_MESSAGE) + { + ParameterBag = new ParameterBag(response.Parameter, ParameterBag.ManufacturerID, ParameterBag.DeviceModelID, ParameterBag.SoftwareVersionID); + Define = MetadataFactory.GetDefine(ParameterBag); + } ResponsePayloadObject = MetadataFactory.ParseDataToPayload(Define, commandResponse, bytes.ToArray()); State = EPeerToPeerProcessState.Finished; return; diff --git a/RDMSharp/RDM/Tools.cs b/RDMSharp/RDM/Tools.cs index c4ef3b3..474d2bb 100644 --- a/RDMSharp/RDM/Tools.cs +++ b/RDMSharp/RDM/Tools.cs @@ -15,6 +15,7 @@ public static class Constants { 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, diff --git a/RDMSharpTests/Devices/TestRDMSendReceive.cs b/RDMSharpTests/Devices/TestRDMSendReceive.cs index 8ce08c6..8529c1f 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceive.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceive.cs @@ -20,7 +20,7 @@ public void TearDown() remote.Dispose(); } - [Test] + [Test, Order(1)] [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] public async Task TestDevice1() { @@ -102,7 +102,7 @@ public async Task TestDevice1() //}); } - [Test] + [Test, Order(2)] [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] public void TestDevice1Slots() { @@ -182,7 +182,7 @@ public void TestDevice1Slots() //}); } - [Test] + [Test, Order(3)] [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] public void TestDevice1Sensor() { @@ -208,5 +208,15 @@ public void TestDevice1Sensor() ///Record Sensors Unicast ///Record Sensors Broadcast } + [Test, Order(4)] + public async Task TestDevice1QueuedUpdates() + { + var parameterValuesRemote = remote.GetAllParameterValues(); + var parameterValuesGenerated = generated.GetAllParameterValues(); + await Task.Delay(5000); + generated.DMXAddress = 69; + await Task.Delay(5000); + Assert.That (remote.GetAllParameterValues()[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(69)); + } } } \ No newline at end of file From 6ede1784a5fbfdfffaf09c875e4e22ee14645146 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 23 May 2025 01:53:36 +0200 Subject: [PATCH 12/20] Minor --- .../RDM/Device/AbstractGeneratedRDMDevice.cs | 41 +++++++++----- .../RDM/Device/AbstractRemoteRDMDevice.cs | 14 ++++- RDMSharp/RDM/GlobalTimers.cs | 4 +- RDMSharpTests/Devices/TestRDMSendReceive.cs | 53 +++++++++++++------ 4 files changed, 81 insertions(+), 31 deletions(-) diff --git a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs index 9f4aa85..19dd47b 100644 --- a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs @@ -109,6 +109,7 @@ public byte? CurrentPersonality currentPersonality = value.Value; this.OnPropertyChanged(nameof(this.CurrentPersonality)); + this.updateDeviceInfo(); } } private bool discoveryMuted; @@ -476,7 +477,15 @@ private void setParameterValue(ERDM_Parameter parameter, object value, object in goto default; default: - parameterValues.AddOrUpdate(parameter, value, (o, p) => value); + bool notNew = false; + parameterValues.AddOrUpdate(parameter, value, (o, p) => + { + if (object.Equals(p, value)) + notNew = true; + return value; + }); + if (notNew) + return; updateParameterBag(parameter, index); return; } @@ -551,7 +560,7 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) response = new RDMMessage(ERDM_NackReason.SUB_DEVICE_OUT_OF_RANGE) { Parameter = parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; goto FAIL; } - if(parameter == ERDM_Parameter.QUEUED_MESSAGE) + if (parameter == ERDM_Parameter.QUEUED_MESSAGE) { if (ParameterUpdatedBag.IsEmpty) { @@ -570,6 +579,8 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) messageCounter = (byte)Math.Min(ParameterUpdatedBag.Count, byte.MaxValue); } } + else + removeParamterFromParameterUpdateBag(parameter); parameterValues.TryGetValue(parameter, out object responseValue); var parameterBag = new ParameterBag(parameter, UID.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); @@ -684,17 +695,7 @@ private void updateParameterBag(ERDM_Parameter parameter, object index = null) return; try { - 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(parameter, index))) - tempQueue.Enqueue(item); - - - while (tempQueue.TryDequeue(out var item)) - ParameterUpdatedBag.Enqueue(item); - } + removeParamterFromParameterUpdateBag(parameter, index); ParameterUpdatedBag.Enqueue(new ParameterUpdatedBag(parameter, index)); } catch(Exception e) @@ -702,6 +703,20 @@ private void updateParameterBag(ERDM_Parameter parameter, object index = null) } } + private void removeParamterFromParameterUpdateBag(ERDM_Parameter parameter, object index = null) + { + 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(parameter, index))) + tempQueue.Enqueue(item); + + + while (tempQueue.TryDequeue(out var item)) + ParameterUpdatedBag.Enqueue(item); + } + } protected sealed override void OnDispose() { try diff --git a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs index 6bc1ea6..d5dee8f 100644 --- a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs @@ -99,6 +99,8 @@ private set } } + private DateTime lastSendQueuedMessage; + private bool present; public bool Present { @@ -115,6 +117,7 @@ internal set } } + public AbstractRemoteRDMDevice(UID uid) : base(uid) { } @@ -134,6 +137,10 @@ protected override async void initialize(RDMDeviceInfo deviceInfo = null) private async void DeviceModel_Initialized(object sender, EventArgs e) { deviceModel.Initialized -= DeviceModel_Initialized; + await collectParameters(); + } + private async Task collectParameters() + { await collectAllParametersOnRoot(); await scanSubDevices(); AllDataPulled = true; @@ -235,6 +242,8 @@ private async Task updateParameters(bool queued = true) { if (queued && !deviceModel.KnownNotSupportedParameters.Contains(ERDM_Parameter.QUEUED_MESSAGE)) { + if (DateTime.UtcNow - lastSendQueuedMessage < TimeSpan.FromSeconds(4)) + 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) @@ -242,6 +251,7 @@ private async Task updateParameters(bool queued = true) byte mc = 0; do { + lastSendQueuedMessage = DateTime.UtcNow; mc = await requestGetParameterWithEmptyPayload(parameterBag, define, UID, Subdevice); } while (mc != 0); @@ -252,7 +262,7 @@ private async Task updateParameters(bool queued = true) { while(ParameterUpdatedBag.TryPeek(out ParameterUpdatedBag bag)) { - if (DateTime.UtcNow - bag.Timestamp < TimeSpan.FromMilliseconds(10000)) + if (DateTime.UtcNow - bag.Timestamp < TimeSpan.FromSeconds(10)) return; await requestParameter(bag.Parameter, bag.Index); @@ -274,7 +284,7 @@ private async Task getDeviceModelAndCollectAllParameters() await deviceModel.Initialize(); } else - await collectAllParametersOnRoot(); + await collectParameters(); } private async Task collectAllParametersOnRoot() { diff --git a/RDMSharp/RDM/GlobalTimers.cs b/RDMSharp/RDM/GlobalTimers.cs index e32f753..aaf3ae0 100644 --- a/RDMSharp/RDM/GlobalTimers.cs +++ b/RDMSharp/RDM/GlobalTimers.cs @@ -25,7 +25,8 @@ public event EventHandler ParameterUpdateTimerElapsed { if (parameterUpdateTimer == null) initializeParameterUpdateTimer(); - parameterUpdateTimerElapsed += value; + + parameterUpdateTimerElapsed += value; } remove { @@ -51,6 +52,7 @@ private void destroyParameterUpdateTimer() parameterUpdateTimer.Enabled = false; parameterUpdateTimer.Elapsed -= ParameterUpdateTimer_Elapsed; parameterUpdateTimer.Dispose(); + parameterUpdateTimer = null; } private void ParameterUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) diff --git a/RDMSharpTests/Devices/TestRDMSendReceive.cs b/RDMSharpTests/Devices/TestRDMSendReceive.cs index 8529c1f..332b35d 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceive.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceive.cs @@ -4,28 +4,31 @@ namespace RDMSharpTests.RDM.Devices { public class TestRDMSendReceive { - private MockGeneratedDevice1 generated; - private MockDevice remote; + private MockGeneratedDevice1? generated; + private MockDevice? remote; + private Random random = new Random(); [SetUp] public void Setup() { - var uid = new UID(0x9fff, 1); + var uid = new UID((ushort)random.Next(), (uint)random.Next()); generated = new MockGeneratedDevice1(uid); remote = new MockDevice(uid, false); } [TearDown] public void TearDown() { - generated.Dispose(); - remote.Dispose(); + generated?.Dispose(); + generated = null; + remote?.Dispose(); + remote = null; } [Test, 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(); + var parameterValuesRemote = remote!.GetAllParameterValues(); + var parameterValuesGenerated = generated!.GetAllParameterValues(); //Assert.Multiple(() => //{ @@ -106,7 +109,7 @@ public async Task TestDevice1() [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 slotIntensity = remote!.Slots[0]; var slotStrobe = remote.Slots[1]; var slotRed = remote.Slots[2]; var slotGreen = remote.Slots[3]; @@ -114,7 +117,7 @@ public void TestDevice1Slots() //Assert.Multiple(() => //{ - Assert.That(slotIntensity, Is.EqualTo(generated.Personalities[0].Slots[0])); + 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])); @@ -186,8 +189,8 @@ public void TestDevice1Slots() [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] public void TestDevice1Sensor() { - var sensorsRemote = remote.Sensors.Values.ToList(); - var sensorsGenerated = generated.Sensors.Values.ToList(); + var sensorsRemote = remote!.Sensors.Values.ToList(); + var sensorsGenerated = generated!.Sensors.Values.ToList(); Assert.Multiple(() => { @@ -211,12 +214,32 @@ public void TestDevice1Sensor() [Test, Order(4)] public async Task TestDevice1QueuedUpdates() { - var parameterValuesRemote = remote.GetAllParameterValues(); - var parameterValuesGenerated = generated.GetAllParameterValues(); - await Task.Delay(5000); + var parameterValuesRemote = remote!.GetAllParameterValues(); + var parameterValuesGenerated = generated!.GetAllParameterValues(); + Assert.That(parameterValuesRemote[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); + + await Task.Delay(1000); + generated.DMXAddress = 69; + generated.DeviceLabel = "Test Label QUEUE"; + generated.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, true); + + await Task.Delay(5000); + 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.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, false); + generated.DMXAddress = 44; + generated.CurrentPersonality = 2; + await Task.Delay(5000); - Assert.That (remote.GetAllParameterValues()[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(69)); + 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 From 9c61c37f9d6fef32bcf9e68c70e49480fb88d080 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 23 May 2025 08:58:12 +0200 Subject: [PATCH 13/20] grrr --- RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs | 4 ++-- RDMSharp/RDM/GlobalTimers.cs | 18 +++++++++++++++++- RDMSharpTests/Devices/TestRDMSendReceive.cs | 8 ++++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs index d5dee8f..f0f2db4 100644 --- a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs @@ -242,7 +242,7 @@ private async Task updateParameters(bool queued = true) { if (queued && !deviceModel.KnownNotSupportedParameters.Contains(ERDM_Parameter.QUEUED_MESSAGE)) { - if (DateTime.UtcNow - lastSendQueuedMessage < TimeSpan.FromSeconds(4)) + 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); @@ -262,7 +262,7 @@ private async Task updateParameters(bool queued = true) { while(ParameterUpdatedBag.TryPeek(out ParameterUpdatedBag bag)) { - if (DateTime.UtcNow - bag.Timestamp < TimeSpan.FromSeconds(10)) + if (DateTime.UtcNow - bag.Timestamp < TimeSpan.FromMilliseconds(GlobalTimers.Instance.NonQueuedUpdateTime)) return; await requestParameter(bag.Parameter, bag.Index); diff --git a/RDMSharp/RDM/GlobalTimers.cs b/RDMSharp/RDM/GlobalTimers.cs index aaf3ae0..d1b01ad 100644 --- a/RDMSharp/RDM/GlobalTimers.cs +++ b/RDMSharp/RDM/GlobalTimers.cs @@ -15,7 +15,23 @@ public static GlobalTimers Instance } } - public int ParameterUpdateTimerInterval { get; set; } = 1000; + + public int QueuedUpdateTime { get; set; } = 4000; + public int NonQueuedUpdateTime { get; set; } = 10000; + private int parameterUpdateTimerInterval = 1000; + public int ParameterUpdateTimerInterval + { + get + { + return parameterUpdateTimerInterval; + } + set + { + parameterUpdateTimerInterval = value; + if (parameterUpdateTimer != null) + parameterUpdateTimer.Interval = value; + } + } private System.Timers.Timer? parameterUpdateTimer = null; private event EventHandler parameterUpdateTimerElapsed; diff --git a/RDMSharpTests/Devices/TestRDMSendReceive.cs b/RDMSharpTests/Devices/TestRDMSendReceive.cs index 332b35d..740c655 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceive.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceive.cs @@ -17,6 +17,8 @@ public void Setup() [TearDown] public void TearDown() { + GlobalTimers.Instance.QueuedUpdateTime = 4000; + GlobalTimers.Instance.ParameterUpdateTimerInterval = 1000; generated?.Dispose(); generated = null; remote?.Dispose(); @@ -214,6 +216,8 @@ public void TestDevice1Sensor() [Test, Order(4)] public async Task TestDevice1QueuedUpdates() { + GlobalTimers.Instance.QueuedUpdateTime = 100; + GlobalTimers.Instance.ParameterUpdateTimerInterval = 100; var parameterValuesRemote = remote!.GetAllParameterValues(); var parameterValuesGenerated = generated!.GetAllParameterValues(); Assert.That(parameterValuesRemote[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); @@ -224,7 +228,7 @@ public async Task TestDevice1QueuedUpdates() generated.DeviceLabel = "Test Label QUEUE"; generated.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, true); - await Task.Delay(5000); + await Task.Delay(1000); parameterValuesRemote = remote.GetAllParameterValues(); Assert.That(parameterValuesRemote[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(69)); @@ -235,7 +239,7 @@ public async Task TestDevice1QueuedUpdates() generated.DMXAddress = 44; generated.CurrentPersonality = 2; - await Task.Delay(5000); + await Task.Delay(1000); parameterValuesRemote = remote.GetAllParameterValues(); Assert.That(parameterValuesRemote[ERDM_Parameter.IDENTIFY_DEVICE], Is.False); Assert.That(parameterValuesRemote[ERDM_Parameter.DMX_START_ADDRESS], Is.EqualTo(44)); From 992209208a79c1d63a60bd8806bd4570a0d2bcbc Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 28 May 2025 01:52:05 +0200 Subject: [PATCH 14/20] Implement StatusMessage Stuff --- RDMSharp/Metadata/DataTreeBranch.cs | 11 +- .../RDM/Device/AbstractGeneratedRDMDevice.cs | 415 ++++++++++++++---- RDMSharp/RDM/Device/AbstractRDMCache.cs | 11 +- RDMSharp/RDM/Device/AbstractRDMDevice.cs | 2 +- .../RDM/Device/AbstractRemoteRDMDevice.cs | 13 +- RDMSharp/RDM/Enum/ERDM_Status.cs | 9 + RDMSharp/RDM/GlobalTimers.cs | 21 +- .../RDM/PayloadObject/RDMStatusMessage.cs | 29 +- RDMSharp/RDM/PeerToPeerProcess.cs | 7 +- .../Mock/AbstractMockGeneratedDevice.cs | 18 + .../Devices/Mock/MockGeneratedDevice1.cs | 5 + .../Mock/MockGeneratedDeviceWithSubDevice1.cs | 10 + RDMSharpTests/Devices/TestRDMSendReceive.cs | 6 +- .../TestRDMSendReceiveGeneratedOnly.cs | 405 +++++++++++++++++ 14 files changed, 854 insertions(+), 108 deletions(-) create mode 100644 RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs diff --git a/RDMSharp/Metadata/DataTreeBranch.cs b/RDMSharp/Metadata/DataTreeBranch.cs index 7144fb6..47c311c 100644 --- a/RDMSharp/Metadata/DataTreeBranch.cs +++ b/RDMSharp/Metadata/DataTreeBranch.cs @@ -279,8 +279,15 @@ public static DataTreeBranch FromObject(object obj, object key, ERDM_Command com var tryGetValueMethod = type.GetMethod("TryGetValue"); object[] parameters = { key, null }; - - bool found = (bool)tryGetValueMethod.Invoke(obj, parameters); + bool found = false; + try + { + found = (bool)tryGetValueMethod.Invoke(obj, parameters); + } + catch(Exception e) + { + Logger.LogError(e); + } if (found) { diff --git a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs index 19dd47b..30637fd 100644 --- a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs @@ -3,14 +3,19 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; +using System.Runtime.CompilerServices; using System.Threading.Tasks; +[assembly: InternalsVisibleTo("RDMSharpTests")] namespace RDMSharp { public abstract class AbstractGeneratedRDMDevice : AbstractRDMDevice { public sealed override bool IsGenerated => true; + public abstract bool SupportQueued { get; } + public abstract bool SupportStatus { get; } #region DeviceInfoStuff public readonly ERDM_Parameter[] Parameters; public abstract EManufacturer ManufacturerID { get; } @@ -24,10 +29,14 @@ public abstract class AbstractGeneratedRDMDevice : AbstractRDMDevice 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[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; @@ -141,11 +150,13 @@ private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[ if (!((ushort)ManufacturerID).Equals(uid.ManufacturerID)) throw new Exception($"{uid.ManufacturerID} not match the {ManufacturerID}"); - if (sensors != null) - this.AddSensors(sensors); - #region Parameters var _params = parameters.ToList(); + if (SupportQueued) + _params.Add(ERDM_Parameter.QUEUED_MESSAGE); + if (SupportStatus) + _params.Add(ERDM_Parameter.STATUS_MESSAGES); + _params.Add(ERDM_Parameter.DEVICE_INFO); _params.Add(ERDM_Parameter.SUPPORTED_PARAMETERS); _params.Add(ERDM_Parameter.BOOT_SOFTWARE_VERSION_ID); @@ -163,7 +174,7 @@ private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[ _params.Add(ERDM_Parameter.SLOT_DESCRIPTION); _params.Add(ERDM_Parameter.DEFAULT_SLOT_VALUE); } - if ((Sensors?.Count ?? 0) != 0) + if ((sensors?.Length ?? 0) != 0) { _params.Add(ERDM_Parameter.SENSOR_DEFINITION); _params.Add(ERDM_Parameter.SENSOR_VALUE); @@ -215,64 +226,15 @@ private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[ #endregion #region Sensors - if (Sensors != null) - { - var _sensors = Sensors.Values.ToArray(); - if (_sensors.Length >= byte.MaxValue) - throw new ArgumentOutOfRangeException($"There to many {Sensors}! Maximum is {byte.MaxValue - 1}"); - - 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"); - - if (_sensors.Length != 0) - { - var sensorDef = new ConcurrentDictionary(); - var sensorValue = new ConcurrentDictionary(); - foreach (var sensor in _sensors) - { - 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 (sensors != null) + this.AddSensors(sensors); - sensor.PropertyChanged += (o, e) => - { - 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); - 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; - } - }; - } + #endregion - setParameterValue(ERDM_Parameter.SENSOR_DEFINITION, sensorDef); - setParameterValue(ERDM_Parameter.SENSOR_VALUE, sensorValue); - } - } + #region StatusMessage + if (SupportStatus) + trySetParameter(ERDM_Parameter.STATUS_MESSAGES, new RDMStatusMessage[0]); #endregion #region DMX-Address @@ -281,7 +243,6 @@ private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[ #endregion updateDeviceInfo(); - ParameterUpdatedBag.Clear(); _initialized = true; } @@ -313,14 +274,43 @@ private void updateDeviceInfo(RDMDeviceInfo value) protected void AddSensors(params Sensor[] @sensors) { + if (sensors == null) + throw new ArgumentNullException(); + + sensorDef = new ConcurrentDictionary(); + sensorValue = new ConcurrentDictionary(); 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} already exists"); - this.sensors.TryAdd(sensor.SensorId, sensor); + if(this.sensors.TryAdd(sensor.SensorId, sensor)) + { + 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; + } } + + var _sensors = Sensors.Values.ToArray(); + if (_sensors.Length >= byte.MaxValue) + throw new ArgumentOutOfRangeException($"There to many {Sensors}! Maximum is {byte.MaxValue - 1}"); + + 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); } protected void RemoveSensors(params Sensor[] @sensors) { @@ -332,26 +322,55 @@ protected void RemoveSensors(params Sensor[] @sensors) 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) { - sensorDef.TryRemove(sensor.SensorId, out _); - setParameterValue(ERDM_Parameter.SENSOR_DEFINITION, 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) { - sensorValue.TryRemove(sensor.SensorId, out _); - setParameterValue(ERDM_Parameter.SENSOR_VALUE, sensorValue); + if (sensorValue.TryRemove(sensor.SensorId, out _)) + setParameterValue(ERDM_Parameter.SENSOR_VALUE, sensorValue); } } } } + 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); + 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; } @@ -486,7 +505,16 @@ private void setParameterValue(ERDM_Parameter parameter, object value, object in }); if (notNew) return; - updateParameterBag(parameter, index); + if (parameter != ERDM_Parameter.SLOT_DESCRIPTION) + { + updateParameterBag(parameter, index); + return; + } + else if(value is ConcurrentDictionary dict) + { + foreach (var p in dict) + updateParameterBag(parameter, p.Key); + } return; } } @@ -504,6 +532,8 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) RDMMessage response = null; try { + var controllerCache = getControllerCommunicationCache(rdmMessage.SourceUID); + controllerCache.Seen(); if (rdmMessage.Command == ERDM_Command.DISCOVERY_COMMAND) { switch (rdmMessage.Parameter) @@ -562,7 +592,29 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) } if (parameter == ERDM_Parameter.QUEUED_MESSAGE) { - if (ParameterUpdatedBag.IsEmpty) + 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 { @@ -570,17 +622,53 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) Command = ERDM_Command.GET_COMMAND_RESPONSE, MessageCounter = 0 }; + if (SupportStatus) + fillRDMMessageWithStatusMessageData(controllerCache, statusCode, ref response); + goto FAIL; } - else if (ParameterUpdatedBag.TryDequeue(out var item)) + else if (controllerCache.ParameterUpdatedBag.TryDequeue(out var item)) { parameter = item.Parameter; requestValue = item.Index; - messageCounter = (byte)Math.Min(ParameterUpdatedBag.Count, byte.MaxValue); + messageCounter = (byte)Math.Min(controllerCache.ParameterUpdatedBag.Count, byte.MaxValue); + } + } + else 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 - removeParamterFromParameterUpdateBag(parameter); + removeParameterFromParameterUpdateBag(parameter); parameterValues.TryGetValue(parameter, out object responseValue); var parameterBag = new ParameterBag(parameter, UID.ManufacturerID, DeviceInfo.DeviceModelId, DeviceInfo.SoftwareVersionId); @@ -598,6 +686,9 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) MessageCounter = messageCounter, ParameterData = data, }; + if (rdmMessage.Parameter == ERDM_Parameter.QUEUED_MESSAGE) + controllerCache.SetLastSendQueuedOrStatusRDMMessageResponse(response); + controllerCache.SetLastSendRDMMessageResponse(response); } else goto FAIL; @@ -660,6 +751,10 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) return null; if (rdmMessage.DestUID.IsBroadcast) // no Response on Broadcast return null; + if(response == null) + { + + } response ??= new RDMMessage(ERDM_NackReason.UNKNOWN_PID) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; @@ -695,28 +790,132 @@ private void updateParameterBag(ERDM_Parameter parameter, object index = null) return; try { - removeParamterFromParameterUpdateBag(parameter, index); - ParameterUpdatedBag.Enqueue(new ParameterUpdatedBag(parameter, index)); + addOrUpdateParameterFromParameterUpdateBag(parameter, index); } catch(Exception e) { + Logger.LogError(e); + } + } + private void addOrUpdateParameterFromParameterUpdateBag(ERDM_Parameter parameter, object index = null) + { + foreach (var cache in controllerCommunicationCache) + { + 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); + + while (tempQueue.TryDequeue(out var item)) + cache.Value.ParameterUpdatedBag.Enqueue(item); + } + cache.Value.ParameterUpdatedBag.Enqueue(new ParameterUpdatedBag(parameter, index)); } } - private void removeParamterFromParameterUpdateBag(ERDM_Parameter parameter, object index = null) + private void removeParameterFromParameterUpdateBag(ERDM_Parameter parameter, object index = null) { - if (ParameterUpdatedBag.Any(p => p.Parameter == parameter && p.Index == index)) + foreach (var cache in controllerCommunicationCache) { - var tempQueue = new ConcurrentQueue(); - while (ParameterUpdatedBag.TryDequeue(out var item)) - if (!(item.Parameter.Equals(parameter) && Equals(parameter, index))) - tempQueue.Enqueue(item); + 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); - while (tempQueue.TryDequeue(out var item)) - 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) + { + if (!SupportStatus) + throw new NotSupportedException($"The Device {this.UID} not support Status Messages."); + this.statusMessages.Where(s => s.Value.Equals(statusMessage)).ToList().ForEach(s => + { + 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 => + { + if (this.statusMessages.TryRemove(s.Key, out _)) + succes = true; + }); + if(succes) + setParameterValue(ERDM_Parameter.STATUS_MESSAGES, this.statusMessages.Select(sm => sm.Value).ToArray()); + } + 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) + { + 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 (statusMessage.StatusType == ERDM_Status.GET_LAST_MESSAGE) + throw new NotSupportedException($"The StatusCode: {statusMessage.StatusType}, not supported in this Method."); + + var statusType = statusMessage.StatusType & ~ERDM_Status.CLEARED; + + return statusType >= statusCode; + } + } + private ControllerCommunicationCache getControllerCommunicationCache(UID uid) + { + if (!controllerCommunicationCache.TryGetValue(uid, out var cache)) + { + cache = new ControllerCommunicationCache(uid); + controllerCommunicationCache.TryAdd(uid, cache); + } + return cache; + } protected sealed override void OnDispose() { try @@ -729,5 +928,57 @@ protected sealed override void OnDispose() } } protected abstract void onDispose(); + + 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(); + + public ControllerCommunicationCache(UID uid) : this() + { + 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; + + return -1; + } + + 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; + } + } } } \ No newline at end of file diff --git a/RDMSharp/RDM/Device/AbstractRDMCache.cs b/RDMSharp/RDM/Device/AbstractRDMCache.cs index 3d22abd..87c55f0 100644 --- a/RDMSharp/RDM/Device/AbstractRDMCache.cs +++ b/RDMSharp/RDM/Device/AbstractRDMCache.cs @@ -208,7 +208,7 @@ protected async Task requestGetParameterWithEmptyPayload(ParameterBag para } return 0; } - protected async Task requestGetParameterWithPayload(ParameterBag parameterBag, MetadataJSONObjectDefine define, UID uid, SubDevice subDevice, object? i=null) + 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(); @@ -231,7 +231,7 @@ protected async Task requestGetParameterWithPayload(ParameterBag parameterBag, M continue; if (((IComparable)max).CompareTo(i) == -1) - return; + return 0; DataTreeBranch dataTreeBranch = new DataTreeBranch(new DataTree(name, 0, i)); PeerToPeerProcess ptpProcess = new PeerToPeerProcess(ERDM_Command.GET_COMMAND, uid, subDevice, parameterBag, dataTreeBranch); @@ -242,6 +242,7 @@ protected async Task requestGetParameterWithPayload(ParameterBag parameterBag, M i = intType.IncrementJumpRange(i); count = intType.Increment(count); } + return 0; } else { @@ -249,14 +250,16 @@ protected async Task requestGetParameterWithPayload(ParameterBag parameterBag, M 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); + updateParameterValuesDataTreeBranch(new ParameterDataCacheBag(ptpProcess.ParameterBag.PID, parameterBag.PID == ERDM_Parameter.QUEUED_MESSAGE || parameterBag.PID == ERDM_Parameter.STATUS_MESSAGES ? null : i), ptpProcess.ResponsePayloadObject); + return ptpProcess.MessageCounter; } } catch (Exception e) { - Logger.LogError(e, $"Failed to get parameter {parameterBag.PID} with Bag: {parameterBag}"); + Logger?.LogError(e, $"Failed to get parameter {parameterBag.PID} with Bag: {parameterBag}"); } } + return 0; } diff --git a/RDMSharp/RDM/Device/AbstractRDMDevice.cs b/RDMSharp/RDM/Device/AbstractRDMDevice.cs index 358773c..fb0b1a4 100644 --- a/RDMSharp/RDM/Device/AbstractRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractRDMDevice.cs @@ -22,12 +22,12 @@ public abstract class AbstractRDMDevice : AbstractRDMCache, IRDMDevice 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(); - protected ConcurrentQueue ParameterUpdatedBag = new ConcurrentQueue(); public new bool IsDisposing { get; private set; } public new bool IsDisposed { get; private set; } diff --git a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs index f0f2db4..e16b35f 100644 --- a/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractRemoteRDMDevice.cs @@ -29,6 +29,12 @@ public abstract class AbstractRemoteRDMDevice : AbstractRDMDevice , IRDMRemoteDe 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(); } } + + protected ConcurrentQueue ParameterUpdatedBag = new ConcurrentQueue(); + private RDMDeviceInfo deviceInfo; public override RDMDeviceInfo DeviceInfo { get { return deviceInfo; } } @@ -221,6 +227,11 @@ private async Task requestParameters() { 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); } @@ -252,7 +263,7 @@ private async Task updateParameters(bool queued = true) do { lastSendQueuedMessage = DateTime.UtcNow; - mc = await requestGetParameterWithEmptyPayload(parameterBag, define, UID, Subdevice); + mc = await requestGetParameterWithPayload(parameterBag, define, UID, Subdevice, ERDM_Status.ADVISORY); } while (mc != 0); } diff --git a/RDMSharp/RDM/Enum/ERDM_Status.cs b/RDMSharp/RDM/Enum/ERDM_Status.cs index 8509cfd..2f1d8e3 100644 --- a/RDMSharp/RDM/Enum/ERDM_Status.cs +++ b/RDMSharp/RDM/Enum/ERDM_Status.cs @@ -1,18 +1,27 @@ using RDMSharp.Metadata; using RDMSharp.Metadata.JSON; +using System; namespace RDMSharp { [DataTreeEnum(ERDM_Parameter.STATUS_MESSAGES, Command.ECommandDublicate.GetRequest, "status_type")] + [DataTreeEnum(ERDM_Parameter.QUEUED_MESSAGE, Command.ECommandDublicate.GetRequest, "status_type")] [DataTreeEnum(ERDM_Parameter.SUB_DEVICE_STATUS_REPORT_THRESHOLD, Command.ECommandDublicate.GetResponse, "status_type")] [DataTreeEnum(ERDM_Parameter.SUB_DEVICE_STATUS_REPORT_THRESHOLD, Command.ECommandDublicate.SetRequest, "status_type")] + + [Flags] public enum ERDM_Status : byte { NONE = 0x00, + GET_LAST_MESSAGE = 0x01, + ADVISORY = 0x02, WARNING = 0x03, ERROR = 0x04, + + CLEARED = 0x10, + ADVISORY_CLEARED = 0x12, WARNING_CLEARED = 0x13, ERROR_CLEARED = 0x14, diff --git a/RDMSharp/RDM/GlobalTimers.cs b/RDMSharp/RDM/GlobalTimers.cs index d1b01ad..126446e 100644 --- a/RDMSharp/RDM/GlobalTimers.cs +++ b/RDMSharp/RDM/GlobalTimers.cs @@ -4,7 +4,7 @@ namespace RDMSharp { public class GlobalTimers { - private static GlobalTimers? instance = null; + private static GlobalTimers instance = null; public static GlobalTimers Instance { get @@ -15,10 +15,12 @@ public static GlobalTimers Instance } } - - public int QueuedUpdateTime { get; set; } = 4000; - public int NonQueuedUpdateTime { get; set; } = 10000; - private int parameterUpdateTimerInterval = 1000; + public const int DefaultQueuedUpdateTime = 4000; // 4 seconds + public const int DefaultNonQueuedUpdateTime = 10000; // 10 seconds + public const int DefaultUpdateTimerInterval = 10000; // 10 seconds + public int QueuedUpdateTime { get; set; } = DefaultQueuedUpdateTime; + public int NonQueuedUpdateTime { get; set; } = DefaultNonQueuedUpdateTime; + private int parameterUpdateTimerInterval = DefaultUpdateTimerInterval; public int ParameterUpdateTimerInterval { get @@ -32,7 +34,7 @@ public int ParameterUpdateTimerInterval parameterUpdateTimer.Interval = value; } } - private System.Timers.Timer? parameterUpdateTimer = null; + private System.Timers.Timer parameterUpdateTimer = null; private event EventHandler parameterUpdateTimerElapsed; public event EventHandler ParameterUpdateTimerElapsed @@ -71,6 +73,13 @@ private void destroyParameterUpdateTimer() parameterUpdateTimer = null; } + public void ResetAllTimersToDefault() + { + QueuedUpdateTime = DefaultQueuedUpdateTime; + NonQueuedUpdateTime = DefaultNonQueuedUpdateTime; + ParameterUpdateTimerInterval = DefaultUpdateTimerInterval; + } + private void ParameterUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { parameterUpdateTimerElapsed?.InvokeFailSafe(sender, EventArgs.Empty); diff --git a/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs b/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs index 5eab0ee..9a357b0 100644 --- a/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs +++ b/RDMSharp/RDM/PayloadObject/RDMStatusMessage.cs @@ -1,12 +1,13 @@ using RDMSharp.Metadata; using RDMSharp.Metadata.JSON; +using System; using System.Collections.Generic; using System.Text; namespace RDMSharp { [DataTreeObject(ERDM_Parameter.STATUS_MESSAGES, Command.ECommandDublicate.GetResponse, true, "slots")] - public class RDMStatusMessage : AbstractRDMPayloadObject + public class RDMStatusMessage : AbstractRDMPayloadObject, IEquatable { public RDMStatusMessage( ushort subDeviceId = 0, @@ -24,11 +25,11 @@ public RDMStatusMessage( [DataTreeObjectConstructor] public RDMStatusMessage( - [DataTreeObjectParameter("slots/subdevice_id")] ushort subDeviceId, - [DataTreeObjectParameter("slots/status_type")] byte statusType, - [DataTreeObjectParameter("slots/status_message_id")] byte statusMessage, - [DataTreeObjectParameter("slots/data_value_1")] short dataValue1, - [DataTreeObjectParameter("slots/data_value_2")] short dataValue2) + [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) { } @@ -42,6 +43,11 @@ public RDMStatusMessage( public const int PDL = 9; public string FormatedString => StatusMessage.GetStatusMessage(DataValue1, DataValue2); + internal void Clear() + { + StatusType |= ERDM_Status.CLEARED; + } + public override string ToString() { StringBuilder b = new StringBuilder(); @@ -84,5 +90,16 @@ public override byte[] ToPayloadData() 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.StatusType == other.StatusType && + this.StatusMessage == other.StatusMessage && + this.DataValue1 == other.DataValue1 && + this.DataValue2 == other.DataValue2; + } } } \ No newline at end of file diff --git a/RDMSharp/RDM/PeerToPeerProcess.cs b/RDMSharp/RDM/PeerToPeerProcess.cs index e922cd2..3eb996d 100644 --- a/RDMSharp/RDM/PeerToPeerProcess.cs +++ b/RDMSharp/RDM/PeerToPeerProcess.cs @@ -42,8 +42,8 @@ public PeerToPeerProcess(ERDM_Command command, UID uid, SubDevice subDevice, Par ParameterBag = parameterBag; RequestPayloadObject = payloadObject ?? DataTreeBranch.Unset; - if (ParameterBag.PID != ERDM_Parameter.QUEUED_MESSAGE) - Define = MetadataFactory.GetDefine(ParameterBag); + //if (ParameterBag.PID != ERDM_Parameter.QUEUED_MESSAGE) + Define = MetadataFactory.GetDefine(ParameterBag); } public async Task Run(AsyncRDMRequestHelper asyncRDMRequestHelper) @@ -71,7 +71,8 @@ private async Task run(AsyncRDMRequestHelper asyncRDMRequestHelper) if (Command == ERDM_Command.SET_COMMAND) commandResponse = ECommandDublicate.SetResponse; - byte[] parameterData = ParameterBag.PID != ERDM_Parameter.QUEUED_MESSAGE ? MetadataFactory.ParsePayloadToData(Define, commandRequest, RequestPayloadObject) : null; + byte[] parameterData = //ParameterBag.PID != ERDM_Parameter.QUEUED_MESSAGE ? + MetadataFactory.ParsePayloadToData(Define, commandRequest, RequestPayloadObject);// : null; request = new RDMMessage() { Command = Command, diff --git a/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs b/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs index cfa813d..b256b1a 100644 --- a/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs +++ b/RDMSharpTests/Devices/Mock/AbstractMockGeneratedDevice.cs @@ -54,6 +54,10 @@ private async void SendReceivePipelineImitateRealConditions_RDMMessageReceivedRe { await base.ReceiveRDMMessage(rdmMessage); } + internal RDMMessage? ProcessRequestMessage_Internal(RDMMessage request) + { + return base.processRequestMessage(request); + } protected override async Task SendRDMMessage(RDMMessage rdmMessage) { if (rdmMessage == null) @@ -70,6 +74,20 @@ protected override async Task SendRDMMessage(RDMMessage rdmMessage) else SendReceivePipeline.RDMMessageSend(i, rdmMessage); } + + 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); + } + protected sealed override void onDispose() { try diff --git a/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs b/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs index a7b047c..378474a 100644 --- a/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs +++ b/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs @@ -50,6 +50,11 @@ public override EManufacturer ManufacturerID new MockSensorVolt3_3(3, 331), new MockSensorVolt5(4, 498) }; public override GeneratedPersonality[] Personalities => PERSONALITYS; + + public override bool SupportQueued => true; + + public override bool SupportStatus => true; + public MockGeneratedDevice1(UID uid) : base(uid, SubDevice.Root, new ERDM_Parameter[] { ERDM_Parameter.IDENTIFY_DEVICE, ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL }, "Dummy Manufacturer 9FFF", SENSORS) { this.DeviceLabel = "Dummy Device 1"; diff --git a/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs b/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs index ffd8be8..dd6288f 100644 --- a/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs +++ b/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs @@ -41,6 +41,11 @@ internal sealed class MockGeneratedDeviceWithSubDeviceMaster1 : MockGeneratedDev 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; + public MockGeneratedDeviceWithSubDeviceMaster1(UID uid, ushort subDevicesCount) : base(uid, getSubDevices(uid, subDevicesCount), SENSORS) { } @@ -70,6 +75,11 @@ internal sealed class MockGeneratedDeviceWithSubDeviceSub1 : MockGeneratedDevice new MockSensorTemp(0, 1, 3000)}; public override GeneratedPersonality[] Personalities => PERSONALITYS; + + public override bool SupportQueued => true; + + public override bool SupportStatus => true; + public MockGeneratedDeviceWithSubDeviceSub1(UID uid, ushort subDeviceID) : base(uid, getSubDevice(subDeviceID), SENSORS) { } diff --git a/RDMSharpTests/Devices/TestRDMSendReceive.cs b/RDMSharpTests/Devices/TestRDMSendReceive.cs index 740c655..0b4ad3d 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceive.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceive.cs @@ -9,7 +9,8 @@ public class TestRDMSendReceive private Random random = new Random(); [SetUp] public void Setup() - { + { + GlobalTimers.Instance.ResetAllTimersToDefault(); var uid = new UID((ushort)random.Next(), (uint)random.Next()); generated = new MockGeneratedDevice1(uid); remote = new MockDevice(uid, false); @@ -17,8 +18,7 @@ public void Setup() [TearDown] public void TearDown() { - GlobalTimers.Instance.QueuedUpdateTime = 4000; - GlobalTimers.Instance.ParameterUpdateTimerInterval = 1000; + GlobalTimers.Instance.ResetAllTimersToDefault(); generated?.Dispose(); generated = null; remote?.Dispose(); diff --git a/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs b/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs new file mode 100644 index 0000000..91d4bc1 --- /dev/null +++ b/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs @@ -0,0 +1,405 @@ +using RDMSharpTests.Devices.Mock; + +namespace RDMSharpTests.RDM.Devices +{ + public class TestRDMSendReceiveGeneratedOnly + { + private MockGeneratedDevice1? generated; + private Random random = new Random(); + 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 TestGetStatusMessages() + { + #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].StatusType, Is.EqualTo(ERDM_Status.ERROR_CLEARED)); + for (int i = 0; i < 2; i++) + Assert.That(statusMessages[i], Is.EqualTo(generated.StatusMessages[i])); + #endregion + } + [Test, Order(1000)] + public void TestGetQueuedMessages() + { + #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 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)); + + 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 + } + } +} \ No newline at end of file From d478db97be331c99f8e0d55ffa2141b842d02c3a Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 28 May 2025 01:57:40 +0200 Subject: [PATCH 15/20] Grrr --- RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs index 30637fd..898b21b 100644 --- a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs @@ -929,7 +929,7 @@ protected sealed override void OnDispose() } protected abstract void onDispose(); - private class ControllerCommunicationCache() + private class ControllerCommunicationCache { public readonly UID Uid; public DateTime LastSeen = DateTime.UtcNow; @@ -939,7 +939,7 @@ private class ControllerCommunicationCache() internal ConcurrentQueue ParameterUpdatedBag = new ConcurrentQueue(); - public ControllerCommunicationCache(UID uid) : this() + public ControllerCommunicationCache(UID uid) { this.Uid = uid; } From c48db1ff87620ea85d093a82ae21a0b1213907a7 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 28 May 2025 03:17:42 +0200 Subject: [PATCH 16/20] More Tests --- .../RDM/Device/AbstractGeneratedRDMDevice.cs | 25 ++ .../Devices/Mock/MockGeneratedDevice1.cs | 3 +- .../Mock/MockGeneratedDeviceWithSubDevice1.cs | 1 - RDMSharpTests/Devices/TestRDMSendReceive.cs | 4 +- .../TestRDMSendReceiveGeneratedOnly.cs | 389 +++++++++++++++++- 5 files changed, 415 insertions(+), 7 deletions(-) diff --git a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs index 898b21b..7c7ff0f 100644 --- a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs @@ -137,6 +137,23 @@ private set } } + private bool identify; + public bool Identify + { + get + { + return identify; + } + set + { + if (string.Equals(identify, value)) + return; + + identify = value; + this.OnPropertyChanged(nameof(this.Identify)); + } + } + 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) @@ -164,6 +181,7 @@ private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[ _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 (SupportDMXAddress) _params.Add(ERDM_Parameter.DMX_START_ADDRESS); if ((Personalities?.Length ?? 0) != 0) @@ -184,6 +202,7 @@ private AbstractGeneratedRDMDevice(UID uid, SubDevice subDevice, ERDM_Parameter[ Parameters = _params.Distinct().ToArray(); trySetParameter(ERDM_Parameter.SUPPORTED_PARAMETERS, Parameters); + trySetParameter(ERDM_Parameter.IDENTIFY_DEVICE, Identify); #endregion #region ManufacturerLabel @@ -453,6 +472,9 @@ protected sealed override void OnPropertyChanged(string property) 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))); @@ -745,6 +767,9 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) catch (Exception e) { Logger?.LogError(e, string.Empty); + + response = new RDMMessage(ERDM_NackReason.ACTION_NOT_SUPPORTED) { Parameter = rdmMessage.Parameter, Command = rdmMessage.Command | ERDM_Command.RESPONSE }; + 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. diff --git a/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs b/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs index 378474a..0f5f2f3 100644 --- a/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs +++ b/RDMSharpTests/Devices/Mock/MockGeneratedDevice1.cs @@ -55,10 +55,9 @@ public override EManufacturer ManufacturerID public override bool SupportStatus => true; - public MockGeneratedDevice1(UID uid) : base(uid, SubDevice.Root, new ERDM_Parameter[] { ERDM_Parameter.IDENTIFY_DEVICE, ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL }, "Dummy Manufacturer 9FFF", SENSORS) + public MockGeneratedDevice1(UID uid) : base(uid, SubDevice.Root, new ERDM_Parameter[] { ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL }, "Dummy Manufacturer 9FFF", SENSORS) { this.DeviceLabel = "Dummy Device 1"; - this.trySetParameter(ERDM_Parameter.IDENTIFY_DEVICE, false); this.trySetParameter(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL, $"Dummy Software"); } diff --git a/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs b/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs index dd6288f..2a5c6d7 100644 --- a/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs +++ b/RDMSharpTests/Devices/Mock/MockGeneratedDeviceWithSubDevice1.cs @@ -22,7 +22,6 @@ internal abstract class MockGeneratedDeviceWithSubDevice1 : AbstractMockGenerate } private void setInitParameters() { - this.trySetParameter(ERDM_Parameter.IDENTIFY_DEVICE, false); this.trySetParameter(ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL, $"Dummy Software"); } diff --git a/RDMSharpTests/Devices/TestRDMSendReceive.cs b/RDMSharpTests/Devices/TestRDMSendReceive.cs index 0b4ad3d..a82a18e 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceive.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceive.cs @@ -226,7 +226,7 @@ public async Task TestDevice1QueuedUpdates() generated.DMXAddress = 69; generated.DeviceLabel = "Test Label QUEUE"; - generated.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, true); + generated.Identify = true; await Task.Delay(1000); parameterValuesRemote = remote.GetAllParameterValues(); @@ -235,7 +235,7 @@ public async Task TestDevice1QueuedUpdates() Assert.That(parameterValuesRemote[ERDM_Parameter.DEVICE_LABEL], Is.EqualTo("Test Label QUEUE")); Assert.That(parameterValuesRemote[ERDM_Parameter.IDENTIFY_DEVICE], Is.True); - generated.SetParameter(ERDM_Parameter.IDENTIFY_DEVICE, false); + generated.Identify = false; generated.DMXAddress = 44; generated.CurrentPersonality = 2; diff --git a/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs b/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs index 91d4bc1..4b46fe3 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs @@ -20,8 +20,393 @@ public void TearDown() generated = null; } + [Test, Order(1)] - public void TestGetStatusMessages() + 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.Length * 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)); + #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 Label changed + 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 + } + [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.ACTION_NOT_SUPPORTED })); + + 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)); + } + #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)); + #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(30)] + public void TestGetBOOT_SOFTWARE_VERSION_LABEL() + { + const string SOFTWARE_VERSION_LABEL = "Dummy Software"; + #region Test Basic + Assert.That(generated, Is.Not.Null); + Assert.That(generated.ParameterValues[ERDM_Parameter.BOOT_SOFTWARE_VERSION_LABEL], Is.EqualTo(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(SOFTWARE_VERSION_LABEL.Length)); + Assert.That(response.Value, Is.EqualTo(SOFTWARE_VERSION_LABEL)); + #endregion + } + + [Test, Order(100)] + public void TestGetSTATUS_MESSAGES() { #region Test Empty Status Messages Assert.That(generated, Is.Not.Null); @@ -186,7 +571,7 @@ public void TestGetStatusMessages() #endregion } [Test, Order(1000)] - public void TestGetQueuedMessages() + public void TestGetQUEUED_MESSAGE() { #region Test Empty queue Assert.That(generated, Is.Not.Null); From c600feb430ec09e1b425489f023ea1e5fc412a34 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 29 May 2025 23:29:57 +0200 Subject: [PATCH 17/20] Add Tests for Slots --- .../RDM/Device/AbstractGeneratedRDMDevice.cs | 5 +- .../TestRDMSendReceiveGeneratedOnly.cs | 224 +++++++++++++++++- 2 files changed, 227 insertions(+), 2 deletions(-) diff --git a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs index 7c7ff0f..8899421 100644 --- a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs @@ -32,7 +32,7 @@ public abstract class AbstractGeneratedRDMDevice : AbstractRDMDevice private ConcurrentDictionary sensorDef; private ConcurrentDictionary sensorValue; - public sealed override IReadOnlyDictionary Slots { get { return CurrentPersonality.HasValue ? Personalities[CurrentPersonality.Value].Slots : null; } } + 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(); } } @@ -113,6 +113,9 @@ public byte? CurrentPersonality 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; diff --git a/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs b/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs index 4b46fe3..44168b0 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs @@ -5,7 +5,7 @@ namespace RDMSharpTests.RDM.Devices public class TestRDMSendReceiveGeneratedOnly { private MockGeneratedDevice1? generated; - private Random random = new Random(); + private static UID CONTROLLER_UID = new UID(0x1fff, 333); private static UID DEVCIE_UID = new UID(123, 555); [SetUp] @@ -405,6 +405,205 @@ public void TestGetBOOT_SOFTWARE_VERSION_LABEL() #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(ArgumentOutOfRangeException), () => generated.CurrentPersonality = 4); // Change to personality 4 + #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(ArgumentOutOfRangeException), () => generated.CurrentPersonality = 4); // Change to personality 4 + #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(ArgumentOutOfRangeException), () => generated.CurrentPersonality = 4); // Change to personality 4 + + 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.ACTION_NOT_SUPPORTED })); + #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(100)] public void TestGetSTATUS_MESSAGES() { @@ -626,6 +825,21 @@ public void TestGetQUEUED_MESSAGE() 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; @@ -637,6 +851,7 @@ public void TestGetQUEUED_MESSAGE() 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)); @@ -786,5 +1001,12 @@ public void TestGetQUEUED_MESSAGE() Assert.That(response.ParameterData, Has.Length.EqualTo(0)); #endregion } + // Gibt das Low- und High-Byte eines ushort-Werts i zurück + public static (byte low, byte high) GetLowHighBytes(ushort i) + { + byte low = (byte)(i & 0xFF); + byte high = (byte)((i >> 8) & 0xFF); + return (low, high); + } } } \ No newline at end of file From d1cd2f53d25738086675b3ad88a7d05da55de56a Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 30 May 2025 00:04:17 +0200 Subject: [PATCH 18/20] Fix previous Commit --- .../RDM/Device/AbstractGeneratedRDMDevice.cs | 5 +++++ RDMSharp/RDM/LoggingTools.cs | 12 ++++++------ RDMSharpTests/Devices/TestRDMDiscovery.cs | 12 ++++++------ .../Devices/TestRDMSendReceiveSubDevices.cs | 17 ++++++++++------- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs index 8899421..162b5c4 100644 --- a/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractGeneratedRDMDevice.cs @@ -755,6 +755,11 @@ protected RDMMessage processRequestMessage(RDMMessage rdmMessage) catch (Exception e) { Logger.LogError(e); + if (e is ArgumentOutOfRangeException) + response = new RDMMessage(ERDM_NackReason.ACTION_NOT_SUPPORTED) { 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; } } diff --git a/RDMSharp/RDM/LoggingTools.cs b/RDMSharp/RDM/LoggingTools.cs index 091ae8f..e5d1b56 100644 --- a/RDMSharp/RDM/LoggingTools.cs +++ b/RDMSharp/RDM/LoggingTools.cs @@ -6,11 +6,11 @@ namespace RDMSharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2254:Vorlage muss ein statischer Ausdruck sein", Justification = "")] public static class LoggingTools { - 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); + 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/RDMSharpTests/Devices/TestRDMDiscovery.cs b/RDMSharpTests/Devices/TestRDMDiscovery.cs index 383b770..983095b 100644 --- a/RDMSharpTests/Devices/TestRDMDiscovery.cs +++ b/RDMSharpTests/Devices/TestRDMDiscovery.cs @@ -36,7 +36,7 @@ public void Report(RDMDiscoveryStatus value) ProgressChanged?.Invoke(this, value); } } - [Test, Retry(3)] + [Test, Retry(3), CancelAfter(120000)] public void TestDiscoveryProgress() { var progress = new DiscoveryProgress(); @@ -76,7 +76,7 @@ private async Task AssertDiscovery(bool full = true) }); } - [Test, Retry(3)] + [Test, Retry(3), CancelAfter(30000)] public async Task TestDiscovery1() { mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 4444))); @@ -92,7 +92,7 @@ public async Task TestDiscovery1() expected = mockDevices.Select(m => m.UID).ToList(); await AssertDiscovery(); } - [Test, Retry(3)] + [Test, Retry(3), CancelAfter(60000)] public async Task TestDiscovery2() { mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234254))); @@ -111,7 +111,7 @@ public async Task TestDiscovery2() expected = mockDevices.Select(m => m.UID).ToList(); await AssertDiscovery(); } - [Test, Retry(3)] + [Test, Retry(3), CancelAfter(60000)] public async Task TestDiscovery3() { mockDevices.Add(new MockGeneratedDevice1(new UID(0x9fff, 234254))); @@ -133,7 +133,7 @@ public async Task TestDiscovery3() expected = mockDevices.Select(m => m.UID).ToList(); await AssertDiscovery(); } - [Test, Retry(3)] + [Test, Retry(3), CancelAfter(180000)] public async Task TestDiscovery4() { HashSet ids = new HashSet(); @@ -152,7 +152,7 @@ public async Task TestDiscovery4() expected = mockDevices.Select(m => m.UID).ToList(); await AssertDiscovery(); } - [Test, Retry(3)] + [Test, Retry(3), CancelAfter(180000)] public async Task TestDiscovery5TotalyRandom() { HashSet ids = new HashSet(); diff --git a/RDMSharpTests/Devices/TestRDMSendReceiveSubDevices.cs b/RDMSharpTests/Devices/TestRDMSendReceiveSubDevices.cs index 261ce21..db06d34 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceiveSubDevices.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceiveSubDevices.cs @@ -23,7 +23,7 @@ public void TearDown() remote.Dispose(); } - [Test] + [Test, CancelAfter(10000)] [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", "NUnit2010:Use EqualConstraint for better assertion messages in case of failure", Justification = "")] public async Task TestDevice1() { @@ -92,12 +92,15 @@ private async Task PerformTests(AbstractRemoteRDMDevice remote, AbstractGenerate Assert.That(generated.DMXAddress, Is.EqualTo(512)); //}); - await remote.SetParameter(ERDM_Parameter.DMX_PERSONALITY, (byte)3); - //Assert.Multiple(() => - //{ - Assert.That(remote.GetAllParameterValues()[ERDM_Parameter.DMX_PERSONALITY], Is.EqualTo(3)); - Assert.That(generated.CurrentPersonality, Is.EqualTo(3)); - //}); + if (generated.Personalities.Any(p => p.ID == 3)) + { + await remote.SetParameter(ERDM_Parameter.DMX_PERSONALITY, (byte)3); + //Assert.Multiple(() => + //{ + Assert.That(remote.GetAllParameterValues()[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); From e3bbf6e8308a1fcd0ebd3adee68cdcea3fdcd56a Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 30 May 2025 01:33:36 +0200 Subject: [PATCH 19/20] Add Tests for Sensors --- .../TestRDMSendReceiveGeneratedOnly.cs | 97 ++++++++++++++++--- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs b/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs index 44168b0..69acb5a 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs @@ -467,7 +467,10 @@ public void TestGetSLOT_INFO() #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 } @@ -533,11 +536,13 @@ public void TestGetDEFAULT_SLOT_VALUE() #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() { @@ -571,7 +576,10 @@ public void TestGetSLOT_DESCRIPTION() #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); @@ -579,7 +587,7 @@ public void TestGetSLOT_DESCRIPTION() 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.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.ACTION_NOT_SUPPORTED })); @@ -595,7 +603,7 @@ void doTests(Slot[] slots) 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.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(2 + slot.Description.Length)); @@ -604,6 +612,80 @@ void doTests(Slot[] slots) } } + [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.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_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(100)] public void TestGetSTATUS_MESSAGES() { @@ -957,7 +1039,7 @@ public void TestGetQUEUED_MESSAGE() 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.Parameter, Is.EqualTo(ERDM_Parameter.SENSOR_DEFINITION)); 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)); @@ -1001,12 +1083,5 @@ public void TestGetQUEUED_MESSAGE() Assert.That(response.ParameterData, Has.Length.EqualTo(0)); #endregion } - // Gibt das Low- und High-Byte eines ushort-Werts i zurück - public static (byte low, byte high) GetLowHighBytes(ushort i) - { - byte low = (byte)(i & 0xFF); - byte high = (byte)((i >> 8) & 0xFF); - return (low, high); - } } } \ No newline at end of file From 86429afeb238b1d6a353eac4c86466d221453e0c Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 30 May 2025 01:38:51 +0200 Subject: [PATCH 20/20] Grrr --- RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs b/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs index 69acb5a..7cf3f15 100644 --- a/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs +++ b/RDMSharpTests/Devices/TestRDMSendReceiveGeneratedOnly.cs @@ -587,7 +587,7 @@ public void TestGetSLOT_DESCRIPTION() 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.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.ACTION_NOT_SUPPORTED })); @@ -603,7 +603,7 @@ void doTests(Slot[] slots) 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.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)); @@ -1039,7 +1039,7 @@ public void TestGetQUEUED_MESSAGE() 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.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));