mirror of
https://github.com/OpenLogics/MewtocolNet.git
synced 2025-12-06 03:01:24 +00:00
Added new unit tests
This commit is contained in:
@@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,10 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MewtocolNet.Registers {
|
namespace MewtocolNet.Registers {
|
||||||
@@ -254,6 +256,111 @@ namespace MewtocolNet.Registers {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Builds a register from a given register string like DT100 / XA / Y1
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="regString">The input string to parse</param>
|
||||||
|
/// <returns>A built register</returns>
|
||||||
|
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<SpecialAddress>(areaGroup, out var parsedSpecial) && isBool) {
|
||||||
|
|
||||||
|
return new BRegister(parsedSpecial, parsedRegType, name);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotSupportedException($"Register with value {regString} is not supported");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NRegister<T> FromString<T> (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<T>(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 () {
|
internal string GetCombinedName () {
|
||||||
|
|
||||||
return $"{(CollectionType != null ? $"{CollectionType.Name}." : "")}{Name ?? "Unnamed"}";
|
return $"{(CollectionType != null ? $"{CollectionType.Name}." : "")}{Name ?? "Unnamed"}";
|
||||||
|
|||||||
104
MewtocolTests/TestClient.cs
Normal file
104
MewtocolTests/TestClient.cs
Normal file
@@ -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<ExpectedTestData> 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; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -25,7 +25,6 @@ namespace MewtocolTests {
|
|||||||
new NRegister<int>(50),
|
new NRegister<int>(50),
|
||||||
new NRegister<uint>(50),
|
new NRegister<uint>(50),
|
||||||
new NRegister<float>(50),
|
new NRegister<float>(50),
|
||||||
new NRegister<BitArray>(50),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
List<string> expcectedIdents = new List<string> {
|
List<string> expcectedIdents = new List<string> {
|
||||||
@@ -35,7 +34,6 @@ namespace MewtocolTests {
|
|||||||
"D0005000051", //double word register
|
"D0005000051", //double word register
|
||||||
"D0005000051", //double word register
|
"D0005000051", //double word register
|
||||||
"D0005000051", //double word register
|
"D0005000051", //double word register
|
||||||
"D0005000051", //double word register
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//test mewtocol idents
|
//test mewtocol idents
|
||||||
|
|||||||
Reference in New Issue
Block a user