Local MQTT gateway for FoxESS M1/Q1 microinverters - No cloud required

A Raspberry Pi-based gateway that pulls telemetry from FoxESS M1 (and potentially Q1) microinverters like the popular M1-800-E into Home Assistant without using the FoxESS cloud or mobile app at any point. The Pi intercepts the inverter's local TCP-to-cloud connection, decodes the proprietary frame format, and publishes everything to MQTT with auto-discovery.

What's in:

  • Setup via Bluetooth. The Pi can provision new and existing inverters directly over BLE, so the FoxESS mobile app isn't needed for setup.
  • Local telemetry every 90 s: PV power/voltage/current per string, AC power/voltage/current/frequency, inverter temperature, lifetime generation, lifetime grid export.
  • Diagnostic sensors: operating state, fault state, last fault code with a human-readable message, last fault time.
  • Optional cloud relay if you want the FoxESS app and cloud to keep working alongside.
  • Mesh-aware: with multiple inverters, sensors expose which one is the WiFi-connected mesh root and which are followers.
  • One install script sets up the AP, DHCP, redirect, daemon, and HA discovery and provision your inverter so it uses the new Wifi network.

Q1 testers wanted. The decoder has model-aware support for the Q1's third and fourth PV strings, but I don't own a Q1 to validate against. If you have one — particularly Q1-1600-E, Q1-2000-E, Q1-2400-E, or Q1-2500-E — and would be willing to try the installer and report what works or breaks, that would help close that gap.

Code, setup instructions, and a runbook:
github.com/040medien/foxess_local_gateway

Would this work on any FoxESS inverter. Like the hybrid's? As long as they have a wifi-signal to send?

The honest answer is that I don't know. If they are built on the same platform, then I expect their communication protocol to be the same, but that only the fields that I've implemented for M1 (and potentially Q1) would be shown. There are plenty of zeros in the data packages I've observed, so I suspect that's where the model-specific data would live for those. The debug logs of my implementation would contain them, so if you want to try it and send me those, that would be a start. But I would need to also get full cloud data exports for the same time duration to correlate it with real world data so I can decode the fields.