選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

286 行
8.3 KiB

  1. using ModbusDemo.Device;
  2. using ModbusDemo.Model;
  3. using Prism.Commands;
  4. using Prism.Mvvm;
  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 ModbusDemo.VIewModel
  13. {
  14. class RegisterUCViewModel : BindableBase
  15. {
  16. //定义数据库操作类
  17. private ModbusDbContext _modbusDbContext;
  18. //获取读线圈的类
  19. private IModbusRTU _modbusRTU;
  20. //定义读线圈的命令
  21. public DelegateCommand ReadRegisterCmm { get; set; }
  22. //定义写线圈操作
  23. public DelegateCommand WriteRegisterCmm { get; set; }
  24. //获取当前使用的串口
  25. private SerialPort _serialPort;
  26. //显示当前链接串口的信息
  27. public string SerialPortInfo
  28. {
  29. get
  30. {
  31. return "当前为读写寄存器:" + "串口号:" + _serialPort.PortName + ",波特率:" + _serialPort.BaudRate
  32. + ",数据位:" + _serialPort.DataBits + ",校验位:" + _serialPort.Parity + ",停止位:" + _serialPort.StopBits;
  33. }
  34. }
  35. #region 读取定义
  36. //读取的从站id
  37. private string _slaveAddress;
  38. public string SlaveAddress
  39. {
  40. get { return _slaveAddress; }
  41. set
  42. {
  43. _slaveAddress = value;
  44. RaisePropertyChanged();
  45. }
  46. }
  47. //读取的起始地址
  48. private string _startAddress;
  49. public string StartAddress
  50. {
  51. get { return _startAddress; }
  52. set
  53. {
  54. _startAddress = value;
  55. RaisePropertyChanged();
  56. }
  57. }
  58. //读取的位数
  59. private string _numberOfPoints;
  60. public string NumberOfPoints
  61. {
  62. get { return _numberOfPoints; }
  63. set
  64. {
  65. _numberOfPoints = value;
  66. RaisePropertyChanged();
  67. }
  68. }
  69. private string _readResult;
  70. //读取的结果
  71. public string ReadResult
  72. {
  73. get { return _readResult; }
  74. set
  75. {
  76. _readResult = value;
  77. RaisePropertyChanged();
  78. }
  79. }
  80. #endregion
  81. #region 写入定义
  82. //写入的从站id
  83. private string _writeslaveAddress;
  84. public string WriteSlaveAddress
  85. {
  86. get { return _writeslaveAddress; }
  87. set
  88. {
  89. _writeslaveAddress = value;
  90. RaisePropertyChanged();
  91. }
  92. }
  93. //写入的起始地址
  94. private string _writestartAddress;
  95. public string WriteStartAddress
  96. {
  97. get { return _writestartAddress; }
  98. set
  99. {
  100. _writestartAddress = value;
  101. RaisePropertyChanged();
  102. }
  103. }
  104. //写入的数据
  105. private string _writeData;
  106. public string WriteData
  107. {
  108. get { return _writeData; }
  109. set
  110. {
  111. _writeData = value;
  112. RaisePropertyChanged();
  113. }
  114. }
  115. #endregion
  116. private List<ModbusLog> _modbusLogList;
  117. public List<ModbusLog> ModbusLogList
  118. {
  119. get { return _modbusLogList; }
  120. set
  121. {
  122. _modbusLogList = value;
  123. RaisePropertyChanged();
  124. }
  125. }
  126. public RegisterUCViewModel()
  127. {
  128. }
  129. public RegisterUCViewModel(SerialPort serialPort, ModbusRTU modbusRTU, ModbusDbContext modbusDbContext)
  130. {
  131. _serialPort = serialPort;
  132. ReadRegisterCmm = new DelegateCommand(ReadRegister);
  133. _modbusRTU = modbusRTU;
  134. WriteRegisterCmm = new DelegateCommand(WriteRegister);
  135. _modbusDbContext = modbusDbContext;
  136. ModbusLogList = GetOperateRegister();
  137. }
  138. /// <summary>
  139. /// 线圈读取操作
  140. /// </summary>
  141. private void ReadRegister()
  142. {
  143. if (!byte.TryParse(SlaveAddress, out byte slaveAddressValue))
  144. {
  145. MessageBox.Show("SlaveAddress 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
  146. return;
  147. }
  148. if (!ushort.TryParse(StartAddress, out ushort startAddressValue))
  149. {
  150. MessageBox.Show("StartAddress 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
  151. return;
  152. }
  153. if (!ushort.TryParse(NumberOfPoints, out ushort numberOfPointsValue))
  154. {
  155. MessageBox.Show("NumberOfPoints 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
  156. return;
  157. }
  158. //使用子线程进行读取,防止ui线程卡顿
  159. Task.Run(() =>
  160. {
  161. ushort[] result = _modbusRTU.ReadRegisters(slaveAddressValue, startAddressValue, numberOfPointsValue);
  162. if (result == null)
  163. {
  164. MessageBox.Show("读取失败", "error", MessageBoxButton.OK, MessageBoxImage.Error);
  165. ModbusLogList = GetOperateRegister();
  166. return;
  167. }
  168. string temp = "";
  169. foreach (var item in result)
  170. {
  171. temp += item;
  172. temp += " ";
  173. }
  174. ReadResult = temp;
  175. MessageBox.Show("读取成功");
  176. ModbusLogList = GetOperateRegister();
  177. });
  178. }
  179. private void WriteRegister()
  180. {
  181. if (!byte.TryParse(WriteSlaveAddress, out byte writeSlaveAddressValue))
  182. {
  183. MessageBox.Show("WriteSlaveAddress 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
  184. return;
  185. }
  186. if (!ushort.TryParse(WriteStartAddress, out ushort WriteStartAddressValue))
  187. {
  188. MessageBox.Show("WriteStartAddress 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
  189. return;
  190. }
  191. if (string.IsNullOrEmpty(WriteData))
  192. {
  193. MessageBox.Show("WriteData 格式无效", "warning", MessageBoxButton.OK, MessageBoxImage.Warning);
  194. return;
  195. }
  196. string[] parts = WriteData.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
  197. // 3. 创建结果数组
  198. ushort[] data = new ushort[parts.Length];
  199. // 4. 遍历并转换每个部分
  200. for (int i = 0; i < parts.Length; i++)
  201. {
  202. // 尝试解析为ushort
  203. if (ushort.TryParse(parts[i], out ushort value))
  204. {
  205. data[i] = value;
  206. }
  207. else
  208. {
  209. MessageBox.Show($"无法将 '{parts[i]}' 转换为 ushort 类型");
  210. return;
  211. }
  212. }
  213. //使用子线程来去执行操作,防止ui线程卡顿
  214. Task.Run(() =>
  215. {
  216. _modbusRTU.WriteRegisters(writeSlaveAddressValue, WriteStartAddressValue, data);
  217. ModbusLogList = GetOperateRegister();
  218. ModbusLog modbusLog = ModbusLogList.FirstOrDefault();
  219. if (modbusLog != null && modbusLog.ResponseData != string.Empty)
  220. {
  221. MessageBox.Show("写入成功");
  222. }
  223. else
  224. {
  225. MessageBox.Show("写入失败", "error", MessageBoxButton.OK, MessageBoxImage.Error);
  226. }
  227. });
  228. }
  229. /// <summary>
  230. /// 获取展示数据
  231. /// </summary>
  232. /// <returns></returns>
  233. private List<ModbusLog> GetOperateRegister()
  234. {
  235. return _modbusDbContext.ModbusLog
  236. .Where(log => log.OperationType == "读寄存器" || log.OperationType == "写寄存器")
  237. .OrderByDescending(log => log.Time) // 按时间倒序,最新的在前
  238. .Take(20) // 只取前20条记录
  239. .ToList(); // 执行查询
  240. }
  241. }
  242. }