From 24525521af6602e7c9b1b34bad4daf3e62689fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Wei=C3=9F?= <72068105+Sandoun@users.noreply.github.com> Date: Tue, 13 Jun 2023 11:42:49 +0200 Subject: [PATCH] Added new unit tests --- MewtocolNet/Mewtocol/MewtocolHelpers.cs | 33 ++++++ MewtocolNet/Mewtocol/Subregisters/Register.cs | 107 ++++++++++++++++++ MewtocolTests/TestClient.cs | 104 +++++++++++++++++ MewtocolTests/TestComProtocol.cs | 2 - 4 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 MewtocolTests/TestClient.cs diff --git a/MewtocolNet/Mewtocol/MewtocolHelpers.cs b/MewtocolNet/Mewtocol/MewtocolHelpers.cs index fbcd79e..31a3295 100644 --- a/MewtocolNet/Mewtocol/MewtocolHelpers.cs +++ b/MewtocolNet/Mewtocol/MewtocolHelpers.cs @@ -197,6 +197,39 @@ namespace MewtocolNet { } + internal static bool IsDoubleNumericRegisterType (this Type type) { + + //Type[] singles = new Type[] { + // typeof(short), + // typeof(ushort), + //}; + + Type[] doubles = new Type[] { + typeof(int), + typeof(uint), + typeof(float), + typeof(TimeSpan), + }; + + return doubles.Contains(type); + + } + + internal static bool IsNumericSupportedType (this Type type) { + + Type[] supported = new Type[] { + typeof(short), + typeof(ushort), + typeof(int), + typeof(uint), + typeof(float), + typeof(TimeSpan), + }; + + return supported.Contains(type); + + } + } } \ No newline at end of file diff --git a/MewtocolNet/Mewtocol/Subregisters/Register.cs b/MewtocolNet/Mewtocol/Subregisters/Register.cs index 2af8c46..eea7ff1 100644 --- a/MewtocolNet/Mewtocol/Subregisters/Register.cs +++ b/MewtocolNet/Mewtocol/Subregisters/Register.cs @@ -2,8 +2,10 @@ using System.Collections; using System.Collections.Generic; using System.ComponentModel; +using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace MewtocolNet.Registers { @@ -254,6 +256,111 @@ namespace MewtocolNet.Registers { } + /// + /// Builds a register from a given register string like DT100 / XA / Y1 + /// + /// The input string to parse + /// A built register + public static Register FromString (string regString, string name = null) { + + var match = Regex.Match(regString, @"(X|Y|R)([A-F]|[0-9_.-]{1,5})"); + + if (match != null && match.Success) { + + var typeGroup = match.Groups[1].Value; + var areaGroup = match.Groups[2].Value; + + bool isBool = false; + var parsedRegType = RegisterType.R; + if (new string[] { "X", "Y", "R" }.Contains(typeGroup)) { + switch (typeGroup) { + case "X": + parsedRegType = RegisterType.X; + isBool = true; + break; + case "Y": + parsedRegType = RegisterType.Y; + isBool = true; + break; + case "R": + parsedRegType = RegisterType.R; + isBool = true; + break; + } + } + + if(!isBool) { + throw new NotSupportedException($"Register with value {regString} is not of type bool"); + } + + if (int.TryParse(areaGroup, out var parsedNum) && isBool) { + + return new BRegister(parsedNum, parsedRegType, name); + + } else if(Enum.TryParse(areaGroup, out var parsedSpecial) && isBool) { + + return new BRegister(parsedSpecial, parsedRegType, name); + + } + } + + throw new NotSupportedException($"Register with value {regString} is not supported"); + + } + + public static NRegister FromString (string regString, string name = null) { + + var match = Regex.Match(regString, @"(DT|DDT)([0-9_.-]{1,5})"); + + if (match != null && match.Success) { + + var typeGroup = match.Groups[1].Value; + var areaGroup = match.Groups[2].Value; + + bool isTypeDoubleSize = false; + bool isSupportedNumericFormat = false; + + if(typeGroup == "") + + switch (typeGroup) { + case "DT": + isSupportedNumericFormat = true; + break; + case "DDT": + isTypeDoubleSize = true; + isSupportedNumericFormat = true; + break; + } + + if(typeof(T).IsDoubleNumericRegisterType() != isTypeDoubleSize) { + throw new NotSupportedException($"Input register type was {typeGroup}, the cast type was not of the same size"); + } + + if (int.TryParse(areaGroup, out var parsedNum) && typeof(T).IsNumericSupportedType() && isSupportedNumericFormat ) { + + return new NRegister(parsedNum, name); + + } + + } + + throw new NotSupportedException($"Register with value {regString} is not supported"); + + } + + public static SRegister FromString (string regString, int reserved, string name = null) { + + var match = Regex.Match(regString, @"(DT)([0-9_.-]{1,5})"); + + if (match != null && match.Success) { + + + } + + throw new NotSupportedException($"Register with value {regString} is not supported"); + + } + internal string GetCombinedName () { return $"{(CollectionType != null ? $"{CollectionType.Name}." : "")}{Name ?? "Unnamed"}"; diff --git a/MewtocolTests/TestClient.cs b/MewtocolTests/TestClient.cs new file mode 100644 index 0000000..6f2a699 --- /dev/null +++ b/MewtocolTests/TestClient.cs @@ -0,0 +1,104 @@ +using MewtocolNet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace MewtocolTests { + + public class TestClient { + + private readonly ITestOutputHelper output; + + private List testData = new() { + + new ExpectedTestData { + + PLCName = "FPX-H C30T", + PLCIP = "192.168.115.210", + PLCPort = 9094, + Type = CpuType.FP_Sigma_X_H_30K_60K_120K, + ProgCapacity = 32, + + }, + new ExpectedTestData { + + PLCName = "FPX-H C14R", + PLCIP = "192.168.115.212", + PLCPort = 9094, + Type = CpuType.FP_Sigma_X_H_30K_60K_120K, + ProgCapacity = 16, + + }, + + }; + + public TestClient (ITestOutputHelper output) { + this.output = output; + } + + [Fact(DisplayName = "Connection cycle client to PLC")] + public async void TestClientConnection () { + + foreach (var plc in testData) { + + output.WriteLine($"Testing: {plc.PLCName}"); + + var cycleClient = new MewtocolInterface(plc.PLCIP, plc.PLCPort); + + await cycleClient.ConnectAsync(); + + Assert.True(cycleClient.IsConnected); + + cycleClient.Disconnect(); + + Assert.False(cycleClient.IsConnected); + + } + + } + + [Fact(DisplayName = "Reading basic information from PLC")] + public async void TestClientReadPLCStatus () { + + foreach (var plc in testData) { + + output.WriteLine($"Testing: {plc.PLCName}\n"); + + var client = new MewtocolInterface(plc.PLCIP, plc.PLCPort); + + await client.ConnectAsync(); + + output.WriteLine($"{client.PlcInfo}\n"); + + Assert.True(client.IsConnected); + + Assert.Equal(client.PlcInfo.CpuInformation.Cputype, plc.Type); + Assert.Equal(client.PlcInfo.CpuInformation.ProgramCapacity, plc.ProgCapacity); + + client.Disconnect(); + + } + + } + + } + + public class ExpectedTestData { + + public string PLCName { get; set; } + + public string PLCIP { get; set; } + + public int PLCPort { get; set; } + + public CpuType Type { get; set; } + + public int ProgCapacity { get; set; } + + } + +} diff --git a/MewtocolTests/TestComProtocol.cs b/MewtocolTests/TestComProtocol.cs index d9180f5..ebe07c0 100644 --- a/MewtocolTests/TestComProtocol.cs +++ b/MewtocolTests/TestComProtocol.cs @@ -25,7 +25,6 @@ namespace MewtocolTests { new NRegister(50), new NRegister(50), new NRegister(50), - new NRegister(50), }; List expcectedIdents = new List { @@ -35,7 +34,6 @@ namespace MewtocolTests { "D0005000051", //double word register "D0005000051", //double word register "D0005000051", //double word register - "D0005000051", //double word register }; //test mewtocol idents