{"id":40168788,"url":"https://github.com/rhwendt/enphase-exporter","last_synced_at":"2026-04-02T17:03:25.433Z","repository":{"id":333370345,"uuid":"1137060147","full_name":"rhwendt/enphase-exporter","owner":"rhwendt","description":"Prometheus exporter for Enphase IQ Gateway - exposes solar production metrics","archived":false,"fork":false,"pushed_at":"2026-03-28T21:21:47.000Z","size":83,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-29T00:21:12.882Z","etag":null,"topics":["enphase","enphase-api","enphase-gateway","enphase-iq-envoy","prometheus-exporter"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rhwendt.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-18T20:54:31.000Z","updated_at":"2026-03-28T21:30:14.000Z","dependencies_parsed_at":"2026-01-22T07:00:11.377Z","dependency_job_id":null,"html_url":"https://github.com/rhwendt/enphase-exporter","commit_stats":null,"previous_names":["rhwendt/enphase-exporter"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/rhwendt/enphase-exporter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhwendt%2Fenphase-exporter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhwendt%2Fenphase-exporter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhwendt%2Fenphase-exporter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhwendt%2Fenphase-exporter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rhwendt","download_url":"https://codeload.github.com/rhwendt/enphase-exporter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhwendt%2Fenphase-exporter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31311040,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["enphase","enphase-api","enphase-gateway","enphase-iq-envoy","prometheus-exporter"],"created_at":"2026-01-19T17:02:01.986Z","updated_at":"2026-04-02T17:03:25.427Z","avatar_url":"https://github.com/rhwendt.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Enphase Prometheus Exporter\n\nA Prometheus exporter for Enphase IQ Gateway that exposes solar production metrics from your local gateway.\n\n## Features\n\n- **Local API access** - No cloud dependency, real-time metrics\n- **Per-inverter metrics** - Monitor individual panel performance\n- **Production \u0026 consumption** - Track solar production and home consumption\n- **Net power** - See if you're exporting or importing from the grid\n- **Meter readings** - Voltage, current, power factor, frequency per phase\n- **Daily/weekly totals** - Production and consumption trends\n- **Kubernetes ready** - Includes Deployment, Service, and ServiceMonitor manifests\n\n## Metrics\n\n### Production Metrics\n\n| Metric | Description | Labels |\n|--------|-------------|--------|\n| `enphase_production_watts` | Current production in watts | `device_type` |\n| `enphase_production_wh_total` | Lifetime production in Wh | `device_type` |\n| `enphase_production_wh_today` | Production today in Wh | `device_type` |\n| `enphase_production_wh_last_seven_days` | Production last 7 days in Wh | `device_type` |\n| `enphase_production_voltage_volts` | RMS voltage | `device_type` |\n| `enphase_production_current_amps` | RMS current | `device_type` |\n| `enphase_production_power_factor` | Power factor | `device_type` |\n\n### Consumption Metrics\n\nRequires consumption CT clamps installed at your main panel.\n\n| Metric | Description | Labels |\n|--------|-------------|--------|\n| `enphase_consumption_watts` | Current consumption in watts | `measurement_type` |\n| `enphase_consumption_wh_total` | Lifetime consumption in Wh | `measurement_type` |\n| `enphase_consumption_wh_today` | Consumption today in Wh | `measurement_type` |\n| `enphase_consumption_wh_last_seven_days` | Consumption last 7 days in Wh | `measurement_type` |\n\nThe `measurement_type` label distinguishes:\n- `total-consumption` - Total power consumed by your home\n- `net-consumption` - Consumption from the grid (excludes self-consumed solar)\n\n### Net Power\n\n| Metric | Description | Labels |\n|--------|-------------|--------|\n| `enphase_net_watts` | Net power (production - consumption). Positive = exporting, negative = importing | - |\n| `enphase_grid_export_wh_total` | Cumulative energy exported to grid in Wh (resets on restart) | - |\n| `enphase_grid_import_wh_total` | Cumulative energy imported from grid in Wh (resets on restart) | - |\n\n### Per-Inverter Metrics\n\n| Metric | Description | Labels |\n|--------|-------------|--------|\n| `enphase_inverter_watts` | Per-inverter current production | `serial_number` |\n| `enphase_inverter_max_watts` | Per-inverter max reported | `serial_number` |\n| `enphase_inverter_last_report_timestamp` | Unix timestamp of last report | `serial_number` |\n\n### Meter Metrics\n\n| Metric | Description | Labels |\n|--------|-------------|--------|\n| `enphase_active_power_watts` | Meter active power | `measurement_type`, `meter_id`, `phase` |\n| `enphase_current_amps` | Meter current | `measurement_type`, `meter_id`, `phase` |\n| `enphase_voltage_volts` | Meter voltage | `measurement_type`, `meter_id`, `phase` |\n| `enphase_power_factor` | Meter power factor | `measurement_type`, `meter_id`, `phase` |\n| `enphase_frequency_hz` | Grid frequency | `measurement_type`, `meter_id` |\n| `enphase_meter_energy_delivered_wh` | Cumulative energy delivered in Wh | `measurement_type`, `meter_id`, `phase` |\n| `enphase_meter_energy_received_wh` | Cumulative energy received in Wh | `measurement_type`, `meter_id`, `phase` |\n\nThe `measurement_type` label identifies the meter's purpose:\n- `production` - Solar production meter (delivered = energy produced)\n- `net-consumption` - Grid net meter (delivered = exported to grid, received = imported from grid)\n- `total-consumption` - Total consumption meter\n\nThe `phase` label can be `total` for aggregate values or `L1`, `L2`, etc. for per-phase readings.\n\n**Common queries:**\n```promql\n# Grid import (energy received by net meter)\nenphase_meter_energy_received_wh{measurement_type=\"net-consumption\",phase=\"total\"}\n\n# Grid export (energy delivered by net meter)\nenphase_meter_energy_delivered_wh{measurement_type=\"net-consumption\",phase=\"total\"}\n\n# Solar production (energy delivered by production meter)\nenphase_meter_energy_delivered_wh{measurement_type=\"production\",phase=\"total\"}\n```\n\n### Exporter Metrics\n\n| Metric | Description | Labels |\n|--------|-------------|--------|\n| `enphase_exporter_build_info` | Build information | `version`, `commit`, `built` |\n\n## Known Issues\n\n### Daily Metrics Don't Reset at Midnight\n\n**Problem:** The Enphase gateway has a firmware bug where `whToday` values may not reset at midnight. This causes the `enphase_production_wh_today` and `enphase_consumption_wh_today` metrics to accumulate over multiple days, resulting in inflated values.\n\n**Workaround:** Use Prometheus `increase()` function on the lifetime counters instead.\n\n**Rolling 24 Hours:**\n```promql\n# Rolling 24-hour production\nincrease(enphase_production_wh_total{device_type=\"eim\"}[24h])\n\n# Rolling 24-hour total consumption\nincrease(enphase_consumption_wh_total{measurement_type=\"total-consumption\"}[24h])\n\n# Rolling 24-hour net consumption (grid import)\nincrease(enphase_consumption_wh_total{measurement_type=\"net-consumption\"}[24h])\n```\n\n**Today So Far (since midnight):**\n\nIn Grafana, set the dashboard/panel time range to **\"Today so far\"** and use `$__range`:\n\n```promql\n# Production today (since midnight)\nincrease(enphase_production_wh_total{device_type=\"eim\"}[$__range])\n\n# Total consumption today (since midnight)\nincrease(enphase_consumption_wh_total{measurement_type=\"total-consumption\"}[$__range])\n\n# Net consumption today (since midnight)\nincrease(enphase_consumption_wh_total{measurement_type=\"net-consumption\"}[$__range])\n```\n\nThe `$__range` variable automatically adjusts to the selected time range, so \"Today so far\" gives you midnight to now.\n\nThe `_wh_total` metrics are lifetime counters that always increase reliably, making them suitable for calculating daily values via Prometheus.\n\n### Split-Phase Doubling\n\n**Problem:** On split-phase electrical systems (common in North America), the gateway may report doubled values for daily/weekly/lifetime metrics at the top level.\n\n**Workaround:** The exporter automatically sums the per-phase `lines[]` values which provides accurate totals. This is handled internally - no user action needed.\n\n## Quick Start\n\n### 1. Generate JWT Token\n\nGo to [entrez.enphaseenergy.com](https://entrez.enphaseenergy.com):\n\n1. Log in with your Enlighten credentials\n2. Search for your system by name\n3. Select your gateway from the dropdown\n4. Click \"Create access token\"\n5. Copy the token (valid for 1 year)\n\n### 2. Configure\n\n```bash\ncp .env.example .env\n```\n\nEdit `.env`:\n\n```bash\nENVOY_ADDRESS=https://envoy.local   # Or use IP: https://192.168.x.x\nENVOY_SERIAL=your-gateway-serial\nENVOY_JWT=your-jwt-token\n```\n\n### 3. Run\n\n**Local:**\n```bash\ngo run ./cmd/exporter\n```\n\n**Docker:**\n```bash\ndocker build -t enphase-exporter .\ndocker run -p 9090:9090 --env-file .env enphase-exporter\n```\n\n**Docker Compose:**\n```bash\ndocker-compose up\n```\n\n### 4. Verify\n\n```bash\ncurl http://localhost:9090/metrics | grep enphase_\n```\n\n## Docker Deployment\n\n### Option 1: Docker Run\n\n```bash\n# Build the image\ndocker build -t enphase-exporter .\n\n# Run with environment variables\ndocker run -d \\\n  --name enphase-exporter \\\n  --restart unless-stopped \\\n  -p 9090:9090 \\\n  -e ENVOY_ADDRESS=https://192.168.1.100 \\\n  -e ENVOY_SERIAL=your-serial \\\n  -e ENVOY_JWT=your-jwt-token \\\n  enphase-exporter\n```\n\n### Option 2: Docker Compose\n\nCreate a `docker-compose.yml`:\n\n```yaml\nversion: '3.8'\nservices:\n  enphase-exporter:\n    build: .\n    # Or use: image: ghcr.io/rhwendt/enphase-exporter:latest\n    container_name: enphase-exporter\n    restart: unless-stopped\n    ports:\n      - \"9090:9090\"\n    environment:\n      - ENVOY_ADDRESS=https://192.168.1.100\n      - ENVOY_SERIAL=your-serial\n      - ENVOY_JWT=your-jwt-token\n      - LOG_LEVEL=info\n\n  # Optional: Add Prometheus to scrape the exporter\n  prometheus:\n    image: prom/prometheus:latest\n    container_name: prometheus\n    restart: unless-stopped\n    ports:\n      - \"9091:9090\"\n    volumes:\n      - ./deploy/prometheus.yaml:/etc/prometheus/prometheus.yml\n      - prometheus_data:/prometheus\n    command:\n      - '--config.file=/etc/prometheus/prometheus.yml'\n      - '--storage.tsdb.path=/prometheus'\n\nvolumes:\n  prometheus_data:\n```\n\nRun:\n```bash\ndocker-compose up -d\n```\n\n### Option 3: Using .env file\n\n```bash\n# Create .env from example\ncp .env.example .env\n# Edit .env with your values\n\n# Run with .env file\ndocker run -d \\\n  --name enphase-exporter \\\n  --restart unless-stopped \\\n  --env-file .env \\\n  -p 9090:9090 \\\n  enphase-exporter\n```\n\n### Health Checks\n\nThe container exposes health endpoints:\n- `/health` - Liveness (is the process running?)\n- `/ready` - Readiness (is it authenticated and working?)\n\n```bash\n# Check if running\ncurl http://localhost:9090/health\n\n# Check if authenticated\ncurl http://localhost:9090/ready\n```\n\n## Kubernetes Deployment\n\n```bash\n# Create secret with your credentials\nkubectl create secret generic enphase-exporter \\\n  --from-literal=serial=your-serial \\\n  --from-literal=jwt=your-jwt-token\n\n# Deploy\nkubectl apply -f deploy/kubernetes/\n```\n\nThe ServiceMonitor will automatically configure Prometheus Operator to scrape metrics.\n\n## Configuration\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `ENVOY_ADDRESS` | Yes | - | Gateway URL (e.g., `https://envoy.local`) |\n| `ENVOY_SERIAL` | Yes | - | Gateway serial number |\n| `ENVOY_JWT` | Yes | - | JWT token from entrez.enphaseenergy.com |\n| `EXPORTER_PORT` | No | `9090` | Metrics endpoint port |\n| `LOG_LEVEL` | No | `info` | Log level (debug, info, warn, error) |\n| `LOG_FORMAT` | No | `text` | Log format (text, json) |\n\n## Endpoints\n\n| Path | Description |\n|------|-------------|\n| `/metrics` | Prometheus metrics |\n| `/health` | Liveness probe (always returns 200) |\n| `/ready` | Readiness probe (200 when authenticated) |\n\n## Architecture\n\n```mermaid\nflowchart LR\n    P[Prometheus] --\u003e|scrape| E[Enphase Exporter]\n    E --\u003e|API| G[IQ Gateway\u003cbr/\u003elocal]\n    P --\u003e GF[Grafana]\n```\n\n## Authentication Flow\n\n```\n1. User generates JWT at entrez.enphaseenergy.com (1 year validity)\n2. Exporter validates JWT with gateway (/auth/check_jwt)\n3. Gateway returns session cookie (30 min validity)\n4. Exporter auto-refreshes session before expiry\n5. API requests use session cookie\n```\n\n## Development\n\n```bash\n# Build\ngo build -o enphase-exporter ./cmd/exporter\n\n# Build with version info\ngo build -ldflags \"-X main.Version=1.0.0 -X main.GitCommit=$(git rev-parse HEAD)\" ./cmd/exporter\n\n# Run tests\ngo test ./...\n\n# Lint\ngolangci-lint run\n```\n\n## License\n\nMIT\n\n## Acknowledgments\n\n- [Enphase-API](https://github.com/Matthew1471/Enphase-API) - API documentation\n- [go-envoy](https://github.com/loafoe/go-envoy) - Reference implementation\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhwendt%2Fenphase-exporter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frhwendt%2Fenphase-exporter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhwendt%2Fenphase-exporter/lists"}