Skip to main content

aiosolax-uart

PyPI version Python versions License Test codecov Ruff pre-commit

Async Python library to read SolaX inverters over the Pocket USB protocol — the byte-level protocol that the SolaX Pocket WiFi / Pocket USB dongle speaks. Any inverter that accepts a Pocket dongle should be reachable with this library, whether the user connects a real dongle or replaces it with a USB-to-TTL adapter (CP2102, CH340, FT232, …) or an ESPHome serial proxy.

The wire protocol is AA 55 framing at 9600 baud, 8N1. Originally reverse-engineered by xdubx; hybrid-inverter extensions contributed by 70p4z.

Install

pip install aiosolax-uart

Quickstart

import asyncio
from aiosolax_uart import SolaxClient

async def main() -> None:
    async with SolaxClient("/dev/ttyUSB0") as client:
        info = await client.get_device_info()
        print(f"Connected: {info.model.name} (serial {info.inverter_serial})")

        live = await client.get_live_data()
        print(f"AC power: {live.grid_power} W, today: {live.energy_today} kWh")
        if live.import_power is not None:
            print(
                f"House grid: imp={live.import_power}W "
                f"exp={live.export_power}W self={live.self_consumption_power}W"
            )
        if live.battery_soc is not None:
            print(f"Battery: {live.battery_soc}% @ {live.battery_voltage}V")

asyncio.run(main())

The library also works against an ESPHome serial proxy — pass an esphome://host[:port]/?port_name=...&noise_psk=... URL in place of /dev/ttyUSB0.

Supported inverters

The library handles two payload families. Which fields are populated on a given inverter depends on what that inverter actually reports.

Family Models Status
X1 grid-tie X1 Mini (G2/G3), X1 Air, X1 Boost (G3.3/G4), X1 Smart Verified (X1 with CT clamp, May 2026)
X1 Hybrid X1 Hybrid G3 / G4.1+ Decoder present, unverified — needs hardware testers
X3 grid-tie X3 Mega G2, X3 Mic/Pro G2, X3 Forth Same wire protocol, unverified
X3 Hybrid X3 Hybrid G2 / G4.2+ Decoder present, unverified — needs hardware testers

If you can run await client.get_device_info() against your inverter and get a sensible response, please open an issue with the output so the model code can be added to the MODELS registry.

API

SolaxClient

  • SolaxClient(port: str, *, dongle_serial: str = "AIOSOLAX01", baudrate: int = 9600)
  • async connect() -> None — open serial, register with the inverter
  • async close() -> None
  • async get_device_info() -> DeviceInfo — inverter serial, model code, dongle serial. Cached for use by get_live_data().
  • async get_live_data() -> LiveData — instantaneous values + lifetime energy totals. Dispatches to the right decoder using the cached model code.
  • Use as async with SolaxClient(...) as client: to handle setup/teardown.

Data models

  • DeviceInfo — static device info plus a .model property that looks up the entry in MODELS.
  • LiveData — every field that any inverter family can report. Common fields (AC, PV, temperature, energy_total, energy_today, runtime) are always populated; CT, battery, EPS and RTC fields are None when not available.

Model registry

from aiosolax_uart import MODELS, lookup_model

MODELS[5000]  # InverterModel(code=5000, name='X1 (5kW)', family=InverterFamily.X1_GRID_TIE)
lookup_model(0xFFFF)  # InverterModel(code=65535, name='Unknown (65535)', family=InverterFamily.UNKNOWN)

Protocol reference

Frame layout: AA 55 [total_size] [ctrl] [func] [payload...] [chk_lo chk_hi] with a 16-bit little-endian additive checksum over all preceding bytes.

Direction ctrl func Description
Host → 0x02 0x01 Register dongle (10-char ASCII serial)
Host → 0x01 0x05 Read inverter serial / model code
Inv ← 0x01 0x85 Serial response (40-byte payload)
Host → 0x01 0x0C Read live data
Inv ← 0x01 0x8C Live-data response (200 / 210+ bytes depending on family)

The handshake is: open serial → broadcast register frame → wait for the inverter to echo it back → poll live data on a cadence.

Development

uv sync
uv run pytest

Contributing

If your inverter isn't in the MODELS registry yet:

  1. Run a small script that prints await client.get_device_info() against your inverter.
  2. Open an issue with the model code and the inverter's name (from the sticker).

If you have a hybrid inverter, the offsets in _decode_hybrid_extras() need verification. A 220-byte capture of await client.get_live_data() plus your battery's known voltage/SoC right when you took the capture would let us validate the offsets.

License

Apache 2.0

Metadata

Release files for aiosolax-uart 0.1.0

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

Source distribution (sdist)

Source distribution for aiosolax-uart 0.1.0
File Size Uploaded
aiosolax_uart-0.1.0.tar.gz 11.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aiosolax-uart 0.1.0
File Interpreter ABI Platform
aiosolax_uart-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 25.2 kB

Release files / aiosolax_uart-0.1.0.tar.gz

Download URL aiosolax_uart-0.1.0.tar.gz
Size 11.2 kB
Tags Source
SHA-256 checksum
How to use checksums
09f9c3b00230c70674d1d4f6c7206370a714dc1ac7349aa07d68f459892a5b66
BLAKE2b-256 checksum
How to use checksums
4a1d662d909546ee4fffe3b437e037c0fdfcba7361200bae10c226d1608b0459
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

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 May 11, 2026.

Transparency log

Release files / aiosolax_uart-0.1.0-py3-none-any.whl

Download URL aiosolax_uart-0.1.0-py3-none-any.whl
Size 14.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
238947f30cd0a4ec2e44aa038b0e839e51d4bfe527290598493f1efc06641b71
BLAKE2b-256 checksum
How to use checksums
d4c9d931751976f0991d2724e61c3e58e62dc0a7598c7b871ec7ac09f0e0ce97
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

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 May 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

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