From 7e0fa1cf593460706e36d5652810f55ffdcf1655 Mon Sep 17 00:00:00 2001 From: parallelbgls Date: Tue, 14 Feb 2017 11:31:36 +0800 Subject: [PATCH] 2017-02-14 update 1 bug fix. --- .../Modbus.Net.Modbus/ModbusProtocal.cs | 4 +- Modbus.Net/Modbus.Net.Modbus/README.md | 10 +- Modbus.Net/Modbus.Net/README.md | 18 +- Modbus.Net/Modbus.Net/ValueHelper.cs | 40 ++-- Tests/Modbus.Net.Tests/AddressMaker.cs | 53 ----- Tests/Modbus.Net.Tests/BaseTest.cs | 161 +------------ Tests/Modbus.Net.Tests/CommunicationTest.cs | 177 -------------- .../Modbus.Net.Tests/Modbus.Net.Tests.csproj | 6 +- Tests/Modbus.Net.Tests/ModbusTest.cs | 208 +++++++++++++++++ Tests/Modbus.Net.Tests/SiemensTest.cs | 216 ++++++++++++++++++ 10 files changed, 469 insertions(+), 424 deletions(-) delete mode 100644 Tests/Modbus.Net.Tests/AddressMaker.cs delete mode 100644 Tests/Modbus.Net.Tests/CommunicationTest.cs create mode 100644 Tests/Modbus.Net.Tests/ModbusTest.cs create mode 100644 Tests/Modbus.Net.Tests/SiemensTest.cs diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs index 71e2456..3494554 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs @@ -119,7 +119,7 @@ namespace Modbus.Net.Modbus { 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); @@ -193,7 +193,7 @@ namespace Modbus.Net.Modbus { 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, diff --git a/Modbus.Net/Modbus.Net.Modbus/README.md b/Modbus.Net/Modbus.Net.Modbus/README.md index a1f1617..22a75ae 100644 --- a/Modbus.Net/Modbus.Net.Modbus/README.md +++ b/Modbus.Net/Modbus.Net.Modbus/README.md @@ -16,7 +16,7 @@ Modbus is a serial communications protocol originally published by Modicon (now ## 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. @@ -26,8 +26,8 @@ Type | Standard | Extend | ---------------- | ----------- | ------------- | Coil | 00001-09999 | 000001-065536 | Discrete Input | 10001-19999 | 100001-165536 | -Holding Register | 30001-39999 | 300001-365536 | -Input Register | 40001-49999 | 400001-465536 | +Input Register | 30001-39999 | 300001-365536 | +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. @@ -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. -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 @@ -77,4 +77,4 @@ Standard Modbus Modbus.Net.Modbus 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 \ No newline at end of file +15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/README.md b/Modbus.Net/Modbus.Net/README.md index 4df83f9..5ae911b 100644 --- a/Modbus.Net/Modbus.Net/README.md +++ b/Modbus.Net/Modbus.Net/README.md @@ -98,7 +98,7 @@ List addressUnits = new List new AddressUnit() {Id = "1", Area = "V", Address = 3, CommunicationTag = "D2", DataType = typeof (float), Zoom = 1} }; 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)); 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. -Second: Extend ProtocalUnit, InputStruct and OutputStruct. +Second: Extend ProtocalUnit, IInputStruct and IOutputStruct. ```C# public class ReadDataModbusProtocal : ProtocalUnit { - public override byte[] Format(InputStruct message) + public override byte[] Format(IInputStruct message) { var r_message = (ReadDataModbusInputStruct)message; 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 functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); @@ -394,8 +394,14 @@ public class ReadDataModbusProtocal : ProtocalUnit } } ``` -There are two types of ProtocalUnit: ProtocalUnit and SpecialProtocalUnit. -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. +There is another interface called ISpecialProtocalUnit. +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) ProtocalLinker connect the Protocal to the BaseConnector, so that byte array can be sended using some specific way like Ethenet. diff --git a/Modbus.Net/Modbus.Net/ValueHelper.cs b/Modbus.Net/Modbus.Net/ValueHelper.cs index 1bc643a..c708a28 100644 --- a/Modbus.Net/Modbus.Net/ValueHelper.cs +++ b/Modbus.Net/Modbus.Net/ValueHelper.cs @@ -399,7 +399,7 @@ namespace Modbus.Net var temp = data[pos]; for (var i = 0; i < 8; i++) { - t[i] = temp%2 > 0; + t[7 - i] = temp % 2 > 0; temp /= 2; } pos += 1; @@ -442,7 +442,17 @@ namespace Modbus.Net /// 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; } /// @@ -827,14 +837,14 @@ namespace Modbus.Net var creation = 0; if (setBit) { - for (var i = 7; i >= 0; i--) + for (var i = 0; i <= 7; i++) { creation *= 2; if (i == subPos) creation++; } return (byte) (number | creation); } - for (var i = 7; i >= 0; i--) + for (var i = 0; i <= 7; i++) { creation *= 2; if (i != subPos) creation++; @@ -1006,29 +1016,13 @@ namespace Modbus.Net public override bool GetBit(byte[] number, ref int pos, ref int subPos) { - if (subPos < 0 && subPos > 7) throw new IndexOutOfRangeException(); - 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; + return GetBit(number[pos], ref pos, ref subPos); } public override bool[] GetBits(byte[] data, ref int pos) { - var t = new bool[8]; - var temp = data[pos]; - for (var i = 0; i < 8; i++) - { - t[7 - i] = temp%2 > 0; - temp /= 2; - } - pos += 1; + var t = base.GetBits(data, ref pos); + Array.Reverse(t); return t; } diff --git a/Tests/Modbus.Net.Tests/AddressMaker.cs b/Tests/Modbus.Net.Tests/AddressMaker.cs deleted file mode 100644 index 4ce4912..0000000 --- a/Tests/Modbus.Net.Tests/AddressMaker.cs +++ /dev/null @@ -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 MakeAddresses(string areaKey, string addressKey, bool isRead) - { - var combinedAddress = new List(); - - 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(); - } - } -} diff --git a/Tests/Modbus.Net.Tests/BaseTest.cs b/Tests/Modbus.Net.Tests/BaseTest.cs index 061158a..1cb450a 100644 --- a/Tests/Modbus.Net.Tests/BaseTest.cs +++ b/Tests/Modbus.Net.Tests/BaseTest.cs @@ -1,164 +1,15 @@ using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Modbus.Net.Tests { - public sealed class TestAddresses + [TestClass] + public class BaseTest { - private Dictionary[]> Addresses { get; } - - public Tuple[] this[string index] + /*[TestMethod] + public void TestMethod1() { - get { return Addresses[index]; } - set - { - if (!Addresses.ContainsKey(index)) - { - Addresses.Add(index, value); - } - else - { - Addresses[index] = value; - } - } } - - public TestAddresses(Dictionary[]> addresses) - { - Addresses = addresses.ToDictionary(address=>address.Key, address=>address.Value); - } - - public IEnumerable Keys => Addresses.Keys.AsEnumerable(); - - public IEnumerable[]> Values => Addresses.Values.AsEnumerable(); - } - - public sealed class TestAreas - { - private Dictionary 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 addresses) - { - Areas = addresses.ToDictionary(address => address.Key, address => address.Value); - } - - public IEnumerable Keys => Areas.Keys.AsEnumerable(); - - public IEnumerable Values => Areas.Values.AsEnumerable(); - } - - public sealed class BaseTest - { - public static TestAreas TestAreasModbus => new TestAreas(new Dictionary - { - { - "Coil",new []{"0X", "1X"} - }, - { - "Register", new [] {"3X", "4X"} - } - }); - - public static TestAddresses TestAddresses => new TestAddresses(new Dictionary[]> - { - { - "Coil.Single.Min", new [] - { - new Tuple(0, 1, typeof(bool)) - } - }, - { - "Coil.Single.Normal", new[] - { - new Tuple(100, 1, typeof(bool)) - } - }, - { - "Coil.Single.MaxOverFlow", new[] - { - new Tuple(100000, 1, typeof(bool)) - } - }, - { - "Coil.Multi.Normal", new[] - { - new Tuple(0, 30, typeof(bool)) - } - }, - { - "Register.Single.Short", new[] - { - new Tuple(0, 1, typeof(ushort)) - } - }, - { - "Register.Continus.Short", new[] - { - new Tuple(0, 10, typeof(ushort)) - } - }, - { - "Register.Continus.Byte", new[] - { - new Tuple(0, 10, typeof(byte)) - } - }, - { - "Register.Continus.Int", new[] - { - new Tuple(0, 10, typeof(uint)) - } - }, - { - "Register.Continus.Bit", new [] - { - new Tuple(0.5, 8, typeof(bool)) - } - }, - { - "Register.Duplicate.Short", new [] - { - new Tuple(0, 10, typeof(ushort)), - new Tuple(15, 25, typeof(ushort)), - new Tuple(50, 20, typeof(ushort)) - } - }, - { - "Register.Cross.Short", new [] - { - new Tuple(0, 10, typeof(ushort)), - new Tuple(5, 10, typeof(ushort)), - new Tuple(10, 10, typeof(ushort)) - } - }, - { - "Register.Duplicate.Multi", new [] - { - new Tuple(0, 10, typeof(byte)), - new Tuple(20, 10, typeof(byte)), - new Tuple(30, 16, typeof(bool)) - } - }, - }); + */ } } diff --git a/Tests/Modbus.Net.Tests/CommunicationTest.cs b/Tests/Modbus.Net.Tests/CommunicationTest.cs deleted file mode 100644 index a1a0742..0000000 --- a/Tests/Modbus.Net.Tests/CommunicationTest.cs +++ /dev/null @@ -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() - { - { - "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() - { - { - "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() - { - { - "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() - { - { - "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); - } - - } -} diff --git a/Tests/Modbus.Net.Tests/Modbus.Net.Tests.csproj b/Tests/Modbus.Net.Tests/Modbus.Net.Tests.csproj index 2f16bed..8a9c4e2 100644 --- a/Tests/Modbus.Net.Tests/Modbus.Net.Tests.csproj +++ b/Tests/Modbus.Net.Tests/Modbus.Net.Tests.csproj @@ -52,10 +52,10 @@ - - - + + + diff --git a/Tests/Modbus.Net.Tests/ModbusTest.cs b/Tests/Modbus.Net.Tests/ModbusTest.cs new file mode 100644 index 0000000..6e25dd6 --- /dev/null +++ b/Tests/Modbus.Net.Tests/ModbusTest.cs @@ -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 + { + 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() + { + { + "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 + { + 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 + { + 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 + { + 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() + { + { + "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 + { + 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() + { + { + "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); + } + } +} diff --git a/Tests/Modbus.Net.Tests/SiemensTest.cs b/Tests/Modbus.Net.Tests/SiemensTest.cs new file mode 100644 index 0000000..8c97220 --- /dev/null +++ b/Tests/Modbus.Net.Tests/SiemensTest.cs @@ -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 + { + 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() + { + { + "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 + { + 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 + { + 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() + { + { + "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 + { + 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() + { + { + "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 + { + 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() + { + { + "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); + } + } +}