您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

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