Using MQTT Nodes in Detail
The gateway runs its own HiveMQ broker on the same machine (default port 1883, TLS 1884). This is the standard pattern when connecting to external SCADA / cloud IoT systems.
Broker connection details on 2026.05+ boxes
- Broker URL:
tcp://127.0.0.1:1883(plain) /ssl://127.0.0.1:1884(TLS) - Username / Password:
mqtt.server.user/mqtt.server.passwordinapp.properties— on production boxes these are random per box (check/etc/kopens/credentials.txt). The entrypoint automatically syncs the HiveMQ auth.properties. - MQTT 5 support (HiveMQ 2025.4): retained / will / session expiry / shared subscriptions, full feature set.
- Shares the same broker as Sparkplug B — you can subscribe to
spBv1.0/#at the same time for monitoring.
1. Node Types
| Node | Purpose |
|---|---|
mqtt in | Subscribes to a topic — the flow starts each time a message arrives |
mqtt out | Publishes a message |
2. Broker (Server) Configuration — Create Once, Shared by All Nodes
Double-click the mqtt in or mqtt out node → pencil icon to the right of the Server field → new broker configuration.
| Tab | Item | Recommended Value |
|---|---|---|
| Connection | Server | 127.0.0.1 (the gateway's own HiveMQ) or an external broker IP |
| Port | 1883 (8883 for TLS) | |
| Client ID | Auto-generated if left blank. A fixed ID is recommended in production (e.g. edge-<gateway-id>-flow1) | |
| Keep alive | 60 seconds recommended | |
| Use TLS | ON when connecting to an external cloud | |
| Security | Username/Password | When broker authentication is used |
| Messages | LWT (Last Will) | edge/<id>/status topic + payload offline — automatic notification when the gateway dies unexpectedly |
| Messages | Birth | On connect, publishes online to edge/<id>/status with retain |
3. Publishing (mqtt out) — Scenario: Send All tag Values to the Cloud
inject (1s) ──▶ 태그값 읽기 ──▶ change (topic 만들기) ──▶ mqtt out
change node:
| Action | Property | To |
|---|---|---|
| Set | msg.topic | plant/${msg.payload.tag_id}/value (J-Expression ${...} or mustache) |
| Set | msg.payload | { "ts": $millis(), "v": msg.payload.value, "q": msg.payload.value_read_status } (JSONata) |
mqtt out node settings:
| Item | Value |
|---|---|
| Topic | (leave blank → msg.topic is used) |
| QoS | 1 (guaranteed at-least-once delivery) — 0 is fine for ordinary telemetry |
| Retain | false (real-time values) — use true for stateful data |
4. Subscribing (mqtt in) — Scenario: Write to a tag from an External Command
mqtt in (plant/+/cmd) ──▶ change (tagId/value 추출) ──▶ 태그값 쓰기
mqtt in:
| Item | Value |
|---|---|
| Topic | plant/+/cmd (wildcard + = one level) |
| QoS | 1 |
| Output | parsed JSON object — the payload is automatically converted into an object |
change:
| Action | Property | To |
|---|---|---|
| Set | msg.tagId | msg.topic.split('/')[1] (JSONata) |
| Move | msg.payload.value → msg.payload | (feed directly into the write node) |
With this setup, an external SCADA only has to publish {"value":"1"} to the plant/TAG_VALVE_01/cmd topic and the gateway writes that value to the PLC.
5. Common Pitfalls
| Symptom | Cause / Solution |
|---|---|
| No messages ever arrive | Typo in the topic wildcard (#/+). Check the topic tree with a separate tool such as MQTT Explorer |
| Client keeps disconnecting | Client ID collision (another client is connecting with the same ID) — assign a unique ID |
| Retained messages pile up endlessly | Publishing with retain true to the same topic every time. Use retain only for stateful data (online/offline, last alarm) |
| Message order looks wrong | A limitation of QoS 0. Use QoS 1+ when order matters |
6. Next Steps
- OPC-UA Nodes in Detail — communicating with external OPC-UA servers
- Sparkplug B Nodes in Detail — automatic handling of the Sparkplug spec
- IIoT Example Collection