AP300: Add sensors, controls, and encrypted write support - #58
AP300: Add sensors, controls, and encrypted write support#58happytechca wants to merge 8 commits into
Conversation
Add 18 new fields confirmed via BLE register scanning: - Sensors: time remaining, AC input frequency/current, AC output frequency/voltage - Controls: AC/DC toggle, eco mode (DC/AC), charging mode, power lifting, SOC range - Version: BMS version Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove eco timer modes, eco min power thresholds, and BMS version fields that add BLE polling overhead without providing actionable data in Home Assistant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
V2 devices (AP300, etc.) use ECDH + AES-CBC encryption over BLE. DeviceWriter has no handshake support, so writes silently failed. Add write(field, value) to DeviceReader which reuses the existing connect/handshake/notify/cleanup machinery to send encrypted write commands. This unblocks switch and select controls on encrypted devices. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NumberField extends UIntField with is_writeable()=True, enabling writable number entities in HA. AP300's BATTERY_SOC_RANGE_START (2022) and BATTERY_SOC_RANGE_END (2023) are now NumberField(min=0, max=100). BluettiDevice gains get_number_fields() and get_sensor_fields() now excludes NumberField instances. build_write_command() converts float values to int for NumberField writes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- WorkingMode enum: Custom=1, Self-consumption=2, Backup=4, Time of Use=5 - CTRL_WORKING_MODE SelectField at register 2005 - CTRL_CHARGE_FROM_GRID SwitchField at register 2207 - Both FieldName entries added Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Uses existing DisplayMode enum (SEC30=2, MIN1=3, MIN5=4, NEVER=5) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add AP300 to the Controls table with all validated controls - Add new control columns (working_mode, charge_from_grid, etc.) - Add @happytechca as AP300 contributor - Update write command docs to reflect encryption support - Remove unused FieldName import from NumberField Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- NumberField: writeable, allowed types, parse, range validation - BluettiDevice: get_number_fields, sensor exclusion, build_write_command with int and float values - DeviceReader.write: switch field, number field, non-writeable field - Update mock to handle write (action=6) commands separately from reads Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Hey! I noticed we solved the same problem in different ways. I ran into the exact same encryption write problem on my AC180P and opened PR #59 which fixes Then I noticed that even with encryption working, every toggle still took 5–14 seconds because of reconnecting on every write. So I opened a follow-up PR (#60) that introduces a If you want to see how it all looks wired up on the HA integration side, I have a test branch here: If PR #59 lands, the Would you consider splitting that out into a separate PR? Happy to hear any thoughts or feedback on my approach too — always open to suggestions |
|
@defire04 It's funny we worked on the same issue about a day apart. I agree your approach is better, keeping the write logic in DeviceWriter rather than mixing it into DeviceReader makes a lot more sense from a separation of concerns perspective. And the persistent BLE connection in PR #60 is exactly what was needed. I had the same 5-14s toggle lag on my AP300 and it was on my list to investigate. Glad you already tackled it, initial tests looks good with my AP300 device. Here's what I've done to move things forward:
I'll close PR #58 since #61 supersedes it. Thanks for your work! |
Summary
This PR expands AP300 support with new sensors and writable controls, discovered through
register scanning on an Apex 300 unit I recently acquired.
I want to acknowledge upfront that this touches quite a few files (14) across several areas of the codebase
I would have preferred to keep it tighter, but adding writable controls to an encrypted device
required changes that cut across the fields, enums, device reader, and base device layers.
I tried to keep each change minimal and consistent with existing patterns.
AP300 sensors added
AP300 controls added
New:
NumberFieldA new writeable field type (extends
UIntField) for numeric slider controls like SOCrange. This required:
NumberFieldclass inbluetti_bt_lib/fields/get_number_fields()onBluettiDeviceNumberFieldhandling inbuild_write_command()(float → int conversion)get_sensor_fields()so sliders aren't surfaced as read-only sensorsNew:
WorkingModeenumEnum with values: CUSTOM (1), SELF_CONSUMPTION (2), BACKUP (4), TIME_OF_USE (5)
New:
DeviceReader.write()methodThe existing
DeviceWriterclass explicitly does not support encryption ("Encryption on writes is not yet supported"), and lacks the BLE notification handler and key exchange infrastructure needed to communicate with encrypted devices like the AP300.Rather than duplicating all of that plumbing into
DeviceWriter, this PR adds awrite()method toDeviceReader, which already has the full encryption handshake, notification handling, and connection lifecycle in place.This keeps the encrypted write path minimal and avoids diverging two parallel implementations.
Tests (18 new, all 91 pass)
NumberField: writeable, parse, range validation, allowed write typesBluettiDevice:get_number_fields(), sensor exclusion,build_write_commandwith NumberFieldDeviceReader.write(): switch write, number write, non-writeable rejectionREADME updates
@happytechcaas AP300 contributorA note to @Patrick762
I'm very open to feedback, suggestions, or alternative approaches. If you'd prefer this broken into smaller PRs, scoped differently, or reworked in any way. Thank you!
Side note: Most of this code has been written by Claude Code and manually reviewed before the PR.