5759 lines
51 KiB
Markdown
5759 lines
51 KiB
Markdown
\# 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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
shutdown:
|
||
|
||
  gracefulTimeout: 30s
|
||
|
||
```
|
||
|
||
|
||
|
||
During this period the gateway should attempt to:
|
||
|
||
|
||
|
||
```text
|
||
|
||
stop new acquisition
|
||
|
||
finish or cancel active transactions
|
||
|
||
persist synchronization state
|
||
|
||
flush durable state
|
||
|
||
stop OPC UA
|
||
|
||
close storage
|
||
|
||
```
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 8. Logging configuration
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
trace
|
||
|
||
debug
|
||
|
||
information
|
||
|
||
warning
|
||
|
||
error
|
||
|
||
critical
|
||
|
||
```
|
||
|
||
|
||
|
||
Production default should normally be:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
timestamp
|
||
|
||
severity
|
||
|
||
component
|
||
|
||
stationId
|
||
|
||
pointId
|
||
|
||
operation
|
||
|
||
correlationId
|
||
|
||
message
|
||
|
||
error
|
||
|
||
```
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 9. AquaCom telegram logging
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
environment
|
||
|
||
file
|
||
|
||
operating-system secret store
|
||
|
||
container secret
|
||
|
||
external secret service
|
||
|
||
```
|
||
|
||
|
||
|
||
Production secrets shall not normally appear directly in the gateway configuration.
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
database:
|
||
|
||
  username: gateway\_user
|
||
|
||
  passwordSecret: HISTORY\_DB\_PASSWORD
|
||
|
||
```
|
||
|
||
|
||
|
||
rather than:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
password: SuperSecretPassword123
|
||
|
||
```
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 13. OPC UA configuration
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
name: AquaCom Integration Gateway
|
||
|
||
```
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\## 15.2 `opcua.application.uri`
|
||
|
||
|
||
|
||
Stable application URI.
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
uri: urn:example:aquacom-gateway
|
||
|
||
```
|
||
|
||
|
||
|
||
The URI should remain stable for an installed gateway instance.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 16. OPC UA endpoint
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
port: 4840
|
||
|
||
```
|
||
|
||
|
||
|
||
Port conflict shall be detected during startup.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\## 16.3 `opcua.endpoint.path`
|
||
|
||
|
||
|
||
Optional OPC UA endpoint path.
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
path: /aquacom
|
||
|
||
```
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 17. OPC UA namespace
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
reject
|
||
|
||
keep-first
|
||
|
||
keep-last
|
||
|
||
version
|
||
|
||
```
|
||
|
||
|
||
|
||
Recommended default:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
conflictPolicy: reject
|
||
|
||
```
|
||
|
||
|
||
|
||
A conflict shall generate diagnostics.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 25. History synchronization
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
low
|
||
|
||
normal
|
||
|
||
```
|
||
|
||
|
||
|
||
Recommended:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
stop-history
|
||
|
||
reject-new
|
||
|
||
drop-oldest
|
||
|
||
fail-gateway
|
||
|
||
```
|
||
|
||
|
||
|
||
Recommended production default:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
overflowPolicy: stop-history
|
||
|
||
```
|
||
|
||
|
||
|
||
Dropping historical information silently shall not be permitted.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 28. Storage configuration
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
required: true
|
||
|
||
```
|
||
|
||
|
||
|
||
If:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
required: false
|
||
|
||
```
|
||
|
||
|
||
|
||
failure shall generate diagnostics but shall not indefinitely block cleanup of records that have reached all required destinations.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 33. Storage capabilities
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
capabilities:
|
||
|
||
  write: true
|
||
|
||
  query: true
|
||
|
||
```
|
||
|
||
|
||
|
||
This may be validated against the selected driver.
|
||
|
||
|
||
|
||
A repository used for OPC UA Historical Access must have:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
query: true
|
||
|
||
```
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 34. Storage retry configuration
|
||
|
||
|
||
|
||
A storage destination may contain:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
PointId
|
||
|
||
OPC UA NodeId
|
||
|
||
historical identity
|
||
|
||
logs
|
||
|
||
diagnostics
|
||
|
||
```
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 37. `stations\[].displayName`
|
||
|
||
|
||
|
||
Human-readable station name.
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
timezone: Europe/Stockholm
|
||
|
||
```
|
||
|
||
|
||
|
||
This configuration is important where AquaCom timestamps lack explicit timezone information.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 40. Transport configuration
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
tcp
|
||
|
||
serial
|
||
|
||
serial-over-ip
|
||
|
||
```
|
||
|
||
|
||
|
||
Only implemented and verified transport types shall be accepted.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 42. TCP transport
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
profile: app700
|
||
|
||
```
|
||
|
||
|
||
|
||
A profile shall never enable guessed protocol behavior.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 45. Acquisition configuration
|
||
|
||
|
||
|
||
Each station contains:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
acquisition:
|
||
|
||
  live:
|
||
|
||
  ...
|
||
|
||
|
||
|
||
  history:
|
||
|
||
  ...
|
||
|
||
```
|
||
|
||
|
||
|
||
Live acquisition and historical acquisition shall be independently configurable.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 46. Live acquisition
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
ATF
|
||
|
||
static configuration
|
||
|
||
engineering data import
|
||
|
||
future external configuration service
|
||
|
||
```
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
pointDefinitions:
|
||
|
||
  sourceType: atf
|
||
|
||
  path: ./stations/PS001.atf
|
||
|
||
```
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\## 48.1 `pointDefinitions.sourceType`
|
||
|
||
|
||
|
||
Potential values:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
id: LEVEL
|
||
|
||
```
|
||
|
||
|
||
|
||
Logical identity may become:
|
||
|
||
|
||
|
||
```text
|
||
|
||
station:PS001/point:LEVEL
|
||
|
||
```
|
||
|
||
|
||
|
||
Changing `displayName` shall not change this identifier.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 51. Point display name
|
||
|
||
|
||
|
||
\## 51.1 `points\[].displayName`
|
||
|
||
|
||
|
||
Human-readable presentation name.
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
displayName: Wet well level
|
||
|
||
```
|
||
|
||
|
||
|
||
May be changed without creating a new logical process point.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 52. Point source reference
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
engineeringUnit: m
|
||
|
||
```
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
engineeringUnit: l/s
|
||
|
||
```
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
engineeringUnit: °C
|
||
|
||
```
|
||
|
||
|
||
|
||
Engineering units should use a controlled representation where feasible.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 55. Point scaling
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
live:
|
||
|
||
  enabled: true
|
||
|
||
```
|
||
|
||
|
||
|
||
Controls whether the point participates in current-state processing.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 57. Point history configuration
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
history:
|
||
|
||
  enabled: true
|
||
|
||
```
|
||
|
||
|
||
|
||
Controls whether historical information is processed for the point.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 58. Point OPC UA configuration
|
||
|
||
|
||
|
||
Example:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
station timezone
|
||
|
||
```
|
||
|
||
|
||
|
||
then:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
reject
|
||
|
||
prefer-earlier
|
||
|
||
prefer-later
|
||
|
||
mark-uncertain
|
||
|
||
```
|
||
|
||
|
||
|
||
Recommended behavior is either:
|
||
|
||
|
||
|
||
```text
|
||
|
||
mark-uncertain
|
||
|
||
```
|
||
|
||
|
||
|
||
or:
|
||
|
||
|
||
|
||
```text
|
||
|
||
reject
|
||
|
||
```
|
||
|
||
|
||
|
||
depending on operational requirements.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 64. Communication health configuration
|
||
|
||
|
||
|
||
A station may define thresholds such as:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
defaults:
|
||
|
||
  station:
|
||
|
||
  acquisition:
|
||
|
||
  live:
|
||
|
||
  pollingInterval: 5s
|
||
|
||
|
||
|
||
  health:
|
||
|
||
  degradedAfterFailures: 2
|
||
|
||
  offlineAfterFailures: 5
|
||
|
||
```
|
||
|
||
|
||
|
||
Then a station may override:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
opcua:
|
||
|
||
  historicalAccess:
|
||
|
||
  enabled: true
|
||
|
||
```
|
||
|
||
|
||
|
||
then:
|
||
|
||
|
||
|
||
```text
|
||
|
||
a queryable history repository must exist.
|
||
|
||
```
|
||
|
||
|
||
|
||
If:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
point:
|
||
|
||
  opcua:
|
||
|
||
  historizing: true
|
||
|
||
```
|
||
|
||
|
||
|
||
then:
|
||
|
||
|
||
|
||
```text
|
||
|
||
point history must be enabled.
|
||
|
||
```
|
||
|
||
|
||
|
||
If:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
history:
|
||
|
||
  enabled: false
|
||
|
||
```
|
||
|
||
|
||
|
||
then point-level historical acquisition shall not become active.
|
||
|
||
|
||
|
||
If:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
Load
|
||
|
||
  ↓
|
||
|
||
Parse
|
||
|
||
  ↓
|
||
|
||
Schema validation
|
||
|
||
  ↓
|
||
|
||
Semantic validation
|
||
|
||
  ↓
|
||
|
||
Dependency validation
|
||
|
||
  ↓
|
||
|
||
Activation
|
||
|
||
```
|
||
|
||
|
||
|
||
Invalid configuration shall not partially activate.
|
||
|
||
|
||
|
||
Where dynamic reload is supported:
|
||
|
||
|
||
|
||
```text
|
||
|
||
Current valid configuration
|
||
|
||
  │
|
||
|
||
  ▼
|
||
|
||
  New configuration
|
||
|
||
  │
|
||
|
||
  ▼
|
||
|
||
  Validate
|
||
|
||
  ┌───────┴────────┐
|
||
|
||
  │ │
|
||
|
||
  valid invalid
|
||
|
||
  │ │
|
||
|
||
  ▼ ▼
|
||
|
||
  activate retain existing
|
||
|
||
```
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 70. Dynamic configuration
|
||
|
||
|
||
|
||
Changes may be classified as:
|
||
|
||
|
||
|
||
```text
|
||
|
||
runtime-safe
|
||
|
||
controlled-restart
|
||
|
||
full-restart
|
||
|
||
```
|
||
|
||
|
||
|
||
Examples that may eventually be runtime-safe:
|
||
|
||
|
||
|
||
```text
|
||
|
||
logging level
|
||
|
||
polling intervals
|
||
|
||
selected diagnostics
|
||
|
||
storage retry intervals
|
||
|
||
```
|
||
|
||
|
||
|
||
Changes likely requiring controlled restart or resource reconstruction:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
AquaCom live acquisition
|
||
|
||
  ↓
|
||
|
||
OPC UA current values
|
||
|
||
```
|
||
|
||
|
||
|
||
without historical functionality.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 73. Example configuration with history
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
config/
|
||
|
||
└── gateway.yaml
|
||
|
||
```
|
||
|
||
|
||
|
||
Larger installations should be able to split configuration logically:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
station.yaml
|
||
|
||
  │
|
||
|
||
  ├── transport
|
||
|
||
  ├── communication
|
||
|
||
  ├── acquisition
|
||
|
||
  ├── history
|
||
|
||
  ├── security/context
|
||
|
||
  └── ATF reference
|
||
|
||
  │
|
||
|
||
  ▼
|
||
|
||
  station.atf
|
||
|
||
  │
|
||
|
||
  └── AquaCom station capability /
|
||
|
||
  point definition
|
||
|
||
```
|
||
|
||
|
||
|
||
ATF-specific semantics shall be documented under:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
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:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
history:
|
||
|
||
  enabled: true
|
||
|
||
```
|
||
|
||
|
||
|
||
over implementation-specific concepts such as:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
instantiateHistoryWorkerThread: true
|
||
|
||
```
|
||
|
||
|
||
|
||
Prefer:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
required: true
|
||
|
||
```
|
||
|
||
|
||
|
||
over:
|
||
|
||
|
||
|
||
```yaml
|
||
|
||
deleteSpoolRecordAfterDestination2: false
|
||
|
||
```
|
||
|
||
|
||
|
||
The configuration model shall remain understandable independently of implementation language.
|
||
|
||
|
||
|
||
\---
|
||
|
||
|
||
|
||
\# 84. Configuration schema files
|
||
|
||
|
||
|
||
Machine-readable schemas should be separated approximately as:
|
||
|
||
|
||
|
||
```text
|
||
|
||
schemas/
|
||
|
||
├── gateway-config.schema.\*
|
||
|
||
├── station-config.schema.\*
|
||
|
||
├── point-config.schema.\*
|
||
|
||
└── storage-config.schema.\*
|
||
|
||
```
|
||
|
||
|
||
|
||
Schemas shall encode:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
rejected
|
||
|
||
```
|
||
|
||
|
||
|
||
or explicitly documented as:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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:
|
||
|
||
|
||
|
||
```text
|
||
|
||
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.
|
||
|