48 KiB
AquaCom Integration Gateway – Configuration Reference
1. Purpose
This document defines the configuration model for the AquaCom Integration Gateway.
It is the authoritative human-readable reference for:
-
configuration sections;
-
configuration fields;
-
required and optional values;
-
defaults;
-
validation rules;
-
relationships between configuration areas;
-
example configuration.
The configuration model shall remain implementation-language independent.
Machine-readable validation schemas shall be maintained separately under:
schemas/
This document explains what the configuration means.
The schema files define what configuration is syntactically and structurally valid.
2. Configuration principles
Gateway configuration shall be:
-
external to the application executable;
-
machine-readable;
-
versioned;
-
schema-validated;
-
suitable for source control;
-
portable between environments;
-
explicit about identifiers;
-
independent of runtime object allocation.
Production secrets shall not be stored directly in normal version-controlled configuration.
Configuration syntax shown in this document uses YAML for readability.
The final implementation may use YAML, JSON, TOML, or another structured format, provided that the semantic model defined here is preserved.
3. Configuration hierarchy
The gateway configuration shall conceptually contain:
configVersion: 1
gateway:
...
logging:
...
diagnostics:
...
security:
...
opcua:
...
history:
...
storage:
...
stations:
...
The top-level configuration sections are:
| Section | Purpose |
|---|---|
| configVersion | Configuration schema version |
| gateway | Gateway identity and runtime behavior |
| logging | Logging configuration |
| diagnostics | Diagnostics and metrics behavior |
| security | Shared security configuration |
| opcua | OPC UA server configuration |
| history | Historical subsystem configuration |
| storage | Historical repositories and storage destinations |
| stations | AquaCom station definitions |
4. Configuration version
4.1 configVersion
Type: integer
Required: yes
Defines the version of the gateway configuration schema.
Example:
configVersion: 1
The application shall reject configuration using an unsupported schema version.
Configuration migration between incompatible schema versions shall be explicit.
The application shall not silently reinterpret an incompatible configuration format.
5. Gateway configuration
Example:
gateway:
id: aquacom-gateway-01
displayName: Central AquaCom Gateway
timezone: Europe/Stockholm
startup:
allowDegradedStartup: true
shutdown:
gracefulTimeout: 30s
5.1 gateway.id
Type: string
Required: yes
Stable identifier for this gateway instance.
Example:
id: aquacom-gateway-01
Requirements:
-
must be unique within the relevant operational environment;
-
shall remain stable across software restart;
-
shall normally remain stable across software upgrade;
-
shall not be based on runtime-generated identifiers.
This identifier may be used in:
-
diagnostics;
-
logging;
-
historical metadata;
-
OPC UA namespace generation;
-
audit records.
5.2 gateway.displayName
Type: string
Required: no
Human-readable name.
Example:
displayName: Central AquaCom Gateway
Changing this value shall not change the gateway's stable identity.
5.3 gateway.timezone
Type: timezone identifier
Required: yes
Defines the gateway's configured local timezone.
Example:
timezone: Europe/Stockholm
UTC shall normally be used internally.
This timezone may be used for:
-
presentation;
-
interpretation of timestamps where the source does not include timezone information;
-
diagnostics.
A station may override this value.
6. Startup configuration
6.1 gateway.startup.allowDegradedStartup
Type: boolean
Default: true
Defines whether the gateway may start when non-critical external dependencies are unavailable.
Example:
startup:
allowDegradedStartup: true
If enabled, failures such as an unavailable optional storage destination shall not necessarily prevent live AquaCom acquisition or OPC UA startup.
Critical configuration errors shall always prevent startup.
7. Shutdown configuration
7.1 gateway.shutdown.gracefulTimeout
Type: duration
Default: implementation-defined
Defines the maximum time allowed for controlled shutdown.
Example:
shutdown:
gracefulTimeout: 30s
During this period the gateway should attempt to:
stop new acquisition
finish or cancel active transactions
persist synchronization state
flush durable state
stop OPC UA
close storage
8. Logging configuration
Example:
logging:
level: information
structured: true
telegramLogging:
enabled: false
includePayload: false
retention:
maxFiles: 14
maxFileSize: 100MB
8.1 logging.level
Type: enumeration
Required: no
Typical values:
trace
debug
information
warning
error
critical
Production default should normally be:
level: information
8.2 logging.structured
Type: boolean
Default: true
Enables structured logging where supported by the implementation.
Structured log records should support fields such as:
timestamp
severity
component
stationId
pointId
operation
correlationId
message
error
9. AquaCom telegram logging
Example:
telegramLogging:
enabled: false
includePayload: false
Telegram logging shall be treated as a diagnostic capability.
It shall not be enabled by default in production.
9.1 logging.telegramLogging.enabled
Type: boolean
Default: false
Enables AquaCom telegram-level logging.
9.2 logging.telegramLogging.includePayload
Type: boolean
Default: false
Defines whether raw telegram payload is included.
If enabled, operators shall consider:
-
storage consumption;
-
operational sensitivity;
-
possible exposure of process information.
10. Diagnostics configuration
Example:
diagnostics:
enabled: true
opcua:
exposeGatewayDiagnostics: true
exposeStationDiagnostics: true
exposeStorageDiagnostics: true
metrics:
enabled: true
10.1 diagnostics.enabled
Type: boolean
Default: true
Enables gateway diagnostics.
Disabling this shall not disable required internal error handling.
10.2 diagnostics.opcua.exposeGatewayDiagnostics
Type: boolean
Default: true
Exposes gateway-level diagnostic nodes through OPC UA.
10.3 diagnostics.opcua.exposeStationDiagnostics
Type: boolean
Default: true
Exposes per-station communication and synchronization diagnostics.
10.4 diagnostics.opcua.exposeStorageDiagnostics
Type: boolean
Default: true
Exposes historical-storage diagnostics.
10.5 diagnostics.metrics.enabled
Type: boolean
Default: implementation-defined
Enables runtime metrics.
The metrics transport or technology is implementation-specific.
11. Shared security configuration
Example:
security:
secretsProvider:
type: environment
certificates:
directory: ./certificates
This section contains shared security behavior.
Protocol-specific settings belong under their corresponding subsystem.
12. Secret handling
12.1 security.secretsProvider.type
Defines how secrets are supplied.
Possible implementations may include:
environment
file
operating-system secret store
container secret
external secret service
Production secrets shall not normally appear directly in the gateway configuration.
Example:
database:
username: gateway_user
passwordSecret: HISTORY_DB_PASSWORD
rather than:
password: SuperSecretPassword123
13. OPC UA configuration
Example:
opcua:
enabled: true
application:
name: AquaCom Integration Gateway
uri: urn:example:aquacom-gateway
endpoint:
bindAddress: 0.0.0.0
port: 4840
path: /aquacom
namespace:
uri: urn:example:aquacom
rootName: AquaCom
dataAccess:
enabled: true
historicalAccess:
enabled: true
repository: local-history
maxValuesPerRead: 10000
maxConcurrentReads: 10
security:
allowNone: false
certificate: gateway-opcua
trustMode: explicit
14. opcua.enabled
Type: boolean
Default: true
Controls whether the OPC UA server is started.
The gateway architecture shall permit AquaCom acquisition and historical storage to operate independently where practical if OPC UA is disabled.
15. OPC UA application identity
15.1 opcua.application.name
Human-readable OPC UA application name.
Example:
name: AquaCom Integration Gateway
15.2 opcua.application.uri
Stable application URI.
Example:
uri: urn:example:aquacom-gateway
The URI should remain stable for an installed gateway instance.
16. OPC UA endpoint
Example:
endpoint:
bindAddress: 0.0.0.0
port: 4840
path: /aquacom
16.1 opcua.endpoint.bindAddress
Defines the interface on which the OPC UA endpoint listens.
Production deployments should consider binding only to the required OT network interface.
16.2 opcua.endpoint.port
Type: integer
Example:
port: 4840
Port conflict shall be detected during startup.
16.3 opcua.endpoint.path
Optional OPC UA endpoint path.
Example:
path: /aquacom
17. OPC UA namespace
Example:
namespace:
uri: urn:example:aquacom
rootName: AquaCom
17.1 opcua.namespace.uri
Stable namespace URI used for gateway-specific nodes.
Changing this value may affect client configurations and shall therefore be treated as a compatibility-impacting change.
17.2 opcua.namespace.rootName
Human-readable root object name.
Changing this value shall not automatically alter stable NodeIds.
18. OPC UA Data Access
18.1 opcua.dataAccess.enabled
Type: boolean
Default: true
Enables exposure of configured current values.
19. OPC UA Historical Access
Example:
historicalAccess:
enabled: true
repository: local-history
maxValuesPerRead: 10000
maxConcurrentReads: 10
19.1 opcua.historicalAccess.enabled
Type: boolean
Enables OPC UA Historical Access.
If enabled, a queryable history repository must be configured.
19.2 opcua.historicalAccess.repository
Type: storage repository identifier
Required when Historical Access is enabled
Example:
repository: local-history
The referenced destination must implement the History Repository capability.
A sink-only destination is invalid here.
19.3 opcua.historicalAccess.maxValuesPerRead
Type: positive integer
Limits the number of values returned in one historical response.
Example:
maxValuesPerRead: 10000
Larger responses shall use OPC UA continuation where required.
19.4 opcua.historicalAccess.maxConcurrentReads
Type: positive integer
Limits concurrent historical requests.
This protects the gateway and historical repository against excessive resource usage.
20. OPC UA security configuration
Example:
security:
allowNone: false
certificate: gateway-opcua
trustMode: explicit
userAuthentication:
enabled: false
20.1 opcua.security.allowNone
Type: boolean
Default: false
Controls whether an unsecured OPC UA endpoint is permitted.
Production configuration should normally use:
allowNone: false
20.2 opcua.security.certificate
Reference to an externally configured certificate identity.
Private keys shall not be embedded directly in configuration committed to source control.
20.3 opcua.security.trustMode
Possible values may include:
explicit
managed
explicit means client certificates must be explicitly trusted.
The exact supported trust modes depend upon the selected OPC UA implementation.
21. Historical subsystem configuration
Example:
history:
enabled: true
liveHistorization:
enabled: true
deduplication:
enabled: true
conflictPolicy: reject
synchronization:
enabled: true
resumeAfterRestart: true
backfill:
enabled: true
priority: low
maxRequestsPerSecond: 2
spool:
enabled: true
maxSize: 20GB
maxAge: 30d
overflowPolicy: stop-history
22. history.enabled
Type: boolean
Enables the gateway historical subsystem.
This includes historical pipeline functionality.
Individual stations and points may still enable or disable history independently.
23. Live historization
23.1 history.liveHistorization.enabled
Type: boolean
Determines whether live current values may also be submitted to the historical pipeline.
Example:
liveHistorization:
enabled: true
This setting does not replace per-point history configuration.
Both global and point-level configuration shall permit history before a live value is historized.
24. Deduplication
Example:
deduplication:
enabled: true
conflictPolicy: reject
24.1 history.deduplication.enabled
Type: boolean
Recommended: true
Historical processing should normally be idempotent.
24.2 history.deduplication.conflictPolicy
Defines behavior when two different values have the same logical historical identity.
Allowed conceptual values:
reject
keep-first
keep-last
version
Recommended default:
conflictPolicy: reject
A conflict shall generate diagnostics.
25. History synchronization
Example:
synchronization:
enabled: true
resumeAfterRestart: true
25.1 history.synchronization.enabled
Enables synchronization-state management.
25.2 history.synchronization.resumeAfterRestart
Type: boolean
Recommended: true
If enabled, the gateway restores historical synchronization watermarks and continues incomplete synchronization after restart.
26. Backfill configuration
Example:
backfill:
enabled: true
priority: low
maxRequestsPerSecond: 2
26.1 history.backfill.enabled
Enables retrieval of missing AquaCom history following communication interruption.
Actual availability depends upon:
-
AquaCom protocol support;
-
RTU capabilities;
-
verified station configuration.
26.2 history.backfill.priority
Defines scheduling priority relative to other AquaCom operations.
Supported values may include:
low
normal
Recommended:
priority: low
Live acquisition shall normally take precedence.
26.3 history.backfill.maxRequestsPerSecond
Optional history-retrieval rate limit.
Used to prevent large backfill operations from consuming all available station communication capacity.
27. Durable spool configuration
Example:
spool:
enabled: true
path: ./data/spool
maxSize: 20GB
maxAge: 30d
overflowPolicy: stop-history
27.1 history.spool.enabled
Recommended: true
Enables persistent delivery buffering.
27.2 history.spool.path
Location of persistent spool data where the selected implementation requires an explicit path.
The path must be writable.
27.3 history.spool.maxSize
Maximum spool size.
Example:
maxSize: 20GB
The gateway shall provide diagnostics before reaching this limit.
27.4 history.spool.maxAge
Optional maximum retention time for pending spool records.
Care shall be taken before enabling automatic age-based deletion.
27.5 history.spool.overflowPolicy
Defines behavior if the spool cannot accept additional data.
Conceptual values:
stop-history
reject-new
drop-oldest
fail-gateway
Recommended production default:
overflowPolicy: stop-history
Historical information shall never be dropped silently. Policies that do discard data (drop-oldest, and age-based deletion via maxAge) shall emit a diagnostic event per discarded record (or per discarded batch, for bounded diagnostics) so the loss is observable and auditable. reject-new and stop-history remain the recommended policies because they never lose already-accepted records.
28. Storage configuration
Example:
storage:
destinations:
- id: local-history
type: repository
driver: example-local-db
required: true
capabilities:
write: true
query: true
connection:
path: ./data/history
- id: enterprise-historian
type: sink
driver: example-historian
required: true
connection:
endpoint: historian.example.local
credentialSecret: HISTORIAN_CREDENTIAL
- id: archive
type: sink
driver: ndjson
required: false
connection:
directory: ./archive
29. Storage destination identifiers
29.1 storage.destinations[].id
Type: string
Required: yes
Stable identifier for the storage destination.
Example:
id: local-history
Must be unique.
Other configuration sections reference destinations using this identifier.
30. Storage destination type
30.1 storage.destinations[].type
Defines the architectural role.
Conceptual values:
repository
sink
repository-and-sink
Meaning:
| Type | Query | Write |
|---|---|---|
| repository | yes | implementation-dependent |
| sink | no | yes |
| repository-and-sink | yes | yes |
The exact schema may represent capabilities instead of this combined enumeration.
31. Storage driver
31.1 storage.destinations[].driver
Defines the implementation adapter.
Example:
driver: example-local-db
The value is implementation-specific.
Business logic shall not depend directly on this value.
32. Required and optional destinations
32.1 storage.destinations[].required
Type: boolean
Defines whether successful delivery to the destination is required before a spool record may be considered fully delivered.
Example:
required: true
If:
required: false
failure shall generate diagnostics but shall not indefinitely block cleanup of records that have reached all required destinations.
33. Storage capabilities
Example:
capabilities:
write: true
query: true
This may be validated against the selected driver.
A repository used for OPC UA Historical Access must have:
query: true
34. Storage retry configuration
A storage destination may contain:
retry:
enabled: true
initialDelay: 2s
maximumDelay: 5m
multiplier: 2
Retry policy shall be independent for each destination.
Storage retries shall not block AquaCom live acquisition.
35. Station configuration
Example:
stations:
- id: PS001
displayName: Wastewater Pump Station 001
enabled: true
timezone: Europe/Stockholm
transport:
type: tcp
host: 192.0.2.10
port: 1234
aquacom:
address: 101
profile: default
acquisition:
live:
enabled: true
pollingInterval: 5s
requestTimeout: 3s
retryCount: 2
history:
enabled: true
backfillEnabled: true
pointDefinitions:
sourceType: atf
path: ./stations/PS001.atf
36. stations[].id
Type: string
Required: yes
Stable gateway identifier for the station.
Example:
id: PS001
Requirements:
-
unique within the gateway;
-
stable across restart;
-
stable across IP-address changes;
-
stable across display-name changes.
The station ID may form part of:
PointId
OPC UA NodeId
historical identity
logs
diagnostics
37. stations[].displayName
Human-readable station name.
Example:
displayName: Wastewater Pump Station 001
Changing this shall not change the stable station identity.
38. stations[].enabled
Type: boolean
Default: true
Controls whether the gateway actively communicates with the station.
A disabled station configuration may remain visible diagnostically.
39. Station timezone
39.1 stations[].timezone
Optional station-specific timezone.
If omitted, the gateway timezone is inherited.
Example:
timezone: Europe/Stockholm
This configuration is important where AquaCom timestamps lack explicit timezone information.
40. Transport configuration
Example:
transport:
type: tcp
host: 192.0.2.10
port: 1234
connectTimeout: 5s
idleTimeout: 30s
Transport-specific fields are conditional on type.
41. transport.type
Defines the AquaCom transport implementation.
Potential supported values may include:
tcp
serial
serial-over-ip
Only implemented and verified transport types shall be accepted.
42. TCP transport
Example:
transport:
type: tcp
host: 192.0.2.10
port: 1234
connectTimeout: 5s
42.1 transport.host
Hostname or IP address.
This value is not the station's stable identity.
42.2 transport.port
TCP port used for AquaCom communication.
The default shall not be invented if it is not formally defined for the target equipment.
Where no verified standard value exists, explicit configuration shall be required.
42.3 transport.connectTimeout
Maximum connection establishment time.
43. Serial transport
Conceptual example:
transport:
type: serial
port: /dev/ttyS0
baudRate: 9600
dataBits: 8
stopBits: 1
parity: none
Actual values shall be determined from validated AquaCom documentation and target-device requirements.
Codex shall not insert assumed AquaCom serial defaults without evidence.
44. AquaCom station protocol configuration
Example:
aquacom:
address: 101
profile: default
This section contains AquaCom-specific station configuration.
Only verified protocol concepts shall be introduced here.
44.1 aquacom.address
Station address or AquaCom identifier required by the verified protocol implementation.
The representation is protocol-dependent.
It shall not be assumed to be identical to stations[].id.
44.2 aquacom.profile
Optional reference to an AquaCom protocol profile.
Profiles may be useful where different controller generations or configurations require different verified protocol behaviors.
Example:
profile: app700
A profile shall never enable guessed protocol behavior.
45. Acquisition configuration
Each station contains:
acquisition:
live:
...
history:
...
Live acquisition and historical acquisition shall be independently configurable.
46. Live acquisition
Example:
live:
enabled: true
pollingInterval: 5s
requestTimeout: 3s
retryCount: 2
46.1 acquisition.live.enabled
Enables current-value acquisition for the station.
46.2 acquisition.live.pollingInterval
Defines the normal polling period.
The implementation shall validate unreasonable values.
Example:
pollingInterval: 5s
46.3 acquisition.live.requestTimeout
Maximum allowed time for an AquaCom live transaction before timeout handling.
46.4 acquisition.live.retryCount
Number of immediate or near-immediate retries permitted before normal communication-failure logic takes over.
Retries shall not create an uncontrolled retry storm.
47. Station historical acquisition
Example:
history:
enabled: true
backfillEnabled: true
maxBackfillAge: 7d
47.1 acquisition.history.enabled
Enables AquaCom historical retrieval for the station.
This requires verified support for the station/controller type.
47.2 acquisition.history.backfillEnabled
Enables automatic recovery following communication interruption.
47.3 acquisition.history.maxBackfillAge
Optional limit on how far back the gateway will automatically request history.
Example:
maxBackfillAge: 7d
This protects against unexpected very large historical queries.
A value beyond this range may require an explicit administrative operation.
48. Point definition source
Points may originate from sources such as:
ATF
static configuration
engineering data import
future external configuration service
Example:
pointDefinitions:
sourceType: atf
path: ./stations/PS001.atf
48.1 pointDefinitions.sourceType
Potential values:
atf
inline
file
Only implemented source types shall be accepted.
48.2 pointDefinitions.path
Path to an external point-definition file.
File changes shall be validated before activation.
49. Inline point definitions
Conceptual example:
points:
- id: LEVEL
displayName: Wet well level
description: Measured wet well level
source:
reference: ...
dataType: float
engineeringUnit: m
scaling:
enabled: false
live:
enabled: true
history:
enabled: true
opcua:
enabled: true
historizing: true
storage:
enabled: true
The exact AquaCom source-reference syntax shall only be defined when supported by verified protocol or ATF semantics.
50. Point identifier
50.1 points[].id
Required: yes
Stable point identifier within the station.
Example:
id: LEVEL
Logical identity may become:
station:PS001/point:LEVEL
Changing displayName shall not change this identifier.
51. Point display name
51.1 points[].displayName
Human-readable presentation name.
Example:
displayName: Wet well level
May be changed without creating a new logical process point.
52. Point source reference
Example:
source:
reference: ...
Defines how the point maps to AquaCom.
The content is intentionally unspecified until AquaCom mapping rules are verified.
Codex shall not invent source-reference syntax.
53. Point data type
53.1 points[].dataType
Logical canonical data type.
Possible values may include:
boolean
integer
unsigned-integer
float
double
string
The final supported set shall be defined by the canonical data model.
54. Engineering unit
54.1 points[].engineeringUnit
Optional engineering unit.
Examples:
engineeringUnit: m
engineeringUnit: l/s
engineeringUnit: °C
Engineering units should use a controlled representation where feasible.
55. Point scaling
Example:
scaling:
enabled: true
multiplier: 0.1
offset: 0
Scaling is applied after verified AquaCom decoding and before creation of the canonical value.
The raw value may optionally be retained diagnostically.
56. Point live configuration
Example:
live:
enabled: true
Controls whether the point participates in current-state processing.
57. Point history configuration
Example:
history:
enabled: true
Controls whether historical information is processed for the point.
58. Point OPC UA configuration
Example:
opcua:
enabled: true
historizing: true
58.1 points[].opcua.enabled
Controls whether the point is exposed through OPC UA.
58.2 points[].opcua.historizing
Controls whether the OPC UA Variable advertises historical capability.
If enabled:
-
point history must be enabled;
-
OPC UA Historical Access must be enabled;
-
a queryable repository must be configured.
59. Explicit NodeId override
Optional example:
opcua:
enabled: true
nodeId: station/PS001/point/LEVEL
Normally the gateway should generate deterministic NodeIds from stable station and point identifiers.
Manual override should only be required for compatibility or migration scenarios.
Duplicate NodeIds shall be rejected.
60. Point storage configuration
Example:
storage:
enabled: true
destinations:
- local-history
- enterprise-historian
If destinations is omitted, the default routing policy applies. The default routing shall be deterministic and explicit:
- if exactly one destination is configured, points route to it;
- if more than one destination is configured, validation requires either a
history.defaultDestinationslist or per-pointdestinations— an implicit "deliver to everything" or "deliver to nothing" default is not permitted, because both silently change delivery behavior when destinations are added or removed.
The exact form of the global default is implementation-defined but shall be validated; ambiguity shall fail configuration validation rather than resolve silently.
61. Storage routing
The system shall support routing history to selected destinations.
Example:
storage:
enabled: true
destinations:
- local-history
- enterprise-historian
Different points may therefore use different storage policies if required.
62. History source behavior
A point may theoretically receive historical data from:
live historization
AquaCom historical retrieval
AquaCom report retrieval
future import
The canonical AcquisitionSource shall preserve the origin.
Storage routing shall not normally depend upon raw AquaCom message types.
63. Timestamp configuration
Station timestamp behavior may include:
timestamps:
sourceTimezone: Europe/Stockholm
maximumFutureDeviation: 5m
maximumPastDeviation: 365d
ambiguousDstPolicy: reject
63.1 timestamps.sourceTimezone
Used to interpret device timestamps without explicit timezone information.
Defaults to:
station timezone
then:
gateway timezone
if no station timezone exists.
63.2 timestamps.maximumFutureDeviation
Maximum permitted source timestamp ahead of gateway time before it is flagged.
63.3 timestamps.maximumPastDeviation
Optional sanity threshold for implausibly old values.
Historical backfill behavior may legitimately require values much older than normal live values.
The implementation shall distinguish history from erroneous live timestamps.
63.4 timestamps.ambiguousDstPolicy
Defines behavior when a source local timestamp is ambiguous during daylight-saving transition.
Possible conceptual values:
reject
prefer-earlier
prefer-later
mark-uncertain
Recommended behavior is either:
mark-uncertain
or:
reject
depending on operational requirements.
64. Communication health configuration
A station may define thresholds such as:
health:
degradedAfterFailures: 2
offlineAfterFailures: 5
staleAfter: 30s
64.1 health.degradedAfterFailures
Consecutive failed transactions before communication changes to a degraded state.
64.2 health.offlineAfterFailures
Consecutive failed transactions before the station is considered offline.
This value must be greater than or equal to the degraded threshold.
64.3 health.staleAfter
Maximum age of a current value before quality may be changed to stale/uncertain/bad according to configured behavior.
65. Retry behavior
Transport, AquaCom transactions and storage destinations may each have separate retry policies.
These retries shall not be combined into an uncontrolled nested retry loop.
Retry configuration should define:
retry:
initialDelay: 1s
maximumDelay: 1m
multiplier: 2
jitter: true
Exact supported fields are implementation-specific.
66. Configuration inheritance
Where practical, the gateway may support default configuration inheritance.
Example:
defaults:
station:
acquisition:
live:
pollingInterval: 5s
health:
degradedAfterFailures: 2
offlineAfterFailures: 5
Then a station may override:
stations:
- id: PS001
acquisition:
live:
pollingInterval: 2s
If implemented, inheritance rules must be deterministic and documented.
Implicit multi-level inheritance should be avoided if it makes effective configuration difficult to understand.
67. Configuration validation rules
The configuration validator shall detect at least:
unsupported configVersion
duplicate gateway/station/point/storage identifiers
duplicate OPC UA NodeIds
missing referenced storage destinations
Historical Access enabled without queryable repository
point historizing enabled without history capability
unsupported transport type
unsupported storage driver
invalid timezone
invalid durations
invalid numeric limits
invalid security configuration
required secrets not available
nonexistent required files
invalid ATF or point-definition references
history enabled for unsupported station profile
configuration contradictions
68. Cross-field validation
Examples of required relationships follow.
If:
opcua:
historicalAccess:
enabled: true
then:
a queryable history repository must exist.
If:
point:
opcua:
historizing: true
then:
point history must be enabled.
If:
history:
enabled: false
then point-level historical acquisition shall not become active.
If:
station:
acquisition:
history:
enabled: true
but the configured AquaCom profile has no verified historical implementation, validation shall fail or the station history feature shall be explicitly marked unavailable.
It shall not silently use guessed AquaCom behavior.
69. Configuration activation
Configuration shall follow:
Load
↓
Parse
↓
Schema validation
↓
Semantic validation
↓
Dependency validation
↓
Activation
Invalid configuration shall not partially activate.
Where dynamic reload is supported:
Current valid configuration
│
▼
New configuration
│
▼
Validate
┌───────┴────────┐
│ │
valid invalid
│ │
▼ ▼
activate retain existing
70. Dynamic configuration
Changes may be classified as:
runtime-safe
controlled-restart
full-restart
Examples that may eventually be runtime-safe:
logging level
polling intervals
selected diagnostics
storage retry intervals
Changes likely requiring controlled restart or resource reconstruction:
OPC UA application certificate
OPC UA namespace URI
transport type
storage driver type
persistent storage path
Exact behavior shall be defined by the implementation.
71. Configuration compatibility
The gateway shall distinguish:
configuration schema compatibility
OPC UA namespace compatibility
storage schema compatibility
protocol profile compatibility
A configuration schema change shall not automatically require an OPC UA namespace change.
72. Example minimal configuration
configVersion: 1
gateway:
id: aquacom-gateway-01
timezone: Europe/Stockholm
logging:
level: information
diagnostics:
enabled: true
opcua:
enabled: true
application:
name: AquaCom Integration Gateway
uri: urn:example:aquacom-gateway
endpoint:
bindAddress: 0.0.0.0
port: 4840
namespace:
uri: urn:example:aquacom
dataAccess:
enabled: true
historicalAccess:
enabled: false
security:
allowNone: false
certificate: gateway-opcua
history:
enabled: false
storage:
destinations: []
stations:
- id: PS001
enabled: true
transport:
type: tcp
host: 192.0.2.10
port: 1234
aquacom:
address: 101
acquisition:
live:
enabled: true
pollingInterval: 5s
pointDefinitions:
sourceType: atf
path: ./stations/PS001.atf
This configuration represents:
AquaCom live acquisition
↓
OPC UA current values
without historical functionality.
73. Example configuration with history
configVersion: 1
gateway:
id: aquacom-gateway-01
timezone: Europe/Stockholm
logging:
level: information
diagnostics:
enabled: true
opcua:
enabled: true
application:
name: AquaCom Integration Gateway
uri: urn:example:aquacom-gateway
endpoint:
bindAddress: 0.0.0.0
port: 4840
namespace:
uri: urn:example:aquacom
dataAccess:
enabled: true
historicalAccess:
enabled: true
repository: local-history
maxValuesPerRead: 10000
security:
allowNone: false
certificate: gateway-opcua
history:
enabled: true
liveHistorization:
enabled: true
deduplication:
enabled: true
conflictPolicy: reject
synchronization:
enabled: true
resumeAfterRestart: true
backfill:
enabled: true
priority: low
maxRequestsPerSecond: 2
spool:
enabled: true
path: ./data/spool
maxSize: 20GB
overflowPolicy: stop-history
storage:
destinations:
- id: local-history
type: repository-and-sink
driver: local-history
required: true
capabilities:
write: true
query: true
connection:
path: ./data/history
- id: central-historian
type: sink
driver: enterprise-historian
required: true
capabilities:
write: true
query: false
connection:
endpoint: historian.example.local
credentialSecret: CENTRAL_HISTORIAN_CREDENTIAL
- id: archive
type: sink
driver: ndjson
required: false
capabilities:
write: true
query: false
connection:
directory: ./archive
stations:
- id: PS001
displayName: Wastewater Pump Station 001
enabled: true
timezone: Europe/Stockholm
transport:
type: tcp
host: 192.0.2.10
port: 1234
connectTimeout: 5s
aquacom:
address: 101
profile: default
acquisition:
live:
enabled: true
pollingInterval: 5s
requestTimeout: 3s
retryCount: 2
history:
enabled: true
backfillEnabled: true
maxBackfillAge: 7d
timestamps:
sourceTimezone: Europe/Stockholm
maximumFutureDeviation: 5m
health:
degradedAfterFailures: 2
offlineAfterFailures: 5
staleAfter: 30s
pointDefinitions:
sourceType: atf
path: ./stations/PS001.atf
74. Example resulting data flow
Using the configuration above:
PS001
│
│ AquaCom
▼
Gateway
│
├────────► Current-State Service
│ │
│ ▼
│ OPC UA DA
│
└────────► Historical Pipeline
│
▼
Durable Spool
│
┌─────────┼─────────────┐
│ │ │
▼ ▼ ▼
Local History Central Archive
Repository Historian
│
▼
OPC UA HA
75. Recommended configuration file organization
Small installations may use one file:
config/
└── gateway.yaml
Larger installations should be able to split configuration logically:
config/
├── gateway.yaml
├── opcua.yaml
├── storage.yaml
├── defaults.yaml
│
└── stations/
├── PS001.yaml
├── PS002.yaml
├── PS003.yaml
└── ...
The implementation may support file inclusion or configuration-directory loading.
Regardless of physical layout, the resulting configuration model shall be equivalent to the logical model described in this document.
76. Recommended station-file organization
For a larger number of AquaCom installations:
config/
└── stations/
│
├── PS001/
│ ├── station.yaml
│ └── station.atf
│
├── PS002/
│ ├── station.yaml
│ └── station.atf
│
└── PS003/
├── station.yaml
└── station.atf
This allows station-specific engineering configuration to remain grouped.
77. Relationship to ATF
Where ATF files are used, configuration and ATF have separate responsibilities.
Conceptually:
station.yaml
│
├── transport
├── communication
├── acquisition
├── history
├── security/context
└── ATF reference
│
▼
station.atf
│
└── AquaCom station capability /
point definition
ATF-specific semantics shall be documented under:
docs/protocol/
once verified.
The generic configuration model shall not duplicate all information contained in the ATF unless required for overrides or normalization.
78. Point overrides
The architecture should permit gateway-specific metadata to augment imported point definitions.
Conceptual example:
pointOverrides:
LEVEL:
displayName: Wet well level
engineeringUnit: m
opcua:
enabled: true
historizing: true
INTERNAL_DIAGNOSTIC_17:
opcua:
enabled: false
history:
enabled: false
This permits an imported ATF point model to remain unchanged while gateway behavior is customized.
79. Configuration precedence
If multiple configuration sources are supported, precedence shall be explicit.
Recommended conceptual order:
built-in safe defaults
↓
global configuration
↓
station configuration
↓
point definition source
↓
explicit point override
Later layers may override earlier values only where permitted.
Secrets are resolved independently and shall not be written back into the effective configuration.
80. Effective configuration
The gateway should provide a diagnostic mechanism for viewing the effective non-secret configuration.
For example:
configured polling interval
effective polling interval
configured storage routing
effective point properties
selected AquaCom profile
selected OPC UA NodeId
This significantly improves troubleshooting.
Secret values shall be redacted.
81. Configuration audit
Changes to active configuration should be auditable.
An audit event should identify:
configuration version
previous configuration identity/hash
new configuration identity/hash
activation timestamp
result
operator/source where known
The exact implementation is technology-dependent.
Administrative channel
Audit events require an administrative actor, but no interactive administration interface is defined in the initial scope. Until one is introduced, administrative actions (configuration activation, certificate trust decisions, manually initiated history synchronization) are performed through the deployment mechanism — controlled configuration-file changes and process restart/reload — and the audit record shall identify that source accordingly (for example, operator: config-file). A dedicated administrative interface (CLI, API, or similar) may be added later as a separately specified and separately authorized capability; implementations shall not invent one ad hoc.
82. Safe configuration behavior
When configuration is incomplete or contradictory, prefer explicit failure over implicit behavior.
Examples:
Do not automatically select an arbitrary repository if:
opcua:
historicalAccess:
enabled: true
and multiple repositories exist but none is identified.
Do not silently enable insecure OPC UA because certificate configuration failed.
Do not invent AquaCom transport defaults if no verified defaults exist.
Do not activate historical retrieval for an unsupported AquaCom controller profile.
83. Configuration design rule
Configuration should express intent, not implementation internals.
Prefer:
history:
enabled: true
over implementation-specific concepts such as:
instantiateHistoryWorkerThread: true
Prefer:
required: true
over:
deleteSpoolRecordAfterDestination2: false
The configuration model shall remain understandable independently of implementation language.
84. Configuration schema files
Machine-readable schemas should be separated approximately as:
schemas/
├── gateway-config.schema.*
├── station-config.schema.*
├── point-config.schema.*
└── storage-config.schema.*
Schemas shall encode:
required properties
types
enumerations
ranges
formats
basic structural constraints
Cross-component semantic validation may require application-level validation in addition to schema validation.
85. Configuration tests
Automated tests shall verify at least:
minimal valid configuration accepted
complete valid configuration accepted
duplicate station ID rejected
duplicate point ID rejected
duplicate OPC UA NodeId rejected
missing History Repository rejected when OPC UA HA enabled
unknown storage destination rejected
invalid timezone rejected
invalid duration rejected
unsupported transport rejected
unsupported AquaCom profile rejected
history configuration rejected where implementation support is absent
insecure OPC UA production default prevented
missing required secret reported
point override applied correctly
configuration reload failure leaves previous valid configuration active
86. Initial implementation recommendation
The first configuration implementation should support only the fields required for the initial production scope.
The model in this document defines the intended architecture but does not require every optional field to be implemented immediately.
Unsupported fields shall be:
rejected
or explicitly documented as:
not implemented
They shall not be silently ignored unless the configuration model explicitly permits forward-compatible unknown fields.
87. Final configuration rule
The configuration system shall preserve the architectural separation of the gateway.
In particular:
station transport configuration
≠
station identity
display name
≠
PointId
OPC UA NodeId
≠
runtime object identifier
history retrieval
≠
OPC UA HistoryRead
storage destination
≠
AquaCom protocol implementation
The configuration model shall describe how components are connected without coupling those components internally.
The most important configuration principles are:
Stable identifiers shall remain stable even when presentation or transport details change.
Invalid or unsupported AquaCom behavior shall never be activated through configuration by relying on guessed protocol semantics.
Historical acquisition, historical persistence, and OPC UA Historical Access shall remain independently configurable concerns.