# Configuration An open.CONNECT instance is configured on three levels: 1. the **`.env` file** — what the instance does and where it gets its configuration; 2. **devices** — one entry per connection (PLC, server, folder, …); 3. **items** — one entry per value to read from a device. Devices and items come either from a JSON **config file** (`OC_OFFLINE = true`) or from a **Parse server** (`OC_OFFLINE = false`). ## Environment variables | Variable | Meaning | |---|---| | `OC_CAP_FLAGS` | Comma-separated capabilities: `plc`, `api`, `manage`, `mqttwrite` — see the [Übersicht](Developer/open.CONNECT/Übersicht.md#capabilities). | | `OC_OFFLINE` | `true` → load devices/items from the file `OC_OFFLINE_FILE`; `false` → load from Parse. | | `OC_OFFLINE_FILE` | Path of the JSON config file, e.g. `configs/config.json`. | | `OC_REFRESH_INTERVAL` | How often (ms) the configuration is re-checked for changes. Changed devices are restarted automatically. | | `OC_PARSE_HOST` / `OC_PARSE_APPID` / `OC_PARSE_USER` / `OC_PARSE_PASSWORD` | Parse server connection (only with `OC_OFFLINE = false`). | | `OC_WEBAPI_PORT` | Port of the web API / management UI (default `80`). | | `OC_WEBAPI_SECRET` | HMAC secret for the API tokens and login password of the management UI. | | `OC_THREAD_POOLSIZE` | Size of the reader thread pool (default `4`). | | `OC_MQTT_WRITE_HOST` / `OC_MQTT_WRITE_CLIENTID` / `OC_MQTT_WRITE_USERNAME` / `OC_MQTT_WRITE_PASSWORD` | Broker connection of the [MQTT write API](write-api.md#writing-via-mqtt) (capability `mqttwrite`). | | `OC_UPTIME_KUMA_HEARTBEAT` | Optional Uptime-Kuma heartbeat URL, pinged by the configuration runnable. | | `MAIL_*` | Optional SMTP settings for mail notifications (`MAIL_ENABLE`, `MAIL_HOST`, `MAIL_PORT`, `MAIL_USERNAME`, `MAIL_PASSWORD`, `MAIL_FROM_ADDRESS`, `MAIL_TO_ADDRESS`, `MAIL_STARTTLS`, `MAIL_SMTP_SSL_ENABLE`, `MAIL_SSL_TRUST`). | ## Config file structure ```json { "devices": [ { "…": "one entry per connection" } ], "items": [ { "…": "one entry per value" } ] } ``` ## Device options These fields work the same for every adapter: | Option | Type | Default | Meaning | |---|---|---|---| | `connectionString` | string | — | Selects the adapter (prefix = adapter id) and carries host/port/path, e.g. `modbus.tcp://10.0.0.5:502`. | | `objectId` | string | — | Unique device id. Items reference it, and the write API addresses the device by it. | | `enabled` | boolean | — | If `false`, the device is skipped and no reader thread is started. | | `interval` | long (ms) | — | Poll period, scheduled as a **fixed delay** between consecutive runs. | | `watch` | long (ms) | `0` | Watchdog. If `> 0` and there was no successful run within `watch` ms, the process exits and relies on the container/service manager to restart it. | | `name` | string | — | Human-readable device name; used as the source name of the produced data items. | | `options` | object | `{}` | **Protocol-specific** settings — documented on each [adapter page](/docs/openconnect/adapters). | | `extraOptions` | object | `{}` | MQTT output settings, see below. | **`extraOptions` — MQTT output per device:** | Key | Meaning | |---|---| | `host` | MQTT broker (`host[:port]`, connected as `tcp://…`). Empty → this device publishes nothing. | | `clientId` | Base client id (suffixed with the device `objectId` and a timestamp). | | `username` / `password` | Optional broker credentials. | | `prefix` / `suffix` | Prepended/appended to every published topic. | ## Item options | Option | Type | Meaning | |---|---|---| | `objectId` | string | Unique item id. | | `DeviceID.objectId` | string | The device this item belongs to. | | `address` | string | **Protocol-specific** address of the value — documented on each [adapter page](/docs/openconnect/adapters). | | `label` | string | Display name of the value dimension. | | `unit` | string | Unit of the value dimension. | | `type` | string | Value type: `Number`, `Boolean`, `String`, `Object`. | | `source.tag` | string | Source/tag of the produced data item (part of the MQTT topic). | | `enabled` | boolean | Only enabled items are read. | | `onChange` | boolean | If `true`, publish only when the value changed. Without a threshold, unchanged values are suppressed within a 60 s window. | **`extraOptions` — item pipeline:** | Key | Shape | Behaviour | |---|---|---| | `scale` | `{ "factor": 1.0, "offset": 0.0 }` | Linear transform on each numeric dimension: `new = value * factor + offset`. | | `changeThreshold` | `{ "type": "absolute", "threshold": 0.5 }` | Refines `onChange`. `absolute` → resend when the difference exceeds `threshold`; any other type → relative: resend when the old value is `0` or the relative change exceeds `threshold`. | | `useManualId` | string | Overrides the produced item id. | | `overwrites` | object | Post-read overrides: `name`, `source`, `id`, `meta`, and per-dimension `valueTypes[].name` / `valueTypes[].unit`. | | `valueTypes` | array | Declares multiple dimensions for items whose address yields more than one value: `[{ "name": "…", "unit": "…", "type": "Number" }, …]`. | Example item using the pipeline options: ```json { "objectId": "temp1", "DeviceID": { "objectId": "plc1" }, "address": "HR::16int::100::1", "label": "Temperature", "type": "Number", "unit": "°C", "source": { "tag": "hall1/oven" }, "enabled": true, "onChange": true, "extraOptions": { "scale": { "factor": 0.1, "offset": 0 }, "changeThreshold": { "type": "absolute", "threshold": 0.5 } } } ``` ## Connection and retry behaviour - **Connect backoff:** exponential — `2^min(8, retries)` seconds between connection attempts, reset on success. - **MQTT reconnect:** throttled to at most once every 30 s; reconnects automatically on connection loss. - **Subscriptions:** adapters that support subscriptions register the items once (first successful run) and receive pushed values; all others are polled every `interval` ms. - **Config refresh:** the configuration is re-read every `OC_REFRESH_INTERVAL` ms; changed devices are restarted with their new settings. ## Parse-based configuration With `OC_OFFLINE = false`, devices and items are loaded from the Parse classes `OWPlcDevice` and the item class, using the same fields as the file-based configuration. An item object then carries the usual Parse metadata in addition — for reference, this is what an item looks like when it comes from Parse: ```json { "objectId": "XX", "address": "XX::XX::XX", "onChange": false, "DeviceID": { "__type": "Pointer", "className": "OWPlcDevice", "objectId": "XXX" }, "label": "Some name", "type": "Number", "unit": "#", "enabled": true, "source": { "__type": "Object", "className": "OD3_Source", "objectId": "XX", "name": "XX", "tag": "some tag" }, "extraOptions": { "note": "some note", "charset": "UTF-8", "persist": true } } ``` ## Sync files (API mapping) For instances that map values between HTTP APIs (capability `api` with sync services), a sync file in the `sync/` folder describes the field mapping. The mapper uses Apache Velocity templates to extract and replace fields: ```json { "from-service": { "to-service": { "request-type": { "targetField": { "value": "$source.id", "type": "string" } } } } } ```