5.2 KiB
5.2 KiB
TODO — implementation status
Companion to docs/IMPLEMENTATION_PLAN.md (the authoritative plan) and
CHANGELOG.md (what shipped). One row per plan task; updated as work lands.
Legend: [done] complete & verified · [partial] some of it landed ·
[todo] not started · [skip] dropped by decision.
Phase 0 — Feasibility & environment [done]
- [done] Wrapper backend decision: OPC DA Automation Wrapper (
OPC.Automation) → 32-bit interpreter mandatory (spec §11). - [done] Test server: Matrikon OPC Simulation Server, local ProgID
Matrikon.OPC.Simulation.1; baseline read RTT + wrapper error shapes recorded (repo memory). - [done] Dependencies chosen for a 32-bit, no-compiler install: ruamel.yaml (PyYAML has no cp314 win32 wheels), pywin32.
Phase 1 — Core engine [done]
- [done] 1.
config.py— typed YAML config + strict validation; D16devices:indicators with configurableok_values;check-configprints them. - [done] 2.
quality.py— decode tables (spec §7) +status_text(raw) -> "NAME / SUBCODE (0xNN)"clear-text helper. - [done] 3.
opc/base.py— client/browser protocols,ReadResult,OpcErrorwith decoded HRESULT. - [done] 4.
opc/automation.py— connect / browse / read (per-itemItem.Read;SyncReadis unmarshallable from pywin32 — verified), per-tag errors, safe COM teardown.- [skip] Single persistent group + static items (poller creates its own per client; the throwaway-group read pattern is verified).
- [done] 5.
monitor/state.py— connection state machine, exponential backoff (1 s → 60 s cap, reset on success), reconnect accounting, D3 flapping window (pure, clock-fed). - [done] 6.
monitor/detectors.py— D4–D16 pure detectors + rolling window: latency spike/streak/p95 (D4–D6), quality transitions/persistence/flapping (D8–D11), stale/frozen (D12–D13), mass-bad latch (D14), D16 device-link (ok_valuesedge-level DOWN/UP). - [done] 7.
monitor/poller.py— coordinator + dedicated COM worker thread (client born on the worker), D7 soft-hang flag, hard-hang watchdog (abandon + rebuild), backoff between sessions.- [open] Poll source default (CACHE vs DEVICE) — needs a spec decision: Matrikon shows BAD qualities on some tags only via CACHE.
- [done] 8.
runverb — foreground monitoring loop, console reporter with clear-text status, heartbeat (D15), Ctrl+C stop (second Ctrl+C aborts). - [done] 9.
opc/fake.py— scenario engine: scripted polls (exact results /"good"shorthand) andPollScriptErrorwhole-call failures; hang clients are plain sleeping fakes in tests.- [open] D12 stale events re-emit every poll while a tag stays stale — the spec defines the condition per-poll; ops may want debounce/latch (decide before the 24 h soak; live sim output showed the spam clearly).
Phase 2 — Reporters
- [todo] 1.
report/jsonl.py— rotating JSONL (size + backups), config-digest header, atomic-ish append. The console reporter already emits the same events inrun(Phase 1); Phase 2 swaps in the fan-out. - [todo] 2.
report/textlog.py— plain-text anomaly log (spec §9.1):anomalies-YYYYMMDD.log, one line per detected anomaly, clear-text statusNAME (0xNN), recoveries logged so it reads as an incident narrative. - [todo] 3.
report/eventlog.py— Windows Event Log (WARN+), source registration viainstall. - [todo] 4.
report/http.py— optional webhook, bounded queue, never blocks polling. - [todo] 5. Heartbeat assembly (D15) + reporter fan-out dispatcher.
Phase 3 — Windows service
- [todo] 1.
service.py—ServiceFrameworkhost; clean stop (STOP_PENDING, join-with-timeout, abandon hung COM thread). - [todo] 2. CLI verbs
install/uninstall/start/stop(sc.exe semantics). - [todo] 3. SCM recovery (
sc failure ... restart), auto-start, service account docs. - [todo] 4.
%ProgramData%\OPCDA-Diagnozer\config/log dir conventions (frozen exe already defaults there). - [open] Frozen-exe SCM hosting: console exe must expose
ServiceMain— one careful build pass (pywin32ServiceControlDispatcher).
Phase 4 — Integration & chaos testing
- [todo] Scenario matrix vs the sim server: server kill / service stop /
firewall silent drop / latency injection / device comm failure / quality
oscillation / stale+frozen / mass bad / config errors / D16: flip a device
indicator (e.g. a
P500x.Connectedalias). - [todo] 24 h soak (AC10): no leaks, reconnect accounting correct, heartbeats every 5 min, ≤ ~50 MB RAM, ~0 % CPU idle.
Phase 5 — Packaging & docs
- [done] PyInstaller exe build (
scripts/build_exe.ps1, onedir + onefile, read canary) — live-verified. - [done] README (install, config, DCOM checklist, HRESULT table).
- [todo] Ops runbook: reading events, kind meanings (spec §12 matrix), threshold tuning, evidence locations.
- [todo] 1.0.0 tag once AC1–AC10 pass.
Housekeeping
- [todo] Wire
status_textintoread/probeoutput once it exists (currently showsraw_hex+ decoded name separately). - [todo] Record the CACHE-vs-DEVICE poll-source decision in the spec once made; add fake-client scripted reads for both sources to the poller tests.