A Prometheus exporter for Sigenergy solar + battery inverter systems. Reads power-flow data from the inverter via Modbus TCP, derives split-flow and cost/savings metrics, and exposes them in the Prometheus text exposition format on :8000/metrics.
- Prerequisites
- Quick start
- Running as a systemd service
- Configuration
- Prometheus setup
- Metrics reference
- Alert rules
- Sigenergy notes
- Development & testing
- Python 3.10+
- Network access to the Sigenergy plant on port
502(Modbus TCP) - Modbus TCP Server enabled on the inverter — see Sigenergy notes
git clone https://github.com/edricklabs/sigenergy-prometheus-exporter.git
cd sigenergy-prometheus-exporter
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp env.example .env
# Edit .env — set SIGENERGY_HOST to your inverter's IP
nano .env
python sigenergy_prometheus_exporter.pyMetrics are available at http://localhost:8000/metrics.
A ready-made unit file is included. Install it on any Linux host:
# 1. Create a dedicated user and install directory
sudo useradd --system --no-create-home --shell /usr/sbin/nologin sigenergy
sudo mkdir -p /opt/sigenergy-exporter
sudo chown sigenergy:sigenergy /opt/sigenergy-exporter
# 2. Copy files
sudo cp sigenergy_prometheus_exporter.py requirements.txt /opt/sigenergy-exporter/
sudo cp env.example /opt/sigenergy-exporter/.env
sudo chown sigenergy:sigenergy /opt/sigenergy-exporter/.env
# 3. Create a virtualenv and install dependencies
sudo -u sigenergy python3 -m venv /opt/sigenergy-exporter/.venv
sudo -u sigenergy /opt/sigenergy-exporter/.venv/bin/pip install -r /opt/sigenergy-exporter/requirements.txt
# 4. Edit the config
sudo nano /opt/sigenergy-exporter/.env
# 5. Install and start the service
sudo cp sigenergy-exporter.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now sigenergy-exporter
# 6. Check status
sudo systemctl status sigenergy-exporter
journalctl -u sigenergy-exporter -fCopy env.example to .env and set your values. The exporter reads all configuration from environment variables (or from the .env file via the systemd EnvironmentFile directive).
| Variable | Default | Description |
|---|---|---|
SIGENERGY_MODE |
modbus |
modbus (real device) or sample (synthetic test data, no hardware needed) |
SIGENERGY_HOST |
(unset) | IP or hostname of the Sigenergy plant; required in modbus mode |
SIGENERGY_PORT |
502 |
Modbus TCP port |
SIGENERGY_PLANT_UNIT_ID |
247 |
Modbus unit ID for plant-level registers |
SIGENERGY_INVERTER_UNIT_ID |
1 |
Modbus unit ID for inverter-level registers |
SIGENERGY_TIMEOUT_SECONDS |
5 |
Per-connection Modbus read timeout (seconds) |
SIGENERGY_SCRAPE_INTERVAL_SECONDS |
15 |
Collection interval; keep aligned with Prometheus scrape settings |
SIGENERGY_EXPORTER_PORT |
8000 |
Port the exporter HTTP server listens on |
LOG_LEVEL |
INFO |
Python logging level (DEBUG, INFO, WARNING, …) |
Leave both unset to disable all cost/savings metrics.
| Variable | Format | Description |
|---|---|---|
SIGENERGY_IMPORT_TARIFF_SCHEDULE |
start-end:rate,... |
Time-of-use import tariff in cents/kWh. 24 h clock, comma-separated. Example: 0-2:16.93,2-4:9.94,4-8:16.93,8-23:34.34,23-24:16.93 |
SIGENERGY_EXPORT_TARIFF_CENTS_PER_KWH |
decimal | Flat feed-in / export rate in cents/kWh. Example: 19.5 |
A minimal Prometheus config is provided in prometheus.yml. It scrapes the local exporter and optionally remote-writes to Grafana Cloud, VictoriaMetrics, or any Prometheus-compatible endpoint.
# Install Prometheus (example — adjust version/arch as needed)
PROM_VERSION=2.54.1
curl -Lo /tmp/prometheus.tar.gz \
https://github.com/prometheus/prometheus/releases/download/v${PROM_VERSION}/prometheus-${PROM_VERSION}.linux-amd64.tar.gz
tar xzf /tmp/prometheus.tar.gz -C /tmp
sudo mv /tmp/prometheus-*/prometheus /usr/local/bin/
# Install config and alert rules
sudo mkdir -p /etc/prometheus
sudo cp prometheus.yml /etc/prometheus/
sudo cp prometheus-alerts.yml /etc/prometheus/
# Edit /etc/prometheus/prometheus.yml to fill in remote_write credentials
# Install and start the service
sudo cp prometheus.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now prometheusEdit /etc/prometheus/prometheus.yml to set your remote_write URL and credentials before enabling the service. Remove the remote_write block entirely if you are running a local Prometheus instance (not in agent mode).
| Metric | Type | Description |
|---|---|---|
sigenergy_plant_power_watts |
Gauge | Plant active power (W) |
sigenergy_pv_power_watts |
Gauge | PV / solar generation (W) |
sigenergy_house_load_power_watts |
Gauge | House / general load (W) |
sigenergy_grid_active_power_watts |
Gauge | Signed grid power; positive = import, negative = export (W) |
sigenergy_grid_import_power_watts |
Gauge | Grid import (W) |
sigenergy_grid_export_power_watts |
Gauge | Grid export (W) |
sigenergy_ess_power_watts |
Gauge | Signed ESS power; positive = charge, negative = discharge (W) |
sigenergy_battery_power_watts |
Gauge | Signed battery power; positive = discharge (W) |
sigenergy_battery_charge_power_watts |
Gauge | Battery charging (W) |
sigenergy_battery_discharge_power_watts |
Gauge | Battery discharging (W) |
sigenergy_battery_state_of_charge_percent |
Gauge | Battery SoC (%) |
| Metric | Type | Description |
|---|---|---|
sigenergy_load_supplied_by_solar_watts |
Gauge | Load met by solar (W) |
sigenergy_load_supplied_by_battery_watts |
Gauge | Load met by battery (W) |
sigenergy_load_supplied_by_grid_watts |
Gauge | Load met by grid (W) |
sigenergy_load_supplied_by_solar_percent |
Gauge | Solar share of load (%) |
sigenergy_load_supplied_by_battery_percent |
Gauge | Battery share of load (%) |
sigenergy_load_supplied_by_grid_percent |
Gauge | Grid share of load (%) |
| Metric | Type | Description |
|---|---|---|
sigenergy_pv_to_load_watts |
Gauge | PV used directly by load (W) |
sigenergy_pv_to_battery_watts |
Gauge | PV sent to battery (W) |
sigenergy_pv_to_grid_watts |
Gauge | PV exported to grid (W) |
sigenergy_pv_to_load_percent |
Gauge | PV share to load (%) |
sigenergy_pv_to_battery_percent |
Gauge | PV share to battery (%) |
sigenergy_pv_to_grid_percent |
Gauge | PV share to grid (%) |
sigenergy_battery_charge_from_solar_watts |
Gauge | Estimated battery charge from PV (W) |
sigenergy_battery_charge_from_grid_watts |
Gauge | Estimated battery charge from grid (W) |
Derived flow metrics are best-effort allocations from instantaneous power readings. They are useful for dashboards and operational hints, but exact causality depends on the real Sigenergy register semantics and inverter operating mode.
Only emitted when tariff env vars are set. Counters accumulate since exporter start — use increase(...[$__range]) in Grafana to show totals over a selected time range.
| Metric | Type | Description |
|---|---|---|
sigenergy_current_import_tariff_cents_per_kwh |
Gauge | Active import tariff rate (c/kWh) |
sigenergy_current_export_tariff_cents_per_kwh |
Gauge | Active export tariff rate (c/kWh) |
sigenergy_grid_import_cost_cents_per_hour |
Gauge | Import cost burn rate (c/hr) |
sigenergy_grid_export_credit_cents_per_hour |
Gauge | Export credit earn rate (c/hr) |
sigenergy_avoided_import_savings_cents_per_hour |
Gauge | Avoided import savings from solar + battery supplied load (c/hr) |
sigenergy_net_grid_cost_cents_per_hour |
Gauge | Net grid cost after export credit (c/hr) |
sigenergy_grid_import_cost_cents_total |
Counter | Cumulative import cost since exporter start (c) |
sigenergy_grid_export_credit_cents_total |
Counter | Cumulative export credit since exporter start (c) |
sigenergy_avoided_import_savings_cents_total |
Counter | Cumulative avoided import savings since exporter start (c) |
| Metric | Type | Description |
|---|---|---|
sigenergy_device_up |
Gauge | 1 if device was reachable on last scrape |
sigenergy_scrape_success |
Gauge | 1 if the last collection completed without error |
sigenergy_last_success_timestamp_seconds |
Gauge | Unix timestamp of the last successful scrape |
sigenergy_collection_duration_seconds |
Gauge | Duration of the last scrape (s) |
sigenergy_collection_errors_total |
Counter | Total collection errors since exporter start |
prometheus-alerts.yml contains Prometheus alerting rules. Load it by referencing it from your prometheus.yml rule_files block:
rule_files:
- /etc/prometheus/prometheus-alerts.yml| Alert | Severity | Condition |
|---|---|---|
SigenergyExporterDown |
critical | Prometheus cannot scrape the exporter for > 2 min |
SigenergyDeviceCollectionFailed |
warning | Exporter is reachable but collection is failing |
SigenergyMetricsStale |
warning | No successful collection for > 5 min |
SigenergyBatteryLow |
warning | Battery SoC < 20 % for > 5 min |
SigenergyHighGridDependency |
info | Grid supplies > 80 % of load for > 15 min |
SigenergyExportingWhileBatteryLow |
info | PV export > 250 W while SoC < 40 % for > 10 min |
SigenergyGridChargingBattery |
info | Estimated grid-to-battery charge > 500 W for > 10 min |
-
Enable Modbus TCP Server in the Sigenergy app / web portal before attempting real reads (
Settings → System Settings → Modbus TCP Server Settings). Port502will not respond until this is on. -
Default Modbus addressing follows this register map:
- Plant unit ID:
247 - Inverter unit ID:
1
- Plant unit ID:
-
Confirmed register addresses (plant unit, holding registers):
Address Description Type Scale 30005Grid active power (+ import / − export) S32 1 W 30014Battery state of charge U16 × 0.1 % 30031Plant active power S32 1 W 30035PV generation power S32 1 W 30037ESS power (+ charge / − discharge) S32 1 W 30282House / general load power S32 1 W -
Register addresses may vary across firmware versions. Probe with a generic Modbus tool (e.g.
modpoll) if readings look wrong.
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
# Run tests
pytest -q
# Run in sample mode (no hardware needed)
SIGENERGY_MODE=sample python sigenergy_prometheus_exporter.py