You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have observed a bug where my SolarFlow batteries (sf2400ac and sf2400ac+) remain in INACTIVE state even when there is a significant solar surplus (over 1000W of grid injection). The batteries stay in "Idle" mode and refuse to transition to "Charge" mode because the internal power distribution logic fails to handle the negative sign convention used by these AC models.
To Reproduce
Have a SolarFlow AC or AC+ battery in INACTIVE state (Idle).
Configure the device with a fusegroup (in my case: "Device has its own circuit or phase" for each battery).
Generate a solar surplus (negative P1 value) between 0W and 1200W.
Observe that the battery remains in INACTIVE state and does not start charging, despite the surplus being available.
The system only recovers if the surplus exceeds ~1200W or after a long delay via the "50W pulse" fallback mechanism.
Expected Behaviour
The batteries should immediately transition to CHARGE mode as soon as a negative surplus (injection) is detected on the P1 meter, respecting the SmartMode.POWER_START threshold.
Ironically, in my case, the only thing that eventually "saves" the system and starts the charge is a communication bottleneck on the battery side. The internal ESP processor sometimes fails to keep up with the volume of requests, leading to timeouts.
The system is stuck in the 0W bootstrap loop.
It sends periodic -50W pulses to "test" the idle batteries.
Multiple HTTP TimeoutErrors (due to the ESP being overwhelmed) delayed the state update for over a minute.
When a request finally succeeded, it reported a 49W consumption.
This 49W value (from the pulse) is what finally moved the battery to the charge list, breaking the 0W capping logic. Without these communication timeouts and the 50W fallback, the system would likely stay stuck at 0W indefinitely.
Evidence: Timeline of the failure (2026-03-25)
Time (Local)
Solar Prod
House Cons
Net Export
Battery State
Battery Charge
Status
09:13:45
1116 W
56 W
-1060 W
INACTIVE
0 W
Stuck (Bug)
09:13:50
1116 W
56 W
-1060 W
INACTIVE
0 W
Stuck (Bug)
09:13:55
1116 W
56 W
-1060 W
INACTIVE
0 W
Stuck (Bug)
09:13:57
1116 W
56 W
-1060 W
ACTIVE
-1019 W
Recovered via Fallback
Technical Analysis: The "1200W Invisible Wall"
For sf2400ac models, the integration defines a "Charge Limit" of -2400W. The manager calculates an "Optimal Charge" (1/4 of the limit), resulting in -600W.
The wake-up condition if dev_start < 0 is never met as long as the surplus is less than 1200W because: dev_start = Surplus(-1000) - (Optimal_Charge(-600) * 2) = +200 (which is > 0).
graph TD
A[Surplus Detected: -1000W] --> B{Are batteries charging?}
B -- No --> C[Calculate dev_start threshold]
C --> D["dev_start = Surplus - (Optimal_Charge * 2)"]
D --> E["dev_start = -1000 - (-600 * 2) = +200"]
E --> F{Is dev_start < 0?}
F -- No (+200) --> G[STAY IN IDLE]
F -- Yes --> H[WAKE UP BATTERY]
G --> I[Invisible Wall: No charging starts]
Loading
Affected Code (manager.py)
# custom_components/zendure_ha/manager.py:531limit=self.charge_limit# is 0 if no batteries are chargingsetpoint=max(limit, setpoint) # max(0, -1069) = 0W. Surplus is deleted.# custom_components/zendure_ha/manager.py:558if (dev_start:=dev_start-d.charge_optimal*2) >=0: # logic fails with negative optimalbreak
Proposed Fix
Use Absolute Values: Update formulas to use abs(charge_optimal) to handle both positive and negative sign conventions.
Protect Setpoint during Bootstrap: Allow the setpoint to remain negative even if the current active limit is 0, as long as idle batteries are available.
Home Assistant Version
2026.3.4
Zendure Integration Version
1.2.7-pre3
Describe the bug
I have observed a bug where my SolarFlow batteries (sf2400ac and sf2400ac+) remain in
INACTIVEstate even when there is a significant solar surplus (over 1000W of grid injection). The batteries stay in "Idle" mode and refuse to transition to "Charge" mode because the internal power distribution logic fails to handle the negative sign convention used by these AC models.To Reproduce
INACTIVEstate (Idle).INACTIVEstate and does not start charging, despite the surplus being available.Expected Behaviour
The batteries should immediately transition to
CHARGEmode as soon as a negative surplus (injection) is detected on the P1 meter, respecting theSmartMode.POWER_STARTthreshold.What device are you using?
Log Extracts
Other Information
The "HTTP Timeout Rescue" (Strange Recovery)
Ironically, in my case, the only thing that eventually "saves" the system and starts the charge is a communication bottleneck on the battery side. The internal ESP processor sometimes fails to keep up with the volume of requests, leading to timeouts.
charge list, breaking the 0W capping logic.Without these communication timeouts and the 50W fallback, the system would likely stay stuck at 0W indefinitely.
Evidence: Timeline of the failure (2026-03-25)
Technical Analysis: The "1200W Invisible Wall"
For sf2400ac models, the integration defines a "Charge Limit" of -2400W. The manager calculates an "Optimal Charge" (1/4 of the limit), resulting in -600W.
The wake-up condition
if dev_start < 0is never met as long as the surplus is less than 1200W because:dev_start = Surplus(-1000) - (Optimal_Charge(-600) * 2) = +200(which is > 0).graph TD A[Surplus Detected: -1000W] --> B{Are batteries charging?} B -- No --> C[Calculate dev_start threshold] C --> D["dev_start = Surplus - (Optimal_Charge * 2)"] D --> E["dev_start = -1000 - (-600 * 2) = +200"] E --> F{Is dev_start < 0?} F -- No (+200) --> G[STAY IN IDLE] F -- Yes --> H[WAKE UP BATTERY] G --> I[Invisible Wall: No charging starts]Affected Code (manager.py)
Proposed Fix
abs(charge_optimal)to handle both positive and negative sign conventions.setpointto remain negative even if the current activelimitis 0, as long as idle batteries are available.