homebridge-shelly-matter: Shelly energy metering in Apple Home, via Matter
There are eleven Shelly devices in my house: relays behind wall switches, metering plugs on the appliances, a two-channel Pro 2PM running the garage. They’ve been in the Home app for years through HomeKit bridges, and for years they’ve all been standard on/off tiles. The interesting half of what a Shelly measures — live watts, accumulated kilowatt-hours — had nowhere to go, because HomeKit’s accessory protocol simply has no energy characteristics. Never had.
Matter has. And with iOS 27, the Home app finally grew an Energy view that reads them. When Homebridge 2.2 added Matter’s electrical measurement clusters to its plugin API, the missing piece existed at every layer of the stack, except no plugin actually connected them. So I wrote one: homebridge-shelly-matter.
What It Is
homebridge-shelly-matter exposes Shelly devices to Apple Home (and any other Matter controller) through Homebridge’s Matter bridge — including live power, voltage, current, and cumulative energy, which surface in the Home app starting with iOS/tvOS 27. A metering plug shows its wattage right on the tile; consumption feeds the home’s energy total.
It is deliberately a Matter-only plugin: it publishes no HAP accessories at all. If you want classic HAP exposure and don’t care about energy, homebridge-shelly-ng already does that well. This plugin exists for the thing HAP cannot do.
The Shelly protocol layer is not mine. It’s vendored from matterbridge-shelly by Luca Liguori (Apache-2.0, credited in the NOTICE file), which speaks every Shelly generation: Gen 2/3 over WebSocket RPC, Gen 1 over CoIoT. Standing on that meant I could spend my time on the Matter side, which it turned out, needed all of it.
Channels Are Accessories
The first real design decision came from a user, not from me. Multi-channel devices like the Pro 4PM originally mapped to one composed accessory with a control per channel — technically correct, and useless the moment your four channels belong in four different rooms: Apple Home assigns rooms per accessory, and even “separate tiles” of one accessory move rooms together.
So multi-channel devices are now split into independent accessories per channel by default, each with its own name, each assignable to its own room. Grouping is still there as an explicit opt-out. Getting this to work safely was its own story: Apple Home reacts badly to a device that reappears with the same identity but a different shape — broken, uneditable accessory records. The plugin therefore rotates identities on any structural change, never reuses an old one, and applies composition changes while the bridge is still offline during a restart, so a paired hub only ever sees clean transitions.
The Tricky Parts
Homebridge’s Matter API shipped weeks before this plugin; being one of the first real-world consumers meant finding where theory met an actual paired Apple Home.
Restarts used to delete your rooms. A Matter bridge that comes online with an empty parts list, then registers its accessories a second later races the hub’s re-subscription, and the hub happily deletes everything it can’t see. The fix (restore cached accessories before the node goes online, reconcile plugin registrations in place) landed upstream in Homebridge itself. That was the pattern for this whole project: eight upstream issues and pull requests so far. Composed-accessory fixes, deferred bridge online, a commissioned-fabrics display, per-accessory firmware, spec-conformance for the power cluster, most already shipped in the 2.2.2 betas.
Apple’s Energy view has a guest list. Here is the important finding, documented in the README: bridged accessories’ consumption is counted in the whole-home total, but only certified, natively-paired Matter devices get listed per-device. We verified this the hard way, commissioning a second controller onto a certified Eve Energy to dump its exact cluster structure, then replicating it: same reporting shape, same feature flags, same dedicated sensor endpoint. No difference. A Homebridge bridge can’t carry a device attestation certificate, so this is Apple policy, not a plugin gap. (Filed with Apple, along with five other behavioral findings from this project.)
Tile wattage follows the device type. Apple shows live watts only on outlet-typed accessories. A light exposing byte-identical power data shows nothing. The plugin lets you type any relay channel as an outlet, and if you prefer the light look, the Home app’s “Show As” override keeps the wattage. These Apple behaviors aren’t documented anywhere; they’re all in the README so the next person doesn’t have to rediscover them.
Idle sockets are not errors. Gen 2 Shellys close idle WebSockets by design and reconnect on demand. The protocol layer’s reconnect logging looked alarming at info level for something that happens all day by design. One of the two total changes made to the vendored code was demoting it to debug.
Configuration
Most people should never touch JSON: the plugin has a full settings UI where discovered devices appear in a table — name, per-channel accessory type, hide toggles, split control. Under the hood it’s a single devices array where entries record only deviations from sensible defaults:
{
"platform": "ShellyMatter",
"devices": [
{ "device": "shellyplus1-441793AABBCC", "name": "Office Ceiling" },
{
"device": "shellypro2pm-EC62AABBCC",
"name": "Garage",
"channels": [
{ "channel": 0, "name": "Garage Light" },
{ "channel": 1, "name": "Garage Door", "accessoryType": "switch" }
]
}
]
}
Plugs default to outlets, wired relays to lights; devices that need nothing beyond the defaults need no entry at all.
Built with Claude Code
Like homebridge-sony-adcp, this was built with Claude Code, Anthropic’s CLI coding agent. But this project was a different kind of collaboration. The plugin code was the easy half. The hard half was systematic debugging of a stack where every layer was weeks old: writing throwaway Matter controllers to read a certified device’s clusters off the wire, differential-testing against a second bridge implementation, bisecting whether a lost room assignment was the plugin, Homebridge, matter.js, or Apple. That loop — instrument, capture, compare, fix the right layer, upstream the fix — ran for days, and it’s exactly the work an agent in the terminal accelerates. The upstream Homebridge PRs came out of the same sessions.
Get Started
homebridge-shelly-matter is open source under Apache-2.0 and published to npm.
Install from the Homebridge UI — search for Shelly Matter on the Plugins tab. Or from the command line:
npm install -g homebridge-shelly-matter
Two things to know up front. It needs Homebridge 2.2.2-beta.7 or later with Matter enabled on the plugin’s child bridge — until 2.2.2 stable ships, that means npm install -g homebridge@beta. And you pair using the bridge’s Matter pairing code, not the HAP QR code. This plugin publishes nothing over HAP, so the plugin declares itself Matter-only and current Homebridge UI betas set new child bridges up correctly (Matter on, HAP off) on their own.
Source and full documentation are on GitHub.