Control a Bluetooth Marpac Dohm sound machine from Home Assistant as a
media player (on/off + volume). The BLE protocol was reverse-engineered
from the official app; see docs/protocol.md and the
docs/reverse-engineering.md runbook.
Upgrading from 0.1.x? The Dohm used to be a
fanentity. It is now amedia_player, because what you adjust on a sound machine is loudness, not airflow — and volume is something the rest of Home Assistant already understands. This changes the entity ID, so any automation, script, or dashboard card referring tofan.<your dohm>needs to point atmedia_player.<your dohm>instead. The oldfan.*entity is left behind in the registry as unavailable — delete it yourself from Settings → Devices & Services → Entities.
- In HACS, add this repository as a custom repository (category: Integration).
- Install Marpac Dohm and restart Home Assistant.
- The Dohm should be auto-discovered. If not, go to Settings → Devices & Services → Add Integration → Marpac Dohm.
- Hold the top button on the Dohm for ~5 seconds to make it discoverable, then select it.
- Give it a name and, optionally, an area. The name becomes both the device and the entity name, so it is what voice assistants listen for — worth naming after the room if you have more than one. After this one-time pairing, Home Assistant reconnects on its own.
One controller at a time. The Dohm stores exactly one pairing, and the top button grants a new one, replacing whatever was there. That button is only for pairing — it plays no part in normal operation, so pressing it while troubleshooting will break a working setup. If the phone app has the pairing, forget the Dohm there before adding it here.
-
It connects but never responds. The Dohm only replies over a paired (encrypted) link, so this usually means the stored pairing no longer matches. Give it a few minutes first — a link that is merely slow to start looks identical, and Home Assistant keeps retrying. If it stays that way, hold the top button ~5 seconds and use Configure → Clear the pairing and pair again on the integration entry.
The integration will not do this on its own. Earlier versions cleared the pairing automatically after three failed polls, which could not tell a slow link from a stale one — and guessing wrong threw away a working pairing that only the top button could restore.
-
Adding it does nothing / says it's already configured. An existing config entry is blocking the add, and disabled entries are hidden by default. Turn on show disabled entries under Settings → Devices & Services, then delete the old one before re-adding.
-
It went unavailable and stayed there. Check the logs for
custom_components.dohm; the version history and diagnostic recipes are indocs/debugging.md.
- A media player entity (device class speaker): turn on/off and set volume across the device's 10 levels. Volume up/down step exactly one level rather than the usual 10%, so every press is a setting the device actually has, and the control snaps immediately to the level the Dohm took — drop the slider at 43% and it moves to 50% right away rather than after a round-trip.
- Voice control via the standard volume intents — "set the white noise to 40 percent", "turn the white noise down" — which a fan entity can't answer.
- A proper device entry (manufacturer Marpac, model Dohm), with firmware/ serial pulled from the device when available.
The Dohm has no silent setting, so volume 0 is the quietest level rather than off; use turn off for silence. It plays no media, so no transport controls, sources, or metadata are exposed and it is never offered as a playback target.
Scheduling is intentionally left to Home Assistant automations rather than the device's onboard timer — far more flexible, and it sidesteps the device's drifting onboard clock.
- A Bluetooth adapter on the Home Assistant host or an ESPHome Bluetooth Proxy within range of the Dohm. No external Python packages — the integration is self-contained and uses Home Assistant's bundled Bluetooth stack.
The reverse-engineering engine (protocol.py, client.py) is vendored inside
custom_components/dohm/ and unit-tested without hardware:
uv run pytesttools/ holds the BLE exploration helpers used to map the protocol
(probe.py, explore.py, extract_writes.py).
MIT.