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

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