Files
Axi_Omron/README.md
yunxiao.zhu d70b94e904 feat(*): 添加扫码枪启动探活、全局退出助手及 README
- 添加扫码枪串口启动探活,检测端口占用并更新 UI 状态
- 新增 ShutdownHelper 安全停止 Host 扩展方法
- 新增 README.md 项目说明文档
- 更新 WorkflowHostedService 启动探活逻辑
- 补充 ShutdownHelper 与 WorkflowHostedService 单元测试
- 优化 DashboardPage 与 SystemSettingsPage 界面布局
- 调整 ModbusTcpPlcService 监控镜像读取逻辑
2026-04-19 14:29:07 +08:00

175 lines
7.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AxiOmron.PcbCheck
基于 `.NET 8 + WPF + MVVM Toolkit + Generic Host/DI + NLog` 的 PCB 目检上位机示例工程,包含 PLC 通信、扫码枪触发、SFTP 文件校验、安灯报警和运行态监控。
## 项目结构
```text
Axi_Omron/
src/
AxiOmron.PcbCheck/
tests/
AxiOmron.PcbCheck.Tests/
docs/
AxiOmron.PcbCheck.slnx
```
主程序位于 [src/AxiOmron.PcbCheck](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck),测试位于 [tests/AxiOmron.PcbCheck.Tests](d:/Dev/Codes/MFD_Solution/Axi_Omron/tests/AxiOmron.PcbCheck.Tests)。
## 技术栈
- `.NET 8` / `WPF`
- `CommunityToolkit.Mvvm`
- `Microsoft.Extensions.Hosting`
- `NLog`
- `IoTClient` Modbus TCP
- `SSH.NET`
- `HandyControl`
## 配置说明
主配置文件位于 [src/AxiOmron.PcbCheck/appConfig.json](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/appConfig.json)。
当前 PLC 相关默认配置示例:
- `Plc.Host`: `127.0.0.1`
- `Plc.Port`: `502`
- `Plc.UnitId`: `1`
- `Plc.PollIntervalMs`: `200`
- `Plc.ReleasePulseMs`: `500`
- `Plc.ReleaseAckTimeoutMs`: `2000`
点位映射示例:
- 输入点位
- `PcbArrived = 0`
- `PlcReset = 1`
- `PlcAckRelease = 2`
- 输出点位
- `PcBusy = 51`
- `ReleasePermit = 52`
- 寄存器
- `ResultCode = 0`
系统设置页可修改 PLC 参数,界面入口在 [SystemSettingsPage.xaml](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Views/Pages/SystemSettingsPage.xaml#L58)。
注意:配置保存后会写入运行目录下的 `appConfig.json`,当前界面提示为“重启应用后完全生效”。
## 构建与运行
```powershell
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 后台轮询调用链
### 总览
```text
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](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/App.xaml.cs#L125)
[App.xaml.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/App.xaml.cs#L127)
- 轮询主循环:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L70)
- PLC 输入读取:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L81)
- 轮询周期:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L110)
- 启动流程判定:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L366)
- 启动单板流程:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L388)
- 单板总流程:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L496)
- 扫码流程:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L542)
- SFTP 校验流程:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L630)
- 放行及等待 PLC 应答:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L727)
- 流程状态写回 PLC
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L942)
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L954)
### PLC 底层读写落点
- `IPlcService` 接口:
[CoreInterfaces.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Interfaces/CoreInterfaces.cs#L97)
- `ReadSignalsAsync` 实现:
[ModbusTcpPlcService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/ModbusTcpPlcService.cs#L37)
- 实际读取的输入位:
[ModbusTcpPlcService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/ModbusTcpPlcService.cs#L47)
[ModbusTcpPlcService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/ModbusTcpPlcService.cs#L48)
[ModbusTcpPlcService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/ModbusTcpPlcService.cs#L49)
- 监控区镜像读取:
[ModbusTcpPlcService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/ModbusTcpPlcService.cs#L69)
- 输出状态写入:
[ModbusTcpPlcService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/ModbusTcpPlcService.cs#L113)
### UI 刷新链
- 后台更新运行态快照:
[AppStateStore.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/AppStateStore.cs#L45)
- 主界面监听快照变化:
[MainWindowViewModel.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/ViewModels/MainWindowViewModel.cs#L532)
- 设置页监听快照变化:
[SystemSettingViewModel.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/ViewModels/SystemSettingViewModel.cs#L150)
### 常用排查入口
- `PlcReset` 触发软件复位:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L85)
- 轮询异常进入故障锁存:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L103)
- 流程异常进入故障锁存:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L432)
- 故障状态写回:
[WorkflowHostedService.cs](d:/Dev/Codes/MFD_Solution/Axi_Omron/src/AxiOmron.PcbCheck/Services/Implementations/WorkflowHostedService.cs#L823)
## 说明
本 README 主要补充程序整体说明与 PLC 后台轮询调用链便于排查“PLC 轮询在哪里启动、如何触发单板流程、状态如何回写和刷新 UI”这类问题。