aiosaj
Async Python library to read live data from SAJ solar inverters, over either their Ethernet (LAN) interface or their WiFi module. It was written for Home Assistant but works in any asyncio application.
aiosaj continues the work of fredericvl/pysaj.
Installation
pip install aiosaj
Requires Python 3.9 or newer.
Usage
import asyncio
from aiosaj import SAJ, Sensors
async def main():
# WiFi module: wifi=True, with the module's web login (admin/admin by default).
# Ethernet: SAJ("192.168.1.100") - no login needed.
saj = SAJ("192.168.1.100", wifi=True, username="admin", password="admin")
sensors = Sensors(wifi=True)
if await saj.read(sensors):
for sensor in sensors:
if sensor.enabled:
print(sensor.name, sensor.value, sensor.unit)
else:
print("Inverter not reachable (it switches off when there is no sunlight)")
asyncio.run(main())
read()returnsTruewhen new values were read, andFalsewhen the inverter cannot be reached. SAJ inverters run on solar power, so this is normal at night.sensors["total_yield"]looks up a single sensor by name.sensor.enabledisTruefor every sensor your inverter actually reports. Sensors for channels your inverter does not have, such as a third PV string, stay disabled.saj.serialnumberholds the inverter's serial number after the first read, if the inverter's firmware provides it.
Use Sensors(wifi=True) together with SAJ(..., wifi=True), and Sensors() with an
Ethernet connection.
Sensors
Both interfaces
| Sensor | Unit | Description |
|---|---|---|
current_power |
W | Power being delivered right now |
today_yield |
kWh | Energy produced today |
total_yield |
kWh | Energy produced over the inverter's lifetime |
today_time |
h | Hours in operation today |
total_time |
h | Hours in operation over the inverter's lifetime |
total_co2_reduced |
kg | Lifetime CO₂ saving, as calculated by the inverter |
temperature |
°C | Inverter temperature |
state |
Run state: Normal, Waiting, Not connected, Error or Upgrading |
Ethernet only
| Sensor | Unit | Description |
|---|---|---|
today_max_current |
W | Highest power output reached today |
WiFi only
| Sensor | Unit | Description |
|---|---|---|
pv1_voltage, pv2_voltage, pv3_voltage |
V | Voltage of each PV input |
pv1_current, pv2_current, pv3_current |
A | Current of each PV input |
pv1_string1_current … pv3_string4_current |
A | Current of each string on each PV input |
grid_frequency |
Hz | Grid frequency |
line1_voltage, line2_voltage, line3_voltage |
V | Grid voltage per phase |
line1_current, line2_current, line3_current |
A | Grid current per phase |
bus_voltage |
V | Internal DC bus voltage |
Older WiFi module firmware only reports the sensors that both interfaces have.
How values behave
- Values are only updated while the inverter's state is
Normal. While it is starting up, waiting or in error, live values such as power and voltage becomeNone, and the energy and time counters keep their last value. total_yield,total_timeandtotal_co2_reducednever go down, andtoday_yieldandtoday_timeonly go back to zero when a new day starts. This keeps energy statistics, such as Home Assistant's Energy dashboard, free of false spikes.- A reading that is out of range or clearly wrong is skipped, and the sensor keeps its previous value.
Credits
aiosaj builds on pysaj by @fredericvl, which was in turn based on the pysma library by @kellerza.
License
MIT, see LICENSE.
Metadata
Release files for aiosaj 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aiosaj-0.2.1.tar.gz | 20.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aiosaj-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.0 kB
Release files / aiosaj-0.2.1.tar.gz
| Download URL | aiosaj-0.2.1.tar.gz |
|---|---|
| Size | 20.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
12665b063b090aa47647590a55d14b96a516efe60ab60d25af55817294f2b957
|
|
BLAKE2b-256 checksum How to use checksums |
fc3fad42b28c5f414855e1aa2ebb5283b327f70622d2a80a6fd41f3166ad9947
|
| 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 Oct 19, 2026.
Transparency logRelease files / aiosaj-0.2.1-py3-none-any.whl
| Download URL | aiosaj-0.2.1-py3-none-any.whl |
|---|---|
| Size | 12.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0036f3a2bd462028a190209858813be603651e1c11cf0246383c446532bbb0fa
|
|
BLAKE2b-256 checksum How to use checksums |
647470768e10b5cb75efe5522ae4d1f6ea413bf665d961049b4d48bad31d193e
|
| 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 Oct 19, 2026.
Transparency log