Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

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