Files
aquacom-gateway-suite/docs/configuration/configuration-reference.md
T
2026-10-05 20:32:13 +02:00

51 KiB
Raw Blame History

# 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

Dropping historical information silently shall not be permitted.

---

# 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, a global/default routing policy may be used.

---

# 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.

---

# 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.