using Edge.Core.Parser.BinaryParser.Util; using Microsoft.VisualStudio.TestTools.UnitTesting; using SunGrowInverter; using SunGrowInverter.MessageEntity; using System; using System.Collections.Generic; using System.Linq; namespace SunGrowInverterTest { [TestClass] public class UnitTest1 { public static bool ValueEquals(IEnumerable array1, IEnumerable array2) { if (array1 == null && array2 == null) { return true; } if ((array1 == null) || (array2 == null)) { return false; } if (array1.Count() != array2.Count()) { return false; } if (array1.Equals(array2)) { return true; } else { for (int Index = 0; Index < array1.Count(); Index++) { if (!Equals(array1.ElementAt(Index), array2.ElementAt(Index))) { return false; } } } return true; } [TestMethod] public void 获取一条运行信息OutgoingMessageTestMethod1() { /* 获取一条运行信息 假设从机地址为 1,需要获取 3x 地址类型的 5000 地址数据。 */ var msg = new OutgoingQueryMessage(); msg.FunctionCode = FunctionCodeEnum.只读寄存器; msg.SlaveAddress = 1; msg.StartingRegAddress = 4999; msg.NoOfRegAddress = 1; Parser parser = new Parser(); var actual = parser.Serialize(msg); var expect = "01 04 13 87 00 01 85 67".ToBytes(); Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}"); } [TestMethod] public void 获取一条运行信息IncomingMessageTestMethod1() { /*从机回应(HEX):*/ var rawIncomingBytes = "01 04 02 01 32 39 75".ToBytes(); Parser parser = new Parser(); var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage; Assert.IsNotNull(incomingMsg); Assert.AreEqual(FunctionCodeEnum.只读寄存器, incomingMsg.FunctionCode); Assert.AreEqual(1, incomingMsg.SlaveAddress); Assert.AreEqual(2, incomingMsg.DataLength); //注:读取 SG60KU-M 设备类型码为 0x0132 Assert.AreEqual(true, ValueEquals(incomingMsg.RawData, "01 32".ToBytes())); } [TestMethod] public void 获取多条运行信息OutgoingMessageTestMethod2() { /* 获取多条运行信息 假设从机地址为 1,需要获取 3x 地址类型的 5000 地址开始的 10 个地址的数据 */ var msg = new OutgoingQueryMessage(); msg.FunctionCode = FunctionCodeEnum.只读寄存器; msg.SlaveAddress = 1; msg.StartingRegAddress = 4999; msg.NoOfRegAddress = 10; Parser parser = new Parser(); var actual = parser.Serialize(msg); var expect = "01 04 13 87 00 0A C4 A0".ToBytes(); Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}"); } [TestMethod] public void 获取多条运行信息IncomingMessageTestMethod2() { /*从机回应(HEX):*/ var rawIncomingBytes = "01 04 14 01 32 00 28 00 00 00 00 00 05 00 00 00 26 00 00 00 00 00 00 56 EA".ToBytes(); Parser parser = new Parser(); var response = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage; Assert.IsNotNull(response); Assert.AreEqual(FunctionCodeEnum.只读寄存器, response.FunctionCode); Assert.AreEqual(1, response.SlaveAddress); Assert.AreEqual(20, response.DataLength); //注:读取 SG60KU-M 设备类型码为 0x0132,额定输出功率 4.0 kW,两相,日发电量为 0, //总发电量为 5 kWh,总运行时间为 38h,机内空气温度为 0,机内变压器温度为 0。 Assert.AreEqual(true, ValueEquals(response.RawData, "01 32 00 28 00 00 00 00 00 05 00 00 00 26 00 00 00 00 00 00".ToBytes())); var 设备类型编码 = response.RawData.Take(2); //0.1kW var 额定有功功率 = BitConverter.ToUInt16(response.RawData.Skip(2).Take(2).Reverse().ToArray()) / 10; var raw_输出类型 = BitConverter.ToUInt16(response.RawData.Skip(4).Take(2).ToArray()); var 输出类型 = raw_输出类型 == 0 ? "单相" : (raw_输出类型 == 1 ? "三相四线" : "三相三线"); //0.1kWh var 日发电量 = BitConverter.ToUInt16(response.RawData.Skip(6).Take(2).Reverse().ToArray()) / 10; //kWh var 总发电量 = BitConverter.ToUInt16(response.RawData.Skip(8).Take(2).Reverse().ToArray()); //h var 总并网运行时间 = BitConverter.ToInt32(response.RawData.Skip(10).Take(4).Reverse().ToArray()); //0.1℃ var 机内空气温度 = BitConverter.ToInt16(response.RawData.Skip(14).Take(2).Reverse().ToArray()) / 10; //VA var 总视在功率 = BitConverter.ToInt32(response.RawData.Skip(16).Take(4).Reverse().ToArray()); } [TestMethod] public void 获取SN序列号OutgoingMessageTestMethod2() { /* 假设从机地址为 1,需要获取 3x 地址类型的 4990 地址开始的 10 个地址的数据 */ var msg = new OutgoingQueryMessage(); msg.FunctionCode = FunctionCodeEnum.只读寄存器; msg.SlaveAddress = 1; msg.StartingRegAddress = 4989; msg.NoOfRegAddress = 10; Parser parser = new Parser(); var actual = parser.Serialize(msg); var expect = "01 04 13 7D 00 0A E4 91".ToBytes(); Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}"); } [TestMethod] public void 获取SN序列号IncomingMessageTestMethod2() { /*从机回应(HEX):*/ var rawIncomingBytes = "01 04 14 31 32 31 32 31 32 30 30 31 00 00 00 00 00 00 00 00 00 00 00 9B 56".ToBytes(); Parser parser = new Parser(); var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage; Assert.IsNotNull(incomingMsg); Assert.AreEqual(FunctionCodeEnum.只读寄存器, incomingMsg.FunctionCode); Assert.AreEqual(1, incomingMsg.SlaveAddress); Assert.AreEqual(0x14, incomingMsg.DataLength); //1、SN 数据类型为 UTF-8。 //2、SN 序列号: 121212001。 Assert.AreEqual(true, ValueEquals(incomingMsg.RawData, "31 32 31 32 31 32 30 30 31 00 00 00 00 00 00 00 00 00 00 00".ToBytes())); } [TestMethod] public void 读取一条设置数据OutgoingMessageTestMethod2() { /* 假设从机地址为 1,需要获取 3x 地址类型的 4990 地址开始的 10 个地址的数据 */ var msg = new OutgoingQueryMessage(); msg.FunctionCode = FunctionCodeEnum.保持寄存器; msg.SlaveAddress = 1; msg.StartingRegAddress = 4999; msg.NoOfRegAddress = 1; Parser parser = new Parser(); var actual = parser.Serialize(msg); var expect = "01 03 13 87 00 01 30 A7".ToBytes(); Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}"); } [TestMethod] public void 读取一条设置数据IncomingMessageTestMethod2() { /*从机回应(HEX):*/ var rawIncomingBytes = "01 03 02 07 D8 BA 2E".ToBytes(); Parser parser = new Parser(); var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage; Assert.IsNotNull(incomingMsg); Assert.AreEqual(FunctionCodeEnum.保持寄存器, incomingMsg.FunctionCode); Assert.AreEqual(1, incomingMsg.SlaveAddress); Assert.AreEqual(0x02, incomingMsg.DataLength); //注:读取 2008 年。 Assert.AreEqual(true, ValueEquals(incomingMsg.RawData, "07 D8".ToBytes())); } [TestMethod] public void 读取多条设置数据OutgoingMessageTestMethod2() { /* 假设从机地址为 1,需要获取 4x 地址类型的 5000 地址开始的 10 个地址的数据 */ var msg = new OutgoingQueryMessage(); msg.FunctionCode = FunctionCodeEnum.保持寄存器; msg.SlaveAddress = 1; msg.StartingRegAddress = 4999; msg.NoOfRegAddress = 10; Parser parser = new Parser(); var actual = parser.Serialize(msg); var expect = "01 03 13 87 00 0A 71 60".ToBytes(); Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}"); } [TestMethod] public void 读取多条设置数据IncomingMessageTestMethod2() { /*从机回应(HEX):*/ var rawIncomingBytes = "01 03 14 07 DA 00 0A 00 1E 00 09 00 28 00 25 00 CE 00 AA 01 F4 00 00 80 53".ToBytes(); Parser parser = new Parser(); var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage; Assert.IsNotNull(incomingMsg); Assert.AreEqual(1, incomingMsg.SlaveAddress); Assert.AreEqual(FunctionCodeEnum.保持寄存器, incomingMsg.FunctionCode); Assert.AreEqual(0x14, incomingMsg.DataLength); //注释:读取时间:2010 年 10 月 30 日 9 时 40 分 37 秒;关机;限功率启用,且限功率设置为 50.0% Assert.AreEqual(true, ValueEquals(incomingMsg.RawData, "07 DA 00 0A 00 1E 00 09 00 28 00 25 00 CE 00 AA 01 F4 00 00".ToBytes())); } [TestMethod] public void 设置一条数据OutgoingMessageTestMethod2() { /* 假设从机地址为 1,需要设置 4x 地址类型的 5000 地址数据。 */ var msg = new OutgoingWriteToMultipleRegMessage(); msg.SlaveAddress = 1; msg.FunctionCode = FunctionCodeEnum.命令码写入_对单个或者多个寄存器; msg.StartingRegAddress = 4999; msg.NoOfRegAddress = 1; msg.RawData = " 07 DA".ToBytes().ToList(); Parser parser = new Parser(); var actual = parser.Serialize(msg); var expect = "01 10 " + "13 87 " + "00 01 " + "02 " + //2009 "07 DA " + "19 4D"; Assert.AreEqual(true, ValueEquals(actual, expect.ToBytes()), $"actual is: 0x{actual.ToHexLogString()}"); } [TestMethod] public void 设置一条数据IncomingMessageTestMethod2() { /*从机回应(HEX):*/ var rawIncomingBytes = "01 10 13 87 00 01 B5 64".ToBytes(); Parser parser = new Parser(); var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingWriteToMultipleRegMessage; Assert.IsNotNull(incomingMsg); Assert.AreEqual(FunctionCodeEnum.命令码写入_对单个或者多个寄存器, incomingMsg.FunctionCode); Assert.AreEqual(1, incomingMsg.SlaveAddress); var deserialized_StartingRegAddress = BitConverter.ToInt32(new byte[] { 0x87, 0x13, 0x00, 0x00 }); Assert.AreEqual(deserialized_StartingRegAddress, incomingMsg.StartingRegAddress); Assert.AreEqual(1, incomingMsg.NoOfRegAddress); //从机回应(HEX): } [TestMethod] public void 设置一条数据OutgoingMessageTestMethod3() { /* 假设从机地址为 1,需要设置 4x 地址类型的 5000 地址数据。 */ var msg = new OutgoingWriteToSingleRegMessage(); msg.SlaveAddress = 1; msg.RegAddress = 4999; msg.RawData = " 07 DA".ToBytes().ToList(); Parser parser = new Parser(); var actual = parser.Serialize(msg); var expect = "01 06 13 87 07 DA BECC".ToBytes(); Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}"); } [TestMethod] public void 设置一条数据IncomingMessageTestMethod3() { /*从机回应(HEX):*/ var rawIncomingBytes = "01 06 13 87 07 DA BE CC".ToBytes(); Parser parser = new Parser(); var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingWriteToSingleRegMessage; Assert.IsNotNull(incomingMsg); Assert.AreEqual(FunctionCodeEnum.命令码写入_对单个寄存器, incomingMsg.FunctionCode); Assert.AreEqual(1, incomingMsg.SlaveAddress); var deserialized_StartingRegAddress = BitConverter.ToInt32(new byte[] { 0x87, 0x13, 0x00, 0x00 }); Assert.AreEqual(deserialized_StartingRegAddress, incomingMsg.RegAddress); Assert.AreEqual(true, ValueEquals(new byte[] { 0x07, 0xDA }, incomingMsg.RawData)); //从机回应(HEX): } [TestMethod] public void 设置多条数据OutgoingMessageTestMethod2() { /* 假设从机地址为 1,需要设置 4x 地址类型的 5000 地址开始的 10 个地址的数据 注:时间设置为:2009 年 10 月 30 日 9 时 16 分 0 秒;设置为关机;限功率启用,且限功率设置为 50.0%。 */ var msg = new OutgoingWriteToMultipleRegMessage(); msg.SlaveAddress = 1; msg.FunctionCode = FunctionCodeEnum.命令码写入_对单个或者多个寄存器; msg.StartingRegAddress = 4999; msg.NoOfRegAddress = 10; msg.RawData = "07 D9 00 0A 00 1E 00 09 00 10 00 00 00 CE 00 AA 01 F4 00 00".ToBytes().ToList(); Parser parser = new Parser(); var actual = parser.Serialize(msg); var expect = "01 10 " + "13 87 " + "00 0A " + "14 " + //2009 "07 D9 " + //10 "00 0A " + //30 "00 1E " + //9 "00 09 " + //16 "00 10 " + //0 "00 00 " + //0xCF(开机) //0xCE(关机) "00 CE " + //0xAA(使能) //0x55(关闭) "00 AA " + //500, 需要先将限功率开关(5007)使能(0xAA)才能设置 "01 F4 " + //保留 "00 00 " + "3E65"; Assert.AreEqual(true, ValueEquals(actual, expect.ToBytes()), $"actual is: 0x{actual.ToHexLogString()}"); } [TestMethod] public void 设置多条数据IncomingMessageTestMethod2() { /*从机回应(HEX):*/ var rawIncomingBytes = "01 10 13 87 00 0A F4 A3".ToBytes(); Parser parser = new Parser(); var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingWriteToMultipleRegMessage; Assert.IsNotNull(incomingMsg); Assert.AreEqual(FunctionCodeEnum.命令码写入_对单个或者多个寄存器, incomingMsg.FunctionCode); Assert.AreEqual(1, incomingMsg.SlaveAddress); var deserialized_StartingRegAddress = BitConverter.ToInt32(new byte[] { 0x87, 0x13, 0x00, 0x00 }); Assert.AreEqual(deserialized_StartingRegAddress, incomingMsg.StartingRegAddress); Assert.AreEqual(0x0A, incomingMsg.NoOfRegAddress); //从机回应(HEX): } [TestMethod] public void 读取机器运行信息OutgoingMessageTestMethod1() { /* 假设从机地址为 1,需要获取 3x 地址类型的 5038 地址开始的 8 个地址的数据。 */ var msg = new OutgoingQueryMessage(); msg.FunctionCode = FunctionCodeEnum.只读寄存器; msg.SlaveAddress = 1; msg.StartingRegAddress = 5037; msg.NoOfRegAddress = 8; Parser parser = new Parser(); var actual = parser.Serialize(msg); var expect = "01 04 13 AD 00 0864 A9".ToBytes(); Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}"); } [TestMethod] public void 读取机器运行信息IncomingMessageTestMethod1() { /*从机回应(HEX):*/ var rawIncomingBytes = "01 04 10 55 00 07 DF 00 0C 00 15 00 04 00 0C 00 3B 00 0A EE D1".ToBytes(); Parser parser = new Parser(); var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage; Assert.IsNotNull(incomingMsg); Assert.AreEqual(FunctionCodeEnum.只读寄存器, incomingMsg.FunctionCode); Assert.AreEqual(1, incomingMsg.SlaveAddress); Assert.AreEqual(0x10, incomingMsg.DataLength); Assert.AreEqual(true, ValueEquals("55 00 07 DF 00 0C 00 15 00 04 00 0C 00 3B 00 0A".ToBytes(), incomingMsg.RawData)); //从机回应(HEX): //①机器的运行状态为故障停机(0x5500),此状态下故障/告警时间和编码有效; //②故障时间为:2015(0x07DF)年 12(0x000C)月 21(0x0015)日 4(0x0004)时 12(0x000C)分 59(0x003B)秒;此时的故障是孤岛(0x000A) } } }