From bcddcd0bed90526ddbad1ca40f5a2c000c354922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=23=20=E5=BC=80=E5=8F=91?= Date: Wed, 19 Aug 2026 01:16:32 +0000 Subject: [PATCH] =?UTF-8?q?=E4=BA=A4=E8=BF=90=E8=A1=8C=E5=B7=A5=E4=BD=8D?= =?UTF-8?q?=E6=A1=A9=EF=BC=9A=E4=B8=89=E5=8F=A3=E5=A5=91=E7=BA=A6=E3=80=81?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=9C=8D=E5=8A=A1=E3=80=81=E5=85=AD=E6=80=81?= =?UTF-8?q?=20VM=E3=80=81=E8=B7=A8=E7=BA=BF=E7=A8=8B=E5=88=87=20UI?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 采集/PLC/Inspect 均为桩,验收 1–8 可测。不部署现场。 --- .gitignore | 15 + README.md | 27 ++ VisionHost.sln | 34 ++ src/VisionHost.App/App.xaml | 12 + src/VisionHost.App/App.xaml.cs | 7 + .../Converters/HexToBrushConverter.cs | 25 ++ src/VisionHost.App/Themes/Station.xaml | 110 ++++++ src/VisionHost.App/Views/RunStationView.xaml | 137 ++++++++ .../Views/RunStationView.xaml.cs | 22 ++ src/VisionHost.App/VisionHost.App.csproj | 15 + src/VisionHost.App/WpfUserConfirm.cs | 64 ++++ src/VisionHost.Contracts/DeviceStatusInfo.cs | 13 + src/VisionHost.Contracts/FrameReadyEvent.cs | 7 + src/VisionHost.Contracts/IDeviceStatus.cs | 8 + src/VisionHost.Contracts/IFrameSource.cs | 8 + src/VisionHost.Contracts/IInspectService.cs | 7 + src/VisionHost.Contracts/IPlcIo.cs | 9 + src/VisionHost.Contracts/IUiDispatch.cs | 6 + src/VisionHost.Contracts/IUserConfirm.cs | 8 + src/VisionHost.Contracts/InspectResult.cs | 8 + src/VisionHost.Contracts/RunState.cs | 12 + src/VisionHost.Contracts/RuntimeOptions.cs | 11 + .../VisionHost.Contracts.csproj | 8 + src/VisionHost.Runtime/Alarm.cs | 4 + src/VisionHost.Runtime/AlwaysConfirm.cs | 10 + src/VisionHost.Runtime/RunService.cs | 314 ++++++++++++++++++ src/VisionHost.Runtime/RunViewModel.cs | 98 ++++++ src/VisionHost.Runtime/ScriptedConfirm.cs | 31 ++ src/VisionHost.Runtime/StationSnapshot.cs | 22 ++ src/VisionHost.Runtime/StubFrameSource.cs | 72 ++++ src/VisionHost.Runtime/StubInspectService.cs | 22 ++ src/VisionHost.Runtime/StubPlcIo.cs | 15 + .../SynchronizationContextDispatch.cs | 24 ++ .../VisionHost.Runtime.csproj | 11 + .../RunServiceAcceptanceTests.cs | 220 ++++++++++++ .../VisionHost.Runtime.Tests.csproj | 16 + 36 files changed, 1432 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 VisionHost.sln create mode 100644 src/VisionHost.App/App.xaml create mode 100644 src/VisionHost.App/App.xaml.cs create mode 100644 src/VisionHost.App/Converters/HexToBrushConverter.cs create mode 100644 src/VisionHost.App/Themes/Station.xaml create mode 100644 src/VisionHost.App/Views/RunStationView.xaml create mode 100644 src/VisionHost.App/Views/RunStationView.xaml.cs create mode 100644 src/VisionHost.App/VisionHost.App.csproj create mode 100644 src/VisionHost.App/WpfUserConfirm.cs create mode 100644 src/VisionHost.Contracts/DeviceStatusInfo.cs create mode 100644 src/VisionHost.Contracts/FrameReadyEvent.cs create mode 100644 src/VisionHost.Contracts/IDeviceStatus.cs create mode 100644 src/VisionHost.Contracts/IFrameSource.cs create mode 100644 src/VisionHost.Contracts/IInspectService.cs create mode 100644 src/VisionHost.Contracts/IPlcIo.cs create mode 100644 src/VisionHost.Contracts/IUiDispatch.cs create mode 100644 src/VisionHost.Contracts/IUserConfirm.cs create mode 100644 src/VisionHost.Contracts/InspectResult.cs create mode 100644 src/VisionHost.Contracts/RunState.cs create mode 100644 src/VisionHost.Contracts/RuntimeOptions.cs create mode 100644 src/VisionHost.Contracts/VisionHost.Contracts.csproj create mode 100644 src/VisionHost.Runtime/Alarm.cs create mode 100644 src/VisionHost.Runtime/AlwaysConfirm.cs create mode 100644 src/VisionHost.Runtime/RunService.cs create mode 100644 src/VisionHost.Runtime/RunViewModel.cs create mode 100644 src/VisionHost.Runtime/ScriptedConfirm.cs create mode 100644 src/VisionHost.Runtime/StationSnapshot.cs create mode 100644 src/VisionHost.Runtime/StubFrameSource.cs create mode 100644 src/VisionHost.Runtime/StubInspectService.cs create mode 100644 src/VisionHost.Runtime/StubPlcIo.cs create mode 100644 src/VisionHost.Runtime/SynchronizationContextDispatch.cs create mode 100644 src/VisionHost.Runtime/VisionHost.Runtime.csproj create mode 100644 tests/VisionHost.Runtime.Tests/RunServiceAcceptanceTests.cs create mode 100644 tests/VisionHost.Runtime.Tests/VisionHost.Runtime.Tests.csproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..816f864 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +bin/ +obj/ +.vs/ +.idea/ +*.user +*.suo +*.userosscache +*.sln.docstates +[Dd]ebug/ +[Rr]elease/ +*.dll +*.pdb +*.cache +TestResults/ +.dotnet/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..c947f88 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ + +# VisionHost 运行工位桩 + +本迭代只交操作员运行壳(验收 1–7)。采集 / PLC / Inspect 均为桩,不做真检测、不改主干、不部署。 + +## 工程 + +- `VisionHost.Contracts` 三口:`IFrameSource` / `IInspectService` / `IPlcIo` +- `VisionHost.Runtime` 运行服务 + `RunViewModel`(绑定名对齐 WPF 骨架) +- `VisionHost.Runtime.Tests` 运行壳用例 +- `VisionHost.App` 操作员运行页(WPF,hex 转笔刷) + +可点界面:`src/VisionHost.App`(Windows)。`LastResultBrush`/`AlarmBrush` 用 `HexToBrushConverter`。 + +## 行为 + +- 确认启动才清零并开跑;停机保持计数 +- 未连接 / 重连中:不弹确认,`CanStart=false` +- Inspect 桩:1–4 OK,第 5 拍 `NG STUB`,拍号在算法桩内计 +- 六态由运行服务推,VM 不自判 + +## 构建 + +``` +export PATH="$HOME/.dotnet:$PATH" +dotnet test VisionHost.sln +``` diff --git a/VisionHost.sln b/VisionHost.sln new file mode 100644 index 0000000..1c02b7b --- /dev/null +++ b/VisionHost.sln @@ -0,0 +1,34 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisionHost.Contracts", "src\VisionHost.Contracts\VisionHost.Contracts.csproj", "{A1111111-1111-1111-1111-111111111111}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisionHost.Runtime", "src\VisionHost.Runtime\VisionHost.Runtime.csproj", "{A2222222-2222-2222-2222-222222222222}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisionHost.Runtime.Tests", "tests\VisionHost.Runtime.Tests\VisionHost.Runtime.Tests.csproj", "{A3333333-3333-3333-3333-333333333333}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VisionHost.App", "src\VisionHost.App\VisionHost.App.csproj", "{A4444444-4444-4444-4444-444444444444}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A1111111-1111-1111-1111-111111111111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1111111-1111-1111-1111-111111111111}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1111111-1111-1111-1111-111111111111}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1111111-1111-1111-1111-111111111111}.Release|Any CPU.Build.0 = Release|Any CPU + {A2222222-2222-2222-2222-222222222222}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A2222222-2222-2222-2222-222222222222}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A2222222-2222-2222-2222-222222222222}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A2222222-2222-2222-2222-222222222222}.Release|Any CPU.Build.0 = Release|Any CPU + {A3333333-3333-3333-3333-333333333333}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A3333333-3333-3333-3333-333333333333}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3333333-3333-3333-3333-333333333333}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A3333333-3333-3333-3333-333333333333}.Release|Any CPU.Build.0 = Release|Any CPU + {A4444444-4444-4444-4444-444444444444}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A4444444-4444-4444-4444-444444444444}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A4444444-4444-4444-4444-444444444444}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A4444444-4444-4444-4444-444444444444}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/src/VisionHost.App/App.xaml b/src/VisionHost.App/App.xaml new file mode 100644 index 0000000..8692475 --- /dev/null +++ b/src/VisionHost.App/App.xaml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/src/VisionHost.App/App.xaml.cs b/src/VisionHost.App/App.xaml.cs new file mode 100644 index 0000000..82e7294 --- /dev/null +++ b/src/VisionHost.App/App.xaml.cs @@ -0,0 +1,7 @@ +using System.Windows; + +namespace VisionHost.App; + +public partial class App : Application +{ +} diff --git a/src/VisionHost.App/Converters/HexToBrushConverter.cs b/src/VisionHost.App/Converters/HexToBrushConverter.cs new file mode 100644 index 0000000..bb9d136 --- /dev/null +++ b/src/VisionHost.App/Converters/HexToBrushConverter.cs @@ -0,0 +1,25 @@ +using System.Globalization; +using System.Windows.Data; +using System.Windows.Media; + +namespace VisionHost.App.Converters; + +public sealed class HexToBrushConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is not string hex || hex.Length < 7 || hex[0] != '#') + return Brushes.White; + try + { + return (SolidColorBrush)new BrushConverter().ConvertFromString(hex)!; + } + catch + { + return Brushes.White; + } + } + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotSupportedException(); +} diff --git a/src/VisionHost.App/Themes/Station.xaml b/src/VisionHost.App/Themes/Station.xaml new file mode 100644 index 0000000..d501ea4 --- /dev/null +++ b/src/VisionHost.App/Themes/Station.xaml @@ -0,0 +1,110 @@ + + + + #1A1D21 + #252A31 + #3A414B + #F2F4F7 + #9AA3AF + #22C55E + #EF4444 + #F59E0B + #38BDF8 + #9CA3AF + #16A34A + #DC2626 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/VisionHost.App/Views/RunStationView.xaml b/src/VisionHost.App/Views/RunStationView.xaml new file mode 100644 index 0000000..3355508 --- /dev/null +++ b/src/VisionHost.App/Views/RunStationView.xaml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +