* 新增 CsvBoardRecordRepository 实现按日期分卷的 CSV 记录存储 * 新增 RecordPersistenceModels 定义板件检测记录数据结构 * 在 WorkflowHostedService 中集成检测完成后的记录持久化 * 更新 MainWindowViewModel 支持记录查询与异常标记 * 更新 AppStateStore 添加记录存储相关状态管理 * 新增 DashboardPage UI 元素展示记录存储状态 * 更新 SystemSettingViewModel 与 appConfig 添加存储路径配置 * 注册 TimeProvider 与 IBoardRecordRepository 到 DI 容器 * 新增 CsvBoardRecordRepositoryTests 与 MainWindowViewModelTests * 配置 Release 模式 portable PDB 并在发布时自动移除
AxiOmron.PcbCheck
基于 .NET 8 + WPF + MVVM Toolkit + Generic Host/DI + NLog 的 PCB 目检上位机示例工程,包含 PLC 通信、扫码枪触发、SFTP 文件校验、安灯报警和运行态监控。
项目结构
Axi_Omron/
src/
AxiOmron.PcbCheck/
tests/
AxiOmron.PcbCheck.Tests/
docs/
AxiOmron.PcbCheck.slnx
主程序位于 src/AxiOmron.PcbCheck,测试位于 tests/AxiOmron.PcbCheck.Tests。
技术栈
.NET 8/WPFCommunityToolkit.MvvmMicrosoft.Extensions.HostingNLogIoTClientModbus TCPSSH.NETHandyControl
配置说明
主配置文件位于 src/AxiOmron.PcbCheck/appConfig.json。
当前 PLC 相关默认配置示例:
Plc.Host:127.0.0.1Plc.Port:502Plc.UnitId:1Plc.PollIntervalMs:200Plc.ReleasePulseMs:500Plc.ReleaseAckTimeoutMs:2000
点位映射示例:
- 输入点位
PcbArrived = 0PlcReset = 1PlcAckRelease = 2- 输出点位
PcBusy = 51ReleasePermit = 52- 寄存器
ResultCode = 0
系统设置页可修改 PLC 参数,界面入口在 SystemSettingsPage.xaml。
注意:配置保存后会写入运行目录下的 appConfig.json,当前界面提示为“重启应用后完全生效”。
构建与运行
dotnet restore .\src\AxiOmron.PcbCheck\AxiOmron.PcbCheck.csproj
dotnet build .\src\AxiOmron.PcbCheck\AxiOmron.PcbCheck.csproj -c Debug
dotnet run --project .\src\AxiOmron.PcbCheck\AxiOmron.PcbCheck.csproj -c Debug
dotnet test .\tests\AxiOmron.PcbCheck.Tests\AxiOmron.PcbCheck.Tests.csproj
PLC 后台轮询调用链
总览
App 启动
-> BuildHost 注册 WorkflowHostedService 为 HostedService
-> Host.StartAsync()
-> WorkflowHostedService.ExecuteAsync()
ExecuteAsync 主循环
-> ProbePlcOnStartupAsync() 启动先探活
-> while (...)
-> _plcService.ReadSignalsAsync() 读取 PLC 输入
-> HandleSignalSnapshot() 刷 PLC 连接状态
-> RefreshPlcMonitorSnapshotAsync() 刷监控区
-> if PlcReset = true
-> ResetAsync()
else if ShouldStartWorkflow() 命中上升沿
-> StartWorkflowInBackground()
-> RunWorkflowOnceAsync()
RunWorkflowOnceAsync 单板流程
-> InitializeBoardState()
-> ApplyProcessStateAsync(Triggered, PcBusy=true)
-> ExecuteScanFlowAsync()
-> _scannerService.TriggerScanAsync()
-> ExecuteSftpFlowAsync(barcode)
-> _sftpLookupService.CheckFileAsync()
-> ReleaseAndCompleteAsync()
-> ApplyProcessStateAsync(Releasing, ReleasePermit=true)
-> 循环 _plcService.ReadSignalsAsync() 等 PlcAckRelease
-> Delay(ReleasePulseMs)
-> ApplyProcessStateAsync(Completed, ReleasePermit=false, PcBusy=false)
-> _stateStore.AddRecord(...)
状态/UI 更新支线
-> PublishRuntimeState() / UpdateSnapshot()
-> AppStateStore.SnapshotChanged
-> MainWindowViewModel.OnSnapshotChanged()
-> DashboardPage / SystemSettingsPage 绑定刷新
关键代码入口
- 后台服务注册: App.xaml.cs App.xaml.cs
- 轮询主循环: WorkflowHostedService.cs
- PLC 输入读取: WorkflowHostedService.cs
- 轮询周期: WorkflowHostedService.cs
- 启动流程判定: WorkflowHostedService.cs
- 启动单板流程: WorkflowHostedService.cs
- 单板总流程: WorkflowHostedService.cs
- 扫码流程: WorkflowHostedService.cs
- SFTP 校验流程: WorkflowHostedService.cs
- 放行及等待 PLC 应答: WorkflowHostedService.cs
- 流程状态写回 PLC: WorkflowHostedService.cs WorkflowHostedService.cs
PLC 底层读写落点
IPlcService接口: CoreInterfaces.csReadSignalsAsync实现: ModbusTcpPlcService.cs- 实际读取的输入位: ModbusTcpPlcService.cs ModbusTcpPlcService.cs ModbusTcpPlcService.cs
- 监控区镜像读取: ModbusTcpPlcService.cs
- 输出状态写入: ModbusTcpPlcService.cs
UI 刷新链
- 后台更新运行态快照: AppStateStore.cs
- 主界面监听快照变化: MainWindowViewModel.cs
- 设置页监听快照变化: SystemSettingViewModel.cs
常用排查入口
PlcReset触发软件复位: WorkflowHostedService.cs- 轮询异常进入故障锁存: WorkflowHostedService.cs
- 流程异常进入故障锁存: WorkflowHostedService.cs
- 故障状态写回: WorkflowHostedService.cs
说明
本 README 主要补充程序整体说明与 PLC 后台轮询调用链,便于排查“PLC 轮询在哪里启动、如何触发单板流程、状态如何回写和刷新 UI”这类问题。
Description
Languages
C#
100%