Local-first EMS control for Zendure SolarFlow systems. It reads local grid meter and Zendure telemetry, controls inverter output, and provides a local dashboard.
Tip
New to EMS SolarFlow? Read the Project Overview for a non-technical introduction to the main features, supported setups, dashboards, energy management, and system administration.
EMS controls real power hardware. Read the safety guide before enabling live writes.
Each device carries one status — Validated, Family-supported, Reverse-engineered or User-reported. The maintainer validates on a SolarFlow 800 Pro 2 and a Shelly Pro; wider coverage needs community reports. Definitions and the full matrix live in docs/user/supported-setups.md.
| Hardware / integration | Connection | Status |
|---|---|---|
| SolarFlow ZenSDK inverters — 800 Pro 2, plus 800 / 800 Plus / 800 Pro / 1600 AC+ / 2400 AC / 2400 AC+ / SolarFlow 2400 Pro / 4000 AC+ | Local API (ZenSDK) + Zendure cloud MQTT | 800 Pro 2 Validated; rest Family-supported |
| Older Hub / Hyper / AIO / Ace MQTT devices — Hub 1200/2000, Hyper 2000, AIO 2400, Ace 1500 | Local or Zendure cloud MQTT | Reverse-engineered |
| Any Zendure device via API key | Zendure cloud MQTT | Telemetry for any device; control needs an exact supported model |
| Zendure & Shelly grid meters — Shelly Pro, Zendure Smart Meter 3CT / Smart Meter D0 (Local API) | HTTP | Shelly Pro Validated; Zendure meters Reverse-engineered |
| Other HTTP / MQTT grid meters — Shelly Plus/Gen2/Gen3, Shelly 3EM Gen1, everHome EcoTracker, Tasmota, generic MQTT, D0 over local MQTT | HTTP / MQTT | Family-supported / Reverse-engineered |
| Home Assistant entity as a load signal | HA API | Legacy; not recommended for new setups |
MQTT control is an implemented EMS transport, not a future feature: a supported inverter joins the same control loop, target calculation and safety gates as the Local API, over a local broker or Zendure cloud MQTT. ZenSDK cloud control is Validated on the SolarFlow 800 Pro 2; the older legacy-JSON write path is Reverse-engineered and still needs broader hardware validation — the Roadmap is confirming it on more device generations, not building the feature. Every write still requires an exact supported model, a verified write protocol, the per-device control capability and the transport write gate. Device compatibility reports (working or broken) are very welcome.
Tip
New here? Start with the Admin Console — the recommended path for most users. Browser-guided setup, hardware discovery, updates, backups and maintenance, with no shell or config-file editing. It finds your devices and sets up the connection for you.
Install and start it in a local EMS folder:
mkdir -p ems-solarflow-api-control
cd ems-solarflow-api-control
curl -fsSLO https://raw.githubusercontent.com/basecubedev/ems-solarflow-api-control/main/deploy/admin/install-admin-console.sh
sh install-admin-console.shThen open http://127.0.0.1:8090 and create the shared EMS/Admin password in
the browser. Host networking is the default (best for local discovery); add
--bridge only if you need Docker bridge networking.
Full guide with demo videos of a fresh install and a guided update: docs/user/admin-console.md
Prefer the shell? These converge on the same config/config.json, so you can
switch later.
| Path | Choose this if |
|---|---|
| Docker Bootstrap | Shell-only Docker setup |
| Developer Setup | Develop, debug or build from source |
The Admin Console picks the right one during discovery — you don't choose upfront. EMS reaches your devices over any one of:
- Local API (ZenSDK) — newer SolarFlow / ZenSDK models on your LAN. Fastest, fully local.
- Local MQTT — devices re-pointed to your own broker. Low latency, no cloud.
- Zendure MQTT (cloud) — any Zendure device via your Zendure API key. Higher latency over the internet.
- Step-by-step guides: Admin Console · EMS Dashboard
- User documentation
- Technical reference
- Developer documentation
- Full documentation map

