Files
aquacom-gateway-suite/docs/protocol/test-vectors.md
T
2026-10-06 07:08:03 +02:00

12 KiB
Raw Blame History

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.