# MQTT Integration (Connecting Stations Live)

## What is it?

Stations that speak MQTT can deliver their measurements directly to
TestLabIQ — without a CSV detour and without your own REST script. The app
connects to your MQTT broker (e.g., Mosquitto, EMQX, HiveMQ) and accepts all
messages on a topic. Processing and tenant isolation are identical to REST
ingestion: the station API key decides which organization the values belong
to.

## How to use it

1. **Configure the broker (operator/on-premise):** Set `MQTT_BROKER_URL` in
   the app's environment (e.g., `mqtts://broker.example:8883`), optionally
   `MQTT_USERNAME`/`MQTT_PASSWORD`, and `MQTT_TOPIC` (default
   `testlabiq/ingest`). Without `MQTT_BROKER_URL`, MQTT ingestion is
   completely disabled.
2. **Get the station API key:** On the station's detail page (as with REST
   ingestion). The key identifies **both** the station and the organization.
3. **Have the station publish:** JSON on the topic (QoS 1 recommended), same
   format as the REST push plus `apiKey`:

   ```json
   {
     "apiKey": "<station API key>",
     "sequenceItemId": "<uuid>",
     "measurements": [
       { "timestamp": "2026-07-20T08:00:00Z", "channelName": "U_in",
         "value": 12.1, "unit": "V" }
     ]
   }
   ```

   The key deliberately lives in the payload and **not in the topic**: topics
   are visible everywhere in broker logs and ACLs — a secret has no business
   being there.
4. **Live tracking:** Incoming values appear immediately in the **"Live
   measurements"** section — on the running test case's page (only that test
   case's values) or on the station's detail page (all values for that
   station, regardless of test case/sequence). This view is a pure read
   channel: station → app → browser; there are deliberately no commands sent
   back to the station.
5. **Switch between tiles and chart:** By default the view shows tiles — the
   latest value per measurement channel (color-checked against the limits,
   if defined) plus min/max since the page was opened. The toggle in the
   top-right switches to a line chart that plots several measurement channels
   at once (e.g. voltage, current, and temperature in one chart) — each
   channel in its own color, individually shown/hidden by clicking its legend
   entry. The time axis can be set to a fixed window from 1 minute to 6 hours,
   or to **Auto**, which continuously adapts to the data available.
6. **Checking:** MQTT has no response back to the station. Whether values
   arrived is shown by the **delivery log**: retrievable via
   `GET /api/v1/ingestion/deliveries` (see [REST API](https://www.testlabiq.com/en/help/rest-api)) or by
   asking the support assistant "Why aren't my measurements arriving?".

## Common issues

- **Values don't arrive, nothing in the delivery log.** Either the message
  never reaches the app (check the broker/topic: does the station publish to
  the configured topic? Is `MQTT_BROKER_URL` set?), or the `apiKey` in the
  payload is invalid — in that case the message can't be assigned to any
  organization and only shows up in the operator's server log.
- **Delivery log shows "Sequence item not found…".** The `sequenceItemId`
  doesn't belong to this station's organization, or doesn't exist. Check the
  ID — it's on the test execution page of the respective test case.
- **Delivery log shows "Invalid payload…".** Required fields are missing or
  have the wrong type (`timestamp` as ISO-8601, `value` as a number). The
  message names the affected fields.
- **Duplicate values.** Identical measurement points are skipped
  (`duplicates` in the delivery log). Not an error — this makes QoS-1 retries
  after a reconnect harmless.
- **Values arrived delayed.** On a connection drop, the broker buffers (QoS
  1, persistent session) and delivers once the app reconnects. Nothing to do.
- **The live view shows nothing even though values arrive.** The view only
  shows values for **this** test case (check `sequenceItemId` in the payload)
  and is only visible while the test case isn't completed yet. After
  completion, the measurement results table is what counts, not the live
  stream.
- **The chart only shows a slice of a large time window.** The lookback is
  capped at 24 hours so a single request can't load a station's entire
  measurement history. For older analysis, use the measurement results table
  or the report instead of the live view.

---

Source: https://www.testlabiq.com/en/help/mqtt-integration
