Repository navigation
Fox Cloud: support Feed-in First (freeze export) via the work-mode setting #5022
Description
(Claude wrote this issue, posted under my account.)
Split out of #5015, which turned off support_feedin_first for FoxCloud because the Cloud path never selects the mode. This issue tracks actually adding it.
Background
The Fox hardware does have a Feed-in First work mode, and Predbat already uses it on the modbus path: templates/fox.yaml ships a discharge_freeze_service stanza that selects "Feed-in First" on select.foxess_work_mode, published by the FoxESS HA integration.
The Cloud path has no equivalent. templates/fox_cloud.yaml contains no *_service stanzas at all, so during a freeze export slot adjust_export_immediate(..., freeze=True) calls call_service_template("discharge_freeze_service", ...), finds nothing configured, falls back to discharge_stop_service (also unset), and the freeze becomes a no-op. The inverter stays in Self Use.
Same hardware, different control surface.
What makes this look implementable
The Cloud component already publishes a writable work-mode select:
automatic_configwiresinverter_modetoselect.{prefix}_fox_{device}_setting_workmode(fox.py:2221)- that entity carries
enumList: OPTIONS_WORK_MODE, which includes"Feedin"(fox.py:44,fox.py:57) - writes route
select_event→write_setting_from_event→set_device_setting, a real Fox API write (fox.py:1994-2005)
So a discharge_freeze_service stanza in fox_cloud.yaml pointing at that select is plausibly most of the work — structurally the same as the modbus template, just a different entity id.
The catch
adjust_inverter_mode writes to that same inverter_mode entity and hardcodes SelfUse for any has_fox_inverter_mode inverter:
if self.inv_has_fox_inverter_mode:
# For fox we only use selfuse as the rest is done by schedule
new_inverter_mode = "SelfUse"(inverter.py:2443-2444, added in #2659, Sept 2025.)
A service call setting Feedin would be reverted to SelfUse on the next cycle — the two would fight. So the template stanza alone is not sufficient; the hardcode needs to learn that freeze export is a legitimate third state. That comment's premise ("the rest is done by schedule") holds for Cloud but not for modbus, which is why one brand-named flag spanning both control paths leaves this gap.
Also worth checking whether the scheduler writer (apply_battery_schedule, which rewrites the schedule each cycle and only emits ForceCharge/ForceDischarge) would interfere.
Caveats
- The Fox Cloud integration - Freeze Export planned but has no effect #5015 reporter notes that ~200W still flows into the battery even under Feed-in Priority on their inverter, so this will not be an exact SoC hold even when working.
write_setting_from_eventonly writes when the value actually changed, so ordering between the service call andadjust_inverter_modematters.- Needs validation on real Fox Cloud hardware — the enum lists say
Feedinis accepted, but that is not proof the API takes it in this context.
Once this works, support_feedin_first can go back to True for FoxCloud in config.py.
Related
- Fox Cloud integration - Freeze Export planned but has no effect #5015 — the bug this was split from (planner modelled the mode; execute never delivered it)
- FoxESS Freeze Export mode predicts no battery charge, but the battery does charge #4207 / fix(plan): let PV surplus charge the battery during an export freeze #4425 — where the modbus Feed-in First modelling came from
- Auto-config: two vendor components silently overwrite each other's inverter args #4824, Unneccessay updates to inverter causing eeprom wear #2328 — other instances of declared capability disagreeing with observed behaviour
Activity
springfall2008 commentedon Sep 9, 2026
Automated first-pass triage — a maintainer will review before any action is taken.
Classification: enhancement (labels
enhancement/foxalready applied — no change).Investigation against main (
d48cb223, v8.55.1-9-gd48cb223) — every code pointer in the issue verifies:templates/fox.yamldoes shipdischarge_freeze_serviceselecting"Feed-in First"onselect.foxess_work_mode;templates/fox_cloud.yamlhas no*_servicestanzas at all, so the Cloud freeze falls throughcall_service_templateand no-ops.OPTIONS_WORK_MODEincludesFeedin(fox.py:44) andautomatic_configwiresinverter_modetoselect.{prefix}_fox_{device}_setting_workmode(fox.py:2221), with writes routedselect_event→write_setting_from_event→set_device_settingand a write-only-on-change guard (fox.py:~1995) — so the proposed template stanza is indeed structurally the same as the modbus one.adjust_inverter_modehardcode is real and live:if self.inv_has_fox_inverter_mode: new_inverter_mode = "SelfUse"(inverter.py:2442-2444) — aFeedinwrite would be reverted on the next execute cycle, so the template stanza alone is not sufficient, as the issue states.freeze=True→discharge_freeze_service, falling back todischarge_stop_service; with neither configured for FoxCloud neither fires and the inverter stays in Self Use. This is exactly the Fox Cloud integration - Freeze Export planned but has no effect #5015 symptom.One correction: the issue states #5015 "turned off"
support_feedin_firstfor FoxCloud. It did not — no commit has.support_feedin_first: Truehas been set for FoxESS and FoxCloud since commit3ed9151e(24 Aug, the #4207 modelling change), and #5015 itself is still open. That state is the sharper version of the problem: the flag beingTruemeans prediction.py's freeze branch models PV recapture as charging the battery, while the Cloud execute path still cannot select Feed-in — so the plan shows a working freeze that execution never delivers. The enhancement remains as described; only the flag premise is backwards.No regression test was run — this is a feature request, not a behavioural claim against an existing test module. The implementation questions it raises (ordering vs
adjust_inverter_mode, and whetherapply_battery_schedulere-emitting ForceCharge/ForceDischarge fights the mode write) are for the PR that implements this and will need real-hardware validation, as the issue already flags.fix(fox): do not let an eventually consistent scheduler read skip a w…
chalfontchubby commentedon Sep 10, 2026
5015 can close then if you are happy
feat(fox): select Feed-in First for a Fox Cloud freeze export (spring…