EP760 device register map - #88
Open
mikwhe wants to merge 6 commits into
Open
Conversation
…xes — confirmed working live 2026-07-22/23, previously only existed in running container
…fields, DC_INPUT_POWER (144) mapping — confirmed live 2026-07-25
…C_INPUT_POWER (was DecimalField, should be UIntField)
This was referenced Aug 12, 2026
Open
Patrick762
reviewed
Aug 29, 2026
Contributor
Author
There was a problem hiding this comment.
Very sorry, that was a stray tatus file from a git diff redirect gone wrong — removed in the latest commit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes to the EP760 register map based on empirical BLE data captured against a live EP760 (4x B500 battery packs, ~20kWh) capable of grid export — one of very few Bluetti devices with confirmed export behavior, so this also fills a gap where upstream has essentially not tested export/negative-grid data.
All changes below are backed by raw-byte BLE captures, not inference from decoded values. Full session notes and raw data available on request — happy to share the consolidated findings doc if useful for review.
Changes
1.
AC_P1_POWER(register 1510):UIntField→IntFieldThis register is genuinely signed and goes negative during net export (grid buyback).
As
UIntFieldit wraps negative values to ~65500+ instead of reporting them as small negatives.Evidence: Live raw capture during a charge-from-grid event showed the raw register value as
62175(unsigned) — decoded correctly as−3361Wonce treated as a signed 16-bit int.History review also showed sustained ~−800W periods displaying as
64737–64739under the old unsigned interpretation.This required introducing a new
IntFieldclass (struct.unpack("!h", ...), big-endian signed short) alongside the existingUIntField/DecimalField/etc. — flagging this explicitly since it's a new field type, not just a data reinterpretation, in case an equivalent already exists upstream under a different name.2.
PV_S1/PV_S2current:UIntField→DecimalField, and reclassification of registers 1228–1230 fromSM_P1(smart meter) toPV_S3(PV String 3)Registers 1228/1229/1230 were previously mapped as a smart meter channel (
SM_P1_POWER/VOLTAGE/CURRENT). Confirmed against live hardware that these are in fact the third PV string input, not a smart meter reading — this device has 3 PV string inputs, and only 2 were previously mapped. Renamed toPV_S3_POWER/PV_S3_VOLTAGE/PV_S3_CURRENTaccordingly, and current field changed fromUIntFieldtoDecimalField(1 decimal place) to match how PV S1/S2 current is already handled elsewhere in the same file.The existing
SM_P1/SM_P2/SM_P3field names remain defined inFieldName.py/FieldUnit.pyfor other devices that do use a real smart meter channel — this PR only changes what the EP760 device definition maps register 1228 onto, not the shared enum.3. New registers:
CTRL_GRID_MAX_IMPORT_POWER(2213) andCTRL_GRID_MAX_EXPORT_POWER(2215)Discovered via deliberate register diffing against app-side setting changes (import: 11500 → 6000 → 4000W; export: 2500 → 3333W — diffs isolated to these two addresses in each case).
Behavioral confirmation for 2213: when set at or below current house load,
AC_P1_POWER(1510) reads exactly0— grid continues covering house load directly, but battery charging from grid is fully blocked. This is distinct from the ~house-load baseline (~400W) AC1 shows when the battery is simply idle but not blocked.4.
BATTERY_SOC_RANGE_START/BATTERY_SOC_RANGE_END(registers 2022/2023)Added low/high SOC display registers. Address matches the equivalent mapping already used for EP600, EP2000, AC300, AC500, and EP500 in this repo, so treated as high-confidence by analogy rather than independently BLE-captured on the EP760 specifically.
5.
HOUSE_LOAD_POWER(register 142) andDC_INPUT_POWER(register 144)Added for Home Assistant Energy Dashboard support.
HOUSE_LOAD_POWERconfirmed tracking load independently of export/import direction.6. Energy counters —
POWER_GENERATION(154),TOTAL_GRID_CONSUMPTION(156),TOTAL_GRID_FEED(158),TOTAL_LOAD_CONSUMPTION(152)POWER_GENERATION,TOTAL_GRID_CONSUMPTION, andTOTAL_GRID_FEEDcross-checked against the Bluetti app's own reported figures across 8+ days; near-exact matches.TOTAL_LOAD_CONSUMPTION(152) is included but flagged below as not fully confirmed.7.
CTRL_WORKING_MODE(2029) andCTRL_CHARGE_FROM_GRID(2207)Added as switch controls.
CTRL_WORKING_MODEconfirmed as the TOU master enable switch (not a live TOU-period indicator).Not included / known caveats
TOTAL_LOAD_CONSUMPTION(register 152): included above but not fully confirmed. An unexplained mid-day counter reset caused a ~1kWh accounting discrepancy during testing that hasn't been root-caused. Flagging so reviewers/users know this one isn't as solid as the others.Testing methodology
All findings are based on deliberate single-variable test scenarios against real hardware — known device wattages, controlled export/import setpoint changes via the Bluetti app, and raw BLE byte captures matched sample-by-sample against Home Assistant sensor history. Only registers with direct confirming evidence are included; anything inferred but not directly observed was left out or explicitly flagged above as unconfirmed.
Happy to provide raw capture logs or walk through any of the above in more detail if it helps review.