Skip to content

startup_reset_registers() crashes the whole app on a SolisCloud timeout, requires manual restart #5202

Closed as not planned

Description

@LarsSchuy

Version: v9.1.0, Solis integration (solis_automatic: true, solis_control_enable: true)

Summary: When solis_control_enable is turned on, startup_reset_registers() (solis.py:3496) calls read_cid() to read SOLIS_CID_BATTERY_OVER_DISCHARGE_SOC. If that call hits a SolisCloud API timeout, _with_retry() exhausts its retries and re-raises (solis.py:692), and nothing catches it at the run() level (solis.py:3566) or in component_base.py's asyncio.wait_for(asyncio.shield(task), ...) wrapper (line 266). The whole app hangs - no further log output, no automatic recovery - until the add-on is manually restarted.

This is inconsistent with the rest of the Solis integration: most other API call sites (e.g. fetch_inverter_data) clearly catch the same kind of timeout and just log a Warn: line and continue polling. This one path doesn't.

Reproduction: With solis_control_enable: true, restart the add-on (or Home Assistant core, which forces a Predbat restart) during a period of elevated SolisCloud API latency. Observed 4 times in ~25 minutes on 2026-09-22, each time requiring a manual add-on restart via Supervisor. solis_control_enable: false never triggers this path at all.

Traceback:

Traceback (most recent call last):
  File "/config/component_base.py", line 266, in start
    run_result = await asyncio.wait_for(asyncio.shield(task), timeout=self.run_timeout)
  File "/config/solis.py", line 3566, in run
    await self.startup_reset_registers(sn)
  File "/config/solis.py", line 3496, in startup_reset_registers
    value = await self.read_cid(device_sn, SOLIS_CID_BATTERY_OVER_DISCHARGE_SOC)
  File "/config/solis.py", line 721, in read_cid
    return await self._with_retry(read_operation)
  File "/config/solis.py", line 692, in _with_retry
    raise err
  File "/config/solis.py", line 680, in _with_retry
    return await operation()
  File "/config/solis.py", line 704, in read_operation
    data = await self._execute_request(SOLIS_READ_ENDPOINT, payload)
  File "/config/solis.py", line 667, in _execute_request
    raise SolisAPIError(f"Timeout accessing {url}") from err
solis.SolisAPIError: Timeout accessing https://www.soliscloud.com:13333/v2/api/atRead

Suggested fix: wrap the startup_reset_registers() call (or the individual read_cid call within it) in a try/except that logs a warning and continues, matching the pattern used elsewhere in the file, rather than letting it propagate and stall the run loop.

Activity

  1. springfall2008 commented on Sep 23, 2026

    @springfall2008
    Owner

    Automated first-pass triage — a maintainer will review before any action is taken.

    Classification: bug — duplicate of #5177, which reports the same failure with a different trigger error.

    What I verified against current main (8b9fe029, v9.1.0-58):

    • The path you report is present and unguarded on main. In the first-cycle block of run(), await self.startup_reset_registers(sn) has no try/except (solis.py:3566). Your traceback's line numbers (solis.py:3566 and 3496) match current main exactly, so your install matches main in this area — the bug is live there.
    • One correction to the report: the app does not hang permanently. SolisAPIError derives from Exception (solis.py:382), so the escaped exception is caught by the generic handler in ComponentBase.start() (component_base.py:373) — it is logged, the loop survives, and because first never clears, the component re-enters the startup backoff loop (60 s doubling up to 128 minutes between attempts, component_base.py:328-329) and never starts. The add-on keeps running, but the Solis component stays dead until restarted or until an attempt finally succeeds, and each retry re-logs the same traceback up to two hours apart. That matches your experience of a component needing manual restarts; it is endless-backoff rather than a true hang.
    • The solis_control_enable gate is confirmed: the call only happens when control_enable is on and the inverter reports a battery (solis.py:3564-3566), which matches your observation that solis_control_enable: false never reaches this path.

    Duplicate assessment: #5177 reports the same unguarded startup_reset_registers() call aborting startup — its trigger was a persistent B0600 datalogger refusal, yours is a SolisCloud timeout. Both are SolisAPIErrors escaping the same call site, and both need the same fix.

    Fix status: PR #5185 (opened for #5177, still open pending review) already fixes exactly this: it wraps the call at solis.py:3566 in a try/except that logs Warn: Solis API: Startup register reset failed for inverter <sn>, continuing without it and continues startup. Since the timeout raises SolisAPIError, an Exception subclass, that guard covers your case too. It also adds B0600 to the no-retry code list and gives B0600 a per-inverter cooldown like B0115's. Your suggested fix matches what that PR implements.

    Closing as a duplicate — please follow #5177 and PR #5185 for the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BOT_TRIAGEDHas been through the triage botbugSomething isn't workingduplicateThis issue or pull request already existspriority_mediumsolis

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions