WPF + Modbus 实现一套开源 MES系统(附完整代码)

📅 发布时间:2026/9/26 7:30:48
WPF + Modbus 实现一套开源 MES系统(附完整代码)
目录前言项目介绍项目功能项目特点项目技术项目代码项目效果项目源码总结前言在中小型制造企业数字化转型的浪潮中一套趁手且不臃肿的生产管理系统往往比那些动辄上百万的大厂ERP更接地气。设备数据采集难、订单进度追踪乱、报表统计靠手工——这些场景我太熟悉了。本文推荐用一套简洁的技术方案把产线设备监控和订单管理这两件事儿理顺。项目介绍一套基于WPF开发的桌面端制造执行系统主要面向设备规模在几十台以内的中小型车间。它通过Modbus协议与现场设备打交道——不管是网线连接的TCP设备还是通过串口通讯的RTU老设备都能接入进来统一管理。系统跑起来之后车间管理人员可以在一台电脑上同时看到所有在线设备的实时数据温度、压力、转速这些还能随时下达生产订单、追踪每个订单的完成进度最后自动生成带图表的统计报表。整个项目围绕轻量二字展开没有复杂的分布式架构一台普通办公电脑就能跑得很顺畅。项目功能功能模块具体说明设备实时监控通过Modbus TCP/RTU采集设备运行参数仪表盘实时刷新温度、压力、速度等关键指标订单管理支持订单创建、下达、暂停、完成等状态流转每个订单关联具体产品和设备生产记录追踪自动记录每个订单的实际生产数量、耗时、良品率形成可追溯的生产履历数据报表看板基于采集的历史数据生成趋势图、产量排行、设备利用率等可视化报表设备告警管理当采集值超出预设阈值时自动记录告警并推送Toast通知到操作界面用户权限控制区分操作员、班组长、管理员三个角色不同角色看到的功能菜单不同设备模拟测试内置模拟设备客户端在没有真实硬件的情况下也能完整走通业务流程项目特点通信层可插拔TCP、RTU、Mock三种客户端实现同一接口切换设备类型无需改动上层业务逻辑添加新协议只需要新增一个实现类轮询策略可配置默认轮询策略支持按设备组、优先级、频率等多维度调度也可以在DeviceCommunicationService里替换成自己的采集逻辑状态机管理连接每个设备都有连接/断连两种状态状态切换时自动触发UI更新和日志记录连接异常后还会自动尝试重连MVVM与WPF深度绑定借助CommunityToolkit.Mvvm的可观测属性和命令机制ViewModel层完全解耦View层单元测试可以直接针对ViewModel编写数据持久化双轨制EF Core负责实体关系映射Dapper负责复杂查询和批量写入两者共存各取所长实时图表开箱即用LiveChartsCore接入后只需绑定ObservableCollection设备数据变化时图表自动刷新省掉大量手动刷新逻辑结构化日志全链路Serilog记录每次设备通信、订单操作、系统异常日志按天切割排查问题可以精确到毫秒级项目技术技术方向选型及说明开发语言C#基于.NET 6.0UI框架WPFWindows Presentation Foundation架构模式MVVM CommunityToolkit.Mvvm负责可观测对象、命令、消息传递Modbus通信NModbus同时支持TCP和RTU串口两种传输方式数据可视化LiveChartsCore.SkiaSharpView实时曲线图和柱状图渲染界面样式MaterialDesignThemesMaterial Design风格的控件库日志组件Serilog文件输出 Debug输出支持异步写入ORM框架Entity Framework Core实体迁移和关系管理 Dapper复杂查询和批量操作数据库SQL Server本地或远程实例均可依赖注入.NET 6.0原生DI容器ServiceCollection项目代码整个项目的代码结构按照功能边界做了清晰的分层从通信层到UI层逐级向上依赖。通信引擎这块是整套系统的核心。DeviceCommunicationService启动后会为每个设备创建独立的轮询循环每个循环周期内通过DeviceClientFactory拿到对应的TCP或RTU客户端然后调用DefaultPollingStrategy执行具体的数据读取逻辑。读取到的原始数据经过转换后通过DataRepository写入SQL Server同时触发DeviceStatusChanged事件通知上层。// 单设备轮询循环的核心逻辑简化版 private async Task SingleDevicePollingLoop(DeviceModel device, CancellationToken token) { while (!token.IsCancellationRequested) { try { var client _activeClients.GetOrAdd(device.Id, _deviceClientFactory.CreateClient(device)); var snapshot await _pollingStrategy.PollAsync(client, device); await _dataRepository.SaveDeviceSnapshotAsync(snapshot); _statusNotifier.OnDeviceUpdated(device.Id, snapshot); await Task.Delay(device.PollingIntervalMs, token); } catch (Exception ex) { _logger.Error(ex, 设备 {DeviceName} 轮询异常, device.Name); _statusNotifier.OnDeviceError(device.Id, ex.Message); await Task.Delay(5000, token); } } }ViewModel层这边MonitorViewModel订阅了设备状态变更事件每次收到新数据就更新ObservableCollectionDeviceSnapshot。WPF的DataTemplate机制把视图模型和对应的View绑定起来ContentControl的内容切换实现了单页路由效果切换菜单时整个界面不会重新加载。UI层做了一些细节优化。比如左侧导航菜单的折叠展开使用ToggleButton的IsChecked状态控制子菜单的Visibility配合BooleanToVisibilityConverter实现平滑切换。所有的导航按钮统一了样式模板鼠标悬停和按下都有对应的背景色反馈操作手感比较跟手。项目效果主界面分为深蓝色侧边导航栏和白色工作区两部分。左侧菜单从上到下依次是Logo区、导航菜单、退出按钮右侧工作区顶部展示当前页面标题和登录用户信息下方是具体业务内容。进入设备监控页面后每个设备以卡片形式展示。卡片上显示设备名称、IP地址、当前连接状态绿色代表在线红色代表离线以及温度、压力、速度三个关键参数的实时数值。参数数值下方是一条实时趋势曲线数据点随着轮询周期不断向右推进看起来像是产线监控大屏的缩小版。订单管理页面以表格形式列出所有订单每一行包含订单编号、产品名称、计划数量、已完成数量、当前状态待下达/进行中/已完成/已暂停、下达时间等字段。点击下达按钮后系统会校验对应设备是否在线确认无误后更新订单状态并记录开始时间。数据报表页面提供了按时间范围筛选的功能选好起止日期后点击查询会生成产量趋势折线图、各设备产量对比柱状图以及一个汇总统计表格。所有图表支持鼠标悬停查看数值详情导出功能还在规划中目前可以直接截图使用。项目源码主要文件说明Core/DeviceCommunicationService.cs— 设备轮询调度器MES的心脏Core/TcpDeviceClient.cs和RtuDeviceClient.cs— Modbus通信的具体实现ViewModels/MonitorViewModel.cs— 监控面板的业务逻辑负责数据绑定和事件订阅Views/MonitorView.xaml— 设备监控卡片的UI布局Services/DAL/DataRepository.cs— 数据库操作的具体实现Sql/SQLQuery1.sql— 数据库初始化脚本包含设备表、订单表、用户表等拿到源码后用Visual Studio 2022打开解决方案文件还原NuGet包修改appsettings.json里的数据库连接字符串然后按F5就能跑起来。默认账号是admin密码123456首次登录后记得修改。githubhttps://github.com/DrageonShark/SimpleMES总结这个项目从立项到跑通前后花了不到两周时间核心目标一直很明确——做一套能真正用在车间里、不折腾人的轻量级MES。它没有盲目追求大而全的功能覆盖而是在设备数据采集和订单追踪这两个刚需场景上做深做透。从技术层面看.NET 6.0 WPF这套组合在Windows桌面应用领域依然能打配合MVVM模式写出来的代码可维护性不输Web前端框架。Modbus作为工业现场的事实标准协议NModbus库的封装足够成熟稳定TCP和RTU两套实现切换起来毫无障碍。如果大家也在做类似的车间管理系统或者对工业设备数据采集感兴趣欢迎把代码拉下来跑一跑。开源的意义在于大家一起把轮子造得更好用。引入地址