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