[3.0.0] - 2026-04-13
Summary
This release adds multi-device support — you can now add multiple MSpa hot tubs from the same account as separate integrations in Home Assistant. Existing single-device setups are automatically migrated. It also brings dynamic diagnostic sensors, firmware version reporting, multi-device reliability improvements, and a developer demo mode.
Added
-
Multi-Device Support - Add multiple MSpa hot tubs from the same account
- Two-step config flow: enter credentials, then select which device to add
- Each device gets its own config entry, coordinator, and set of entities
- Already-configured devices are filtered from the device picker
- Clear abort message when all devices on the account are already configured
- Config flow skips the credential step when adding a second spa, reusing credentials from the first entry automatically
-
Translations - Added
translations/en.jsonfor reliable UI string display in custom integrations -
Firmware Version Sensor - New sensor combining
wifi_versionandmcu_versionfrom the device list API into a single"141-3A1"style value, matching the format shown in the MSpa app -
Time to Target Temperature Sensors (experimental) — available on all models
- Time to Target Temperature — minutes until the set-point is reached (heating or cooling direction)
- Ready At — absolute timestamp of when the spa should be ready
- Both sensors become unavailable once the target temperature is reached, making them easy to use in conditional cards and automations
- Rate is self-learned via an exponential moving average (EMA) of observed 0.5 °C temperature steps — no reliance on device-reported values
- Heating rate sampled during full-heat mode; cooling rate sampled passively when heater is off and temperature is dropping
- Outlier rejection (e.g. adding hot/cold water mid-session) prevents spikes from corrupting the EMA
- Device-reported
device_heat_perhour(Oslo series etc.) used as a heating fallback until the EMA has enough data - Marked experimental: algorithm is new and needs a few weeks of real-world validation across seasonal conditions — feedback welcome
-
Dynamic Diagnostic Sensors - Diagnostic sensors are now created automatically from every key in the thing-shadow payload that is not otherwise handled by a structured sensor. New firmware keys appear as new sensors without any code changes; removed keys disappear.
-
Shared Rate Limiter (
_MSpaThrottle) - Per-account spike-arrest rate limiter (0.4 s minimum between requests) shared across all coordinators for the same account, preventing API rate-limit errors (code 11000) when two spas start up simultaneously -
Shared Auth Store - All coordinators for the same MSpa account share one token and one
asyncio.Lock, eliminating token-collision races on startup -
Entry Title Self-Correction - On each startup the integration checks whether the config entry title matches the device alias returned by the cloud and corrects it if not. Prevents stale titles persisting across restarts without a delete-and-re-add.
-
Block Device-Only Deletion (
async_remove_config_entry_device) - Prevents users from deleting the spa device from the device-detail page without removing the integration entry, avoiding ghost entities. HA redirects the user to delete the integration entry instead. -
Improved Device Info — device page now shows firmware version (
141-3A1format), serial number, MAC address, and model ID sourced from the device list API -
Developer Demo Mode - Use email
demo@mspa.test(any password) to add up to three virtual spa devices (Frame / Oslo / Alpine) with no cloud connectivity. Status polls return realistic drifting mock data; commands update mock state in memory. See the README for full details.
Changed
-
Config Flow - Redesigned as a two-step flow
- Step 1: Enter email, password, and region (with auto-detection)
- Step 2: Select device from your account (auto-selected if only one)
- Duplicate device prevention via unique_id per physical device
-
Device Identity - Devices now use the real MSpa device ID as their identifier
- Enables proper multi-device support in the device registry
- Existing devices are automatically migrated from the old generic identifier
-
Entity Unique IDs - Diagnostic sensor unique IDs now include the device ID suffix
- Prevents entity collisions when multiple devices are configured
- Existing entities are automatically migrated to the new format
-
Diagnostic Sensor Keys are Verbatim - The coordinator no longer normalises shadow payload key names (e.g.
wifivertion,mcuversion). Old key names appear as-is so that firmware renames become visible in the UI rather than being silently hidden. The firmware version sensor uses the authoritative values from the device list API. -
Auth Cleanup on Full Unload -
async_unload_entrynow correctly removes the shared auth store when the last entry is unloaded. -
Code Quality - Extracted helper functions and removed dead code
_build_headers()and_obfuscate_email()helpers in API client_get_option_int()and_calculate_total_power()helpers in sensor module- Removed unused
RAPID_POLL_MAX_ATTEMPTS,_update_lock, and trivialasync_request_refreshoverride - Fixed
authenticate()silently returning stale token on failure — now raisesRuntimeError - Config flow distinguishes
invalid_authfromcannot_connecterrors
Fixed
- Filter Status Unique ID - Fixed missing underscore in
filter_statusentity unique ID (mspa_filter_status{id}→mspa_filter_status_{id}) - Command Serialisation - Write commands across two coordinators for the same account are serialised via a shared
api_lock, preventing interleaved command payloads MSpaDiagnosticSensor.state- Fixed property reading from the internal_last_datadict instead of the public coordinator property which can beNoneon first load
Migration
- Automatic: Device identifiers, entity unique IDs, and the filter_status fix are all migrated automatically on first startup after upgrade. No manual action required.
- If you experience issues: If entities appear duplicated or missing after upgrading, remove the integration and re-add it. Your device will be rediscovered automatically.