Adds a Select entity with four options (Normal / Charge Disabled /
Discharge Disabled / Both Disabled) that sends the 0xE1 write command
to the BMS and immediately refreshes sensor state. Current option is
derived from the mos_charge_enabled / mos_discharge_enabled bits
already parsed on every poll.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Device name: coordinator now takes name=entry.title so the HA device card
shows the actual BLE advertised name instead of "Xiaoxiang Smart BMS"
- Hard poll timeout: each poll is capped at (poll_interval - 3)s via
asyncio.wait_for so a stalled poll can't bleed into the next cycle
- Request timeout: 5s → 3s (BMS should reply in <1s under normal conditions)
- Retry delay: 0.5s → 0.3s between retries
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Retries (bluetooth_handler):
- request() now retries up to 3× with 0.5s pause between attempts
- Tries Write With Response first, falls back to Write Without Response
automatically if the characteristic rejects it — handles both BMS variants
Number entity (number.py):
- "Nominal Capacity (Override)" lets user correct a stale BMS capacity value
(e.g. after a cell upgrade) without PC software
- Value is restored across HA restarts via RestoreEntity
- Immediately patches coordinator.data so the sensor reflects it without
waiting for the next poll
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>