A tiny native macOS menu bar app showing the live solar production of a Zendure SolarFlow battery — local-first (no account, no broker, no credentials on your LAN), with an optional Zendure Cloud mode for when the local API isn't reachable.
Free & open source (MIT) · macOS 14+ · signed & notarized DMG · Sparkle auto-updates · local-first
Everything the SolarFlow reports on your LAN, one click away — and a few things you can send back to it.
Your current solar production sits permanently in the menu bar, polled every 5 seconds. Prefer something else? Show the battery percentage, the power sent to the home — or just the icon.
Battery state of charge, charge and discharge power, output to the home, grid input, per-MPPT PV input, today's solar energy, per-pack SOC and temperature, the home's total consumption — with a 15 min / day / 14 days selector, daily peak and a vs-yesterday comparison. New in 1.11: every card collapses to one line (click its header — the key value stays visible) and can be hidden entirely in Settings.
New in 2.2: the same flows, the same numbers, read two ways — a picker switches between them and remembers your choice. Schematic shows the topology: the SolarFlow at the center, panels, batteries with per-pack SOC chips, grid, home and the off-grid outlet around it, each link animating only when energy actually flows. Sankey makes ribbon width the wattage, so the split reads at a glance — and it shows what the schematic can't: how much of your consumption never goes through the battery at all. In both, the grid→home draw is explicit — measured with a Smart CT, honestly marked “not measured” without one — plus savings in € and CO₂.
New in 1.10. Away from home or LAN down? Switch to the optional Zendure Cloud mode: paste the app's Authorization Cloud Key (kept in the macOS Keychain) and the data arrives in real time over MQTT — read-only, the local API stays the default. And if a SmartMeter3CT sits in your electrical panel, the app polls it on the LAN for the home's real grid draw and total consumption. New in 1.11: an opt-in automatic switch moves to Cloud when the battery stops answering locally, and back to local as soon as it does again.
Everything the Sun window pioneered lives on in SunRoad's sidebar: per-array azimuth/tilt sliders that re-aim the panels live in the 3D scene, ephemerides computed locally (NOAA — nothing leaves your Mac), twilights and golden hours, clear-sky theoretical output with estimated efficiency, and the local weather (Open-Meteo) with a cloud-adjusted forecast.
New in 2.0. A real-3D scene of your house, your neighborhood and the sun: building footprints and roads from OpenStreetMap, the sun as an actual light source with real cast shadows sweeping across the day, your panel arrays at their true azimuth and tilt, animated energy-flow beads paced by the live watts, a production ribbon along the sun's arc, real cloud cover veiling the light, a ±48 h timeline, per-layer visibility toggles and a clean wall mode. Inspired by the Helios card for Home Assistant — in native SceneKit.
New in 1.12. Daily energy fetched from Zendure's servers — up to 365 days back, even for periods when your Mac was off. Bar charts over 7/30/90/365 days per device, per-device metric lists (solar, home, battery charge/discharge…), lifetime totals, and a local cache so past days are only downloaded once. Signs in with your main Zendure account, stored only in the Keychain — works in local and cloud modes alike.
Three sizes for the desktop and Notification Center: small and medium with the live production, and — new in 1.7 — a large widget carrying the full 14-day production histogram, so the trend stays visible even with the panel closed.
A dedicated tab to change the AC mode and the output and charge limits of the battery, written straight to the device over the local API.
Export the recorded production history to CSV and take it to a spreadsheet — daily kWh, multi-day trends, whatever you feel like plotting yourself.
Optional alerts: battery low or full, unexpected grid draw while the sun is shining, and daily production records. Plus launch at login, a theme override, an upfront permissions check, and a UI localized in French and English.
A dedicated window for the whole picture — with the energy flow readable as a schematic or as a Sankey since 2.2 — and, since 2.0, a real-3D scene of your home under its sun (SunRoad replaces the former Sun window; its analytics live on in the sidebar).
Local-first by design, but never stuck: the app can reach your battery three different ways, and the bottom of the panel always tells you which one is in use, with a green/orange status dot.
The default and the recommendation. Recent Zendure firmwares embed a plain HTTP server
on the device itself — the zenSDK REST API.
One GET /properties/report on your LAN every few seconds, found over Bonjour
or by IP. No account, no broker, no credentials, nothing leaves your network.
Away from home? Set a second address — the same battery reached through a Tailscale or WireGuard tunnel. The app polls the primary host first and switches over automatically when it doesn't answer, then keeps checking the primary to switch back. Same local API, same data, still nothing shared with anyone.
New in 1.10, and optional. When the local API isn't reachable at all, switch the data source to Zendure's servers: paste the mobile app's Authorization Cloud Key (kept in the macOS Keychain) and the reports arrive in real time over MQTT, from anywhere — no VPN. Read-only by design: battery control stays local-only. Since 1.11 the switch can even be automatic, both ways.
⚠️ A word on remote access: the zenSDK API has no authentication whatsoever. Never port-forward the device's port 80 to the internet — use a VPN into your home network and point the fallback host at that, or use the Cloud mode. The README walks through the Tailscale setup.
Developed and tested on a SolarFlow 2400 Pro. Any Zendure device that ships the local zenSDK REST API should work:
If discovery finds nothing, the local API may simply be disabled on your unit — adding a HEMS integration in the Zendure mobile app and then quitting it is the documented way to turn it on for good.
Download the DMG from the latest release — signed and notarized, so it opens without a Gatekeeper detour.
Drag ZendureMonitor.app to /Applications and launch it. It lives in the menu bar, not in the Dock.
Accept the local network prompt — macOS asks for it, and the app needs it to reach the battery on your LAN.
Point it at your device. Click the ☀️ icon → Settings → scan the network (or type the IP address) → test the connection. Done.
Updates land in-app afterwards through Sparkle — no need to come back here.
Need more? The full user guide covers every window, the widgets, battery control, remote access and troubleshooting — in French or English, also on the wiki.
The panel follows the system appearance — and you can pin it to dark or light if you'd rather it didn't follow along.