Skip to main content

sma-modbus

Async Python library for the Modbus TCP interface of SMA devices, built on modbus-connection.

[!WARNING]

Developer Preview

Working, but do not use in production. Please report any issues you come across.

[!NOTE]

Based on a partial agentic port of fronius-modbus. 🫶

Supports the following SMA devices (so far):

  • Sunny Home Manager 2.0
  • Sunny Boy Smart Energy 3.6-6.0
  • Sunny Boy 3.0-6.0
  • Sunny Tripower 3.0-6.0 untested

Not all Modbus parameters have been added, yet. Support for read/write registers maybe later.

The SMA register map is mostly fixed, but it has been slightly modified with firmware updates in the past.

Reading

The library consumes a ModbusConnection and manages its own unit handles internally. Use discover() to auto-detect the device type and serial number from the Type Label (probes unit ID 1, then unit ID 3):

import asyncio

from modbus_connection.tmodbus import connect_tcp

from sma_modbus import DEVICE_CLASSES, discover


async def main() -> None:
    connection = await connect_tcp("192.168.1.50", port=502)
    info = await discover(connection)
    inverter = DEVICE_CLASSES[info.device_type](connection, info.unit_id)

    # one pooled read refreshes the whole device, block by block
    await inverter.async_update()

    print("PV power:", inverter.pv_power, "W")
    print("PV energy:", inverter.pv_energy_total, "Wh")
    print("Battery SoC:", inverter.battery_state_of_charge, "%")
    print("DC string 1:", inverter.dc_voltage_1, "V", inverter.dc_power_1, "W")

    await connection.close()


asyncio.run(main())

Pass unit_id= to discover() to read the Type Label from a specific unit ID and use it for measurements. This covers inverters that have been reconfigured to a non-default unit ID. Without unit_id, discovery probes unit IDs 1 and 3 and uses the device type's standard default (3 for inverters, 2 for the Sunny Home Manager):

info = await discover(connection, unit_id=5)

A field reads as None when the device reports its not-a-value sentinel, so a powered-down or unsupported measurement is distinct from a real zero.

Testing on real hardware

scripts/read_device.py is a one-shot dump of everything the library reads:

uv run scripts/read_device.py <host> [--port 502] [--unit <id>]

The device type is auto-detected. Use --unit to override the measurement unit ID if the device has been reconfigured.

Modbus must be enabled on the device.

Testing support

sma_modbus.testing provides set_input_registers() to load a modbus_connection.mock.MockModbusConnection with raw register words for a component:

from modbus_connection.mock import MockModbusConnection
from sma_modbus import SunnyHomeManager
from sma_modbus.testing import set_input_registers

connection = MockModbusConnection()
device = SunnyHomeManager(connection)
set_input_registers(
    connection,
    device,
    {"grid_import_energy": 123456, "grid_export_power": 750},
)
await device.async_update()
assert device.grid_import_energy == 123456

The mock_modbus_connection fixture (shipped by modbus_connection's pytest plugin) hands a ready-to-configure connection to each test.

Disclaimer

This is an unofficial library and in no way affiliated with SMA Solar Technology AG.

Release files for sma-modbus 2.1.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 sma-modbus 2.1.3
File Size Uploaded
sma_modbus-2.1.3.tar.gz 25.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sma-modbus 2.1.3
File Interpreter ABI Platform
sma_modbus-2.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 56.8 kB

Release files / sma_modbus-2.1.3.tar.gz

Download URL sma_modbus-2.1.3.tar.gz
Size 25.3 kB
Tags Source
SHA-256 checksum
How to use checksums
5b3d452a4b86f4014b94c2f4205e5370b5308925fc9d2d0d72df42e4e31fb888
BLAKE2b-256 checksum
How to use checksums
6ae55a0d3e4428d4c32a4d1ad61375f0bcc9f2804b4e661b73dcc2f6fb61f084
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 8, 2026.

Transparency log

Release files / sma_modbus-2.1.3-py3-none-any.whl

Download URL sma_modbus-2.1.3-py3-none-any.whl
Size 31.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9eeef23462454e1bbc610d0c1dce7d34d2048a9347777923f5e4226f2e22e5d6
BLAKE2b-256 checksum
How to use checksums
9f8ab4d836f74dbbb38279e024a0dd0bc2d13ec5d60201bdd84a06957bdf380d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.1.3 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