Control an MSpa hot tub from Home Assistant, with a dashboard card that is a working replica of the physical MSpa control panel: seven-segment display, backlit keys, target chevrons.
The integration talks straight to the MSpa cloud (the API behind the MSpa Link app). No extra server is needed.
This is an unofficial community project. It is not affiliated with or endorsed by MSpa. MSpa is a trademark of its owner.
- HACS → three-dot menu → Custom repositories → add
https://github.com/viktorbk/ha_mspaas type Integration. - Install MSpa Panel and restart Home Assistant.
Copy custom_components/ha_mspa into <config>/custom_components/ and restart
Home Assistant.
Settings → Devices & services → Add integration → MSpa Panel, then enter:
| Field | Value |
|---|---|
| MSpa Link email | the account you use in the MSpa Link app |
| Password | that account's password |
| Region | where the account was created: Europe and rest of world, United States and Canada, or China |
If the account has several spas you are asked which one to add. Repeat the flow to add the others.
One login per account. MSpa allows a single active session per account, so the MSpa Link app is signed out while Home Assistant is connected. To keep both working, share the spa with a second account in the app and use that second account here.
Only the MD5 digest the cloud expects is stored, never the password itself. The session token is kept across restarts so Home Assistant does not log in again each time. Too many logins in a short time lock an MSpa account for a few minutes.
The card is served by the integration and loaded automatically. There is no dashboard resource to add. Edit a dashboard → Add card → MSpa Panel, or use YAML:
type: custom:ha-mspa-card
entity: climate.backyard_spaThe card finds the other entities of the same spa by itself.
| Key | What it does |
|---|---|
| Heater | Heater on or off. Starts the filter pump first, as the spa requires. |
| Bubble | Bubbles on or off, at the level set by the Bubble level entity. |
| Lock | Locks the card so other keys ignore taps. See below. |
| Filter | Filter pump on or off. Switching it off also stops the heater. |
| Timer | Heats now and switches the heater off after Heat timer duration (4 hours by default). Tap again to cancel. |
| UVC | UV-C sanitizer on or off. |
| Chevrons | Target temperature down or up by one degree (20 to 40 °C). |
The MSpa cloud has no child-lock field, so Lock lives in Home Assistant. It protects the card from stray taps. It does not block automations or services.
Optional card settings:
type: custom:ha-mspa-card
entity: climate.backyard_spa
labels: # rename the key captions
heater: Hitari
bubble: Bólur
entities: # override auto-discovery for single keys
uvc: switch.some_other_switchAfter updating the integration, hard-refresh the browser (Ctrl+Shift+R) if the card looks stale.
| Entity | Notes |
|---|---|
climate |
water temperature, target, heat / off |
switch heater, filter, bubbles, UVC |
the panel keys |
switch ozone, jets |
only created when the spa reports them |
switch heat timer |
ends_at attribute holds the end time |
switch panel lock |
card lock |
number bubble level |
1 to 3 |
number heat timer duration |
1 to 12 hours |
sensor water temperature |
for history graphs |
sensor fault |
diagnostic |
binary_sensor online |
diagnostic |
The polling interval (60 s by default) is under the integration's Configure button. After a command the state is shown at once and confirmed from the cloud a few seconds later.
pip install pytest-homeassistant-custom-component
pip install -c "$(python -c 'import homeassistant, pathlib; print(pathlib.Path(homeassistant.__file__).parent / "package_constraints.txt")')" home-assistant-frontend
pytestThe second line installs the frontend package the integration depends on, at the version that matches the installed Home Assistant.
tests/test_api.py runs the cloud client against a local fake MSpa cloud and
only needs aiohttp, pytest and pytest-asyncio. tests/test_integration.py
runs the config flow, entities, timer and card serving inside a real Home
Assistant test instance.
To preview the card without Home Assistant, serve this folder and open
demo/index.html:
python -m http.server 8765The protocol was reverse-engineered by the community. See DTekNO/mspa-homeassistant.
MIT. See LICENSE.