RWRunConfig.cs 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369
  1. using Modbus;
  2. using Modbus.Device;
  3. using Modbus.IO;
  4. using MV485.model;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO.Ports;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using System.Windows;
  12. namespace MV485.helper
  13. {
  14. //读写配置参数
  15. public class RWRunConfig
  16. {
  17. private SerialPort _serialPort;
  18. private ModbusSerialMaster _modbusMaster;
  19. private ModbusSerialTransport _modbusTransport;
  20. private byte[] sentData; //发送到设备的数据
  21. private byte[] recvData; //从设备接收的数据
  22. //private string _sendDataHex;
  23. //private string _recvDataHex;
  24. private string _portName;
  25. private int _baudrate; //读时使用的波特率额
  26. private byte _address; //读时使用的地址
  27. private string _message;
  28. //public event Action<bool, string, int, byte> SearchFinished;
  29. public event Action<string> RWLog;
  30. public event Action<bool,string,int,byte> SerialConnected; //串口是否已连接
  31. public event Action<bool,string,int,byte> SerialStatusChanged; //串口连接状态变化
  32. private string _lastErrorMessage; //最后一次的错误说明
  33. public string GetLastError()
  34. {
  35. return _lastErrorMessage;
  36. }
  37. public RWRunConfig()
  38. {
  39. }
  40. //cfgType 1:AI参数;2:图像参数; 3:采样时间参数
  41. public RunConfig ReadRunConfig(string portName, int baudrate, byte devId,int cfgType)
  42. {
  43. RunConfig runConfig = null;
  44. _portName = portName;
  45. _baudrate = baudrate;
  46. _address = devId;
  47. if (OpenSerial(portName, baudrate))
  48. {
  49. if (cfgType == 1)
  50. {
  51. runConfig = GetAIConfig(devId);
  52. }
  53. else if (cfgType == 2)
  54. {
  55. runConfig = GetRegionConfig(devId);
  56. }
  57. else if (cfgType == 3)
  58. {
  59. runConfig = GetSampleConfig(devId);
  60. }
  61. else
  62. {
  63. runConfig = GetRunConfig(devId);
  64. }
  65. }
  66. CloseSerial();
  67. return runConfig;
  68. }
  69. private RunConfig GetAIConfig(byte devId)
  70. {
  71. string readName = "";
  72. try
  73. {
  74. RunConfig runConfig = new RunConfig();
  75. ushort[] readRegisters;
  76. readName = "水表类型";
  77. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  78. Constant.MB_REGISTER_ADD_METER_TYPE, Constant.MB_REGISTER_NUM_METER_TYPE);
  79. byte meterType = (byte)(readRegisters[0] & 0xFF);
  80. runConfig.MeterTypeWRFlag = true;
  81. runConfig.MeterType = meterType;
  82. GenerateSendAndRecvHexLog(true, readName);
  83. _message = $"{readName}: {meterType}";
  84. RWLog?.Invoke(_message);
  85. readName = "每小时最大流量";
  86. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  87. Constant.MB_REGISTER_ADD_DN_VALUE, Constant.MB_REGISTER_NUM_DN_VALUE);
  88. ushort dnValue = readRegisters[0];
  89. runConfig.DnValueWRFlag = true;
  90. runConfig.DnValue = dnValue;
  91. GenerateSendAndRecvHexLog(true, readName);
  92. _message = $"{readName}: {dnValue}";
  93. RWLog?.Invoke(_message);
  94. if (meterType == Constant.METER_TYPE_NUM_IND || meterType == Constant.METER_TYPE_NUM)
  95. {
  96. readName = "数字个数";
  97. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  98. Constant.MB_REGISTER_ADD_DIGIT_COUNT, Constant.MB_REGISTER_NUM_DIGIT_COUNT);
  99. byte digitCount = (byte)(readRegisters[0] & 0xFF);
  100. runConfig.DigitCountWRFlag = true;
  101. runConfig.DigitCount = digitCount;
  102. GenerateSendAndRecvHexLog(true, readName);
  103. GenerateValueLog(readName, digitCount);
  104. }
  105. if (meterType == Constant.METER_TYPE_NUM_IND || meterType == Constant.METER_TYPE_IND)
  106. {
  107. readName = "指针个数";
  108. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  109. Constant.MB_REGISTER_ADD_INDICATOR_COUNT, Constant.MB_REGISTER_NUM_INDICATOR_COUNT);
  110. byte indCount = (byte)(readRegisters[0] & 0xFF);
  111. runConfig.IndCountWRFlag = true;
  112. runConfig.IndCount = indCount;
  113. GenerateSendAndRecvHexLog(true, readName);
  114. GenerateValueLog(readName, indCount);
  115. }
  116. //此项已经不需要了
  117. /*readName = "照片亮度放大倍率";
  118. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  119. Constant.MB_REGISTER_ADD_BRIGHT_VALUE, Constant.MB_REGISTER_NUM_BRIGHT_VALUE);
  120. byte birghtValue = (byte)(readRegisters[0] & 0xFF); // 10f;
  121. runConfig.BrightValueWRFlag = true;
  122. runConfig.BrightValue = birghtValue / 10f;
  123. GenerateSendAndRecvHexLog(true, readName);
  124. GenerateValueLog(readName, birghtValue);*/
  125. readName = "尾数单位等级";
  126. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  127. Constant.MB_REGISTER_ADD_LAST_UNIT_LEVEL, Constant.MB_REGISTER_NUM_LAST_UNIT_LEVEL);
  128. byte lastUnitLevel = (byte)(readRegisters[0] & 0xFF);
  129. runConfig.LastUnitLevelWRFlag = true;
  130. runConfig.LastUnitLevel = lastUnitLevel;
  131. GenerateSendAndRecvHexLog(true, readName);
  132. GenerateValueLog(readName, lastUnitLevel);
  133. readName = "上传红色指针读数";
  134. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  135. Constant.MB_REGISTER_ADD_UPLOAD_REDIND, Constant.MB_REGISTER_NUM_UPLOAD_REDIND);
  136. byte uploadRedind = (byte)(readRegisters[0] & 0xFF);
  137. runConfig.UploadRedindWRFlag = true;
  138. runConfig.UploadRedind = uploadRedind;
  139. GenerateSendAndRecvHexLog(true, readName);
  140. GenerateValueLog(readName, uploadRedind);
  141. readName = "表底读数";
  142. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  143. Constant.MB_REGISTER_ADD_LATEST_VALUE, Constant.MB_REGISTER_NUM_LATEST_VALUE);
  144. //4个寄存器
  145. ulong latestValue = ((ulong)readRegisters[0] << 48) | ((ulong)readRegisters[1] << 32) |
  146. ((ulong)readRegisters[2] << 16) | readRegisters[3];
  147. runConfig.LatestValueWRFlag = true;
  148. runConfig.LatestValue = latestValue;
  149. GenerateSendAndRecvHexLog(true, readName);
  150. GenerateValueLog(readName, latestValue);
  151. readName = "表底读数时间";
  152. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  153. Constant.MB_REGISTER_ADD_LATEST_TIME, Constant.MB_REGISTER_NUM_LATEST_TIME);
  154. //6个寄存器
  155. int year = (byte)(readRegisters[0] & 0xFF);
  156. int month = (byte)(readRegisters[1] & 0xFF);
  157. int day = (byte)(readRegisters[2] & 0xFF);
  158. int hour = (byte)(readRegisters[3] & 0xFF);
  159. int minute = (byte)(readRegisters[4] & 0xFF);
  160. int second = (byte)(readRegisters[5] & 0xFF);
  161. //DateTime dtLatestTime = new DateTime(2000 + year, month, day, hour, minute, second);
  162. //string latestTime = dtLatestTime.ToString("yyyy-MM-dd HH:mm:ss");
  163. string latestTime = $"{2000 + year}-{month.ToString("D2")}-{day.ToString("D2")} " +
  164. $"{hour.ToString("D2")}:{minute.ToString("D2")}:{second.ToString("D2")}";
  165. if (DateTime.TryParse(latestTime, out DateTime dtLatestTime))
  166. {
  167. runConfig.LatestTimeWRFlag = true;
  168. runConfig.LatestTime = dtLatestTime;
  169. }
  170. GenerateSendAndRecvHexLog(true, readName);
  171. GenerateValueLog(readName, latestTime);
  172. return runConfig;
  173. }
  174. catch (TimeoutException ex)
  175. {
  176. GenerateSendHexLog(readName);
  177. _message = $"读取{readName}超时,{ex.Message}";
  178. RWLog?.Invoke(_message);
  179. return null;
  180. }
  181. catch (SlaveException ex)
  182. {
  183. GenerateSendHexLog(readName);
  184. _message = $"读取{readName}Modbus错误,{ex.Message}";
  185. RWLog?.Invoke(_message);
  186. return null;
  187. }
  188. catch (Exception ex)
  189. {
  190. GenerateSendHexLog(readName);
  191. _message = $"读取{readName}错误,{ex.Message}";
  192. RWLog?.Invoke(_message);
  193. return null;
  194. }
  195. }
  196. private RunConfig GetRegionConfig(byte devId)
  197. {
  198. string readName = "";
  199. try
  200. {
  201. RunConfig runConfig = new RunConfig();
  202. ushort[] readRegisters;
  203. readName = "水表类型";
  204. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  205. Constant.MB_REGISTER_ADD_METER_TYPE, Constant.MB_REGISTER_NUM_METER_TYPE);
  206. byte meterType = (byte)(readRegisters[0] & 0xFF);
  207. runConfig.MeterTypeWRFlag = true;
  208. runConfig.MeterType = meterType;
  209. GenerateSendAndRecvHexLog(true, readName);
  210. _message = $"{readName}: {meterType}";
  211. RWLog?.Invoke(_message);
  212. readName = "表盘区域坐标";
  213. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  214. Constant.MB_REGISTER_ADD_METER_REGION, Constant.MB_REGISTER_NUM_METER_REGION);
  215. //4个寄存器
  216. string meterRegion = $"{readRegisters[0]},{readRegisters[1]} {readRegisters[2]},{readRegisters[3]}";
  217. runConfig.MeterRegionWRFlag = true;
  218. runConfig.MeterRegion = meterRegion;
  219. GenerateSendAndRecvHexLog(true, readName);
  220. GenerateValueLog(readName, meterRegion);
  221. if (meterType == Constant.METER_TYPE_NUM_IND || meterType == Constant.METER_TYPE_NUM)
  222. {
  223. readName = "数字区域坐标";
  224. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  225. Constant.MB_REGISTER_ADD_DIGIT_REGION, Constant.MB_REGISTER_NUM_DIGIT_REGION);
  226. //8个寄存器
  227. string digitRegion = $"{readRegisters[0]},{readRegisters[1]} {readRegisters[2]},{readRegisters[3]} " +
  228. $"{readRegisters[4]},{readRegisters[5]} {readRegisters[6]},{readRegisters[7]}";
  229. runConfig.DigitRegionWRFlag = true;
  230. runConfig.DigitRegion = digitRegion;
  231. GenerateSendAndRecvHexLog(true, readName);
  232. GenerateValueLog(readName, digitRegion);
  233. }
  234. if (meterType == Constant.METER_TYPE_IND)
  235. {
  236. readName = "首尾指针坐标";
  237. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  238. Constant.MB_REGISTER_ADD_FTIND_REGION, Constant.MB_REGISTER_NUM_FTIND_REGION);
  239. //4个寄存器
  240. string ftIndRegion = $"{readRegisters[0]},{readRegisters[1]} {readRegisters[2]},{readRegisters[3]}";
  241. runConfig.FTIndRegionWRFlag = true;
  242. runConfig.FTIndRegion = ftIndRegion;
  243. GenerateSendAndRecvHexLog(true, readName);
  244. GenerateValueLog(readName, ftIndRegion);
  245. }
  246. return runConfig;
  247. }
  248. catch (TimeoutException ex)
  249. {
  250. GenerateSendHexLog(readName);
  251. _message = $"读取{readName}超时,{ex.Message}";
  252. RWLog?.Invoke(_message);
  253. return null;
  254. }
  255. catch (SlaveException ex)
  256. {
  257. GenerateSendHexLog(readName);
  258. _message = $"读取{readName}Modbus错误,{ex.Message}";
  259. RWLog?.Invoke(_message);
  260. return null;
  261. }
  262. catch (Exception ex)
  263. {
  264. GenerateSendHexLog(readName);
  265. _message = $"读取{readName}错误,{ex.Message}";
  266. RWLog?.Invoke(_message);
  267. return null;
  268. }
  269. }
  270. private RunConfig GetSampleConfig(byte devId)
  271. {
  272. string readName = "";
  273. try
  274. {
  275. RunConfig runConfig = new RunConfig();
  276. ushort[] readRegisters;
  277. readName = "采样识别时间间隔(分)";
  278. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  279. Constant.MB_REGISTER_ADD_SAMPLE_INTERVAL, Constant.MB_REGISTER_NUM_SAMPLE_INTERVAL);
  280. ushort sampleInterval = readRegisters[0];
  281. runConfig.SampleIntervalFlag = true;
  282. runConfig.SampleInterval = sampleInterval;
  283. GenerateSendAndRecvHexLog(true, readName);
  284. GenerateValueLog(readName, sampleInterval);
  285. readName = "首次采样整点小时";
  286. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  287. Constant.MB_REGISTER_ADD_SAMPLE_FIRST_HOUR, Constant.MB_REGISTER_NUM_SAMPLE_FIRST_HOUR);
  288. byte firstHour = (byte)(readRegisters[0] & 0xFF);
  289. runConfig.FirstHourFlag = true;
  290. runConfig.FirstHour = firstHour;
  291. GenerateSendAndRecvHexLog(true, readName);
  292. GenerateValueLog(readName, firstHour);
  293. return runConfig;
  294. }
  295. catch (TimeoutException ex)
  296. {
  297. GenerateSendHexLog(readName);
  298. _message = $"读取{readName}超时,{ex.Message}";
  299. RWLog?.Invoke(_message);
  300. return null;
  301. }
  302. catch (SlaveException ex)
  303. {
  304. GenerateSendHexLog(readName);
  305. _message = $"读取{readName}Modbus错误,{ex.Message}";
  306. RWLog?.Invoke(_message);
  307. return null;
  308. }
  309. catch (Exception ex)
  310. {
  311. GenerateSendHexLog(readName);
  312. _message = $"读取{readName}错误,{ex.Message}";
  313. RWLog?.Invoke(_message);
  314. return null;
  315. }
  316. }
  317. private RunConfig GetRunConfig(byte devId)
  318. {
  319. string readName = "";
  320. try
  321. {
  322. RunConfig runConfig = new RunConfig();
  323. ushort[] readRegisters;
  324. readName = "水表类型";
  325. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  326. Constant.MB_REGISTER_ADD_METER_TYPE, Constant.MB_REGISTER_NUM_METER_TYPE);
  327. byte meterType = (byte)(readRegisters[0] & 0xFF);
  328. runConfig.MeterTypeWRFlag = true;
  329. runConfig.MeterType = meterType;
  330. GenerateSendAndRecvHexLog(true,readName);
  331. _message = $"{readName}: {meterType}";
  332. RWLog?.Invoke(_message);
  333. readName = "每小时最大流量";
  334. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  335. Constant.MB_REGISTER_ADD_DN_VALUE, Constant.MB_REGISTER_NUM_DN_VALUE);
  336. ushort dnValue = readRegisters[0];
  337. runConfig.DnValueWRFlag = true;
  338. runConfig.DnValue = dnValue;
  339. GenerateSendAndRecvHexLog(true, readName);
  340. _message = $"{readName}: {dnValue}";
  341. RWLog?.Invoke(_message);
  342. if (meterType == Constant.METER_TYPE_NUM_IND || meterType == Constant.METER_TYPE_NUM)
  343. {
  344. readName = "数字个数";
  345. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  346. Constant.MB_REGISTER_ADD_DIGIT_COUNT, Constant.MB_REGISTER_NUM_DIGIT_COUNT);
  347. byte digitCount = (byte)(readRegisters[0] & 0xFF);
  348. runConfig.DigitCountWRFlag = true;
  349. runConfig.DigitCount = digitCount;
  350. GenerateSendAndRecvHexLog(true, readName);
  351. GenerateValueLog(readName, digitCount);
  352. }
  353. if (meterType == Constant.METER_TYPE_NUM_IND || meterType == Constant.METER_TYPE_IND)
  354. {
  355. readName = "指针个数";
  356. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  357. Constant.MB_REGISTER_ADD_INDICATOR_COUNT, Constant.MB_REGISTER_NUM_INDICATOR_COUNT);
  358. byte indCount = (byte)(readRegisters[0] & 0xFF);
  359. runConfig.IndCountWRFlag = true;
  360. runConfig.IndCount = indCount;
  361. GenerateSendAndRecvHexLog(true, readName);
  362. GenerateValueLog(readName, indCount);
  363. }
  364. //此项已经不需要了
  365. /*readName = "照片亮度放大倍率";
  366. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  367. Constant.MB_REGISTER_ADD_BRIGHT_VALUE, Constant.MB_REGISTER_NUM_BRIGHT_VALUE);
  368. byte birghtValue = (byte)(readRegisters[0] & 0xFF); // 10f;
  369. runConfig.BrightValueWRFlag = true;
  370. runConfig.BrightValue = birghtValue / 10f;
  371. GenerateSendAndRecvHexLog(true, readName);
  372. GenerateValueLog(readName, birghtValue);*/
  373. readName = "尾数单位等级";
  374. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  375. Constant.MB_REGISTER_ADD_LAST_UNIT_LEVEL, Constant.MB_REGISTER_NUM_LAST_UNIT_LEVEL);
  376. byte lastUnitLevel = (byte)(readRegisters[0] & 0xFF);
  377. runConfig.LastUnitLevelWRFlag = true;
  378. runConfig.LastUnitLevel = lastUnitLevel;
  379. GenerateSendAndRecvHexLog(true, readName);
  380. GenerateValueLog(readName, lastUnitLevel);
  381. readName = "上传红色指针读数";
  382. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  383. Constant.MB_REGISTER_ADD_UPLOAD_REDIND, Constant.MB_REGISTER_NUM_UPLOAD_REDIND);
  384. byte uploadRedind = (byte)(readRegisters[0] & 0xFF);
  385. runConfig.UploadRedindWRFlag = true;
  386. runConfig.UploadRedind = uploadRedind;
  387. GenerateSendAndRecvHexLog(true, readName);
  388. GenerateValueLog(readName, uploadRedind);
  389. readName = "表底读数";
  390. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  391. Constant.MB_REGISTER_ADD_LATEST_VALUE, Constant.MB_REGISTER_NUM_LATEST_VALUE);
  392. //4个寄存器
  393. ulong latestValue = ((ulong)readRegisters[0] << 48) | ((ulong)readRegisters[1] << 32) |
  394. ((ulong)readRegisters[2] << 16) | readRegisters[3];
  395. runConfig.LatestValueWRFlag = true;
  396. runConfig.LatestValue = latestValue;
  397. GenerateSendAndRecvHexLog(true, readName);
  398. GenerateValueLog(readName, latestValue);
  399. readName = "表底读数时间";
  400. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  401. Constant.MB_REGISTER_ADD_LATEST_TIME, Constant.MB_REGISTER_NUM_LATEST_TIME);
  402. //6个寄存器
  403. int year = (byte)(readRegisters[0] & 0xFF);
  404. int month = (byte)(readRegisters[1] & 0xFF);
  405. int day = (byte)(readRegisters[2] & 0xFF);
  406. int hour = (byte)(readRegisters[3] & 0xFF);
  407. int minute = (byte)(readRegisters[4] & 0xFF);
  408. int second = (byte)(readRegisters[5] & 0xFF);
  409. //DateTime dtLatestTime = new DateTime(2000 + year, month, day, hour, minute, second);
  410. //string latestTime = dtLatestTime.ToString("yyyy-MM-dd HH:mm:ss");
  411. string latestTime = $"{2000 + year}-{month.ToString("D2")}-{day.ToString("D2")} " +
  412. $"{hour.ToString("D2")}:{minute.ToString("D2")}:{second.ToString("D2")}";
  413. if(DateTime.TryParse(latestTime,out DateTime dtLatestTime))
  414. {
  415. runConfig.LatestTimeWRFlag = true;
  416. runConfig.LatestTime = dtLatestTime;
  417. }
  418. GenerateSendAndRecvHexLog(true, readName);
  419. GenerateValueLog(readName, latestTime);
  420. readName = "表盘区域坐标";
  421. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  422. Constant.MB_REGISTER_ADD_METER_REGION, Constant.MB_REGISTER_NUM_METER_REGION);
  423. //4个寄存器
  424. string meterRegion = $"{readRegisters[0]},{readRegisters[1]} {readRegisters[2]},{readRegisters[3]}";
  425. runConfig.MeterRegionWRFlag = true;
  426. runConfig.MeterRegion = meterRegion;
  427. GenerateSendAndRecvHexLog(true, readName);
  428. GenerateValueLog(readName, meterRegion);
  429. if (meterType == Constant.METER_TYPE_NUM_IND || meterType == Constant.METER_TYPE_NUM)
  430. {
  431. readName = "数字区域坐标";
  432. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  433. Constant.MB_REGISTER_ADD_DIGIT_REGION, Constant.MB_REGISTER_NUM_DIGIT_REGION);
  434. //8个寄存器
  435. string digitRegion = $"{readRegisters[0]},{readRegisters[1]} {readRegisters[2]},{readRegisters[3]} " +
  436. $"{readRegisters[4]},{readRegisters[5]} {readRegisters[6]},{readRegisters[7]}";
  437. runConfig.DigitRegionWRFlag = true;
  438. runConfig.DigitRegion = digitRegion;
  439. GenerateSendAndRecvHexLog(true, readName);
  440. GenerateValueLog(readName, digitRegion);
  441. }
  442. if (meterType == Constant.METER_TYPE_IND)
  443. {
  444. readName = "首尾指针坐标";
  445. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  446. Constant.MB_REGISTER_ADD_FTIND_REGION, Constant.MB_REGISTER_NUM_FTIND_REGION);
  447. //4个寄存器
  448. string ftIndRegion = $"{readRegisters[0]},{readRegisters[1]} {readRegisters[2]},{readRegisters[3]}";
  449. runConfig.FTIndRegionWRFlag = true;
  450. runConfig.FTIndRegion = ftIndRegion;
  451. GenerateSendAndRecvHexLog(true, readName);
  452. GenerateValueLog(readName, ftIndRegion);
  453. }
  454. readName = "采样识别时间间隔(分)";
  455. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  456. Constant.MB_REGISTER_ADD_SAMPLE_INTERVAL, Constant.MB_REGISTER_NUM_SAMPLE_INTERVAL);
  457. ushort sampleInterval = readRegisters[0];
  458. runConfig.SampleIntervalFlag = true;
  459. runConfig.SampleInterval = sampleInterval;
  460. GenerateSendAndRecvHexLog(true, readName);
  461. GenerateValueLog(readName, sampleInterval);
  462. readName = "首次采样整点小时";
  463. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  464. Constant.MB_REGISTER_ADD_SAMPLE_FIRST_HOUR, Constant.MB_REGISTER_NUM_SAMPLE_FIRST_HOUR);
  465. byte firstHour = (byte)(readRegisters[0] & 0xFF);
  466. runConfig.FirstHourFlag = true;
  467. runConfig.FirstHour = firstHour;
  468. GenerateSendAndRecvHexLog(true, readName);
  469. GenerateValueLog(readName, lastUnitLevel);
  470. return runConfig;
  471. }
  472. catch (TimeoutException ex)
  473. {
  474. GenerateSendHexLog(readName);
  475. _message = $"读取{readName}超时,{ex.Message}";
  476. RWLog?.Invoke(_message);
  477. return null;
  478. }
  479. catch (SlaveException ex)
  480. {
  481. GenerateSendHexLog(readName);
  482. _message = $"读取{readName}Modbus错误,{ex.Message}";
  483. RWLog?.Invoke(_message);
  484. return null;
  485. }
  486. catch (Exception ex)
  487. {
  488. GenerateSendHexLog(readName);
  489. _message = $"读取{readName}错误,{ex.Message}";
  490. RWLog?.Invoke(_message);
  491. return null;
  492. }
  493. }
  494. public WMData ReadWMData(string portName,int baudrate,byte devId)
  495. {
  496. WMData wmData = null;
  497. _portName = portName;
  498. _baudrate = baudrate;
  499. _address = devId;
  500. if (OpenSerial(portName, baudrate))
  501. {
  502. wmData = GetWMData(devId);
  503. }
  504. CloseSerial();
  505. return wmData;
  506. }
  507. private WMData GetWMData(byte devId)
  508. {
  509. string readName = "";
  510. try
  511. {
  512. WMData data = new WMData();
  513. ushort[] readRegisters;
  514. readName = "波特率";
  515. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  516. Constant.MB_REGISTER_ADD_BAUDRATE, Constant.MB_REGISTER_NUM_BAUDRATE);
  517. //data.BaudRate = readRegisters[0];
  518. byte baudRateType = (byte)(readRegisters[0] & 0xFF);
  519. int baudRate = Tools.GetBaudRate(baudRateType);
  520. data.BaudRate = baudRate;
  521. GenerateSendAndRecvHexLog(true, readName);
  522. GenerateValueLog(readName, baudRate);
  523. readName = "485地址";
  524. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  525. Constant.MB_REGISTER_ADD_ADDRESS, Constant.MB_REGISTER_NUM_ADDRESS);
  526. byte slaveAddress = (byte)(readRegisters[0] & 0xFF);
  527. data.SlaveAddress = slaveAddress;
  528. GenerateSendAndRecvHexLog(true, readName);
  529. GenerateValueLog(readName, slaveAddress);
  530. readName = "固件版本";
  531. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  532. Constant.MB_REGISTER_ADD_FIREWARE, Constant.MB_REGISTER_NUM_FIREWARE);
  533. string fireware = $"{(readRegisters[0] & 0xFF).ToString("D2")}." +
  534. $"{(readRegisters[1] >> 8).ToString("D2")}." +
  535. $"{(readRegisters[1] & 0xFF).ToString("D2")}";
  536. data.McuVer = fireware;
  537. GenerateSendAndRecvHexLog(true, readName);
  538. GenerateValueLog(readName, fireware);
  539. readName = "设备SN";
  540. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  541. Constant.MB_REGISTER_ADD_DEVICE_SN, Constant.MB_REGISTER_NUM_DEVICE_SN);
  542. string deviceSn = Tools.SNBcdToString(readRegisters);
  543. data.DeviceSn = deviceSn;
  544. GenerateSendAndRecvHexLog(true, deviceSn);
  545. GenerateValueLog(readName, deviceSn);
  546. //水表类型,暂无
  547. readName = "累计用水量";
  548. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  549. Constant.MB_REGISTER_ADD_SAMPLE_RESULT, Constant.MB_REGISTER_NUM_SAMPLE_RESULT);
  550. ulong sampleResult = ((ulong)readRegisters[0] << 48) |
  551. ((ulong)readRegisters[1] << 32) | ((ulong)readRegisters[2] << 16) | readRegisters[3];
  552. data.TotalFlow = sampleResult;
  553. GenerateSendAndRecvHexLog(true, readName);
  554. GenerateValueLog(readName, sampleResult);
  555. readName = "采样时间";
  556. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  557. Constant.MB_REGISTER_ADD_SAMPLE_TIME, Constant.MB_REGISTER_NUM_SAMPLE_TIME);
  558. GenerateSendAndRecvHexLog(true, readName);
  559. //DateTime sampleTime = new DateTime(2000+ readRegisters[0], readRegisters[1],
  560. // readRegisters[2], readRegisters[3], readRegisters[4], readRegisters[5]);
  561. string strSampleTime = $"{2000 + readRegisters[0]}-{readRegisters[1]}-{readRegisters[2]} " +
  562. $"{readRegisters[3]}:{readRegisters[4]}:{readRegisters[5]}";
  563. if(DateTime.TryParse(strSampleTime,out DateTime sampleTime))
  564. {
  565. data.SampleTime = sampleTime;
  566. }
  567. else
  568. {
  569. RWLog?.Invoke($"采样时间错误:{readRegisters[0]}-{readRegisters[1]}-{readRegisters[2]} " +
  570. $"{readRegisters[3]}:{readRegisters[4]}:{readRegisters[5]}");
  571. data.SampleTime = DateTime.MinValue;
  572. }
  573. GenerateValueLog(readName, sampleTime.ToString("yyyy-MM-dd HH:mm"));
  574. //结果说明
  575. readName = "识别结果类型";
  576. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  577. Constant.MB_REGISTER_ADD_RESULT_TYPE, Constant.MB_REGISTER_NUM_RESULT_TYPE);
  578. byte resultType = (byte)(readRegisters[0] & 0xFF);
  579. data.ResultType = resultType;
  580. GenerateSendAndRecvHexLog(true, readName);
  581. GenerateValueLog(readName, resultType);
  582. //保留的小数位数
  583. readName = "单位为立方时保留的小数位数";
  584. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  585. Constant.MB_REGISTER_ADD_RESULT_DECIMAL_PLACES, Constant.MB_REGISTER_NUM_RESULT_DECIMAL_PLACES);
  586. byte decimalPlaces = (byte)(readRegisters[0] & 0xFF);
  587. data.ResultDecimalPlaces = decimalPlaces;
  588. GenerateSendAndRecvHexLog(true, readName);
  589. GenerateValueLog(readName, decimalPlaces);
  590. return data;
  591. }
  592. catch(TimeoutException ex)
  593. {
  594. _message = $"读取{readName}超时,{ex.Message}";
  595. _lastErrorMessage = _message;
  596. RWLog?.Invoke(_message);
  597. return null;
  598. }
  599. catch(SlaveException ex)
  600. {
  601. GenerateSendHexLog(readName);
  602. _message = $"读取{readName}Modbus错误,{ex.Message}";
  603. _lastErrorMessage = _message;
  604. RWLog?.Invoke(_message);
  605. return null;
  606. }
  607. catch(Exception ex)
  608. {
  609. GenerateSendHexLog(readName);
  610. _message = $"读取{readName}错误,{ex.Message}";
  611. _lastErrorMessage = _message;
  612. RWLog?.Invoke(_message);
  613. return null;
  614. }
  615. }
  616. //读取抄表器的当前时钟
  617. public string ReadDeviceTime(string portName,int baudrate,byte devId)
  618. {
  619. string deviceTime = null;
  620. _portName = portName;
  621. _baudrate = baudrate;
  622. _address = devId;
  623. if (OpenSerial(portName, baudrate))
  624. {
  625. deviceTime = GetDeviceTime(devId);
  626. }
  627. CloseSerial();
  628. return deviceTime;
  629. }
  630. private string GetDeviceTime(byte devId)
  631. {
  632. string readName = "";
  633. try
  634. {
  635. readName = "读抄表器时钟";
  636. ushort[] readRegisters;
  637. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  638. Constant.MB_REGISTER_ADD_DEVICE_TIME, Constant.MB_REGISTER_NUM_DEVICE_TIME);
  639. int year = (byte)(readRegisters[0] & 0xFF);
  640. int month = (byte)(readRegisters[1] & 0xFF);
  641. int day = (byte)(readRegisters[2] & 0xFF);
  642. int hour = (byte)(readRegisters[3] & 0xFF);
  643. int minute = (byte)(readRegisters[4] & 0xFF);
  644. int second = (byte)(readRegisters[5] & 0xFF);
  645. string deviceTime = $"{2000 + year}-{month.ToString("D2")}-{day.ToString("D2")} " +
  646. $"{hour.ToString("D2")}:{minute.ToString("D2")}:{second.ToString("D2")}";
  647. GenerateSendAndRecvHexLog(true, readName);
  648. GenerateValueLog(readName, deviceTime);
  649. return deviceTime;
  650. }
  651. catch (TimeoutException ex)
  652. {
  653. _message = $"读取{readName}超时,{ex.Message}";
  654. _lastErrorMessage = _message;
  655. RWLog?.Invoke(_message);
  656. return null;
  657. }
  658. catch (SlaveException ex)
  659. {
  660. GenerateSendHexLog(readName);
  661. _message = $"读取{readName}Modbus错误,{ex.Message}";
  662. _lastErrorMessage = _message;
  663. RWLog?.Invoke(_message);
  664. return null;
  665. }
  666. catch (Exception ex)
  667. {
  668. GenerateSendHexLog(readName);
  669. _message = $"读取{readName}错误,{ex.Message}";
  670. _lastErrorMessage = _message;
  671. RWLog?.Invoke(_message);
  672. return null;
  673. }
  674. }
  675. public bool ReadFireware(string portName,int baudrate,byte devId,out string deviceSn,out string fireware)
  676. {
  677. bool blRead = false;
  678. deviceSn = "";
  679. fireware = "";
  680. _portName = portName;
  681. _baudrate = baudrate;
  682. _address = devId;
  683. if (OpenSerial(portName, baudrate))
  684. {
  685. blRead = GetFirewareInfo(devId, out deviceSn, out fireware);
  686. }
  687. CloseSerial();
  688. return blRead;
  689. }
  690. private bool GetFirewareInfo(byte devId,out string outDeviceSn,out string outFireware)
  691. {
  692. outDeviceSn = "";
  693. outFireware = "";
  694. string readName = "";
  695. try
  696. {
  697. ushort[] readRegisters;
  698. readName = "固件版本";
  699. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  700. Constant.MB_REGISTER_ADD_FIREWARE, Constant.MB_REGISTER_NUM_FIREWARE);
  701. string fireware = $"{(readRegisters[0] & 0xFF).ToString("D2")}." +
  702. $"{(readRegisters[1] >> 8).ToString("D2")}." +
  703. $"{(readRegisters[1] & 0xFF).ToString("D2")}";
  704. outFireware = fireware;
  705. GenerateSendAndRecvHexLog(true, readName);
  706. GenerateValueLog(readName, fireware);
  707. readName = "设备SN";
  708. readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  709. Constant.MB_REGISTER_ADD_DEVICE_SN, Constant.MB_REGISTER_NUM_DEVICE_SN);
  710. string deviceSn = Tools.SNBcdToString(readRegisters);
  711. outDeviceSn = deviceSn;
  712. GenerateSendAndRecvHexLog(true, deviceSn);
  713. GenerateValueLog(readName, deviceSn);
  714. return true;
  715. }
  716. catch (TimeoutException ex)
  717. {
  718. GenerateSendHexLog(readName);
  719. _message = $"读取{readName}超时,{ex.Message}";
  720. _lastErrorMessage = _message;
  721. RWLog?.Invoke(_message);
  722. return false;
  723. }
  724. catch (SlaveException ex)
  725. {
  726. GenerateSendHexLog(readName);
  727. _message = $"读取{readName}Modbus错误,{ex.Message}";
  728. _lastErrorMessage = _message;
  729. RWLog?.Invoke(_message);
  730. return false;
  731. }
  732. catch (Exception ex)
  733. {
  734. GenerateSendHexLog(readName);
  735. _message = $"读取{readName}错误,{ex.Message}";
  736. _lastErrorMessage = _message;
  737. RWLog?.Invoke(_message);
  738. return false;
  739. }
  740. }
  741. //读取照片字节数
  742. public ushort ReadImageSize(string portName,int baudrate,byte devId)
  743. {
  744. _portName = portName;
  745. _baudrate = baudrate;
  746. _address = devId;
  747. ushort imageSize = 0;
  748. if (OpenSerial(portName, baudrate))
  749. {
  750. string readName = ""; // = "照片文件大小";
  751. try
  752. {
  753. readName = "照片文件大小";
  754. //读取照片字节数
  755. ushort[] readRegisters = _modbusMaster.ReadHoldingRegisters(devId, Constant.MB_REGISTER_IMAGE_SIZE, 1);
  756. imageSize = readRegisters[0];
  757. GenerateSendAndRecvHexLog(true, readName);
  758. GenerateValueLog(readName, imageSize);
  759. }
  760. catch (TimeoutException ex)
  761. {
  762. GenerateSendHexLog(readName);
  763. _message = $"读取{readName}超时,{ex.Message}";
  764. _lastErrorMessage = _message;
  765. RWLog?.Invoke(_message);
  766. }
  767. catch(SlaveException ex)
  768. {
  769. GenerateSendHexLog(readName);
  770. _message = $"读取{readName}Modbus错误,{ex.Message}";
  771. _lastErrorMessage = _message;
  772. RWLog?.Invoke(_message);
  773. }
  774. catch(Exception ex)
  775. {
  776. GenerateSendHexLog(readName);
  777. _message = $"读取{readName}错误,{ex.Message}";
  778. _lastErrorMessage = _message;
  779. RWLog?.Invoke(_message);
  780. }
  781. }
  782. CloseSerial();
  783. return imageSize;
  784. }
  785. public bool ConnectTest(string portName, int baudrate, byte devId,out string message)
  786. {
  787. _portName = portName;
  788. _baudrate = baudrate;
  789. _address = devId;
  790. bool blConnected = false;
  791. if (OpenSerial(portName, baudrate))
  792. {
  793. string readName = ""; // = "照片文件大小";
  794. try
  795. {
  796. readName = "设备地址";
  797. //读取照片字节数
  798. ushort[] readRegisters = _modbusMaster.ReadHoldingRegisters(devId,
  799. Constant.MB_REGISTER_ADD_ADDRESS, Constant.MB_REGISTER_NUM_ADDRESS);
  800. byte slaveAddress = (byte)(readRegisters[0] & 0xFF);
  801. blConnected = slaveAddress == devId;
  802. GenerateSendAndRecvHexLog(true, readName);
  803. GenerateValueLog(readName, devId);
  804. }
  805. catch (Exception ex)
  806. {
  807. GenerateSendHexLog(readName);
  808. _lastErrorMessage = $"{_message},{ex.Message}";
  809. RWLog?.Invoke(_message);
  810. }
  811. }
  812. CloseSerial();
  813. _message = $"端口:{portName},波特率:{baudrate},设备地址:{devId},连接测试{(blConnected ? "通过":"失败")}";
  814. RWLog?.Invoke(_message);
  815. message = _message;
  816. return blConnected;
  817. }
  818. public bool WriteRunConfig(string portName,int baudrate,byte devId,RunConfig runConfig)
  819. {
  820. bool blWrite = false;
  821. _portName = portName;
  822. _baudrate = baudrate;
  823. _address = devId;
  824. if (OpenSerial(portName,baudrate))
  825. {
  826. blWrite = SetRunConfig(devId,runConfig);
  827. }
  828. CloseSerial();
  829. return blWrite;
  830. }
  831. //向设备写入配置值
  832. private bool SetRunConfig(byte devId,RunConfig runConfig)
  833. {
  834. bool blWrite = false;
  835. string writeName = "";
  836. try
  837. {
  838. if (runConfig.MeterTypeWRFlag)
  839. {
  840. writeName = "水表类型";
  841. _modbusMaster.WriteSingleRegister(devId, Constant.MB_REGISTER_ADD_METER_TYPE, runConfig.MeterType);
  842. GenerateValueLog(writeName, runConfig.LatestValue);
  843. GenerateSendAndRecvHexLog(false, writeName);
  844. }
  845. if (runConfig.DnValueWRFlag)
  846. {
  847. writeName = "每小时最大水流";
  848. _modbusMaster.WriteSingleRegister(devId, Constant.MB_REGISTER_ADD_DN_VALUE, runConfig.DnValue);
  849. GenerateValueLog(writeName, runConfig.DnValue);
  850. GenerateSendAndRecvHexLog(false, writeName);
  851. }
  852. if (runConfig.DigitCountWRFlag)
  853. {
  854. writeName = "数字个数";
  855. _modbusMaster.WriteSingleRegister(devId, Constant.MB_REGISTER_ADD_DIGIT_COUNT, runConfig.DigitCount);
  856. GenerateValueLog(writeName, runConfig.DigitCount);
  857. GenerateSendAndRecvHexLog(false, writeName);
  858. }
  859. if (runConfig.IndCountWRFlag)
  860. {
  861. writeName = "指针个数";
  862. _modbusMaster.WriteSingleRegister(devId, Constant.MB_REGISTER_ADD_INDICATOR_COUNT, runConfig.IndCount);
  863. GenerateValueLog(writeName, runConfig.IndCount);
  864. GenerateSendAndRecvHexLog(false, writeName);
  865. }
  866. //此项已经不需要了
  867. /*if (runConfig.BrightValueWRFlag)
  868. {
  869. writeName = "照片亮度系数";
  870. ushort brightValue = (ushort)(runConfig.BrightValue * 10);
  871. _modbusMaster.WriteSingleRegister(devId, Constant.MB_REGISTER_ADD_BRIGHT_VALUE, brightValue);
  872. GenerateValueLog(writeName, runConfig.BrightValue);
  873. GenerateSendAndRecvHexLog(false, writeName);
  874. }*/
  875. if (runConfig.LastUnitLevelWRFlag)
  876. {
  877. writeName = "尾数单位等级";
  878. _modbusMaster.WriteSingleRegister(devId, Constant.MB_REGISTER_ADD_LAST_UNIT_LEVEL, runConfig.LastUnitLevel);
  879. GenerateValueLog(writeName, runConfig.LastUnitLevel);
  880. GenerateSendAndRecvHexLog(false, writeName);
  881. }
  882. if (runConfig.UploadRedindWRFlag)
  883. {
  884. writeName = "上传红色指针读数";
  885. _modbusMaster.WriteSingleRegister(devId, Constant.MB_REGISTER_ADD_UPLOAD_REDIND , runConfig.UploadRedind);
  886. GenerateValueLog(writeName, runConfig.UploadRedind);
  887. GenerateSendAndRecvHexLog(false, writeName);
  888. }
  889. if (runConfig.LatestValueWRFlag)
  890. {
  891. writeName = "表底读数";
  892. _modbusMaster.WriteMultipleRegisters(devId, Constant.MB_REGISTER_ADD_LATEST_VALUE, runConfig.LatestValues);
  893. GenerateValueLog(writeName, runConfig.LatestValue);
  894. GenerateSendAndRecvHexLog(false, writeName);
  895. }
  896. if (runConfig.LatestTimeWRFlag && runConfig.LatestTimes != null)
  897. {
  898. writeName = "表底读数时间";
  899. _modbusMaster.WriteMultipleRegisters(devId, Constant.MB_REGISTER_ADD_LATEST_TIME, runConfig.LatestTimes);
  900. GenerateValueLog(writeName, runConfig.LatestTime.ToString("yyyy-MM-dd HH:mm:ss"));
  901. GenerateSendAndRecvHexLog(false, writeName);
  902. }
  903. if (runConfig.MeterRegionWRFlag && runConfig.MeterRegions != null)
  904. {
  905. writeName = "表盘区域坐标";
  906. _modbusMaster.WriteMultipleRegisters(devId, Constant.MB_REGISTER_ADD_METER_REGION, runConfig.MeterRegions);
  907. GenerateValueLog(writeName, runConfig.MeterRegion);
  908. GenerateSendAndRecvHexLog(false, writeName);
  909. }
  910. if (runConfig.DigitRegionWRFlag && runConfig.DigitRegions != null)
  911. {
  912. writeName = "数字区域坐标";
  913. _modbusMaster.WriteMultipleRegisters(devId, Constant.MB_REGISTER_ADD_DIGIT_REGION, runConfig.DigitRegions);
  914. GenerateValueLog(writeName, runConfig.DigitRegion);
  915. GenerateSendAndRecvHexLog(false, writeName);
  916. }
  917. if (runConfig.FTIndRegionWRFlag && runConfig.FTIndRegions != null)
  918. {
  919. writeName = "指针水表首尾同刻度坐标";
  920. _modbusMaster.WriteMultipleRegisters(devId, Constant.MB_REGISTER_ADD_FTIND_REGION, runConfig.FTIndRegions);
  921. GenerateValueLog(writeName, runConfig.FTIndRegion);
  922. GenerateSendAndRecvHexLog(false, writeName);
  923. }
  924. if (runConfig.SampleIntervalFlag)
  925. {
  926. writeName = "识别采样时间间隔(分)";
  927. _modbusMaster.WriteSingleRegister(devId, Constant.MB_REGISTER_ADD_SAMPLE_INTERVAL, runConfig.SampleInterval);
  928. GenerateValueLog(writeName, runConfig.SampleInterval);
  929. GenerateSendAndRecvHexLog(false, writeName);
  930. }
  931. if (runConfig.FirstHourFlag)
  932. {
  933. writeName = "每日首次采样";
  934. _modbusMaster.WriteSingleRegister(devId, Constant.MB_REGISTER_ADD_SAMPLE_FIRST_HOUR, runConfig.FirstHour);
  935. GenerateValueLog(writeName, runConfig.FirstHour);
  936. GenerateSendAndRecvHexLog(false, writeName);
  937. }
  938. writeName = "配置确认";
  939. _modbusMaster.WriteSingleRegister(devId, Constant.MB_REGISTER_ADD_EFFECT_FLAG, 1);
  940. GenerateValueLog(writeName, runConfig.LatestValue);
  941. GenerateSendAndRecvHexLog(false, writeName);
  942. blWrite = true;
  943. }
  944. catch (TimeoutException ex)
  945. {
  946. GenerateSendHexLog(writeName);
  947. _message = $"写入{writeName}超时,{ex.Message}";
  948. _lastErrorMessage = _message;
  949. RWLog?.Invoke(_message);
  950. }
  951. catch (SlaveException ex)
  952. {
  953. GenerateSendHexLog(writeName);
  954. _message = $"写入{writeName}Modbus错误,{ex.Message}";
  955. _lastErrorMessage = _message;
  956. RWLog?.Invoke(_message);
  957. }
  958. catch (Exception ex)
  959. {
  960. GenerateSendHexLog(writeName);
  961. _message = $"写入{writeName}错误,{ex.Message}";
  962. _lastErrorMessage = _message;
  963. RWLog?.Invoke(_message);
  964. }
  965. return blWrite;
  966. }
  967. public bool WriteDeviceTime(string portName,int baudrate,byte devId,DateTime dateTime)
  968. {
  969. bool blWrite = false;
  970. _portName = portName;
  971. _baudrate = baudrate;
  972. _address = devId;
  973. if (OpenSerial(portName, baudrate))
  974. {
  975. blWrite = SetDeviceTime(devId, dateTime);
  976. }
  977. CloseSerial();
  978. return blWrite;
  979. }
  980. private bool SetDeviceTime(byte devId,DateTime dateTime)
  981. {
  982. bool blWrite = false;
  983. string writeName = "";
  984. try
  985. {
  986. writeName = "抄表器时钟";
  987. ushort[] result = new ushort[6];
  988. result[0] = (ushort)(dateTime.Year - 2000);
  989. result[1] = (ushort)dateTime.Month;
  990. result[2] = (ushort)dateTime.Day;
  991. result[3] = (ushort)dateTime.Hour;
  992. result[4] = (ushort)dateTime.Minute;
  993. result[5] = (ushort)dateTime.Second;
  994. _modbusMaster.WriteMultipleRegisters(devId, Constant.MB_REGISTER_ADD_DEVICE_TIME , result);
  995. GenerateValueLog(writeName, dateTime.ToString("yyyy-MM-dd HH:mm:ss"));
  996. GenerateSendAndRecvHexLog(false, writeName);
  997. blWrite = true;
  998. }
  999. catch (TimeoutException ex)
  1000. {
  1001. GenerateSendHexLog(writeName);
  1002. _message = $"写入{writeName}超时,{ex.Message}";
  1003. _lastErrorMessage = _message;
  1004. RWLog?.Invoke(_message);
  1005. }
  1006. catch (SlaveException ex)
  1007. {
  1008. GenerateSendHexLog(writeName);
  1009. _message = $"写入{writeName}Modbus错误,{ex.Message}";
  1010. _lastErrorMessage = _message;
  1011. RWLog?.Invoke(_message);
  1012. }
  1013. catch (Exception ex)
  1014. {
  1015. GenerateSendHexLog(writeName);
  1016. _message = $"写入{writeName}错误,{ex.Message}";
  1017. _lastErrorMessage = _message;
  1018. RWLog?.Invoke(_message);
  1019. }
  1020. return blWrite;
  1021. }
  1022. //设置抄表器进行固件版本的回滚
  1023. public bool WriteDeviceRollback(string portName,int baudrate,byte devId)
  1024. {
  1025. bool blWrite = false;
  1026. _portName = portName;
  1027. _baudrate = baudrate;
  1028. _address = devId;
  1029. if (OpenSerial(portName, baudrate))
  1030. {
  1031. blWrite = SetDeviceRollback(devId);
  1032. }
  1033. CloseSerial();
  1034. return blWrite;
  1035. }
  1036. private bool SetDeviceRollback(byte devId)
  1037. {
  1038. bool blWrite = false;
  1039. string writeName = "";
  1040. try
  1041. {
  1042. writeName = "固件版本回滚";
  1043. _modbusMaster.WriteSingleRegister(devId, Constant.MB_REGISTER_ADD_FIREWARE_ROLLBACK, 0x0001);
  1044. GenerateValueLog(writeName, "=1");
  1045. GenerateSendAndRecvHexLog(false, writeName);
  1046. blWrite = true;
  1047. }
  1048. catch (TimeoutException ex)
  1049. {
  1050. GenerateSendHexLog(writeName);
  1051. _message = $"写入{writeName}超时,{ex.Message}";
  1052. _lastErrorMessage = _message;
  1053. RWLog?.Invoke(_message);
  1054. }
  1055. catch (SlaveException ex)
  1056. {
  1057. GenerateSendHexLog(writeName);
  1058. _message = $"写入{writeName}Modbus错误,{ex.Message}";
  1059. _lastErrorMessage = _message;
  1060. RWLog?.Invoke(_message);
  1061. }
  1062. catch (Exception ex)
  1063. {
  1064. GenerateSendHexLog(writeName);
  1065. _message = $"写入{writeName}错误,{ex.Message}";
  1066. _lastErrorMessage = _message;
  1067. RWLog?.Invoke(_message);
  1068. }
  1069. return blWrite;
  1070. }
  1071. //写升级包的信息
  1072. public bool WrtieUpgradeInfo(string portName,int baudrate,byte devId,uint fileSize,uint fileCrc32)
  1073. {
  1074. bool blWrite = false;
  1075. _portName = portName;
  1076. _baudrate = baudrate;
  1077. _address = devId;
  1078. if (OpenSerial(portName, baudrate))
  1079. {
  1080. blWrite = SetUpgradeInfo(devId, fileSize, fileCrc32);
  1081. }
  1082. CloseSerial();
  1083. return blWrite;
  1084. }
  1085. private bool SetUpgradeInfo(byte devId,uint fileSize,uint fileCrc32)
  1086. {
  1087. bool blWrite = false;
  1088. string writeName = "";
  1089. try
  1090. {
  1091. writeName = "升级文件信息";
  1092. ushort[] infos = new ushort[4];
  1093. infos[0] = (ushort)(fileSize >> 16);
  1094. infos[1] = (ushort)(fileSize & 0xFFFF);
  1095. infos[2] = (ushort)(fileCrc32 >> 16);
  1096. infos[3] = (ushort)(fileCrc32 & 0xFFFF);
  1097. _modbusMaster.WriteMultipleRegisters(devId, Constant.MB_REGISTER_ADD_UPGRADE_DATA, infos);
  1098. string upgradeInfo = $"文件长度: {fileSize},CRC32: {fileCrc32}";
  1099. GenerateValueLog(writeName, upgradeInfo);
  1100. GenerateSendAndRecvHexLog(false, writeName);
  1101. blWrite = true;
  1102. }
  1103. catch (TimeoutException ex)
  1104. {
  1105. GenerateSendHexLog(writeName);
  1106. _message = $"写入{writeName}超时,{ex.Message}";
  1107. RWLog?.Invoke(_message);
  1108. }
  1109. catch (SlaveException ex)
  1110. {
  1111. GenerateSendHexLog(writeName);
  1112. _message = $"写入{writeName}Modbus错误,{ex.Message}";
  1113. RWLog?.Invoke(_message);
  1114. }
  1115. catch (Exception ex)
  1116. {
  1117. GenerateSendHexLog(writeName);
  1118. _message = $"写入{writeName}错误,{ex.Message}";
  1119. RWLog?.Invoke(_message);
  1120. }
  1121. return blWrite;
  1122. }
  1123. private bool OpenSerial(string portName, int baudRate)
  1124. {
  1125. CloseSerial();
  1126. try
  1127. {
  1128. //除去波特率外,其它参数默认为不会被修改
  1129. SerialPort serialPort = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
  1130. serialPort.ReadTimeout = 1000; //读取的超时时间应该短一些
  1131. serialPort.WriteTimeout = 1000;
  1132. serialPort.Open();
  1133. _serialPort = serialPort;
  1134. _modbusMaster = ModbusSerialMaster.CreateRtu(_serialPort);
  1135. _modbusTransport = (ModbusSerialTransport)_modbusMaster.Transport;
  1136. //_modbusTransport.Retries = 1;
  1137. //_modbusTransport.WaitToRetryMilliseconds = 1000;
  1138. //_modbusTransport.RetryOnOldResponseThreshold = 500;
  1139. _message = $"串口{portName}连接成功";
  1140. RWLog?.Invoke(_message);
  1141. Logger.Info(_message);
  1142. SerialConnected?.Invoke(true,_portName,_baudrate,_address);
  1143. return true;
  1144. }
  1145. catch (Exception ex)
  1146. {
  1147. _message = $"串口{portName}连接失败";
  1148. _lastErrorMessage = ex.Message;
  1149. RWLog?.Invoke(_message);
  1150. SerialConnected?.Invoke(false,_portName,_baudrate,_address);
  1151. Logger.Info(_message);
  1152. Logger.Error(ex.Message);
  1153. return false;
  1154. }
  1155. }
  1156. private void CloseSerial()
  1157. {
  1158. try
  1159. {
  1160. if (_serialPort != null)
  1161. {
  1162. if (_serialPort.IsOpen)
  1163. {
  1164. _serialPort.Close();
  1165. _message = $"串口{_portName}已关闭";
  1166. SerialStatusChanged?.Invoke(false,_portName,_baudrate,_address); //串口关闭
  1167. RWLog?.Invoke(_message);
  1168. Logger.Info(_message);
  1169. }
  1170. _serialPort.Dispose();
  1171. _serialPort = null;
  1172. }
  1173. _modbusTransport?.Dispose();
  1174. _modbusTransport = null;
  1175. }
  1176. catch (Exception ex)
  1177. {
  1178. _message = $"关闭串口{_portName}失败: {ex.Message}";
  1179. _lastErrorMessage = _message;
  1180. RWLog?.Invoke(_message);
  1181. Logger.Error(_message);
  1182. }
  1183. }
  1184. private void GenerateValueLog(string readName,object value)
  1185. {
  1186. _message = $"{readName}: {value.ToString()}";
  1187. RWLog?.Invoke(_message);
  1188. }
  1189. private void GenerateSendHexLog(string readName)
  1190. {
  1191. _message = $"读取{readName},发送: {GetSendDataString()}";
  1192. RWLog?.Invoke(_message);
  1193. }
  1194. //发送和接收数据的日志
  1195. private void GenerateSendAndRecvHexLog(bool blRead,string wrName)
  1196. {
  1197. _message = $"{(blRead?"读取":"写入")}{wrName},发送: {GetSendDataString()}, 接收: {GetRecvDataString()}";
  1198. RWLog?.Invoke(_message);
  1199. }
  1200. private string GetSendDataString()
  1201. {
  1202. sentData = _modbusTransport.GetLastSentData();
  1203. if (sentData != null)
  1204. {
  1205. return BitConverter.ToString(sentData).Replace("-", " ");
  1206. }
  1207. else
  1208. {
  1209. return "";
  1210. }
  1211. }
  1212. private string GetRecvDataString()
  1213. {
  1214. recvData = _modbusTransport.GetLastReceivedData();
  1215. if (recvData != null)
  1216. {
  1217. return BitConverter.ToString(recvData).Replace("-", " ");
  1218. }
  1219. else
  1220. {
  1221. return "";
  1222. }
  1223. }
  1224. //-----------------------------------------------
  1225. }
  1226. }