An Indigo plugin that connects directly to a zigbee2mqtt MQTT broker, auto-discovers all Zigbee device types, and creates matching Indigo devices — all organised in a Zigbee2MQTT device folder.
- Connects directly to the zigbee2mqtt MQTT broker (paho-mqtt) — no extra bridge in between
- Auto-detects the right Indigo device type from each device's zigbee2mqtt
exposesdefinition - Discover & Create Devices menu item: one click creates every Indigo device, no manual setup
- Device types created:
- Z2M Light (dimmer) — bulbs, LED strips and Hue, with brightness plus optional colour / colour-temperature
- Z2M Relay (relay) — switches, outlets and plugs, with on/off plus optional power / energy
- Z2M Cover (dimmer) — blinds and shutters, with position 0-100% mapped to Indigo brightness, plus tilt
- Z2M Repeater — Zigbee routers and coordinators in repeater mode (SLZB, SMLIGHT), with link quality and availability
- Z2M Button / Scene — button and scene controllers. The
lastActionstate is an Indigo enumeration, so you get a boolean sub-state per action (lastAction.single,.double,.hold, and so on) and can trigger on a specific press straight from the Triggers UI, with no string compare - Z2M Sensor family — a generic sensor plus auto-classified Contact, Occupancy / presence, Water-leak and Temperature / Humidity types, each given the matching Indigo subType so HomeKit and friends route them correctly
- Z2M Coordinator — one device per MQTT bridge, tracking the Z2M version, coordinator type, permit-join, network and device count
- Every payload field is imported. Beyond the semantic states above, any other field a device reports is captured as a dynamically-declared state of the correct Indigo type (boolean / integer / real / string), so nothing is thrown away
- Self-healing MQTT — an application-level liveness backstop rebuilds the connection if it falls silent, catching the half-open-socket wedge that paho's own auto-reconnect can miss. MQTT also disconnects and reconnects cleanly across Mac sleep and wake
- Multiple zigbee2mqtt instances supported (for example a main bridge plus a separate garage coordinator)
- Availability and link quality tracked per device, friendly names containing
/handled, everything organised in a Zigbee2MQTT device folder
- Indigo 2023.2 or later (developed and run on Indigo 2025.2 / Python 3.13)
- zigbee2mqtt running and reachable over MQTT
- MQTT credentials in
IndigoSecrets.pyOR entered in PluginConfig (fallback added in v1.9.6) - Bundled Python dependencies, installed automatically on first run:
paho-mqttonly (as of v1.9.16)
- Go to the Releases page and download
Zigbee2MQTTBridge.indigoPlugin.zip - Unzip the downloaded file — you will get
Zigbee2MQTTBridge.indigoPlugin - Double-click
Zigbee2MQTTBridge.indigoPlugin— Indigo will install it automatically
This plugin (along with all CliveS Indigo plugins) reads sensitive values from a shared master credentials file at:
/Library/Application Support/Perceptive Automation/IndigoSecrets.py
| File | Purpose | Real data? | Committed to GitHub? |
|---|---|---|---|
IndigoSecrets.py |
Working file the plugin reads at runtime. Keep a backup in a password manager. | YES | NO — listed in .gitignore |
IndigoSecrets_example.py |
Template only — empty placeholders. Shipped in the plugin bundle. | NO | YES |
If you do not have IndigoSecrets.py, copy IndigoSecrets_example.py from
the plugin bundle to /Library/Application Support/Perceptive Automation/ and rename it to IndigoSecrets.py, then fill in your values. Or skip
IndigoSecrets.py entirely and enter values via the plugin's configuration
dialog — IndigoSecrets.py wins over the dialog when both are set.
If a required value is set in NEITHER source the plugin logs an ERROR
pointing the user to either fill in the matching field or add the key to
IndigoSecrets.py.
Keys read by Zigbee2MQTTBridge:
MQTT_BROKER = "192.168.x.x" # hostname or IP of your MQTT broker
MQTT_PORT = 1883
MQTT_USERNAME = "" # blank = no auth
MQTT_PASSWORD = ""All four have matching PluginConfig fields under Plugins → Zigbee2MQTT Bridge → Configure (fallback added in v1.9.6).
Every log line is prefixed with a millisecond timestamp [HH:MM:SS.mmm] so
events can be correlated tightly with other CliveS plugins (Device Activity
Monitor uses the same convention).
To turn the prefix off (or back on) at any time:
Plugins → Zigbee2MQTT Bridge → Toggle Timestamps in Log (on/off)
The setting is stored in pluginPrefs (timestampEnabled) and persists across
restarts. Defaults to ON.
- 1.9.16 (10-06-2026) — housekeeping from a full repo audit, nothing visible changes day to day. Installs are much lighter: the unmaintained
colormathlibrary (which dragged the largenumpypackage onto every machine) has been dropped — the one colour conversion it performed is now done in a few lines of plain Python, with proper gamma correction so reported lamp colours stay true. The repo also gained automatic testing on every change (GitHub Actions runs the full 269-test suite plus a lint pass), a couple of silent edge cases now log a warning instead of vanishing (a malformed bridge message used to be discarded without trace), and an internal threading rule that one callback was quietly bending is now followed to the letter. - 1.9.15 (06-06-2026) — review fixes: corrected the universal-action handler name so Send Status Request works on every path, stopped combo devices (a dimmer or switch that also sends scene actions) being mistakenly rebuilt as buttons, and a malformed payload field is now skipped on its own rather than dropping the whole update.
- 1.9.14 (29-05-2026) — self-healing MQTT: an application-level liveness backstop rebuilds the connection after a silent half-open socket that paho's own auto-reconnect can miss.
- 1.9.13 (28-05-2026) — dynamic state-type inference: each captured payload field is declared with the correct Indigo type (boolean / integer / real / string) rather than always string.
- 1.9.12 (28-05-2026) —
lastActionon button devices became an Indigo enumeration, so each action gets a boolean sub-state for one-click triggers. - 1.9.11 (27-05-2026) — clean MQTT disconnect and reconnect across Mac sleep and wake.
- 1.9.8–1.9.10 (25-05-2026) —
actionControlSensorso Send Status Request works on sensor devices,didDeviceCommPropertyChangeto stop unnecessary device-comm cycling, and a pytest test suite. - 1.9.0–1.9.7 (22–23-05-2026) — coordinator devices, the Refresh Device Capabilities menu, Indigo subType mapping for HomeKit, PluginConfig credential fallback, and millisecond log timestamps.
- Enable the plugin in Indigo (Plugins → Manage Plugins)
- Set the Topic Prefix in plugin preferences (default:
zigbee2mqtt) - Wait for
MQTT connectedandBridge device cache updated: N devicesin the event log - Plugins → Zigbee2MQTT Bridge → Discover & Create Devices — creates every device
- (Optional) Create Coordinator Devices — adds one coordinator device per MQTT bridge
- All your Zigbee devices appear in Indigo under the Zigbee2MQTT folder
Re-run Discover & Create Devices any time you add new Zigbee devices, and Refresh Device Capabilities after a device's zigbee2mqtt definition changes (it re-detects capabilities and corrects the Indigo subType without delete-and-recreate).
With thanks to Autolog for the zigbee2mqtt plugin — studying its design showed us the way to build this plugin, and the project would not exist without that prior work.
Vibed into existence by CliveS, who knew what he wanted, argued until he got it, and tested it on a real house. Typed at inhuman speed by Claude (Anthropic), who mostly did as it was told.
© 2026 CliveS · MIT licence — copy it, fork it, bend it, break it, fix it, ship it. If it breaks, you get to keep both pieces.