Vibrant BLE API Specification
All UUID prefixes below are hexadecimal and expand to
XXXXXXXX-C1EC-46E2-AC97-7D4C7B4BB930.
The base service is 00000001.
1. Gateway BLE specification — current
Overview
BLE provides gateway identification, Wi-Fi setup, commissioning RPCs, and update interfaces. Protocol version: 1.
Characteristics
| Prefix | Name | Access | Encoding |
|---|---|---|---|
00000100 |
Device Info / capabilities | Read | UTF-8 JSON |
00000101 |
Device Status | Read / Notify | UTF-8 JSON |
00000102 |
Command | Read / Write / Write Without Response / Notify | Framed JSON |
00000110–00000113 |
Serial / type / firmware / model | Read | UTF-8 |
00000114 |
Protocol version | Read | Exactly 2 bytes, uint16LE |
00000115–00000116 |
Image version / release ID | Read | UTF-8 |
00000117 |
Identity public key | Read | 32-byte Ed25519 key |
00000210 |
Wi-Fi Config | Write | UTF-8 JSON |
00000211 |
Wi-Fi Status | Read / Notify | UTF-8 JSON |
00000600 |
Upload | Write Without Response | Binary |
Command format
Subscribe to Command notifications, then send the framed request.
Request example:
{"op":"factory_reset","params":{"confirm":true}}
Successful response example:
{"op":"factory_reset","ok":true}
token is optional in the request and forwarded to HTTP routes. Responses may
include data and an error string; absent fields are omitted.
Framing: [index:u8][total:u8][JSON fragment]. Index starts at zero; even
single-frame messages include the header. Current response frames use a fixed
247-byte size budget.
Operations
| Group | Operations |
|---|---|
| Device | identify, reboot, factory_reset |
| Network | network_status, wifi_scan, wifi_connect |
| Setup | status, versions, bootstrap, claim, gateway configuration/topology |
| Thread/device management | OTBR, commissioning, registration, settings |
| Updates | ota_begin, ota_finalize, ota_cancel, Rugix update/status |
Current limitations
identifyreturns success without physically identifying the gateway.- Factory reset removes setup state, not all gateway configuration.
- Outer
okfollows HTTP status and can contradict nesteddata.ok. - Wi-Fi status mapping and binary upload session wiring are broken.
- GATT permissions do not require encryption; local device operations bypass token checks.
2. Firmware Air BLE specification — current
Overview
BLE provides identification, Thread provisioning, actuator control, pressure configuration, and Nordic firmware updates. Protocol version: 1.
Characteristics
| Prefix | Name | Access | Encoding |
|---|---|---|---|
00000100 |
Device Info / capabilities | Read | UTF-8 JSON |
00000101 |
Device Status | Read / Notify | UTF-8 JSON |
00000102 |
Command | Write / Notify | Plain UTF-8 JSON |
00000110–00000113 |
Serial / type / firmware / model | Read | UTF-8 |
00000114 |
Protocol version | Read | Exactly 2 bytes, uint16LE |
00000200 |
Thread Config | Read / Write / Write Without Response | UTF-8 JSON |
00000201 |
Thread Status | Read / Notify | UTF-8 JSON |
00000300 |
Fan State | Read / Write / Notify | UTF-8 JSON |
00000400 |
Pressure Config | Read / Write / Write Without Response | UTF-8 JSON |
00000401 |
Pressure Status | Read / Notify | UTF-8 JSON |
Command format
Subscribe to Command notifications, then write an unframed request. Parameters are top-level fields.
Request example:
{"command":"identify","duration_sec":5}
Successful response example:
{"command":"identify","ok":true,"data":null,"error":null}
Operations
| Group | Operations |
|---|---|
| Device | identify, reboot, factory_reset |
| Dampers | setDamper, setDamperPct, getDamper, getDamperPct, homeDamper, testDamper |
| Wi-Fi builds | wifiScan, wifiConnect, wifiDisconnect, wifiStatus |
| RTC | getDeviceTime, setDeviceTime, getRtcSerial, setRtcSerial |
identify.duration_sec: integer, default 5, range 1–30. Factory reset
requires confirm:true, resets OpenThread state, and reboots.
Fan updates use {"fans":[{"index":0,"percent":50}]}. Pressure configuration
accepts partial field updates.
OTA: standard MCUmgr SMP service,
8D53DC1D-1DB7-4CD3-868B-8A527460AA84.
Current limitations
- Command storage permits 319 bytes, but ordinary writes/notifications remain MTU-limited.
- The configured MTU ceiling is 128: notification payload budget is at most 125 bytes. Larger responses/status can fail.
- Capabilities can overclaim hardware/backend support.
- GATT permissions do not require encryption.
docs/pressure.mdreferences outdated characteristics; actual pressure UUIDs are400/401.
3. Unified Vibrant BLE specification — proposed
Overview
One shared identity and application contract, with explicit transport and device-specific profiles.
Characteristics
Preserve the existing UUIDs:
| Profile | Required characteristics |
|---|---|
| Common | Info 100, Status 101, Command 102, scalar identity 110–114 |
| Gateway | Image/key 115–117, Wi-Fi 210/211, upload 600 when functional |
| Thread endpoint | Config 200, Status 201 |
| Fan control | Fan State 300 |
| Pressure control | Config 400, Status 401 |
| Nordic OTA | Standard MCUmgr SMP service |
Capabilities describe working features, not merely registered callbacks or characteristics.
Command format
Use the original shared specification's command/params envelope on every device.
Request:
{"command":"identify","params":{"duration_sec":5}}
Compact successful response:
{"command":"identify","ok":true}
["identify", {}]
command: required operation name, echoed in the response.params: object; omitted means{}.ok: actual operation success—not just transport acceptance.data: include when the operation returns a result; otherwise omit or usenull. Operation-specific required result fields must not be omitted.error: non-empty failure string whenok:false; omit or usenullon success.- Clients accept omitted and
nulloptional fields equivalently. JSON whitespace and key order have no meaning; senders may use compact JSON.
Common operations
| Operation | Parameters | Behavior |
|---|---|---|
identify |
duration_sec: integer, default 5, range 1–30 |
Physically identify the device |
reboot |
None | Acknowledge before reboot |
factory_reset |
confirm:true |
Clear documented device-owned configuration and reboot |
Device-specific operations remain extensions, with their own parameter/result tables.
Transport, status, and security
- Plain mode: complete JSON writes and notifications; responses must fit the negotiated notification budget.
- Chunked mode: selected through
chunked_command;[index:u8][total:u8][fragment], with fragment budget ATT MTU − 5. - Framing never changes the JSON envelope. Validate ordering, consistent totals, size limits, and assembly timeout; never silently truncate.
- Clients subscribe before sending and allow one outstanding command per connection.
- Common health fields: required
readyanderror_code; optionaluptime_secanderror_message. Omit an empty error message or sendnull; clients ignore unknown extension fields. - Scalar identity is preferred; legacy Info is the fallback. Malformed scalar identity is an error, not a reason to silently switch formats.
- Credentials require an authenticated, encrypted link; sensitive writes require authorized access.
- Version-1 adapters explicitly handle gateway framed
op/paramsversus Firmware Air plaincommand/flat fields.
Resource limits — contract requirements
- Each device profile documents maximum encoded request/response bytes and string/array lengths, including worst-case UTF-8 and JSON escaping. Gateway limits are not minimum requirements for Nordic devices.
- Buffer capacity and wire limits are different: current firmware's 320-byte command buffer permits 319 JSON bytes, but does not make a 319-byte notification possible. Notifications must also fit the negotiated ATT budget.
- Reject oversized requests before applying changes. Never truncate valid JSON, silently drop required fields, or report success for an incomplete operation.
- Chunking is capability-selected, not mandatory for every device. When supported, bound the complete message as well as individual frames; splitting a message does not remove its reassembly memory cost.
- Keep partial configuration updates so clients can send small independent updates. Clients must not assume those separate updates form one atomic change.
- Discover optional profiles from capabilities; do not require Nordic devices to implement gateway operations or gateway OTA. Keep Nordic OTA on MCUmgr SMP.
The main unification change is the command envelope and its semantics—not making every device expose identical features.
telemetry payload
ERV example, can be partial
{
"ex_pm10": float,
"su_pm10": float
}