foxess-modbus
A modern, standalone Python device library and Home Assistant custom integration for communicating with FoxESS hybrid solar inverters over Modbus.
Built specifically against modbus-connection, following the architectural pattern introduced in Modernizing Modbus in Home Assistant (Home Assistant Core 2026.7+).
Like this integration?
Key Features
- Backend-Neutral: Operates on
modbus-connection, supporting bothtmodbusandpymodbusseamlessly. - Inverter Microcontroller Protection: Automatically groups and limits register reads (
max_span = 8) to prevent the FoxESS AUX microcontroller UART FIFO buffer from overflowing and stalling. - Resilient Bus Timing & Debouncing: Enforces 300ms RS-485 inter-frame pacing with adaptive backoff to 450ms during transient timeouts. Telemetry and connection status sensors are debounced to absorb isolated packet loss without flapping in the Home Assistant logbook.
- Shared Gateway Friendly: Designed to operate with Home Assistant's
async_get_unitconnection broker. Multiple integrations and meters (e.g. Eastron, heat pumps) can share the same physical RS-485 bridge without bus collisions. - Configurable Polling Interval: User-selectable scan rate (5s, 10s, 15s, 30s, 60s; default is 15s) configured directly in Options.
- First-Class Predbat Automation: Native signed net grid power sensor (+export, -import) and dedicated services for force charging, force discharging, clearing overrides, and setting work modes using remote active power registers to avoid solar curtailment.
- Dynamic Power Scaling: Scales power limits dynamically up to 30,000 W for commercial H3-Pro systems.
- Multi-Model EPS Telemetry: Real-time backup power, voltage, current, and frequency monitoring across single-phase and three-phase inverters.
- Strongly Typed: Registers and coils map to typed Python properties with automatic endianness and scale factor decoding.
- Standalone PyPI Distribution: Published as
foxess-modernon PyPI via GitHub Actions Trusted Publishing, maintaining 100% synchronization with the vendored Home Assistant custom integration. - Fully Tested: Tested with mock in-memory Modbus backends and automated zero-drift compliance tests.
Supported Inverter Models
| Series | Models | Strings / Trackers | Interface | Modbus Type | Register Set |
|---|---|---|---|---|---|
| H3-Pro Series | H3-Pro-15.0 to H3-Pro-30.0 | 6 Strings (PV1-PV6 across 3 MPPTs) | RS485 / LAN | Modbus TCP / RTU | Holding Registers (Commercial) |
| KH Series | KH7, KH8, KH9, KH10, KH10.5 | 4 Strings (PV1-PV4 across 4 MPPTs) | AUX / LAN | Modbus TCP / RTU | Holding Registers (1.33+) |
| H3 / AC3 Series | H3-5.0 to H3-12.0, AC3, AIO-H3 | 2 Strings (PV1-PV2 across 2 MPPTs) | RS485 / LAN | Modbus TCP / RTU | Holding Registers (Three-Phase) |
| H1 / AC1 Series | H1-3.0 to H1-6.0, AC1, AIO-H1 | 2 Strings (PV1-PV2 across 2 MPPTs) | AUX / LAN | Modbus TCP / RTU | Holding Registers |
Home Assistant Installation
Option 1: 1-Click via HACS
- Click the Open in HACS badge above.
- In the modal dialog, click Add.
- Download the integration and restart Home Assistant.
- Click the button below to add your inverter:
Option 2: Manual Installation
Copy custom_components/foxess_modern into your Home Assistant <config>/custom_components/ directory and restart.
Home Assistant Energy Dashboard Setup
foxess_modern automatically creates native cumulative energy entities (measured in kWh with device_class: energy and state_class: total_increasing). These sensors persist across Home Assistant restarts and are directly selectable in Home Assistant's built-in Energy Dashboard without needing to manually configure Riemann sum integral helpers.
Navigate to Settings > Dashboards > Energy and configure the fields as follows:
| Energy Dashboard Category | Recommended Entity | Description |
|---|---|---|
| Electricity Grid: Grid Consumption | sensor.<serial>_grid_import_energy_total |
Total energy imported from the grid (kWh) |
| Electricity Grid: Return to Grid | sensor.<serial>_grid_export_energy_total |
Total solar energy exported to the grid (kWh) |
| Solar Panels: Solar Production | sensor.<serial>_pv_energy_total |
Total solar power harvested across all MPPTs (kWh) |
| Battery Systems: Energy going into battery | sensor.<serial>_battery_charge_energy_total |
Total energy stored into the battery (kWh) |
| Battery Systems: Energy coming out of battery | sensor.<serial>_battery_discharge_energy_total |
Total energy discharged from the battery (kWh) |
| Individual Devices (Optional) | sensor.<serial>_load_energy_total |
Total house consumption / load energy (kWh) |
Documentation & Detailed Guides
To maintain a clean, user-focused overview on the front page, technical implementation details and wiring references have been organized into dedicated documentation files:
- Hardware Setup & Field Observations Guide: Detailed RJ45 and 16-pin connector pinouts, RS-485 bridge configuration (Waveshare, USR, Elfin), Wi-Fi Faraday cage mitigations, UDP fallback, and the complete two-tier power-cycle recovery protocol.
- Internal Architecture & Anti-Drift Reference: Architectural invariants, bounded frame rules (
max_span = 8), coordinator lifecycle standards, units and statistics integrity, and zero-drift spec enforcement. - Predbat Integration Guide: Drop-in
apps.yamlconfiguration, signed native net grid power explanation, service automation triggers, and details on preventing solar curtailment via remote active power control. - Modbus Register Map Reference: Comprehensive multi-family register reference across KH, H1/AC1, and H3/H3-Pro models, including telemetry, EPS, and holding registers.
- Migration Guide from Legacy foxess_modbus: Step-by-step instructions for transitioning from Nathan Marlor's integration with zero data loss, automated entity mapping, and statistics validation.
Python Library Installation
pip install "foxess-modern"
To include the high-performance async tmodbus backend:
pip install "foxess-modern[tmodbus]"
Quick Start Example
import asyncio
from modbus_connection import ModbusTcpParams
from modbus_connection.tmodbus import ModbusConnection
from foxess_modbus import FoxessKH10Inverter, WorkMode
async def main():
# Configure your RS-485 to Ethernet adapter (e.g., Waveshare, Elfin EW11)
params = ModbusTcpParams(host="192.168.86.162", port=502)
connection = ModbusConnection(params, timeout=5.0, message_spacing=0.30)
try:
# Request unit handle for slave address 247
unit = connection.for_unit(247)
inverter = FoxessKH10Inverter(unit)
# Refresh all telemetry in minimal batched Modbus calls
report = await inverter.async_update_readings()
print(f"Updated components: {report.updated}")
# Access decoded metrics
print(f"PV Total Power: {inverter.pv.pv_power_total} W")
print(f"PV1: {inverter.pv.pv1_voltage} V, {inverter.pv.pv1_power} W")
print(f"PV2: {inverter.pv.pv2_voltage} V, {inverter.pv.pv2_power} W")
print(f"PV3: {inverter.pv.pv3_voltage} V, {inverter.pv.pv3_power} W")
print(f"PV4: {inverter.pv.pv4_voltage} V, {inverter.pv.pv4_power} W")
print(f"Battery SoC: {inverter.battery.soc} %")
print(f"Battery Power: {inverter.battery.power} W")
print(f"Battery Voltage: {inverter.battery.voltage} V")
print(f"Grid Voltage: {inverter.grid.voltage} V")
print(f"CT Meter Power: {inverter.grid.ct_meter_power} W")
print(f"Inverter State: {inverter.inverter.state}")
# Control commands
await inverter.async_set_work_mode(WorkMode.SELF_USE)
await inverter.async_set_min_soc(15)
finally:
await connection.close()
if __name__ == "__main__":
asyncio.run(main())
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for development setup instructions, guidelines for adding new FoxESS inverter models, and testing procedures.
License
This project is licensed under the Apache 2.0 License.
Release files for foxess-modern 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| foxess_modern-0.2.0.tar.gz | 2.3 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| foxess_modern-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.4 MB
Release files / foxess_modern-0.2.0.tar.gz
| Download URL | foxess_modern-0.2.0.tar.gz |
|---|---|
| Size | 2.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6635568550bb30a82c5c332fd4df24c232a067af82b7521f4db75ca0328658dc
|
|
BLAKE2b-256 checksum How to use checksums |
d436a014fc71a1889c5930ac18cfadb618bd72b9b127f6c2a7ed0eba3e62a196
|
| 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 25, 2026.
Transparency logRelease files / foxess_modern-0.2.0-py3-none-any.whl
| Download URL | foxess_modern-0.2.0-py3-none-any.whl |
|---|---|
| Size | 33.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
af19dcd471352cdca0ad4a36ceb395ce295c641ef469f08588805cb8d66222b2
|
|
BLAKE2b-256 checksum How to use checksums |
2718c8b6eb183e6115d08bada4356da1bbf23701656f9330ee84fde5c31ffae6
|
| 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 25, 2026.
Transparency log