mirror of
https://github.com/S7NetPlus/s7netplus.git
synced 2026-02-17 14:28:25 +08:00
Merge branch 'develop' into test-workflow
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
|
||||
using S7.Net.Types;
|
||||
|
||||
namespace S7.Net.UnitTest.Helpers
|
||||
{
|
||||
class TestClass
|
||||
@@ -51,5 +53,16 @@ namespace S7.Net.UnitTest.Helpers
|
||||
/// DB1.DBD16
|
||||
/// </summary>
|
||||
public ushort DWordVariable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// DB1.DBX20.0
|
||||
/// </summary>
|
||||
[S7String(S7StringType.S7WString, 10)]
|
||||
public string WStringVariable { get; set; }
|
||||
/// <summary>
|
||||
/// DB1.DBX44.0
|
||||
/// </summary>
|
||||
[S7String(S7StringType.S7String, 10)]
|
||||
public string StringVariable { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using S7.Net.Types;
|
||||
using S7.UnitTest.Helpers;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -154,7 +155,9 @@ namespace S7.Net.UnitTest
|
||||
IntVariable = -15000,
|
||||
LRealVariable = -154.789,
|
||||
RealVariable = -154.789f,
|
||||
DWordVariable = 850
|
||||
DWordVariable = 850,
|
||||
WStringVariable = "ÄÜÉÊéà",
|
||||
StringVariable = "Hallo"
|
||||
};
|
||||
|
||||
await plc.WriteClassAsync(tc, DB2);
|
||||
@@ -168,6 +171,8 @@ namespace S7.Net.UnitTest
|
||||
Assert.AreEqual(tc.LRealVariable, tc2.LRealVariable);
|
||||
Assert.AreEqual(tc.RealVariable, tc2.RealVariable);
|
||||
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
|
||||
Assert.AreEqual(tc.WStringVariable, tc2.WStringVariable);
|
||||
Assert.AreEqual(tc.StringVariable, tc2.StringVariable);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -580,7 +585,9 @@ namespace S7.Net.UnitTest
|
||||
IntVariable = -15000,
|
||||
LRealVariable = -154.789,
|
||||
RealVariable = -154.789f,
|
||||
DWordVariable = 850
|
||||
DWordVariable = 850,
|
||||
WStringVariable = "ÄÜÉÊéà",
|
||||
StringVariable = "Hallo"
|
||||
};
|
||||
|
||||
await plc.WriteClassAsync(tc, DB2);
|
||||
@@ -628,7 +635,10 @@ namespace S7.Net.UnitTest
|
||||
IntVariable = -15000,
|
||||
LRealVariable = -154.789,
|
||||
RealVariable = -154.789f,
|
||||
DWordVariable = 850
|
||||
DWordVariable = 850,
|
||||
WStringVariable = "ÄÜÉÊéà",
|
||||
StringVariable = "Hallo"
|
||||
|
||||
};
|
||||
|
||||
await plc.WriteClassAsync(tc, DB2);
|
||||
@@ -646,6 +656,9 @@ namespace S7.Net.UnitTest
|
||||
Assert.AreEqual(Math.Round(tc2.LRealVariable, 3), Math.Round(tc2Generic.LRealVariable, 3));
|
||||
Assert.AreEqual(tc2.RealVariable, tc2Generic.RealVariable);
|
||||
Assert.AreEqual(tc2.DWordVariable, tc2Generic.DWordVariable);
|
||||
Assert.AreEqual(tc2.WStringVariable, tc2Generic.WStringVariable);
|
||||
Assert.AreEqual(tc2.StringVariable, tc2Generic.StringVariable);
|
||||
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -671,7 +684,9 @@ namespace S7.Net.UnitTest
|
||||
IntVariable = -15000,
|
||||
LRealVariable = -154.789,
|
||||
RealVariable = -154.789f,
|
||||
DWordVariable = 850
|
||||
DWordVariable = 850,
|
||||
WStringVariable = "ÄÜÉÊéà",
|
||||
StringVariable = "Hallo"
|
||||
};
|
||||
|
||||
await plc.WriteClassAsync(tc, DB2);
|
||||
@@ -686,6 +701,8 @@ namespace S7.Net.UnitTest
|
||||
Assert.AreEqual(Math.Round(tc2Generic.LRealVariable, 3), Math.Round(tc2GenericWithClassFactory.LRealVariable, 3));
|
||||
Assert.AreEqual(tc2Generic.RealVariable, tc2GenericWithClassFactory.RealVariable);
|
||||
Assert.AreEqual(tc2Generic.DWordVariable, tc2GenericWithClassFactory.DWordVariable);
|
||||
Assert.AreEqual(tc2Generic.WStringVariable, tc2GenericWithClassFactory.WStringVariable);
|
||||
Assert.AreEqual(tc2Generic.StringVariable, tc2GenericWithClassFactory.StringVariable);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -792,7 +809,9 @@ namespace S7.Net.UnitTest
|
||||
IntVariable = -15000,
|
||||
LRealVariable = -154.789,
|
||||
RealVariable = -154.789f,
|
||||
DWordVariable = 850
|
||||
DWordVariable = 850,
|
||||
WStringVariable = "ÄÜÉÊéà",
|
||||
StringVariable = "Hallo"
|
||||
};
|
||||
plc.WriteClass(tc, DB2);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using S7.Net.UnitTest.Helpers;
|
||||
using S7.Net.Types;
|
||||
using S7.UnitTest.Helpers;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -183,6 +184,9 @@ namespace S7.Net.UnitTest
|
||||
tc.LRealVariable = -154.789;
|
||||
tc.RealVariable = -154.789f;
|
||||
tc.DWordVariable = 850;
|
||||
tc.WStringVariable = "ÄÜÉÊéà";
|
||||
tc.StringVariable = "Hallo";
|
||||
|
||||
plc.WriteClass(tc, DB2);
|
||||
TestClass tc2 = new TestClass();
|
||||
// Values that are read from a class are stored inside the class itself, that is passed by reference
|
||||
@@ -194,6 +198,8 @@ namespace S7.Net.UnitTest
|
||||
Assert.AreEqual(tc.LRealVariable, tc2.LRealVariable);
|
||||
Assert.AreEqual(tc.RealVariable, tc2.RealVariable);
|
||||
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
|
||||
Assert.AreEqual(tc.WStringVariable, tc2.WStringVariable);
|
||||
Assert.AreEqual(tc.StringVariable, tc2.StringVariable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -577,6 +583,8 @@ namespace S7.Net.UnitTest
|
||||
tc.LRealVariable = -154.789;
|
||||
tc.RealVariable = -154.789f;
|
||||
tc.DWordVariable = 850;
|
||||
tc.WStringVariable = "ÄÜÉÊéà";
|
||||
tc.StringVariable = "Hallo";
|
||||
|
||||
plc.WriteClass(tc, DB2);
|
||||
|
||||
@@ -622,6 +630,8 @@ namespace S7.Net.UnitTest
|
||||
tc.LRealVariable = -154.789;
|
||||
tc.RealVariable = -154.789f;
|
||||
tc.DWordVariable = 850;
|
||||
tc.WStringVariable = "ÄÜÉÊéà";
|
||||
tc.StringVariable = "Hallo";
|
||||
|
||||
plc.WriteClass(tc, DB2);
|
||||
|
||||
@@ -637,6 +647,8 @@ namespace S7.Net.UnitTest
|
||||
Assert.AreEqual(Math.Round(tc2.LRealVariable, 3), Math.Round(tc2Generic.LRealVariable, 3));
|
||||
Assert.AreEqual(tc2.RealVariable, tc2Generic.RealVariable);
|
||||
Assert.AreEqual(tc2.DWordVariable, tc2Generic.DWordVariable);
|
||||
Assert.AreEqual(tc2.WStringVariable, tc2Generic.WStringVariable);
|
||||
Assert.AreEqual(tc2.StringVariable, tc2Generic.StringVariable);
|
||||
}
|
||||
|
||||
[TestMethod, ExpectedException(typeof(PlcException))]
|
||||
@@ -665,6 +677,8 @@ namespace S7.Net.UnitTest
|
||||
tc.LRealVariable = -154.789;
|
||||
tc.RealVariable = -154.789f;
|
||||
tc.DWordVariable = 850;
|
||||
tc.WStringVariable = "ÄÜÉÊéà";
|
||||
tc.StringVariable = "Hallo";
|
||||
|
||||
plc.WriteClass(tc, DB2);
|
||||
|
||||
@@ -679,6 +693,8 @@ namespace S7.Net.UnitTest
|
||||
Assert.AreEqual(Math.Round(tc2Generic.LRealVariable, 3), Math.Round(tc2GenericWithClassFactory.LRealVariable, 3));
|
||||
Assert.AreEqual(tc2Generic.RealVariable, tc2GenericWithClassFactory.RealVariable);
|
||||
Assert.AreEqual(tc2Generic.DWordVariable, tc2GenericWithClassFactory.DWordVariable);
|
||||
Assert.AreEqual(tc2Generic.WStringVariable, tc2GenericWithClassFactory.WStringVariable);
|
||||
Assert.AreEqual(tc2Generic.StringVariable, tc2GenericWithClassFactory.StringVariable);
|
||||
}
|
||||
|
||||
[TestMethod, ExpectedException(typeof(PlcException))]
|
||||
@@ -837,6 +853,9 @@ namespace S7.Net.UnitTest
|
||||
tc.LRealVariable = -154.789;
|
||||
tc.RealVariable = -154.789f;
|
||||
tc.DWordVariable = 850;
|
||||
tc.WStringVariable = "ÄÜÉÊéà";
|
||||
tc.StringVariable = "Hallo";
|
||||
|
||||
plc.WriteClass(tc, DB2);
|
||||
|
||||
int expectedReadBytes = (int)Types.Class.GetClassSize(tc);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
@@ -25,7 +26,7 @@ namespace S7.Net.Types
|
||||
|
||||
}
|
||||
|
||||
private static double GetIncreasedNumberOfBytes(double numBytes, Type type)
|
||||
private static double GetIncreasedNumberOfBytes(double numBytes, Type type, PropertyInfo? propertyInfo)
|
||||
{
|
||||
switch (type.Name)
|
||||
{
|
||||
@@ -38,30 +39,30 @@ namespace S7.Net.Types
|
||||
break;
|
||||
case "Int16":
|
||||
case "UInt16":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
IncrementToEven(ref numBytes);
|
||||
numBytes += 2;
|
||||
break;
|
||||
case "Int32":
|
||||
case "UInt32":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
IncrementToEven(ref numBytes);
|
||||
numBytes += 4;
|
||||
break;
|
||||
case "Single":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
IncrementToEven(ref numBytes);
|
||||
numBytes += 4;
|
||||
break;
|
||||
case "Double":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
IncrementToEven(ref numBytes);
|
||||
numBytes += 8;
|
||||
break;
|
||||
case "String":
|
||||
S7StringAttribute? attribute = propertyInfo?.GetCustomAttributes<S7StringAttribute>().SingleOrDefault();
|
||||
if (attribute == default(S7StringAttribute))
|
||||
throw new ArgumentException("Please add S7StringAttribute to the string field");
|
||||
|
||||
IncrementToEven(ref numBytes);
|
||||
numBytes += attribute.ReservedLengthInBytes;
|
||||
break;
|
||||
default:
|
||||
var propertyClass = Activator.CreateInstance(type);
|
||||
numBytes = GetClassSize(propertyClass, numBytes, true);
|
||||
@@ -93,12 +94,12 @@ namespace S7.Net.Types
|
||||
IncrementToEven(ref numBytes);
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
numBytes = GetIncreasedNumberOfBytes(numBytes, elementType);
|
||||
numBytes = GetIncreasedNumberOfBytes(numBytes, elementType, property);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
numBytes = GetIncreasedNumberOfBytes(numBytes, property.PropertyType);
|
||||
numBytes = GetIncreasedNumberOfBytes(numBytes, property.PropertyType, property);
|
||||
}
|
||||
}
|
||||
if (false == isInnerProperty)
|
||||
@@ -111,7 +112,7 @@ namespace S7.Net.Types
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
private static object? GetPropertyValue(Type propertyType, byte[] bytes, ref double numBytes)
|
||||
private static object? GetPropertyValue(Type propertyType, PropertyInfo? propertyInfo, byte[] bytes, ref double numBytes)
|
||||
{
|
||||
object? value = null;
|
||||
|
||||
@@ -133,26 +134,20 @@ namespace S7.Net.Types
|
||||
numBytes++;
|
||||
break;
|
||||
case "Int16":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
IncrementToEven(ref numBytes);
|
||||
// hier auswerten
|
||||
ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]);
|
||||
value = source.ConvertToShort();
|
||||
numBytes += 2;
|
||||
break;
|
||||
case "UInt16":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
IncrementToEven(ref numBytes);
|
||||
// hier auswerten
|
||||
value = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]);
|
||||
numBytes += 2;
|
||||
break;
|
||||
case "Int32":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
IncrementToEven(ref numBytes);
|
||||
// hier auswerten
|
||||
uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3],
|
||||
bytes[(int)numBytes + 2],
|
||||
@@ -162,9 +157,7 @@ namespace S7.Net.Types
|
||||
numBytes += 4;
|
||||
break;
|
||||
case "UInt32":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
IncrementToEven(ref numBytes);
|
||||
// hier auswerten
|
||||
value = DWord.FromBytes(
|
||||
bytes[(int)numBytes],
|
||||
@@ -174,9 +167,7 @@ namespace S7.Net.Types
|
||||
numBytes += 4;
|
||||
break;
|
||||
case "Single":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
IncrementToEven(ref numBytes);
|
||||
// hier auswerten
|
||||
value = Real.FromByteArray(
|
||||
new byte[] {
|
||||
@@ -187,15 +178,31 @@ namespace S7.Net.Types
|
||||
numBytes += 4;
|
||||
break;
|
||||
case "Double":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
IncrementToEven(ref numBytes);
|
||||
var buffer = new byte[8];
|
||||
Array.Copy(bytes, (int)numBytes, buffer, 0, 8);
|
||||
// hier auswerten
|
||||
value = LReal.FromByteArray(buffer);
|
||||
numBytes += 8;
|
||||
break;
|
||||
case "String":
|
||||
S7StringAttribute? attribute = propertyInfo?.GetCustomAttributes<S7StringAttribute>().SingleOrDefault();
|
||||
if (attribute == default(S7StringAttribute))
|
||||
throw new ArgumentException("Please add S7StringAttribute to the string field");
|
||||
|
||||
IncrementToEven(ref numBytes);
|
||||
|
||||
// get the value
|
||||
var sData = new byte[attribute.ReservedLengthInBytes];
|
||||
Array.Copy(bytes, (int)numBytes, sData, 0, sData.Length);
|
||||
value = attribute.Type switch
|
||||
{
|
||||
S7StringType.S7String => S7String.FromByteArray(sData),
|
||||
S7StringType.S7WString => S7WString.FromByteArray(sData),
|
||||
_ => throw new ArgumentException("Please use a valid string type for the S7StringAttribute")
|
||||
};
|
||||
numBytes += sData.Length;
|
||||
break;
|
||||
default:
|
||||
var propClass = Activator.CreateInstance(propertyType);
|
||||
numBytes = FromBytes(propClass, bytes, numBytes);
|
||||
@@ -227,7 +234,7 @@ namespace S7.Net.Types
|
||||
for (int i = 0; i < array.Length && numBytes < bytes.Length; i++)
|
||||
{
|
||||
array.SetValue(
|
||||
GetPropertyValue(elementType, bytes, ref numBytes),
|
||||
GetPropertyValue(elementType, property, bytes, ref numBytes),
|
||||
i);
|
||||
}
|
||||
}
|
||||
@@ -235,7 +242,7 @@ namespace S7.Net.Types
|
||||
{
|
||||
property.SetValue(
|
||||
sourceClass,
|
||||
GetPropertyValue(property.PropertyType, bytes, ref numBytes),
|
||||
GetPropertyValue(property.PropertyType, property, bytes, ref numBytes),
|
||||
null);
|
||||
}
|
||||
}
|
||||
@@ -243,7 +250,7 @@ namespace S7.Net.Types
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
private static double SetBytesFromProperty(object propertyValue, byte[] bytes, double numBytes)
|
||||
private static double SetBytesFromProperty(object propertyValue, PropertyInfo? propertyInfo, byte[] bytes, double numBytes)
|
||||
{
|
||||
int bytePos = 0;
|
||||
int bitPos = 0;
|
||||
@@ -285,6 +292,18 @@ namespace S7.Net.Types
|
||||
case "Double":
|
||||
bytes2 = LReal.ToByteArray((double)propertyValue);
|
||||
break;
|
||||
case "String":
|
||||
S7StringAttribute? attribute = propertyInfo?.GetCustomAttributes<S7StringAttribute>().SingleOrDefault();
|
||||
if (attribute == default(S7StringAttribute))
|
||||
throw new ArgumentException("Please add S7StringAttribute to the string field");
|
||||
|
||||
bytes2 = attribute.Type switch
|
||||
{
|
||||
S7StringType.S7String => S7String.ToByteArray((string)propertyValue, attribute.ReservedLength),
|
||||
S7StringType.S7WString => S7WString.ToByteArray((string)propertyValue, attribute.ReservedLength),
|
||||
_ => throw new ArgumentException("Please use a valid string type for the S7StringAttribute")
|
||||
};
|
||||
break;
|
||||
default:
|
||||
numBytes = ToBytes(propertyValue, bytes, numBytes);
|
||||
break;
|
||||
@@ -320,12 +339,12 @@ namespace S7.Net.Types
|
||||
Type elementType = property.PropertyType.GetElementType();
|
||||
for (int i = 0; i < array.Length && numBytes < bytes.Length; i++)
|
||||
{
|
||||
numBytes = SetBytesFromProperty(array.GetValue(i), bytes, numBytes);
|
||||
numBytes = SetBytesFromProperty(array.GetValue(i), property, bytes, numBytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
numBytes = SetBytesFromProperty(property.GetValue(sourceClass, null), bytes, numBytes);
|
||||
numBytes = SetBytesFromProperty(property.GetValue(sourceClass, null), property, bytes, numBytes);
|
||||
}
|
||||
}
|
||||
return numBytes;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
|
||||
public sealed class S7StringAttribute : Attribute
|
||||
{
|
||||
private readonly S7StringType type;
|
||||
|
||||
Reference in New Issue
Block a user