Skip to content

Write a definition

A definition is a JSON file that says what a kind of device can do and how the bridge reaches each part. The bridge calls only what a definition binds, so a definition is also the limit of what any credential can ask of the device.

The full rules are in the definition format reference. This guide builds an HTTP definition step by step.

{
"formatVersion": 1,
"id": "workshop-heater",
"title": "Workshop heater",
"description": "A fan heater with a thermostat and a boost mode.",
"driver": "http"
}
  • id is lowercase letters, digits and -, at most 64 characters, and starts with a letter or digit.
  • driver is http or mqtt.

A property is a value the device has. Give it a type and, where they help, a title, a unit and limits. Values are checked against these in both directions: a write outside them is refused before it is sent, and a device reply outside them is refused as INVALID_DEVICE_VALUE.

"properties": {
"temperature": {
"type": "number",
"title": "Temperature",
"unit": "degree celsius",
"readOnly": true,
"observable": true
},
"setpoint": {
"type": "integer",
"title": "Setpoint",
"unit": "degree celsius",
"minimum": 5,
"maximum": 30
},
"mode": {
"type": "string",
"enum": ["off", "eco", "comfort"],
"title": "Mode"
}
}

Three flags describe a property, and they must agree with its bindings:

Flag Meaning Rule
readOnly Cannot be written No writeproperty binding
writeOnly Cannot be read, and its value is not kept on the record or collected for history No readproperty binding
observable Can be watched for live values Must have an observeproperty binding

A flag you leave out is false.

An action is something the device does when asked, with an optional input and output. An event is something the device reports on its own.

"actions": {
"boost": {
"title": "Boost",
"input": {
"type": "object",
"properties": { "minutes": { "type": "integer", "minimum": 1, "maximum": 60 } },
"required": ["minutes"],
"additionalProperties": false
},
"output": {
"type": "object",
"properties": { "until": { "type": "string" } },
"required": ["until"]
}
}
},
"events": {
"overheat": {
"title": "Overheat",
"data": {
"type": "object",
"properties": { "temperature": { "type": "number" } },
"required": ["temperature"]
}
}
}

Capability names start with a letter and use letters, digits, _ and -, up to 64 characters.

Every property needs at least one binding. Every action needs exactly one invokeaction binding, and every event exactly one subscribeevent binding. Paths are literal and start with /.

"bindings": {
"properties": {
"temperature": {
"readproperty": { "method": "GET", "path": "/api/temperature", "responsePointer": "/value" },
"observeproperty": { "method": "GET", "path": "/api/temperature/events", "stream": "sse", "responsePointer": "/value" }
},
"setpoint": {
"readproperty": { "method": "GET", "path": "/api/setpoint", "responsePointer": "/value" },
"writeproperty": { "method": "PUT", "path": "/api/setpoint" }
},
"mode": {
"readproperty": { "method": "GET", "path": "/api/mode", "responsePointer": "/mode" },
"writeproperty": { "method": "POST", "path": "/api/mode" }
}
},
"actions": {
"boost": {
"invokeaction": { "method": "POST", "path": "/api/boost" }
}
},
"events": {
"overheat": {
"subscribeevent": { "method": "GET", "path": "/api/events", "stream": "sse", "event": "overheat" }
}
}
}
  • responsePointer is a JSON Pointer into the device’s JSON reply. Leave it out to use the whole reply.
  • A write sends the value as the JSON body. With the definition above, writing 21 to setpoint sends PUT /api/setpoint with the body 21. A write binding has no responsePointer; a successful write returns null.
  • An action sends its input as the JSON body. Its output is the reply, or the part of it at responsePointer. An action with responsePointer must declare an output.
  • A stream binding reads a text/event-stream response. Each event’s data is parsed as JSON and the pointer applied. With event set, only events of that name count.
Terminal window
nodelets definition install workshop-heater.json

The bridge checks the file against the format and the rules above and says what is wrong if it fails. Then add a device with it. See Add an HTTP device.

An installed definition cannot be changed in place. Installing a different file under an ID that is already installed fails with A different definition with this ID is already installed. To change one:

  1. Give the new file a new id, for example workshop-heater-2, and install it.
  2. Move each device to it with nodelets thing update ID, choosing the new definition.

The Nodelets keep their IDs. A changed definition ends live subscriptions to them, and subscribers are told.

Permissions match capabilities by name. If a new definition gives a name a different meaning, a key that named it now reaches the new meaning.