using Microsoft.VisualStudio.TestTools.UnitTesting; using Modbus.Net.Siemens; using AddressUnit = Modbus.Net.AddressUnit; namespace Modbus.Net.Tests { /// /// 西门子 PLC 测试类 /// 测试 Siemens S7-1200 (TCP) 和 S7-200 (PPI) 的读写功能 /// [TestClass] public class SiemensTest { // Siemens TCP 机器实例(S7-1200) private BaseMachine? _siemensTcpMachine; // Siemens PPI 机器实例(S7-200) private BaseMachine? _siemensPpiMachine; // 测试机器 IP 地址 private string _machineIp = "10.10.18.251"; // 测试串口 private string _machineCom = "COM11"; /// /// 测试初始化方法 /// 创建 S7-1200 (TCP) 和 S7-200 (PPI) 两种机器实例 /// [TestInitialize] public void Init() { // 创建 S7-1200 TCP 机器实例 // 参数:ID, 别名,连接类型,IP 地址,型号,地址列表,保持连接,从站地址,主站地址 _siemensTcpMachine = new SiemensMachine("1", "", SiemensType.Tcp, _machineIp, SiemensMachineModel.S7_1200, null, true, 2, 0); // 创建 S7-200 PPI 机器实例 // 参数:ID, 别名,连接类型,串口,型号,地址列表,保持连接,从站地址,主站地址,src, dst _siemensPpiMachine = new SiemensMachine("2", "", SiemensType.Ppi, _machineCom, SiemensMachineModel.S7_200, null, true, 2, 0, 1, 0); } /// /// 测试单个线圈读写 /// 验证 Siemens TCP 和 PPI 协议的输出继电器(Q 区)读写功能 /// [TestMethod] public async Task SiemensCoilSingle() { Random r = new Random(); // 定义地址单元 var addresses = new List { new AddressUnit { Id = "0", Area = "Q", Address = 0, SubAddress = 0, CommunicationTag = "A1", DataType = typeof(bool) } }; // 生成随机值(0 或 1) var dic1 = new Dictionary() { { "Q 0.0", r.Next(0, 2) } }; // 设置 TCP 机器的地址列表并写入 _siemensTcpMachine!.GetAddresses = addresses; await _siemensTcpMachine.SetDatasAsync(MachineDataType.Address, dic1); // 设置 PPI 机器的地址列表并写入 _siemensPpiMachine!.GetAddresses = addresses; await _siemensPpiMachine.SetDatasAsync(MachineDataType.Address, dic1); // 分别通过 TCP 和 PPI 读取数据 var ans = await _siemensTcpMachine.GetDatasAsync(MachineDataType.Address); var ans2 = await _siemensPpiMachine.GetDatasAsync(MachineDataType.Address); // 验证两种协议读取的值与写入的值一致 Assert.AreEqual(ans.Datas["Q 0.0"].DeviceValue, dic1["Q 0.0"]); Assert.AreEqual(ans2.Datas["Q 0.0"].DeviceValue, dic1["Q 0.0"]); } /// /// 测试单个离散输入读取 /// 验证 Siemens TCP 和 PPI 协议的输入继电器(I 区)读取功能 /// 输入继电器为只读 /// [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; _siemensPpiMachine!.GetAddresses = addresses; // 分别通过 TCP 和 PPI 读取数据 var ans = await _siemensTcpMachine.GetDatasAsync(MachineDataType.Address); var ans2 = await _siemensPpiMachine.GetDatasAsync(MachineDataType.Address); // 验证两种协议读取的值都为 0(默认值) Assert.AreEqual(ans.Datas["I 0.0"].DeviceValue, 0); Assert.AreEqual(ans2.Datas["I 0.0"].DeviceValue, 0); } /// /// 测试单个位存储器读写 /// 验证 Siemens TCP 和 PPI 协议的位存储器(M 区)读写功能 /// [TestMethod] public async Task SiemensMSingle() { Random r = new Random(); // 定义地址单元 var addresses = new List { new AddressUnit { Id = "0", Area = "M", Address = 0, SubAddress = 0, CommunicationTag = "A1", DataType = typeof(ushort) } }; // 设置两种协议的地址列表 _siemensTcpMachine!.GetAddresses = addresses; _siemensPpiMachine!.GetAddresses = addresses; // 生成随机值 var dic1 = new Dictionary() { { "M 0", r.Next(0, UInt16.MaxValue) } }; // 分别通过 TCP 和 PPI 写入数据 await _siemensTcpMachine.SetDatasAsync(MachineDataType.Address, dic1); await _siemensPpiMachine.SetDatasAsync(MachineDataType.Address, dic1); // 分别通过 TCP 和 PPI 读取数据 var ans = await _siemensTcpMachine.GetDatasAsync(MachineDataType.Address); var ans2 = await _siemensPpiMachine.GetDatasAsync(MachineDataType.Address); // 验证两种协议读取的值与写入的值一致 Assert.AreEqual(ans.Datas["M 0.0"].DeviceValue, dic1["M 0"]); Assert.AreEqual(ans2.Datas["M 0.0"].DeviceValue, dic1["M 0"]); } /// /// 测试单个位存储器位读写 /// 验证 Siemens TCP 和 PPI 协议的位存储器(M 区)位读写功能 /// [TestMethod] public async Task SiemensMSingleBool() { Random r = new Random(); // 定义地址单元 var addresses = new List { new AddressUnit { Id = "0", Area = "M", Address = 0, SubAddress = 0, CommunicationTag = "A1", DataType = typeof(bool) } }; // 设置两种协议的地址列表 _siemensTcpMachine!.GetAddresses = addresses; _siemensPpiMachine!.GetAddresses = addresses; // 生成随机值(0 或 1) var dic1 = new Dictionary() { { "M 0.0", r.Next(0, 2) } }; // 分别通过 TCP 和 PPI 写入数据 await _siemensTcpMachine.SetDatasAsync(MachineDataType.Address, dic1); await _siemensPpiMachine.SetDatasAsync(MachineDataType.Address, dic1); // 分别通过 TCP 和 PPI 读取数据 var ans = await _siemensTcpMachine.GetDatasAsync(MachineDataType.Address); var ans2 = await _siemensPpiMachine.GetDatasAsync(MachineDataType.Address); // 验证两种协议读取的值与写入的值一致 Assert.AreEqual(ans.Datas["M 0.0"].DeviceValue, dic1["M 0.0"]); Assert.AreEqual(ans2.Datas["M 0.0"].DeviceValue, dic1["M 0.0"]); } /// /// 测试单个数据块读写 /// 验证 Siemens TCP 和 PPI 协议的数据块(DB 区)读写功能 /// [TestMethod] public async Task SiemensDbSingle() { Random r = new Random(); // 定义地址单元 var addresses = new List { new AddressUnit { Id = "0", Area = "DB1", Address = 0, SubAddress = 0, CommunicationTag = "A1", DataType = typeof(ushort) } }; // 生成随机值 var dic1 = new Dictionary() { { "DB1 0.0", r.Next(0, UInt16.MaxValue) } }; // 设置两种协议的地址列表 _siemensTcpMachine!.GetAddresses = addresses; _siemensPpiMachine!.GetAddresses = addresses; // 分别通过 TCP 和 PPI 写入数据 await _siemensTcpMachine.SetDatasAsync(MachineDataType.Address, dic1); await _siemensPpiMachine.SetDatasAsync(MachineDataType.Address, dic1); // 分别通过 TCP 和 PPI 读取数据 var ans = await _siemensTcpMachine.GetDatasAsync(MachineDataType.Address); var ans2 = await _siemensPpiMachine.GetDatasAsync(MachineDataType.Address); // 验证两种协议读取的值与写入的值一致 Assert.AreEqual(ans.Datas["DB1 0.0"].DeviceValue, dic1["DB1 0.0"]); Assert.AreEqual(ans2.Datas["DB1 0.0"].DeviceValue, dic1["DB1 0.0"]); } } }