From 2f17e1a8f15afd7ed2ce111aa79dcef096739b9a Mon Sep 17 00:00:00 2001 From: zhangyongpan Date: Sun, 27 Jul 2025 17:12:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E6=AF=8F=E4=B8=80=E6=AC=A1=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E9=83=BD=E6=8F=92=E5=85=A5=E5=88=B0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ModbusDemo/App.xaml.cs | 27 +++++++-- ModbusDemo/Device/ModbusRTU.cs | 79 ++++++++++++++++++++++--- ModbusDemo/ModbusDemo.csproj | 9 +++ ModbusDemo/Model/ModbusDbContext.cs | 20 +++++++ ModbusDemo/Model/ModbusLog.cs | 26 ++++++++ ModbusDemo/VIew/CoilUC.xaml | 4 +- ModbusDemo/VIew/SettingsUC.xaml | 1 + ModbusDemo/VIew/SettingsUC.xaml.cs | 23 ++++++- ModbusDemo/VIewModel/CoilUCViewModel.cs | 79 +++++++++++++++++++++++-- ModbusDemo/appsettings.json | 14 +++++ 10 files changed, 264 insertions(+), 18 deletions(-) create mode 100644 ModbusDemo/Model/ModbusDbContext.cs create mode 100644 ModbusDemo/Model/ModbusLog.cs create mode 100644 ModbusDemo/appsettings.json diff --git a/ModbusDemo/App.xaml.cs b/ModbusDemo/App.xaml.cs index 769b243..a10a9cd 100644 --- a/ModbusDemo/App.xaml.cs +++ b/ModbusDemo/App.xaml.cs @@ -1,11 +1,16 @@ -using ModbusDemo.Device; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using ModbusDemo.Device; +using ModbusDemo.Model; using ModbusDemo.VIew; using ModbusDemo.VIewModel; using Prism.DryIoc; using Prism.Ioc; +using System; using System.Configuration; using System.Data; using System.DirectoryServices; +using System.IO; using System.IO.Ports; using System.Windows; @@ -38,12 +43,26 @@ namespace ModbusDemo containerRegistry.RegisterForNavigation(); //将寄存器操作页面和寄存器操作页面的VM结合起来 containerRegistry.RegisterForNavigation(); - //将窗口注册为全局唯一的单例 + //将串口注册为全局唯一的单例 containerRegistry.RegisterSingleton(); - - //将读线圈注册 containerRegistry.Register(); + + + + // 1. 加载配置文件 + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + + // 2. 配置 DbContextOptions + var options = new DbContextOptionsBuilder() + .UseSqlServer(configuration.GetConnectionString("ConnStr")) + .Options; + + // 3. 注册 DbContext(作用域生命周期) + containerRegistry.Register(() => new ModbusDbContext(options)); } /// /// 程序打开默认是设置界面,来设置串口的各个东西 diff --git a/ModbusDemo/Device/ModbusRTU.cs b/ModbusDemo/Device/ModbusRTU.cs index 4eaacfc..7b63209 100644 --- a/ModbusDemo/Device/ModbusRTU.cs +++ b/ModbusDemo/Device/ModbusRTU.cs @@ -1,4 +1,5 @@ -using ModbusDemo.Uitls; +using ModbusDemo.Model; +using ModbusDemo.Uitls; using System; using System.Collections.Generic; using System.IO.Ports; @@ -11,11 +12,14 @@ namespace ModbusDemo.Device { public class ModbusRTU : IModbusRTU { - private SerialPort _serialPort; - public ModbusRTU(SerialPort serialPort) + private SerialPort _serialPort; + //用于操作数据库 + private ModbusDbContext _modbusDbContext; + public ModbusRTU(SerialPort serialPort,ModbusDbContext modbusDbContext) { _serialPort = serialPort; + _modbusDbContext = modbusDbContext; } /// /// 用来发送读写线圈的指令 @@ -58,7 +62,8 @@ namespace ModbusDemo.Device Thread.Sleep(300); byte[] response = new byte[_serialPort.BytesToRead]; _serialPort.Read(response, 0, _serialPort.BytesToRead); - return ParseCoilresponse(response, numberOfPoints); + + return ParseCoilresponse(sendByte, response, numberOfPoints); } @@ -66,8 +71,19 @@ namespace ModbusDemo.Device } - public bool[] ParseCoilresponse(byte[] response, ushort numberOfPoints) + public bool[] ParseCoilresponse(byte[] sendByte, byte[] response, ushort numberOfPoints) { + //将操作的指令,插入数据库 + string RequestStr = ByteArrayToString(sendByte); + string responseStr = ByteArrayToString(response); + ModbusLog m = new ModbusLog(); + m.OperationType = "读线圈"; + m.ResponseData = responseStr; + m.RequestData = responseStr; + _modbusDbContext.Add(m); + _modbusDbContext.SaveChanges(); + + //判断发送回来的数据是否正确 CheckData.CheckResponse(response); @@ -164,6 +180,16 @@ namespace ModbusDemo.Device byte[] response = new byte[_serialPort.BytesToRead]; _serialPort.Read(response, 0, _serialPort.BytesToRead); + //将操作的指令,插入数据库 + string RequestStr = ByteArrayToString(sendByte); + string responseStr = ByteArrayToString(response); + ModbusLog m = new ModbusLog(); + m.OperationType = "写线圈"; + m.ResponseData = responseStr; + m.RequestData = responseStr; + _modbusDbContext.Add(m); + _modbusDbContext.SaveChanges(); + //判断发送回来的数据是否正确 CheckData.CheckResponse(response); @@ -212,13 +238,23 @@ namespace ModbusDemo.Device Thread.Sleep(300); byte[] response = new byte[_serialPort.BytesToRead]; _serialPort.Read(response, 0, _serialPort.BytesToRead); - return ParseRegistersresponse(response, numberOfPoints); + return ParseRegistersresponse(sendByte, response, numberOfPoints); } return null; } - public ushort[] ParseRegistersresponse(byte[] response, ushort numberOfPoints) + public ushort[] ParseRegistersresponse(byte[] sendByte, byte[] response, ushort numberOfPoints) { + //将操作的指令,插入数据库 + string RequestStr = ByteArrayToString(sendByte); + string responseStr = ByteArrayToString(response); + ModbusLog m = new ModbusLog(); + m.OperationType = "读寄存器"; + m.ResponseData = responseStr; + m.RequestData = responseStr; + _modbusDbContext.Add(m); + _modbusDbContext.SaveChanges(); + //判断发送回来的数据是否正确 CheckData.CheckResponse(response); @@ -283,6 +319,15 @@ namespace ModbusDemo.Device byte[] response = new byte[_serialPort.BytesToRead]; _serialPort.Read(response, 0, _serialPort.BytesToRead); + //将操作的指令,插入数据库 + string RequestStr = ByteArrayToString(sendByte); + string responseStr = ByteArrayToString(response); + ModbusLog m = new ModbusLog(); + m.OperationType = "写寄存器"; + m.ResponseData = responseStr; + m.RequestData = responseStr; + _modbusDbContext.Add(m); + _modbusDbContext.SaveChanges(); //判断发送回来的数据是否正确 CheckData.CheckResponse(response); @@ -293,5 +338,25 @@ namespace ModbusDemo.Device } } } + + static string ByteArrayToString(byte[] byteArray) + { + if (byteArray == null || byteArray.Length == 0) + return string.Empty; + + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + + // 处理第一个元素(无前导空格) + sb.Append(byteArray[0].ToString("X2")); + + // 处理后续元素(每个前面加空格) + for (int i = 1; i < byteArray.Length; i++) + { + sb.Append(' '); + sb.Append(byteArray[i].ToString("X2")); + } + + return sb.ToString(); + } } } diff --git a/ModbusDemo/ModbusDemo.csproj b/ModbusDemo/ModbusDemo.csproj index ddcf4d4..d32b218 100644 --- a/ModbusDemo/ModbusDemo.csproj +++ b/ModbusDemo/ModbusDemo.csproj @@ -10,8 +10,17 @@ + + + + + + Always + + + diff --git a/ModbusDemo/Model/ModbusDbContext.cs b/ModbusDemo/Model/ModbusDbContext.cs new file mode 100644 index 0000000..3c4b97d --- /dev/null +++ b/ModbusDemo/Model/ModbusDbContext.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModbusDemo.Model +{ + public class ModbusDbContext:DbContext + { + + public ModbusDbContext(DbContextOptions options) :base(options) + { + + } + + public DbSet ModbusLog { get; set; } + } +} diff --git a/ModbusDemo/Model/ModbusLog.cs b/ModbusDemo/Model/ModbusLog.cs new file mode 100644 index 0000000..fc0e255 --- /dev/null +++ b/ModbusDemo/Model/ModbusLog.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModbusDemo.Model +{ + public class ModbusLog + { + //数据库主键 + [Key] + public int Id { get; set; } + //操作的类型是读还是写 + public string OperationType { get; set; } + //请求的字节信息 + public string RequestData { get; set; } + //返回的字节信息 + public string ResponseData { get; set; } + + //操作的时间 + public DateTime Time { get; set; } = DateTime.Now; + + } +} diff --git a/ModbusDemo/VIew/CoilUC.xaml b/ModbusDemo/VIew/CoilUC.xaml index 10f4142..d07854e 100644 --- a/ModbusDemo/VIew/CoilUC.xaml +++ b/ModbusDemo/VIew/CoilUC.xaml @@ -149,7 +149,9 @@ - + + + diff --git a/ModbusDemo/VIew/SettingsUC.xaml b/ModbusDemo/VIew/SettingsUC.xaml index 929a6b0..3be6244 100644 --- a/ModbusDemo/VIew/SettingsUC.xaml +++ b/ModbusDemo/VIew/SettingsUC.xaml @@ -31,6 +31,7 @@ + diff --git a/ModbusDemo/VIew/SettingsUC.xaml.cs b/ModbusDemo/VIew/SettingsUC.xaml.cs index 2b8692d..26020a4 100644 --- a/ModbusDemo/VIew/SettingsUC.xaml.cs +++ b/ModbusDemo/VIew/SettingsUC.xaml.cs @@ -1,4 +1,5 @@ -using System; +using ModbusDemo.Model; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -20,9 +21,27 @@ namespace ModbusDemo.VIew /// public partial class SettingsUC : UserControl { - public SettingsUC() + private ModbusDbContext _ModbusDbContext; + public SettingsUC(ModbusDbContext ModbusDbContext) { InitializeComponent(); + _ModbusDbContext = ModbusDbContext; + } + + private void Button_Click(object sender, RoutedEventArgs e) + { + ModbusLog m = new ModbusLog(); + m.OperationType = "read"; + m.ResponseData = "0120"; + m.RequestData = "8888"; + + + + _ModbusDbContext.Add(m); + + _ModbusDbContext.SaveChanges(); + + } } } diff --git a/ModbusDemo/VIewModel/CoilUCViewModel.cs b/ModbusDemo/VIewModel/CoilUCViewModel.cs index bd50693..eed4199 100644 --- a/ModbusDemo/VIewModel/CoilUCViewModel.cs +++ b/ModbusDemo/VIewModel/CoilUCViewModel.cs @@ -1,4 +1,5 @@ using ModbusDemo.Device; +using ModbusDemo.Model; using Prism.Commands; using Prism.Mvvm; using System; @@ -132,6 +133,20 @@ namespace ModbusDemo.VIewModel #endregion + + + private List _modbusLogList; + + public List ModbusLogList + { + get { return _modbusLogList; } + set + { + _modbusLogList = value; + RaisePropertyChanged(); + } + } + public CoilUCViewModel() { @@ -143,9 +158,65 @@ namespace ModbusDemo.VIewModel ReadCoilCmm = new DelegateCommand(ReadCoil); _modbusRTU = modbusRTU; WriteCoilCmm = new DelegateCommand(WriteCoil); - } + ModbusLogList = new List(); + + ModbusLogList.Add(new ModbusLog + { + OperationType = "读取", + RequestData = "01 03 00 00 00 02", + ResponseData = "01 03 04 00 0A 00 0B", + + Time = DateTime.Now.AddMinutes(-5) + }); + + ModbusLogList.Add(new ModbusLog + { + OperationType = "写入", + RequestData = "01 06 00 01 00 03", + ResponseData = "01 06 00 01 00 03", + + Time = DateTime.Now.AddMinutes(-2) + }); + + ModbusLogList.Add(new ModbusLog + { + OperationType = "读取", + RequestData = "01 03 00 00 00 02", + ResponseData = "01 03 04 00 0A 00 0B", + + Time = DateTime.Now.AddMinutes(-5) + }); + + ModbusLogList.Add(new ModbusLog + { + OperationType = "写入", + RequestData = "01 06 00 01 00 03", + ResponseData = "01 06 00 01 00 03", + + Time = DateTime.Now.AddMinutes(-2) + }); + + ModbusLogList.Add(new ModbusLog + { + OperationType = "读取", + RequestData = "01 03 00 00 00 02", + ResponseData = "01 03 04 00 0A 00 0B", + + Time = DateTime.Now.AddMinutes(-5) + }); + + ModbusLogList.Add(new ModbusLog + { + OperationType = "写入", + RequestData = "01 06 00 01 00 03", + ResponseData = "01 06 00 01 00 03", + + Time = DateTime.Now.AddMinutes(-2) + }); + + } /// /// 线圈读取操作 @@ -178,9 +249,9 @@ namespace ModbusDemo.VIewModel private void WriteCoil() { //去除字符串中的空格 - WriteData = WriteData.Replace(" ", ""); + WriteData = WriteData.Replace(" ", ""); //转换为布尔数组 - bool[] data = WriteData.Select(m => m == '1').ToArray(); + bool[] data = WriteData.Select(m => m == '1').ToArray(); try { @@ -193,7 +264,7 @@ namespace ModbusDemo.VIewModel MessageBox.Show("信息配置错误"); } - + } } } diff --git a/ModbusDemo/appsettings.json b/ModbusDemo/appsettings.json new file mode 100644 index 0000000..04f7cc6 --- /dev/null +++ b/ModbusDemo/appsettings.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "noImplicitAny": false, + "noEmitOnError": true, + "removeComments": false, + "sourceMap": true, + "target": "es5" + }, + "exclude": [ + "node_modules", + "wwwroot" + ], + "ConnectionStrings": { "ConnStr": "server=.;uid=sa;pwd=123456;database=Modbus;TrustServerCertificate=true" } +}