Skip to main content

kaco-rs485

Read KACO Powador xi-series inverters (6400xi, 8000xi, and relatives) over RS485 — from a local adapter, or across the network through an ESPHome serial proxy.

Companion to kaco-modbus, which covers the newer blueplanet units over SunSpec Modbus TCP. Different protocol, different hardware generation, same fleet.

Install

uv add kaco-serial         # library
uv add 'kaco-serial[cli]'  # + the diagnostic CLI and ESPHome transport

The bus is addressed by URL

There is one transport, and it takes an opaque URL. serialx resolves the scheme, so nothing in this library knows or cares how the bytes get there:

URL Where
/dev/tty.usbserial-0001 local RS485 adapter
esphome://host:6053/?port_name=RS-485 ESPHome proxy, standalone
esphome-hass://esphome/<entry_id>?port_name=RS-485 ESPHome proxy, inside Home Assistant
socket://host:port any ser2net-style bridge

The esphome-hass scheme is registered by Home Assistant and resolves the ESPHome integration's already-authenticated client — which is why the Home Assistant integration built on this library stores no host and no API key.

If you have no RS485 port on the network yet, the quickest one is the ready-made ESPHome project for the M5Stack AtomS3 Lite with an ATOMIC RS485 Base, which installs from the browser. Other hardware is covered by the serial-proxies repository and the serial_proxy component.

An ESPHome API encryption key is passed separately — --key on the CLI, or the key argument to AsyncBus — and never as part of the URL, so it needs no escaping.

Library

from kaco_rs485 import AsyncBus, KacoRs485Client
from kaco_rs485.discovery import scan

async with AsyncBus("esphome://proxy.local:6053/?port_name=RS-485") as bus:
    found = await scan(bus)
    client = KacoRs485Client(bus, [d.address for d in found.supported])
    states = await client.poll_cycle()
    for address, state in states.items():
        print(address, state.measured.ac_power_w)

KacoRs485Client owns the pacing. Don't drive AsyncBus from two tasks at once — RS485 is a shared medium and interleaved requests garble each other.

Bringing up a bus

Four CLI modes, in the order you actually need them:

# 1. Is anything there, and are A/B the right way round?
#    Transmits nothing — safe while another master is still connected.
kaco-rs485 --url <url> listen --seconds 30

# 2. Which addresses are occupied, and what is at them?
#    Probes all 32 addresses; a silent one costs ~2.5s.
kaco-rs485 --url <url> scan

# 3. Everything one address can tell you.
kaco-rs485 --url <url> sweep --addresses 2 -v

# 4. Does it keep working? Scans first if you omit --addresses.
kaco-rs485 --url <url> poll

When nothing answers, the CLI prints a diagnostic checklist rather than just a timeout. Only one master may drive an RS485 bus — power down any other polling device before blaming the wiring.

Protocol notes

The parsers were validated against bytes captured from a live installation, and they deliberately tolerate several places where real hardware diverges from the KACO specification:

  • Command 3 replies on xi units omit the *<adr>3 header the spec shows. Both shapes are accepted.
  • Command 3 total yield is in kWh on xi units, Wh on the blueplanet. total_yield_raw is exposed unscaled; the caller decides.
  • Command s (serial number) is unsupported on xi units — they return nothing. Use command 9 for identification.
  • The command 0 checksum byte may be any value 0-255, including CR and LF. This is why framing is length-gated instead of scanning for a terminator, and why readline-style parsing cannot work here.
  • xi units pause >250 ms mid-frame, between the checksum byte and the trailing type string. Frames legitimately end anywhere from 58 to 65 bytes; the type string is decorative.
  • Replies start 1-2 seconds after the request.
  • Status codes 4 (feeding in) and 6 (standby) are observed in the field but absent from the specification's table.

tests/reference/ holds real frames from a live bus. The framing tests replay them split at every possible byte boundary, because through a network proxy the arrival chunking is arbitrary.

Contributing a capture

This library is developed against Powador 6400xi and 8000xi units. Other KACO hardware very likely works, or would with a small change, but that cannot be confirmed without bytes from someone who owns it. A capture from your installation is the single most useful contribution.

kaco-rs485 --url <url> --log-dir captures sweep

Open a pull request adding the resulting .json to tests/reference/. It is picked up automatically — every parser and framing test will run against it, so a file that breaks nothing is evidence your hardware is supported, and a file that breaks something is a bug report with a reproduction attached.

Especially wanted:

  • Other xi-series units (2500xi, 3600xi, 4200xi, 5000xi…). Expected to use the same series-"00" frames; confirmation is cheap and valuable.
  • Series "000xi" park inverters. These answer with command byte 4 instead of 0 and need a parser that does not exist yet.
  • blueplanet / TL / TR units, which speak CRC16 Generic Protocol (command byte n). A whole second protocol; captures are the prerequisite for deciding whether to implement it here.

Before you open the PR, look at what is in the file. A capture contains your total yield, operating hours, and — if command s answered — the inverter's serial number. None of it is dangerous, but total yield and uptime do describe the size and age of your installation, so it is your call. Deleting the 8/9/s entries and keeping only 0 and 3 still makes a useful fixture.

Metadata

Release files for kaco-serial 1.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kaco-serial 1.0.3
File Size Uploaded Provenance Actions
kaco_serial-1.0.3.tar.gz 98.7 kB With provenance Details for kaco_serial-1.0.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for kaco-serial 1.0.3
File Interpreter ABI Platform Actions
kaco_serial-1.0.3-py3-none-any.whl Python 3 none any Details for kaco_serial-1.0.3-py3-none-any.whl

Total release size: 141.7 kB

Release files / kaco_serial-1.0.3.tar.gz

Download URL kaco_serial-1.0.3.tar.gz
Size 98.7 kB
Tags Source
SHA-256 checksum
How to use checksums
e6ed9545b7aff2c72711fc1691952198ca3eb254c0aa09d8d1b4b41fdefa2a62
BLAKE2b-256 checksum
How to use checksums
e43b4ade4c501b2cffa60ac34f1da607567af1db2e849b2df5963154b2201603
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Release files / kaco_serial-1.0.3-py3-none-any.whl

Download URL kaco_serial-1.0.3-py3-none-any.whl
Size 43.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
994d7ee293e348046f728bbdad5327ccaa2306a636bf991eff49b1c9f5fcb378
BLAKE2b-256 checksum
How to use checksums
330fbab176425934a1dedeb5faa46f514b46896a6097414ba6327cd3c9ff985e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Security for kaco-serial 1.0.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for kaco_serial-1.0.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page