Wire ApplyScaling, StorageRate; close out write-commands plan
ApplyScaling (HistorianTagDefinition.ApplyScaling): The EnsT2 trailer's second byte controls server-side scaling — `FE 00` mirrors MinRaw to MinEU and sets AnalogTag.Scaling=0; `FE 01` persists distinct MinRaw/MaxRaw and sets Scaling=1. Decoded by toggling set_ApplyScaling on the native harness and capturing the wire bytes for both values with identical inputs. The earlier docs claimed EnsureTagAsync needed a follow-up "UpdateTags" call; the WCF surface has no such operation — toggling that one byte is the whole fix. StorageRate (HistorianTagDefinition.StorageRateMs): Serializer accepts a non-default rate, validated empirically against the live server which only accepts quantized values (1000/5000/10000/60000/300000 ms). EnsureTagAsync upsert semantics: Second call on the same tag name with different fields succeeds and updates Description, MinEU, MaxEU, MinRaw, MaxRaw, Scaling in place (verified by direct SQL inspection in a live test). Plan + doc closeout: write-commands-reverse-engineering.md rewritten as a current-state plan with three workstreams (A doc closeout / B idempotency / C1 StorageRate) and a parallelism table; prior phase notes preserved as appendix. handoff.md, implementation-status.md, wcf-contract-evidence.md, README.md updated to remove "writes are out of scope" / non-existent UpdateTags references and document the actual EnsT2 wire format including the `FE xx` trailer. Reverse-engineering harness gains --write-apply-scaling and a SQL post-check that prints the persisted AnalogTag bounds so future RE sessions can verify wire→DB causality without leaving the harness. 169/169 tests pass (was 165; +4 new tests covering ApplyScaling, StorageRate golden bytes, StorageRate live persistence, and EnsureTagAsync upsert semantics). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,13 +3,23 @@
|
||||
## Completed
|
||||
|
||||
- Production SDK targets `net10.0` and has no AVEVA binary references.
|
||||
- Public API now includes the intended parity surface:
|
||||
- Public API includes the full intended parity surface:
|
||||
- TCP probe
|
||||
- raw, aggregate, at-time, and block history reads
|
||||
- event reads
|
||||
- tag browse and metadata calls
|
||||
- connection, store-forward, and system-parameter status calls
|
||||
- write-back intentionally remains out of scope for this read-only SDK pass
|
||||
- **`EnsureTagAsync`** for analog Float/Double/Int2/Int4/UInt4 with
|
||||
optional `ApplyScaling=true` for distinct MinRaw/MaxRaw persistence
|
||||
(live-verified end-to-end against `localhost`; SQL post-check confirms
|
||||
`AnalogTag.Scaling=1` and distinct raw bounds when the flag is set)
|
||||
- **`DeleteTagAsync`** (live-verified)
|
||||
- **AddS2 (write samples) is architecturally blocked** — server runtime
|
||||
cache only ingests from configured IOServers / Application Server
|
||||
pipelines, not from `HistorianAccess.AddTag`-only flows. Three
|
||||
independent reproduction attempts confirmed the same
|
||||
`129 "Tag not found in cache"` failure even with the real wwTagKey,
|
||||
fresh sessions, and 8s settle waits. Not a protocol gap.
|
||||
- Internal protocol scaffolding exists:
|
||||
- `HistorianConnection`
|
||||
- `HistorianFrameReader`
|
||||
|
||||
Reference in New Issue
Block a user