SPAcentral for Balboa Whirlpool - a native HACS integration
Thanks first to jshank for the great work and for the EW11 add-on that’s been running in my
setup for years. His original thread is still the best starting point for the EW11 approach:
https://community.home-assistant.io/t/balboa-hot-tub-spa-automation-and-power-savings/
Installation
Through HACS: it’s in the default store - no custom repository needed.
- HACS → Integrations → search for SPAcentral for Balboa Whirlpool
- Download it
- Restart Home Assistant
By hand: copy custom_components/spacentral_for_balboa/ into <config>/custom_components/
and restart.
Repo
If you hit a bug, please open an issue there. If there’s something you’d like supported that
isn’t yet, please open a feature request too - I’ll add what’s feasible and makes sense for
the project.
Setup
Settings → Devices & Services → Add Integration → SPAcentral for Balboa Whirlpool, then
pick your connection:
| Choice | For | Default port |
|---|---|---|
| Serial gateway on the network | Elfin EW11, ser2net, ESPHome serial server | 8899 |
| Balboa Wi-Fi module | the original bwa module | 4257 |
| Serial adapter on this machine | USB or GPIO RS-485 adapter | — |
Add the integration once per spa - there’s no limit, and multiple instances don’t interfere
with each other. Your gateway needs to run in TCP server mode at 115200 baud, 8N1. If the
setup dialog connects but the spa stays silent, it’s almost always the baud rate or swapped
RS-485 A/B wiring.
Requires Home Assistant 2025.2.0 or newer.
Why I built this
I own a “SwimSpa” - one unit, but two separate water zones (whirlpool and swim zone), each
with its own Balboa control system. jshank’s add-on doesn’t support that: it publishes to a
hardcoded MQTT topic, so a second instance just collides with the first instead of behaving
as a second device.
I first patched around this with a pretty ugly workaround that limped along, but re-merging
upstream changes by hand got old fast. So I decided to build it properly instead: drop the
add-on/Docker/MQTT model, support both the Wi-Fi module and RS-485 gateways through one
integration, treat multiple spas as a first-class case, and wrap it in a proper config-flow
UI distributed through HACS.
What it does
Only creates entities for hardware the spa controller actually reports - a spa with three
pumps gets three fan entities, not six.
| Entity | Covers |
|---|---|
climate |
water & target temperature, heating action, heat mode, temperature range |
fan |
pumps 1–6 and the blower, single- and two-speed |
light |
lights 1–2 |
switch |
auxiliary outputs, mister, second filter cycle |
time / number |
filter cycle start times and durations |
sensor |
water & target temperature, heat mode, temperature range, reminder, last fault |
binary_sensor |
heating, circulation pump, filter cycles, priming, hold |
event |
maintenance reminders |
Plus: keeping the spa clock in sync with Home Assistant, and a diagnostics download from the
device page with the address/MAC redacted.
What you can connect
| Connection | Status |
|---|---|
| RS-485 gateway over TCP (Elfin EW11, ser2net, ESPHome serial server) | verified on real hardware, reading and writing - this is what the project is developed and tested against |
| Local serial adapter (USB / GPIO RS-485) | supported by design, not yet verified on hardware |
| Balboa Wi-Fi module (bwa 50350, TCP 4257) | supported by design, not yet verified on hardware - if you own one, testing and feedback would be hugely appreciated |
Why bother with a gateway at all? The official Balboa Wi-Fi module works fine, but it’s a
proprietary, spa-specific product and priced accordingly. An EW11 is a fraction of that cost and it isn’t even a spa product. The Elfin EW11 is a generic, mass-produced RS-485-to-WiFi
serial gateway sold for all kinds of industrial/Modbus applications; it just happens to work
perfectly here because the spa’s control board exposes the same RS-485 bus the topside panel
and the official Wi-Fi module use. You’ll find it cheap on AliExpress and similar general
electronics marketplaces - search for “Elfin EW11.” Wire it to that bus, set it to TCP server
mode, and this integration talks to it exactly like it would talk to the official module -
just on a different port, with no broker in between.
For the physical wiring and gateway configuration, jshank’s guide is still the best
reference: https://community.home-assistant.io/t/balboa-hot-tub-spa-automation-and-power-savings/
The Wi-Fi module and the RS-485 path share the exact same transport, framing and parser -
only the default port and a write-timing policy differ - so it’s exercised by the same test
suite. It’s just genuinely unverified because I don’t own that hardware myself.
The whole protocol layer has been checked against 40,000+ real frames captured from two
physical controllers, and is currently driving both of my zones live.
How it’s different from what’s already out there
| Wi-Fi module | RS-485 / EW11 | No MQTT broker needed | Multiple spas | Identity without MAC | |
|---|---|---|---|---|---|
| ccutrer/balboa_worldwide_app + jshank/bwalink | |||||
HA core balboa + pybalboa |
|||||
| jozefnad/homeassistant-smartspaclient | |||||
| SPAcentral for Balboa Whirlpool |
That last column mattered most for my use case: other integrations derive entity identity
from a MAC address an RS-485 gateway setup may never report, or from a display name you
might change. This integration keys identity off the MAC when available, and off Home
Assistant’s own entry_id otherwise - never the name. That’s what makes two identical
controllers on the same gateway type actually stay apart.
A few design choices, for anyone curious
- One transport, two worlds. The Balboa Wi-Fi module and an RS-485 gateway like the EW11
speak the same protocol over the same kind of socket - they only differ in port number. - The protocol layer doesn’t know Home Assistant exists. It’s tested purely against
recorded byte streams, independent of the HA integration on top of it. - Bus arbitration is a policy, not a given. Immediate writes for TCP gateways,
token-bound writes for direct RS-485, switchable. - Push, not polling. The controller sends a status frame roughly every second, so there’s
noDataUpdateCoordinatorand no poll-interval setting to tune.
Credits
Built on protocol work and design ideas from
ccutrer/balboa_worldwide_app (MIT) and
garbled1/pybalboa (Apache-2.0).
And once more, thank you jshank - this whole project exists because your add-on
solved this for me for years
This is an unofficial, community-built integration and is not affiliated with, endorsed by,
or in any way connected to Balboa Water Group. “Balboa” and related names/marks are
trademarks of Balboa Water Group, referenced here only to describe hardware compatibility.
Code is MIT-licensed.
