UnitTest1.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. using Edge.Core.Parser.BinaryParser.Util;
  2. using Microsoft.VisualStudio.TestTools.UnitTesting;
  3. using SunGrowInverter;
  4. using SunGrowInverter.MessageEntity;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. namespace SunGrowInverterTest
  9. {
  10. [TestClass]
  11. public class UnitTest1
  12. {
  13. public static bool ValueEquals(IEnumerable<byte> array1, IEnumerable<byte> array2)
  14. {
  15. if (array1 == null && array2 == null)
  16. {
  17. return true;
  18. }
  19. if ((array1 == null) || (array2 == null))
  20. {
  21. return false;
  22. }
  23. if (array1.Count() != array2.Count())
  24. {
  25. return false;
  26. }
  27. if (array1.Equals(array2))
  28. {
  29. return true;
  30. }
  31. else
  32. {
  33. for (int Index = 0; Index < array1.Count(); Index++)
  34. {
  35. if (!Equals(array1.ElementAt(Index), array2.ElementAt(Index)))
  36. {
  37. return false;
  38. }
  39. }
  40. }
  41. return true;
  42. }
  43. [TestMethod]
  44. public void 获取一条运行信息OutgoingMessageTestMethod1()
  45. {
  46. /*
  47. 获取一条运行信息
  48. 假设从机地址为 1,需要获取 3x 地址类型的 5000 地址数据。
  49. */
  50. var msg = new OutgoingQueryMessage();
  51. msg.FunctionCode = FunctionCodeEnum.只读寄存器;
  52. msg.SlaveAddress = 1;
  53. msg.StartingRegAddress = 4999;
  54. msg.NoOfRegAddress = 1;
  55. Parser parser = new Parser();
  56. var actual = parser.Serialize(msg);
  57. var expect = "01 04 13 87 00 01 85 67".ToBytes();
  58. Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}");
  59. }
  60. [TestMethod]
  61. public void 获取一条运行信息IncomingMessageTestMethod1()
  62. {
  63. /*从机回应(HEX):*/
  64. var rawIncomingBytes = "01 04 02 01 32 39 75".ToBytes();
  65. Parser parser = new Parser();
  66. var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage;
  67. Assert.IsNotNull(incomingMsg);
  68. Assert.AreEqual(FunctionCodeEnum.只读寄存器, incomingMsg.FunctionCode);
  69. Assert.AreEqual(1, incomingMsg.SlaveAddress);
  70. Assert.AreEqual(2, incomingMsg.DataLength);
  71. //注:读取 SG60KU-M 设备类型码为 0x0132
  72. Assert.AreEqual(true, ValueEquals(incomingMsg.RawData, "01 32".ToBytes()));
  73. }
  74. [TestMethod]
  75. public void 获取多条运行信息OutgoingMessageTestMethod2()
  76. {
  77. /*
  78. 获取多条运行信息
  79. 假设从机地址为 1,需要获取 3x 地址类型的 5000 地址开始的 10 个地址的数据
  80. */
  81. var msg = new OutgoingQueryMessage();
  82. msg.FunctionCode = FunctionCodeEnum.只读寄存器;
  83. msg.SlaveAddress = 1;
  84. msg.StartingRegAddress = 4999;
  85. msg.NoOfRegAddress = 10;
  86. Parser parser = new Parser();
  87. var actual = parser.Serialize(msg);
  88. var expect = "01 04 13 87 00 0A C4 A0".ToBytes();
  89. Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}");
  90. }
  91. [TestMethod]
  92. public void 获取多条运行信息IncomingMessageTestMethod2()
  93. {
  94. /*从机回应(HEX):*/
  95. 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();
  96. Parser parser = new Parser();
  97. var response = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage;
  98. Assert.IsNotNull(response);
  99. Assert.AreEqual(FunctionCodeEnum.只读寄存器, response.FunctionCode);
  100. Assert.AreEqual(1, response.SlaveAddress);
  101. Assert.AreEqual(20, response.DataLength);
  102. //注:读取 SG60KU-M 设备类型码为 0x0132,额定输出功率 4.0 kW,两相,日发电量为 0,
  103. //总发电量为 5 kWh,总运行时间为 38h,机内空气温度为 0,机内变压器温度为 0。
  104. 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()));
  105. var 设备类型编码 = response.RawData.Take(2);
  106. //0.1kW
  107. var 额定有功功率 = BitConverter.ToUInt16(response.RawData.Skip(2).Take(2).Reverse().ToArray()) / 10;
  108. var raw_输出类型 = BitConverter.ToUInt16(response.RawData.Skip(4).Take(2).ToArray());
  109. var 输出类型 = raw_输出类型 == 0 ? "单相" : (raw_输出类型 == 1 ? "三相四线" : "三相三线");
  110. //0.1kWh
  111. var 日发电量 = BitConverter.ToUInt16(response.RawData.Skip(6).Take(2).Reverse().ToArray()) / 10;
  112. //kWh
  113. var 总发电量 = BitConverter.ToUInt16(response.RawData.Skip(8).Take(2).Reverse().ToArray());
  114. //h
  115. var 总并网运行时间 = BitConverter.ToInt32(response.RawData.Skip(10).Take(4).Reverse().ToArray());
  116. //0.1℃
  117. var 机内空气温度 = BitConverter.ToInt16(response.RawData.Skip(14).Take(2).Reverse().ToArray()) / 10;
  118. //VA
  119. var 总视在功率 = BitConverter.ToInt32(response.RawData.Skip(16).Take(4).Reverse().ToArray());
  120. }
  121. [TestMethod]
  122. public void 获取SN序列号OutgoingMessageTestMethod2()
  123. {
  124. /*
  125. 假设从机地址为 1,需要获取 3x 地址类型的 4990 地址开始的 10 个地址的数据
  126. */
  127. var msg = new OutgoingQueryMessage();
  128. msg.FunctionCode = FunctionCodeEnum.只读寄存器;
  129. msg.SlaveAddress = 1;
  130. msg.StartingRegAddress = 4989;
  131. msg.NoOfRegAddress = 10;
  132. Parser parser = new Parser();
  133. var actual = parser.Serialize(msg);
  134. var expect = "01 04 13 7D 00 0A E4 91".ToBytes();
  135. Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}");
  136. }
  137. [TestMethod]
  138. public void 获取SN序列号IncomingMessageTestMethod2()
  139. {
  140. /*从机回应(HEX):*/
  141. 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();
  142. Parser parser = new Parser();
  143. var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage;
  144. Assert.IsNotNull(incomingMsg);
  145. Assert.AreEqual(FunctionCodeEnum.只读寄存器, incomingMsg.FunctionCode);
  146. Assert.AreEqual(1, incomingMsg.SlaveAddress);
  147. Assert.AreEqual(0x14, incomingMsg.DataLength);
  148. //1、SN 数据类型为 UTF-8。
  149. //2、SN 序列号: 121212001。
  150. 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()));
  151. }
  152. [TestMethod]
  153. public void 读取一条设置数据OutgoingMessageTestMethod2()
  154. {
  155. /*
  156. 假设从机地址为 1,需要获取 3x 地址类型的 4990 地址开始的 10 个地址的数据
  157. */
  158. var msg = new OutgoingQueryMessage();
  159. msg.FunctionCode = FunctionCodeEnum.保持寄存器;
  160. msg.SlaveAddress = 1;
  161. msg.StartingRegAddress = 4999;
  162. msg.NoOfRegAddress = 1;
  163. Parser parser = new Parser();
  164. var actual = parser.Serialize(msg);
  165. var expect = "01 03 13 87 00 01 30 A7".ToBytes();
  166. Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}");
  167. }
  168. [TestMethod]
  169. public void 读取一条设置数据IncomingMessageTestMethod2()
  170. {
  171. /*从机回应(HEX):*/
  172. var rawIncomingBytes = "01 03 02 07 D8 BA 2E".ToBytes();
  173. Parser parser = new Parser();
  174. var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage;
  175. Assert.IsNotNull(incomingMsg);
  176. Assert.AreEqual(FunctionCodeEnum.保持寄存器, incomingMsg.FunctionCode);
  177. Assert.AreEqual(1, incomingMsg.SlaveAddress);
  178. Assert.AreEqual(0x02, incomingMsg.DataLength);
  179. //注:读取 2008 年。
  180. Assert.AreEqual(true, ValueEquals(incomingMsg.RawData, "07 D8".ToBytes()));
  181. }
  182. [TestMethod]
  183. public void 读取多条设置数据OutgoingMessageTestMethod2()
  184. {
  185. /*
  186. 假设从机地址为 1,需要获取 4x 地址类型的 5000 地址开始的 10 个地址的数据
  187. */
  188. var msg = new OutgoingQueryMessage();
  189. msg.FunctionCode = FunctionCodeEnum.保持寄存器;
  190. msg.SlaveAddress = 1;
  191. msg.StartingRegAddress = 4999;
  192. msg.NoOfRegAddress = 10;
  193. Parser parser = new Parser();
  194. var actual = parser.Serialize(msg);
  195. var expect = "01 03 13 87 00 0A 71 60".ToBytes();
  196. Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}");
  197. }
  198. [TestMethod]
  199. public void 读取多条设置数据IncomingMessageTestMethod2()
  200. {
  201. /*从机回应(HEX):*/
  202. 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();
  203. Parser parser = new Parser();
  204. var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage;
  205. Assert.IsNotNull(incomingMsg);
  206. Assert.AreEqual(1, incomingMsg.SlaveAddress);
  207. Assert.AreEqual(FunctionCodeEnum.保持寄存器, incomingMsg.FunctionCode);
  208. Assert.AreEqual(0x14, incomingMsg.DataLength);
  209. //注释:读取时间:2010 年 10 月 30 日 9 时 40 分 37 秒;关机;限功率启用,且限功率设置为 50.0%
  210. 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()));
  211. }
  212. [TestMethod]
  213. public void 设置一条数据OutgoingMessageTestMethod2()
  214. {
  215. /*
  216. 假设从机地址为 1,需要设置 4x 地址类型的 5000 地址数据。
  217. */
  218. var msg = new OutgoingWriteToMultipleRegMessage();
  219. msg.SlaveAddress = 1;
  220. msg.FunctionCode = FunctionCodeEnum.命令码写入_对单个或者多个寄存器;
  221. msg.StartingRegAddress = 4999;
  222. msg.NoOfRegAddress = 1;
  223. msg.RawData = " 07 DA".ToBytes().ToList();
  224. Parser parser = new Parser();
  225. var actual = parser.Serialize(msg);
  226. var expect = "01 10 " +
  227. "13 87 " +
  228. "00 01 " +
  229. "02 " +
  230. //2009
  231. "07 DA " +
  232. "19 4D";
  233. Assert.AreEqual(true, ValueEquals(actual, expect.ToBytes()), $"actual is: 0x{actual.ToHexLogString()}");
  234. }
  235. [TestMethod]
  236. public void 设置一条数据IncomingMessageTestMethod2()
  237. {
  238. /*从机回应(HEX):*/
  239. var rawIncomingBytes = "01 10 13 87 00 01 B5 64".ToBytes();
  240. Parser parser = new Parser();
  241. var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingWriteToMultipleRegMessage;
  242. Assert.IsNotNull(incomingMsg);
  243. Assert.AreEqual(FunctionCodeEnum.命令码写入_对单个或者多个寄存器, incomingMsg.FunctionCode);
  244. Assert.AreEqual(1, incomingMsg.SlaveAddress);
  245. var deserialized_StartingRegAddress = BitConverter.ToInt32(new byte[] { 0x87, 0x13, 0x00, 0x00 });
  246. Assert.AreEqual(deserialized_StartingRegAddress, incomingMsg.StartingRegAddress);
  247. Assert.AreEqual(1, incomingMsg.NoOfRegAddress);
  248. //从机回应(HEX):
  249. }
  250. [TestMethod]
  251. public void 设置一条数据OutgoingMessageTestMethod3()
  252. {
  253. /*
  254. 假设从机地址为 1,需要设置 4x 地址类型的 5000 地址数据。
  255. */
  256. var msg = new OutgoingWriteToSingleRegMessage();
  257. msg.SlaveAddress = 1;
  258. msg.RegAddress = 4999;
  259. msg.RawData = " 07 DA".ToBytes().ToList();
  260. Parser parser = new Parser();
  261. var actual = parser.Serialize(msg);
  262. var expect = "01 06 13 87 07 DA BECC".ToBytes();
  263. Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}");
  264. }
  265. [TestMethod]
  266. public void 设置一条数据IncomingMessageTestMethod3()
  267. {
  268. /*从机回应(HEX):*/
  269. var rawIncomingBytes = "01 06 13 87 07 DA BE CC".ToBytes();
  270. Parser parser = new Parser();
  271. var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingWriteToSingleRegMessage;
  272. Assert.IsNotNull(incomingMsg);
  273. Assert.AreEqual(FunctionCodeEnum.命令码写入_对单个寄存器, incomingMsg.FunctionCode);
  274. Assert.AreEqual(1, incomingMsg.SlaveAddress);
  275. var deserialized_StartingRegAddress = BitConverter.ToInt32(new byte[] { 0x87, 0x13, 0x00, 0x00 });
  276. Assert.AreEqual(deserialized_StartingRegAddress, incomingMsg.RegAddress);
  277. Assert.AreEqual(true, ValueEquals(new byte[] { 0x07, 0xDA }, incomingMsg.RawData));
  278. //从机回应(HEX):
  279. }
  280. [TestMethod]
  281. public void 设置多条数据OutgoingMessageTestMethod2()
  282. {
  283. /*
  284. 假设从机地址为 1,需要设置 4x 地址类型的 5000 地址开始的 10 个地址的数据
  285. 注:时间设置为:2009 年 10 月 30 日 9 时 16 分 0 秒;设置为关机;限功率启用,且限功率设置为 50.0%。
  286. */
  287. var msg = new OutgoingWriteToMultipleRegMessage();
  288. msg.SlaveAddress = 1;
  289. msg.FunctionCode = FunctionCodeEnum.命令码写入_对单个或者多个寄存器;
  290. msg.StartingRegAddress = 4999;
  291. msg.NoOfRegAddress = 10;
  292. msg.RawData = "07 D9 00 0A 00 1E 00 09 00 10 00 00 00 CE 00 AA 01 F4 00 00".ToBytes().ToList();
  293. Parser parser = new Parser();
  294. var actual = parser.Serialize(msg);
  295. var expect = "01 10 " +
  296. "13 87 " +
  297. "00 0A " +
  298. "14 " +
  299. //2009
  300. "07 D9 " +
  301. //10
  302. "00 0A " +
  303. //30
  304. "00 1E " +
  305. //9
  306. "00 09 " +
  307. //16
  308. "00 10 " +
  309. //0
  310. "00 00 " +
  311. //0xCF(开机)
  312. //0xCE(关机)
  313. "00 CE " +
  314. //0xAA(使能)
  315. //0x55(关闭)
  316. "00 AA " +
  317. //500, 需要先将限功率开关(5007)使能(0xAA)才能设置
  318. "01 F4 " +
  319. //保留
  320. "00 00 " +
  321. "3E65";
  322. Assert.AreEqual(true, ValueEquals(actual, expect.ToBytes()), $"actual is: 0x{actual.ToHexLogString()}");
  323. }
  324. [TestMethod]
  325. public void 设置多条数据IncomingMessageTestMethod2()
  326. {
  327. /*从机回应(HEX):*/
  328. var rawIncomingBytes = "01 10 13 87 00 0A F4 A3".ToBytes();
  329. Parser parser = new Parser();
  330. var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingWriteToMultipleRegMessage;
  331. Assert.IsNotNull(incomingMsg);
  332. Assert.AreEqual(FunctionCodeEnum.命令码写入_对单个或者多个寄存器, incomingMsg.FunctionCode);
  333. Assert.AreEqual(1, incomingMsg.SlaveAddress);
  334. var deserialized_StartingRegAddress = BitConverter.ToInt32(new byte[] { 0x87, 0x13, 0x00, 0x00 });
  335. Assert.AreEqual(deserialized_StartingRegAddress, incomingMsg.StartingRegAddress);
  336. Assert.AreEqual(0x0A, incomingMsg.NoOfRegAddress);
  337. //从机回应(HEX):
  338. }
  339. [TestMethod]
  340. public void 读取机器运行信息OutgoingMessageTestMethod1()
  341. {
  342. /*
  343. 假设从机地址为 1,需要获取 3x 地址类型的 5038 地址开始的 8 个地址的数据。
  344. */
  345. var msg = new OutgoingQueryMessage();
  346. msg.FunctionCode = FunctionCodeEnum.只读寄存器;
  347. msg.SlaveAddress = 1;
  348. msg.StartingRegAddress = 5037;
  349. msg.NoOfRegAddress = 8;
  350. Parser parser = new Parser();
  351. var actual = parser.Serialize(msg);
  352. var expect = "01 04 13 AD 00 0864 A9".ToBytes();
  353. Assert.AreEqual(true, ValueEquals(actual, expect), $"actual is: 0x{actual.ToHexLogString()}");
  354. }
  355. [TestMethod]
  356. public void 读取机器运行信息IncomingMessageTestMethod1()
  357. {
  358. /*从机回应(HEX):*/
  359. var rawIncomingBytes = "01 04 10 55 00 07 DF 00 0C 00 15 00 04 00 0C 00 3B 00 0A EE D1".ToBytes();
  360. Parser parser = new Parser();
  361. var incomingMsg = parser.Deserialize(rawIncomingBytes) as IncomingQueryMessage;
  362. Assert.IsNotNull(incomingMsg);
  363. Assert.AreEqual(FunctionCodeEnum.只读寄存器, incomingMsg.FunctionCode);
  364. Assert.AreEqual(1, incomingMsg.SlaveAddress);
  365. Assert.AreEqual(0x10, incomingMsg.DataLength);
  366. Assert.AreEqual(true, ValueEquals("55 00 07 DF 00 0C 00 15 00 04 00 0C 00 3B 00 0A".ToBytes(), incomingMsg.RawData));
  367. //从机回应(HEX):
  368. //①机器的运行状态为故障停机(0x5500),此状态下故障/告警时间和编码有效;
  369. //②故障时间为:2015(0x07DF)年 12(0x000C)月 21(0x0015)日 4(0x0004)时 12(0x000C)分 59(0x003B)秒;此时的故障是孤岛(0x000A)
  370. }
  371. }
  372. }