M2 "Machine Management UX": full N-machine management from UI plus runtime resilience. All 3 screens now live (dashboard, detail, config). Core: - PollingEngine offline detection: consecutive-fail threshold emits a synthetic Disconnected snapshot (no-spam, resets on recovery). - MachineMonitor dynamic API: AddOrUpdateMachineAsync / RemoveMachineAsync start/restart/stop a machine's polling live (no app restart); idempotent. - MachineMonitor.AvailableProtocols exposes loaded protocol ids. App: - Machine detail screen: full current snapshot, reachable from dashboard row, live-refreshing, Back nav. - Config screen: add / edit / delete machines with validation; Save upserts + reloads monitor live; Delete two-state confirm + stops polling. - Dashboard: "Add machine" button, per-row Details, reload after mutation. Repo hygiene: - Untrack stray src/Junction.App/plugins/ build artifact (real output goes to bin/*/plugins via build target); add to .gitignore. PAUL: initialized .paul/ (PROJECT/ROADMAP/STATE + paul.json) as cross-session system-of-record. v0.1 shipped, v0.2 complete, v0.3 OPC UA next. Build 0 warn/0 err (net48 + net8.0). Tests: 125 unit + 2 docker integration. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.3 KiB
5.3 KiB
Junction
What This Is
Junction is a Windows desktop application that reads live data from industrial machines over multiple industrial protocols. Protocols are pluggable modules (MTConnect first; OPC UA, Fanuc FOCAS, and others planned). A dashboard lists configured machines with their current status (last read datum), a detail page shows the full current snapshot, and a config screen lets the user add/edit/remove machines.
Core Value
Operators see the live state of every configured machine — across heterogeneous protocols — in one place, adding new machines and protocols without touching code.
Current State
| Attribute | Value |
|---|---|
| Type | Application (C# / .NET, Avalonia desktop) |
| Version | 0.1.0 |
| Status | MVP (M1 walking skeleton shipped; M2 in progress) |
| Last Updated | 2026-07-21 |
Requirements
Core Features
- Dashboard listing configured machines with current connection state + last-read datum, live-refreshing.
- Machine detail page: full current snapshot (all data items) reachable from dashboard.
- Config screen: add / edit / remove machines (name, protocol, endpoint, poll interval).
- Pluggable protocol drivers loaded at runtime (MTConnect implemented).
Validated (Shipped)
- Solution scaffold, multi-project, net48 + net8.0 multi-target — v0.1.0
- Domain: Result, models, IProtocolDriver, IMachineRepository, plugin manifest — v0.1.0
- Core: PollingEngine, PluginLoader (Assembly.LoadFrom), MachineMonitor, DI — v0.1.0
- Persistence: SqliteMachineRepository (Dapper), swap-provider seam — v0.1.0
- MTConnect driver + namespace-version-agnostic parser (1.7 + 2.0) — v0.1.0
- Avalonia dashboard, live last-datum from monitor — v0.1.0
- Docker MTConnect mock (ladder99/agent) — v0.1.0
Active (In Progress)
- M2: machine detail screen (done), config add/edit/delete (in progress), offline detection (done), live monitor reload on config change (in progress)
Planned (Next)
- OPC UA protocol plugin
- Fanuc FOCAS protocol plugin (P/Invoke, Windows-only native fwlib32)
- Historical data / trends (schema already allows)
- Robust disconnection UX
Out of Scope
- .NET 8+ runtime target (fleet includes Windows 7/8 → net48 mandatory)
- EF Core (not net48-compatible at supported versions)
Target Users
Primary: Shop-floor operators / production engineers monitoring CNC and industrial machines.
- Need at-a-glance machine status across mixed protocol fleets.
- Add machines/protocols themselves without a developer.
Constraints
Technical Constraints
- Deploy target Windows only; fleet includes Windows 7/8 → net48 mandatory (last .NET Framework supporting Win7 SP1).
- Avalonia pinned 11.3.x (Avalonia 12 drops net48 — never bump to 12).
- Plugins via Assembly.LoadFrom (net48 = no AssemblyLoadContext, no runtime unload).
- SQLite native e_sqlite3 needs bundle + RuntimeIdentifiers on net48 (efcore#19396).
- Dev machine is Linux → net48 built via Microsoft.NETFramework.ReferenceAssemblies; UI runs on Linux via net8.0 target, ships net48.
- DB behind IMachineRepository (swap SQLite → SQL Server).
- All package versions pinned exact (deterministic builds for fleet).
Business Constraints
- Manager-mode workflow: all implementation delegated to subagents, reviewed by manager (dotnet-manager skill). Caveman communication.
Key Decisions
| Decision | Rationale | Date | Status |
|---|---|---|---|
| net48 target | Fleet includes Win7/8 | 2026-07-21 | Active |
| Avalonia 11.3.10 (never 12) | 12 drops net48 | 2026-07-21 | Active |
| Dapper + Microsoft.Data.Sqlite (not EF Core) | EF Core not net48-viable | 2026-07-21 | Active |
| Dynamic plugins IProtocolDriver + Assembly.LoadFrom | Add protocols without touching core | 2026-07-21 | Active |
| App multi-target net48;net8.0 (dropped separate DevHead) | Dev on Linux net8.0, ship net48, one project | 2026-07-21 | Active |
| CommunityToolkit.Mvvm | Lightweight MVVM, net48-safe | 2026-07-21 | Active |
| Generic Dictionary machine config | Domain stays protocol-agnostic | 2026-07-21 | Active |
Success Metrics
| Metric | Target | Current | Status |
|---|---|---|---|
| Build (net48 + net8.0, Linux) | 0 errors | 0 err / 0 warn | Achieved |
| Test suite | green | 124 pass + 2 docker-skip | On track |
| Live e2e (machine → dashboard) | working | proven vs docker mock | Achieved |
| Protocols supported | 3+ (MTConnect, OPC, Fanuc) | 1 (MTConnect) | On track |
Tech Stack / Tools
| Layer | Technology | Notes |
|---|---|---|
| Language/runtime | C# / .NET Framework 4.8 (+ net8.0 dev head) | multi-target |
| UI | Avalonia 11.3.10 + CommunityToolkit.Mvvm | MVVM |
| DI | Microsoft.Extensions.DependencyInjection 8.0.x | App = composition root |
| Persistence | Dapper 2.1.66 + Microsoft.Data.Sqlite 8.0.11 | behind IMachineRepository |
| Logging | NLog 5.x (via Microsoft.Extensions.Logging) | Core = abstractions only |
| Protocol #1 | MTConnect (HTTP + XML, System.Xml.Linq) | runtime plugin |
| Tests | xUnit + Moq (net8.0) | 124+ tests |
| Mock | Docker ladder99/agent | dev MTConnect agent :5000 |
Links
| Resource | URL |
|---|---|
| Repository | ssh://3nt-git.duckdns.org:222/davide.trentin/junction.git |
PROJECT.md — Updated when requirements or context change Last updated: 2026-07-21