Releases: bluetti-community/bluetti-home-assistant
Releases · bluetti-community/bluetti-home-assistant
Release list
v1.2.4rc1
Pre-release - for testing
Enable "Show beta versions" in HACS to see this. Requires pybluetti>=0.2.1rc1, itself a pre-release - HACS/pip will resolve it automatically since no stable pybluetti release satisfies that floor yet.
Fixed
- 1.2.3's fix for the websocket crash-reconnect loop (bluetti-official#145) was only partial - real logs on 1.2.3 itself still showed
Failed to send heartbeat: Cannot write to closing transportrepeating on every reconnect cycle.pybluetti0.2.1rc1 fixes the actual cause:_run()wasn't closing the abandoned connection itself on this path, only on a token-expiry. See the pybluetti CHANGELOG for the full root-cause writeup.
If you were seeing this specific log message, please test this pre-release and report back on the issue whether it's actually gone now.
v1.2.3
Fixed
- Fix the websocket real-time update connection getting stuck in a silent crash-reconnect loop once the cloud rejects it with a persistent (non-token-expiry) error - reported as a repeating
Upgrade required, and then reconfigure the BLUETTI integration/BLUETTI WebSocket task crashedcycle every ~30 seconds (bluetti-official#145). Device data kept updating via the 30-second polling fallback throughout, but real-time push stayed broken with no visible signal beyond log spam. The integration now surfaces this as a Repair issue in Settings -> Devices & services -> Repairs instead, andpybluetti(>= 0.2.0) no longer leaks the previous connection's heartbeat task into every retry or re-logs the same full traceback on each one.
v1.2.2
Fixed
- Modbus-sourced entities (Balco260/EP2000 local connection) no longer flap unavailable on every transient read glitch. The device's Modbus TCP stack occasionally returns a malformed/truncated response for a single register block; the coordinator now retries once immediately instead of waiting a full 30s poll interval.
- Dropped a trailing slash from the default profile's
wssURL, which could prevent the push-update websocket from connecting.
v1.2.1
Fixes:
- Fix cloud API failures (e.g. an expired token) being silently treated as empty data instead of a real error, in three places: device state refresh, the config flow's device list, and the options flow's device list. The account previously looked like it had "no devices" or the setup just failed generically instead of correctly triggering reauthentication.
- Fix a second BLUETTI account authenticating through a fresh "Add Integration" flow silently merging into (and overwriting the token of) an already-configured account's entry - it now correctly rejects as already configured. Also fix bind_devices()'s response never being checked, so a rejected device bind (nonzero msgCode) was treated as success in both the config flow and the options flow.
- Fix entry.data["products"] caching every product on the account instead of just the ones actually selected (in the config flow's create/merge paths and the options flow's add-devices path) - a device left unselected the first time would, when added later, reuse this stale cached metadata instead of a fresh fetch.
- Fix a device unbind: the coordinator was torn down and the unbind marked complete before the removal was actually persisted to the config entry - a persistence failure left the device "enabled" forever with no coordinator and no retry path. Persistence now runs first; the unbind notification also now says so honestly instead of always claiming success.
- Fix the OAuth access token not being guaranteed fresh before it's handed to the cloud/websocket clients at setup (the call that ensures this had been commented out), and fix the first refresh of each device's coordinator not waiting for slower devices when another device fails - they were left running as orphaned background tasks after setup had already moved on.
- Fix the periodic (daily) OAuth token check reporting the token as expired without even attempting a refresh first, and fix it (plus the config flow's reauth path) triggering two reload cycles for a single token update.
- Fix ENUM-type sensors (e.g. inverter state) not declaring their possible values (
_attr_options) to Home Assistant when the cloud provides them. - Fix the estimated battery charge/discharge power sensor being silently dropped for EBOX-EP2000 after an over-eager restriction to Balco260 only - both models' real diagnostics data support the same estimate.
v1.2.0
New:
- The device's serial number now shows up in its Device Info panel (Settings -> Devices & services -> BLUETTI -> device page), matching how other Home Assistant integrations surface it.
- A single device can now be removed from an existing multi-device setup via its device page's "Delete" button, without having to remove and re-add the whole integration. This only stops Home Assistant from tracking the device - it does not unbind it from your BLUETTI account, so it can be added back later via Settings -> Devices & services -> BLUETTI -> Configure.
Internal:
- The BLUETTI cloud API client (HTTP + websocket push updates) now lives in a standalone package,
pybluetti, instead of being embedded in this repo. Along the way, the websocket transport moved off the blockingwebsocket-clientlibrary (run on a dedicated thread) ontoaiohttp's native async websocket client - fully async, no threads. No user-visible behavior change;manifest.jsonnow depends onpybluetti>=0.1.0instead ofpydantic/stomper/websocket-clientdirectly. - Adopted
mypy --strictacross the whole codebase (wired into CI viascripts/typecheck), fulfilling the "strict-typing" requirement of Home Assistant's Platinum integration quality scale.
Fixes:
- Fix the device's real serial number appearing in plain text in downloaded diagnostics (in the device list, the
coordinatorskeys, and the enabled-devices list underentry_options), even though the same serial is redacted everywhere else in the dump. It's now aliased to a stable "device_N" per dump instead, so devices in a multi-device dump can still be told apart without exposing the actual serial number. - Fix the integration getting permanently stuck failing to set up with "BLUETTI setup failed: Implementation not available" if the underlying OAuth Application Credential is ever lost (e.g. a partial backup restore, or an entry created without going through the config flow). The default credential is now automatically re-imported and setup retried once, instead of requiring a manual remove-and-re-add of the integration.
- Fix the daily proactive OAuth token-refresh timer silently failing every single time it fired (a
TypeErrorfrom a callback signature mismatch, found while adding strict typing) - the "check again in 24 hours" mechanism had effectively never worked. - Fix two spots (
options_flow.py,oauth.py) where adding a device on an account with zero BLUETTI devices bound to it would crash instead of showing "no devices available". - Fix
set_state_valuecrashing instead of just not applying the update if the cloud ever responds to a control command with a non-JSON body. - Fix
hassfestvalidation failures:icons.json's entity translation keys used the cloud's raw, mixed-casefn_codevalues, which don't match Home Assistant's required key pattern; andmanifest.json'sdocumentationfield pointed at a URL reserved for integrations already bundled in Home Assistant core, not a custom integration like this one. - Fix the "Online" binary sensor being registered under the
sensor.*domain instead ofbinary_sensor.*- it was being added through thesensorplatform'sasync_add_entitiesinstead of its ownbinary_sensorplatform (entity_id domain is decided by which platform registers the entity, not by the entity class's own base class). It now lives in its ownbinary_sensor.pyplatform file, matchingswitch.py/select.py.