Skip to content

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 #4415

Description

@iansyder8

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

  1. 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.
  2. 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.
  3. 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

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions