Skip to content

feat: Add support for Elite 200 V2 - #49

Open
brunosccosta wants to merge 9 commits into
Patrick762:mainfrom
brunosccosta:el200v2
Open

feat: Add support for Elite 200 V2#49
brunosccosta wants to merge 9 commits into
Patrick762:mainfrom
brunosccosta:el200v2

Conversation

@brunosccosta

Copy link
Copy Markdown

Adding supporting for the Elite 200 v2 model. The following fields are confirmed. I'll try to map more and add in a later commit.

I had to add both E200V2 and Elite\s200\sV2 regexp because the battery itself, when reading it's registers, says it's name is "Elite 200 V2" and this is used in device_recognizer::recognize_device, while the Bluetooth name the battery uses is "E200V2" and this is used by device_builder::build_device

Bruno and others added 9 commits February 9, 2026 21:59
- Fix readall range from 20000 to 2000 registers
- Comment out pack reading code (untested)
- Add logging for register read start
- Improve exception handling in device_reader
- Add __main__ guards to all scripts
- Increase readall timeout and simplify output filename
- Update .gitignore: ignore data/ and .vscode/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- test_proxy_scan.py: scan for BLE devices via ESPHome proxy
- test_proxy.py: attempt BLE connection to Bluetti via proxy
- debug_proxy_logs.py: subscribe to ESP32 logs during connection attempt

Used to debug BLE connectivity through M5Stack Atom (ESPHome 2026.3.0).
Known issue: connection fails with GATT_BUSY on MTU negotiation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Library changes:
- e200v2.py: add TIME_REMAINING (104), BATTERY_VOLTAGE (152, ×0.01V),
  AC_INPUT_CURRENT (1315, ×0.1A), AC_OUTPUT_CURRENT (1432, ×0.1A),
  AC_OUTPUT_FREQUENCY (1470, ×0.1Hz)
- FieldName.py: add BATTERY_VOLTAGE enum value

All 5 fields confirmed by live read (pass-through mode, SoC=75%):
- 1315 = 2.8A, 1432 = 2.8A (656W ÷ 234.7V = 2.79A ✓)
- 152 = 39.89V (LFP at 75% SoC ✓)
- 1470 = 49.9Hz ✓

Tools:
- poll.py: long-running poller writing data/snapshots.jsonl
- decode_registers.py: human-readable register dump decoder
- test_direct_ble.py: quick single-register read via Mac BLE
- ble-proxy.yaml: ESPHome BLE proxy config (M5Stack Atom)
- debug_proxy_logs.py, test_proxy.py: want_disconnect_ workaround

Notebook:
- notebooks/explore.ipynb: Steps A/B/C register analysis
  (time series, state-based comparison, correlation vs known anchors)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The device reports 'Elite 200 V2' via SwapStringField (reg 110).
DEVICE_NAME_RE already matched it but DEVICES dict only had 'E200V2',
causing build_device() to return None and the device to go unrecognized.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously DeviceReader connected, did ECDH, read registers, then
disconnected and wiped encryption keys on every poll. At 60s intervals
this hammered the Bluetti BLE stack into stopping advertisement after
days (observed Apr 19, Apr 28 on Elite 200 V2 with encryption=true).

Now:
- Skip establish_connection if client.is_connected
- Skip ECDH if encryption already ready (keys survive across polls)
- Only disconnect + reset on errors via _cleanup()
- Add disconnect() for explicit teardown on coordinator shutdown

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@loganbest

Copy link
Copy Markdown

def looking forward to this merging. I have three of these Elite 200 V2's that I'd love to have monitored properly in HA

@brunosccosta

Copy link
Copy Markdown
Author

@loganbest
If you want to use this now without waiting for upstream to merge, install directly from this fork by editing the bluetti_bt custom component's manifest.json.

Find the file at /config/custom_components/bluetti_bt/manifest.json and update the requirements field:

"requirements": [
    "bluetti-bt-lib @ git+https://github.com/brunosccosta/bluetti-bt-lib.git@dc91bce5ac3bb996e0f0d6030bc289e3569f7240"
]

Then restart Home Assistant. Commit dc91bce is the tip of this branch — includes E200V2 device support, persistent BLE connection, and TIME_REMAINING minutes→hours fix.

Note: after a bluetti_bt HACS update, manifest.json gets overwritten — reapply this change afterward.

@Patrick762

Copy link
Copy Markdown
Owner

too much else in this PR. Please only submit the new device without any other changes, otherwise it's not clear what the PR does

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants