Skip to content

Edge config document

This page lists every field you can set in an Edge's configuration, for use on a template's JSON tab and in Overrides JSON on a group or an Edge.

The complete configuration an Edge receives is a JSON document of type wt.config.device/v1. Preview render on an Edge's Config tab shows it. A template or an override contains only the fields it sets. See Edge configuration for how layers combine.

Top-level keys

The complete document has exactly these six keys. No other keys are allowed.

Key Type Default when no layer sets it Purpose
schema string, always "wt.config.device/v1" "wt.config.device/v1" Document type.
agent object see agent Log level, offline storage and change confirmation.
assets object {"schema":"wt.config.assets/v1","assets":[]} Devices the Edge reads and their metrics.
lan_reach object {"whitelist":[]} Devices operators may reach through the Edge.
app_access array [] Filled by Watchtower from access grants. Do not set it.
update_policy object or null null Agent update policy. null turns updates off.

Watchtower fills a default only for a key that no layer sets. A key that any layer sets must be complete after the layers combine.

agent

All three fields are required when you set agent. The template's Agent tab writes them all.

Field Type Allowed Default Agent tab label
log_level string error, warn, info, debug, trace info Log level
telemetry.outbox_max_mb integer 1 to 10240 256 Outbox max MB
telemetry.outbox_max_age_hours integer 1 to 8760 168 Outbox max age hours
commit_confirm.timeout_s integer 1 to 86400 120 Confirm timeout seconds
commit_confirm.rollback_on_connector_failure boolean true, false false Roll back when a connector fails

telemetry and commit_confirm each need both of their fields. The effective document can also show an agent.endpoints object, which Watchtower manages. Do not set it.

assets

Field Type Required Rules
schema string, always "wt.config.assets/v1" Yes Document type.
defaults.batch_interval_ms integer No 100 to 60000. Default 5000. How often readings are sent in a batch.
defaults.report object No Default report mode for all metrics.
assets array Yes At most 64 assets. asset_id must be unique.

Asset

Field Type Required Rules
asset_id string Yes Lowercase letters, digits and hyphens, 2 to 63 characters, starting with a letter or digit.
name string Yes 1 to 128 characters.
enabled boolean No Default true. A disabled asset is not read, and its metrics do not count as tags.
protocol string Yes opcua, modbus-tcp, sparkplug-b, s7, enip or simulator.
connection object Yes See Protocols.
collection object No (required for sparkplug-b) See Protocols.
batch_interval_ms integer No 100 to 60000. Overrides defaults.batch_interval_ms.
metrics array Yes At most 5000 per asset and 10000 per Edge.

Metric

Field Type Required Rules
name string Yes Up to 64 characters: lowercase letters, digits, _, . and -, starting with a letter or digit. Unique within the asset.
source object Yes The address on the device. See Protocols.
data_type string For modbus-tcp, s7 and enip bool, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64, string, datetime, bytes, json.
unit string No Up to 32 characters.
description string No Up to 256 characters.
report object No Overrides the default report mode.

Report modes

Value Behaviour
{"mode":"always"} Send every reading.
{"mode":"on_change","deadband":0,"max_silence_ms":60000} Send when the value changes by more than deadband (at least 0, default 0), when its quality changes, or after max_silence_ms without a send (at least 1000, default 60000).

Protocols

opcua

Part Field Rules and default
connection endpoint_url Required. Starts with opc.tcp://.
security_mode none, sign, sign_encrypt. Default sign_encrypt.
security_policy None, Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss. Default Basic256Sha256.
auth {"type":"anonymous"} (default) or {"type":"username","username":"…","password":<secret>}.
trust {"mode":"tofu"} (default: trust the server certificate on first use) or {"mode":"pinned","thumbprints":["<40 hex characters>"]}.
session_timeout_ms At least 1000. Default 60000.
collection subscription {"mode":"subscription","publishing_interval_ms":1000,"sampling_interval_ms":null,"queue_size":1}. Intervals at least 100. queue_size at least 1.
polling {"mode":"polling","interval_ms":1000}. interval_ms at least 100.
source node_id Required, for example ns=2;s=Filler.Temp.
sampling_interval_ms Optional, at least 100.

modbus-tcp

Part Field Rules and default
connection host Required.
port 1 to 65535. Default 502.
unit_id 0 to 255. Default 1.
timeout_ms 100 to 30000. Default 1000.
collection interval_ms At least 100. Default 1000.
max_registers_per_read 1 to 125. Default 125.
max_bits_per_read 1 to 2000. Default 2000.
max_gap 0 to 100. Default 10.
inter_request_delay_ms 0 to 1000. Default 0.
source table Required. coil, discrete_input, holding_register, input_register.
address Required. 0 to 65535, zero-based: register 40001 is address 0.
bit 0 to 15. Reads one bit of a register as bool.
word_order, byte_order big (default) or little.
length 1 to 125 registers. Required for string.
scale, offset Numbers. Defaults 1 and 0.

data_type must be bool, int16, uint16, int32, uint32, int64, uint64, float32, float64 or string. Coils and discrete inputs need bool. bool on a register needs bit.

sparkplug-b

Part Field Rules and default
connection broker Required. Embedded broker on the Edge: {"mode":"embedded","listen":"0.0.0.0:1883","users":[{"username":"…","password":<secret>}]}, at least one user. Existing broker: {"mode":"external","url":"mqtts://…","username":"…","password":<secret>,"ca_pem":null}, url starting with mqtt:// or mqtts://.
primary_host_id Optional string or null.
request_rebirth Boolean. Default true.
collection group_id, edge_node_id Required.
device_id Optional. Leave it out for node-level metrics.
source metric Required. The metric name exactly as the device publishes it.

s7

Part Field Rules and default
connection host Required.
rack 0 to 7. Default 0.
slot 0 to 31. Default 1 (S7-1200 and S7-1500). S7-300 usually uses 2.
connection_type pg (default), op, s7_basic.
password Optional secret, only if the CPU is password-protected.
port 1 to 65535. Default 102.
timeout_ms 100 to 60000. Default 2000.
collection interval_ms At least 100. Default 1000.
max_items_per_read 1 to 20. Default 20.
source address Required, for example DB10.DBD4, DB10.DBX0.3, MB4, I0.0.

For data blocks on S7-1200 and S7-1500, enable PUT/GET access and turn off optimized block access in the PLC project.

enip

Part Field Rules and default
connection host Required. Use host:port for a non-default port.
plc Required. controllogix, compactlogix, micro800, micrologix, plc5, slc500, omron-njnx.
path Default 1,0. Empty string for Micro800.
timeout_ms 100 to 60000. Default 2000.
collection interval_ms At least 100. Default 1000.
source tag Required, for example MyArray[3] or Udt.Field. PLC-5 and SLC 500 use addresses such as N7:0.
elem_count At least 1. Default 1.

simulator

Part Field Rules and default
connection Empty object {}.
collection interval_ms 100 to 60000. Default 1000.
seed Optional integer.
source kind sine (default), counter, random, toggle, constant.
period_ms At least 100. Default 60000.
min, max Numbers. Defaults 0 and 100.
value Fixed value for constant.

Secrets

Wherever a field takes a password, write a secret reference instead of the value:

{ "secret": { "ref": "sec_4fK2pQ9xLm7Rt1Vb" } }

Watchtower rejects any configuration that contains a password in plain text. See Edge configuration.

lan_reach

Field Type Rules
whitelist array Required. Each entry has exactly these four fields.
whitelist[].id string Lowercase letters, digits and hyphens, up to 63 characters. Unique.
whitelist[].ip string IPv4 address.
whitelist[].port integer 1 to 65535.
whitelist[].label string 1 to 128 characters.

See LAN Reach.

app_access

Watchtower builds this list from active access grants and replaces anything a layer sets. Manage it with Grant access to an Edge.

update_policy

null turns agent updates off. Otherwise all three fields are required:

Field Type Rules
mode string auto, download_only or manual.
window.days array At least one of sun, mon, tue, wed, thu, fri, sat.
window.start, window.end string 24-hour HH:MM. If end is earlier than start, the window runs past midnight.
window.tz string Time zone name, for example Europe/Berlin.
allowed_registry string The image repository the Edge accepts updates from.

See Updates.

Complete example

A complete document with an OPC UA asset, a Modbus TCP asset, a LAN Reach entry and an update policy:

{
  "schema": "wt.config.device/v1",
  "agent": {
    "log_level": "info",
    "telemetry": { "outbox_max_mb": 256, "outbox_max_age_hours": 168 },
    "commit_confirm": { "timeout_s": 120, "rollback_on_connector_failure": false }
  },
  "assets": {
    "schema": "wt.config.assets/v1",
    "defaults": {
      "batch_interval_ms": 5000,
      "report": { "mode": "on_change", "deadband": 0, "max_silence_ms": 60000 }
    },
    "assets": [
      {
        "asset_id": "filler-opcua",
        "name": "Filler OPC UA server",
        "protocol": "opcua",
        "connection": {
          "endpoint_url": "opc.tcp://192.0.2.21:4840",
          "security_mode": "sign_encrypt",
          "security_policy": "Basic256Sha256",
          "auth": {
            "type": "username",
            "username": "edge",
            "password": { "secret": { "ref": "sec_4fK2pQ9xLm7Rt1Vb" } }
          },
          "trust": { "mode": "tofu" }
        },
        "collection": { "mode": "subscription", "publishing_interval_ms": 1000 },
        "metrics": [
          { "name": "filler.temp", "source": { "node_id": "ns=2;s=Filler.Temp" }, "unit": "°C" },
          { "name": "filler.running", "source": { "node_id": "ns=2;s=Filler.Running" }, "report": { "mode": "always" } }
        ]
      },
      {
        "asset_id": "tank-plc",
        "name": "Tank PLC",
        "protocol": "modbus-tcp",
        "connection": { "host": "192.0.2.20", "port": 502, "unit_id": 1 },
        "collection": { "interval_ms": 1000 },
        "batch_interval_ms": 2000,
        "metrics": [
          {
            "name": "tank_level",
            "source": { "table": "holding_register", "address": 0 },
            "data_type": "uint16",
            "unit": "%"
          },
          {
            "name": "flow_rate",
            "source": { "table": "holding_register", "address": 10, "scale": 0.1 },
            "data_type": "float32",
            "unit": "m3/h",
            "report": { "mode": "on_change", "deadband": 0.5, "max_silence_ms": 30000 }
          }
        ]
      }
    ]
  },
  "lan_reach": {
    "whitelist": [
      { "id": "hmi-web", "ip": "192.0.2.10", "port": 443, "label": "HMI web UI" }
    ]
  },
  "app_access": [],
  "update_policy": {
    "mode": "auto",
    "window": { "days": ["sat", "sun"], "start": "02:00", "end": "05:00", "tz": "Europe/Berlin" },
    "allowed_registry": "ghcr.io/privitty/privitty-edge"
  }
}

In a template or an override, include only the sections you want to set, and leave out app_access.

When Watchtower refuses a configuration

Watchtower checks each Edge's complete document before it sends it. If a check fails, the Edge keeps its current configuration and the error appears when you hover the Sync cell on the Edges page. Preview render shows the same problems in advance. Watchtower refuses a document when:

  • A field breaks a rule on this page. The error names the field by its path, such as /assets/assets/0/asset_id.
  • An asset_id or a metric name inside one asset appears twice, or the Edge exceeds 64 assets or 10000 metrics.
  • The Edge does not support a protocol you use: Edge agent does not support <protocol>. Check Capabilities on the Edge's Overview tab.
  • The change would exceed the tag limit of your plan: tag_cap_reached total=<n> cap=<m>. See Billing and usage.