Skip to content

Verification Request: homebridge-mqttthing-ex #1145

Description

@tasict

Plugin Name

homebridge-mqttthing-ex

Link To GitHub Repo

https://github.com/tasict/homebridge-mqttthing-ex

Plugin Icon (Optional)

Image

The plugin does not offer the same nor less functionality than that of any existing verified plugin.

🟢 Yes

The plugin successfully installs and does not start unless it is configured.

🟢 Yes

The plugin does not require the user to run Homebridge in a TTY or with non-standard startup parameters, even for initial configuration.

🟢 Yes

The plugin does not contain any analytics or calls that enable you to track the user.

🟢 Yes

If the plugin needs to write files to disk (cache, keys, etc.), it stores them inside the Homebridge storage directory.

🟢 Yes

The plugin does not throw unhandled exceptions, the plugin must catch and log its own errors.

🟢 Yes

More Information

Relationship to homebridge-mqttthing

I want to be upfront about this rather than let the review discover it: this
plugin covers the same problem domain as
homebridge-mqttthing
by David Miller, and it began as a re-implementation of that plugin's
configuration format.

That plugin has been the reference MQTT plugin for Homebridge for years and I
have a great deal of respect for it — this project exists because of it, not
in spite of it. Its most recent npm release is 1.1.49 (January 2026) and its
engines.node range does not yet cover Node 24. Working through the Homebridge
2.0 transition I ran into API-surface issues I could not resolve inside the
existing CommonJS codebase without effectively rewriting it, and upstream has
been quiet for a while. Rather than maintain a divergent fork, I rewrote the
plugin from the ground up in TypeScript / ESM against the modern HAP APIs
(onGet / onSet), with a 327-test suite and CI on Node 20, 22 and 24.
Upstream attribution is in
NOTICE;
the licence is Apache-2.0.

As far as I can tell homebridge-mqttthing is not on the current
verified-plugins.json list, so I don't believe this request displaces a
verified plugin. The verified plugins in adjacent territory
(homebridge-easy-mqtt, homebridge-mqtt-tasmota, homebridge-mqttsmokesensor
and similar) are deliberately narrow — a single device family or a small set of
service types. This plugin is a general MQTT ↔ HomeKit bridge covering roughly
50 accessory types, so I don't believe it duplicates or reduces any of them.

A design decision the review should know about

The plugin registers the accessory alias mqttthing — the same alias upstream
uses.
This is deliberate: it lets an existing user migrate by uninstalling the
old plugin, installing this one and restarting, with no config.json changes
and no HomeKit re-pairing
, because Homebridge derives the accessory UUID from
the alias plus the configured name. Minimising migration friction for existing
users was the primary design goal.

The trade-off is that the two plugins cannot be installed side by side. This is
handled gracefully rather than by crashing: registration is wrapped in
try/catch and logs an actionable message naming the conflicting plugin
(src/index.ts),
and the behaviour is documented in the README migration section. If the
Homebridge team would prefer the aliases not to collide, I'm happy to rename and
ship a migration path instead — please just say so.

Functionality beyond a like-for-like rewrite

  • Platform mode — one config block with a devices[] array, sharing one
    MQTT connection per broker
    instead of one per accessory (a 40-device setup
    goes from 40 sockets, keepalive timers and broker-side sessions to 1). Devices
    carry a stable id, so renaming is no longer destructive, and cached platform
    accessories keep their HomeKit place (room, scenes, automations) while a
    misconfiguration is fixed. Moving a device into platform mode preserves its
    existing UUID, so this too needs no re-pairing.
  • Custom configuration UI (@homebridge/plugin-ui-utils) — searchable
    accessory list built for setups with dozens of devices, a type-aware editor
    with a topic table, editing of apply expressions and of the custom
    multi-service type (which a plain schema form cannot represent), live MQTT
    connection testing and topic probing.
  • Outbound publish queue with per-topic coalescing and throttling, so
    HomeKit scene bursts and slider drags cannot overwhelm low-power IoT devices.
  • Upstream bugs fixed — spurious colour publishes at start-up, adaptive
    lighting switching lights on, temperature clamping of sensor readings,
    wildcard subscriptions, null-payload crashes, history crashes with multiple
    services. Full list with upstream issue references:
    docs/UpstreamIssues.md.
  • Backwards compatible with existing CommonJS codec files and
    { "topic": …, "apply": … } expressions.

Development continues in step with Homebridge releases; further capabilities
will follow as the platform gains them.

Requirement notes

  • Dynamic platformMqttThingPlatform implements DynamicPlatformPlugin
    and is registered with api.registerPlatform(); config.schema.json declares
    "pluginType": "platform". The legacy mqttthing accessory registration is
    retained purely so existing config.json files keep working during migration.
  • Does not start unless configured — neither the platform nor the accessory
    is instantiated by Homebridge without a matching config block, and there is no
    ambient work at module load.
  • Files on disk — the only writes are the fakegato-history counter files,
    under api.user.storagePath()
    (src/features/history.ts).
    The custom UI server reads codecs from, and writes config.json within, the
    Homebridge storage directory only.
  • No analytics — there are no outbound HTTP calls of any kind; the only
    network I/O is to the user's configured MQTT broker.
  • No post-install scriptspackage.json declares no
    preinstall/postinstall.
  • Releases — every npm version has a matching GitHub release with notes;
    publishing runs from a release-triggered workflow with npm provenance.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions