Serial paths and collector interfaces remain compatible. Bluetooth polling uses a 60-second cache and backoff. Offline Bluetooth devices no longer retry forever inside a client request. Invalid device specifications do not echo account IDs.
bmspy
bmspy is a tool to get information from a xiaoxiang-type 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=<name>):
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:
poetry install -E ecoflow-bt
Close the EcoFlow app and stop other Bluetooth collectors before connecting.
Setup
Get your EcoFlow account user ID:
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. From the bmspy repository root, download it:
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:
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 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
for names, units, and limits.