UMEC MQTT Connector Protocol v3
UMEC MQTT v3 is the public device-to-platform contract for UMEC Space Light. It must not share the internal Manager MQTT API topic model or credentials.
Quick start
Before connecting, an operator creates the device identity, its ACL, device credentials and asset mapping. Never put credentials in Git, images, logs or examples.
- Obtain
tenant,deviceId, a dedicated username/password and TLS details from the operator. - Connect to
mqtt.iot.umec.space:8883with TLS 1.2+; anonymous access is disabled. - Subscribe to
<tenant>/<deviceId>/p2d. - Publish inventory and state only to
<tenant>/<deviceId>/d2pusing QoS 1 andretain=false. - Process P2D
config,commandandack; retain the command correlation ID and send the resulting state echo.
Verification: the broker accepts the TLS connection, the D2P message passes JSON Schema validation and the mapped asset receives the expected state. See the normative reference for the complete contract.
Transport and topics
| Item | Requirement |
|---|---|
| Endpoint | mqtt.iot.umec.space:8883 |
| Transport | MQTT over TLS, TLS 1.2 or newer |
| Authentication | dedicated username/password; anonymous access is prohibited |
| Topic shape | <tenant>/<deviceId>/<d2p|p2d> |
| QoS | 1 for inventory, state, config, command and ack |
| Retain | always false |
| Maximum payload | 1 MiB |
| Telemetry batch | at most 1000 sensor/parameter/error points |
d2p means device-to-platform: the device has write permission only. p2d means platform-to-device: the device has read permission only.
# Receive platform-to-device messages; no real secret is included here
mosquitto_sub -h mqtt.iot.umec.space -p 8883 \
--cafile /path/to/ca.pem \
-u '<device-username>' -P '<device-password>' \
-q 1 -t '<tenant>/<deviceId>/p2d'
First D2P state message
Every v3 request is a JSON-RPC 2.0 object with numeric id, method and params.timestamp (Unix epoch milliseconds).
{
"jsonrpc": "2.0",
"id": 1001,
"method": "state",
"params": {
"timestamp": 1760000000000,
"device": {"id": "<deviceId>", "sensors": [{"id": "temperature", "value": 21.6}]}
}
}
mosquitto_pub -h mqtt.iot.umec.space -p 8883 \
--cafile /path/to/ca.pem \
-u '<device-username>' -P '<device-password>' \
-q 1 -r false -t '<tenant>/<deviceId>/d2p' -m @state.json
Use state for deltas and full snapshots. The published v3 schema has no separate snapshot discriminator: use only the agreed device/modules model and do not add undocumented fields.
Incoming P2D messages
| Method | Direction | Purpose |
|---|---|---|
config | P2D | Configuration published by the platform for the device |
command | P2D | Control command with a numeric correlation ID |
ack | P2D | Acknowledgement or command-flow result |
The device never publishes P2D and never subscribes to other devices' D2P topics. Wildcard topics are not allowed.
Command lifecycle
- The platform publishes
commandto P2D with a JSON-RPCid. - The device validates method, timestamp and its allowed controls.
- The same command ID for a
tenant/deviceIdpair is not executed twice within 300 seconds. acceptedmeans queue admission.appliedis confirmed only by the matching state echo. On failure return a JSON-RPC error; never mask an error as a successful ACK.- Apply a bounded timeout/retry policy. Retry an idempotent operation with the same correlation ID only; do not create a new ID to hide an unknown result.
Provisioning and revocation
Provisioning is performed by an operator or automation with the required rights:
- Create the physical identity and v3 logical device identity.
- Grant ACL only for
tenant/deviceId/d2p(device write) andtenant/deviceId/p2d(device read). - Create separated server principals: ingest reads D2P and publisher writes P2D.
- Create asset mapping and verify that inventory/state reaches the intended asset.
- Deliver credentials outside Git and logs, then verify the TLS connection.
- If credentials are compromised, revoke credentials and ACL immediately, issue a new pair and repeat verification.
Node.js
import mqtt from 'mqtt';
const client = mqtt.connect('mqtts://mqtt.iot.umec.space:8883', {
username: process.env.UMEC_MQTT_USERNAME,
password: process.env.UMEC_MQTT_PASSWORD,
protocolVersion: 4,
rejectUnauthorized: true
});
client.on('connect', () => {
client.subscribe('<tenant>/<deviceId>/p2d', {qos: 1});
client.publish('<tenant>/<deviceId>/d2p', JSON.stringify({
jsonrpc: '2.0', id: 1001, method: 'state',
params: {timestamp: Date.now(), device: {id: '<deviceId>'}}
}), {qos: 1, retain: false});
});
WirenBoard
Create a non-secret publisher package with the bridge helper. It emits templates without Wi-Fi secrets, MQTT passwords, service tokens or private keys.
npm run wirenboard:publisher-setup -- \
--tenant-id '<tenant>' --physical-device-id '<physical-device-id>' \
--sensor-ids temperature --command-ids cmd-1
Compatibility
| UMEC MQTT v3 | Internal Manager MQTT API | |
|---|---|---|
| Purpose | public UMEC device connection | internal Manager API for provisioned controls |
| Topics | <tenant>/<deviceId>/d2p and p2d | internal attribute-event topics |
| Authentication | v3 broker ACL | Manager service client |
| Credentials | v3 device/server principals | separate service identity |
| Mixing | prohibited | prohibited |
Do not use an internal Manager topic as an alternative public D2P/P2D broker. It receives no public v3 broker ACL.
Diagnostics
| Symptom | Cause | Safe correction |
|---|---|---|
| Cannot connect | TLS, port or credentials are wrong | verify hostname, CA and issued identity; never disable TLS verification |
| Publish rejected | wrong direction, QoS/retain or ACL | use D2P, QoS 1, retain false and request ACL verification |
| Command repeats | duplicate ID policy not persisted | deduplicate id for 300 seconds and confirm with a state echo |
| No history | state failed schema/limits or asset mapping | validate JSON, keep batch ≤1000 points and check mapping |
Contract and conformance material: JSON Schema, reference.