2017-02-14 update 1 bug fix.
This commit is contained in:
@@ -119,7 +119,7 @@ namespace Modbus.Net.Modbus
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < dataValue.Length; i++)
|
for (var i = 0; i < dataValue.Length; i++)
|
||||||
{
|
{
|
||||||
dataValue[i] = BigEndianValueHelper.Instance.ReverseByte(dataValue[i]);
|
dataValue[i] = dataValue[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ReadDataModbusOutputStruct(slaveAddress, functionCode, dataCount, dataValue);
|
return new ReadDataModbusOutputStruct(slaveAddress, functionCode, dataCount, dataValue);
|
||||||
@@ -193,7 +193,7 @@ namespace Modbus.Net.Modbus
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < dataValue.Length; i++)
|
for (var i = 0; i < dataValue.Length; i++)
|
||||||
{
|
{
|
||||||
dataValue[i] = BigEndianValueHelper.Instance.ReverseByte(dataValue[i]);
|
dataValue[i] = dataValue[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode,
|
var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Modbus is a serial communications protocol originally published by Modicon (now
|
|||||||
|
|
||||||
##<a name="address"></a> Address Mapping
|
##<a name="address"></a> Address Mapping
|
||||||
|
|
||||||
Modbus has four types of address: Coil, Discrete Input, Holding Register and Input Register.
|
Modbus has four types of address: Coil, Discrete Input, Input Register and Holding Register.
|
||||||
|
|
||||||
Modbus has two address description method: standard and extend.
|
Modbus has two address description method: standard and extend.
|
||||||
|
|
||||||
@@ -26,8 +26,8 @@ Type | Standard | Extend |
|
|||||||
---------------- | ----------- | ------------- |
|
---------------- | ----------- | ------------- |
|
||||||
Coil | 00001-09999 | 000001-065536 |
|
Coil | 00001-09999 | 000001-065536 |
|
||||||
Discrete Input | 10001-19999 | 100001-165536 |
|
Discrete Input | 10001-19999 | 100001-165536 |
|
||||||
Holding Register | 30001-39999 | 300001-365536 |
|
Input Register | 30001-39999 | 300001-365536 |
|
||||||
Input Register | 40001-49999 | 400001-465536 |
|
Holding Register | 40001-49999 | 400001-465536 |
|
||||||
|
|
||||||
Standard and Extend address description are all supported in Modbus.Net.Modbus. The only difference is don't write too large number in address.
|
Standard and Extend address description are all supported in Modbus.Net.Modbus. The only difference is don't write too large number in address.
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ The number of SubAddress is from 0 to 15.
|
|||||||
|
|
||||||
Caution: Modbus.Net.Modbus SubAddress has a giant difference towards standard Modbus.
|
Caution: Modbus.Net.Modbus SubAddress has a giant difference towards standard Modbus.
|
||||||
|
|
||||||
Bit position from standard modbus is from last to first. But Modbus.Net is from first to last.
|
Bit position from Modbus.Net is one less than standard modbus.
|
||||||
|
|
||||||
Standard Modbus
|
Standard Modbus
|
||||||
|
|
||||||
@@ -77,4 +77,4 @@ Standard Modbus
|
|||||||
Modbus.Net.Modbus
|
Modbus.Net.Modbus
|
||||||
|
|
||||||
1 0 1 1 1 0 0 0 1 0 0 0 0 1 1 0
|
1 0 1 1 1 0 0 0 1 0 0 0 0 1 1 0
|
||||||
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||||||
@@ -98,7 +98,7 @@ List<AddressUnit> addressUnits = new List<AddressUnit>
|
|||||||
new AddressUnit() {Id = "1", Area = "V", Address = 3, CommunicationTag = "D2", DataType = typeof (float), Zoom = 1}
|
new AddressUnit() {Id = "1", Area = "V", Address = 3, CommunicationTag = "D2", DataType = typeof (float), Zoom = 1}
|
||||||
};
|
};
|
||||||
TaskManager task = new TaskManager(10, 300, true);
|
TaskManager task = new TaskManager(10, 300, true);
|
||||||
task.AddMachine(new SiemensMachine(SiemensType.Tcp, "192.168.3.11",SiemensMachineModel.S7_300, addressUnits,
|
task.AddMachine(new SiemensMachine(SiemensType.Tcp, "192.168.3.11", SiemensMachineModel.S7_300, addressUnits,
|
||||||
true, 2, 0));
|
true, 2, 0));
|
||||||
task.ReturnValues += (returnValues) =>
|
task.ReturnValues += (returnValues) =>
|
||||||
{
|
{
|
||||||
@@ -373,17 +373,17 @@ public class ModbusTcpProtocal : ModbusProtocal
|
|||||||
```
|
```
|
||||||
"abstract" keyword is optional because if user can use this protocal don't write abstract.
|
"abstract" keyword is optional because if user can use this protocal don't write abstract.
|
||||||
|
|
||||||
Second: Extend ProtocalUnit, InputStruct and OutputStruct.
|
Second: Extend ProtocalUnit, IInputStruct and IOutputStruct.
|
||||||
```C#
|
```C#
|
||||||
public class ReadDataModbusProtocal : ProtocalUnit
|
public class ReadDataModbusProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(IInputStruct message)
|
||||||
{
|
{
|
||||||
var r_message = (ReadDataModbusInputStruct)message;
|
var r_message = (ReadDataModbusInputStruct)message;
|
||||||
return Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.StartAddress, r_message.GetCount);
|
return Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.StartAddress, r_message.GetCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
|
public override IOutputStruct Unformat(byte[] messageBytes, ref int pos)
|
||||||
{
|
{
|
||||||
byte slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
|
byte slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
|
||||||
byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
|
byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
|
||||||
@@ -394,8 +394,14 @@ public class ReadDataModbusProtocal : ProtocalUnit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
There are two types of ProtocalUnit: ProtocalUnit and SpecialProtocalUnit.
|
There is another interface called ISpecialProtocalUnit.
|
||||||
If you see the implementation, you will find that there are no differences between ProtocalUnit and SpecialProtocalUnit. But actually there is a difference between them: SpecialProtocalUnit will not call ProtocalLinkerBytesExtend. If you don't want some protocals to call the ProtocalLinkerBytesExtend, extend those protocals from SpecialProtocalUnit.
|
If you add ISpecialProtocalUnit to ProtocalUnit, then the protocal will not run BytesExtend and BytesDecact.
|
||||||
|
```C#
|
||||||
|
internal class CreateReferenceSiemensProtocal : ProtocalUnit, ISpecialProtocalUnit
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
2.Implement Protocal based ProtocalLinker. (ModbusTcpProtocalLinker)
|
2.Implement Protocal based ProtocalLinker. (ModbusTcpProtocalLinker)
|
||||||
ProtocalLinker connect the Protocal to the BaseConnector, so that byte array can be sended using some specific way like Ethenet.
|
ProtocalLinker connect the Protocal to the BaseConnector, so that byte array can be sended using some specific way like Ethenet.
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ namespace Modbus.Net
|
|||||||
var temp = data[pos];
|
var temp = data[pos];
|
||||||
for (var i = 0; i < 8; i++)
|
for (var i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
t[i] = temp%2 > 0;
|
t[7 - i] = temp % 2 > 0;
|
||||||
temp /= 2;
|
temp /= 2;
|
||||||
}
|
}
|
||||||
pos += 1;
|
pos += 1;
|
||||||
@@ -442,7 +442,17 @@ namespace Modbus.Net
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual bool GetBit(byte[] number, ref int pos, ref int subPos)
|
public virtual bool GetBit(byte[] number, ref int pos, ref int subPos)
|
||||||
{
|
{
|
||||||
return GetBit(number[pos], ref pos, ref subPos);
|
if (subPos < 0 && subPos > 7) throw new IndexOutOfRangeException();
|
||||||
|
var tspos = subPos;
|
||||||
|
var tpos = pos;
|
||||||
|
var bit = GetBit(number[pos], ref tpos, ref tspos);
|
||||||
|
subPos += 1;
|
||||||
|
if (subPos > 7)
|
||||||
|
{
|
||||||
|
pos++;
|
||||||
|
subPos = 0;
|
||||||
|
}
|
||||||
|
return bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -827,14 +837,14 @@ namespace Modbus.Net
|
|||||||
var creation = 0;
|
var creation = 0;
|
||||||
if (setBit)
|
if (setBit)
|
||||||
{
|
{
|
||||||
for (var i = 7; i >= 0; i--)
|
for (var i = 0; i <= 7; i++)
|
||||||
{
|
{
|
||||||
creation *= 2;
|
creation *= 2;
|
||||||
if (i == subPos) creation++;
|
if (i == subPos) creation++;
|
||||||
}
|
}
|
||||||
return (byte) (number | creation);
|
return (byte) (number | creation);
|
||||||
}
|
}
|
||||||
for (var i = 7; i >= 0; i--)
|
for (var i = 0; i <= 7; i++)
|
||||||
{
|
{
|
||||||
creation *= 2;
|
creation *= 2;
|
||||||
if (i != subPos) creation++;
|
if (i != subPos) creation++;
|
||||||
@@ -1006,29 +1016,13 @@ namespace Modbus.Net
|
|||||||
|
|
||||||
public override bool GetBit(byte[] number, ref int pos, ref int subPos)
|
public override bool GetBit(byte[] number, ref int pos, ref int subPos)
|
||||||
{
|
{
|
||||||
if (subPos < 0 && subPos > 7) throw new IndexOutOfRangeException();
|
return GetBit(number[pos], ref pos, ref subPos);
|
||||||
var tspos = 7 - subPos;
|
|
||||||
var tpos = pos;
|
|
||||||
var bit = GetBit(number[pos], ref tpos, ref tspos);
|
|
||||||
subPos += 1;
|
|
||||||
if (subPos > 7)
|
|
||||||
{
|
|
||||||
pos++;
|
|
||||||
subPos = 0;
|
|
||||||
}
|
|
||||||
return bit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool[] GetBits(byte[] data, ref int pos)
|
public override bool[] GetBits(byte[] data, ref int pos)
|
||||||
{
|
{
|
||||||
var t = new bool[8];
|
var t = base.GetBits(data, ref pos);
|
||||||
var temp = data[pos];
|
Array.Reverse(t);
|
||||||
for (var i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
t[7 - i] = temp%2 > 0;
|
|
||||||
temp /= 2;
|
|
||||||
}
|
|
||||||
pos += 1;
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Modbus.Net.Tests
|
|
||||||
{
|
|
||||||
public sealed class AddressMaker
|
|
||||||
{
|
|
||||||
public TestAreas TestAreas { get; set; }
|
|
||||||
public TestAddresses TestAddresses { get; set; }
|
|
||||||
|
|
||||||
private AddressFormater AddressFormater { get; set; }
|
|
||||||
private AddressTranslator AddressTranslator { get; set; }
|
|
||||||
|
|
||||||
public List<AddressUnit> MakeAddresses(string areaKey, string addressKey, bool isRead)
|
|
||||||
{
|
|
||||||
var combinedAddress = new List<string>();
|
|
||||||
|
|
||||||
foreach (var area in TestAreas[areaKey])
|
|
||||||
{
|
|
||||||
foreach (var address in TestAddresses[addressKey])
|
|
||||||
{
|
|
||||||
for (double currentAddress = address.Item1, i = 0;
|
|
||||||
i < address.Item2;
|
|
||||||
currentAddress +=
|
|
||||||
ValueHelper.Instance.ByteLength[address.Item3.FullName]/
|
|
||||||
AddressTranslator.GetAreaByteLength(area), i++)
|
|
||||||
{
|
|
||||||
combinedAddress.Add(AddressFormater.FormatAddress(area, (int) currentAddress, (int)
|
|
||||||
((currentAddress - (int) currentAddress)/
|
|
||||||
(ValueHelper.Instance.ByteLength[address.Item3.FullName]/
|
|
||||||
AddressTranslator.GetAreaByteLength(area)))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return combinedAddress.Select(p =>
|
|
||||||
{
|
|
||||||
var translateAns = AddressTranslator.AddressTranslate(p, isRead);
|
|
||||||
return new AddressUnit()
|
|
||||||
{
|
|
||||||
Area = translateAns.AreaString,
|
|
||||||
Address = translateAns.Address,
|
|
||||||
SubAddress = translateAns.SubAddress,
|
|
||||||
Id = p,
|
|
||||||
CommunicationTag = p
|
|
||||||
};
|
|
||||||
}).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,164 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Modbus.Net.Tests
|
namespace Modbus.Net.Tests
|
||||||
{
|
{
|
||||||
public sealed class TestAddresses
|
[TestClass]
|
||||||
|
public class BaseTest
|
||||||
{
|
{
|
||||||
private Dictionary<string, Tuple<double, int, Type>[]> Addresses { get; }
|
/*[TestMethod]
|
||||||
|
public void TestMethod1()
|
||||||
public Tuple<double, int, Type>[] this[string index]
|
|
||||||
{
|
{
|
||||||
get { return Addresses[index]; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (!Addresses.ContainsKey(index))
|
|
||||||
{
|
|
||||||
Addresses.Add(index, value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Addresses[index] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
public TestAddresses(Dictionary<string, Tuple<double, int, Type>[]> addresses)
|
|
||||||
{
|
|
||||||
Addresses = addresses.ToDictionary(address=>address.Key, address=>address.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<string> Keys => Addresses.Keys.AsEnumerable();
|
|
||||||
|
|
||||||
public IEnumerable<Tuple<double, int, Type>[]> Values => Addresses.Values.AsEnumerable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class TestAreas
|
|
||||||
{
|
|
||||||
private Dictionary<string, string[]> Areas { get; }
|
|
||||||
|
|
||||||
public string[] this[string index]
|
|
||||||
{
|
|
||||||
get { return Areas[index]; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (!Areas.ContainsKey(index))
|
|
||||||
{
|
|
||||||
Areas.Add(index, value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Areas[index] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestAreas(Dictionary<string, string[]> addresses)
|
|
||||||
{
|
|
||||||
Areas = addresses.ToDictionary(address => address.Key, address => address.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<string> Keys => Areas.Keys.AsEnumerable();
|
|
||||||
|
|
||||||
public IEnumerable<string[]> Values => Areas.Values.AsEnumerable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class BaseTest
|
|
||||||
{
|
|
||||||
public static TestAreas TestAreasModbus => new TestAreas(new Dictionary<string, string[]>
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"Coil",new []{"0X", "1X"}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Register", new [] {"3X", "4X"}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
public static TestAddresses TestAddresses => new TestAddresses(new Dictionary<string, Tuple<double, int, Type>[]>
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"Coil.Single.Min", new []
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(0, 1, typeof(bool))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Coil.Single.Normal", new[]
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(100, 1, typeof(bool))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Coil.Single.MaxOverFlow", new[]
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(100000, 1, typeof(bool))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Coil.Multi.Normal", new[]
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(0, 30, typeof(bool))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Register.Single.Short", new[]
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(0, 1, typeof(ushort))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Register.Continus.Short", new[]
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(0, 10, typeof(ushort))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Register.Continus.Byte", new[]
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(0, 10, typeof(byte))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Register.Continus.Int", new[]
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(0, 10, typeof(uint))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Register.Continus.Bit", new []
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(0.5, 8, typeof(bool))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Register.Duplicate.Short", new []
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(0, 10, typeof(ushort)),
|
|
||||||
new Tuple<double, int, Type>(15, 25, typeof(ushort)),
|
|
||||||
new Tuple<double, int, Type>(50, 20, typeof(ushort))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Register.Cross.Short", new []
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(0, 10, typeof(ushort)),
|
|
||||||
new Tuple<double, int, Type>(5, 10, typeof(ushort)),
|
|
||||||
new Tuple<double, int, Type>(10, 10, typeof(ushort))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Register.Duplicate.Multi", new []
|
|
||||||
{
|
|
||||||
new Tuple<double, int, Type>(0, 10, typeof(byte)),
|
|
||||||
new Tuple<double, int, Type>(20, 10, typeof(byte)),
|
|
||||||
new Tuple<double, int, Type>(30, 16, typeof(bool))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,177 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using Modbus.Net.Modbus;
|
|
||||||
|
|
||||||
namespace Modbus.Net.Tests
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class CommunicationTest
|
|
||||||
{
|
|
||||||
protected AddressMaker AddressMaker = new AddressMaker()
|
|
||||||
{
|
|
||||||
TestAreas = BaseTest.TestAreasModbus,
|
|
||||||
TestAddresses = BaseTest.TestAddresses
|
|
||||||
};
|
|
||||||
|
|
||||||
protected BaseMachine Machine = new ModbusMachine(ModbusType.Tcp, "192.168.3.12", null, true, 2, 0);
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public async Task CoilSingle()
|
|
||||||
{
|
|
||||||
var addresses = AddressMaker.MakeAddresses("Coil", "Coil.Single.Normal", false);
|
|
||||||
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
|
|
||||||
Machine.GetAddresses = addresses;
|
|
||||||
var ans = await Machine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"0X 100", 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"1X 100", 1
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var addresses2 = AddressMaker.MakeAddresses("Coil", "Coil.Signle.Normal", true);
|
|
||||||
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
|
|
||||||
Machine.GetAddresses = addresses2;
|
|
||||||
var ans2 = await Machine.GetDatasAsync(MachineGetDataType.Address);
|
|
||||||
Assert.AreEqual(ans2["0X 100"], 1);
|
|
||||||
Assert.AreEqual(ans2["1X 100"], 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public async Task CoilMuiltiRead()
|
|
||||||
{
|
|
||||||
var addresses = AddressMaker.MakeAddresses("Coil", "Coil.Multi.Normal", false);
|
|
||||||
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
|
|
||||||
Machine.GetAddresses = addresses;
|
|
||||||
var ans = await Machine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"0X 3", 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"0X 4", 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"0X 16", 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"0X 22", 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"1X 3", 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"1X 4", 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"1X 16", 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"1X 22", 1
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var addresses2 = AddressMaker.MakeAddresses("Coil", "Coil.Multi.Normal", true);
|
|
||||||
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
|
|
||||||
Machine.GetAddresses = addresses;
|
|
||||||
var ans2 = await Machine.GetDatasAsync(MachineGetDataType.Address);
|
|
||||||
Assert.AreEqual(ans2["0X 3"], 1);
|
|
||||||
Assert.AreEqual(ans2["0X 4"], 1);
|
|
||||||
Assert.AreEqual(ans2["0X 16"], 1);
|
|
||||||
Assert.AreEqual(ans2["0X 22"], 1);
|
|
||||||
Assert.AreEqual(ans2["0X 7"], 0);
|
|
||||||
Assert.AreEqual(ans2["0X 29"], 0);
|
|
||||||
Assert.AreEqual(ans2["1X 3"], 1);
|
|
||||||
Assert.AreEqual(ans2["1X 4"], 1);
|
|
||||||
Assert.AreEqual(ans2["1X 16"], 1);
|
|
||||||
Assert.AreEqual(ans2["1X 22"], 1);
|
|
||||||
Assert.AreEqual(ans2["1X 7"], 0);
|
|
||||||
Assert.AreEqual(ans2["1X 29"], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public async Task RegisterSingleRead()
|
|
||||||
{
|
|
||||||
var addresses = AddressMaker.MakeAddresses("Register", "Register.Single.Short", false);
|
|
||||||
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
|
|
||||||
Machine.GetAddresses = addresses;
|
|
||||||
var ans = await Machine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"3X 0", 32767
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"4X 0", 32767
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var addresses2 = AddressMaker.MakeAddresses("Register", "Register.Single.Short", true);
|
|
||||||
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
|
|
||||||
Machine.GetAddresses = addresses;
|
|
||||||
var ans2 = await Machine.GetDatasAsync(MachineGetDataType.Address);
|
|
||||||
|
|
||||||
Assert.AreEqual(ans2["3X 0"], 32767);
|
|
||||||
Assert.AreEqual(ans2["4X 0"], 32767);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public async Task RegistertMultiRead()
|
|
||||||
{
|
|
||||||
var addresses = AddressMaker.MakeAddresses("Register", "Register.Duplicate.Short", false);
|
|
||||||
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
|
|
||||||
Machine.GetAddresses = addresses;
|
|
||||||
var ans = await Machine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"3X 4", 17
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"3X 7", 20
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"3X 17", 5255
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"3X 18", 3019
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"3X 55", 192
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"4X 4", 18
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"4X 7", 21
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"4X 17", 5256
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"4X 18", 3020
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"4X 55", 193
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var addresses2 = AddressMaker.MakeAddresses("Register", "Register.Duplicate.Short", true);
|
|
||||||
Machine.AddressCombiner = new AddressCombinerNumericJump(20, Machine.AddressTranslator);
|
|
||||||
Machine.GetAddresses = addresses;
|
|
||||||
var ans2 = await Machine.GetDatasAsync(MachineGetDataType.Address);
|
|
||||||
|
|
||||||
Assert.AreEqual(ans2["3X 4"], 17);
|
|
||||||
Assert.AreEqual(ans2["3X 7"], 20);
|
|
||||||
Assert.AreEqual(ans2["3X 17"], 5255);
|
|
||||||
Assert.AreEqual(ans2["3X 18"], 3019);
|
|
||||||
Assert.AreEqual(ans2["3X 55"], 192);
|
|
||||||
|
|
||||||
Assert.AreEqual(ans2["4X 4"], 18);
|
|
||||||
Assert.AreEqual(ans2["4X 7"], 21);
|
|
||||||
Assert.AreEqual(ans2["4X 17"], 5256);
|
|
||||||
Assert.AreEqual(ans2["4X 18"], 3020);
|
|
||||||
Assert.AreEqual(ans2["4X 55"], 193);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -52,10 +52,10 @@
|
|||||||
</Otherwise>
|
</Otherwise>
|
||||||
</Choose>
|
</Choose>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AddressMaker.cs" />
|
|
||||||
<Compile Include="BaseTest.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="CommunicationTest.cs" />
|
<Compile Include="ModbusTest.cs" />
|
||||||
|
<Compile Include="SiemensTest.cs" />
|
||||||
|
<Compile Include="BaseTest.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Modbus.Net\Modbus.Net.Modbus\Modbus.Net.Modbus.csproj">
|
<ProjectReference Include="..\..\Modbus.Net\Modbus.Net.Modbus\Modbus.Net.Modbus.csproj">
|
||||||
|
|||||||
208
Tests/Modbus.Net.Tests/ModbusTest.cs
Normal file
208
Tests/Modbus.Net.Tests/ModbusTest.cs
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Modbus.Net.Modbus;
|
||||||
|
|
||||||
|
namespace Modbus.Net.Tests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class ModbusTest
|
||||||
|
{
|
||||||
|
private BaseMachine _modbusTcpMachine;
|
||||||
|
|
||||||
|
[TestInitialize]
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
_modbusTcpMachine = new ModbusMachine(ModbusType.Tcp, "192.168.3.10", null, true, 2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ModbusCoilSingle()
|
||||||
|
{
|
||||||
|
var addresses = new List<AddressUnit>
|
||||||
|
{
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "0",
|
||||||
|
Area = "0X",
|
||||||
|
Address = 1,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A1",
|
||||||
|
DataType = typeof(bool)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_modbusTcpMachine.GetAddresses = addresses;
|
||||||
|
await _modbusTcpMachine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"0X 1.0", 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var ans = await _modbusTcpMachine.GetDatasAsync(MachineGetDataType.Address);
|
||||||
|
Assert.AreEqual(ans["0X 1.0"].PlcValue, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ModbusDInputSingle()
|
||||||
|
{
|
||||||
|
var addresses = new List<AddressUnit>
|
||||||
|
{
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "0",
|
||||||
|
Area = "1X",
|
||||||
|
Address = 1,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A1",
|
||||||
|
DataType = typeof(bool)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_modbusTcpMachine.GetAddresses = addresses;
|
||||||
|
var ans = await _modbusTcpMachine.GetDatasAsync(MachineGetDataType.Address);
|
||||||
|
Assert.AreEqual(ans["1X 1.0"].PlcValue, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ModbusIRegSingle()
|
||||||
|
{
|
||||||
|
var addresses = new List<AddressUnit>
|
||||||
|
{
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "0",
|
||||||
|
Area = "3X",
|
||||||
|
Address = 1,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A1",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_modbusTcpMachine.GetAddresses = addresses;
|
||||||
|
var ans = await _modbusTcpMachine.GetDatasAsync(MachineGetDataType.Address);
|
||||||
|
Assert.AreEqual(ans["3X 1.0"].PlcValue, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ModbusRegSingle()
|
||||||
|
{
|
||||||
|
var addresses = new List<AddressUnit>
|
||||||
|
{
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "0",
|
||||||
|
Area = "4X",
|
||||||
|
Address = 1,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A1",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_modbusTcpMachine.GetAddresses = addresses;
|
||||||
|
await _modbusTcpMachine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"4X 1", 31125
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var ans = await _modbusTcpMachine.GetDatasAsync(MachineGetDataType.Address);
|
||||||
|
Assert.AreEqual(ans["4X 1.0"].PlcValue, 31125);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task ModbusRegMultiple()
|
||||||
|
{
|
||||||
|
var addresses = new List<AddressUnit>
|
||||||
|
{
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "0",
|
||||||
|
Area = "4X",
|
||||||
|
Address = 2,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A1",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
},
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "1",
|
||||||
|
Area = "4X",
|
||||||
|
Address = 3,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A2",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
},
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "2",
|
||||||
|
Area = "4X",
|
||||||
|
Address = 4,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A3",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
},
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "3",
|
||||||
|
Area = "4X",
|
||||||
|
Address = 5,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A4",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
},
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "4",
|
||||||
|
Area = "4X",
|
||||||
|
Address = 6,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A5",
|
||||||
|
DataType = typeof(uint)
|
||||||
|
},
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "5",
|
||||||
|
Area = "4X",
|
||||||
|
Address = 8,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A6",
|
||||||
|
DataType = typeof(uint)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_modbusTcpMachine.GetAddresses = addresses;
|
||||||
|
await _modbusTcpMachine.SetDatasAsync(MachineSetDataType.CommunicationTag, new Dictionary<string, double>()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"A1", 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A2", 71
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A3", 72
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A4", 73
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A5", 717870
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A6", 717871
|
||||||
|
},
|
||||||
|
});
|
||||||
|
var ans = await _modbusTcpMachine.GetDatasAsync(MachineGetDataType.CommunicationTag);
|
||||||
|
Assert.AreEqual(ans["A1"].PlcValue, 70);
|
||||||
|
Assert.AreEqual(ans["A2"].PlcValue, 71);
|
||||||
|
Assert.AreEqual(ans["A3"].PlcValue, 72);
|
||||||
|
Assert.AreEqual(ans["A4"].PlcValue, 73);
|
||||||
|
Assert.AreEqual(ans["A5"].PlcValue, 717870);
|
||||||
|
Assert.AreEqual(ans["A6"].PlcValue, 717871);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
216
Tests/Modbus.Net.Tests/SiemensTest.cs
Normal file
216
Tests/Modbus.Net.Tests/SiemensTest.cs
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Modbus.Net.Modbus;
|
||||||
|
using Modbus.Net.Siemens;
|
||||||
|
|
||||||
|
namespace Modbus.Net.Tests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class SiemensTest
|
||||||
|
{
|
||||||
|
private BaseMachine _siemensTcpMachine;
|
||||||
|
|
||||||
|
[TestInitialize]
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
_siemensTcpMachine = new SiemensMachine(SiemensType.Tcp, "192.168.3.10", SiemensMachineModel.S7_1200, null, true, 2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task SiemensCoilSingle()
|
||||||
|
{
|
||||||
|
var addresses = new List<AddressUnit>
|
||||||
|
{
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "0",
|
||||||
|
Area = "Q",
|
||||||
|
Address = 0,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A1",
|
||||||
|
DataType = typeof(bool)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_siemensTcpMachine.GetAddresses = addresses;
|
||||||
|
await _siemensTcpMachine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"Q 0.0", 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var ans = await _siemensTcpMachine.GetDatasAsync(MachineGetDataType.Address);
|
||||||
|
Assert.AreEqual(ans["Q 0.0"].PlcValue, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task SiemensDInputSingle()
|
||||||
|
{
|
||||||
|
var addresses = new List<AddressUnit>
|
||||||
|
{
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "0",
|
||||||
|
Area = "I",
|
||||||
|
Address = 0,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A1",
|
||||||
|
DataType = typeof(bool)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_siemensTcpMachine.GetAddresses = addresses;
|
||||||
|
var ans = await _siemensTcpMachine.GetDatasAsync(MachineGetDataType.Address);
|
||||||
|
Assert.AreEqual(ans["I 0.0"].PlcValue, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task SiemensMSingle()
|
||||||
|
{
|
||||||
|
var addresses = new List<AddressUnit>
|
||||||
|
{
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "0",
|
||||||
|
Area = "M",
|
||||||
|
Address = 0,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A1",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_siemensTcpMachine.GetAddresses = addresses;
|
||||||
|
|
||||||
|
await _siemensTcpMachine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"M 0", 31125
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var ans = await _siemensTcpMachine.GetDatasAsync(MachineGetDataType.Address);
|
||||||
|
Assert.AreEqual(ans["M 0.0"].PlcValue, 31125);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task SiemensDbSingle()
|
||||||
|
{
|
||||||
|
var addresses = new List<AddressUnit>
|
||||||
|
{
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "0",
|
||||||
|
Area = "DB2",
|
||||||
|
Address = 0,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A1",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_siemensTcpMachine.GetAddresses = addresses;
|
||||||
|
await _siemensTcpMachine.SetDatasAsync(MachineSetDataType.Address, new Dictionary<string, double>()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"DB2 0.0", 31125
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var ans = await _siemensTcpMachine.GetDatasAsync(MachineGetDataType.Address);
|
||||||
|
Assert.AreEqual(ans["DB2 0.0"].PlcValue, 31125);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task SiemensDbMultiple()
|
||||||
|
{
|
||||||
|
var addresses = new List<AddressUnit>
|
||||||
|
{
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "0",
|
||||||
|
Area = "DB2",
|
||||||
|
Address = 2,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A1",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
},
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "1",
|
||||||
|
Area = "DB2",
|
||||||
|
Address = 4,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A2",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
},
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "2",
|
||||||
|
Area = "DB2",
|
||||||
|
Address = 6,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A3",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
},
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "3",
|
||||||
|
Area = "DB2",
|
||||||
|
Address = 8,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A4",
|
||||||
|
DataType = typeof(ushort)
|
||||||
|
},
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "4",
|
||||||
|
Area = "DB2",
|
||||||
|
Address = 10,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A5",
|
||||||
|
DataType = typeof(uint)
|
||||||
|
},
|
||||||
|
new AddressUnit
|
||||||
|
{
|
||||||
|
Id = "5",
|
||||||
|
Area = "DB2",
|
||||||
|
Address = 14,
|
||||||
|
SubAddress = 0,
|
||||||
|
CommunicationTag = "A6",
|
||||||
|
DataType = typeof(uint)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_siemensTcpMachine.GetAddresses = addresses;
|
||||||
|
await _siemensTcpMachine.SetDatasAsync(MachineSetDataType.CommunicationTag, new Dictionary<string, double>()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"A1", 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A2", 71
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A3", 72
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A4", 73
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A5", 717870
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A6", 717871
|
||||||
|
},
|
||||||
|
});
|
||||||
|
var ans = await _siemensTcpMachine.GetDatasAsync(MachineGetDataType.CommunicationTag);
|
||||||
|
Assert.AreEqual(ans["A1"].PlcValue, 70);
|
||||||
|
Assert.AreEqual(ans["A2"].PlcValue, 71);
|
||||||
|
Assert.AreEqual(ans["A3"].PlcValue, 72);
|
||||||
|
Assert.AreEqual(ans["A4"].PlcValue, 73);
|
||||||
|
Assert.AreEqual(ans["A5"].PlcValue, 717870);
|
||||||
|
Assert.AreEqual(ans["A6"].PlcValue, 717871);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user