https://github.com/smlx/goodwe-exporters
Prometheus Exporters for Goodwe Energy Monitors (smart meters) and Solar Inverters
https://github.com/smlx/goodwe-exporters
go golang goodwe mitm prometheus prometheus-exporter sems-portal
Last synced: 10 months ago
JSON representation
Prometheus Exporters for Goodwe Energy Monitors (smart meters) and Solar Inverters
- Host: GitHub
- URL: https://github.com/smlx/goodwe-exporters
- Owner: smlx
- License: apache-2.0
- Created: 2023-11-16T13:34:21.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2025-08-04T12:15:27.000Z (11 months ago)
- Last Synced: 2025-08-04T13:14:18.004Z (11 months ago)
- Topics: go, golang, goodwe, mitm, prometheus, prometheus-exporter, sems-portal
- Language: Go
- Homepage:
- Size: 271 KB
- Stars: 17
- Watchers: 4
- Forks: 1
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Goodwe Prometheus Exporters
This repository contains Prometheus metrics exporters for Goodwe solar energy devices including inverters and smart meters.
## SEMS MITM Exporter
This is a Prometheus exporter for Goodwe devices which integrate with the cloud-hosted Smart Energy Managment System (SEMS) portal.
It works by implementing a [MITM attack](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) on the SEMS portal protocol, hence the name.
### Why does this exist?
#### Short version
Homekit 1000 does not support Modbus for metrics querying, so the only way to get data out of it appears to be from the SEMS Portal traffic.
Other Goodwe hardware probably supports Modbus, which may be more convenient for scraping metrics.
#### Long version
See the [blog post](https://smlx.dev/posts/goodwe-sems-protocol-teardown/).
### Features
The SEMS MITM exporter has the following advantages over just using the SEMS Portal:
* Transparently forwards data to SEMS Portal (option not to forward traffic is a WIP).
* Allows you to store your data in a Prometheus instance that you control.
* Visualise your data using standard tools like Grafana.
* Drops unrecognised incoming packets to block e.g. firmware upgrades.
* Summons Batman to the SEMS Portal (optional, set env var `BATSIGNAL=true`).
### Hardware support
Currently hardware support in the SEMS MITM Exporter is limited to the equipment I own:
* [Homekit 1000](https://www.goodwe.com.au/single-phase-homekit)
* [DNS G3](https://www.goodwe.com.au/dns-g3-au)
PRs welcome if you want to add support for your device.
> [!NOTE]
> I don't have a battery, so the exporter and metrics naming reflects that.
> Open issues to discuss how to improve this if you have a battery and don't like the metric naming.
### How to get it
You have a couple of options:
* Pull a docker image from the Github image registry (recommended!).
* Download a release binary from the Releases page.
### How to use it
At a high level:
1. Start the exporter.
1. Get traffic to the exporter. Either:
* Point the DNS of `tcp.goodwe-power.com` to the IP of the exporter; or
* Reconfigure your hardware to connect to the IP of the exporter.
1. Configure Prometheus to scrape from the exporter on port 14028.
1. Grab the [Grafana dashboard](https://grafana.com/grafana/dashboards/20479-household-power/) and visualise your metrics.
Detailed instructions for supported hardware is a WIP.
For command-line flags and environment variables run the exporter with the `--help` flag.
#### Example: docker compose
Here's how I run it locally using docker compose:
```yaml
---
version: '3.8'
services:
sems_mitm_exporter:
# avoid copying host search option
dns_search: .
image: ghcr.io/smlx/goodwe-exporters/sems_mitm_exporter:latest
ports:
- "20001:20001"
restart: unless-stopped
environment:
- DEBUG=true
```
### Metrics exported
> [!NOTE]
> Only the useful metrics are listed here. Unlisted metrics which are also exported include:
>
> * Device metrics which aren't particularly useful (e.g. other values summed together).
> * Values which are unknown due to uncertainties when reverse engineering the packet structure (`*_unknown_*` variables). If you figure out what these are, please open an issue/PR.
Except where noted, all metrics are labelled with:
* `device`
* `model`
* `serial`
#### Homekit 1000
| Metric | Description |
| --- | --- |
| `meter_power_generation_watts` | Power generated by PV array. |
| `meter_power_export_watts` | Power exported to the grid. |
| `meter_energy_generation_decawatt_hours_total` | Cumulative energy generated. |
| `meter_energy_export_decawatt_hours_total` | Cumulative energy exported. |
| `meter_energy_import_decawatt_hours_total` | Cumulative energy imported. |
| `batsignal_top` | Top of the batsignal. (only when `BATSIGNAL=true`) |
| `batsignal_bottom` | Bottom of the batsignal. (only when `BATSIGNAL=true`) |
#### DNS G3
| Metric | Description |
| --- | --- |
| `inverter_input_voltage_dc_decivolts` | Input DC voltage to inverter. |
| `inverter_input_current_dc_deciamps` | Input DC current to inverter. |
| `inverter_output_voltage_ac_decivolts` | Output AC voltage from inverter. |
| `inverter_output_current_ac_deciamps` | Output AC current from inverter. |
| `inverter_output_frequency_ac_centihertz` | Output AC frequency from inverter. |
| `inverter_power_output_watts` | Power output from inverter. |
| `inverter_internal_temperature_decidegrees_celsius` | Internal temperature of inverter. |
| `inverter_energy_output_hectowatt_hours_day` | Cumulative energy output today. |
| `inverter_energy_output_hectowatt_hours_total` | Cumulative energy output total. |
| `inverter_uptime_hours_total` | Inverter total operation time. |
| `inverter_rssi_percent` | Inverter WLAN received signal strength indicator. |
#### Exporter internals
| Metric | Description |
| --- | --- |
| `meter_time_sync_packets_total` | Count of outbound time sync packets. |
| `meter_time_sync_ack_packets_total` | Count of outbound time sync acknowledgement packets. |
| `meter_metrics_packets_total` | Count of outbound metrics packets. |
| `inbound_unknown_packets_total` | Count of inbound unknown packets. (no labels) |
| `outbound_unknown_packets_total` | Count of outbound unknown packets. (no labels) |
| `inverter_time_sync_packets_total` | Count of outbound time sync packets. |
| `inverter_metrics_packets_total` | Count of outbound metrics packets. |