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
{{ message }}
Repository navigation
Hanchu: battery_rate_max / inverter_limit depend on held power limits, not the unit's rating #5664
ranges_for raises the power ceiling to whatever the device currently holds, and battery_rate_max / inverter_limit are derived from that. On the tested 6.0K this gives the right figures (5000 / 6000) only because its limits happen to be set that way. The result depends on what the limits were last set to, not on the unit:
Situation
Result
Manual
6.0K with discharge limit set to e.g. 4000
inverter_limit 5000 (menu max)
6000
6.0K with charge limit set to 6000
battery_rate_max 6000
5000
3.0 / 3.68 / 4.0K at defaults
inverter_limit 5000
3000 / 3680 / 4000
7 / 8 / 10K holding 5000 or less
5000 for both
7000 / 8000 / 10000
The model is known (e.g. HESS-HY-S-6.0K), so a lookup table from the manuals would be reliable, with held values used only for models not in the table and the user overrides winning as now. Figures from the Hanchu user manuals (full per-model detail in my comment on #5305):
Single phase 3.0–6.0K: battery 5000 W for all; AC 3000 / 3680 / 4000 / 5000 / 6000 W.
Single phase 7 / 8 / 10K: battery = AC = 7000 / 8000 / 10000 W.
Three phase (T-05K…12K, T-4K-M…12K-M, T-10K-M4…20K-M4, CESS 25–50K): battery charge power = rated AC output in every case.
"6 kW" covers three different limits (S-6.0K 5000 W, T-06K 6000 W, T-6K-M 6 kW), so matching needs the full model string. The _warn_if_default_power docstring ("3.68, 5, 6 and 10 kW, so the default is wrong for most") also needs updating: the 5000 W default is correct for the 3.68 and 6 kW battery limit.
Evidence: this is a code reading against the manufacturer's specifications, not a runtime fault on my unit (HESS-HY-S-5.0K, where everything is 5000 W). The manual pages are summarised on #5305; I can attach screenshots of the spec tables if useful.
For information (not separate problems): slots crossing midnight work on my unit for charge, but keeping the split is the safe choice; and DTU_AC_CHG_SOC_LMT is confirmed as the right key for the charge target. My BLE setup uses it daily to stop grid charging, and CHG_BAT_SOC_LMT caps solar too, so never writing it is correct.
🤖 This is an automated first-pass triage — a maintainer will review before any action is taken.
This ticket reports several distinct problems in one place, so detailed triage is on hold until it is split — the convention here is one problem per ticket, because each problem gets its own investigation and (if it goes ahead) its own fix PR. Reading your list, the separate problems are:
Power limits taken from held values — ranges_for raises the power ceiling to whatever the device currently holds, so battery_rate_max / inverter_limit end up depending on the last-set limits rather than on the unit; a lookup table from the manuals, with held values used only for models not in it, would be reliable. ← trim this ticket down to this one
Freeze export will not freeze — on your unit CHG_PWR_LMT only governs charging the battery from the grid, so surplus solar charges the battery regardless and freeze export does nothing; the proposed CHG_BAT_SOC_LMT fallback also couldn't go below 50% SoC.
Hold: backstop on grid charging — during a hold, also write DTU_AC_CHG_SOC_LMT at the current SoC (minimum 20) in the same iotSet, so grid charging stops even if the 0 W write did not take.
Minor: docs — Predbat overwrites all three charge and all three discharge slots, so anything set in the Hanchu app is cleared when Predbat takes control; worth a line in the docs for users moving from the app.
Your midnight-slots note and the confirmed charge-target key are information rather than problems, so they don't need tickets of their own; the hold-slot rewrite question fits naturally alongside the hold issue you open for the backstop.
Please:
Trim this issue down to the power-limits problem above (adjust the title/body to match), and
open one new issue for each of the others — freeze export, the hold backstop, and the docs line — carrying over the relevant section from here.
In each new issue, please add the evidence that fits that problem: a predbat_debug.yaml and predbat.log captured while the behaviour is happening, both from the Debug panel on Predbat's web interface (the debug file downloads as predbat_debug.yaml.txt and can be attached as-is), or if an incident is over the debug snapshot for that time from the Debug column of the plan's History view — see the debug history docs. For these Hanchu items also useful: any Hanchu-side or component logs of the calls being made, screenshots of the relevant limits in the Hanchu app, your apps.yaml renamed to apps.txt, and when it happened (date, time, timezone).
Detailed triage of each part will follow once they are separate.
changed the title [-]Hanchu cloud component: follow-up from #5305 (power limits, freeze export, midnight slots, hold)[/-][+]Hanchu: battery_rate_max / inverter_limit depend on held power limits, not the unit's rating[/+]on Oct 20, 2026
Evidence from the harness (python3 hanchu.py --dump-menu) on my HESS-HY-S-5.0K. The menu's power limit items list the models they apply to:
CHG_PWR_LMT type 1 0-5000 models HESS-HY-S-3.0K,HESS-HY-S-3.68K,HESS-HY-S-4.0K,HESS-HY-S-5.0K,HESS-HY-S-6.0K,HESS-HY-S-7.0K,HESS-HY-S-8.0K,HESS-HY-S-10.0K,HESS-HY-T-05K,HC-HY-SL-2K-G2,HC-HY-SL-2.5K-G2,HC-HY-SL-3K-G2,HC-HY-SL-3.68K-G2,HC-HY-SL-4K-G2,HC-HY-SL-5K-G2,HC-HY-SL-6K-G2 when work_mode=3
DSCHG_PWR_LMT type 1 0-5000 (same model list)
So the menu itself gives 7.0K, 8.0K and 10.0K units a 5000 W ceiling, while their manual (HESS-HY-S-7K-10K, section 10.1) gives 7000 / 8000 / 10000 W charge and discharge. Those units will be capped at 5000 W unless they happen to hold a higher value. The other three-phase models (T-06K and up) are not in this item at all, so if their menu matches, they fall back to the 5000 W default.
Everything else read correctly on my unit: AC coupling detected and pv_power correct, status online, TCT_/TDT_ slots in work mode 3, all ranges from the menu, battery_rate_max and inverter_limit both 5000 W.
🤖 This is an automated follow-up triage review — a maintainer will review before any action is taken.
What's new since the last review: the ticket is now trimmed to the power-limits problem, with the other parts split out into #5665, #5667 and #5668 — the split is complete, thank you. The new comment also supplied harness evidence (--dump-menu on a HESS-HY-S-5.0K): the menu's CHG_PWR_LMT/DSCHG_PWR_LMT items are 0–5000 W items whose model list covers HESS-HY-S-3.0K–10.0K plus the HC-HY-SL-2K–6K-G2 range. The previous bot comment was a split request, so there was no assessment to revise — this is the first full triage of the trimmed ticket.
Verified against current main (b743b50 / v9.4.2-13, the commit that merged the component — nothing has changed since):
ranges_for (hanchu.py:751-774) applies the menu's bounds over built-in (0, 5000) defaults and raises both power-key ceilings to any higher value the device holds; battery_rate_max reads the charge-power ceiling (hanchu.py:829-840) and inverter_limit the discharge-power ceiling (hanchu.py:842-853). All four rows of the ticket's situation table reproduce from the code.
The new menu evidence strengthens the report: the menu's only power item is one 0–5000 W entry shared across models, so 7/8/10K units are capped at 5000 W unless holding a higher value, and models outside the entry's model list fall back to the 5000 W default. That menu behaviour on 7–10K and three-phase units is inferred from one device's menu, not observed on them. Note also _parse_menu_ranges (hanchu.py:663-684) ignores each item's productModel list — last match wins, and one key can appear several times, each for a different model set — so the menu could not discriminate by model today even where it names them.
_warn_if_default_power (hanchu.py:776-791) warns only when the power keys are absent entirely — a menu that answers with the shared 5000 W entry never warns, even where 5000 W is wrong for the model. Agreed its docstring is inaccurate as written: per the manuals the 5000 W default matches the battery limit on all single-phase 3.0–6.0K, and is wrong only for their AC ratings and the ≥7 kW models.
Mitigation exists today: the hanchu_battery_rate_max and hanchu_inverter_limit overrides win over the derived values (hanchu.py:838-839, 851-852).
Classification changed to bug, priority_low (the split gate had left it unclear with no assessment). The derived limits are the planner's only model of what the hardware can do, and they are wrong for nearly every Hanchu model; but the user overrides mitigate today, the component is a day old and flagged draft/unverified against hardware in its own merge commit, and the consequence is plan-quality bias rather than wrong control or hardware risk — the same treatment as the sibling ticket #5665. I've replaced this bot's own split-gate label unclear with bug + priority_low; I couldn't read the label-event history to double-check who applied unclear (the API call is unavailable in this session), so if that removal is wrong the maintainer can restore it. (There is no Hanchu-specific label in the repo to add.)
One-line bug statement: battery_rate_max and inverter_limit are derived from a menu range the API shares across models plus whatever the device currently holds, so they don't match the unit's rating for most Hanchu models; a table of manual ratings should take precedence, with held values only for models the table doesn't cover.
One question that decides the fix's shape: does a device-list entry carry a model string? The component reads only sn/devType from each entry (hanchu.py:498-521), the catalogue deliberately reports no model name (hanchu.py:1086-1088, where the device-list entry "may well have more fields"), and device_detail stores capacity/station/status only (hanchu.py:597-607). With tracing on (the harness default) your run has already printed the raw responses: the fields one device-list entry carries — from the Hanchu API response device_list trace line, with personal details removed — would settle whether the lookup table can key on the model as proposed, or needs the user to declare the model instead. (Screenshots of the manual spec tables aren't needed for this triage; they'd be welcome alongside a fix PR.)
Answering the question: the device-list entry carries no model string ({"devType": "2", "sn": "<serial>"} only), but getDeviceStatus already carries devModel, and the Hanchu web console maps it to a model name. From the console's JavaScript bundle (pcsEnMap):
Confirmed on my unit: devModel 4, and the console's Inverter Information panel shows "HESS-HY-S-5.0K". (The console's pcs/detail call also returns ratedPower: 5000.0, but that is a /gateway/platform/ endpoint, so devModel from getDeviceStatus looks the better source.)
With the manuals, that gives a complete table keyed on devModel:
Notes: codes are not in size order (7/8/10K were added as 30–32), so a lookup is needed rather than an ordinal. The menu also lists HC-HY-SL-*-G2 models, which are not in pcsEnMap (possibly a different brandCode); those, 28/29 and any unknown code would fall back to the current derivation, with the user overrides winning throughout.
Activity
springfall2008 commentedon Oct 20, 2026
🤖 This is an automated first-pass triage — a maintainer will review before any action is taken.
This ticket reports several distinct problems in one place, so detailed triage is on hold until it is split — the convention here is one problem per ticket, because each problem gets its own investigation and (if it goes ahead) its own fix PR. Reading your list, the separate problems are:
ranges_forraises the power ceiling to whatever the device currently holds, sobattery_rate_max/inverter_limitend up depending on the last-set limits rather than on the unit; a lookup table from the manuals, with held values used only for models not in it, would be reliable. ← trim this ticket down to this oneCHG_PWR_LMTonly governs charging the battery from the grid, so surplus solar charges the battery regardless and freeze export does nothing; the proposedCHG_BAT_SOC_LMTfallback also couldn't go below 50% SoC.DTU_AC_CHG_SOC_LMTat the current SoC (minimum 20) in the sameiotSet, so grid charging stops even if the 0 W write did not take.Your midnight-slots note and the confirmed charge-target key are information rather than problems, so they don't need tickets of their own; the hold-slot rewrite question fits naturally alongside the hold issue you open for the backstop.
Please:
In each new issue, please add the evidence that fits that problem: a
predbat_debug.yamlandpredbat.logcaptured while the behaviour is happening, both from the Debug panel on Predbat's web interface (the debug file downloads aspredbat_debug.yaml.txtand can be attached as-is), or if an incident is over the debug snapshot for that time from the Debug column of the plan's History view — see the debug history docs. For these Hanchu items also useful: any Hanchu-side or component logs of the calls being made, screenshots of the relevant limits in the Hanchu app, yourapps.yamlrenamed toapps.txt, and when it happened (date, time, timezone).Detailed triage of each part will follow once they are separate.
[-]Hanchu cloud component: follow-up from #5305 (power limits, freeze export, midnight slots, hold)[/-][+]Hanchu: battery_rate_max / inverter_limit depend on held power limits, not the unit's rating[/+]upton68 commentedon Oct 21, 2026
Evidence from the harness (
python3 hanchu.py --dump-menu) on my HESS-HY-S-5.0K. The menu's power limit items list the models they apply to:So the menu itself gives 7.0K, 8.0K and 10.0K units a 5000 W ceiling, while their manual (HESS-HY-S-7K-10K, section 10.1) gives 7000 / 8000 / 10000 W charge and discharge. Those units will be capped at 5000 W unless they happen to hold a higher value. The other three-phase models (T-06K and up) are not in this item at all, so if their menu matches, they fall back to the 5000 W default.
Everything else read correctly on my unit: AC coupling detected and pv_power correct, status online, TCT_/TDT_ slots in work mode 3, all ranges from the menu, battery_rate_max and inverter_limit both 5000 W.
springfall2008 commentedon Oct 21, 2026
🤖 This is an automated follow-up triage review — a maintainer will review before any action is taken.
What's new since the last review: the ticket is now trimmed to the power-limits problem, with the other parts split out into #5665, #5667 and #5668 — the split is complete, thank you. The new comment also supplied harness evidence (
--dump-menuon a HESS-HY-S-5.0K): the menu'sCHG_PWR_LMT/DSCHG_PWR_LMTitems are 0–5000 W items whose model list covers HESS-HY-S-3.0K–10.0K plus the HC-HY-SL-2K–6K-G2 range. The previous bot comment was a split request, so there was no assessment to revise — this is the first full triage of the trimmed ticket.Verified against current main (b743b50 / v9.4.2-13, the commit that merged the component — nothing has changed since):
ranges_for(hanchu.py:751-774) applies the menu's bounds over built-in(0, 5000)defaults and raises both power-key ceilings to any higher value the device holds;battery_rate_maxreads the charge-power ceiling (hanchu.py:829-840) andinverter_limitthe discharge-power ceiling (hanchu.py:842-853). All four rows of the ticket's situation table reproduce from the code._parse_menu_ranges(hanchu.py:663-684) ignores each item'sproductModellist — last match wins, and one key can appear several times, each for a different model set — so the menu could not discriminate by model today even where it names them._warn_if_default_power(hanchu.py:776-791) warns only when the power keys are absent entirely — a menu that answers with the shared 5000 W entry never warns, even where 5000 W is wrong for the model. Agreed its docstring is inaccurate as written: per the manuals the 5000 W default matches the battery limit on all single-phase 3.0–6.0K, and is wrong only for their AC ratings and the ≥7 kW models.hanchu_battery_rate_maxandhanchu_inverter_limitoverrides win over the derived values (hanchu.py:838-839, 851-852).Classification changed to
bug,priority_low(the split gate had left itunclearwith no assessment). The derived limits are the planner's only model of what the hardware can do, and they are wrong for nearly every Hanchu model; but the user overrides mitigate today, the component is a day old and flagged draft/unverified against hardware in its own merge commit, and the consequence is plan-quality bias rather than wrong control or hardware risk — the same treatment as the sibling ticket #5665. I've replaced this bot's own split-gate labelunclearwithbug+priority_low; I couldn't read the label-event history to double-check who appliedunclear(the API call is unavailable in this session), so if that removal is wrong the maintainer can restore it. (There is no Hanchu-specific label in the repo to add.)One-line bug statement: battery_rate_max and inverter_limit are derived from a menu range the API shares across models plus whatever the device currently holds, so they don't match the unit's rating for most Hanchu models; a table of manual ratings should take precedence, with held values only for models the table doesn't cover.
One question that decides the fix's shape: does a device-list entry carry a model string? The component reads only
sn/devTypefrom each entry (hanchu.py:498-521), the catalogue deliberately reports no model name (hanchu.py:1086-1088, where the device-list entry "may well have more fields"), anddevice_detailstores capacity/station/status only (hanchu.py:597-607). With tracing on (the harness default) your run has already printed the raw responses: the fields one device-list entry carries — from theHanchu API response device_listtrace line, with personal details removed — would settle whether the lookup table can key on the model as proposed, or needs the user to declare the model instead. (Screenshots of the manual spec tables aren't needed for this triage; they'd be welcome alongside a fix PR.)Applying
waiting_for_userfor that answer.upton68 commentedon Oct 21, 2026
Answering the question: the device-list entry carries no model string (
{"devType": "2", "sn": "<serial>"}only), butgetDeviceStatusalready carriesdevModel, and the Hanchu web console maps it to a model name. From the console's JavaScript bundle (pcsEnMap):Confirmed on my unit:
devModel4, and the console's Inverter Information panel shows "HESS-HY-S-5.0K". (The console'spcs/detailcall also returnsratedPower: 5000.0, but that is a/gateway/platform/endpoint, sodevModelfrom getDeviceStatus looks the better source.)With the manuals, that gives a complete table keyed on
devModel:Notes: codes are not in size order (7/8/10K were added as 30–32), so a lookup is needed rather than an ordinal. The menu also lists HC-HY-SL-*-G2 models, which are not in
pcsEnMap(possibly a differentbrandCode); those, 28/29 and any unknown code would fall back to the current derivation, with the user overrides winning throughout.fix(hanchu): event-loop write fix, #5672 review fixes, model ratings,…