# Station Simulator (Testing Data Reception)

## What is it?

The station simulator is a standalone testing tool that mimics a real test
station: it continuously generates measurements and sends them to TestLabIQ
via exactly the same paths real hardware uses — **REST push**
(`POST /api/v1/measurements`) or **MQTT** (JSON on a broker topic). This lets
you test the app's data reception without connecting a physical station: Do
values arrive? Do they show up live on the test case page? Is the delivery
log correct?

It lives in the monorepo under `apps/simulator` and has its own small
dashboard in the browser where you configure everything about the simulated
station — most importantly the **protocol** used to send.

> The simulator is a development and testing tool. It's deliberately **not**
> part of the product app and needs no login; like real hardware, it
> authenticates solely via the station API key.

## How to use it

1. **Start the app** you want to send to (e.g., `pnpm --filter @lab-mgmt/web dev`
   on port 4000). For MQTT, also provide a broker and start the app with
   `MQTT_BROKER_URL` (see [MQTT Integration](https://www.testlabiq.com/en/help/mqtt-integration)). The REST path
   needs **no** broker.

   > **Broker via Docker (optional):** The repo ships an opt-in Mosquitto
   > broker profile. To test with MQTT, start the app together with the
   > broker and give it the broker address:
   >
   > ```bash
   > MQTT_BROKER_URL=mqtt://mqtt:1883 docker compose --profile prod --profile mqtt up -d
   > ```
   >
   > Locally without Docker, a broker works the same way:
   > `mqtt://localhost:1883`.
2. **Start the simulator:**

   ```bash
   pnpm --filter @lab-mgmt/simulator dev
   ```

   Then open the dashboard: <http://localhost:4100> (port changeable via
   `SIM_PORT`).
3. **Get the station API key:** In the app, on the station's detail page. The
   key identifies **both** the station and the organization.
4. **Get the sequenceItemId:** The UUID of the running sequence item is on
   the test execution page of the respective test case.
5. **Configure in the dashboard:**
   - **Protocol:** *REST push* or *MQTT*.
     - REST: **App URL** (e.g., `http://localhost:4000`).
     - MQTT: **broker URL**, **topic** (default `testlabiq/ingest`),
       optionally username/password.
   - Enter the **station API key** and **sequenceItemId**.
   - Choose the **send interval** (ms) and **measurement points per
     channel/send**. More than one point spreads the timestamps across the
     interval — producing a curve instead of a single value.
   - Define **measurement channels**: name (must match the test case, e.g.,
     `U_in`), unit, waveform, value range (min/max), period, and noise.
6. **Sending:**
   - **Send once** sends a single batch — good for a quick check.
   - **Start** begins continuous sending at the configured interval, **Stop**
     ends it.
7. **Checking:** On the right, the dashboard shows send operations, sent
   measurement points, values accepted via REST, duplicates, and errors, plus
   a log of recent sends. In the app, values appear live on the test case page
   and in the **delivery log** (`GET /api/v1/ingestion/deliveries`).

## Waveforms

| Signal | Behavior |
|---|---|
| `sine` | sine wave between min and max over the period |
| `sawtooth` | linear rise min → max, then jump back |
| `ramp` | triangle min → max → min (e.g., a slowly heating soak test) |
| `square` | square wave, half period max, half period min |
| `random` | uniformly distributed random value within the band |
| `constant` | average of min and max |

Optional uniformly distributed **noise** (± amplitude) is added to every
value; the result stays within the [min, max] band.

## Defaults from the environment

So the simulator and app work together with no extra setup, the simulator
picks up — if set — the same environment variables as the app on startup:
`NEXT_PUBLIC_APP_URL` (REST target), `MQTT_BROKER_URL`, `MQTT_TOPIC`,
`MQTT_USERNAME`, `MQTT_PASSWORD`. Additionally: `SIM_PORT` (dashboard port,
default 4100), `SIM_API_KEY`, and `SIM_SEQUENCE_ITEM_ID` as presets.

## Common issues

- **REST reports 401 "Invalid API key".** The entered station API key is
  wrong (or was rotated). Get a new key from the station page.
- **REST reports 404 "Sequence item not found…".** The `sequenceItemId`
  doesn't belong to this station's organization, or doesn't exist.
- **REST connection failed.** Is the app running at the entered app URL?
  Check the port and scheme (`http://`).
- **MQTT: "connected = no" or publish errors.** Check the broker URL, port,
  and any credentials. MQTT has **no** response channel — whether values
  arrived is shown only by the app's **delivery log**, not by the simulator
  (it only confirms publishing).
- **Values arrive but don't show up live.** The channel name and
  `sequenceItemId` must match the currently running test case.

---

Source: https://www.testlabiq.com/en/help/station-simulator
