MQTT Migration Guide
This guide describes the recommended process for migrating MQTT integrations from the PANS PRO RTLS stack to the LEAPS RTLS stack. Teams may modernise their existing applications to speak the LEAPS topics directly or deploy a temporary/permanent bridge that performs the translation on their behalf. It consolidates the documentation found in:
PANS PRO RTLS:
LEAPS RTLS:
1. Scope & Inventory
The table below consolidates the MQTT traffic described in the PANS PRO and LEAPS RTLS connector guides. Use it as a baseline when planning migrations or validating completeness.
Domain |
PANS PRO topics (QoS / retain) |
Payload focus |
LEAPS RTLS topics (QoS / retain) |
Payload focus |
Notes |
|---|---|---|---|---|---|
Server lifecycle |
{prefix}/server server status (QoS 1 / retained ✓)<br>`{prefix}/server` requests (QoS 1 / retained ✗) |
Server status (empty/min JSON)<br> ServerMessage requests |
{prefix}/server/status (QoS 1 / retained ✗)<br>`{prefix}/server/request` (QoS 1 / retained ✗) |
leaps_api.server_message (state, version, nodeList, request, networks) |
Consumers subscribe to {prefix}/server/status; server LWT publishes {“state”:”DISCONNECTED”}. |
Gateway status & config |
{prefix}/gateway/{deviceId}/uplink (QoS 1 / retained ✓)<br>`{prefix}/gateway/{deviceId}/downlink` (QoS 1 / retained ✗) |
GatewayStatusAndConfig (networkId, bridgeNodeId, configuration) |
{prefix}/{networkId}/gateway/uplink/status/{deviceId} (QoS 1 / retained ✗)<br>`{prefix}/{networkId}/gateway/uplink/config/{deviceId}` (QoS 1 / retained ✗)<br>`{prefix}/{networkId}/gateway/downlink/config/{deviceId}` (QoS 1 / retained ✗) |
Insert {networkId} from legacy networkId; split status vs configuration topics. |
|
Node status & config |
{prefix}/node/{deviceId}/uplink/status (QoS 1 / retained ✓)<br>`{prefix}/node/{deviceId}/uplink/config` (QoS 1 / retained ✓)<br>`{prefix}/node/{deviceId}/downlink/config` (QoS 1 / retained ✗) |
{prefix}/{networkId}/{nodegateway}/uplink/status/{deviceId} (QoS 1 / retained ✗)<br>`{prefix}/{networkId}/{nodegateway}/uplink/config/{deviceId}` (QoS 1 / retained ✗)<br>`{prefix}/{networkId}/{nodegateway}/downlink/config/{deviceId}` (QoS 1 / retained ✗) |
Map nodeType into anchor_config/tag_config; remove redundant networkId. |
||
Data & service channels |
{prefix}/node/{deviceId}/uplink/data (QoS 1 / retained ✗)<br>`{prefix}/node/{deviceId}/downlink/data` (QoS 1 / retained ✗)<br>`{prefix}/node/{deviceId}/uplink/service` (QoS 1 / retained ✗)<br>`{prefix}/node/{deviceId}/downlink/service` (QoS 1 / retained ✗) |
NodeDataUplink with Base64 payloads with optional superFrameNumber <br> NodeDataDownlink with Base64 payloads with optional overwrite <br> NodeServiceUplink / NodeServiceDownlink TLV messages |
{prefix}/{networkId}/{nodegateway}/uplink/data/{deviceId} (QoS 1 / retained ✗)<br>`{prefix}/{networkId}/{nodegateway}/downlink/data/{deviceId}` (QoS 1 / retained ✗)<br>`{prefix}/{networkId}/{nodegateway}/uplink/service/{deviceId}` (QoS 1 / retained ✗)<br>`{prefix}/{networkId}/{nodegateway}/downlink/service/{deviceId}` (QoS 1 / retained ✗) |
LEAPS omits superFrameNumber; keep timestamps and overwrite flags. |
|
Location streams |
{prefix}/node/{deviceId}/uplink/location (QoS 0 / retained ✓) |
NodeLocationUplink (Position), superFrameNumber) |
{prefix}/{networkId}/node/uplink/location/{deviceId} (QoS 0 / retained ✗) |
leaps_api.location (node_location, statistics) |
Wrap coordinates inside location and drop superFrameNumber. |
1. Schema Alignment and Translation Recipes
The following sections document the translation requirements for each domain. Use them when refactoring publishers/consumers or building an adapter.
2.1 Server Lifecycle
PANS topics:
Uplink server status:
{prefix}/server(retained, QoS 1) publishing an empty or minimal JSON payload when the server is online; broker LWT sends the same topic with an empty payload on disconnect (see Description).Downlink commands:
{prefix}/servercarryingServerMessagerequests such as{"request":"REFRESH_TOPICS"}(see Description).
LEAPS topics:
Uplink status:
{prefix}/server/status(not retained, QoS 1) conveyingleaps_api.server_messagepayloads (see Description and leaps_api.server_message).Downlink requests:
{prefix}/server/request(not retained, QoS 1) using the sameleaps_api.server_messageschema for requests (See Description).
Translation steps:
Subscriber change: Update consumers to subscribe to
{prefix}/server/status(uplink) instead of{prefix}/server. Expect JSON payloads with at leaststateand handle disconnect events when{"state":"DISCONNECTED"}is received.Publisher change: Configure the server (or bridge) to emit a server status payloads such as
{"state":"CONNECTED"}to{prefix}/server/statusand set the broker LWT on that topic to publish{"state":"DISCONNECTED"}.Request routing: Move any command publications to
{prefix}/server/requestand encode them as{"request":"PUBLISH_ALL_TOPICS"}with optionalnetworksfilters.
Before / After:
// PANS server status {} // LEAPS server status { "state": "CONNECTED", "version": "2.2.8" }
2.2 Gateway Status and Configuration
PANS topics:
{prefix}/gateway/{deviceId}/uplink(retained, QoS 1) reportingGatewayStatusAndConfigpayloads with fields such asnetworkId,bridgeNodeId,version,uwb, and nestedconfiguration(see Description).{prefix}/gateway/{deviceId}/downlinkfor configuration updates (see Description).
LEAPS topics:
{prefix}/{networkId}/gateway/uplink/status/{deviceId}(not retained, QoS 1) carryingleaps_api.status(see Description).{prefix}/{networkId}/gateway/uplink/config/{deviceId}and{prefix}/{networkId}/gateway/downlink/config/{deviceId}usingleaps_api.node_config(Description and Description).
Translation steps:
Introduce the
{networkId}path segment (using the value previously found in the PANSnetworkIdfield). Remove the now-duplicatenetworkIdfield from the payload.Map gateway health indicators:
present,downlink,uwb,batt, andtempcan be copied directly intoleaps_api.status. If PANS includedbridgeNodeIdor routing diagnostics, log or expose them via observability channels because LEAPS does not have one-to-one fields.Restructure
configurationinto theleaps_api.node_configshape:ipAddress[],ipMask[],ipGateway[]→inet.ip[].addr,inet.ip[].mask,inet.ip[].gatewaydns[]→inet.dnsinterface→inet.ifacetls→inet.tlsserver/port→inet.server.host/inet.server.portdhcp→inet.dhcpOptional Wi-Fi fields →
wifi
If firmware
versiondetails are required, subscribe them through{prefix}/server/statusor a management database; LEAPS gateway config/topic does not transport release metadata.
Before / After:
// PANS gateway uplink { "networkId": 1, "uwb": "CONNECTED_BH", "configuration": { "ipAddress": ["10.0.1.10"], "ipMask": ["255.255.255.0"], "dns": ["8.8.8.8"], "interface": "ETHERNET", "tls": "OFF", "server": "10.0.1.13", "port": 7777 } } // LEAPS gateway uplink (status + config pair) { "present": true, "downlink": true, "uwb": "CONNECTED_BH", "timestamp": "1681398574409278" } { "label": "DW590F-nWIFI", "uwb_mode": "UWB_MODE_ACTIVE", "fw_update": true, "inet": { "ip": [ {"addr": "10.0.1.10", "mask": "255.255.255.0"} ], "dns": ["8.8.8.8"], "iface": "ETHERNET", "tls": "OFF", "dhcp": true, "server": {"host": "10.0.1.13", "port": 7777} } }
2.3 Node Configuration and Status
PANS topics:
{prefix}/node/{deviceId}/uplink/status(retained, QoS 1) withNodeStatusUplinkpayloads (See Description).{prefix}/node/{deviceId}/uplink/configand{prefix}/node/{deviceId}/downlink/configsharingNodeConfigurationstructures (see Description and and see Description).
LEAPS topics:
{prefix}/{networkId}/{node\|gateway}/uplink/status/{deviceId}carryingleaps_api.status(See Description).{prefix}/{networkId}/{node\|gateway}/{uplink|downlink}/config/{deviceId}usingleaps_api.node_config(See Description).
Translation steps:
Insert
{networkId}and the device role (nodeorgateway) into the topic path; remove redundantnetworkIdornodeTypeidentifiers from the payload.Map shared fields directly:
present,downlink,uwb,batt,batt_state,temp, andtimestampmatch one-to-one inleaps_api.status.Convert configuration objects:
configuration.label→labelnodeType→ choose between populatinganchor(for anchors/gateways) ortag(for tags); absence of a section implies the other roleble,leds,uwbFirmwareUpdate→ble,leds,fw_updateanchor.position(x/y/z/quality) →anchor.locationanchor.routingConfig(ROUTING_CFG_*) →anchor.routing(ROUTING_*enum)anchor.routingStatushas no LEAPS equivalent; surface via monitoring or dropanchor.initiator→anchor.initiatorTag settings (
TagConfiguration) →tagfields (location_engine,low_power,stationary_detection,update_rate_*)
Carry timestamps forward; ensure they are strings or integers consistent with LEAPS examples (microseconds).
Before / After:
// PANS node config { "configuration": { "label": "DW0F07", "nodeType": "ANCHOR", "ble": true, "leds": true, "uwbFirmwareUpdate": true, "anchor": { "initiator": true, "position": {"x": 0, "y": 0, "z": 0, "quality": 0}, "routingConfig": "ROUTING_CFG_OFF" } } } // LEAPS node config { "label": "DW0F07", "uwb_mode": "UWB_MODE_ACTIVE", "ble": true, "leds": true, "fw_update": true, "anchor": { "initiator": true, "location": {"x": 0.0, "y": 0.0, "z": 0.0, "quality": 0}, "routing": "ROUTING_OFF" } }
2.4 Uplink Data and Service Channels
PANS topics:
{prefix}/node/{deviceId}/uplink/dataand{prefix}/node/{deviceId}/downlink/datacarrying base64 payloads plussuperFrameNumber(See Description).{prefix}/node/{deviceId}/uplink/serviceand{prefix}/node/{deviceId}/downlink/servicetransporting TLV command acknowledgements (see Description, see Description).
LEAPS topics:
{prefix}/{networkId}/{node\|gateway}/uplink/data/{deviceId}and corresponding downlink topics forleaps_api.user_data(See Description, Description).{prefix}/{networkId}/{node\|gateway}/uplink/service/{deviceId}and downlink equivalents forleaps_api.service_data(Description).
Translation steps:
Add
{networkId}and the device role to the topic path; dropsuperFrameNumberunless an application explicitly requires it (LEAPS does not define this field—store it in analytics or embed it intoservice_dataif necessary).Preserve
dataas base64; ensureoverwritesemantics follow LEAPS expectations (optional boolean in both uplink and downlink payloads).Translate service message
typevalues to the LEAPS enum names:TLV_API_CMD,TLV_API_ACK,TLV_API_NACK(See tag_config).Ensure timestamps stay in microseconds and remain optional fields (
timestamp).
Before / After:
// PANS uplink data { "data": "ASNFZ4mrze8=", "superFrameNumber": 1028, "timestamp": "1679495612282922" } // LEAPS uplink data { "data": "ASNFZ4mrze8=", "timestamp": "1679495612282922" }
2.5 Location Streams
PANS topics:
{prefix}/node/{deviceId}/uplink/locationwithNodeLocationUplinkpayloads (see Description).LEAPS topics:
{prefix}/{networkId}/node/uplink/location/{deviceId}publishingleaps_api.locationpayloads (see Description).Translation steps:
Add
{networkId}to the topic and removenetworkIdfields from the body.Nest position coordinates inside the
locationobject expected by LEAPS:position.x→location.x, etc. If PANS suppliedKernelPositionbytes, convert them to floating-point meters before publishing.Move optional quality metrics into LEAPS statistics fields when available (
sd_x,sd_y,sd_z,r95,toa). Values without direct equivalents can be stored in application-specific telemetry streams.Drop
superFrameNumberor repurpose it within analytics; LEAPS does not define that field inleaps_api.location.
Before / After:
// PANS location { "position": { "x": 3.25238609, "y": -0.00895162672, "z": 0.42510426, "quality": 21 }, "superFrameNumber": 1144, "timestamp": "1679495047880989" } // LEAPS location { "location": { "x": 3.25238609, "y": -0.00895162672, "z": 0.42510426, "quality": 21 }, "timestamp": "1679495047880989" }
1. Environment Updates
Broker configuration: Update topic ACLs, retained flags, and LWT settings to accommodate the LEAPS namespace. Ensure
{prefix}/server/statusand{prefix}/server/requestare available and that QoS requirements match the LEAPS documentation.Client endpoints: Point gateways and management tools to the LEAPS server endpoints. Adjust client-side MQTT settings (QoS, retain) to match the new specifications.
Documentation: Record any broker-level changes so that future deployments reference the LEAPS expectations instead of the legacy ones.
4. Cutover & Validation
Staging rehearsal: Run the full traffic set through a staging LEAPS deployment. Confirm that consumers process the new topics without schema errors.
Production cutover: Schedule the switch once staging passes. Monitor the broker, adapter logs, and downstream applications for discrepancies.
Fallback plan: Maintain the adapter or dual-publish strategy until metrics show stable consumption on the LEAPS topics.
Alerting updates: Modify monitoring rules to inspect the new topics (e.g., checking
state != "CONNECTED"on{prefix}/server/status).
5. Post-Migration Cleanup
Retire PANS PRO topic publishers and remove obsolete ACLs from the broker.
Decommission temporary adapters once every producer and consumer speaks native LEAPS.
Archive the translation recipes and sample payloads. They remain valuable for onboarding and audits.
Update team runbooks and diagrams to reflect the LEAPS RTLS architecture.