BLUETTI over local Modbus TCP — S Meter and Balco 260 working, Core PR open

Hi all,

Sharing where a community effort around BLUETTI hardware has got to, in case anyone
here owns one of these devices.

The starting point

BLUETTI’s official Home Assistant integration is cloud-based — OAuth against their
servers — and covers a broad range of power stations. It works, but it has two
limitations that matter for energy monitoring: it only reports instantaneous power in
watts, never cumulated energy in kWh, and on the Balco 260 it sends no battery power
at all. I confirmed the latter from a diagnostics dump: the field simply isn’t in the
payload. The only workaround was estimating battery power from the power balance,
which is accurate at rest and not much else.

Local Modbus fixes both

The community Modbus integration now reads two devices over local Modbus TCP: the
S Meter and the Balco 260. No cloud, no internet dependency, no latency.

What you get that the cloud API doesn’t provide:

  • Native cumulated energy counters — PV production, grid import and export, AC
    output, straight from the device in kWh. No Riemann sum helpers
  • Real battery energy, charged and discharged in Wh, plus SoC, SoH and cycle
    count. The estimation becomes unnecessary
  • Per-string PV data — power, voltage and current for each of the four MPPT
    inputs individually, which makes it possible to verify each panel separately
  • Inverter status, warnings and faults as enumerated values

:information_source: To be clear, this is independent of BLUETTI’s official integration, not a
replacement for it. Different scope: the official one covers the catalogue and
remote control over the cloud, this one covers local operation and more detailed
data. They can run side by side.

Core submission

A PR is open against Core, built on the new Modbus device architecture introduced in
2026.9:

It covers the Balco 260 only for now — Core maintainers ask for small, focused PRs,
which is entirely fair given the review volume. The S Meter follows in a separate PR,
then the remaining models one at a time.

A finding worth passing on

While testing persistent connections we switched our client library’s default backend
from pymodbus to tmodbus. Reason: pymodbus reports a truncated or corrupted
reply as a generic timeout, while tmodbus correctly surfaces it as
ModbusProtocolError. We lost a fair amount of time debugging “timeouts” that were
actually malformed frames. Worth knowing if you’re chasing a flaky Modbus device of
any brand.

Honest status

Young code, still rough in places. The devices’ own Modbus firmware has its share of
instability too — intermittent truncated frames, and a socket pool that can be
exhausted by rapid connections — both reported upstream to BLUETTI and worked around
client-side for now. Usable day to day, not yet bulletproof.

Where help is needed

Extending model coverage isn’t limited by development time. It’s limited by hardware
access: I own one Balco 260.

If you own any BLUETTI device, enabling Modbus TCP takes a couple of minutes (device’s
local web server, log in as admin with your BLUETTI app password, Settings →
Modbus TCP, port 502, then remember to hit save — it’s easy to miss). One read, and
the output tells us what’s mappable.

Best route is an issue or discussion on the repo rather than a reply here — it gets
tracked and searchable, and it helps whoever comes next:

Questions and feedback very welcome in this thread though.

That’s not really an issue of the code, so I thought I’d better write here instead of creating a github issue:
I cannot reach my AC500 via its IP. I can ping this IP, but there seems to be no webserver running I could connect to.
Is there some trick you didn’t add in the how-to?

Maybe this will help you, and maybe this one, too.
You need a specific version of the firmware.

Thanks, you are right, the *.17 version is offered yet I do not have any option to do the update itself. Maybe I need to contact the Bluetti support.

Try to clean cache apps, remove app, etc…
It should be popup an install :face_with_diagonal_mouth:

Two more devices — AC500 and AC200L / AC200L2 — and expansion packs on the Balco 260

Since the opening post, the local Modbus integration (hassio-bluetti-modbus, 0.0.73) reads two more BLUETTI models, both confirmed on real hardware by their owners:

  • AC500 — 30 fields (powers, energies, per-string PV, battery totals, firmware versions), AC and DC output switches, SoC thresholds. Confirmed by community members on their own units. Owners report the local web page — and with it Modbus TCP — only shows up with the IoT module firmware v9041.17, offered as an update in the BLUETTI app; if your AC500 answers ping but has no web page, that is the reason.
  • AC200L / AC200L2 — new this week. 30 fields, AC and DC output switches, SoC thresholds (read-only for now). The profile was built by an AC200L2 owner (@awrede) by cross-checking every register against the same unit’s Bluetooth readings, then confirmed again on the generated version. Energy and PV fields haven’t been seen non-zero yet (no panels on that unit) — if you have an AC200L2 with panels, your diagnostics would close that. The device names itself “AC200L”; whether an original AC200L exposes Modbus TCP at all is unknown.

Setup is the same for both: enable Modbus TCP on the device’s own local web page (http://<device-ip>/, user admin, password = your BLUETTI app account password; Settings → Modbus TCP → Enable, port 502), then add the integration by hand — neither model announces itself on the network, so there is no automatic discovery for them. Details in the README.

Balco 260 owners with BC260 expansion packs: each pack now gets its own sub-device (“Pack 2”, “Pack 3”, …) with the same sensors as the built-in battery — voltage, current, SoC, SoH, cycle count, firmware, energies. It took a while: the packs answer at their own Modbus addresses, 41 and up, not where everyone (us included) first looked, and two owners’ units settled it this week. A pack the inverter knows but that isn’t reporting (asleep, switched off, unplugged since) shows as unavailable rather than 0 % — that’s the device saying nothing, not a fault. Also on the Balco 260: a dozen registers of BLUETTI’s official list that never carry a value on this device are gone (confirmed with BLUETTI as not supported — the totals cover them), and writes are handled correctly despite a firmware quirk in how the device confirms them (reported to BLUETTI, fixed on their side in a future release).

Other model? Register data is welcome — the hardware-testing guide walks through it without coding. The Core PR is unchanged for now: Balco 260 first, the rest follows once it lands.

An update on the local Modbus TCP integration

Since the last post it covers seven devices, each one verified on real hardware by an owner:

Device Entities Controllable from HA
Balco 260 107, plus one sub-device per battery pack AC output, grid charging, feed-in, battery thresholds
S Meter 31, grouped per phase —
AC500 32 AC and DC output
AC200L 30 AC and DC output
EP500Pro 32 AC and DC output
FridgePower 120, plus a battery sub-device DC output, grid charging
Balco Transfer Hub 27 —

Three of those are new: the EP500Pro, the FridgePower and the Balco Transfer Hub. The hub went from “nobody has ever tried one” to a supported device in three days, thanks to an owner who has three of them and tested every step. It has no battery of its own: the charge, voltage and solar figures it shows belong to the power station connected to it.

Getting started

  • Modbus TCP is off out of the box. You turn it on from the device’s own web page: its IP address in a browser, user admin, password = the Bluetooth password you set in the app (blank if you never set one).
  • The Balco 260 and the S Meter are found automatically. The others are added by IP address, and that will not change: BLUETTI confirmed their network modules have no room for automatic announcement on top of Modbus.
  • Install through HACS: GitHub - bluetti-community/hassio-bluetti-modbus: BLUETTI Modbus Integration for Home Assistant · GitHub

Where help is needed

The Balco 500 and the EP2000 have profiles written from BLUETTI’s own documentation, but no real unit has ever confirmed either. If you own one, say so: there is a two-minute, read-only check that settles it. Same for any model not on the list.

The Home Assistant Core PR is still open (#180602).

Finally, for anyone who would rather stay on the cloud: the community fork of the official integration now finds the data centre that serves your account by itself — European accounts were being signed out in a loop — and rides out the BLUETTI cloud’s brief outages instead of flapping every entity.