📝 Documenation
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
# ExecPlan 001 — Implementation Roadmap: AquaCom Integration Gateway
|
||||
|
||||
**Document type:** ExecPlan (umbrella roadmap)
|
||||
**Status:** Active
|
||||
**Created:** 2026-10-06
|
||||
**Scope:** Phases 0–14 (implementation specification §60) through the initial production release
|
||||
**Authoritative references:** `ARCHITECTURE.md` · `docs/product/software-specification.md` · `docs/product/codex-implementation-specification.md` · `docs/configuration/configuration-reference.md` · `docs/protocol/` (gap registry, operations registry, test vectors)
|
||||
|
||||
> This is the **umbrella plan**: it sequences the whole implementation and records cross-phase decisions. Substantial individual features may spawn focused child ExecPlans in this directory (implementation specification §59); this roadmap remains the index. Per `ARCHITECTURE.md` §1, role-authoritative documents win over any restatement here.
|
||||
|
||||
---
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
Provide a single, gated execution path from the current documentation-complete, evidence-prepared repository state to the initial production release defined by `software-specification.md` §47 / implementation specification §74, such that:
|
||||
|
||||
- every implemented AquaCom behavior traces to verified evidence (`AGENTS.md`, `known-operations.md`);
|
||||
- each phase ends in a working, testable repository state (implementation specification §79);
|
||||
- the one open blocking decision (technology selection) is resolved explicitly and recorded before code begins;
|
||||
- protocol gaps are consumed at the phase that needs them, with documented workarounds where possible.
|
||||
|
||||
## 2. Current state (2026-10-06)
|
||||
|
||||
**Exists and verified:**
|
||||
|
||||
- Complete, consistent documentation set: short-form `AGENTS.md` entry point; `ARCHITECTURE.md` with document precedence (§1) and invariants INV-001…INV-016; `software-specification.md` with requirement IDs AQG-001…AQG-030 and RFC-2119 keywords; agent-neutral implementation specification; `configuration-reference.md`.
|
||||
- Protocol evidence: authoritative source (*AquaCom – RTU level, Rev 1.6, ITT Flygt AB, 2004*) as PDF + markdown conversion in `docs/protocol/`.
|
||||
- `docs/protocol/protocol-gaps.md` — 10 entries (1 `VERIFY`, 9 `OPEN`), each with working hypotheses where applicable.
|
||||
- `docs/protocol/known-operations.md` — OPS-001…OPS-012 registered with evidence sections, scope status, and an evidence-complete implementation order.
|
||||
- `docs/protocol/test-vectors.md` — **35 source checksum vectors verified by recomputation** against the §2.4 algorithm (including the §3.6.4 Wait-byte pair), framing/session vectors, 4 synthetic wraparound vectors, WGS/WGH/WGD decode scenarios, simulator scenario requirements.
|
||||
|
||||
**Does not exist yet:** `src/`, `tests/`, `simulator/`, `schemas/`, `config/`, CI, `README.md`, `CHANGELOG.md`, any implementation.
|
||||
|
||||
**Open:** technology selection (decision D-001 below) — the only blocking item.
|
||||
|
||||
## 3. Desired state
|
||||
|
||||
The initial production scope (implementation specification §74): verified live and historical AquaCom acquisition for multiple stations; canonical data model; live cache; historical pipeline with deduplication and durable spool; ≥1 queryable history repository; ≥2 independently configurable storage destinations; OPC UA Data Access + Historical Access with stable NodeIds and security on by default; diagnostics and structured logging; simulator; automated tests including restart recovery; configuration validation. Explicitly excluded: process control, setpoint writes, OPC UA HistoryUpdate, HA clustering (implementation specification §75).
|
||||
|
||||
## 4. Constraints
|
||||
|
||||
Hard rules that bind every phase (traceability in parentheses):
|
||||
|
||||
1. Never invent AquaCom protocol behavior; evidence classes only (`AGENTS.md`; implementation specification §3.1).
|
||||
2. AquaCom logic only in `src/aquacom`; OPC UA and storage never parse telegrams (INV-001/002/003).
|
||||
3. Historical samples never update current state (INV-004); SourceTimestamp preserved (INV-005).
|
||||
4. OPC UA HistoryRead queries a repository, never the RTU (INV-006).
|
||||
5. Storage failure never stops live acquisition (INV-007).
|
||||
6. Stable StationId/PointId/NodeIds across restart, upgrade, rename, transport change (INV-008/009).
|
||||
7. Watermark advances on durable spool commit (INV-014); dedup correct across restart (INV-015).
|
||||
8. Out-of-order historical arrival supported (INV-013); missing-timestamp records quarantined (INV-016).
|
||||
9. Live acquisition priority over backfill (AQG-028); every queue bounded (ARCHITECTURE §51).
|
||||
10. Secure defaults; no secrets in the repo (`AGENTS.md` Security).
|
||||
|
||||
## 5. Open decisions
|
||||
|
||||
| ID | Decision | Blocks | Recommendation / resolution path |
|
||||
|---|---|---|---|
|
||||
| **D-001** | Implementation language + OPC UA server stack | **Phase 1 (all code)** | The hard constraint is **server-side Historical Access** (Part 11) — far less commonly supported than Data Access. Run a HistoryRead smoke test per candidate before committing. Candidates in priority order: C#/.NET (OPC Foundation .NET Standard stack — reference HA implementation), Java/Milo (HA supported), Python/asyncua (fast development; **verify HA server completeness first**). |
|
||||
| D-002 | Configuration format | Phase 0 (schema skeleton) | YAML — all examples in `configuration-reference.md` are already YAML. Low risk. |
|
||||
| D-003 | First history repository technology | Phase 8 | Behind the `HistoryRepository` interface (ARCHITECTURE §25), so replaceable. Embedded (e.g. SQLite) minimizes external dependencies for the first release; external (PostgreSQL/TimescaleDB) remains a valid Phase 12+ sink. Decide at Phase 8 entry. |
|
||||
| D-004 | Second storage sink technology | Phase 12 | NDJSON file archive is the lowest-risk second destination (config examples already use it). Decide at Phase 12 entry. |
|
||||
| D-005 | CI platform | Phase 0 | Whatever the repository host provides; must run format/lint/static/unit/integration + schema validation without network access (implementation specification §57). |
|
||||
| D-006 | Configuration schema technology | Phase 0 | JSON Schema if D-002 = YAML (standard YAML-schema validation path). |
|
||||
|
||||
**Pre-implementation checklist (project owner, in order):**
|
||||
|
||||
1. **Resolve D-001.** I can build and run the HA smoke test for each candidate stack on request — a ~50-line HistoryRead server+client per candidate settles it empirically.
|
||||
2. **PDF spot-checks** (~30 min, recommended before Phase 3/6; non-blocking for Phases 0–2): confirm AQ-GAP-001(a) MCC type table, (b) WGS answer `mp1–mp128` byte ranges, (e) whether §3.7 truly ends mid-telegram; AQ-GAP-002 whether the PDF defines `alp` more explicitly; AQ-GAP-006 whether the MAT request really prints 557.
|
||||
3. **Confirm deployment target**: OS/host, and whether field contact is TCP via terminal server (serial-over-IP) or direct serial — determines which Phase 2 transports to implement first.
|
||||
|
||||
**What does *not* block starting:** real RTU hardware or captures (the simulator drives Phases 0–13; every gap that would need a live capture has a documented workaround), `aquacom.md` consolidation, operations documentation (Phase 14).
|
||||
|
||||
## 6. Implementation sequence
|
||||
|
||||
### 6.1 Phase/gate overview
|
||||
|
||||
| Phase | Scope (§60) | Gate — exit criteria | Key gap dependency |
|
||||
|---|---|---|---|
|
||||
| **0** | Repository skeleton, CI, README/CHANGELOG, config schema skeleton | **G0:** CI green on placeholder test; schema validates the §72 minimal config; tree matches implementation specification §5 | — |
|
||||
| **1** | Canonical core: StationId, PointId, CurrentValue, HistoricalSample, DataQuality, AcquisitionSource, config domain | **G1:** domain unit tests + serialization round-trips pass; identifier-stability rule enforced (rename ≠ new PointId); `core` has zero aquacom/opcua/storage imports | — |
|
||||
| **2** | Transport abstraction + mock transport; TCP first (serial-over-IP per deployment answer) | **G2:** connect/send/receive/timeout/reconnect tests pass; supports shared-medium arbitration (software-specification §5.1) | — |
|
||||
| **3** | Codec framework: framing, checksum, Wait-byte stripping, validation, fixture framework | **G3:** **100 % of approved vectors green** (AQ-CK-001…035, S1–S4, framing vectors AQ-FR-001…005); invalid telegrams rejected with diagnostics | AQ-GAP-001 (`VERIFY` items against PDF) |
|
||||
| **4** | AquaCom simulator | **G4:** scripted WGS success/timeout/malformed/checksum-error/configurable values; **no shared codec code** (self-validation ban, §49) | — |
|
||||
| **5** | Station/session manager | **G5:** multiple simulated stations; one failing station does not affect others; state machine per §18; configurable thresholds | — |
|
||||
| **6** | Live acquisition: WGS decode → point mapping → scaling → CurrentValue | **G6:** simulator → CurrentValue with correct value, quality, timestamps (Source vs Received distinguished); scaling formula applied; alarm/point split via `Nal` | AQ-GAP-002 (workaround: decode via `Nal`, `alp` diagnostic-only) |
|
||||
| **7** | OPC UA live interface: DA, subscriptions, stable NodeIds, security | **G7:** OPC UA test client browses/reads/subscribes; NodeIds stable across restart; security `None` disabled | — |
|
||||
| **8** | Local historical repository (first queryable store) | **G8:** store / query interval / bounds / restart persistence behind the §25 interface | — |
|
||||
| **9** | Historical pipeline: validation → dedup → durable spool → distribution | **G9:** duplicate submissions produce no duplicate records (idempotent across restart, INV-015); spool survives restart; out-of-order writes accepted (INV-013) | — |
|
||||
| **10** | AquaCom historical acquisition: WGH retrieval, watermark, backfill state machine, throttling | **G10:** simulator's missing interval recovered after reconnect; watermark resumes from persistent state; backfill throttled so live polling stays responsive | AQ-GAP-003 (hypothesis: block value count from station CFG — validate against simulator) |
|
||||
| **11** | OPC UA Historical Access: HistoryRead raw values, continuation | **G11:** HA client reads both originally stored and recovered values; continuation works; **INV-006 test: HistoryRead never triggers AquaCom traffic** | — |
|
||||
| **12** | Second storage destination (sink abstraction) | **G12:** one HistoricalSample → repository + sink B; failure of B does not stop A | — |
|
||||
| **13** | Store-and-forward resilience | **G13:** destination offline → history accumulates → delivered on restore; restart during backlog loses no acknowledged data (§53) | — |
|
||||
| **14** | Production hardening: security, resource limits, performance validation, ops documentation | **G14:** §77 DoD reviewed item-by-item; §69 performance validation with capacity targets recorded | — |
|
||||
| **O-1** (optional, after 10) | WGD periodical reports (`AQUACOM_REPORT`) | report day retrieved, scaled per point, `NDA` handled as missing-not-failed | AQ-GAP-009 (documented defaults) |
|
||||
|
||||
### 6.2 Task mapping (implementation specification §79)
|
||||
|
||||
T001→P0 · T002→P1 · T003→P0/P1 (config model + schema validation) · T004→P2 · T005+T006→P3 · T007→P4 · T008→P6 (WGS, first verified live operation) · T009→P5/P6 · T010→P6 (current-state service) · T011→P7 · T012→P8 · T013→P9 · T014→P9/P13 (durable spool) · T015+T016→P10 (WGH + backfill state machine) · T017→P11 · T018→P12 · T019→P13 (full reconnect/backfill acceptance) · T020→P14.
|
||||
|
||||
Each task ends in a working repository state. Recommended task granularity: one §79-sized task per working session, each with the Goal / Files / Behavior / Constraints / Tests / Acceptance structure (§61).
|
||||
|
||||
### 6.3 Gap consumption schedule
|
||||
|
||||
| Gap | Consumed at | Handling |
|
||||
|---|---|---|
|
||||
| AQ-GAP-001 | before Phase 3 table implementations | `VERIFY` against PDF; 35 approved vectors already cover framing/checksum |
|
||||
| AQ-GAP-002 | Phase 6 | workaround documented (decode via `Nal`); hypothesis strengthened by all four examples |
|
||||
| AQ-GAP-003 | Phase 10 | hypothesis wired to station CFG; simulator validation; close on first real capture |
|
||||
| AQ-GAP-004 | text points (none in initial scope) | deferred |
|
||||
| AQ-GAP-005 | any time PDF text is available | transcribe long examples → recompute → approve as wraparound fixtures (synthetics cover the branch meanwhile) |
|
||||
| AQ-GAP-006 | Phase 3 fixture import | use 540 once PDF-confirmed; verified answer vector approvable independently |
|
||||
| AQ-GAP-007 | SCE handling (Phase 3/6) | payload treated as optional diagnostic, never parse-critical |
|
||||
| AQ-GAP-008/009/010 | dialled lines / WGD / alarms | extension scope; not in initial release |
|
||||
|
||||
## 7. Files/components affected
|
||||
|
||||
`src/{core,aquacom,history,storage,opcua,diagnostics,host}/` per `ARCHITECTURE.md` §6 and dependency direction §7 · `tests/{unit,integration,protocol,opcua,history,acceptance}/` · `simulator/` · `fixtures/` (imported from `docs/protocol/test-vectors.md`) · `schemas/` · `config/examples/` · `README.md`, `CHANGELOG.md` · CI definition · documentation updates in `docs/` as behavior lands (never after).
|
||||
|
||||
## 8. Data model changes
|
||||
|
||||
None yet — the canonical contracts are frozen in `ARCHITECTURE.md` §13–§14 and implementation specification §10–§13. Any contract change requires: update the role-authoritative document first, update dependents, update tests, record the decision here. The core module must compile without AquaCom/OPC UA/storage imports (enforced in CI from Phase 1).
|
||||
|
||||
## 9. Failure handling
|
||||
|
||||
The failure matrix of `software-specification.md` §35 / `ARCHITECTURE.md` §55 is normative: station failure isolates; storage failure isolates and buffers; OPC UA failure never stops acquisition; malformed telegrams are rejected with diagnostics; restart loses no acknowledged history. Each phase's tests must cover the failure modes it introduces (implementation specification §56 fault injection); every new failure mode gets a diagnostic (AGENTS.md Task completion).
|
||||
|
||||
## 10. Testing
|
||||
|
||||
- Pyramid per §50: deterministic unit/component tests dominate; integration via simulator; acceptance scenario at the top.
|
||||
- Fixtures: imported **only** from `docs/protocol/test-vectors.md`; approved fixtures immutable; new vectors require evidence and registry update (never delete).
|
||||
- Protocol tests run without external network (§57); simulator must not share codec code (§49).
|
||||
- Restart-recovery tests at every phase that adds persistent state (§53).
|
||||
- Bug fixes carry regression tests (AGENTS.md).
|
||||
|
||||
## 11. Migration/compatibility
|
||||
|
||||
Storage schemas versioned with explicit migrations; startup never silently destroys incompatible data; destructive migration requires administrative action (implementation specification §65). `configVersion` gating with explicit migration tooling (§66). OPC UA NodeId stability across releases (§68); configuration schema changes never force namespace changes (`configuration-reference.md` §71).
|
||||
|
||||
## 12. Progress
|
||||
|
||||
| Date | Entry |
|
||||
|---|---|
|
||||
| 2026-10-05 | Documentation set completed and made consistent; protocol evidence acquired (Rev 1.6 source); gap registry (10 entries), operations registry (OPS-001…012), and test-vector catalogue (35 verified vectors) created. Phase 0 documentation deliverables done. |
|
||||
| 2026-10-06 | This roadmap created. Awaiting D-001 (technology selection) before Phase 0 code tasks. |
|
||||
| 2026-10-06 | `README.md` and `CHANGELOG.md` created — the §5 repository-structure documentation items for Phase 0 are complete. Remaining Phase 0 deliverables: technology selection (D-001), code skeleton, CI, configuration schema. |
|
||||
|
||||
_Update this log at every phase gate; spawn child ExecPlans for §59-triggering work and link them here._
|
||||
|
||||
## 13. Decisions log
|
||||
|
||||
| ID | Date | Decision | Reference |
|
||||
|---|---|---|---|
|
||||
| DR-001 | 2026-10-05 | Documentation unescaped, de-duplicated; single-source-of-truth precedence defined | `ARCHITECTURE.md` §1 |
|
||||
| DR-002 | 2026-10-05 | `AGENTS.md` reduced to short entry-point form per its own spec §4/§6 | `AGENTS.md` |
|
||||
| DR-003 | 2026-10-05 | Watermark advances on **durable spool commit**, not final delivery | `ARCHITECTURE.md` §21, INV-014 |
|
||||
| DR-004 | 2026-10-05 | Duplicate-conflict default **REJECT_CONFLICT** | software-spec §13 |
|
||||
| DR-005 | 2026-10-05 | Deduplication correct across restart (persisted state or idempotent storage) | INV-015 |
|
||||
| DR-006 | 2026-10-05 | Pipeline accepts out-of-order historical arrival; queries order by SourceTimestamp | INV-013 |
|
||||
| DR-007 | 2026-10-05 | Records without usable SourceTimestamp quarantined with diagnostics | INV-016 |
|
||||
| DR-008 | 2026-10-05 | Control/setpoint writes OUT-OF-SCOPE for initial release; read-only integration first | known-operations OPS-005/006/009/010 |
|
||||
| DR-009 | 2026-10-05 | WGS decode via `Nal`; `alp` diagnostic-only until AQ-GAP-002 closes | AQ-GAP-002 hypothesis |
|
||||
| DR-010 | 2026-10-05 | WGH block value count derived from station CFG | AQ-GAP-003 hypothesis |
|
||||
| DR-011 | 2026-10-06 | Umbrella roadmap established; D-001 recorded as the blocking decision | this document |
|
||||
|
||||
## 14. Unexpected findings
|
||||
|
||||
- Source document contains checksum/typo defects: MAT fetch request prints 557 (recomputes 540; 557 = SLT fetch checksum — copy-paste error), narrative destination mismatches (§2.2.3.1 "plant 89" vs telegram dest 86; §3.4.10.2 fixed-line dest given as plant number) — recorded in AQ-GAP-005/006.
|
||||
- The PDF→markdown conversion is lossy at specific tables and truncates §3.7; byte-exact recomputation of long examples from the conversion is impossible (AQ-GAP-001/005). The PDF is authoritative.
|
||||
- The §2.4 checksum algorithm verified exactly against all 35 single-line examples — including the subtle rules that spaces around `#` are summed and Wait bytes are excluded.
|
||||
|
||||
## 15. Acceptance evidence
|
||||
|
||||
Production evaluation requires all of (implementation specification §77), evidenced by:
|
||||
|
||||
1. **Mandatory end-to-end scenario** (§54 T0–T8; `software-specification.md` §46): recorded as an automated acceptance test (T019); passing run attached to the Phase 14 gate.
|
||||
2. **Protocol traceability audit:** every implemented operation maps to an `known-operations.md` entry with evidence; remaining gaps explicitly listed (§77 items 2, 15) — the gap registry *is* the evidence.
|
||||
3. **Vector suite green:** all approved vectors passing in CI (§77 item 12).
|
||||
4. **Restart/data-integrity tests** (§53): no acknowledged history lost across restart, outage, backlog (items 7–9).
|
||||
5. **Security tests** (§55): untrusted certs rejected, None disabled in production config, no secrets logged.
|
||||
6. **DoD checklist review:** the 15 items of §77 walked item-by-item at G14, each with its artifact.
|
||||
7. Items 13 (validated against real equipment/traffic) and operational documentation remain **post-simulator** milestones dependent on field access — explicitly tracked, not silently dropped.
|
||||
|
||||
## 16. Plan maintenance
|
||||
|
||||
- Update §12 (Progress) at every phase gate; record new decisions in §13 immediately.
|
||||
- Spawn a child ExecPlan (same structure, §59) for: any new AquaCom operation, storage/persistence architecture, OPC UA namespace redesign, security changes, cross-module refactors, data migration. Link children from §12.
|
||||
- Move this plan to `docs/exec-plans/completed/` when G14 and §15 are satisfied.
|
||||
- This plan never overrides the role-authoritative documents (`ARCHITECTURE.md` §1).
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 181 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
@@ -0,0 +1,165 @@
|
||||
# AquaCom known operations registry
|
||||
|
||||
**Source of all evidence:** *Technical description – AquaCom – RTU level*, Rev 1.6, ITT Flygt AB, July 2004 (`AquaCom_RTU_1_6_eng.pdf`; markdown conversion in this folder). Section references below are to that document.
|
||||
|
||||
**Purpose.** Registers every AquaCom operation the gateway may implement, with its evidence and implementation status. An operation enters this registry *before* implementation begins; adding an operation with status beyond `REGISTERED` requires its evidence to be complete and its gaps resolved or scoped. Open questions live in `protocol-gaps.md` — this registry never invents behavior not stated in the source.
|
||||
|
||||
**Status values:** `REGISTERED` (evidence located, not yet implemented) · `PARTIAL` (framework-level support only) · `IMPLEMENTED` (codec + tests + traceability) · `OUT-OF-SCOPE` (deliberately not implemented in the initial release; evidence retained for future phases).
|
||||
|
||||
**Framing note (applies to every operation):** CS→RTU telegrams are `SOH + SPACE + DEST + SPACE + TYPE + SPACE + DATA… + SPACE + '#' + SPACE + CHK + CR`; RTU→CS telegrams are `STX + SPACE + DATA… + SPACE + '#' + SPACE + CHK + CR` (§2.3.2). Checksum per §2.4; `Wait` (DC3) bytes are stripped before parsing and excluded from the checksum (§3.6.4).
|
||||
|
||||
---
|
||||
|
||||
## Session / control operations
|
||||
|
||||
### OPS-001 — Connection message (`OK`)
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | RTU→CS (CS dialled) · CS→RTU (RTU dialled in alarm) |
|
||||
| Purpose | Dialled-line connection answer; the answering side sends OK before conversation begins. The answering phase is "6×OK with 2.5s delay between each, aborted as soon as a telegram arrives"; some RTUs send 2×OK ≈4s apart instead (§2.2.3, §3.3.1). |
|
||||
| Evidence | §2.2.3, §3.3.1, examples §3.4.1.2, §3.4.5.3, §3.4.7.2, §3.4.9.2, §3.4.10.3, §3.4.11.3, §3.4.12.2 |
|
||||
| Gaps | — |
|
||||
| Status | REGISTERED (dialled lines only; not applicable to fixed/TCP operation) |
|
||||
|
||||
### OPS-002 — Break (`BRK`)
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | CS→RTU |
|
||||
| Purpose | End communication. No answer is returned. Send 3× in a row before hanging up. Mandatory after a WGS containing a control command — some RTUs stay "remote controlled" until BRK (§3.4.13). |
|
||||
| Evidence | §3.4.13 |
|
||||
| Gaps | — |
|
||||
| Status | REGISTERED (required for session teardown; harmless on fixed lines) |
|
||||
|
||||
### OPS-003 — Break with acknowledge (`EBR`)
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | CS→RTU |
|
||||
| Purpose | BRK variant expecting a `SCO` answer; retransmit up to 6 times on timeout or wrong answer. Not supported in Forth RTUs (§3.5.4, §3.2 summary table). |
|
||||
| Evidence | §3.5.4 |
|
||||
| Gaps | — |
|
||||
| Status | REGISTERED (Basic RTUs only) |
|
||||
|
||||
### OPS-004 — Caller identification (dialled lines)
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | RTU→CS |
|
||||
| Purpose | Identifies the calling RTU (`STX DEST ACT # CHK CR`); capability-dependent (§2.2.3.2). |
|
||||
| Evidence | §2.2.3.2–3 |
|
||||
| Gaps | AQ-GAP-008 (ACT values unknown) |
|
||||
| Status | REGISTERED — blocked by AQ-GAP-008 |
|
||||
|
||||
---
|
||||
|
||||
## Live-data operations
|
||||
|
||||
### OPS-005 — Status request (`WGS`)
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | CS→RTU, answer RTU→CS |
|
||||
| Purpose | Live-values polling. Answer: `ver, prod, Nal, alp, rem, r1–r4, mp1–mpN` (measuring points for the requested picture), followed by `Nal` alarm codes (§3.4.10). This is the protocol's primary live-acquisition operation. |
|
||||
| Evidence | §3.4.10, examples §3.4.10.2–3, §2.2.3.1, §3.6.4; CFG picture/command sections §3.4.10.4–5 |
|
||||
| Gaps | AQ-GAP-002 (alp semantics; hypothesis `mp count = alp−1` consistent with all four examples), AQ-GAP-005 (long-example checksums pending PDF transcription) |
|
||||
| Status | REGISTERED (live acquisition is core scope; see `software-specification.md` §11) |
|
||||
|
||||
The `dir` field (F/B/N/M/!) is machine **control** — excluded from the initial release (`software-specification.md` §3.2); the decoder shall tolerate its syntax, and the gateway shall always transmit `!` (ignore).
|
||||
|
||||
### OPS-006 — Alarm request (`WCA`) and answers `ALR`/`ALN`/`ALO`
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | CS→RTU (`WCA`, `ALO`), RTU→CS (`ALR`, `ALN`) |
|
||||
| Purpose | Alarm polling/acknowledgement; `set=2` sets the RTU clock from the request's date/time (§3.4.1). Alarm retrieval is extension scope but the evidence now exists. |
|
||||
| Evidence | §3.4.1, §2.2.3.3, §3.5.1.1 (Basic ALR variant) |
|
||||
| Gaps | AQ-GAP-010 |
|
||||
| Status | REGISTERED — alarm retrieval is OUT-OF-SCOPE for the initial release; clock setting (`set=2`) also OUT-OF-SCOPE (audit + confirmation architecture required first, cf. implementation specification §76) |
|
||||
|
||||
---
|
||||
|
||||
## Historical-data operations
|
||||
|
||||
### OPS-007 — Historical trend (`WGH`)
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | CS→RTU, answer RTU→CS (data or `NDA`) |
|
||||
| Purpose | 5-minute-block historical trend retrieval. Request carries the timestamp of the last stored block; the answer continues from there, up to max 6 hours / 4000 chars; `NDA` ends the stream. This is the backfill/watermark operation the Historical Acquisition Manager is built around (§3.4.12). |
|
||||
| Evidence | §3.4.12 incl. full multi-answer example §3.4.12.2 and CFG scaling §3.4.12.3; wire-level example §3.7 |
|
||||
| Gaps | AQ-GAP-003 (block value count), AQ-GAP-001(e/g) |
|
||||
| Status | REGISTERED (core scope; requires `protocol-gaps.md` AQ-GAP-003 working hypothesis wired to station point configuration) |
|
||||
|
||||
Semantics confirmed by example: a day's final block is timestamped `00:00` of the *next* day (§3.4.12.2 comment); requests use the last received block's timestamp to resume — the exact pattern the gateway's synchronization watermark must reproduce.
|
||||
|
||||
### OPS-008 — Periodical report (`WGD`)
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | CS→RTU, answer RTU→CS (data or `NDA`) |
|
||||
| Purpose | Per-day segmented aggregates (default 00-06 / 06-09 / 09-16 / 16-00 + sum) per reporting point (§3.4.11). Maps to canonical `AcquisitionSource = AQUACOM_REPORT`. Request also sets the RTU clock (same caveat as WCA). |
|
||||
| Evidence | §3.4.11 incl. CFG section and scaling formula |
|
||||
| Gaps | AQ-GAP-009, AQ-GAP-010(b) |
|
||||
| Status | REGISTERED (implemented after WGH; report points configured separately from trend points per §3.4.11.4) |
|
||||
|
||||
---
|
||||
|
||||
## Configuration / definition operations
|
||||
|
||||
### OPS-009 — Function channels (`MCC`, `MPA`, `MPB`, `MPC`, `MPD`, `MPL`)
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | CS→RTU (set) and RTU→CS (fetch) |
|
||||
| Purpose | Setpoint/config channel write & fetch. **Fetch limitation (Forth):** the RTU echoes only the *last sent* telegram — you must send what you want to receive; a cold-started RTU cannot be fetched from (§3.4.2–3, §3.4.3 "Important 2"). Types: `A`/`D` integer, `T` text (quoted, `_` = empty/space-as-underscore), `0–4` float decimals (§3.4.2.2; Basic variant §3.5.2). |
|
||||
| Evidence | §3.4.2–3, §3.4.2.3 CFG/AquaView examples |
|
||||
| Gaps | AQ-GAP-001(a), AQ-GAP-004 |
|
||||
| Status | REGISTERED (used for station configuration; **writes to setpoints are control operations — OUT-OF-SCOPE initially**; read-back of a previously sent telegram is acceptable) |
|
||||
|
||||
### OPS-010 — Analogue channels (`MAS`)
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | CS→RTU (set) and RTU→CS (fetch) |
|
||||
| Purpose | Analogue input config (signal type, alarm levels, hysteresis, decimals; `htr` trend flag on Basic RTUs). Fetch requires a prior send, as with MCC (§3.4.4–5, §3.5.3). |
|
||||
| Evidence | §3.4.4–5, §3.5.3, CFG examples |
|
||||
| Gaps | AQ-GAP-003 (htr vs. Forth CFG trend section) |
|
||||
| Status | REGISTERED (definitions source; writes OUT-OF-SCOPE initially, as OPS-009) |
|
||||
|
||||
### OPS-011 — Alarm code filter (`MAT`) and priorities (`SLT`)
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | CS→RTU (set) and RTU→CS (fetch, capability-dependent per ATF controller-type digits) |
|
||||
| Purpose | Alarm code remapping and A–Z priorities. The document itself states MAT "is not necessary to implement" (§3.4.6.3). |
|
||||
| Evidence | §3.4.6–9 |
|
||||
| Gaps | AQ-GAP-006 |
|
||||
| Status | OUT-OF-SCOPE (alarm system extension; revisit when alarm retrieval is scheduled) |
|
||||
|
||||
---
|
||||
|
||||
## Answer telegrams (all operations)
|
||||
|
||||
### OPS-012 — Fixed answers `SCO` / `SCE` / `NDA` / `!!` (Wait)
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Direction | RTU→CS |
|
||||
| Purpose | `SCO` = telegram OK; `SCE` = error in telegram (optional rejected-channel payload, AQ-GAP-007); `NDA` = requested data not available (normal WGH/WGD stream terminator — **not** an error); `!!` = single DC3 (13H) byte, may be embedded *inside* another telegram, must be stripped before parsing, excluded from checksum, and resets the CS receive timeout (§3.6). |
|
||||
| Evidence | §3.6, §3.6.4 checksum-identical pair of examples (both verified: 2925), §3.7 |
|
||||
| Gaps | AQ-GAP-007 (SCE payload) |
|
||||
| Status | REGISTERED (the `!!` handling is a hard requirement for any long-answer operation: WGH, WGD, WGS, MCC fetch) |
|
||||
|
||||
---
|
||||
|
||||
## Implementation order (evidence-complete subset)
|
||||
|
||||
1. Framing + checksum + `!!` stripping (OPS-012 + framing note) — fully evidenced, unblocked.
|
||||
2. OPS-005 `WGS` (live) — blocked only by AQ-GAP-002, which has a documented workaround (decode via `Nal`, cross-check `alp` diagnostically).
|
||||
3. OPS-007 `WGH` (history) — blocked by AQ-GAP-003 working-hypothesis wiring (station configuration drives block layout).
|
||||
4. OPS-008 `WGD` (reports) — after WGH; AQ-GAP-009 defaults.
|
||||
5. Session ops OPS-001/002 as transports require (BRK for fixed-line WGS sessions).
|
||||
|
||||
This order matches the implementation phases (Phase 3 codec → Phase 6 live → Phase 10 historical) and honors live-over-history scheduling.
|
||||
@@ -0,0 +1,163 @@
|
||||
# AquaCom protocol gap registry
|
||||
|
||||
**Source:** *Technical description – AquaCom – RTU level*, Rev 1.6, ITT Flygt AB, July 2004 — present in this folder as `AquaCom_RTU_1_6_eng.pdf` (markdown conversion: `AquaCom_RTU_1_6_eng_markdown/AquaCom_RTU_1_6_eng.md`). The PDF is authoritative wherever the conversion is ambiguous.
|
||||
|
||||
**Policy.** AquaCom protocol behavior may only be implemented from verified evidence (`AGENTS.md`; implementation specification §3.1). Unresolved protocol questions are recorded here instead of guessed (implementation specification §62, case C). An entry is closed only when the missing evidence exists; closing requires citing the evidence, adding a resolution note, and changing the status. Entries are never deleted.
|
||||
|
||||
**Entry format** (implementation specification §17): Gap ID, Description, Affected operation, Evidence available, Evidence missing, Impact, Implementation status.
|
||||
|
||||
**Status values:**
|
||||
|
||||
- `OPEN` — evidence missing; implement only what is documented, never the undocumented part.
|
||||
- `VERIFY` — evidence exists in the PDF; the markdown conversion is unreliable at the cited places; check the PDF before implementing.
|
||||
- `CLOSED` — resolved; cite evidence and date in a resolution note.
|
||||
|
||||
---
|
||||
|
||||
## AQ-GAP-001 — Fidelity of the markdown conversion
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Gap ID | AQ-GAP-001 |
|
||||
| Description | The PDF→markdown conversion is lossy at several places. Confirmed instances: (a) §3.4.2.2 MCC DATA type table is mangled — the type rows are merged ("A = D = Integer (0-32767) … Analogue (0-200)"); (b) §3.4.10.1 WGS status-answer table merges the `mp1–mp128` byte-range cell into the description text (recoverable reading: 1–12 bytes each, measuring points 1–128); (c) §2.2.3.2 caller-ID field table formatting is broken; (d) §3.4.2.3.3 controller-type example prints `101 001` while the surrounding text refers to `(010)` (the parallel sections print `101 010` and `101 100` consistently); (e) the §3.7 detailed example is truncated mid-telegram ("…_0_1_1" followed by the document footer), so the answer's checksum is never reached; (f) WGS request examples print `0!` for the `mash`/`dir` fields — checksum verification proves the wire form is `0 !` (two space-separated fields), so this instance is resolved, but the PDF rendering should be confirmed for the record; (g) §3.4.12.1 states the WGH block `YY` is 2 bytes, but checksum-verified examples transmit single-digit years (e.g. `1 4 30 23 35`) — all block date fields shall be accepted as 1–2 digits. |
|
||||
| Affected operation | all telegram parsing |
|
||||
| Evidence available | authoritative PDF in this folder |
|
||||
| Evidence missing | none — each affected table must be checked against the PDF before implementation |
|
||||
| Impact | wrong field layouts if implemented from the markdown conversion alone |
|
||||
| Status | `VERIFY` |
|
||||
|
||||
---
|
||||
|
||||
## AQ-GAP-002 — WGS status answer: `alp` semantics and measuring-point/alarm boundary
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Gap ID | AQ-GAP-002 |
|
||||
| Description | `Nal` ("number of alarms following last measuring point") is unambiguous and consistent with all examples: alarm codes are appended after the measuring points, `Nal` of them. `alp` ("position where the first alarm is to be found") does not define its reference frame in the document. Arithmetic across **all four** printed examples is consistent with `alp` = the 1-based position, within the measuring-point sequence, of the first alarm, i.e. `measuring-point count = alp − 1`: §2.2.3.1 (alp=48, Nal=3), §3.4.10.2 (alp=22, Nal=1), §3.4.10.3 (alp=64, Nal=1), §3.6.4 (alp=11, Nal=1, 10 measuring points explicit). The earlier note that §2.2.3.1 "does not reconcile" was an analysis error (a mis-split field list), now retracted. What remains missing is an explicit definition, and a capture from a real station (the four examples agree but are all from the same vendor document). |
|
||||
| Affected operation | WGS status answer decoding |
|
||||
| Evidence available | §3.4.10.1 field definitions; arithmetic of examples §2.2.3.1, §3.4.10.2–3, §3.6.4 |
|
||||
| Evidence missing | an explicit definition, or a validated capture from a station whose measuring-point count is independently known |
|
||||
| Impact | the boundary between measuring points and trailing alarm codes; a misparse shifts every subsequent value |
|
||||
| Status | `OPEN` — hypothesis strengthened but still vendor-document-internal; do not treat `alp` as confirmed |
|
||||
|
||||
**Working hypothesis (not confirmed — do not rely on it):** `alp` is the 1-based position, within the measuring-point sequence, of the first alarm; measuring points number `alp − 1`. An initial implementation may split measuring points from alarms using `Nal` alone (documented unambiguously), cross-check against `alp − 1` diagnostically, and shall not reject telegrams on an `alp` mismatch until this gap is closed.
|
||||
|
||||
---
|
||||
|
||||
## AQ-GAP-003 — WGH: number of values per block and trend-point membership
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Gap ID | AQ-GAP-003 |
|
||||
| Description | Historical trend blocks contain `v1…v32`; "the actual numbers is depending of the type of RTU and version". The count is not signaled in the telegram. Examples: §3.4.12.2 has 7 values per block; §3.7 has 6. On Forth RTUs the station CFG contains a dedicated historical-trend section ("; ##3 / Number of points for Historical trend", with per-point wagon mapping) which presumably governs both membership and count; on Basic RTUs the MAS `htr` flag marks trend participation instead (§3.5.3.2). The document never explicitly states that the decoder must derive the per-block value count from station configuration. |
|
||||
| Affected operation | WGH historical trend data decoding |
|
||||
| Evidence available | §3.4.12.1 block format; examples §3.4.12.2 and §3.7; CFG sections §3.4.12.3 and §3.5.3.2 |
|
||||
| Evidence missing | an explicit statement, or a validated capture from a station whose CFG is known |
|
||||
| Impact | block splitting is ambiguous: values are numeric and cannot be distinguished from the following block's date fields by form alone |
|
||||
| Status | `OPEN` |
|
||||
|
||||
**Working hypothesis (not confirmed):** the expected value count comes from the station's point configuration (CFG historical-trend section); the decoder validates each block's structure against it. Values are wagon-mapped and scaled per point (`Scaled = Raw*(Max−Min)/Max_input + Min`, §3.4.12.3).
|
||||
|
||||
---
|
||||
|
||||
## AQ-GAP-004 — Character encoding of text values
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Gap ID | AQ-GAP-004 |
|
||||
| Description | Telegrams are "an ASCII-string with support of IBM extended codes. E.g. codes 01H to FFH is supported" — the code page for IBM extended codes (e.g. Å/Ä/Ö in Swedish station names) is not defined. Some RTUs support UTF-8 in the MCC data part, capability-dependent (ATF controller-type position 3). The checksum is byte-based and unaffected. |
|
||||
| Affected operation | MCC T-type values (station names, telephone numbers), any text-bearing points |
|
||||
| Evidence available | §2.3.1; §3.4.2.3.3 Note 4 |
|
||||
| Evidence missing | a code-page definition, or a capture containing non-ASCII text |
|
||||
| Impact | garbled text values; incorrect string comparisons |
|
||||
| Status | `OPEN` (low priority until text points are used) |
|
||||
|
||||
---
|
||||
|
||||
## AQ-GAP-005 — Example checksum integrity in the source document
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Gap ID | AQ-GAP-005 |
|
||||
| Description | **35 single-line examples** from the document were recomputed against the §2.4 algorithm and verify exactly (see `test-vectors.md` §1), confirming the algorithm itself, including the Wait-exclusion rule (§3.6.4 pair: both forms sum to 2925). However: (a) the long multi-line examples (WGS answers 7679/3633/6967/6968, WGH answers 6922/6479/4220, WGD answers 4984/5632, MCC 24268/28910, SLT 14331/15425/15061) **cannot be byte-exactly recomputed from the markdown conversion** — blockquote `>` prefixes, `\#` escapes and line-wrap artifacts (e.g. `1\n4 30` splitting a block, `- 16384` splitting a value) survive in the conversion and change byte sums; manual cleanup attempts give near-miss values (e.g. SLT 14331 → 14330/14295 depending on artifact handling), proving the artifacts, not the algorithm, are the problem; (b) example narratives contain destination mismatches (§2.2.3.1 says plant number 89 but the telegram uses dest 86; §3.4.10.2 gives a fixed-line dest as "plant number 901" although fixed-line dest should be the Node ID). |
|
||||
| Affected operation | approved test vectors only — the checksum algorithm is confirmed for all short vectors |
|
||||
| Evidence available | 35 verified recomputations in `test-vectors.md`; authoritative PDF |
|
||||
| Evidence missing | PDF text extraction (or manual transcription) of the long examples free of conversion artifacts |
|
||||
| Impact | the long examples cannot be approved fixtures until transcribed from the PDF; they are the only candidates exercising 16-bit wraparound (sums > 65535), so synthetic vectors cover that branch in the meantime |
|
||||
| Status | `OPEN` |
|
||||
|
||||
---
|
||||
|
||||
## AQ-GAP-006 — MAT fetch request checksum
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Gap ID | AQ-GAP-006 |
|
||||
| Description | The MAT fetch **request** `9 MAT 0 1 # 557` (§3.4.7.2) recomputes to **540**. 557 is exactly the checksum of the structurally identical SLT fetch request `9 SLT 0 1` (§3.4.9.2, verified), indicating a copy-paste error in the source document. The MAT fetch **answer** `7 9001 # 353` verifies exactly (353), so the answer side is sound. |
|
||||
| Affected operation | MAT fetch request vector |
|
||||
| Evidence available | §3.4.7.2 examples; recomputation (request: 540; answer: 353 verified) |
|
||||
| Evidence missing | PDF confirmation of which checksum the printed request should carry |
|
||||
| Impact | minor — use 540 for the request vector once PDF-confirmed; the verified answer vector may be approved independently |
|
||||
| Status | `OPEN` |
|
||||
|
||||
---
|
||||
|
||||
## AQ-GAP-007 — SCE payload semantics
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Gap ID | AQ-GAP-007 |
|
||||
| Description | "A SCE answer for a MCC telegram might contain the channel number the RTU rejected. Example: SCE 48 # 423." Whether and when the payload field is present is unspecified ("might"). |
|
||||
| Affected operation | SCE (error in telegram) handling |
|
||||
| Evidence available | §3.4.2.3 example (checksum verifies) |
|
||||
| Evidence missing | a rule for payload presence |
|
||||
| Impact | low — treat any payload as optional diagnostic data, never as parse-critical |
|
||||
| Status | `OPEN` (low) |
|
||||
|
||||
---
|
||||
|
||||
## AQ-GAP-008 — Caller-ID telegram `ACT` field contents
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Gap ID | AQ-GAP-008 |
|
||||
| Description | §2.2.3.2 defines the dialled-line caller-ID telegram (`STX DEST ACT # CHK CR`) with `ACT` = "Type of message, 3 bytes", but lists no valid `ACT` values. The §2.2.3.3 example transmits the literal string `ACT`, and its checksum (369) is consistent with that literal — suggesting an unexpanded placeholder rather than real traffic. |
|
||||
| Affected operation | dialled-line caller identification |
|
||||
| Evidence available | §2.2.3.2–3 |
|
||||
| Evidence missing | valid `ACT` values, or a capture of a real caller-ID telegram |
|
||||
| Impact | low for fixed-line/TCP-first deployments (feature is dialled-only and capability-dependent) |
|
||||
| Status | `OPEN` (low) |
|
||||
|
||||
---
|
||||
|
||||
## AQ-GAP-009 — WGD segment boundaries configurability
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Gap ID | AQ-GAP-009 |
|
||||
| Description | WGD answer segments are documented as "default 00-06 / 06-09 / 09-16 / 16-00". The word "default" implies configurability, but no mechanism is documented in this document. |
|
||||
| Affected operation | WGD periodical data interpretation |
|
||||
| Evidence available | §3.4.11.1 |
|
||||
| Evidence missing | the configuration mechanism (possibly an AquaView/CFG setting outside this document) |
|
||||
| Impact | low — use the documented defaults; record deviation diagnostically |
|
||||
| Status | `OPEN` (low) |
|
||||
|
||||
---
|
||||
|
||||
## AQ-GAP-010 — Minor source-document inconsistencies in alarm telegrams
|
||||
|
||||
| Field | Content |
|
||||
|---|---|
|
||||
| Gap ID | AQ-GAP-010 |
|
||||
| Description | (a) The WCA field table gives the hour range as 0–24 (§3.4.1) while ALR gives 0–23 (§3.4.1.6); 24 is likely a source typo — validate as 0–23 unless the PDF shows otherwise. (b) The semantics of the WCA date/time fields when `set=0` (poll mode) are not stated; the examples always carry the CS's current time, but the document does not say what the RTU does with it when `set=0`. |
|
||||
| Affected operation | WCA request encoding; alarm polling |
|
||||
| Evidence available | §3.4.1, §2.2.3.3, §3.4.1.2–3 examples |
|
||||
| Evidence missing | PDF confirmation; a statement of `set=0` time semantics |
|
||||
| Impact | low — alarms are extension scope; do not implement clock setting or rely on `set=0` time semantics until resolved |
|
||||
| Status | `OPEN` (low) |
|
||||
|
||||
---
|
||||
|
||||
## Closed gaps
|
||||
|
||||
None yet. When closing an entry: keep the original text, append a **Resolution** note citing the evidence and date, and set the status to `CLOSED`.
|
||||
@@ -0,0 +1,114 @@
|
||||
# AquaCom approved test vectors
|
||||
|
||||
**Fixture source policy:** all vectors below are derived from *Technical description – AquaCom – RTU level*, Rev 1.6, ITT Flygt AB, July 2004 (`AquaCom_RTU_1_6_eng.pdf`) — evidence class **SPECIFICATION** (examples printed in the authoritative document). Vectors marked *(synthetic)* are constructed by the project to exercise edge cases the document's examples do not cover; they are labeled **SYNTHETIC_FROM_SPECIFICATION** and are subordinate to the source examples in authority. Each fixture becomes an automated test on implementation; fixtures are immutable once approved (implementation specification §64).
|
||||
|
||||
**Notation.** `<SOH>`=01H, `<STX>`=02H, `<CR>`=0DH, `_`=space (20H), `!W` = Wait byte (DC3, 13H). Checksums are per §2.4: sum of all bytes after SOH/STX up to (excluding) `#`, excluding Wait bytes, in a 16-bit signed integer; the transmitted value is the absolute value. The separator space between `#` and the checksum, and the trailing space before `CR`, **are included** in the summed range.
|
||||
|
||||
**Checksum convention reminder (verified by the examples below):** the summed range starts *after* SOH/STX — i.e. at the space that follows the start byte — and ends at the space immediately before the checksum digits. `32+83+67+79+32=293` for `SCO` (§2.4) confirms this: leading space 32, `SCO` 83+67+79, trailing space 32.
|
||||
|
||||
---
|
||||
|
||||
## 1. Checksum algorithm vectors
|
||||
|
||||
| ID | Telegram | Documented checksum | Verified | Source |
|
||||
|---|---|---|---|---|
|
||||
| AQ-CK-001 | `<STX> SCO _ # _ 293 <CR>` | 293 | yes | §2.4 |
|
||||
| AQ-CK-002 | `<SOH> 9 BRK _ # _ 376 <CR>` | 376 | yes | §3.4.1.2 |
|
||||
| AQ-CK-003 | `<SOH> 0 ALO _ # _ 364 <CR>` | 364 | yes | §2.2.3.3 |
|
||||
| AQ-CK-004 | `<STX> NDA _ # _ 275 <CR>` | 275 | yes | §3.4.12.2 |
|
||||
| AQ-CK-005 | `<STX> SCO _ # _ 293 <CR>` (RTU→CS OK answer) | 293 | yes | §3.4.2.3 |
|
||||
| AQ-CK-006 | `<STX> SCE 48 _ # _ 423 <CR>` | 423 | yes | §3.4.2.3 |
|
||||
| AQ-CK-007 | `<SOH> 9 WCA 0 3 6 17 13 59 _ # _ 1031 <CR>` | 1031 | yes | §2.2.3.3 |
|
||||
| AQ-CK-008 | `<SOH> 9 WCA 0 3 6 17 14 0 _ # _ 970 <CR>` | 970 | yes | §2.2.3.3 |
|
||||
| AQ-CK-009 | `<STX> ALN T 0 0 0 0 _ # _ 719 <CR>` | 719 | yes | §2.2.3.3 |
|
||||
| AQ-CK-010 | `<STX> OK _ # _ 218 <CR>` | 218 | yes | §2.2.3.1, §3.4.1.2 |
|
||||
| AQ-CK-011 | `<SOH> 5 WCA 0 1 4 27 10 13 _ # _ 1011 <CR>` | 1011 | yes | §3.4.1.3 |
|
||||
| AQ-CK-012 | `<STX> ALR 111 11 1 4 27 10 13 A T 0 0 0 0 B 31 _ # _ 1922 <CR>` | 1922 | yes | §3.4.1.3 |
|
||||
| AQ-CK-013 | `<SOH> 5 ALO _ # _ 369 <CR>` | 369 | yes | §3.4.1.3 |
|
||||
| AQ-CK-014 | `<SOH> 9 MCC 0 1 _ # _ 525 <CR>` | 525 | yes | §3.4.3.2 |
|
||||
| AQ-CK-015 | `<SOH> 9 SLT 0 1 _ # _ 557 <CR>` | 557 | yes | §3.4.9.2 |
|
||||
| AQ-CK-016 | `<SOH> 2 MAS 0 1 _ # _ 532 <CR>` | 532 | yes | §3.4.5.3 |
|
||||
| AQ-CK-017 | `<SOH> 2 MAT 7 7 81 81 82 9003 _ # _ 1194 <CR>` | 1194 | yes | §3.4.6.1 |
|
||||
| AQ-CK-018 | `<SOH> 9 MAT 7 9001 _ # _ 700 <CR>` | 700 | yes | §3.4.6.2 |
|
||||
| AQ-CK-019 | `<SOH> 9 WGD 01 05 02 13 38 01 05 01 _ # _ 1433 <CR>` | 1433 | yes | §3.4.11.3 |
|
||||
| AQ-CK-020 | `<SOH> 5 WGD 01 05 02 13 10 01 05 01 _ # _ 1419 <CR>` | 1419 | yes | §3.4.11.2 |
|
||||
| AQ-CK-021 | `<SOH> 9 WGH 01 04 30 23 30 _ # _ 1039 <CR>` | 1039 | yes | §3.4.12.2 |
|
||||
| AQ-CK-022 | `<SOH> 9 WGH 01 05 01 03 50 _ # _ 1038 <CR>` | 1038 | yes | §3.4.12.2 |
|
||||
| AQ-CK-023 | `<SOH> 9 WGH 01 05 01 08 10 _ # _ 1039 <CR>` | 1039 | yes | §3.4.12.2 |
|
||||
| AQ-CK-024 | `<SOH> 9 WGH 01 05 01 08 20 _ # _ 1040 <CR>` | 1040 | yes | §3.4.12.2 |
|
||||
| AQ-CK-025 | `<SOH> 500 WGH 99 12 31 21 40 _ # _ 1147 <CR>` | 1147 | yes | §3.7 |
|
||||
| AQ-CK-026 | `<STX> 9_ACT_#_369_<CR>` (caller-ID, literal ACT) | 369 | yes | §2.2.3.3 |
|
||||
| AQ-CK-027 | `<STX> ALR 9 12 3 6 17 13 58 P T 0 0 0 0 A 27 _ # _ 1867 <CR>` | 1867 | yes | §2.2.3.3 |
|
||||
| AQ-CK-028 | `<STX> ALR 9 12 1 4 27 10 26 P T 0 0 0 0 A 27 _ # _ 1856 <CR>` | 1856 | yes | §3.4.1.2 |
|
||||
| AQ-CK-029 | `<SOH> 9 WCA 0 1 4 27 10 27 _ # _ 1020 <CR>` | 1020 | yes | §3.4.1.2 |
|
||||
| AQ-CK-030 | `<SOH> 86 WGS P 0 ! 1 _ # _ 785 <CR>` | 785 | yes | §2.2.3.1 — confirms the `0 !` two-field form |
|
||||
| AQ-CK-031 | `<SOH> 901 WGS P 0 ! 11 _ # _ 878 <CR>` | 878 | yes | §3.4.10.2 |
|
||||
| AQ-CK-032 | `<SOH> 9 WGS P 2 F 1 _ # _ 771 <CR>` | 771 | yes | §3.4.10.3 |
|
||||
| AQ-CK-033 | `<STX> 32000 654321 03 11 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 8050 8531 8532 _ # _ 2925 <CR>` | 2925 | yes | §3.6.4 (Wait-free form of the WGS-answer pair) |
|
||||
| AQ-CK-034 | `<STX> 32000 65!W4321 03 11!W 0 0 0 0 0!W 1 2 3 4 5!W 6 7 8 9 1!W0 8050 853!W1 8532 _ # _ 2925 <CR>` | 2925 | yes | §3.6.4 (Wait-laden form; identical checksum — proves Wait exclusion) |
|
||||
| AQ-CK-035 | `<STX> 7 9001 _ # _ 353 <CR>` | 353 | yes | §3.4.7.2 (MAT fetch answer) |
|
||||
|
||||
**Discrepant vector (documented checksum fails recomputation; see `protocol-gaps.md` AQ-GAP-006):**
|
||||
|
||||
| ID | Telegram | Documented | Recomputed | Source | Note |
|
||||
|---|---|---|---|---|---|
|
||||
| AQ-CK-E1 | `<SOH> 9 MAT 0 1 _ # _ 557 <CR>` | 557 | 540 | §3.4.7.2 | fetch **request**; 557 is exactly the SLT fetch checksum (copy-paste error); not approved until PDF-confirmed |
|
||||
|
||||
The long multi-line examples (WGS answers 7679 / 3633 / 6967 / 6968; WGH answers 6922 / 6479 / 4220; WGD answers 4984 / 5632; MCC 24268 / 28910; SLT 14331 / 15425 / 15061) are candidates for wraparound coverage (sums > 65535) but **cannot be recomputed from the markdown conversion** — blockquote markers, `\#` escapes and line-wrap artifacts survive in the conversion and alter byte sums (AQ-GAP-005). They must be transcribed from the authoritative PDF before approval; until then they are **not approved fixtures**, and the synthetic vectors below cover the wraparound branches.
|
||||
|
||||
**Synthetic algorithm-branch vectors (values computed and verified against the §2.4 algorithm):**
|
||||
|
||||
| ID | Constructed telegram | Raw sum | Expected checksum | Why |
|
||||
|---|---|---|---|---|
|
||||
| AQ-CK-S1 | `<STX>` + 200 × `A` + ` _ # _` | 13064 | 13064 | no wraparound — round-trip baseline *(synthetic)* |
|
||||
| AQ-CK-S2 | `<STX>` + 806 × `z` + ` _ # _` | 98396 | 32676 | sum > 65535 (16-bit wraparound **and** the ≥32768 absolute-value branch: 98396 mod 65536 = 32860 → 65536−32860 = 32676) *(synthetic)* |
|
||||
| AQ-CK-S3 | `<STX>` + 550 × `z` + ` _ # _` | 67164 | 1628 | wraparound **without** the absolute-value branch (67164 mod 65536 = 1628 < 32768) — isolates the mod-65536 step *(synthetic)* |
|
||||
| AQ-CK-S4 | `<STX> SCO !W !W _ # _ 293 <CR>` | — | 293 | Wait bytes excluded from the sum *(synthetic; superseded by source vector AQ-CK-033/034, retained as an algorithm-level unit test)* |
|
||||
|
||||
---
|
||||
|
||||
## 2. Framing / session vectors
|
||||
|
||||
| ID | Scenario | Expectation | Source |
|
||||
|---|---|---|---|
|
||||
| AQ-FR-001 | CS dialled, RTU answers 6×OK 2.5 s apart; CS transmits request after first OK detected | conversation proceeds; the OK sequence is aborted by the incoming request | §2.2.3 |
|
||||
| AQ-FR-002 | Answer arrives with Wait bytes embedded mid-token (`…65!!4321…`) | strip `!W` before tokenization; checksum unchanged; parser output equals the Wait-free form | §3.6.4 |
|
||||
| AQ-FR-003 | BRK sent 3×, then hang-up | no answer expected; transport closes cleanly | §3.4.13 |
|
||||
| AQ-FR-004 | Inter-character gap of 1 s inside a telegram | accepted (RTU-side limit is exactly 1 s; the gateway as CS uses 4–20 s whole-telegram timeout — §2.5) | §2.5 |
|
||||
| AQ-FR-005 | Telegram data length > 4000 chars | rejected by framer; diagnostic generated (protocol max) | §2.3.2 |
|
||||
|
||||
## 3. Live data vectors (WGS)
|
||||
|
||||
| ID | Scenario | Expected decode | Source |
|
||||
|---|---|---|---|
|
||||
| AQ-WGS-001 | Fixed, request `901 WGS P 0 ! 11` → answer `23400 13885 01 22 0 0 0 0 0 3 0 3 3 4800 … 7 8111` | `ver=23400`, `prod=13885`, `Nal=1`, `alp=22`, `rem=0`, 21 measuring points (alp−1, hypothesis — AQ-GAP-002), then 1 alarm code (8111). Decode via `Nal`; cross-check `alp−1` diagnostically only | §3.4.10.2 (checksum not yet approvable — AQ-GAP-005 long example) |
|
||||
| AQ-WGS-002 | Request with control command then BRK | command suppressed by gateway (control OUT-OF-SCOPE); BRK still required after command-bearing WGS per §3.4.13 | §3.4.10, §3.4.13 |
|
||||
| AQ-WGS-003 | Request with `dir`=`!` (ignore) | no command dispatched; normal status answer | §3.4.10 |
|
||||
|
||||
## 4. Historical vectors (WGH)
|
||||
|
||||
| ID | Scenario | Expected decode | Source |
|
||||
|---|---|---|---|
|
||||
| AQ-WGH-001 | Request `9 WGH 01 04 30 23 30` → first answer of §3.4.12.2 (36 blocks, checksum 6922) | 36 blocks; first `1 4 30 23 35`, last `1 5 1 3 50`; 7 values per block; `!` separators; **requires AQ-GAP-003 hypothesis wiring** | §3.4.12.2 |
|
||||
| AQ-WGH-002 | Continuation: request with last received block timestamp `9 WGH 01 05 01 03 50` → next answer | stream resumes at `1 5 1 3 55`; proves the watermark-resume protocol | §3.4.12.2 |
|
||||
| AQ-WGH-003 | Final continuation `9 WGH 01 05 01 08 20` → `NDA` | `NDA` = normal end-of-stream, not an error; synchronization interval complete | §3.4.12.2 |
|
||||
| AQ-WGH-004 | Day rollover: block `1 4 30 0 0` follows block `1 4 30 23 55` | the `00:00` block belongs to the *next* day (comment: "the last block for a day is the one with time stamp 00:00") — **no date-field jump; the date increments**; single-digit year/month/day accepted (1–2 byte fields) | §3.4.12.2 |
|
||||
| AQ-WGH-005 | Answer with embedded Wait bytes (§3.7 form) | parse identical to Wait-free form; checksum identical (§3.6.4 pair) | §3.7, §3.6.4 |
|
||||
| AQ-WGH-006 | Request whose span exceeds 6 hours or 4000 chars | RTU truncates per §3.4.12.1 limits; gateway detects truncated stream by receiving fewer blocks than the requested interval and re-requests from the last block timestamp (at-least-once; dedup by §13/§23 rules) | §3.4.12.1 *(synthetic scenario, specification-derived limit)* |
|
||||
| AQ-WGH-007 | Scaling: CFG point `Max=0.01, Min=0, Max_input=10`, raw 64786 | `Scaled = Raw×(Max−Min)/Max_input + Min` → 64.786 — every vector decode must apply wagon scaling per station CFG, not raw values | §3.4.12.3 *(synthetic combination of documented formula + example raw value)* |
|
||||
|
||||
## 5. Report vectors (WGD)
|
||||
|
||||
| ID | Scenario | Expected decode | Source |
|
||||
|---|---|---|---|
|
||||
| AQ-WGD-001 | Request `5 WGD 01 05 02 13 10 01 05 01` → answer `0 0 0 501 501 0 0 0 1506 1506 …` | per point: seg1..seg4 + sum; 10 reporting points per §3.4.11.4 CFG; scaling formula per point | §3.4.11.2, §3.4.11.4 |
|
||||
| AQ-WGD-002 | Empty report day → all-zero answer (§3.4.11.3) | 64 zero values decoded as valid (not NDA); zero is a legitimate report value | §3.4.11.3 |
|
||||
| AQ-WGD-003 | `NDA` answer | report data for that day does not exist; mark interval missing, do not treat as failure | §3.4.11 |
|
||||
|
||||
## 6. Simulator scenario requirements (traceability targets)
|
||||
|
||||
The simulator (implementation specification §49) shall be able to replay every vector above plus inject: bad checksum (failing AQ-CK verification), truncated telegram (no `#`/`CR`), over-long telegram, inter-character stall of 1.5 s (RTU-side timeout breach), mid-telegram Wait flooding, duplicate WGH blocks across two answers (dedup regression per `ARCHITECTURE.md` §23), conflicting block re-transmission (REJECT_CONFLICT path per §13), and station clock set to a future date (timestamp-validation diagnostics per `software-specification.md` §26). The simulator must not share parsing code with the production decoder (§49).
|
||||
|
||||
---
|
||||
|
||||
**Approval state:** section 1 verified rows (AQ-CK-001–035) and section 2 approved as fixtures; AQ-CK-E1 pending AQ-GAP-006 (PDF confirmation); long examples pending AQ-GAP-005 (PDF transcription); sections 3–4 blocked by AQ-GAP-002/003 for full decode assertions (framing-level assertions may proceed; `Nal`-based decoding is documented and unblocked). Synthetic vectors subordinate to source vectors. Update this file's approval state when gaps close — never delete vectors.
|
||||
Reference in New Issue
Block a user