Skip to main content

Capability Definitions (v1)

Capability definitions describe what a device model can do in IOTMER:

  • Which capabilities exist (switch, metering, …)
  • Which channels exist (relays, metering channels, sensors, …)
  • Which datapoints exist (fields shown in the UI / carried over MQTT)
  • How datapoints behave (read/write, widgets, alarms, scaling)
  • Optional command hints (supported_commands) — parameter contracts may expand in later versions

This page is the human-facing companion to the normative Capability Definitions Spec v1. For templates, definitions are edited under Device templates → Capability definitions; see Device Templates.


Quickstart

Canonical shape — product and greenfield integrations use a single JSON object envelope with exactly these top-level keys:

{
"spec_version": "1.0",
"capability_definitions": []
}

For a valid saved definition, capability_definitions must contain at least one CapabilityDefinition (the empty array above only illustrates structure). Fill in real definitions below.

The capabilities array on the template (parallel string tags such as ["switch","metering"]) must align with the capability values you declare inside capability_definitions.


Canonical storage shape

Capability definitions must be modeled and persisted as this object envelope{ spec_version, capability_definitions }. No other layout is described here as “correct” for product semantics.

Console vs REST API

SurfaceWhat to follow
This page (product)Only the envelope above. Use it when authoring definitions by hand or exporting portable JSON.
Console template editorIf the empty template still shows a bare [] or another placeholder, trust save-time validation for what the UI accepts until the editor default matches the envelope. Prefer aligning the console default with this envelope so docs and UI stay consistent.
Automation / SDKsRequest and response bodies follow CapabilityDefinitionsPayload in OpenAPI (REST API overview). That schema lists wire-level variants accepted by the backend—verify against live OpenAPI + backend behavior, not only this page.

Required top-level keys

KeyTypeMeaning
spec_versionstring (non-empty)Opaque marker for clients: which interpretation rules apply. v1 validation typically checks presence, not semver formatting.
capability_definitionsarray (min length 1)Each element is a CapabilityDefinition.

Forward compatibility

Any unknown JSON keys anywhere inside the envelope must be preserved end-to-end (pass-through). IOTMER must not strip unknown keys.


CapabilityDefinition

Required keys

KeyTypeDescription
capabilitystring enumOne of: switch, metering, sensor, input
channelsarrayMin length 1
datapointsarrayMin length 1

Optional keys

KeyTypeDescription
supported_commandsstring arrayAllowed tokens: set, countdown, reset_energy. Primarily UI guidance for extra controls beyond defaults.

Notes (v1): For switch, the set command is implicit even if omitted from supported_commands.


Channel

Represents an addressable MQTT channel identity (channel_id in topics).

Required keys

KeyTypeConstraints
idstringsnake_case, unique within the same CapabilityDefinition. Regex: ^[a-z][a-z0-9_]{0,31}$
labelstringHuman-facing UI label, max length 64

Optional keys

KeyTypeRules
linked_relaystringMetering-only. Must reference a switch capability channel id within the same template.

Datapoint

Datapoints are the atomic UI/MQTT fields (voltage, relay state, faults, …).

Required keys (all datapoints)

KeyTypeValues / rules
keystringsnake_case, unique within the same CapabilityDefinition. Regex: ^[a-z][a-z0-9_]{0,31}$
typeenumboolean, float, integer, enum, fault
modeenumro (read-only), rw (read-write), wo (write-only)
widgetenumtoggle, metric, gauge, bar, indicator, alarm_badge, enum_select, text
scopeenumper_channel — values per channel (MQTT segments usually include /{channel_id}). device — device-wide (segments usually omit /{channel_id}).

Widget compatibility matrix (normative)

IOTMER rejects invalid combinations.

typemodeAllowed widgets
booleanrwMust be toggle
booleanroMust be indicator
floatroMust be one of metric, gauge, bar
floatrwMust be metric
integerroMust be one of metric, gauge, bar
integerrwMust be metric
enumrwMust be enum_select
enumroMust be text
fault(any)Must be ro; widget must be alarm_badge

Writeback (boolean RW toggles only)

Optional key:

KeyValuesMeaning
writebackoptimistic | confirmedoptimistic: UI updates immediately after issuing a command. confirmed: UI waits until the device publishes updated state / acknowledgement path is satisfied.

Rules:

  • Allowed only when type="boolean" and mode="rw".
  • Reject: mode="ro" with writeback present; non-boolean datapoint with writeback present.

Default if omitted: optimistic.


Numeric datapoints (float / integer)

Required

KeyTypeNotes
unitstringExamples: V, A, W, kWh, °C, %

Optional

KeyTypeDefaultNotes
scalenumber1Display: display_value = raw_value / scale. Should reject scale == 0.
chartbooleanfalseIf true: product wording — eligible for time-series pipelines.
groupstringUI grouping (e.g. electrical, energy, environment).
aggregationstring arrayElements: avg, max, min, sum. Valid only when chart=true.

Alarm object (numeric only)

Optional example:

{
"condition": "gt",
"value": 16,
"severity": "critical"
}
FieldType
conditiongt, lt, gte, lte
valuenumber — threshold on display scale (after scale is applied)
severitywarning, critical

Reject: alarm object on type=fault.


Enum datapoints

Required

KeyTypeConstraints
enum_valuesstring arrayMin 2, max 32 elements

Fault datapoints

Required

KeyTypeDescription
fault_bitsobjectKeys: bit positions as strings "0""15". Values: fault codes as snake_case strings.

Example:

{
"0": "over_voltage",
"1": "under_voltage",
"2": "over_current",
"3": "over_temperature"
}

Reject: invalid bit keys outside 015.


Platform baseline rules

Switch minimum standard

If capability="switch", the definition must include at least one datapoint:

  • key="state"
  • type="boolean"
  • mode="rw"
  • widget="toggle"
  • scope="per_channel"

Metering linkage rule

If linked_relay is present:

  • It must appear only under metering channels.
  • It must reference an existing switch channel id.
  • Reject templates that define metering links without a switch capability.

default_config (template-level overrides)

default_config is JSON merged into effective device configuration.

Recognized keys include:

KeyTypeNotes
relay_countintegerRequired if switch exists; must equal switch channel count.
energy_channel_countintegerRequired if metering exists; must equal metering channel count.
relay_default_state"on" | "off"Default "off".
timezonestring (IANA)Default "UTC".
ota_channel"stable" | "beta"Default "stable".
max_offline_queueintegerRange 10–1000, default 100.
telemetry_interval_secinteger10–3600, default 60.
heartbeat_interval_secinteger10–300, default 30.
report_on_changebooleanDefault true.
thresholdsobjectOptional advisory tuning (see below).

thresholds object (v1 advisory)

Example keys:

{
"over_current_a": 16,
"over_voltage_v": 260,
"under_voltage_v": 180,
"over_temp_c": 85
}

Greenfield stance: v1 treats thresholds as device tuning hints unless/until strict mapping to fault bits is standardized (stricter validation may arrive in v2).


MQTT mapping

Topic forms (same layout as console ACL examples — workspace slug first, then device key):

{workspace_slug}/{device_key}/{segment}
{workspace_slug}/{device_key}/{segment}/{channel_id}

Segment intent

SegmentTypical directionchannel_id usage
telemetrydevice → cloudDepends on datapoint scope
statedevice → cloudDepends on datapoint scope
cmdcloud → deviceTypically per channel
cmd/ackdevice → cloudTypically per channel
eventdevice → cloudChannel-less topic; channel may appear in payload
configcloud → deviceChannel-less
config/ackdevice → cloudChannel-less
presencedevice → cloudChannel-less
heartbeatdevice → cloudChannel-less

Scope rules (normative)

  • scope=per_channel datapoints participate under telemetry/{channel_id} and/or state/{channel_id} (and related cmd paths as applicable).
  • scope=device datapoints participate under telemetry and/or state without /{channel_id}.

Diagram: envelope vs scope

flowchart LR
subgraph env[Envelope]
SV[spec_version]
CD[capability_definitions array]
end
subgraph scope[Datapoint scope]
PC[per_channel → segments with channel_id]
DV[device → segments without channel_id]
end

Diagram: numeric alarm path

flowchart LR
RAW[raw_value] --> SCALE["÷ scale"]
SCALE --> DISP[display_value]
DISP --> CMP["compare vs alarm.value"]

Payload conventions (examples)

telemetry (typical numeric raw integers)

{
"voltage": 2200,
"current": 153,
"power": 3360,
"energy": 12400,
"fault": 0,
"ts": 1714050000
}

state (relay)

{ "state": true, "fault": 0, "ts": 1714050000 }

cmd examples

{ "cmd": "set", "state": true }
{ "cmd": "countdown", "seconds": 3600 }

event payload rule

Because event topics are channel-less:

  • If the event is channel-specific → payload must include "channel": "<channel_id>".
  • If the event is device-wide → payload must not include channel.

Example:

{
"key": "relay_changed",
"channel": "relay_1",
"state": true,
"triggered_by": "user",
"ts": 1714050000
}

Mobile clients should normalize readings into:

{
"reported": {
"{capability}": {
"{channel_id_or_device}": {
"{datapoint_key}": 0
}
}
}
}

Convention:

  • For scope=per_channel: {channel_id_or_device} is the real channel id (relay_1, ch_1, …).
  • For scope=device: use reserved bucket key device instead of a channel id.

Validation summary (checklist)

IOTMER rejects (non-exhaustive checklist for integrators):

  • Invalid enums (capability, type, mode, widget, scope, …)
  • Empty channels / empty capability_definitions
  • Duplicate channel ids or duplicate datapoint keys within a capability
  • Invalid widget matrix combinations
  • Invalid fault bit keys (015 strings only)
  • aggregation without chart=true
  • Illegal writeback placement (non-boolean or non-RW)
  • Inconsistent relay_count / energy_channel_count vs channel lengths
  • Metering linked_relay without switch capability or unresolved relay id

Size limits

Envelope JSON must not exceed 1 MiB (recommended enforcement at template save paths).


See also

  • Device Templates — where definitions are edited in the console
  • MQTT Overview — broker topics and ACL context
  • REST API overviewCapabilityDefinitionsPayload / template APIs for programmatic clients (wire shapes vs this product envelope)