Scrape stats from a Solax X1 Boost G3 inverter and push them to an MQTT server
Go to file
Nick Thomas 77f52f0b2c Explicit 5-second timeout to ureq 2022-10-18 20:37:47 +01:00
src Explicit 5-second timeout to ureq 2022-10-18 20:37:47 +01:00
.gitignore Initial commit 2022-10-10 19:50:29 +01:00
Cargo.lock Add CLI args for configurable values 2022-10-11 23:54:59 +01:00
Cargo.toml Add CLI args for configurable values 2022-10-11 23:54:59 +01:00
LICENSE.txt Initial commit 2022-10-10 19:50:29 +01:00
README.md Add CLI args for configurable values 2022-10-11 23:54:59 +01:00

README.md

Solax2MQTT

Scrapes the HTTP endpoint of a Solax X1-Boost G3 with PocketWIFI v3 firmware and pushes the scraped values to an MQTT server. Other inverter models are available but I only have access to this one.

Published MQTT messages

solax2mqtt/<adapter-serial>/SENSOR/inverter {
  "inverter": {
    "ac_net_voltage_volts": 230.0,
    "ac_net_frequency_hz": 50.0,
    "ac_out_current_amps": 12.0,
    "ac_out_power_watts": 2000.0,
    "pv1_voltage_volts": 315.0,
    "pv2_voltage_volts": 300.0,
    "pv1_current_amps": 7.5,
    "pv2_current_amps": 7.4,
    "pv1_power_watts": 3000.0,
    "pv2_power_watts": 3000.0,
    "status": 2,
    "runtime_hours": 127,
    "temp_external_kelvin": 240,
    "temp_internal_kelvin": 250,
    "sn": "XB32xxxxxxxxxx",
    "nominal_kw": 3,
    "type": 4,
    "energy_generated_kwh_total": 105.3,
    "energy_generated_kwh_today": 5.6,
    "adapter_sn": "SXxxxxxxxx",
    "adapter_ver": "3.003.02"
  }
}

(Values made up).

Most of the data for this project came from squishykid/solax.

Alternatives

PocketWIFI is dreadfully insecure. Use Modbus-RTU or, at the very least, a PocketLAN, if you can. I'll be switching as soon as I'm able to.

Another cool project: xdubx/Solax-Pocket-USB-reverse-engineering. This is effectively a custom PocketWIFI module built out of an ESP8266. It's possible I could put one of these together and make it talk MQTT instead of having this separate daemon running. One for later.

The PocketWIFI squirts MQTTS to their cloud servers and don't verify TLS, so it can be trivially intercepted. However, the messages are in a useless (to me) binary format.

Usage

First, get TCP access to the PocketWIFI module. Over the AP, it's at 5.8.8.8. If you tell it to connect to your WIFI network, your DHCP server will assign an IP. Next, run solax2mqtt:

solax2mqtt --mqtt-url tcp://<host>:<port> \
           --solax-url http://<host>[:port] \
           --solax-password <admin-password>

That's it. Errors will be outputted to the console; failure to connect to the Solax is not fatal (it will keep retrying). Failure to connect to the MQTT server is (the process will exit).

You can also solax2mqtt --help` to see a few other options.

mqtt2prometheus

Once the metrics are in MQTT, they can be sent to prometheus using mqtt2prometheus:

---
# Remaining mqtt2prometheus options...
json_parsing:
  separator: .
metrics:
 - prom_name: inverter_ac_volts
   mqtt_name: inverter.ac_net_voltage_volts
   help: AC voltage measured by the inverter
   type: gauge
 - prom_name: inverter_ac_output_amps
   mqtt_name: inverter.ac_out_current_amps
   help: Inverter AC current
   type: gauge
 - prom_name: inverter_ac_output_watts
   mqtt_name: inverter.ac_out_power_watts
   help: Inverter AC power
   type: gauge
 - prom_name: inverter_pv1_volts
   mqtt_name: inverter.pv1_voltage_volts
   help: String 1 voltage
   type: gauge
 - prom_name: inverter_pv1_amps
   mqtt_name: inverter.pv1_current_amps
   help: String 1 current
   type: gauge
 - prom_name: inverter_pv1_watts
   mqtt_name: inverter.pv1_power_watts
   help: String 1 power
   type: gauge
 - prom_name: inverter_ac_hz
   mqtt_name: inverter.ac_net_frequency_hz
   help: AC frequency measured by the inverter
   type: gauge
 - prom_name: inverter_status
   mqtt_name: inverter.status
   help: Inverter status
   type: gauge
 - prom_name: inverter_generated_kwh_total
   mqtt_name: inverter.energy_generated_kwh_total
   help: KWh generated to date
   type: counter
 - prom_name: inverter_generated_kwh_today
   mqtt_name: inverter.energy_generated_kwh_today
   help: KWh generated today
   type: gauge
 - prom_name: inverter_external_temperature_kelvin
   mqtt_name: inverter.temp_external_kelvin
   help: Temperature measured from the outside of the inverter
   type: gauge
 - prom_name: inverter_internal_temperature_kelvin
   mqtt_name: inverter.temp_internal_kelvin
   help: Temperature measured from the inside of the inverter
   type: gauge
 - prom_name: inverter_runtime_hours_total
   mqtt_name: inverter.runtime_hours
   help: Inverter runtime
   type: counter