# \# AquaCom Integration Gateway – Architecture # # \## 1. Purpose # # This document defines the high-level software architecture of the \*\*AquaCom Integration Gateway\*\*. # # It describes: # # \- major system components; # \- dependency direction; # \- data flows; # \- architectural boundaries; # \- live-data handling; # \- historical-data handling; # \- OPC UA integration; # \- storage integration; # \- diagnostics; # \- security boundaries; # \- extension points. # # Detailed functional requirements are defined in: # # ```text # docs/product/software-specification.md # ``` # # Implementation requirements and Codex-specific development rules are defined in: # # ```text # docs/product/codex-implementation-specification.md # AGENTS.md # ``` # # Detailed subsystem architecture is documented under: # # ```text # docs/architecture/ # ``` # # AquaCom-specific protocol knowledge is documented under: # # ```text # docs/protocol/ # ``` # # \--- # # \# 2. System purpose # # The AquaCom Integration Gateway provides a modern integration boundary between AquaCom-compatible field equipment and higher-level systems. # # The gateway shall: # # \- communicate with AquaCom field devices; # \- acquire current process values; # \- retrieve historical process values; # \- normalize AquaCom-specific information into a protocol-independent model; # \- expose current values using OPC UA; # \- expose historical values using OPC UA Historical Access; # \- store historical data in one or more configurable destinations; # \- recover historical information following communication interruptions; # \- provide operational and protocol diagnostics. # # The gateway shall not make higher-level systems dependent on AquaCom-specific behavior. # # \--- # # \# 3. Architectural principle # # The central architecture is: # # ```text # AquaCom field device # │ # ▼ # AquaCom Transport # │ # ▼ # AquaCom Protocol Engine # │ # ▼ # Station / Session Manager # │ # ▼ # Canonical Data Model # │ # ├─────────────────────► Current-State Service # │ │ # │ ▼ # │ OPC UA Data Access # │ # └─────────────────────► Historical Pipeline # │ # ┌───────────┼────────────┐ # │ │ │ # ▼ ▼ ▼ # Repository Storage A Storage B # │ # ▼ # OPC UA Historical Access # ``` # # The canonical data model forms the boundary between AquaCom-specific functionality and all northbound integrations. # # \--- # # \# 4. Architectural goals # # The architecture shall support: # # \- protocol isolation; # \- storage independence; # \- stable internal identifiers; # \- stable OPC UA NodeIds; # \- correct handling of source timestamps; # \- reliable history recovery; # \- multiple historical storage destinations; # \- store-and-forward; # \- independent subsystem testing; # \- restart recovery; # \- future replacement of individual technologies; # \- future addition of other northbound interfaces. # # The architecture shall avoid tight coupling between: # # ```text # AquaCom # OPC UA # Database technology # Historian technology # SCADA platform # ``` # # \--- # # \# 5. Architectural boundaries # # The following boundaries are mandatory. # # \## 5.1 AquaCom boundary # # Only the AquaCom subsystem may: # # \- encode AquaCom telegrams; # \- decode AquaCom telegrams; # \- calculate or verify AquaCom checksums; # \- interpret AquaCom operation codes; # \- interpret AquaCom addressing; # \- interpret AquaCom-specific value formats. # # No OPC UA or storage module shall perform AquaCom protocol processing. # # \--- # # \## 5.2 Canonical model boundary # # AquaCom data shall be converted into canonical gateway objects before being forwarded to: # # \- current-state handling; # \- history handling; # \- OPC UA; # \- storage systems; # \- diagnostics where appropriate. # # The canonical model shall remain independent of AquaCom and OPC UA. # # \--- # # \## 5.3 OPC UA boundary # # The OPC UA subsystem shall consume canonical gateway information. # # It shall not: # # \- communicate directly with AquaCom stations; # \- decode telegrams; # \- synchronously request historical data from an RTU; # \- depend upon a particular storage technology. # # \--- # # \## 5.4 Storage boundary # # Storage destinations shall receive canonical historical records. # # Storage implementations shall not depend upon: # # \- AquaCom telegrams; # \- AquaCom transport; # \- OPC UA server internals. # # \--- # # \# 6. Source tree # # The logical source structure is: # # ```text # src/ # ├── core/ # ├── aquacom/ # ├── history/ # ├── storage/ # ├── opcua/ # ├── diagnostics/ # └── host/ # ``` # # The exact language-specific package or project structure may differ, but the architectural responsibilities shall remain equivalent. # # \--- # # \# 7. Dependency direction # # Allowed dependencies shall broadly follow: # # ```text # host # │ # ┌───────────┼─────────────┐ # │ │ │ # ▼ ▼ ▼ # opcua history diagnostics # │ │ # │ storage # │ │ # └──────┬────┘ # ▼ # core # ▲ # │ # aquacom # ``` # # The most important rule is: # # ```text # core # ``` # # shall not depend upon: # # ```text # aquacom # opcua # storage technology # ``` # # \--- # # \# 8. Core subsystem # # The `core` subsystem contains protocol-independent domain concepts. # # Examples include: # # ```text # StationId # PointId # CurrentValue # HistoricalSample # DataQuality # AcquisitionSource # CommunicationState # StationState # HistorySynchronizationState # ``` # # The core subsystem defines shared contracts used between other modules. # # It shall contain no AquaCom protocol logic. # # It shall contain no OPC UA-specific types. # # It shall contain no database-specific types. # # \--- # # \# 9. AquaCom subsystem # # The AquaCom subsystem contains: # # ```text # Transport # Protocol codec # Telegram validation # Station/session handling # Live acquisition # Historical acquisition # Protocol diagnostics # ``` # # Logical structure: # # ```text # AquaCom Transport # │ # ▼ # Protocol Codec # │ # ▼ # Protocol Operations # │ # ▼ # Station Session # │ # ├── Live Acquisition # └── Historical Acquisition # ``` # # Protocol implementation shall be evidence-based. # # Undocumented AquaCom behavior shall not be guessed. # # \--- # # \# 10. AquaCom transport # # The transport layer is responsible for communication only. # # It may support implementations such as: # # ```text # TCP # Serial # Serial-over-IP # Other supported AquaCom transport # ``` # # The transport layer shall not interpret process values. # # Conceptual interface: # # ```text # open # close # send # receive # health # ``` # # \--- # # \# 11. AquaCom protocol engine # # The protocol engine is responsible for: # # \- framing; # \- telegram validation; # \- checksum handling; # \- request encoding; # \- response decoding; # \- protocol error interpretation. # # Conceptual transformation: # # ```text # raw bytes # │ # ▼ # AquaCom message # │ # ▼ # logical protocol result # ``` # # The codec shall be independently testable without a physical AquaCom device. # # \--- # # \# 12. Station/session manager # # Each AquaCom station has an independent logical session. # # Conceptual station states: # # ```text # DISABLED # INITIALIZING # CONNECTING # ONLINE # DEGRADED # OFFLINE # RECOVERING # ``` # # One failing station shall not stop communication with unrelated stations. # # The Station Manager owns: # # \- station lifecycle; # \- communication status; # \- retries; # \- scheduling; # \- station diagnostics; # \- history recovery coordination. # # \--- # # \# 13. Canonical data model # # The gateway uses a protocol-independent canonical model. # # \## 13.1 CurrentValue # # Conceptually: # # ```text # CurrentValue # StationId # PointId # Value # DataType # Quality # SourceTimestamp # ReceivedTimestamp # UpdatedTimestamp # AcquisitionSource # ``` # # \--- # # \## 13.2 HistoricalSample # # Conceptually: # # ```text # HistoricalSample # StationId # PointId # Value # DataType # Quality # SourceTimestamp # ReceivedTimestamp # AcquisitionSource # AcquisitionId # ``` # # Historical samples shall retain the timestamp associated with the process state. # # \--- # # \# 14. Timestamp model # # The gateway shall distinguish at least: # # ```text # SourceTimestamp # ReceivedTimestamp # ``` # # Where applicable also: # # ```text # UpdatedTimestamp # ServerTimestamp # ``` # # Their meanings are: # # | Timestamp | Meaning | # |---|---| # | SourceTimestamp | Time associated with the value at the source | # | ReceivedTimestamp | Time the gateway received the information | # | UpdatedTimestamp | Time current gateway state was changed | # | ServerTimestamp | Timestamp used by the OPC UA server | # # The following must never be assumed: # # ```text # ReceivedTimestamp = SourceTimestamp # ``` # # \--- # # \# 15. Fundamental historical rule # # The fundamental historical-data rule is: # # > A historical sample represents the process at its SourceTimestamp, not at the time the gateway receives the sample. # # Example: # # ```text # Historical value: # SourceTimestamp = 14:05 # ReceivedTimestamp = 18:30 # ``` # # The value belongs to history at: # # ```text # 14:05 # ``` # # It shall not become a new current process value at: # # ```text # 18:30 # ``` # # \--- # # \# 16. Live-data architecture # # Live AquaCom values follow: # # ```text # AquaCom response # │ # ▼ # Protocol decode # │ # ▼ # Point mapping # │ # ▼ # Canonical CurrentValue # │ # ▼ # Current-State Service # │ # ├────────► OPC UA # │ # └────────► Historical pipeline # if live historization is enabled # ``` # # The Current-State Service maintains the latest accepted value for each configured point. # # \--- # # \# 17. Current-State Service # # Responsibilities: # # \- maintain the latest current value; # \- reject obsolete current-state updates where applicable; # \- expose current values to OPC UA; # \- notify subscribers of valid changes; # \- preserve quality and timestamps. # # Conceptual interface: # # ```text # update(CurrentValue) # # get(PointId) # # getAll(StationId) # # subscribe(PointId) # ``` # # Historical backfill shall not directly call `update(CurrentValue)`. # # \--- # # \# 18. Historical-data architecture # # Historical AquaCom data follows: # # ```text # AquaCom history # │ # ▼ # Historical Acquisition Manager # │ # ▼ # Canonical HistoricalSample # │ # ▼ # Historical Pipeline # │ # ├────────► History Repository # ├────────► Storage Sink A # ├────────► Storage Sink B # └────────► Other configured destinations # ``` # # The historical pipeline is independent from OPC UA. # # \--- # # \# 19. Historical Acquisition Manager # # The Historical Acquisition Manager is responsible for: # # \- determining missing intervals; # \- requesting AquaCom history; # \- processing historical responses; # \- maintaining synchronization state; # \- managing watermarks; # \- performing reconnect/backfill; # \- throttling history retrieval; # \- avoiding interference with live polling. # # Live acquisition shall normally have higher communication priority than bulk history recovery. # # \--- # # \# 20. Historical synchronization # # Each station may maintain persistent synchronization state. # # Conceptually: # # ```text # StationId # HistoryStreamId # LastCompleteTimestamp # LastAttemptTimestamp # LastSuccessfulTimestamp # SynchronizationState # ``` # # Example: # # ```text # 12:00 history synchronized # # 12:03 communication lost # # 17:24 communication restored # # 12:00 → 17:24 # identified as recovery interval # ``` # # The gateway then retrieves available AquaCom history for that interval. # # \--- # # \# 21. Watermark rule # # A history synchronization watermark shall only advance after the corresponding interval has been successfully handled according to the configured persistence policy. # # The following is prohibited: # # ```text # receive historical packet # │ # ▼ # advance watermark # │ # ▼ # storage fails # ``` # # Preferred behavior is: # # ```text # receive # ↓ # validate # ↓ # persist/durably queue # ↓ # advance synchronization state # ``` # # \--- # # \# 22. Historical pipeline # # The historical pipeline shall conceptually perform: # # ```text # HistoricalSample # │ # ▼ # Validation # │ # ▼ # Normalization # │ # ▼ # Deduplication # │ # ▼ # Durable Spool # │ # ▼ # Distribution # ``` # # This pipeline provides a stable boundary between acquisition and storage. # # \--- # # \# 23. Deduplication # # The default historical logical identity is: # # ```text # StationId # \+ # PointId # \+ # SourceTimestamp # ``` # # A stronger AquaCom-provided identifier may be used where verified. # # Identical samples shall not create unintended duplicate history. # # Conflicting samples sharing the same logical identity shall generate diagnostics. # # The default conflict strategy should favor explicit conflict detection rather than silent overwrite. # # \--- # # \# 24. Durable spool # # The historical spool provides restart-safe delivery. # # Conceptually: # # ```text # HistoricalSample # │ # ▼ # Persistent spool # │ # ├────► Repository # ├────► Sink A # └────► Sink B # ``` # # Each destination maintains independent acknowledgement. # # Example: # # ```text # Record 4711 # # Repository ACK # CentralHistorian ACK # Archive PENDING # ``` # # The record remains until configured delivery requirements have been fulfilled. # # \--- # # \# 25. History Repository # # A History Repository is a queryable historical source. # # It provides operations conceptually equivalent to: # # ```text # store # storeBatch # readRaw # readAtTime # getBounds # health # ``` # # The repository used by OPC UA Historical Access is selected by configuration. # # The OPC UA implementation shall not know whether the repository is: # # ```text # relational database # time-series database # embedded historian # industrial historian # other queryable implementation # ``` # # \--- # # \# 26. Storage Sink # # A Storage Sink is a destination receiving historical records. # # Conceptual interface: # # ```text # initialize # write # writeBatch # flush # health # shutdown # ``` # # A sink does not need to support historical queries. # # Examples: # # ```text # SQL database # time-series database # enterprise historian # file archive # message broker # data lake connector # ``` # # \--- # # \# 27. Repository versus sink # # These shall remain separate concepts: # # ```text # Repository # = query historical data # # Sink # = receive historical data # ``` # # One implementation may support both. # # Example: # # ```text # Local historian # Repository: yes # Sink: yes # # Archive export # Repository: no # Sink: yes # ``` # # \--- # # \# 28. Multiple storage destinations # # A historical record may be delivered to multiple independent destinations. # # Example: # # ```text # Historical Pipeline # │ # ┌───────────────┼────────────────┐ # │ │ │ # ▼ ▼ ▼ # Local Repository Central DB Archive # ``` # # Failure of one destination shall not unnecessarily block successful destinations. # # \--- # # \# 29. OPC UA architecture # # The OPC UA subsystem provides northbound access to normalized gateway information. # # Logical components: # # ```text # OPC UA Server # │ # ├── Namespace Manager # ├── Current Value Provider # ├── Historical Provider # ├── Quality Mapper # ├── Diagnostics Provider # └── Security # ``` # # \--- # # \# 30. OPC UA current data # # Current values are exposed through normal OPC UA Data Access. # # Mapping: # # ```text # CurrentValue.Value # ↓ # OPC UA Value # # CurrentValue.SourceTimestamp # ↓ # OPC UA SourceTimestamp # # Gateway server time # ↓ # OPC UA ServerTimestamp # # CurrentValue.Quality # ↓ # OPC UA StatusCode # ``` # # \--- # # \# 31. OPC UA Historical Access # # Historical Access shall query the configured History Repository. # # Correct flow: # # ```text # OPC UA Client # │ # │ HistoryRead # ▼ # OPC UA Server # │ # ▼ # Historical Provider # │ # ▼ # History Repository # │ # ▼ # HistoricalSample\[] # │ # ▼ # OPC UA DataValue\[] # ``` # # \--- # # \# 32. Prohibited HistoryRead architecture # # The following architecture is prohibited: # # ```text # OPC UA HistoryRead # │ # ▼ # AquaCom request # │ # ▼ # wait for RTU # │ # ▼ # OPC UA response # ``` # # Historical synchronization and historical client access must be decoupled. # # \--- # # \# 33. OPC UA namespace # # The default logical namespace shall resemble: # # ```text # AquaCom # │ # ├── Gateway # │ ├── Status # │ ├── Version # │ ├── StartTime # │ ├── ConfigurationVersion # │ ├── HistoricalQueueDepth # │ └── Storage # │ # └── Stations # │ # ├── PS001 # │ ├── Process # │ │ ├── Level # │ │ ├── Pump01Running # │ │ └── Pump02Running # │ │ # │ └── Diagnostics # │ ├── CommunicationState # │ ├── LastCommunication # │ ├── HistoryState # │ └── HistoryWatermark # │ # └── PS002 # ``` # # Exact organization may be configurable. # # \--- # # \# 34. Stable OPC UA NodeIds # # OPC UA NodeIds shall derive from stable engineering identifiers. # # Example: # # ```text # station/PS001/point/LEVEL # ``` # # Changing: # # ```text # Wet well level # ``` # # to: # # ```text # Inlet sump level # ``` # # shall not normally change the NodeId. # # Stable NodeIds are required to preserve client configuration. # # \--- # # \# 35. Diagnostics architecture # # Diagnostics are separate from process data. # # Conceptually: # # ```text # Diagnostics # │ # ├── Gateway # │ # ├── Station # │ # ├── AquaCom Protocol # │ # ├── History # │ # ├── Storage # └── OPC UA # ``` # # Diagnostics may be exposed through: # # \- logs; # \- metrics; # \- OPC UA diagnostic nodes; # \- future management interfaces. # # \--- # # \# 36. Gateway diagnostics # # Examples: # # ```text # GatewayState # Version # ConfigurationVersion # StartTime # Uptime # StationCount # OnlineStationCount # HistoricalQueueDepth # SpoolDiskUsage # OPCUAState # ``` # # \--- # # \# 37. Station diagnostics # # Examples: # # ```text # CommunicationState # LastRequest # LastResponse # LastSuccessfulCommunication # ConsecutiveFailures # ProtocolErrors # HistorySynchronizationState # HistoryWatermark # HistoricalBacklog # ``` # # \--- # # \# 38. Storage diagnostics # # Per destination: # # ```text # State # LastSuccessfulWrite # LastFailure # PendingRecords # RetryCount # Latency # ``` # # A storage failure shall be identifiable independently from an AquaCom communication failure. # # \--- # # \# 39. Logging # # Structured logging is preferred. # # Useful context includes: # # ```text # timestamp # severity # component # stationId # pointId # operation # correlationId # message # error # ``` # # Raw AquaCom telegram logging shall be separately configurable. # # \--- # # \# 40. Configuration architecture # # Configuration shall be external and machine-readable. # # Conceptual structure: # # ```text # Gateway Configuration # │ # ├── Gateway # ├── AquaCom # ├── Stations # ├── Points # ├── History # ├── Storage # ├── OPC UA # ├── Security # ├── Diagnostics # └── Logging # ``` # # Configuration validation occurs before activation. # # \--- # # \# 41. Station configuration # # A station definition contains concepts equivalent to: # # ```text # StationId # Enabled # Transport # AquaComAddress # ProtocolProfile # LiveAcquisition # HistoricalAcquisition # PointDefinitionSource # Timezone # ``` # # Station configuration shall not be embedded directly in protocol source code. # # \--- # # \# 42. Point configuration # # A point contains concepts equivalent to: # # ```text # PointId # DisplayName # Description # SourceReference # DataType # EngineeringUnit # Scaling # LiveEnabled # HistoryEnabled # OPCUAEnabled # Historizing # StoragePolicy # ``` # # `PointId` shall remain stable even if presentation metadata changes. # # \--- # # \# 43. Security boundaries # # The architecture assumes AquaCom is a legacy field protocol. # # Security shall therefore be applied around the AquaCom communication environment. # # Conceptually: # # ```text # SCADA / client network # │ # ▼ # Firewall / segmentation # │ # ▼ # AquaCom Gateway # │ # ▼ # OT communication network # │ # ▼ # Site firewall/router/VPN # │ # ▼ # AquaCom RTU # ``` # # The gateway shall not assume that AquaCom itself provides modern confidentiality, authentication or authorization. # # \--- # # \# 44. OPC UA security # # OPC UA security is handled within the OPC UA subsystem. # # Production architecture shall support: # # ```text # application certificates # trusted client management # secure channels # authentication # authorization # encrypted communication # ``` # # Insecure endpoints shall not be the normal production default. # # \--- # # \# 45. Secrets boundary # # Secrets shall not form part of normal version-controlled configuration. # # Examples: # # ```text # database passwords # API tokens # private keys # certificate private keys # ``` # # These shall be injected through an external secret mechanism. # # \--- # # \# 46. Host subsystem # # The `host` subsystem composes the application. # # Responsibilities include: # # \- configuration loading; # \- dependency construction; # \- subsystem startup; # \- lifecycle management; # \- shutdown; # \- top-level health state. # # The host shall not become a location for protocol or business logic. # # \--- # # \# 47. Startup architecture # # Conceptual startup sequence: # # ```text # Load configuration # │ # ▼ # Validate configuration # │ # ▼ # Load persistent state # │ # ▼ # Initialize storage # │ # ▼ # Initialize historical services # │ # ▼ # Initialize OPC UA # │ # ▼ # Initialize AquaCom stations # │ # ▼ # Start live acquisition # │ # ▼ # Start historical synchronization # ``` # # A temporary failure of a non-critical secondary storage destination should not necessarily prevent the gateway from starting. # # \--- # # \# 48. Shutdown architecture # # Conceptual controlled shutdown: # # ```text # Stop accepting administrative changes # │ # ▼ # Stop scheduling new acquisition # │ # ▼ # Complete/cancel active transactions safely # │ # ▼ # Persist synchronization state # │ # ▼ # Flush durable state # │ # ▼ # Stop OPC UA # │ # ▼ # Close storage # │ # ▼ # Terminate # ``` # # \--- # # \# 49. Restart recovery # # After an unclean restart: # # ```text # Load configuration # │ # ▼ # Recover persistent spool # │ # ▼ # Restore synchronization watermarks # │ # ▼ # Reconnect AquaCom stations # │ # ▼ # Resume live acquisition # │ # ▼ # Resume historical recovery # ``` # # Live acquisition should resume before large backlog processing. # # \--- # # \# 50. Scheduling priorities # # Where AquaCom communication capacity is limited, scheduling shall conceptually prioritize: # # ```text # 1\. communication/session health # 2\. current/live acquisition # 3\. alarms/events when implemented # 4\. explicit configuration operations # 5\. historical backfill # 6\. low-priority maintenance # ``` # # Historical synchronization shall be throttleable. # # \--- # # \# 51. Resource boundaries # # All queues and caches shall be bounded. # # This applies to: # # ```text # AquaCom request queues # history queues # storage retry queues # OPC UA historical result sets # continuation state # logging buffers # spool storage # ``` # # Overflow behavior shall be explicit and observable. # # \--- # # \# 52. Testing architecture # # The system shall support independent testing of each architectural boundary. # # Conceptually: # # ```text # Protocol Fixtures # │ # ▼ # AquaCom Codec Tests # # Simulator # │ # ▼ # Session / Acquisition Tests # # Historical Fixtures # │ # ▼ # History Pipeline Tests # # Repository # │ # ▼ # OPC UA HA Tests # # Current-State Service # │ # ▼ # OPC UA DA Tests # ``` # # \--- # # \# 53. AquaCom simulator # # The simulator shall permit development without operational AquaCom equipment. # # Supported scenarios shall eventually include: # # ```text # normal live values # normal history # timeouts # disconnects # delayed response # malformed telegram # bad checksum # duplicate history # conflicting history # clock error # reconnect # backfill # ``` # # The simulator is part of the architecture, not merely a temporary development tool. # # \--- # # \# 54. Protocol evidence architecture # # AquaCom implementation is linked to documented evidence. # # Relevant repository area: # # ```text # docs/protocol/ # ``` # # Recommended structure: # # ```text # aquacom.md # known-operations.md # protocol-gaps.md # test-vectors.md # ``` # # Every implemented AquaCom behavior should be traceable to: # # ```text # Specification # Capture # Known-good implementation # Approved test vector # ``` # # Unknown behavior remains explicitly unresolved. # # \--- # # \# 55. Error isolation # # Failures shall remain contained where possible. # # Examples: # # | Failure | Expected isolation | # |---|---| # | Station A offline | Station B continues | # | Storage A offline | Storage B continues | # | OPC UA client disconnect | Acquisition continues | # | OPC UA server problem | AquaCom acquisition should continue where possible | # | Historical backfill fails | Live acquisition continues | # | Malformed AquaCom telegram | Telegram rejected, station diagnostics updated | # | Secondary storage failure | Durable spool retains pending delivery | # # \--- # # \# 56. Future extension points # # The architecture shall permit future addition of: # # ```text # OPC UA Alarms \& Conditions # AquaCom alarms/events # AquaCom commands # setpoint changes # MQTT # REST API # external analytics # central configuration # redundant gateways # high availability # additional history repositories # additional storage sinks # ``` # # These shall be added behind explicit subsystem interfaces. # # \--- # # \# 57. Future process-control architecture # # If control functionality is introduced later, it shall use a separate command pipeline: # # ```text # Northbound request # │ # ▼ # Authentication # │ # ▼ # Authorization # │ # ▼ # Command validation # │ # ▼ # Command service # │ # ▼ # AquaCom command # │ # ▼ # Confirmation / readback # │ # ▼ # Audit # ``` # # A direct mapping from arbitrary OPC UA writes to raw AquaCom telegrams is not an acceptable control architecture. # # \--- # # \# 58. Architectural invariants # # The following invariants shall hold throughout implementation. # # \## INV-001 # # AquaCom-specific logic exists only behind the AquaCom abstraction. # # \## INV-002 # # The canonical model contains no AquaCom telegram representation. # # \## INV-003 # # The canonical model contains no OPC UA-specific representation. # # \## INV-004 # # Historical samples do not update current state solely because they were recently retrieved. # # \## INV-005 # # Historical SourceTimestamp is preserved. # # \## INV-006 # # OPC UA HistoryRead queries a repository, not an AquaCom device. # # \## INV-007 # # A storage failure does not directly stop unrelated live AquaCom acquisition. # # \## INV-008 # # Point identity remains stable across display-name changes. # # \## INV-009 # # OPC UA NodeIds remain stable across restart and normal upgrades. # # \## INV-010 # # Unverified AquaCom protocol details are not implemented as guesses. # # \## INV-011 # # Synchronization state required for recovery is persistent. # # \## INV-012 # # Historical delivery supports bounded persistent buffering. # # \--- # # \# 59. Primary end-to-end data flows # # \## 59.1 Live data # # ```text # AquaCom RTU # │ # ▼ # Transport # │ # ▼ # Protocol Engine # │ # ▼ # Station Manager # │ # ▼ # CurrentValue # │ # ▼ # Current-State Service # │ # ├────► OPC UA # │ # └────► Historical Pipeline # when live historization is enabled # ``` # # \--- # # \## 59.2 AquaCom historical recovery # # ```text # AquaCom RTU # │ # ▼ # Historical Acquisition # │ # ▼ # HistoricalSample # │ # ▼ # Validation # │ # ▼ # Deduplication # │ # ▼ # Durable Spool # │ # ├────► Repository # ├────► Storage A # └────► Storage B # ``` # # \--- # # \## 59.3 OPC UA historical request # # ```text # OPC UA Client # │ # ▼ # HistoryRead # │ # ▼ # OPC UA Historical Provider # │ # ▼ # History Repository # │ # ▼ # HistoricalSample\[] # │ # ▼ # OPC UA DataValue\[] # ``` # # \--- # # \# 60. Reference architecture # # The complete reference architecture is: # # ```text # FIELD / AQUACOM # │ # ▼ # ┌─────────────────────┐ # │ AquaCom Transport │ # └──────────┬──────────┘ # │ # ▼ # ┌─────────────────────┐ # │ Protocol Engine │ # └──────────┬──────────┘ # │ # ▼ # ┌─────────────────────┐ # │ Station Manager │ # └──────────┬──────────┘ # │ # ▼ # ┌─────────────────────┐ # │ Canonical Model │ # └───────┬───────┬─────┘ # │ │ # LIVE HISTORY # │ │ # ▼ ▼ # ┌──────────────┐ ┌──────────────────┐ # │Current-State │ │Historical │ # │Service │ │Acquisition │ # └──────┬───────┘ └────────┬─────────┘ # │ │ # │ ▼ # │ ┌──────────────────┐ # │ │Historical │ # │ │Pipeline │ # │ └────────┬─────────┘ # │ │ # │ ┌──────────┼───────────┐ # │ │ │ │ # │ ▼ ▼ ▼ # │ Repository Sink A Sink B # │ │ # │ │ # ▼ ▼ # ┌────────────────────────────┐ # │ OPC UA Server │ # │ │ # │ Data Access │ # │ Historical Access │ # │ Diagnostics │ # └──────────────┬─────────────┘ # │ # ▼ # SCADA / Clients # ``` # # \--- # # \# 61. Architecture decision summary # # The gateway is intentionally designed as an: # # ```text # AquaCom Integration Gateway # ``` # # rather than merely an: # # ```text # AquaCom OPC UA Server # ``` # # This allows: # # \- OPC UA to be replaced or supplemented; # \- storage technology to change; # \- multiple historians to coexist; # \- AquaCom equipment to be gradually retired; # \- other northbound interfaces to be added; # \- historical acquisition to continue independently of OPC UA clients. # # The long-term architectural asset is therefore the normalized integration layer and historical recovery mechanism, not any single external interface. # # \--- # # \# 62. Final architectural rule # # The most important data rule is: # # > Historical data is stored and exposed according to when the process value was valid, not when the gateway happened to retrieve it. # # The most important protocol rule is: # # > AquaCom behavior must be based on verified protocol knowledge and must never be invented merely to complete an implementation. # # The most important software rule is: # # > AquaCom, canonical data handling, historical persistence and OPC UA shall remain separate architectural concerns.