mirror of
https://github.com/S7NetPlus/s7netplus.git
synced 2026-02-17 22:38:27 +08:00
Merge pull request #161 from mycroes/throw-on-error
Replace LastErrorCode and LastErrorString with exceptions
This commit is contained in:
@@ -226,10 +226,8 @@ namespace S7.Net.UnitTest
|
||||
IntVariable111 = 201
|
||||
};
|
||||
plc.WriteStruct(tc, DB2);
|
||||
Assert.AreEqual(ErrorCode.NoError, plc.LastErrorCode);
|
||||
// Values that are read from a struct are stored in a new struct, returned by the funcion ReadStruct
|
||||
TestLongStruct tc2 = (TestLongStruct)await plc.ReadStructAsync(typeof(TestLongStruct), DB2);
|
||||
Assert.AreEqual(ErrorCode.NoError, plc.LastErrorCode);
|
||||
Assert.AreEqual(tc.IntVariable0, tc2.IntVariable0);
|
||||
Assert.AreEqual(tc.IntVariable1, tc2.IntVariable1);
|
||||
Assert.AreEqual(tc.IntVariable10, tc2.IntVariable10);
|
||||
@@ -292,11 +290,9 @@ namespace S7.Net.UnitTest
|
||||
IntVariable111 = 201
|
||||
};
|
||||
await plc.WriteClassAsync(tc, DB2);
|
||||
Assert.AreEqual(ErrorCode.NoError, plc.LastErrorCode);
|
||||
// Values that are read from a struct are stored in a new struct, returned by the funcion ReadStruct
|
||||
TestLongClass tc2 = new TestLongClass();
|
||||
await plc.ReadClassAsync(tc2, DB2);
|
||||
Assert.AreEqual(ErrorCode.NoError, plc.LastErrorCode);
|
||||
Assert.AreEqual(tc.IntVariable0, tc2.IntVariable0);
|
||||
Assert.AreEqual(tc.IntVariable1, tc2.IntVariable1);
|
||||
Assert.AreEqual(tc.IntVariable10, tc2.IntVariable10);
|
||||
@@ -571,7 +567,7 @@ namespace S7.Net.UnitTest
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(NullReferenceException))]
|
||||
public async Task Test_Async_ReadBytesThrowsExceptionIfPlcIsNotConnected()
|
||||
public async Task Test_Async_ReadBytesReturnsNullIfPlcIsNotConnected()
|
||||
{
|
||||
using (var notConnectedPlc = new Plc(CpuType.S7300, "255.255.255.255", 0, 0))
|
||||
{
|
||||
@@ -831,11 +827,9 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
double test_value = 55.66;
|
||||
await plc.WriteAsync("DB1.DBD0", test_value);
|
||||
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Write Double");
|
||||
var helper = await plc.ReadAsync("DB1.DBD0");
|
||||
double test_value2 = Conversion.ConvertToDouble((uint)helper);
|
||||
|
||||
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Read Double");
|
||||
Assert.AreEqual(test_value, test_value2, 0.01, "Compare Write/Read"); //Need delta here because S7 only has 32 bit reals
|
||||
}
|
||||
|
||||
@@ -844,11 +838,9 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
float test_value = 55.6632f;
|
||||
await plc.WriteAsync("DB1.DBD0", test_value);
|
||||
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Write Single");
|
||||
var helper = await plc.ReadAsync("DB1.DBD0");
|
||||
float test_value2 = Conversion.ConvertToFloat((uint)helper);
|
||||
|
||||
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Read Single");
|
||||
Assert.AreEqual(test_value, test_value2, "Compare Write/Read"); //No delta, datatype matches
|
||||
}
|
||||
|
||||
|
||||
@@ -81,8 +81,14 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
if (plc.IsConnected == false)
|
||||
{
|
||||
var error = plc.Open();
|
||||
Assert.AreEqual(ErrorCode.NoError, error, "If you have s7 installed you must close s7oiehsx64 service.");
|
||||
try
|
||||
{
|
||||
plc.Open();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("If you have s7 installed you must close s7oiehsx64 service.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,10 +263,8 @@ namespace S7.Net.UnitTest
|
||||
tc.IntVariable110 = 200;
|
||||
tc.IntVariable111 = 201;
|
||||
plc.WriteStruct(tc, DB2);
|
||||
Assert.AreEqual(ErrorCode.NoError, plc.LastErrorCode);
|
||||
// Values that are read from a struct are stored in a new struct, returned by the funcion ReadStruct
|
||||
TestLongStruct tc2 = (TestLongStruct)plc.ReadStruct(typeof(TestLongStruct), DB2);
|
||||
Assert.AreEqual(ErrorCode.NoError, plc.LastErrorCode);
|
||||
Assert.AreEqual(tc.IntVariable0, tc2.IntVariable0);
|
||||
Assert.AreEqual(tc.IntVariable1, tc2.IntVariable1);
|
||||
Assert.AreEqual(tc.IntVariable10, tc2.IntVariable10);
|
||||
@@ -321,11 +325,9 @@ namespace S7.Net.UnitTest
|
||||
tc.IntVariable110 = 200;
|
||||
tc.IntVariable111 = 201;
|
||||
plc.WriteClass(tc, DB2);
|
||||
Assert.AreEqual(ErrorCode.NoError, plc.LastErrorCode);
|
||||
// Values that are read from a struct are stored in a new struct, returned by the funcion ReadStruct
|
||||
TestLongClass tc2 = new TestLongClass();
|
||||
plc.ReadClass(tc2, DB2);
|
||||
Assert.AreEqual(ErrorCode.NoError, plc.LastErrorCode);
|
||||
Assert.AreEqual(tc.IntVariable0, tc2.IntVariable0);
|
||||
Assert.AreEqual(tc.IntVariable1, tc2.IntVariable1);
|
||||
Assert.AreEqual(tc.IntVariable10, tc2.IntVariable10);
|
||||
@@ -596,19 +598,14 @@ namespace S7.Net.UnitTest
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void T13_ReadBytesReturnsEmptyArrayIfPlcIsNotConnected()
|
||||
[TestMethod, ExpectedException(typeof(PlcException))]
|
||||
public void T13_ReadBytesThrowsIfPlcIsNotConnected()
|
||||
{
|
||||
using (var notConnectedPlc = new Plc(CpuType.S7300, "255.255.255.255", 0, 0))
|
||||
{
|
||||
Assert.IsFalse(notConnectedPlc.IsConnected);
|
||||
|
||||
int expectedReadBytes = 0; // 0 bytes, because no connection was established
|
||||
|
||||
TestClass tc = new TestClass();
|
||||
int actualReadBytes = notConnectedPlc.ReadClass(tc, DB2);
|
||||
|
||||
Assert.AreEqual(expectedReadBytes, actualReadBytes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,8 +639,8 @@ namespace S7.Net.UnitTest
|
||||
Assert.AreEqual(tc2.DWordVariable, tc2Generic.DWordVariable);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void T15_ReadClassWithGenericReturnsNullIfPlcIsNotConnected()
|
||||
[TestMethod, ExpectedException(typeof(PlcException))]
|
||||
public void T15_ReadClassWithGenericThrowsIfPlcIsNotConnected()
|
||||
{
|
||||
using (var notConnectedPlc = new Plc(CpuType.S7300, "255.255.255.255", 0, 0))
|
||||
{
|
||||
@@ -684,8 +681,8 @@ namespace S7.Net.UnitTest
|
||||
Assert.AreEqual(tc2Generic.DWordVariable, tc2GenericWithClassFactory.DWordVariable);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void T17_ReadClassWithGenericAndClassFactoryReturnsNullIfPlcIsNotConnected()
|
||||
[TestMethod, ExpectedException(typeof(PlcException))]
|
||||
public void T17_ReadClassWithGenericAndClassFactoryThrowsIfPlcIsNotConnected()
|
||||
{
|
||||
using (var notConnectedPlc = new Plc(CpuType.S7300, "255.255.255.255", 0, 0))
|
||||
{
|
||||
@@ -697,8 +694,8 @@ namespace S7.Net.UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void T18_ReadStructReturnsNullIfPlcIsNotConnected()
|
||||
[TestMethod, ExpectedException(typeof(PlcException))]
|
||||
public void T18_ReadStructThrowsIfPlcIsNotConnected()
|
||||
{
|
||||
using (var notConnectedPlc = new Plc(CpuType.S7300, "255.255.255.255", 0, 0))
|
||||
{
|
||||
@@ -739,8 +736,8 @@ namespace S7.Net.UnitTest
|
||||
Assert.AreEqual(ts2.DWordVariable, ts2Generic.DWordVariable);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void T20_ReadStructWithGenericReturnsNullIfPlcIsNotConnected()
|
||||
[TestMethod, ExpectedException(typeof(PlcException))]
|
||||
public void T20_ReadStructThrowsIfPlcIsNotConnected()
|
||||
{
|
||||
using (var notConnectedPlc = new Plc(CpuType.S7300, "255.255.255.255", 0, 0))
|
||||
{
|
||||
@@ -883,11 +880,9 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
double test_value = 55.66;
|
||||
plc.Write("DB1.DBD0", test_value);
|
||||
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Write Double");
|
||||
var helper = plc.Read("DB1.DBD0");
|
||||
double test_value2 = Conversion.ConvertToDouble((uint)helper);
|
||||
|
||||
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Read Double");
|
||||
Assert.AreEqual(test_value, test_value2, 0.01, "Compare Write/Read"); //Need delta here because S7 only has 32 bit reals
|
||||
}
|
||||
|
||||
@@ -929,19 +924,17 @@ namespace S7.Net.UnitTest
|
||||
Assert.AreEqual(tc.Bool1, tc2.Bool1);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void T29_Read_Write_ExceptionHandlingWhenPlcIsNotReachable()
|
||||
[TestMethod, ExpectedException(typeof(PlcException))]
|
||||
public void T29_Read_Write_ThrowsWhenPlcIsNotReachable()
|
||||
{
|
||||
// leave plc Open
|
||||
S7TestServer.Stop();
|
||||
|
||||
double test_value = 55.66;
|
||||
plc.Write("DB1.DBD0", test_value);
|
||||
Assert.AreEqual(plc.LastErrorCode, ErrorCode.WriteData, "No Write Error.");
|
||||
|
||||
var helper = plc.Read("DB1.DBD0");
|
||||
Assert.AreEqual(helper, null, "Value in Read.");
|
||||
Assert.AreEqual(plc.LastErrorCode, ErrorCode.ReadData, "No Read Error.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -949,11 +942,9 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
float test_value = 55.6632f;
|
||||
plc.Write("DB1.DBD0", test_value);
|
||||
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Write Single");
|
||||
var helper = plc.Read("DB1.DBD0");
|
||||
float test_value2 = Conversion.ConvertToFloat((uint)helper);
|
||||
|
||||
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Read Single");
|
||||
Assert.AreEqual(test_value, test_value2, "Compare Write/Read"); //No delta, datatype matches
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,15 @@ namespace S7.Net
|
||||
//TODO: Fix This
|
||||
get
|
||||
{
|
||||
return Connect() == ErrorCode.NoError;
|
||||
try
|
||||
{
|
||||
Connect();
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,16 +80,6 @@ namespace S7.Net
|
||||
catch { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the last error registered when executing a function
|
||||
/// </summary>
|
||||
public string LastErrorString { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the last error code registered when executing a function
|
||||
/// </summary>
|
||||
public ErrorCode LastErrorCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a PLC object with all the parameters needed for connections.
|
||||
|
||||
@@ -312,15 +312,6 @@ namespace S7.Net
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="LastErrorCode"/> to <see cref="ErrorCode.NoError"/> and <see cref="LastErrorString"/> to <see cref="string.Empty"/>.
|
||||
/// </summary>
|
||||
public void ClearLastError()
|
||||
{
|
||||
LastErrorCode = ErrorCode.NoError;
|
||||
LastErrorString = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a S7 <see cref="VarType"/> (Bool, Word, DWord, etc.), it returns how many bytes to read.
|
||||
/// </summary>
|
||||
@@ -367,7 +358,7 @@ namespace S7.Net
|
||||
{
|
||||
// check for Return Code = Success
|
||||
if (s7data[offset] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
throw new PlcException(ErrorCode.WrongNumberReceivedBytes);
|
||||
|
||||
// to Data bytes
|
||||
offset += 4;
|
||||
|
||||
@@ -14,10 +14,9 @@ namespace S7.Net
|
||||
public partial class Plc
|
||||
{
|
||||
/// <summary>
|
||||
/// Open a <see cref="Socket"/> and connects to the PLC, sending all the corrected package
|
||||
/// and returning if the connection was successful (<see cref="ErrorCode.NoError"/>) of it was wrong.
|
||||
/// Connects to the PLC and performs a COTP ConnectionRequest and S7 CommunicationSetup.
|
||||
/// </summary>
|
||||
/// <returns>Returns ErrorCode.NoError if the connection was successful, otherwise check the ErrorCode</returns>
|
||||
/// <returns>A task that represents the asynchronous open operation.</returns>
|
||||
public async Task OpenAsync()
|
||||
{
|
||||
await ConnectAsync();
|
||||
@@ -227,19 +226,17 @@ namespace S7.Net
|
||||
|
||||
var s7data = await COTP.TSDU.ReadAsync(stream); //TODO use Async
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
throw new PlcException(ErrorCode.WrongNumberReceivedBytes);
|
||||
|
||||
ParseDataIntoDataItems(s7data, dataItems);
|
||||
}
|
||||
catch (SocketException socketException)
|
||||
{
|
||||
LastErrorCode = ErrorCode.ReadData;
|
||||
LastErrorString = socketException.Message;
|
||||
throw new PlcException(ErrorCode.ReadData, socketException);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
LastErrorCode = ErrorCode.ReadData;
|
||||
LastErrorString = exc.Message;
|
||||
throw new PlcException(ErrorCode.ReadData, exc);
|
||||
}
|
||||
return dataItems;
|
||||
}
|
||||
@@ -252,8 +249,8 @@ namespace S7.Net
|
||||
/// <param name="db">Address of the memory area (if you want to read DB1, this is set to 1). This must be set also for other memory area types: counters, timers,etc.</param>
|
||||
/// <param name="startByteAdr">Start byte address. If you want to write DB1.DBW200, this is 200.</param>
|
||||
/// <param name="value">Bytes to write. If more than 200, multiple requests will be made.</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public async Task<ErrorCode> WriteBytesAsync(DataType dataType, int db, int startByteAdr, byte[] value)
|
||||
/// <returns>A task that represents the asynchronous write operation.</returns>
|
||||
public async Task WriteBytesAsync(DataType dataType, int db, int startByteAdr, byte[] value)
|
||||
{
|
||||
int localIndex = 0;
|
||||
int count = value.Length;
|
||||
@@ -263,15 +260,10 @@ namespace S7.Net
|
||||
//Snap7 seems to choke on PDU sizes above 256 even if snap7
|
||||
//replies with bigger PDU size in connection setup.
|
||||
var maxToWrite = (int)Math.Min(count, 200);
|
||||
ErrorCode lastError = await WriteBytesWithASingleRequestAsync(dataType, db, startByteAdr + localIndex, value.Skip(localIndex).Take(maxToWrite).ToArray());
|
||||
if (lastError != ErrorCode.NoError)
|
||||
{
|
||||
return lastError;
|
||||
}
|
||||
await WriteBytesWithASingleRequestAsync(dataType, db, startByteAdr + localIndex, value.Skip(localIndex).Take(maxToWrite).ToArray());
|
||||
count -= maxToWrite;
|
||||
localIndex += maxToWrite;
|
||||
}
|
||||
return ErrorCode.NoError;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -282,19 +274,13 @@ namespace S7.Net
|
||||
/// <param name="startByteAdr">Start byte address. If you want to write DB1.DBW200, this is 200.</param>
|
||||
/// <param name="bitAdr">The address of the bit. (0-7)</param>
|
||||
/// <param name="value">Bytes to write. If more than 200, multiple requests will be made.</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public async Task<ErrorCode> WriteBitAsync(DataType dataType, int db, int startByteAdr, int bitAdr, bool value)
|
||||
/// <returns>A task that represents the asynchronous write operation.</returns>
|
||||
public async Task WriteBitAsync(DataType dataType, int db, int startByteAdr, int bitAdr, bool value)
|
||||
{
|
||||
if (bitAdr < 0 || bitAdr > 7)
|
||||
throw new InvalidAddressException(string.Format("Addressing Error: You can only reference bitwise locations 0-7. Address {0} is invalid", bitAdr));
|
||||
|
||||
ErrorCode lastError = await WriteBitWithASingleRequestAsync(dataType, db, startByteAdr, bitAdr, value);
|
||||
if (lastError != ErrorCode.NoError)
|
||||
{
|
||||
return lastError;
|
||||
}
|
||||
|
||||
return ErrorCode.NoError;
|
||||
await WriteBitWithASingleRequestAsync(dataType, db, startByteAdr, bitAdr, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -305,13 +291,13 @@ namespace S7.Net
|
||||
/// <param name="startByteAdr">Start byte address. If you want to write DB1.DBW200, this is 200.</param>
|
||||
/// <param name="bitAdr">The address of the bit. (0-7)</param>
|
||||
/// <param name="value">Bytes to write. If more than 200, multiple requests will be made.</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public async Task<ErrorCode> WriteBitAsync(DataType dataType, int db, int startByteAdr, int bitAdr, int value)
|
||||
/// <returns>A task that represents the asynchronous write operation.</returns>
|
||||
public async Task WriteBitAsync(DataType dataType, int db, int startByteAdr, int bitAdr, int value)
|
||||
{
|
||||
if (value < 0 || value > 1)
|
||||
throw new ArgumentException("Value must be 0 or 1", nameof(value));
|
||||
|
||||
return await WriteBitAsync(dataType, db, startByteAdr, bitAdr, value == 1);
|
||||
await WriteBitAsync(dataType, db, startByteAdr, bitAdr, value == 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -324,26 +310,29 @@ namespace S7.Net
|
||||
/// <param name="startByteAdr">Start byte address. If you want to read DB1.DBW200, this is 200.</param>
|
||||
/// <param name="value">Bytes to write. The lenght of this parameter can't be higher than 200. If you need more, use recursion.</param>
|
||||
/// <param name="bitAdr">The address of the bit. (0-7)</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public async Task<ErrorCode> WriteAsync(DataType dataType, int db, int startByteAdr, object value, int bitAdr = -1)
|
||||
/// <returns>A task that represents the asynchronous write operation.</returns>
|
||||
public async Task WriteAsync(DataType dataType, int db, int startByteAdr, object value, int bitAdr = -1)
|
||||
{
|
||||
if (bitAdr != -1)
|
||||
{
|
||||
//Must be writing a bit value as bitAdr is specified
|
||||
if (value is bool)
|
||||
{
|
||||
return await WriteBitAsync(dataType, db, startByteAdr, bitAdr, (bool)value);
|
||||
await WriteBitAsync(dataType, db, startByteAdr, bitAdr, (bool) value);
|
||||
}
|
||||
else if (value is int intValue)
|
||||
{
|
||||
if (intValue < 0 || intValue > 7)
|
||||
throw new ArgumentOutOfRangeException(string.Format("Addressing Error: You can only reference bitwise locations 0-7. Address {0} is invalid", bitAdr), nameof(bitAdr));
|
||||
throw new ArgumentOutOfRangeException(
|
||||
string.Format(
|
||||
"Addressing Error: You can only reference bitwise locations 0-7. Address {0} is invalid",
|
||||
bitAdr), nameof(bitAdr));
|
||||
|
||||
return await WriteBitAsync(dataType, db, startByteAdr, bitAdr, intValue == 1);
|
||||
await WriteBitAsync(dataType, db, startByteAdr, bitAdr, intValue == 1);
|
||||
}
|
||||
throw new ArgumentException("Value must be a bool or an int to write a bit", nameof(value));
|
||||
else throw new ArgumentException("Value must be a bool or an int to write a bit", nameof(value));
|
||||
}
|
||||
return await WriteBytesAsync(dataType, db, startByteAdr, Serialization.SerializeValue(value));
|
||||
else await WriteBytesAsync(dataType, db, startByteAdr, Serialization.SerializeValue(value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -352,11 +341,11 @@ namespace S7.Net
|
||||
/// </summary>
|
||||
/// <param name="variable">Input strings like "DB1.DBX0.0", "DB20.DBD200", "MB20", "T45", etc.</param>
|
||||
/// <param name="value">Value to be written to the PLC</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public async Task<ErrorCode> WriteAsync(string variable, object value)
|
||||
/// <returns>A task that represents the asynchronous write operation.</returns>
|
||||
public async Task WriteAsync(string variable, object value)
|
||||
{
|
||||
var adr = new PLCAddress(variable);
|
||||
return await WriteAsync(adr.dataType, adr.DBNumber, adr.Address, value, adr.BitNumber);
|
||||
await WriteAsync(adr.dataType, adr.DBNumber, adr.Address, value, adr.BitNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -365,12 +354,11 @@ namespace S7.Net
|
||||
/// <param name="structValue">The struct to be written</param>
|
||||
/// <param name="db">Db address</param>
|
||||
/// <param name="startByteAdr">Start bytes on the PLC</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public async Task<ErrorCode> WriteStructAsync(object structValue, int db, int startByteAdr = 0)
|
||||
/// <returns>A task that represents the asynchronous write operation.</returns>
|
||||
public async Task WriteStructAsync(object structValue, int db, int startByteAdr = 0)
|
||||
{
|
||||
var bytes = Struct.ToBytes(structValue).ToList();
|
||||
var errCode = await WriteBytesAsync(DataType.DataBlock, db, startByteAdr, bytes.ToArray());
|
||||
return errCode;
|
||||
await WriteBytesAsync(DataType.DataBlock, db, startByteAdr, bytes.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -379,12 +367,11 @@ namespace S7.Net
|
||||
/// <param name="classValue">The class to be written</param>
|
||||
/// <param name="db">Db address</param>
|
||||
/// <param name="startByteAdr">Start bytes on the PLC</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public async Task<ErrorCode> WriteClassAsync(object classValue, int db, int startByteAdr = 0)
|
||||
/// <returns>A task that represents the asynchronous write operation.</returns>
|
||||
public async Task WriteClassAsync(object classValue, int db, int startByteAdr = 0)
|
||||
{
|
||||
var bytes = Types.Class.ToBytes(classValue).ToList();
|
||||
var errCode = await WriteBytesAsync(DataType.DataBlock, db, startByteAdr, bytes.ToArray());
|
||||
return errCode;
|
||||
await WriteBytesAsync(DataType.DataBlock, db, startByteAdr, bytes.ToArray());
|
||||
}
|
||||
|
||||
private async Task<byte[]> ReadBytesWithSingleRequestAsync(DataType dataType, int db, int startByteAdr, int count)
|
||||
@@ -402,7 +389,7 @@ namespace S7.Net
|
||||
|
||||
var s7data = await COTP.TSDU.ReadAsync(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
throw new PlcException(ErrorCode.WrongNumberReceivedBytes);
|
||||
|
||||
for (int cnt = 0; cnt < count; cnt++)
|
||||
bytes[cnt] = s7data[cnt + 18];
|
||||
@@ -427,15 +414,14 @@ namespace S7.Net
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes up to 200 bytes to the PLC and returns NoError if successful. You must specify the memory area type, memory are address, byte start address and bytes count.
|
||||
/// If the write was not successful, check LastErrorCode or LastErrorString.
|
||||
/// Writes up to 200 bytes to the PLC. You must specify the memory area type, memory are address, byte start address and bytes count.
|
||||
/// </summary>
|
||||
/// <param name="dataType">Data type of the memory area, can be DB, Timer, Counter, Merker(Memory), Input, Output.</param>
|
||||
/// <param name="db">Address of the memory area (if you want to read DB1, this is set to 1). This must be set also for other memory area types: counters, timers,etc.</param>
|
||||
/// <param name="startByteAdr">Start byte address. If you want to read DB1.DBW200, this is 200.</param>
|
||||
/// <param name="value">Bytes to write. The lenght of this parameter can't be higher than 200. If you need more, use recursion.</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
private async Task<ErrorCode> WriteBytesWithASingleRequestAsync(DataType dataType, int db, int startByteAdr, byte[] value)
|
||||
/// <returns>A task that represents the asynchronous write operation.</returns>
|
||||
private async Task WriteBytesWithASingleRequestAsync(DataType dataType, int db, int startByteAdr, byte[] value)
|
||||
{
|
||||
byte[] bReceive = new byte[513];
|
||||
int varCount = 0;
|
||||
@@ -471,27 +457,23 @@ namespace S7.Net
|
||||
var s7data = await COTP.TSDU.ReadAsync(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
{
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
throw new PlcException(ErrorCode.WrongNumberReceivedBytes);
|
||||
}
|
||||
|
||||
return ErrorCode.NoError;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
LastErrorCode = ErrorCode.WriteData;
|
||||
LastErrorString = exc.Message;
|
||||
return LastErrorCode;
|
||||
throw new PlcException(ErrorCode.WriteData, exc);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ErrorCode> WriteBitWithASingleRequestAsync(DataType dataType, int db, int startByteAdr, int bitAdr, bool bitValue)
|
||||
private async Task WriteBitWithASingleRequestAsync(DataType dataType, int db, int startByteAdr, int bitAdr, bool bitValue)
|
||||
{
|
||||
byte[] bReceive = new byte[513];
|
||||
int varCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
var value = new[] { bitValue ? (byte)1 : (byte)0 };
|
||||
var value = new[] {bitValue ? (byte) 1 : (byte) 0};
|
||||
varCount = value.Length;
|
||||
// first create the header
|
||||
int packageSize = 35 + value.Length;
|
||||
@@ -520,15 +502,11 @@ namespace S7.Net
|
||||
|
||||
var s7data = await COTP.TSDU.ReadAsync(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
|
||||
return ErrorCode.NoError;
|
||||
throw new PlcException(ErrorCode.WrongNumberReceivedBytes);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
LastErrorCode = ErrorCode.WriteData;
|
||||
LastErrorString = exc.Message;
|
||||
return LastErrorCode;
|
||||
throw new PlcException(ErrorCode.WriteData, exc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
39
S7.Net/PlcException.cs
Normal file
39
S7.Net/PlcException.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
|
||||
namespace S7.Net
|
||||
{
|
||||
#if NET_FULL
|
||||
[Serializable]
|
||||
#endif
|
||||
public class PlcException : Exception
|
||||
{
|
||||
public ErrorCode ErrorCode { get; }
|
||||
|
||||
public PlcException(ErrorCode errorCode) : this(errorCode, $"PLC communication failed with error '{errorCode}'.")
|
||||
{
|
||||
}
|
||||
|
||||
public PlcException(ErrorCode errorCode, Exception innerException) : this(errorCode, innerException.Message,
|
||||
innerException)
|
||||
{
|
||||
}
|
||||
|
||||
public PlcException(ErrorCode errorCode, string message) : base(message)
|
||||
{
|
||||
ErrorCode = errorCode;
|
||||
}
|
||||
|
||||
public PlcException(ErrorCode errorCode, string message, Exception inner) : base(message, inner)
|
||||
{
|
||||
ErrorCode = errorCode;
|
||||
}
|
||||
|
||||
#if NET_FULL
|
||||
protected PlcException(System.Runtime.Serialization.SerializationInfo info,
|
||||
System.Runtime.Serialization.StreamingContext context) : base(info, context)
|
||||
{
|
||||
ErrorCode = (ErrorCode) info.GetInt32(nameof(ErrorCode));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -11,16 +11,12 @@ namespace S7.Net
|
||||
public partial class Plc
|
||||
{
|
||||
/// <summary>
|
||||
/// Open a <see cref="Socket"/> and connects to the PLC, sending all the corrected package
|
||||
/// and returning if the connection was successful (<see cref="ErrorCode.NoError"/>) of it was wrong.
|
||||
/// Connects to the PLC and performs a COTP ConnectionRequest and S7 CommunicationSetup.
|
||||
/// </summary>
|
||||
/// <returns>Returns ErrorCode.NoError if the connection was successful, otherwise check the ErrorCode</returns>
|
||||
public ErrorCode Open()
|
||||
public void Open()
|
||||
{
|
||||
if (Connect() != ErrorCode.NoError)
|
||||
{
|
||||
return LastErrorCode;
|
||||
}
|
||||
Connect();
|
||||
|
||||
try
|
||||
{
|
||||
stream.Write(ConnectionRequest.GetCOTPConnectionRequest(CPU, Rack, Slot), 0, 22);
|
||||
@@ -41,14 +37,12 @@ namespace S7.Net
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
LastErrorCode = ErrorCode.ConnectionError;
|
||||
LastErrorString = string.Format("Couldn't establish the connection to {0}.\nMessage: {1}", IP, exc.Message);
|
||||
return ErrorCode.ConnectionError;
|
||||
throw new PlcException(ErrorCode.ConnectionError,
|
||||
$"Couldn't establish the connection to {IP}.\nMessage: {exc.Message}", exc);
|
||||
}
|
||||
return ErrorCode.NoError;
|
||||
}
|
||||
|
||||
private ErrorCode Connect()
|
||||
private void Connect()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -59,23 +53,15 @@ namespace S7.Net
|
||||
catch (SocketException sex)
|
||||
{
|
||||
// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
|
||||
if (sex.SocketErrorCode == SocketError.TimedOut)
|
||||
{
|
||||
LastErrorCode = ErrorCode.IPAddressNotAvailable;
|
||||
}
|
||||
else
|
||||
{
|
||||
LastErrorCode = ErrorCode.ConnectionError;
|
||||
}
|
||||
|
||||
LastErrorString = sex.Message;
|
||||
throw new PlcException(
|
||||
sex.SocketErrorCode == SocketError.TimedOut
|
||||
? ErrorCode.IPAddressNotAvailable
|
||||
: ErrorCode.ConnectionError, sex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LastErrorCode = ErrorCode.ConnectionError;
|
||||
LastErrorString = ex.Message;
|
||||
throw new PlcException(ErrorCode.ConnectionError, ex);
|
||||
}
|
||||
return LastErrorCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -231,8 +217,7 @@ namespace S7.Net
|
||||
/// <param name="db">Address of the memory area (if you want to read DB1, this is set to 1). This must be set also for other memory area types: counters, timers,etc.</param>
|
||||
/// <param name="startByteAdr">Start byte address. If you want to write DB1.DBW200, this is 200.</param>
|
||||
/// <param name="value">Bytes to write. If more than 200, multiple requests will be made.</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public ErrorCode WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
|
||||
public void WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
|
||||
{
|
||||
int localIndex = 0;
|
||||
int count = value.Length;
|
||||
@@ -241,16 +226,11 @@ namespace S7.Net
|
||||
//TODO: Figure out how to use MaxPDUSize here
|
||||
//Snap7 seems to choke on PDU sizes above 256 even if snap7
|
||||
//replies with bigger PDU size in connection setup.
|
||||
var maxToWrite = (int)Math.Min(count, 200);
|
||||
ErrorCode lastError = WriteBytesWithASingleRequest(dataType, db, startByteAdr + localIndex, value.Skip(localIndex).Take(maxToWrite).ToArray());
|
||||
if (lastError != ErrorCode.NoError)
|
||||
{
|
||||
return lastError;
|
||||
}
|
||||
var maxToWrite = Math.Min(count, 200);
|
||||
WriteBytesWithASingleRequest(dataType, db, startByteAdr + localIndex, value.Skip(localIndex).Take(maxToWrite).ToArray());
|
||||
count -= maxToWrite;
|
||||
localIndex += maxToWrite;
|
||||
}
|
||||
return ErrorCode.NoError;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -261,36 +241,28 @@ namespace S7.Net
|
||||
/// <param name="startByteAdr">Start byte address. If you want to write DB1.DBW200, this is 200.</param>
|
||||
/// <param name="bitAdr">The address of the bit. (0-7)</param>
|
||||
/// <param name="value">Bytes to write. If more than 200, multiple requests will be made.</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public ErrorCode WriteBit(DataType dataType, int db, int startByteAdr, int bitAdr, bool value)
|
||||
public void WriteBit(DataType dataType, int db, int startByteAdr, int bitAdr, bool value)
|
||||
{
|
||||
if (bitAdr < 0 || bitAdr > 7)
|
||||
throw new InvalidAddressException(string.Format("Addressing Error: You can only reference bitwise locations 0-7. Address {0} is invalid", bitAdr));
|
||||
|
||||
ErrorCode lastError = WriteBitWithASingleRequest(dataType, db, startByteAdr, bitAdr, value);
|
||||
if (lastError != ErrorCode.NoError)
|
||||
{
|
||||
return lastError;
|
||||
}
|
||||
|
||||
return ErrorCode.NoError;
|
||||
WriteBitWithASingleRequest(dataType, db, startByteAdr, bitAdr, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a single bit from a DB with the specified index.
|
||||
/// Write a single bit to a DB with the specified index.
|
||||
/// </summary>
|
||||
/// <param name="dataType">Data type of the memory area, can be DB, Timer, Counter, Merker(Memory), Input, Output.</param>
|
||||
/// <param name="db">Address of the memory area (if you want to read DB1, this is set to 1). This must be set also for other memory area types: counters, timers,etc.</param>
|
||||
/// <param name="db">Address of the memory area (if you want to write DB1, this is set to 1). This must be set also for other memory area types: counters, timers,etc.</param>
|
||||
/// <param name="startByteAdr">Start byte address. If you want to write DB1.DBW200, this is 200.</param>
|
||||
/// <param name="bitAdr">The address of the bit. (0-7)</param>
|
||||
/// <param name="value">Bytes to write. If more than 200, multiple requests will be made.</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public ErrorCode WriteBit(DataType dataType, int db, int startByteAdr, int bitAdr, int value)
|
||||
/// <param name="value">Value to write (0 or 1).</param>
|
||||
public void WriteBit(DataType dataType, int db, int startByteAdr, int bitAdr, int value)
|
||||
{
|
||||
if (value < 0 || value > 1)
|
||||
throw new ArgumentException("Value must be 0 or 1", nameof(value));
|
||||
|
||||
return WriteBit(dataType, db, startByteAdr, bitAdr, value == 1);
|
||||
WriteBit(dataType, db, startByteAdr, bitAdr, value == 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -303,26 +275,29 @@ namespace S7.Net
|
||||
/// <param name="startByteAdr">Start byte address. If you want to read DB1.DBW200, this is 200.</param>
|
||||
/// <param name="value">Bytes to write. The lenght of this parameter can't be higher than 200. If you need more, use recursion.</param>
|
||||
/// <param name="bitAdr">The address of the bit. (0-7)</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public ErrorCode Write(DataType dataType, int db, int startByteAdr, object value, int bitAdr = -1)
|
||||
public void Write(DataType dataType, int db, int startByteAdr, object value, int bitAdr = -1)
|
||||
{
|
||||
if (bitAdr != -1)
|
||||
{
|
||||
//Must be writing a bit value as bitAdr is specified
|
||||
if (value is bool)
|
||||
{
|
||||
return WriteBit(dataType, db, startByteAdr, bitAdr, (bool)value);
|
||||
WriteBit(dataType, db, startByteAdr, bitAdr, (bool) value);
|
||||
}
|
||||
else if (value is int intValue)
|
||||
{
|
||||
if (intValue < 0 || intValue > 7)
|
||||
throw new ArgumentOutOfRangeException(string.Format("Addressing Error: You can only reference bitwise locations 0-7. Address {0} is invalid", bitAdr), nameof(bitAdr));
|
||||
throw new ArgumentOutOfRangeException(
|
||||
string.Format(
|
||||
"Addressing Error: You can only reference bitwise locations 0-7. Address {0} is invalid",
|
||||
bitAdr), nameof(bitAdr));
|
||||
|
||||
return WriteBit(dataType, db, startByteAdr, bitAdr, intValue == 1);
|
||||
WriteBit(dataType, db, startByteAdr, bitAdr, intValue == 1);
|
||||
}
|
||||
throw new ArgumentException("Value must be a bool or an int to write a bit", nameof(value));
|
||||
else
|
||||
throw new ArgumentException("Value must be a bool or an int to write a bit", nameof(value));
|
||||
}
|
||||
return WriteBytes(dataType, db, startByteAdr, Serialization.SerializeValue(value));
|
||||
else WriteBytes(dataType, db, startByteAdr, Serialization.SerializeValue(value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -331,11 +306,10 @@ namespace S7.Net
|
||||
/// </summary>
|
||||
/// <param name="variable">Input strings like "DB1.DBX0.0", "DB20.DBD200", "MB20", "T45", etc.</param>
|
||||
/// <param name="value">Value to be written to the PLC</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public ErrorCode Write(string variable, object value)
|
||||
public void Write(string variable, object value)
|
||||
{
|
||||
var adr = new PLCAddress(variable);
|
||||
return Write(adr.dataType, adr.DBNumber, adr.Address, value, adr.BitNumber);
|
||||
Write(adr.dataType, adr.DBNumber, adr.Address, value, adr.BitNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -344,10 +318,9 @@ namespace S7.Net
|
||||
/// <param name="structValue">The struct to be written</param>
|
||||
/// <param name="db">Db address</param>
|
||||
/// <param name="startByteAdr">Start bytes on the PLC</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public ErrorCode WriteStruct(object structValue, int db, int startByteAdr = 0)
|
||||
public void WriteStruct(object structValue, int db, int startByteAdr = 0)
|
||||
{
|
||||
return WriteStructAsync(structValue, db, startByteAdr).Result;
|
||||
WriteStructAsync(structValue, db, startByteAdr).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -356,10 +329,9 @@ namespace S7.Net
|
||||
/// <param name="classValue">The class to be written</param>
|
||||
/// <param name="db">Db address</param>
|
||||
/// <param name="startByteAdr">Start bytes on the PLC</param>
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public ErrorCode WriteClass(object classValue, int db, int startByteAdr = 0)
|
||||
public void WriteClass(object classValue, int db, int startByteAdr = 0)
|
||||
{
|
||||
return WriteClassAsync(classValue, db, startByteAdr).Result;
|
||||
WriteClassAsync(classValue, db, startByteAdr).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private byte[] ReadBytesWithSingleRequest(DataType dataType, int db, int startByteAdr, int count)
|
||||
@@ -378,24 +350,16 @@ namespace S7.Net
|
||||
|
||||
var s7data = COTP.TSDU.Read(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
throw new PlcException(ErrorCode.WrongNumberReceivedBytes);
|
||||
|
||||
for (int cnt = 0; cnt < count; cnt++)
|
||||
bytes[cnt] = s7data[cnt + 18];
|
||||
|
||||
return bytes;
|
||||
}
|
||||
catch (SocketException socketException)
|
||||
{
|
||||
LastErrorCode = ErrorCode.ReadData;
|
||||
LastErrorString = socketException.Message;
|
||||
return null;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
LastErrorCode = ErrorCode.ReadData;
|
||||
LastErrorString = exc.Message;
|
||||
return null;
|
||||
throw new PlcException(ErrorCode.ReadData, exc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,7 +378,7 @@ namespace S7.Net
|
||||
S7WriteMultiple.ParseResponse(response, response.Length, dataItems);
|
||||
}
|
||||
|
||||
private ErrorCode WriteBytesWithASingleRequest(DataType dataType, int db, int startByteAdr, byte[] value)
|
||||
private void WriteBytesWithASingleRequest(DataType dataType, int db, int startByteAdr, byte[] value)
|
||||
{
|
||||
int varCount = 0;
|
||||
try
|
||||
@@ -448,26 +412,22 @@ namespace S7.Net
|
||||
var s7data = COTP.TSDU.Read(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
{
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
throw new PlcException(ErrorCode.WrongNumberReceivedBytes);
|
||||
}
|
||||
|
||||
return ErrorCode.NoError;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
LastErrorCode = ErrorCode.WriteData;
|
||||
LastErrorString = exc.Message;
|
||||
return LastErrorCode;
|
||||
throw new PlcException(ErrorCode.WriteData, exc);
|
||||
}
|
||||
}
|
||||
|
||||
private ErrorCode WriteBitWithASingleRequest(DataType dataType, int db, int startByteAdr, int bitAdr, bool bitValue)
|
||||
private void WriteBitWithASingleRequest(DataType dataType, int db, int startByteAdr, int bitAdr, bool bitValue)
|
||||
{
|
||||
int varCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
var value = new[] { bitValue ? (byte)1 : (byte)0 };
|
||||
var value = new[] {bitValue ? (byte) 1 : (byte) 0};
|
||||
varCount = value.Length;
|
||||
// first create the header
|
||||
int packageSize = 35 + value.Length;
|
||||
@@ -496,15 +456,11 @@ namespace S7.Net
|
||||
|
||||
var s7data = COTP.TSDU.Read(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
|
||||
return ErrorCode.NoError;
|
||||
throw new PlcException(ErrorCode.WrongNumberReceivedBytes);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
LastErrorCode = ErrorCode.WriteData;
|
||||
LastErrorString = exc.Message;
|
||||
return LastErrorCode;
|
||||
throw new PlcException(ErrorCode.WriteData, exc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,7 +487,7 @@ namespace S7.Net
|
||||
{
|
||||
// first create the header
|
||||
int packageSize = 19 + (dataItems.Count * 12);
|
||||
Types.ByteArray package = new ByteArray(packageSize);
|
||||
ByteArray package = new ByteArray(packageSize);
|
||||
package.Add(ReadHeaderPackage(dataItems.Count));
|
||||
// package.Add(0x02); // datenart
|
||||
foreach (var dataItem in dataItems)
|
||||
@@ -543,19 +499,13 @@ namespace S7.Net
|
||||
|
||||
var s7data = COTP.TSDU.Read(stream); //TODO use Async
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
throw new PlcException(ErrorCode.WrongNumberReceivedBytes);
|
||||
|
||||
ParseDataIntoDataItems(s7data, dataItems);
|
||||
}
|
||||
catch (SocketException socketException)
|
||||
{
|
||||
LastErrorCode = ErrorCode.ReadData;
|
||||
LastErrorString = socketException.Message;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
LastErrorCode = ErrorCode.ReadData;
|
||||
LastErrorString = exc.Message;
|
||||
throw new PlcException(ErrorCode.ReadData, exc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user