Releases: dzerik/holabrain-ha
Release list
v0.19.0
Added
- A modelled appliance now surfaces the status keys the integration does not map yet, as
diagnostic, disabled-by-default sensors — the same treatment an unmodelled appliance's keys
already get. Until now this fallback ran only for appliances with no category at all, so a
field a modelled appliance reports but no descriptor, gate, state rule, write guard, native
config or snapshot trigger touches was simply invisible. A user enabling one is exactly the
evidence needed to model it. Raw lifetime counters served by the consumption sensors stay
hidden (their scale is undocumented and they would inflate long-term statistics).
v0.18.0
Added
- The session is now prolonged in place before its token expires, using the cloud's
token/extendendpoint instead of a full re-login. A re-login mints a new session and so
signs the vendor's mobile app out; extending renews the same session, so staying
authenticated no longer costs the app its login. This runs on the integration's own
initiative only in exclusive mode (or whenever a person forces a refresh) — cooperative
mode still never spends an account request unprompted — and fires roughly once per token
lifetime, not every poll. Exposed on the client asasync_extend_token().
v0.17.1
Fixed
-
An expired token no longer wedges the integration. The cloud reports an expired token
with business code12001, which the integration did not recognise — so it never became
an authentication failure, no re-login was attempted, and setup retried every 30 seconds
forever with a token nothing would refresh. Symptom: repeating
"Unexpected error fetching holabrain data … Token has expired" and an integration stuck
on Retrying setup. The stored account and password were always there; nothing was ever
asking them to be used.If you hit this, no action is needed beyond updating — the next request signs in again by
itself. The workaround before this release was HolaBrain → ⋮ → Reconfigure, which
drops the stored session. -
Code
14005is no longer treated as an expired token. It was a guess standing in for the
code above, and the only message ever seen with it reads "unusual activity" — the wording
of a session taken over by another client. It now takes the conservative path, which still
recovers but serves the reclaim cool-down first.
v0.17.0
Added
-
Debug logging that makes a cloud problem reportable in one pass. With
custom_components.holabrain: debugthe log now records every request as
path -> HTTP status in N ms, the business code and message behind any non-success
answer, which command dialect and signature each appliance was given, which
authentication branch ran and how much of the re-login budget is left, and the push
channel connecting, dropping and re-subscribing. See
docs/diagnostics.md.Appliance ids are replaced by the same pseudonyms the diagnostics dump uses, so a log and
a dump can be read together and neither identifies your appliances. Request and response
bodies are not logged at any level. One caveat worth knowing before you attach a log:
httpxis not ours and prints full URLs atinfo, so the documented snippet quiets it.
v0.16.3
Fixed
- Cloud errors now name the code the cloud returned. A business code the integration does
not classify used to surface as the cloud's own text alone — "Token has expired" with no
number — which describes the symptom but not the mapping entry that is missing, and
nothing else in the request path records it. If you are seeing an error like that, the
number in the new message is exactly what a bug report needs.
Changed
- Documentation for the
0xE2water heater now records what the appliance actually does
with a setpoint sent while Smart is active: it neither rejects nor applies it, but leaves
Smart and restores the previous setpoint. The refusal Home Assistant raises is therefore
preventing a silent mode change, not mirroring a refusal by the appliance.
v0.16.0
Added
- Water heater: a
remaining_timesensor (minutes to setpoint, while heating) and afault
problem sensor.
Changed
-
Breaking — the water heater's operation modes are different values.
operation_list
offerednormal,eco,smartandhigh_temp, read as independent flags. It now offers
the three mutually exclusive modes the vendor app's own "Model" picker shows —
single,double,smart— matching raw payloads captured from one unit
(Terma AquaPro WiFi,51020ED8; see docs/hcl.md).Old mode Use instead normaldouble(both tanks) is the closest equivalent;singleif your unit heats oneeconothing — it was sent to the appliance and never came back in a status response, and the app has no Eco control high_tempnothing — it belongs to the app's separate scheduled disinfect cycle, not to this picker, and is left for its own release Two things break, and the second one needs no service call at all. Any automation,
script or scene that still setsnormal,ecoorhigh_tempnow fails outright with
Operation mode … is not valid, so those calls must be edited by hand. And the entity's
own state string changes on every0xE2water heater whether or not you ever touch the
service: what readnormalnow readssingle,doubleorsmart— orunknownon a
model that reports neitherbodyNumnorcloudSmart. Recorder history keeps the old
strings for past periods, so a history graph shows a discontinuity, and templates or
conditions comparing against'normal','eco'or'high_temp'stop matching. -
The water heater refuses
water_heater.set_temperaturewhile Smart is active instead of
sending a setpoint the appliance overrides — Smart picks its own (it went straight to the
maximum on the unit above), and the vendor app disables manual entry there too. The call
raises rather than the control disappearing, so an automation is told what happened
instead of silently doing nothing.
Fixed
- Appliances on a non-direct
thingProtocol(for example some0xE2water heaters) could
never load: the status query and command endpoints for that dialect were signed with the
wrong scheme and pointed at a path the cloud answers with 404. Setup now reaches those
appliances instead of retrying forever with "the cloud could not be reached for any
appliance". - Water heater
current_temperaturecould read as the setpoint instead of the tank's
actual temperature on models that reporttargetTempbut notcur_temperature— the
cloud's field names are swapped from what they suggest (tempis the setpoint,
targetTempis the measured temperature). - Water heater models that report neither
bodyNumnorcloudSmartnow show their
operation mode as unknown instead of claimingdouble— the integration has no evidence
of those units' tank count. - A cloud HTTP error whose body carried no business code (a 404 on an unknown path, a 5xx
from the gateway) was read as a successful, empty response. That could empty the device
inventory — and with it remove every device — turn an outage into a "re-enter your
password" prompt, and report writes that never reached the appliance as done. Such
responses now fail with the path and the status code.
v0.15.0
Added
- Action
holabrain.refresh_tokenand a disabled-by-default Refresh token button on the
account device: sign in again with the stored credentials when a session is stuck. Both
claim the account's only session and sign the mobile app out.
Fixed
- An expired access token is now replaced immediately instead of being counted as a session
taken over by another client. Ordinary token expiry no longer escalates the reclaim
cool-down, which could leave a later poll refused outright. - Credentials the cloud rejects no longer trigger another login attempt with the same
password.
v0.14.0
Added
-
An appliance category the integration does not model yet is no longer invisible. It
produced no device and no entity, only a repair issue, so "my fridge is on the account and
Home Assistant ignores it" read as a broken setup rather than a missing feature. Such an
appliance now gets a device and one sensor per status field it reports.The fallback is deliberately timid: raw cloud key names, no units, no device classes,
everything diagnostic and disabled by default, and nothing writable. Nothing states what
those keys mean or what scale they use — a guessed unit is what made a dishwasher report
tens of megawatt-hours, and a guessed command would be worse than a wrong reading.
Enabling one is the user saying "I recognise this number", which is also the evidence
needed to model the category properly.
v0.13.0
Removed
- The appliance's raw lifetime counters (
total_cycles,total_water,total_energy).
Nothing states their scale — the vendor's own app never reads those fields — so theWh
andLlabels were a guess, and against the cloud's own figures the energy one was out by
a factor of ten, which is how a dishwasher came to report tens of megawatt-hours. They
also disappear from the status while the appliance is off, and atotal_increasingsensor
reads a gap followed by a return as a meter replacement, inflating long-term statistics
without bound. The consumption sensors added in 0.12.0 carry the same information in units
the cloud states itself.
Added
- The ecosystem's appliance-type catalogue. An appliance the integration does not model
yet was reported as a bare token like0xCA, which reads as a malfunction rather than a
missing feature. The repair issue now says "Refrigerator (0xCA)", and the catalogue — 14
types and the models sold under each — is included in diagnostics, which is what makes a
report about an unsupported appliance actionable. An unreachable catalogue degrades to the
raw code rather than to silence. - The operating mode is recorded in diagnostics, so a report about stale readings can be
told apart from one about a dead push channel.
v0.12.1
Fixed
- The consumption figures could stay blank for ever. They are fetched once when the account
first answers; if that attempt lost the race for the session, cooperative mode — which
schedules no further polls once it has data — never tried again, and the only way out was
a button the user had no reason to suspect they needed. Any later proof the account is
reachable, a push frame included, now triggers the retry. - Consumption sensors had no names of their own and fell back to "Electricity", "Electricity
2" and so on. Named in all five languages. - The account device was named after the account's e-mail address, and Home Assistant builds
entity ids from device names — so the address ended up in every automation referencing the
mode switch, every log line and every screenshot attached to a bug report.