Skip to content

fix: correct libbi charge target percentage calculation (resolves #727) - #749

Open
jtracey93 wants to merge 6 commits into
CJNE:mainfrom
jtracey93:fix/libbi-target-charge
Open

fix: correct libbi charge target percentage calculation (resolves #727)#749
jtracey93 wants to merge 6 commits into
CJNE:mainfrom
jtracey93:fix/libbi-target-charge

Conversation

@jtracey93

Copy link
Copy Markdown

Summary

Fixes #727number.myenergi_libbi_charge_target shows a lower percentage than the myenergi app for the same setting (e.g. app shows 70%, HA shows ~63%).

Root cause

TargetChargePercentSlider was dividing/multiplying by the full physical battery capacity (mbc), but the myenergi app uses the usable capacity which accounts for a hardware SoC reserve of ~9.8%.

The fix

The usable capacity ratio is 92/102 ≈ 0.9020 — consistent across all Libbi variants:

  • 10 kWh (mbc=10,200): 9,200 Wh usable → 9200/10200 = 92/102
  • 20 kWh (mbc=20,400): 18,400 Wh usable → 18400/20400 = 92/102

Sources: twonk/MyEnergi-App-Api docs + field data from issue #727.

Before fix (20 kWh battery, app set to 70%):

  • API returns energyTarget = 12880 Wh
  • HA displayed: 12.88 / 20.4 * 100 = 63%

After fix:

  • HA displays: 12.88 / (20.4 * 0.9020) * 100 = 70%

Changes

  • custom_components/myenergi/number.py

    • Add LIBBI_USABLE_CAPACITY_FACTOR = 92 / 102 constant (with explanation comment)
    • Fix native_value: divide by battery_size × factor; return None (not 0) when charge_target is None so HA correctly shows unknown when app credentials are absent
    • Fix async_set_native_value: multiply by battery_size * 1000 * factor; use round() consistently
  • tests/fixtures/client_libbi.json — new test fixture with mbc=20400

  • tests/conftest.py — add mock_libbi_set_charge_target fixture

  • tests/test_number.py — 5 new regression tests:

    • Read 100%: 18,400 Wh → 100 ✅
    • Read 70%: 12,880 Wh → 70 ✅
    • No credentials → unknown state ✅
    • Write 70% → 12,880 Wh sent to API ✅
    • Write 100% → 18,400 Wh sent to API ✅

The TargetChargePercentSlider was dividing/multiplying by the full
physical battery capacity (mbc), but the myenergi app uses the usable
capacity which accounts for a hardware SoC reserve of ~9.8%.

The usable capacity ratio is 92/102 (~0.9020) across all Libbi variants:
- 10 kWh (mbc=10200): 9200 Wh usable  (9200/10200 = 92/102)
- 20 kWh (mbc=20400): 18400 Wh usable (18400/20400 = 92/102)

Source: twonk/MyEnergi-App-Api docs + issue CJNE#727 field data.

Changes:
- Add LIBBI_USABLE_CAPACITY_FACTOR = 92 / 102 constant
- Fix native_value: use usable capacity as divisor; return None
  (not 0) when charge_target is None so HA shows 'unknown' instead
  of a misleading 0%
- Fix async_set_native_value: apply factor when converting % to Wh;
  use round() consistently instead of truncating int()
- Add tests/fixtures/client_libbi.json (mbc=20400)
- Add mock_libbi_set_charge_target fixture to conftest.py
- Add TargetChargePercentSlider tests: read 100%/70%/no-creds,
  write 70% -> 12880 Wh, write 100% -> 18400 Wh

Fixes CJNE#727

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@AJediIAm

AJediIAm commented Apr 8, 2026

Copy link
Copy Markdown
Collaborator

Can you have a look at the failed test?
The other failures can be ignored.

- Add Libbi.refresh_extra mock to setup helper to prevent OAuth calls
- Add client_fixture parameter to setup_mock_myenergi_config_entry
- Move assertions inside PropertyMock context for read tests
- Use real charge_target property for no-credentials test
- Migrate test_sensor.py to use client_fixture parameter

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jtracey93

Copy link
Copy Markdown
Author

@AJediIAm these should now be fixed

@AJediIAm

Copy link
Copy Markdown
Collaborator

@AJediIAm these should now be fixed

Sorry, the notification got snowed under.
Can you have another look at the tests?
Feel free to keep poking me to get this merged. I'll try to stay on top of it.

@AJediIAm

Copy link
Copy Markdown
Collaborator

@jtracey93 : are the failing tests caused by this PR or are they unrelated?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Charge target % is incorrect

2 participants