Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ A Wi-Fi enabled model is required. No custom hardware is required.
This integration supports two main generations of devices (V1 and V2), which must be selected when adding your device to Home Assistant. Broadly speaking:

- V1 covers older models up to around 2024.
- V2 covers newer models from 2025 onwards.
- V2 covers newer models from 2025 onwards. Bestway have moved these across two different cloud backends, so there are two V2 options to choose between; [Configuration](#configuration) explains which one your device needs.

See the [supported devices](docs/supported-devices.md) list for confirmed examples of each.

Expand All @@ -39,13 +39,13 @@ Initial configuration must be done via the relevant mobile app. Bestway have pub

- V2 models must be configured via the Bestway Connect app ([Android][bestway-connect-android]/[iOS][bestway-connect-ios]). Users have reported that the Lay-Z-Spa Wi-Fi app will control devices, but does not provide the crucial sharing QR code described below.

With this done, open Home Assistant and go to **Configuration** > **Devices & Services** > **Add Integration**, then find **Bestway** in the list.
With this done, open Home Assistant and go to **Configuration** > **Devices & Services** > **Add Integration**, then find **Bestway** in the list. The first step asks which backend to use, and the options below map onto that choice.

The process varies depending on model:
- **V1 - Bestway Smart Hub (Gizwits)** requires your Bestway username and password. You must also select the required region (EU or US).

- V1 models require your Bestway username and password. You must also select the required region (EU or US).
- **V2 - Bestway Connect (AWS IoT)** requires a scan of the sharing QR code from the Bestway Connect app (Settings > Device Sharing), plus the required region (Europe, US or China). The code decodes to text beginning `RW_Share_`. If yours decodes to a URL instead, the app that produced it has been updated since July 2026 and this backend cannot accept it - use the account-login option instead.

- V2 models require a scan of the QR code from the Lay-Z-Spa app settings. You must also select the required region (Europe, US or China).
- **V2 - Bestway Connect account login (SmartSpa gateway)** requires the email address and password of your Bestway Connect account, plus the required region (Europe, US or China). This is the option for a device paired by a Bestway Connect app updated after July 2026, where "Share device" produces a share link addressed to an account rather than an anonymous QR code, and no QR code is involved at any point. If you have only ever used the app as a guest, add an email address and password to it first; the device may need re-pairing to that account, because a guest identity does not carry over.

All devices in your account will be automatically detected and added by the integration.

Expand Down
43 changes: 43 additions & 0 deletions tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
)
from custom_components.bestway.bestway.model import BestwayUserToken
from custom_components.bestway.const import (
BUBBLES_MODE_ONOFF,
CONF_API_ROOT,
CONF_API_ROOT_EU,
CONF_BUBBLES_MODE,
CONF_PASSWORD,
CONF_UID,
CONF_USER_TOKEN,
Expand Down Expand Up @@ -76,6 +78,47 @@ async def test_setup_unload_and_reload_entry(hass: HomeAssistant, bypass_get_dat
assert config_entry.entry_id not in hass.data[DOMAIN]


async def test_options_change_keeps_the_entry_loaded(
hass: HomeAssistant, bypass_get_data
):
"""An option change must leave the entry loaded, with a live coordinator.

The reload has to go through the config-entries framework: setting the
entry up directly leaves the framework's state untouched, and the
coordinator's first refresh refuses to run outside SETUP_IN_PROGRESS.
"""
future = (datetime.now(UTC) + timedelta(days=31)).timestamp()
config_entry = MockConfigEntry(
domain=DOMAIN,
data={
CONF_USERNAME: "test@example.org",
CONF_PASSWORD: "P@asw0rd",
CONF_API_ROOT: CONF_API_ROOT_EU,
CONF_USER_TOKEN: "t0k3n",
CONF_USER_TOKEN_EXPIRY: int(future),
CONF_UID: "test_uid_123",
},
version=2,
entry_id="test",
)
config_entry.add_to_hass(hass)

assert await hass.config_entries.async_setup(config_entry.entry_id)
assert config_entry.state is ConfigEntryState.LOADED

# The bubbles UI option is the only one, and the one users change.
hass.config_entries.async_update_entry(
config_entry, options={CONF_BUBBLES_MODE: BUBBLES_MODE_ONOFF}
)
await hass.async_block_till_done()

assert config_entry.state is ConfigEntryState.LOADED
assert DOMAIN in hass.data and config_entry.entry_id in hass.data[DOMAIN]
assert isinstance(
hass.data[DOMAIN][config_entry.entry_id], BestwayUpdateCoordinator
)


async def test_setup_entry_expired_token(hass: HomeAssistant, bypass_get_data):
"""Test what happens when the auth token needs to be refreshed."""

Expand Down
Loading