Solis GS_fb00: timed_discharge_current / timed_charge_current reset to 0A on every cycle and are never re-asserted, so forced export does nothing
Summary
On a Ginlong Solis (inverter_type: GS_fb00) via solax_modbus, the inverter's timed charge/discharge current registers are reset to 0A outside of Predbat's control. Predbat only writes those registers when its cached charge/discharge rate changes — which in normal operation is rare — so once zeroed they stay at zero indefinitely.
The practical effect: Predbat sets up a forced export window and correctly writes every slot time register and scheduled_discharge_enable, but because the timed discharge current is 0A the inverter neither exports nor supplies the house from the battery. The house falls back to importing at full rate with a nearly full battery sitting idle.
Measured cost in my case: ~4.1 kW of import at 30.4p/kWh through an evening export window, battery at 85%.
Evidence below shows the reset is deterministic — it happens on every single Predbat cycle, roughly 120 times overnight without exception.
Environment
|
|
| Predbat version |
v8.47.2 (auto-updated from v8.47.1 mid-log) |
| Inverter type |
GS_fb00 — Ginlong Solis (FB00) |
| Integration |
homeassistant-solax-modbus (version: 2026.08.1) |
| Solis firmware |
TODO |
| Transport |
RS485 → Waveshare RS485-to-ETH gateway, Modbus TCP↔RTU, multi-host enabled, 9600 baud |
| Battery |
soc_max: 32.0 kWh, battery_voltage: 52, battery_rate_max: 8000 W |
Evidence 1 — Predbat writes the current register once in 16 hours
Every successful register write over a continuous 16-hour log (2026-08-01, 04:25 → 20:46):
| Register |
Writes |
idle_start_time |
40 |
discharge_end_time |
35 |
discharge_end_hour |
33 |
idle_end_time |
23 |
discharge_start_time |
20 |
discharge_end_minute |
20 |
discharge_start_minute |
19 |
discharge_start_hour |
12 |
reserve |
3 |
inverter_mode |
3 |
discharge_rate |
2 |
charge_end_time |
2 |
charge_end_minute |
2 |
charge_end_hour |
2 |
timed_discharge_current |
1 |
charge_start_time |
1 |
charge_start_hour |
1 |
timed_charge_current |
0 |
timed_discharge_current appears exactly twice in the whole log:
04:26:05: Inverter 0 write_and_poll_value: No write needed for timed_discharge_current: 0.0 == 0.0 fuzzy 1
04:30:49: Inverter 0 write_and_poll_value: Wrote 153.8 to timed_discharge_current, successfully now 153.8
and that single write is paired with the only rate change of the day:
04:26:05: Wrote 0 to discharge_rate, successfully now 0.0
04:30:44: Wrote 8000 to discharge_rate, successfully now 8000.0
04:30:49: Wrote 153.8 to timed_discharge_current, successfully now 153.8
153.8 = 8000W / 52V, so the derivation is correct — the write path works, it just almost never runs.
timed_charge_current is never written at all, in either direction, anywhere in the log, despite being configured in apps.yaml. That looks like a separate gap in the GS_fb00 template.
Evidence 2 — the register is zeroed on EVERY cycle (deterministic)
I added a Home Assistant automation that rewrites 190A whenever either register drops below 1A, then recorded the register overnight. Home Assistant's recorder shows 239 state changes on number.solis_..._timed_discharge_current between 23:00 and 08:42 — approximately 120 zero → restore pairs, one per Predbat five-minute cycle, with no exceptions across nearly ten hours.
Representative sample:
03:15:39 → 0.0 (zeroed, coincident with Predbat's cycle)
03:15:49 → 190.0 (restored by my automation, ~10s later)
03:20:39 → 0.0
03:20:49 → 190.0
03:25:39 → 0.0
03:25:49 → 190.0
So this is not sporadic or environmental — the reset tracks Predbat's write cycle exactly. Predbat rewrites the slot time registers on essentially every cycle, and the current register is cleared each time.
Because sensor.predbat_GS_fb00_0_discharge_rate had not changed since 04:30 (and ..._charge_rate not since 30 July), Predbat saw no rate change and therefore never re-asserted the current. Without external intervention the register stays at 0A indefinitely — in the first occurrence, 16 hours spanning multiple charge and export windows.
Evidence 3 — the consequence
At 21:18, inside a forced-export window, battery at 85% (well above both battery_min_soc 10% and reserve 15%):
| Measurement |
Value |
timed_discharge_current |
0.0 A |
| Battery power |
0 W |
| Grid |
4,104 W importing |
| House load |
4,062 W |
| Inverter status |
Generating |
predbat.status |
Exporting |
Writing a non-zero value to the register by hand restarted the battery within ~3 seconds:
|
Before |
After |
| Battery |
0 W |
4,254 W discharging |
| Grid |
4,104 W import |
24 W |
Evidence 4 — export also stalls even when the register is correct
Separately, and possibly a distinct issue: with the register held at 190A continuously and verifiably, grid export still ran only in short bursts aligned to Predbat's five-minute cycle:
| Window |
Grid (positive = export) |
| 22:56 – 23:00:06 |
~0 W |
| 23:00:16 – 23:00:46 |
+6,232 to +6,282 W |
| 23:00:56 – 23:05:06 |
~0 W |
| 23:05:16 – 23:05:36 |
+6,105 to +6,244 W |
Roughly 30–40 seconds of export per five-minute cycle. Manually pressing the Update Discharge Times button restarted export, and it then held for about three minutes (23:11:06 → 23:13:56 at ~5.5 kW) rather than 40 seconds.
That suggests re-applying the discharge slot is what puts the inverter into forced export, and something in the register writes that follow drops it back out. I can't attribute this to Predbat rather than the Solis firmware with confidence, so I'm reporting it as an observation rather than a claim.
Expected behaviour
During an active charge or forced-export window, Predbat should ensure the timed current register actually reflects the intended rate, rather than assuming a previously written value has persisted.
Suggested fixes
- Re-assert the current alongside the slot times. Whenever Predbat writes the charge/discharge time registers, also write the corresponding
timed_charge_current / timed_discharge_current. write_and_poll_value already no-ops when the value matches, so the cost is one comparison per cycle.
- Read back and correct. Predbat already reads the register (
No write needed for timed_discharge_current: 0.0 == 0.0) — it could compare against rate / battery_voltage every cycle and correct a mismatch, instead of only comparing when the rate itself changed. This is the cheapest fix: the read is already happening, only the comparison is gated.
- Check
timed_charge_current is wired up for GS_fb00 — it's configured in apps.yaml but never appears in the log in any form.
Workaround currently in use
A Home Assistant automation that rewrites the current registers whenever either reads below 1 A, plus a scheduled check before the overnight charge window. It writes the value only and deliberately does not press the update-times button, since that press appears to be what clears it.
Note for anyone else hitting this: don't use a numeric_state trigger alone. It only fires when a value crosses the threshold, so if the register is already at 0 when Home Assistant restarts or the automation reloads, the crossing never happens and the automation never runs. Add a time_pattern poll and a homeassistant: start trigger alongside it.
apps.yaml (relevant extract)
inverter_type: "GS_fb00"
solax_modbus_new: true
num_inverters: 1
battery_rate_max:
- 8000
soc_max:
- 32
battery_voltage:
- 52
charge_update_button:
- button.solis_fb002_inverter_update_charge_times
discharge_update_button:
- button.solis_fb002_inverter_update_discharge_times
scheduled_charge_enable:
- switch.solis_fb002_inverter_timed_charge_slot_1_enable
scheduled_discharge_enable:
- switch.solis_fb002_inverter_timed_discharge_slot_1_enable
charge_limit:
- number.solis_fb002_inverter_timed_charge_soc
timed_charge_current:
- number.solis_fb002_inverter_timed_charge_current
timed_discharge_current:
- number.solis_fb002_inverter_timed_discharge_current
charge_start_hour:
- number.solis_fb002_inverter_timed_charge_start_hours
charge_start_minute:
- number.solis_fb002_inverter_timed_charge_start_minutes
charge_end_hour:
- number.solis_fb002_inverter_timed_charge_end_hours
charge_end_minute:
- number.solis_fb002_inverter_timed_charge_end_minutes
discharge_start_hour:
- number.solis_fb002_inverter_timed_discharge_start_hours
discharge_start_minute:
- number.solis_fb002_inverter_timed_discharge_start_minutes
discharge_end_hour:
- number.solis_fb002_inverter_timed_discharge_end_hours
discharge_end_minute:
- number.solis_fb002_inverter_timed_discharge_end_minutes
energy_control_switch:
- select.solis_fb002_inverter_energy_storage_control_switch
inverter_limit: 8800
inverter_battery_rate_min:
- 100
Attached
predbat-log-excerpt.txt — every mention of the current registers, every rate write, the full write census, and the 04:30 and 20:30–20:33 sequences.
predbat-log-excerpt.txt
Solis GS_fb00:
timed_discharge_current/timed_charge_currentreset to 0A on every cycle and are never re-asserted, so forced export does nothingSummary
On a Ginlong Solis (
inverter_type: GS_fb00) viasolax_modbus, the inverter's timed charge/discharge current registers are reset to0Aoutside of Predbat's control. Predbat only writes those registers when its cached charge/discharge rate changes — which in normal operation is rare — so once zeroed they stay at zero indefinitely.The practical effect: Predbat sets up a forced export window and correctly writes every slot time register and
scheduled_discharge_enable, but because the timed discharge current is0Athe inverter neither exports nor supplies the house from the battery. The house falls back to importing at full rate with a nearly full battery sitting idle.Measured cost in my case: ~4.1 kW of import at 30.4p/kWh through an evening export window, battery at 85%.
Evidence below shows the reset is deterministic — it happens on every single Predbat cycle, roughly 120 times overnight without exception.
Environment
GS_fb00— Ginlong Solis (FB00)homeassistant-solax-modbus(version: 2026.08.1)soc_max: 32.0kWh,battery_voltage: 52,battery_rate_max: 8000WEvidence 1 — Predbat writes the current register once in 16 hours
Every successful register write over a continuous 16-hour log (2026-08-01, 04:25 → 20:46):
idle_start_timedischarge_end_timedischarge_end_houridle_end_timedischarge_start_timedischarge_end_minutedischarge_start_minutedischarge_start_hourreserveinverter_modedischarge_ratecharge_end_timecharge_end_minutecharge_end_hourtimed_discharge_currentcharge_start_timecharge_start_hourtimed_charge_currenttimed_discharge_currentappears exactly twice in the whole log:and that single write is paired with the only rate change of the day:
153.8=8000W / 52V, so the derivation is correct — the write path works, it just almost never runs.timed_charge_currentis never written at all, in either direction, anywhere in the log, despite being configured inapps.yaml. That looks like a separate gap in theGS_fb00template.Evidence 2 — the register is zeroed on EVERY cycle (deterministic)
I added a Home Assistant automation that rewrites
190Awhenever either register drops below1A, then recorded the register overnight. Home Assistant's recorder shows 239 state changes onnumber.solis_..._timed_discharge_currentbetween 23:00 and 08:42 — approximately 120 zero → restore pairs, one per Predbat five-minute cycle, with no exceptions across nearly ten hours.Representative sample:
So this is not sporadic or environmental — the reset tracks Predbat's write cycle exactly. Predbat rewrites the slot time registers on essentially every cycle, and the current register is cleared each time.
Because
sensor.predbat_GS_fb00_0_discharge_ratehad not changed since 04:30 (and..._charge_ratenot since 30 July), Predbat saw no rate change and therefore never re-asserted the current. Without external intervention the register stays at0Aindefinitely — in the first occurrence, 16 hours spanning multiple charge and export windows.Evidence 3 — the consequence
At 21:18, inside a forced-export window, battery at 85% (well above both
battery_min_soc10% andreserve15%):timed_discharge_currentpredbat.statusWriting a non-zero value to the register by hand restarted the battery within ~3 seconds:
Evidence 4 — export also stalls even when the register is correct
Separately, and possibly a distinct issue: with the register held at
190Acontinuously and verifiably, grid export still ran only in short bursts aligned to Predbat's five-minute cycle:Roughly 30–40 seconds of export per five-minute cycle. Manually pressing the Update Discharge Times button restarted export, and it then held for about three minutes (23:11:06 → 23:13:56 at ~5.5 kW) rather than 40 seconds.
That suggests re-applying the discharge slot is what puts the inverter into forced export, and something in the register writes that follow drops it back out. I can't attribute this to Predbat rather than the Solis firmware with confidence, so I'm reporting it as an observation rather than a claim.
Expected behaviour
During an active charge or forced-export window, Predbat should ensure the timed current register actually reflects the intended rate, rather than assuming a previously written value has persisted.
Suggested fixes
timed_charge_current/timed_discharge_current.write_and_poll_valuealready no-ops when the value matches, so the cost is one comparison per cycle.No write needed for timed_discharge_current: 0.0 == 0.0) — it could compare againstrate / battery_voltageevery cycle and correct a mismatch, instead of only comparing when the rate itself changed. This is the cheapest fix: the read is already happening, only the comparison is gated.timed_charge_currentis wired up forGS_fb00— it's configured inapps.yamlbut never appears in the log in any form.Workaround currently in use
A Home Assistant automation that rewrites the current registers whenever either reads below 1 A, plus a scheduled check before the overnight charge window. It writes the value only and deliberately does not press the update-times button, since that press appears to be what clears it.
Note for anyone else hitting this: don't use a
numeric_statetrigger alone. It only fires when a value crosses the threshold, so if the register is already at0when Home Assistant restarts or the automation reloads, the crossing never happens and the automation never runs. Add atime_patternpoll and ahomeassistant: starttrigger alongside it.apps.yaml(relevant extract)Attached
predbat-log-excerpt.txt— every mention of the current registers, every rate write, the full write census, and the 04:30 and 20:30–20:33 sequences.predbat-log-excerpt.txt