eero-stats is a lightweight daemon that extracts real-time metrics from your Eero Mesh Network and writes them to an InfluxDB v2 time-series database.
Designed for minimal flash storage wear (ideal for TrueNAS SCALE, Unraid, or Proxmox NVMe setups), the daemon uses aggressive write batching to pool metrics in memory before async-flushing to disk.
It ships with a fully automated Grafana dashboard covering network health, device signal quality, node telemetry, and more.
The daemon uses tiered interval-based polling to balance data freshness against Eero API rate limits:
| Tier | Interval | Data Collected |
|---|---|---|
| Fast | 3 min | Device connectivity, node health, network status |
| Medium | 90 min | Node/device metadata, profile mappings |
| Slow | 12 hr | ISP speed tests, network configuration snapshots |
flowchart TD
UserCLI([CLI / Initial 2FA]) -->|Interactive OTP| SessionFile{Session Cache}
SessionFile -->|Loads Token| GoPoller[eero-stats Daemon]
subgraph Poller ["Tiered Poller (Go 1.22)"]
GoPoller -->|Fast · 3 min| FastPoll[Devices + Nodes + Health]
GoPoller -->|Medium · 90 min| MediumPoll[Metadata + Profiles]
GoPoller -->|Slow · 12 hr| SlowPoll[ISP Speeds + Config]
end
Poller -->|Async Batch Write| Influx[(InfluxDB v2)]
Influx -->|Flux Queries| Dashboard[[Grafana Dashboard]]
eero-stats/
├── cmd/eero-stats/ # Application entry point
│ └── main.go # Daemon bootstrap and graceful shutdown
├── internal/
│ ├── auth/ # Eero API authentication (session cache + 2FA)
│ │ └── auth.go
│ ├── config/ # Environment variable loading and validation
│ │ └── config.go
│ ├── db/ # InfluxDB client wrapper (NVMe-optimized batching)
│ │ └── influx.go
│ └── poller/ # Tiered polling engine
│ ├── poller.go # Poll loop orchestration
│ ├── writers.go # InfluxDB data point writers
│ └── retry.go # Exponential backoff retry helper
├── grafana/
│ ├── dashboards/ # Provisioned Grafana dashboard JSON
│ └── provisioning/ # Datasource and dashboard provider configs
├── scripts/
│ └── build_dashboard.py # Regenerates the Grafana dashboard JSON
├── docker-compose.yml # Full stack: daemon + InfluxDB + Grafana
├── Dockerfile # Multi-stage build (builder + alpine runtime)
├── Makefile # Build, lint, Docker, and dashboard targets
└── .env.example # Template for required environment variables
git clone https://github.com/arvarik/eero-stats.git
cd eero-stats
cp .env.example .envEdit .env to include your Eero login email or phone number, your host user's PUID/PGID (run id to find them), and adjust GRAFANA_PORT/INFLUX_PORT if the defaults conflict with existing services.
make docker-upThis launches the daemon, InfluxDB, and Grafana containers.
Note
TrueNAS / NAS Users: If usermod fails, just prefix Docker commands with sudo instead (e.g., sudo docker compose up -d).
The first time the daemon starts, it requires a one-time 2FA verification:
docker attach eero-statsEnter the verification code sent to your email/phone. On success, the session token is cached to ./data/app/.eero_session.json.
Detach with CTRL-P then CTRL-Q to let the daemon continue in the background.
Note
Session Lifecycle: The Eero API issues a long-lived token (typically valid ~30 days). If the daemon starts logging 401 Unauthorized errors, stop the container (make docker-down), delete ./data/app/.eero_session.json, and re-run steps 2–3 to re-authenticate.
Open Grafana at http://<your-ip>:<GRAFANA_PORT> (default: 3000, login: admin / your GF_ADMIN_PASSWORD). The Eero Network Telemetry dashboard is automatically provisioned.
All settings are injected via .env:
| Variable | Required | Description |
|---|---|---|
EERO_LOGIN |
Yes | Email or phone for your Eero Owner Account |
INFLUX_URL |
No | InfluxDB URL (default: http://influxdb:8086) |
INFLUX_TOKEN |
No | InfluxDB API token (default: my-super-secret-auth-token-123) |
INFLUX_ORG |
No | InfluxDB organization (default: eero-stats-org) |
INFLUX_BUCKET |
No | InfluxDB bucket (default: eero) |
make setup # Configures Git hooks for pre-commit linting| Command | Description |
|---|---|
make tidy |
Run go mod tidy and go fmt |
make lint |
Run golangci-lint |
make build |
Compile the daemon to bin/eero-stats |
make dashboard |
Regenerate the Grafana dashboard JSON |
make docker-up |
Start the full Docker Compose stack |
make docker-down |
Stop all containers |
make clean |
Remove build artifacts |
To add new metrics, create writer methods on *Poller in internal/poller/writers.go and call them from the appropriate polling tier in internal/poller/poller.go. Each writer follows a consistent pattern:
- Build a
tagsmap (indexed dimensions) - Build a
fieldsmap (metric values) - Write with
influxdb2.NewPoint(measurement, tags, fields, timestamp)
This project is open-sourced under the MIT License.
