The openHAB MQTT binding connects openHAB to any MQTT broker in two layers: a broker Thing (a bridge that holds the connection: host, port, TLS, credentials) and one or more Generic MQTT Things underneath it, whose channels map individual topics to openHAB Items. Install the binding, add the broker, add a Thing with a channel per value, link Items — and every message on those topics updates your Items, while commands from the UI or rules are published back.
This tutorial walks through both the UI and the text-file configuration, shows how to parse JSON payloads, and how to verify every hop from the command line.
Prerequisites
- openHAB 4.x or newer with the MQTT Binding installed (Settings → Add-on Store → Bindings → MQTT).
- The JSONPath Transformation add-on if your devices send JSON (most do).
- A broker. openHAB does not include one, so run Mosquitto locally or use a hosted broker. The examples use
broker.connectmq.comwith TLS on port8883and test topics undertestmqtt/openhab/....
Step 1: the broker bridge Thing
In the UI go to Settings → Things → + → MQTT Binding → MQTT Broker and fill in:
| Parameter | Value | Notes |
|---|---|---|
| Broker Hostname/IP | broker.connectmq.com | No mqtt:// prefix |
| Broker Port | 8883 | 1883 without TLS |
| Secure Connection | on | Must match the port |
| Protocol | TCP | WebSockets is also available |
| MQTT Version | V5 | V3 means 3.1.1 |
| Client ID | openhab-home | Unique per broker |
| Username / Password | your broker credentials | |
| Keep Alive | 60 | Seconds |
Leave certificate and public-key pinning off when your broker uses a public certificate that renews automatically: pinning stores the first certificate it sees and fails after the broker rotates it. If you need to troubleshoot the TLS side, see testing a TLS connection.
The broker Thing should switch to ONLINE within a few seconds. If it shows OFFLINE - COMMUNICATION_ERROR, the status detail contains the reason — usually a port/TLS mismatch or wrong credentials.
You can also configure a Last Will (lwtTopic, lwtMessage), plus birth and shutdown messages, so other systems know whether openHAB is connected — useful when a dashboard or Node-RED depends on it.
Step 2: a Generic MQTT Thing and its channels
Add Generic MQTT Thing, choose the broker as its bridge, then add channels on the Channels tab. Each channel has a type and, at minimum, a state topic:
| Channel type | Item type | Typical payloads |
|---|---|---|
Text value (string) | String | Any text |
Number value (number) | Number (with unit) | 21.5 |
Percentage value (dimmer) | Dimmer | 0–100 |
On/Off switch (switch) | Switch | ON/OFF (configurable) |
Open/Close contact (contact) | Contact | OPEN/CLOSED |
Color value (color) | Color | r,g,b or h,s,b |
Rollershutter (rollershutter) | Rollershutter | UP/DOWN/STOP, percent |
| Date/Time, Location, Image | DateTime, Location, Image | ISO date, lat,lon, binary |
Trigger (trigger) | — (rules only) | Button events |
The important channel parameters:
- State Topic — openHAB subscribes here and updates the Item.
- Command Topic — openHAB publishes here when the Item receives a command. Use a different topic from the state topic (e.g.
.../set), otherwise your own commands come back as state updates. - Incoming Value Transformations — e.g.
JSONPATH:$.temperature. - Outgoing Value Format — a format string such as
%sor{"state":"%s"}to wrap commands in JSON. - Retained — publish commands as retained messages; see retained messages before turning this on.
- Custom On/Open Value and Custom Off/Closed Value — map device payloads such as
1/0ortrue/false. - Is Command (
postCommand) — treat incoming values as commands instead of state updates, so they trigger other bindings and rules.
The same configuration as text files
For version control, define the broker and Things in a .things file:
Bridge mqtt:broker:connectmq "ConnectMQ broker" [
host="broker.connectmq.com", port=8883, secure=true,
certificatepin=false, publickeypin=false,
protocol="TCP", mqttVersion="V5",
clientID="openhab-home", username="username", password="password",
keepAlive=60, qos=1
] {
Thing topic livingroom "Living room" [
availabilityTopic="testmqtt/openhab/livingroom/status",
payloadAvailable="online", payloadNotAvailable="offline"
] {
Channels:
Type number : temperature "Temperature" [
stateTopic="testmqtt/openhab/livingroom/sensor",
transformationPattern="JSONPATH:$.temperature", unit="°C" ]
Type number : humidity "Humidity" [
stateTopic="testmqtt/openhab/livingroom/sensor",
transformationPattern="JSONPATH:$.humidity", unit="%" ]
Type switch : lamp "Lamp" [
stateTopic="testmqtt/openhab/livingroom/lamp/state",
commandTopic="testmqtt/openhab/livingroom/lamp/set",
on="ON", off="OFF" ]
Type trigger : button "Wall button" [
stateTopic="testmqtt/openhab/livingroom/button" ]
}
}The channel UID is mqtt:topic:connectmq:livingroom:<channel>. Link Items to it:
Number:Temperature LivingRoom_Temperature "Temperature [%.1f %unit%]" { channel="mqtt:topic:connectmq:livingroom:temperature" }
Number:Dimensionless LivingRoom_Humidity "Humidity [%.0f %%]" { channel="mqtt:topic:connectmq:livingroom:humidity" }
Switch LivingRoom_Lamp "Lamp" { channel="mqtt:topic:connectmq:livingroom:lamp" }Two channels share one state topic and extract different JSON fields — the normal pattern for multi-sensor devices. The availabilityTopic marks the Thing OFFLINE when the device's Last Will fires.
Publishing from rules
The broker Thing exposes a publishMQTT action, handy for notifications or for talking to devices that have no Thing:
rule "Publish lamp changes as an event"
when
Item LivingRoom_Lamp changed
then
val mqtt = getActions("mqtt", "mqtt:broker:connectmq")
mqtt.publishMQTT("testmqtt/openhab/events/lamp", newState.toString, false)
end
rule "Wall button pressed"
when
Channel "mqtt:topic:connectmq:livingroom:button" triggered
then
LivingRoom_Lamp.sendCommand(if (LivingRoom_Lamp.state == ON) OFF else ON)
endFor catch-all listeners, add a Publish trigger channel on the broker Thing itself: its state topic accepts wildcards (testmqtt/openhab/+/event), and rules receive topic#payload as the event.
Test every hop
Inbound — publish a fake sensor reading and watch the Items change:
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-u "$MQTT_USER" -P "$MQTT_PASS" \
-t 'testmqtt/openhab/livingroom/sensor' -m '{"temperature": 21.5, "humidity": 48}'
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-u "$MQTT_USER" -P "$MQTT_PASS" \
-t 'testmqtt/openhab/livingroom/status' -m online -revents.log (/var/log/openhab/events.log on Linux packages) should show Item 'LivingRoom_Temperature' changed from NULL to 21.5 °C.
Outbound — subscribe to the command topic and flip the switch in the UI, or from the openHAB console:
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-u "$MQTT_USER" -P "$MQTT_PASS" -t 'testmqtt/openhab/#' -v
# in another shell: openhab-cli console, then
openhab> openhab:send LivingRoom_Lamp ONYou should see testmqtt/openhab/livingroom/lamp/set ON. The online MQTT client works just as well for both directions if you prefer a browser.
Watch openHAB's MQTT traffic in the browser
When nothing happens, raise the log level in the console with log:set DEBUG org.openhab.binding.mqtt and log:set DEBUG org.openhab.core.io.transport.mqtt. Typical findings: the Item is linked to a different channel UID, the JSONPath does not match (the value stays NULL and a transformation warning is logged), or the topic differs by one character — paste both into the topic matcher to check.
Auto-discovery: Homie and Home Assistant
The binding also understands two discovery conventions. Devices that announce themselves via the Homie convention or Home Assistant MQTT discovery (Tasmota, ESPHome, Zigbee2MQTT with discovery enabled) appear in the openHAB Inbox with their channels pre-built. That saves typing, but generic Things remain the most predictable option for custom firmware and for devices such as Shelly or Zigbee2MQTT when you want full control of topic names. Whichever you choose, a consistent smart home topic design keeps the channel configuration short.
The openHAB MQTT binding is simple once the two layers click: one broker Thing per connection, Generic MQTT Things with one channel per value, Items linked to channels. Start with a single channel, prove it with mosquitto_pub and events.log, then add the rest of the house.
Frequently asked questions
Does openHAB include an MQTT broker?
No. Current openHAB versions only ship the MQTT binding, which is a client. You need a separate broker such as Mosquitto on the same machine, or a managed broker reachable over the network.
Why is my openHAB MQTT broker Thing OFFLINE?
The status detail usually says why: wrong host or port, TLS enabled on a plain port (or the reverse), bad credentials, or a client ID already in use. Enable DEBUG logging for org.openhab.binding.mqtt and org.openhab.core.io.transport.mqtt to see the exact error.
How do I read one value from a JSON payload in openHAB?
Install the JSONPath Transformation add-on and set the channel's incoming transformation to JSONPATH:$.temperature (or whatever path you need). Several channels can share the same state topic, each extracting a different field.



