# bmspy bmspy is a tool to get information from a [xiaoxiang-type](https://www.lithiumbatterypcb.com/product/4s-or-3s-12v-li-ion-or-lifepo4-battery-smart-bms-with-bluetooth-function-uart-and-rs485-communication-with-60a-to-120a-constant-current/?attribute_specification-selection=4S+Lifepo4+120A+with+UART+and+RS485) BMS system, using some sort of serial connection. It can display the information as text, in JSON, or export the data continuously to InfluxDB or a Prometheus exporter. Multiple BMS/UPS devices can be connected at once. Each is identified by a name, and data from all of them (or just one) can be pushed to InfluxDB or Prometheus in the same connection, with each measurement tagged with the UPS name. To install: git clone https://git.treehouse.org.za/tim/bmspy cd bmspy poetry install Or, to install with influxdb and/or prometheus support: poetry install -E influxdb -E prometheus ## Running the server The server daemon reads from one or more serial devices and makes the data available over a Unix socket. Single device (defaults to `/dev/ttyUSB0`): poetry run bmspy-server Multiple devices, with optional names (default name is derived from the device path, e.g. `ttyUSB0`): poetry run bmspy-server -d network:/dev/ttyUSB0 -d nas:/dev/ttyUSB1 To run via systemd, copy `bmspy-server.service` to `/etc/systemd/system`, adjust `WorkingDirectory` and the `ExecStart` line as needed, then enable and start it: cp bmspy-server.service /etc/systemd/system $EDITOR /etc/systemd/system/bmspy-server.service systemctl daemon-reload systemctl enable bmspy-server systemctl start bmspy-server ## Running a client To print a summary of all connected UPSes: poetry run bmspy To show only a specific UPS: poetry run bmspy --ups network To push data for all UPSes to InfluxDB (each measurement is tagged `ups=`): poetry run bmspy-influxdb --url https://influx.example.com --org myorg --token mytoken To push data for a single UPS only: poetry run bmspy-influxdb --ups network --url ... InfluxDB connection details can also be supplied via environment variables (`INFLUXDB_V2_URL`, `INFLUXDB_V2_ORG`, `INFLUXDB_V2_TOKEN`) instead of command-line flags. ## EcoFlow Bluetooth LE devices Install the Bluetooth dependencies: ```bash poetry install -E ecoflow-bt ``` Close the EcoFlow app and stop other Bluetooth collectors before connecting. ### Setup Get your EcoFlow account user ID: ```bash poetry run bmspy-ecoflow-login you@example.com ``` The command prompts for your password. Add `--region EU` or `--region US` if needed. Use the diagnostic scan below to find device addresses and serial numbers. Type 7 authentication also needs an external lookup table from [ha-ef-ble](https://github.com/rabits/ha-ef-ble). From the bmspy repository root, download it: ```bash curl --fail --location --output bmspy/ecoflow_keydata.py \ https://raw.githubusercontent.com/rabits/ha-ef-ble/main/custom_components/ef_ble/eflib/keydata.py ``` This file is ignored by Git and excluded from packages. Type 1 devices do not need it. ### Diagnostics Scan and collect reports from nearby supported devices: ```bash poetry run python -u tools/ecoflow-bt.py --user-id YOUR_USER_ID --scan --timeout 30 ``` Add `--watch` to print every packet until Ctrl+C. Watch mode ignores the telemetry timeout, but stops on a lost connection. Its payloads are already decrypted. Keep diagnostic output private because it can contain device and account identifiers. The scan detects encryption automatically. To select one discovered device, add `--device ADDRESS`. Without scanning, replace `--scan` with `--device ADDRESS --serial-number SERIAL`. Direct connections default to Type 7. Session keys stay internal. The script has no encryption override or key-export option. River 2 collection waits for three valid core reports, not optional inverter or solar reports. A timeout reports incomplete collection. Use `--watch` to receive later reports. River 2 reports charge, temperature, power, and time estimates. Missing measurements stay absent. See the [River 2 measurement reference](docs/ecoflow-river2-fields.md) for units, decoding rules, and known limits. Client snapshots include all complete River 2 heartbeat fields under `ef_river2_*`, alongside the shared measurements and raw packets. Partial reports retain earlier field values. See the [River 2 field reference](docs/ecoflow-river2-fields.md#reported-fields-available-to-clients) for names, units, and limits.