3738 lines
48 KiB
Markdown
3738 lines
48 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
|
||
|
||
```
|
||
|
||
Historical information shall never be dropped silently. Policies that do discard data (`drop-oldest`, and age-based deletion via `maxAge`) shall emit a diagnostic event per discarded record (or per discarded batch, for bounded diagnostics) so the loss is observable and auditable. `reject-new` and `stop-history` remain the recommended policies because they never lose already-accepted records.
|
||
|
||
---
|
||
|
||
# 28. Storage configuration
|
||
|
||
Example:
|
||
|
||
```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, the **default routing policy** applies. The default routing shall be deterministic and explicit:
|
||
|
||
- if exactly one destination is configured, points route to it;
|
||
- if more than one destination is configured, validation requires either a `history.defaultDestinations` list or per-point `destinations` — an implicit "deliver to everything" or "deliver to nothing" default is not permitted, because both silently change delivery behavior when destinations are added or removed.
|
||
|
||
The exact form of the global default is implementation-defined but shall be validated; ambiguity shall fail configuration validation rather than resolve silently.
|
||
|
||
---
|
||
|
||
# 61. Storage routing
|
||
|
||
The system shall support routing history to selected destinations.
|
||
|
||
Example:
|
||
|
||
```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.
|
||
|
||
### Administrative channel
|
||
|
||
Audit events require an administrative actor, but no interactive administration interface is defined in the initial scope. Until one is introduced, administrative actions (configuration activation, certificate trust decisions, manually initiated history synchronization) are performed through the deployment mechanism — controlled configuration-file changes and process restart/reload — and the audit record shall identify that source accordingly (for example, `operator: config-file`). A dedicated administrative interface (CLI, API, or similar) may be added later as a separately specified and separately authorized capability; implementations shall not invent one ad hoc.
|
||
|
||
---
|
||
|
||
# 82. Safe configuration behavior
|
||
|
||
When configuration is incomplete or contradictory, prefer explicit failure over implicit behavior.
|
||
|
||
Examples:
|
||
|
||
Do not automatically select an arbitrary repository if:
|
||
|
||
```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.
|
||
|