Proto commits in tolwi/hassio-ecoflow-cloud

These 26 commits are when the Protocol Buffers files have changed:

Commit:5cd5bd3
Author:kolon
Committer:tolwi

fix(stream): keep PV1's field name as powGetPv, not powGetPv1 Deployed the previous two commits to real Ultra X hardware and found the PV1 sensor registered as a brand-new entity (sensor.utilities_ultra_x_ power_pv_1, an unexpected "utilities_" prefix) instead of reusing the existing sensor.ultra_x_power_pv_1 that was already there (disabled, reading the old dead powGetPv key). PV2/3/4 updated in place correctly, because their new field names (powGetPv2/3/4) exactly matched the old dead keys already wired to those entities' unique_ids -- only PV1's old key lacked a trailing digit (powGetPv, not powGetPv1), so renaming it broke that match and created a duplicate entity + orphaned the original. Renamed the new proto field back to powGetPv (still field 361, the real PV1 power) so it lines up with the pre-existing entity/unique_id, same as PV2/3/4 already do. Confirmed after redeploy: no new entity, no orphan, the original sensor.ultra_x_power_pv_1 just starts reporting live data.

Commit:752aca0
Author:kolon
Committer:tolwi

fix(stream): wire Ultra X's per-PV sensors to real protobuf fields, not dead keys devices/internal/stream_ac.py wired power_pv_1..4 to MQTT dict keys (powGetPv/powGetPv2/powGetPv3/powGetPv4) that were never defined anywhere in this class's protobuf schema (StreamACChamp_cmd21_3) -- dead wiring, always missing the dict lookup, which is why these sensors sat at 0 while power_pv_sum (a real field, 517) worked fine. Uses the mapping @zoobuv101 already raw-decoded and verified live against the EcoFlow app in #846's review thread (comment link in the proto and the issue below) but which never made it into that merged PR -- the four PV strings live in the same message as powGetPvSum, under previously-missing field numbers 361/70/996/997 (power) and their voltage/current companions, cross-checked by summing to powGetPvSum. Adds those fields to stream_ac.proto, regenerates the protobuf bindings with the pinned protoc 32.0, and wires power/voltage/current sensors to them, matching this file's existing wiring style. Fixes #889

Commit:d2872e5
Author:GnoX
Committer:tolwi

fix(proto): namespace the bk_series schema as ef_bk_series with prefixed messages

Commit:6b70f4b
Author:Leon Dönch
Committer:tolwi

Add internal/App API support for EcoFlow STREAM Microinverter (BK-series) New device class devices/internal/stream_microinverter.py for SN prefix BK01, parsing the private MQTT topic /app/device/property/<SN>. Reuses the existing StreamACSendHeaderMsg envelope (stream_ac_pb2.py) and adds a new slim bk_series.proto/_pb2 (extracted from rabits/ha-ef-ble, Apache-2.0, round-trip verified) for the DisplayPropertyUpload payload. The key new fact this relies on: msg.pdata is XOR-obfuscated with a single byte derived from the envelope's own seq field (key = seq & 0xFF), which is mandatory before the protobuf parse can succeed. Verified against 54 real device push messages. Sensors cover grid connection power/volt/amp/freq/status, both PV input paths (legacy pow_get_pv* and computed amp x vol, mirroring devices/public/stream_microinverter.py's dual-firmware approach), WiFi RSSI, and feed-in power limit/max. No setter entities yet (ConfigWrite is parsed-schema-only for now). Adds a QuotaScheduledStatusSensorEntity(reload_delay=60) status sensor and a get_quota_message() override modeled on PowerStream's INVERTER_HEARTBEAT pattern, both as a keep-alive against the device going quiet — the MQTT nudge is explicitly unverified against real hardware and documented as best-effort in the code. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Commit:d089057
Author:Luke Smith
Committer:GitHub

Add EcoFlow Stream Ultra X support and fix Stream battery telemetry (#846) Register STREAM_ULTRA_X (private) and "Stream Ultra X" (public) so the device resolves to the StreamAC handler instead of falling through to the Diagnostic device. Decode battery SoC, charge/discharge limits and discharge runtime for Stream Ultra / Ultra X. These values are only emitted inside the nested Champ_cmd21_2 protobuf message on the private API, so the schema is extended and the nested leaves are normalised onto their canonical parameter keys (soc, f32ShowSoc, bmsDsgRemTime, cmsMaxChgSoc, cmsMinDsgSoc). This keeps a single set of sensors working across every Stream variant with no duplicate entities. Values verified against a live Public API read of the same device. Co-authored-by: luke <luke@lukes-MacBook-Air.local> Co-authored-by: tolwi <tolwi@ukr.net>

Commit:95dc51e
Author:Kilian Cavalotti
Committer:tolwi

fix(delta3): decode dc_standby_time from display telemetry The DC (12V) Timeout select reads the dc_standby_time key, which the device reports in the display property upload as field 20. The proto only declared the field on the set command / set reply side (field 11), so the select stayed unknown until the first write from HA. Field number from foxthefox/ioBroker.ecoflow-mqtt. Regenerated ef_delta3_pb2 with protoc 32.0.

Commit:b3e4acb
Author:Kilian Cavalotti
Committer:tolwi

feat(delta3): add AC Charging Mode select (Auto / Silent / Custom) The DELTA 3 exposes its AC charging mode through plug_in_info_ac_in_chg_mode (display field 124, set field 125): 0 = custom user-defined watts, 1 = auto (battery-optimal power), 2 = silent charging. This is the same field 125 that the AC charging power command already writes to 0 as a companion flag: setting a manual wattage switches the device to custom mode, which is why the mode select and the power slider complement each other. Enum values from foxthefox/ioBroker.ecoflow-mqtt (AC_IN_CHG_MODE). Regenerated ef_delta3_pb2 with protoc 32.0.

Commit:45bf54c
Author:Kilian Cavalotti
Committer:tolwi

feat(delta3): expose the operating-mode Backup Reserve SOC as a number entity The DELTA 3 app configures its outage reserve through the operating mode screen (the "Backup reserve" / "Self-powered" battery partition). That value is carried by backup_reverse_soc (display property field 461, settable through Delta3SetCommand field 102, echoed in the set reply), NOT by the legacy energy_backup_en / energy_backup_start_soc pair, which stays at 0 on this firmware even when a reserve is configured in the app (verified on a real DELTA 3 Plus: app showed a 70 percent reserve while both legacy keys reported 0). Adds a "Backup Reserve SOC" number entity (BatteryBackupLevel, bounded by cms_min_dsg_soc / cms_max_chg_soc with the usual 5 point gap) so the actual reserve is readable and settable from Home Assistant. Field numbers from foxthefox/ioBroker.ecoflow-mqtt (backupReverseSoc). Regenerated ef_delta3_pb2 with protoc 32.0.

Commit:bac54c6
Author:Kilian Cavalotti
Committer:tolwi

feat(delta3): add Energy Strategy select (Standard / Self-Powered / Scheduled / TOU) The DELTA 3 family exposes its energy strategy over the private protobuf API: the active mode is reported in the display property upload as three mutually exclusive booleans nested under energy_strategy_operate_mode (field 393), and can be set through the same message written to Delta3SetCommand field 106 (field numbers and message shape from foxthefox/ioBroker.ecoflow-mqtt, verified against a real DELTA 3 Plus). Since a select entity needs one scalar state, the nested flags are collapsed into a synthetic energy_strategy_mode key (0 standard, 1 self-powered, 2 scheduled, 3 TOU) during message decoding, following the existing flow_info_* derivation pattern. The new Energy Strategy select writes all three flags explicitly on every change so the previously active strategy is cleared in the same command. Also adds the self_powered_conflict_flag (395) and tou_mode_conflict_flag (396) fields to the proto for future use. Regenerated ef_delta3_pb2 with protoc 32.0 (same as the mise task).

Commit:88b904f
Author:Roland Wunderlich
Committer:tolwi

feat(devices): add DELTA Pro Ultra X (private API), read-only The DPU X speaks the Delta Pro 3 protobuf dialect (same header, cmdFunc/cmdId routing and DisplayPropertyUpload field numbers), so DeltaPro3's decode pipeline is inherited unchanged; only the entity set and a per-pack second-pass decode are DPU-X-specific. Entities (read-only; control deferred until actuation is deliberately in scope): - enabled: aggregate battery SoC (cms_batt_soc — the DPU X has no internal pack, energy lives in up to 10 external packs), total in/out power with integrated energy sensors (kWh, total_increasing) for the Energy dashboard's battery slot (native accu_chg/dsg counters don't populate for the external-pack topology), charge/discharge remaining time, status - disabled by default: per-pack SoC/temperature for all 10 bays (DisplayPropertyUpload field 786, absent from the DP3 proto — recovered via DPUXDisplayPropertyExtra second pass), AC in/out, 240V/120V output rails (the X has no HV/LV concept; named by voltage per the manual), two HV PV inputs, per-phase output power, AC frequency, SoC limits Not supported via public_api (the developer API returns error 1006 for this device), hence internal/ only. Validated on hardware: aggregate energy vs the EcoFlow app over a battery-discharge day — discharge 21.74 vs 21.71 kWh (+0.1%), charge consistent with the panel-side energy identity to within 0.01 kWh. Docs generated with gendocs (README/summary insertion limited to this device to avoid unrelated regeneration churn). Redacted diagnostic capture included under diag/.

Commit:6114705
Author:Roland Wunderlich

Add DELTA Pro Ultra X + Smart Home Panel 3 (private API) DeltaProUltraX(DeltaPro3): aggregate + per-pack (x10) battery SoC, total in/out power with integrated energy; AC/solar/per-phase disabled by default. Per-pack array decoded from DisplayPropertyUpload field 786. SmartHomePanel3(DeltaPro3): battery SoC; home-load/grid/computed-battery flow powers with integrated energy; 32 per-circuit power (volt/amp disabled), device-provided circuit labels, 240V split-phase pair-combining. Aggregate flows labeled via grid-mode vs islanded capture. Read-only (no control entities). Sanitized diagnostics fixture. v1.5.0-shp3.3.

Commit:4513adf
Author:Tiaan Viljoen
Committer:GitHub

Glacier Classic Support (#767) * Add Glacier Classic device support * Remove unused Glacier Classic proto files * Fix Glacier Classic typing issues * Document Glacier Classic support * Use protobuf schema for Glacier Classic * Align Glacier Classic protobuf code structure * Align Glacier Classic protobuf code structure * Fix Glacier Classic protobuf packet decoding * Fix Glacier Classic power source precedence * Use plug-in flag for Glacier Classic power source * Relax Glacier Classic plug-in source detection * Expose Glacier Classic power source debug fields * Expose Glacier Classic raw power telemetry * Refresh Glacier Classic power debug attributes * Simplify Glacier Classic external supply status * Fix Glacier Classic battery protection mapping * Remove Glacier Classic fan level sensor * Make Glacier Classic screen timeout configurable * Make Glacier Classic screen timeout read-only * Move Glacier Classic simple mode to configuration * Enable Glacier Classic screen timeout sensor * Refine Glacier Classic screen timeout sensor * Restore Glacier Classic screen timeout sensor

Commit:2992aec
Author:redsilver
Committer:GitHub

feat(delta3): add USB switch + derive AC/DC/USB state from flow_info_* and fix DELTA 3 1500 charging state (#757) * feat(delta3): add Grid Bypass switch and fix AC charging power Adds a Grid Bypass switch for the protobuf-based DELTA 3 that mirrors the "Disable grid bypass" toggle in the EcoFlow mobile app. When ON, the battery disconnects from the AC input and runs standalone (no grid charging); when OFF, AC charging resumes normally. This is the missing piece for solar-surplus automations that must fully stop drawing from the grid when PV is insufficient. Implementation parallels the DELTA 3 1500 grid bypass (PR #748) but is adapted to the DELTA 3 protobuf transport: 1. `_create_delta3_bypass_ban_command` crafts a Delta3SetCommand with field 26 (`ban_bypass_en`) set manually as a 3-byte varint. Field 26 is not declared in the generated ef_delta3_pb2 schema — it was discovered by capturing MQTT SET commands issued by the mobile app on real hardware. Semantics match the DELTA 3 1500 `banBypassEn`: 0 = bypass enabled (grid charging allowed), 1 = bypass disabled (standalone). 2. `_decode_message_by_type` is extended so that, for Display property uploads (cmdId 21), it also extracts the same field 146 from the raw bytes via `_extract_proto_varint_field` and injects it as `ban_bypass_en` into the flattened dict. Field 146 is the device's read-back mirror of the bypass state; it appears in delta updates whenever the bypass is toggled, and in full snapshots that the device publishes in response to `get` requests. Absence in a delta means "no update", never "value 0". 3. A new `BypassBanScalarSwitch` class in switch.py reads this scalar varint key and reflects it as the HA entity state. The class is generic — any protobuf or JSON device that exposes its bypass state as a plain integer key can reuse it. To guarantee the switch has a correct state right after HA starts, without waiting for the user to toggle anything: 4. `Delta3.get_quota_message` is overridden to return a protobuf "get all" request (a Delta3SendHeaderMsg with a single empty Delta3Header carrying only src/dest/seq/from). This mirrors what the EcoFlow mobile app sends when opening the device page. The base `BaseInternalDevice.get_quota_message` returns a JSON `latestQuotas` message which the protobuf-only DELTA 3 firmware silently ignores, so `quota_all` was effectively a no-op on this device until now. With the override, the integration setup path (`__init__.py` -> `quota_all(None)`) publishes the request on `thing/property/get` and the device replies on `thing/property/get_reply` with a full multi-header snapshot. 5. `_prepare_data_get_reply_topic` is overridden because the default tolwi path only parses a single header and the snapshot contains several (Display + Runtime + BMS heartbeat + CMS heartbeat). The new implementation iterates every header, decodes each via `_decode_message_by_type`, and merges the results. In particular, this is what carries `ban_bypass_en` from the Display header into the entity update flow at startup. Also fixes the AC charging power number entity, which was effectively read-only: the slider range was 50-305 W (wrong — real hardware accepts 100-1500 W) and, more importantly, the generic tolwi set path only produced wire bytes for field 54 (`plug_in_info_ac_in_chg_pow_max`), which the DELTA 3 firmware silently ACKs but does not act on. Capturing the mobile app's SET packets shows that field 54 must be paired with an undeclared `field 125 = 0` companion flag for the device to actually update its setpoint. A new `_create_delta3_ac_charging_power_command` helper crafts the exact two-field pdata the app uses (`b0 03 <value_varint> e8 07 00`), and the `ChargingPowerEntity` now uses this helper and the correct 100-1500 W range. Verified that the device setpoint follows HA slider changes end-to-end. Tested on a real DELTA 3 across multiple bypass toggle cycles and AC power changes (300 / 500 / 1000 / 1500 W), and across HA restarts: the Grid Bypass switch state is correct within ~5 seconds of boot without any user interaction, and tracks both HA-side and app-side toggles in real time via push deltas. Scope limited to the protobuf-based DELTA 3. No changes touch other device classes. PR #748 covers the sibling DELTA 3 1500 on the JSON DELTA 2 dialect. * feat(delta3): add USB switch + derive AC/DC/USB enable state from flow_info_* The DELTA 3 firmware never sends cfg_ac_out_open, cfg_dc12v_out_open or cfg_usb_open in telemetry push nor in get_reply snapshots, so the HA switches for AC / DC outputs stayed "unknown" until the user manually toggled them (the SetReply was the only source). USB wasn't even exposed. MQTT sniffing confirmed: - USB on/off command is Delta3SetCommand field 19 (varint int32 0/1), undeclared in the tolwi schema. Added as cfg_usb_open in both Delta3SetCommand and Delta3SetReply. - flow_info_12v / flow_info_ac_out / flow_info_qcusb*/typec* equal 14 iff the corresponding output is enabled (verified with DC toggled ON/OFF without any load attached — value switches 4 <-> 14), and 4 when disabled. Any other value is transient and is ignored so we never overwrite a known state with a bad guess. Changes: - ef_delta3.proto: declare cfg_usb_open = 19 in SetCommand and SetReply - ef_delta3_pb2.py: regenerated - delta3.py: add USB EnabledEntity + derive cfg_dc12v_out_open / cfg_ac_out_open / cfg_usb_open from flow_info_* inside the DisplayPropertyUpload decoder. Authoritative SetReply still wins because both updates merge into the same params dict. * fix(delta3_1500): battery charging state — correct key + mapping The firmware of the DELTA 3 1500 never emits ``bms_emsStatus.chgState`` (the key the generic ``ChargingStateSensorEntity`` was reading), so the HA sensor stayed frozen at its boot value indefinitely. MQTT sniffing of a bypass ON → OFF → ON toggle cycle confirmed that: - the correct field is ``bms_emsStatus.sysChgDsgState`` - the mapping used by the firmware is NOT the 0=unused/1=charging/ 2=discharging convention of the generic class. Observed on the wire: * bypass ON (idle, BMS drain -3 A) → sysChgDsgState = 0 * bypass OFF (AC-IN charging, +3.4 A) → sysChgDsgState = 2 So 1 and 2 are swapped compared to the generic class. Introduce ``Delta31500ChargingStateSensorEntity`` with the correct mapping (0=unused, 1=discharging, 2=charging) and point it at the right key. * fix(delta3 proto): regenerate pb2 with protoc 31.1 for HA runtime 6.32 compat Home Assistant ships protobuf runtime 6.32.0, which rejects gencode produced by protoc 34.x (gencode 7.x) with VersionError 'runtime cannot be older than gencode'. Regenerate ef_delta3_pb2.py using protoc 31.1 (gencode 6.31.x), which is compatible with the 6.32.0 runtime. * feat(delta3_1500): add Grid Bypass switch via bypassBan The EcoFlow mobile app exposes a "Disable grid bypass" toggle for the DELTA 3 1500 which is not reachable via the acChgCfg/chgPauseFlag command used for the DELTA 2 family (the device silently ignores it). By sniffing the app's MQTT traffic, the actual command turns out to be `{"moduleType":1,"operateType":"bypassBan","params":{"banBypassEn":N}}`. The device mirrors the state in `pd.reserved[1]` within push telemetry: 0 = bypass enabled (charging), 1 = bypass disabled (standalone). This adds a new reusable `BypassBanSwitch` class in `switch.py` (same module as the other special-case switches) and a new `GRID_BYPASS` constant in `devices/const.py`, wired up in the DELTA 3 1500 device definition. Tested on hardware SN D361... across multiple toggle cycles; behavior matches the mobile app exactly. * fix(delta3_1500): swap 0/1 charging state mapping The mapping I committed in f050e1b was wrong. Re-verified against real operating conditions (bypass ON, battery actively supplying ~140 W of loads while disconnected from grid): * sysChgDsgState = 0 with amp BMS = -3 A → the battery is DISCHARGING, not idle. In bypass ON mode the 1500 feeds its loads directly from the battery, so "0" is the normal discharging state. * sysChgDsgState = 2 with amp BMS = +3.4 A → charging (observed after toggling bypass OFF so AC-IN takes over loads and recharges the battery). * sysChgDsgState = 1 → not observed on the wire. Assumed to be the genuinely-idle state (no AC-IN, no discharge load). Keep the "unused" label as the leftover bucket; if real-world use surfaces a different meaning we can adjust. Only 0 and 1 swap relative to the previous commit; 2 → charging stays. * style: normalize docstring sub-list indent to multiples of 4 Inner sub-lists inside docstrings (explaining proto-field mappings, bypass semantics, and the sysChgDsgState values) were previously indented at +2 spaces relative to the docstring baseline, producing 6/10-space absolute indents. Bump to +4 for PEP-8 consistency; no runtime change. * refactor(delta3): remove unused ban_bypass_en field extraction from Delta3 class * fix(delta3): ensure proper return value in Delta31500ChargingStateSensorEntity update method Co-authored-by: Copilot <copilot@github.com> --------- Co-authored-by: redsilver <18345309+redsilver@users.noreply.github.com> Co-authored-by: tolwi <tolwi@ukr.net> Co-authored-by: Copilot <copilot@github.com>

Commit:a9ddfc5
Author:redsilver
Committer:GitHub

feat(delta3): add Grid Bypass switch and fix AC charging power (#751) * feat(delta3): add Grid Bypass switch and fix AC charging power Adds a Grid Bypass switch for the protobuf-based DELTA 3 that mirrors the "Disable grid bypass" toggle in the EcoFlow mobile app. When ON, the battery disconnects from the AC input and runs standalone (no grid charging); when OFF, AC charging resumes normally. This is the missing piece for solar-surplus automations that must fully stop drawing from the grid when PV is insufficient. Implementation parallels the DELTA 3 1500 grid bypass (PR #748) but is adapted to the DELTA 3 protobuf transport: 1. `_create_delta3_bypass_ban_command` crafts a Delta3SetCommand with field 26 (`ban_bypass_en`) set manually as a 3-byte varint. Field 26 is not declared in the generated ef_delta3_pb2 schema — it was discovered by capturing MQTT SET commands issued by the mobile app on real hardware. Semantics match the DELTA 3 1500 `banBypassEn`: 0 = bypass enabled (grid charging allowed), 1 = bypass disabled (standalone). 2. `_decode_message_by_type` is extended so that, for Display property uploads (cmdId 21), it also extracts the same field 146 from the raw bytes via `_extract_proto_varint_field` and injects it as `ban_bypass_en` into the flattened dict. Field 146 is the device's read-back mirror of the bypass state; it appears in delta updates whenever the bypass is toggled, and in full snapshots that the device publishes in response to `get` requests. Absence in a delta means "no update", never "value 0". 3. A new `BypassBanScalarSwitch` class in switch.py reads this scalar varint key and reflects it as the HA entity state. The class is generic — any protobuf or JSON device that exposes its bypass state as a plain integer key can reuse it. To guarantee the switch has a correct state right after HA starts, without waiting for the user to toggle anything: 4. `Delta3.get_quota_message` is overridden to return a protobuf "get all" request (a Delta3SendHeaderMsg with a single empty Delta3Header carrying only src/dest/seq/from). This mirrors what the EcoFlow mobile app sends when opening the device page. The base `BaseInternalDevice.get_quota_message` returns a JSON `latestQuotas` message which the protobuf-only DELTA 3 firmware silently ignores, so `quota_all` was effectively a no-op on this device until now. With the override, the integration setup path (`__init__.py` -> `quota_all(None)`) publishes the request on `thing/property/get` and the device replies on `thing/property/get_reply` with a full multi-header snapshot. 5. `_prepare_data_get_reply_topic` is overridden because the default tolwi path only parses a single header and the snapshot contains several (Display + Runtime + BMS heartbeat + CMS heartbeat). The new implementation iterates every header, decodes each via `_decode_message_by_type`, and merges the results. In particular, this is what carries `ban_bypass_en` from the Display header into the entity update flow at startup. Also fixes the AC charging power number entity, which was effectively read-only: the slider range was 50-305 W (wrong — real hardware accepts 100-1500 W) and, more importantly, the generic tolwi set path only produced wire bytes for field 54 (`plug_in_info_ac_in_chg_pow_max`), which the DELTA 3 firmware silently ACKs but does not act on. Capturing the mobile app's SET packets shows that field 54 must be paired with an undeclared `field 125 = 0` companion flag for the device to actually update its setpoint. A new `_create_delta3_ac_charging_power_command` helper crafts the exact two-field pdata the app uses (`b0 03 <value_varint> e8 07 00`), and the `ChargingPowerEntity` now uses this helper and the correct 100-1500 W range. Verified that the device setpoint follows HA slider changes end-to-end. Tested on a real DELTA 3 across multiple bypass toggle cycles and AC power changes (300 / 500 / 1000 / 1500 W), and across HA restarts: the Grid Bypass switch state is correct within ~5 seconds of boot without any user interaction, and tracks both HA-side and app-side toggles in real time via push deltas. Scope limited to the protobuf-based DELTA 3. No changes touch other device classes. PR #748 covers the sibling DELTA 3 1500 on the JSON DELTA 2 dialect. * refactor(delta3): declare ban_bypass_en in proto instead of hand-crafting Following review feedback on PR #751: per-field manual varint handling is unnecessary once the fields are added to ef_delta3.proto and the pb2 is regenerated. The proto should be the single source of truth for the wire schema. Changes: - ef_delta3.proto: - Declare ban_bypass_en = 26 in Delta3SetCommand and Delta3SetReply. - Declare ban_bypass_en = 146 in Delta3DisplayPropertyUpload. - ef_delta3_pb2.py: regenerated with protoc 31.1 (gencode 6.31.x, the highest runtime-compatible level for the protobuf 6.32.0 shipped by Home Assistant; protoc 34.x produces gencode 7.x which fails at load time with VersionError). - delta3.py: - Drop _create_delta3_bypass_ban_command — replaced by the standard _create_delta3_proto_command("ban_bypass_en", ...) path. - Drop _extract_proto_varint_field entirely — field 146 is now a regular declared field and gets decoded by ParseFromString. The manual injection inside _decode_message_by_type goes away too. Wire format verified identical to the previous implementation: SetCommand ban_bypass_en=1 -> d0 01 01 (was manually emitted as such) SetCommand ban_bypass_en=0 -> d0 01 00 DisplayPropertyUpload field 146 -> 90 09 <value> --------- Co-authored-by: redsilver <18345309+redsilver@users.noreply.github.com>

Commit:39a00a9
Author:tolwi

fix(wave3): prefix proto messages with Wave3 and fix mypy errors

Commit:f967d68
Author:_Tim1
Committer:GitHub

feat: add EcoFlow Wave 3 support (#762) * feat(devices): add initial support for EcoFlow Wave 3 - Implement protobuf communication and payload parsing for Wave 3. - Add Climate entity with dynamic features (Cool, Heat, Dry, Fan, Auto). - Add sensors for power (AC/Solar/Battery), temperatures, and diagnostics. - Add UI controls for timeouts, screen brightness, beeper, and manual drainage. - Update README with Wave 3 device capabilities. * Code cleanup * added proto file for py * - Changed `Manual Drainage` from `BeeperEntity` to a standard `SwitchEntity`. - Assigned the `mdi:water-pump` icon for correct visual representation in the UI. * - Changed `Manual Drainage` from `BeeperEntity` to a standard `EnabledEntity`. - Assigned the `mdi:water-pump` icon for correct visual representation in the UI. * fix(wave3): rename drainage switch to Auto Drain * updated readme to use api-e.ecoflow.com in europe * fix(wave3): resolve climate power controls and state rubberbanding - Added missing `cfg_sys_pause` and `cfg_main_power` fields to Protobuf definitions based on app traffic sniffing. - Implemented asymmetric power logic: turning off now uses `cfg_sys_pause=True`, while turning on uses `cfg_main_power=True`. - Updated `hvac_mode` state evaluation to check for system pause and main power flags, fixing the UI rubberband effect. * fix(wave3): sync power state via dev_sleep_state to prevent rubberbanding - Replaced unreliable power state caching with native telemetry field evaluation. - Identified `dev_sleep_state` (field 212) via packet sniffing as the definitive indicator for the device's actual power status (1 = Off, 0 = On).

Commit:ba6680f
Author:Daniel Leib
Committer:GitHub

Add SMART_PLUG device support for private API (#391) (#725) * Add SMART_PLUG device support for private API (#391) - added SMART_PLUG device and protobuf - added SMART_PLUG to the registry - added a new `number.MaxWattsEntity` * Refactor Smart Plug message handling and update documentation --------- Co-authored-by: tolwi <tolwi@ukr.net>

Commit:8024ade
Author:Josh Sorchik
Committer:GitHub

Add support for EcoFlow Alternator 800W smart charger (#716) Adds a new ALTERNATOR device type for the EcoFlow 800W Alternator Charger, which communicates via a private protobuf-over-MQTT protocol (cmd_func=254) rather than the standard JSON API used by other devices. Protocol details discovered through hardware reverse-engineering: - cmd_id=21: device heartbeat (sensor data, XOR-encrypted with seq byte) - cmd_id=17: config write (app → device) - cmd_id=37: push / command-applied confirmation (decoded as heartbeat) - Commands must target dest=20 (device address), not dest=53 (MQTT broker) Entities exposed: Sensors (enabled by default): - Alternator In Power (W) - Station Power (W) - Station Battery Charge (%) - Car Battery Voltage (V) - Alternator Temperature (°C) - Charge / Discharge Remaining Time (min) Controls: - Charging Enabled (switch) - Operation Mode select: Charge / Battery Maintenance / Reverse Charge - Charge Current Limit (A, 1–70 A) — alternator → station - Reverse Charge Current Limit (A, 1–70 A) — station → car - Car Battery Start Voltage (V, 11–30 V) Diagnostic sensors (disabled by default): - Rated Power, Charging Power Limit, WiFi RSSI, Status Code - Per-mode current limits and rated maximums - Extension Cable Length, Operation Mode raw value Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

Commit:1d23802
Author:Oleksii Parashchyn
Committer:GitHub

Delta 3 updates (#662) Co-authored-by: Oleksii Parashchyn <oleksii.parashchyn@tomtom.com>

Commit:cc70c59
Author:tolwi
Committer:GitHub

Major proto refactoring (#644) * refactor: update protobuf definitions * update proto: make messages prefixed * finalizing protobuf refactoring * refactor: update Smart Meter sensor keys and protobuf definitions

Commit:2261a08
Author:Andrew F
Committer:GitHub

River 3 support (#624) * River 3 support * code review fixes * changed log level

Commit:bdbadd1
Author:Altair
Committer:GitHub

Delta Pro 3 (app api) (#595) * Add comprehensive CLAUDE.md development guide - Add VS Code task descriptions for Reset homeassistant, Generate Docs, and Run Home Assistant Core - Document dual API architecture (private/public) - Explain device registry structure with internal/public implementations - Detail MQTT client architecture and protocol buffer usage - Document entity types, configuration migration, and development workflow - List key dependencies and development utilities - Provide guidance for manual testing and documentation generation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: Add comprehensive Delta Pro 3 device support and development infrastructure This squashed commit consolidates multiple improvements: **Device Support:** - Add complete Delta Pro 3 device implementation (642 lines) - Implement sensors, switches, and controls for Delta Pro 3 - Add protocol buffer definitions and generated code (1214 lines) - Update device registry with new device mappings **Development Infrastructure:** - Add comprehensive Makefile with development shortcuts - Implement reset, docs, run, dev, and clean targets - Add UTF-8 decode error handling for binary protobuf data - Improve MQTT message processing for binary data **Technical Improvements:** - Add support for binary protobuf data detection - Implement proper error handling for non-JSON messages - Update device parameter IDs and configurations - Add comprehensive device documentation generation Co-Authored-By: Claude <noreply@anthropic.com> * ミスこれはコミットしない * fix(DeltaPro3): 統一Headerメッセージ使用でエンティティ情報取得を修正 - setMessageで重複していたsetHeaderを削除し、統一されたHeaderメッセージを使用 - Protocol Buffersの構造統一により、DeltaPro3のエンティティ情報取得機能を復旧 - 生成されたPythonファイルも対応する構造変更を反映 Fixes: DeltaPro3統合機能でエンティティ情報が取得できない問題 * Add support for cmdFunc=254, cmdId=22 message type - Add cmdFunc254_cmdId22_Report message definition to ef_dp3_iobroker.proto - Add handling for cmdFunc=254, cmdId=22 in delta_pro_3.py - Add handling for cmdFunc=254, cmdId=23 in delta_pro_3.py - Add fallback handling when protobuf classes are not available * Fix pb2 scope issue in delta_pro_3.py - Add pb2 import to _decode_header_message method - Add pb2 import to _decode_message_by_type method - Fix 'name pb2 is not defined' error in all methods that use pb2 * Fix HeaderMessage decoding error in delta_pro_3.py - Add better error handling for pb2 module import - Add detailed error logging for HeaderMessage parsing - Improve debugging information for protobuf issues * Improve fallback handling for cmdFunc254 messages - Change warning to debug level for missing protobuf classes - Add basic timestamp extraction from raw data - Improve error handling for cmdFunc=254, cmdId=22 and cmdId=23 messages * Fix cmdFunc=254, cmdId=22 to use correct RuntimePropertyUpload message type - Change from cmdFunc254_cmdId22_Report to RuntimePropertyUpload - Update comments to reflect correct message purpose (ランタイムプロパティ) - Maintain fallback handling for when protobuf classes are not available - Based on documentation: cmdId=22, cmdFunc=254 is RuntimePropertyUpload for frequent runtime data * Add ef_dp3_iobroker_pb2 import to preload_proto.py and update descriptor in ef_dp3_iobroker_pb2.py - Added import for ef_dp3_iobroker_pb2 in _preload_proto.py - Updated DESCRIPTOR in ef_dp3_iobroker_pb2.py to include ecopacket.proto for improved message handling * chore: Add dev-only files to .gitignore on main branch Prevent development-specific files from being committed to main branch: - AI assistant configurations (.claude/, .cursor/) - Development documentation (docs_4ai/) - Research scripts (scripts/) - Development tools (.devcontainer/post-start.sh, Makefile, etc.) Main branch should only contain upstream sync + DeltaPro3 support code. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Resolve Delta Pro 3 integration issues and protobuf compatibility - Remove duplicate message definitions from ef_dp3_iobroker.proto (EventRecordItem, ProductName*, RTCTime* were already in platform.proto) - Fix import statement to use relative import in ef_dp3_iobroker_pb2.py (Changed `import ecopacket_pb2` to `from . import ecopacket_pb2`) - Add missing imports: smart_meter, stream_ac to registry.py (These were lost during upstream merge conflict resolution) - Fix duplicate delta_pro_3 import that was causing issues - Update manifest.json: protobuf>=4.23.0 → protobuf>=6.32.0 (Required for protobuf 6.x compiled proto files compatibility) - Merge conflict during upstream sync caused missing imports - Proto files compiled with protobuf 6.x required runtime upgrade - Duplicate definitions caused "duplicate symbol" errors Fixes integration startup and MQTT connection for Delta Pro 3 devices. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Correct protobuf import paths for Delta Pro 3 integration Change absolute imports to relative imports in ef_dp3_iobroker_pb2 files to resolve ModuleNotFoundError for ecopacket_pb2 module. Changes: - ef_dp3_iobroker_pb2.py: Use relative import for ecopacket_pb2 - ef_dp3_iobroker_pb2.pyi: Use relative import and consolidate typing imports - Add Japanese translation file (ja.json) - Add detailed fix documentation The protobuf files are auto-generated from .proto files, but the import style depends on the protoc version used. Relative imports are correct for same-directory modules in Python packages. Resolves: ModuleNotFoundError: No module named 'ecopacket_pb2' 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat(delta-pro-3): Add BMSHeartBeatReport support for battery metrics Add missing BMSHeartBeatReport protobuf message to support battery cycles and energy accumulation tracking in Delta Pro 3. Changes: - Add BMSHeartBeatReport message (82 fields) to ef_dp3_iobroker.proto - Recompile protobuf with compatible version 5.29.0 - Fix relative imports in generated protobuf files - Update sensor definitions to use BMSHeartBeatReport fields: - cycles: Battery cycle count - accu_chg_energy: Total charge energy (Wh) - accu_dsg_energy: Total discharge energy (Wh) - Fix protobuf version requirement: 6.32.0 -> 5.29.1 This resolves unknown/unavailable entity issues for: - Battery Cycles - Total Charge Energy - Total Discharge Energy 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix(delta-pro-3): Fix BMSHeartBeatReport decoding for cycles and energy metrics - Remove incorrect cmdFunc=32,cmdId=50 -> RuntimePropertyUpload mapping - Add cmdId=50 to BMSHeartBeatReport condition for proper decoding - Restore BaseDevice to upstream state (remove _is_binary_data) - Add development commands to Makefile (run, restart, stop, logs, status) - Add debug logging and fallback handling Fixes 3 unavailable entities: - Cycles (field 14) - Total Charge Energy (accu_chg_energy, field 79) - Total Discharge Energy (accu_dsg_energy, field 80) Reference: ioBroker confirms cmdFunc=32, cmdId=50 = BMSHeartBeatReport * fix(delta-pro-3): Use camelCase for energy sensor field names - Change sensor field names from snake_case to camelCase - accuChgEnergy and accuDsgEnergy now match Protobuf MessageToDict output - Follows upstream pattern (stream_ac.py uses same convention) - Fixes Total Charge Energy and Total Discharge Energy entities - All 44 Delta Pro 3 entities now working (100% success rate) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Add .serena to .gitignore on main branch * refactor(delta_pro_3): fixes per review + import order cleanup Ref: https://github.com/tolwi/hassio-ecoflow-cloud/pull/595#pullrequestreview-3379894661 (cherry picked from 516ceb6, 80a05d1) * Regenerate ef_dp3_iobroker_pb2.py from ef_dp3_iobroker.proto; keep dp3 import fallback in delta_pro_3.py * Fix import: use package-relative import for ecopacket_pb2 in ef_dp3_iobroker_pb2.py * fix: 統一ef_dp3_iobroker_pb2のインポートパターンと重複シンボルエラー修正 - _preload_proto.pyでef_dp3_iobroker_pb2を事前読み込み - delta_pro_3.pyでモジュールトップレベルでインポート(powerstream.pyと同じパターンに統一) - dev_apl_commを_preload_proto.pyから削除(TIME_TASK_MODE重複シンボルエラー回避) - 空のimport文を削除してSyntaxErrorを修正 これにより、エンティティが正常にデータを取得できるようになった。 * revert: Remove development-only .gitignore changes from PR Development-specific .gitignore entries should only exist in dev branch, not in PR to upstream/main --------- Co-authored-by: NEXTAltair <1401591+NEXTAltair@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>

Commit:f5421af
Author:Stefan Schmidt
Committer:GitHub

PowerStream Private API Improvements (#515) * ecoflow_mqtt.py: __target_topics: Remove unneeded sn iteration * api/__init__.py: Tiny fixes * PowerStream: Upgrade private API support * Implement commands already available in public API * Add Feed-in control (only available via private API) * Add daily energy totals (only available via private API) Big thanks to * Waly_de (Markus Walber) over at [1] who has implemented the quota request for PowerStream/private API * the contributors over at [2] that have implemented sending commands in the private API and support for daily energy totals [1] https://forum.iobroker.net/topic/66743/ecoflow-connector-script-zur-dynamischen-leistungsanpassung [2] https://github.com/peuter/ecoflow * Pre-load proto files at import time This prevents warning messages emitted by Home Assistant about blocking open calls. Implementing the pre-loading required breaking import cycles.

The documentation is generated from this commit.

Commit:470a38c
Author:Angelius
Committer:GitHub

Proto stream - private_api (#492) * Init proto for stream with non revelant value name * Proto stream - naming some fields and popupale sensors * Proto stream - update proto mapping * Proto stream - update private api - add new mapping - remove not mapped sensors/diag by default * Change log level * Update documentation * Update documentation gen * Update _prepare_data for "thing/property/get" topic * fix _prepare_data for "thing/property/get" topic - update to avoid error logs with this topic (json flow and not proto flow)

Commit:a93ee2c
Author:tolwi
Committer:GitHub

public api (#265) - public API support - Delta 2, River 2, River 2 Max, Smart Plug integration via public api - diagnostic option

Commit:20e0d50
Author:Matt Wells
Committer:GitHub

WIP: Add PowerStream Support (#66) * Add Deserialiser for PowerStream packet * Add Sensors * Switches and selects required for a device * Use Protobuf to read MQTT packets * Add Protobuf Requirement to Manifest * Corrected Python Import and Map Heartbeat object to Dictionary * Improvements to Protobuf Descriptors * Ignore Empty Heartbeat Fields * Tidy Up Sensors * Fix for Upstream Changes Timestamp field added to raw payload * Correcting Watt Sensor Units for PowerStream * New Sensor for Celsius at the factor of 10^-1 * Mistake with name for Inverter Frequency * New Sensor for Frequency at the factor of 10^-1 in Hertz * New Sensor for Volts at the factor of 10^-1 * Correcting Power Factor for Various Volt and Amp fields Still missing solutions for what appear random values in AC Input Volts, AC Op Volts and Inverter Output Volts * Add Battery Charge and Discharge Time * Restore Sensors Accidently Deleted in Rebase * Disable AC Input Volts, AC Op Volts and Inverter Output Volts I don't know what these fields do, my guess is that they are settings * Added PowerStream to ReadMe.md * Add Status Fields * Fix Solar 1 Status Type * Change Misc Sensors to Diagnostic Category * Misc Sensor isn't a Measurement