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)
| File | Size | Uploaded | |
|---|---|---|---|
| sma_modbus-2.1.3.tar.gz | 25.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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