Improve local API reliability, telemetry, and control stability#18
Open
uid0c0der wants to merge 39 commits into
Open
Improve local API reliability, telemetry, and control stability#18uid0c0der wants to merge 39 commits into
uid0c0der wants to merge 39 commits into
Conversation
added 10 commits
April 16, 2026 20:19
Poll ES.GetStatus and ES.GetMode energy fields, expose them as Home Assistant total-increasing kWh sensors, and normalize PV power when payload units are inconsistent. Made-with: Cursor
Expose both summed PV input power across PV1-PV4 and raw ES.GetStatus pv_power as dedicated sensors, including coordinator mapping for pv_power. Made-with: Cursor
Expose ES.SetMode controls as Home Assistant select and number entities so users can switch operation mode and set passive power directly from the UI. Made-with: Cursor
Serialize mode/power apply tasks per entity, keep rollback path intact on final retry failure, and send UPS mode in canonical uppercase to improve device compatibility. Made-with: Cursor
Drop temporary readout/sniffer utilities from version control so upstream contribution stays focused on integration features. Made-with: Cursor
Validate ES.SetMode set_result responses, confirm mode transitions via ES.GetMode, and keep optimistic UI state consistent by rolling back when writes are not applied. Made-with: Cursor
Normalize mode string variants and retain the last confirmed mode so the select does not go empty when the device briefly returns unknown/empty mode states. Made-with: Cursor
Author
|
Tested locally on a Venus D device; the Marstek app reports firmware v147. |
Author
|
Update: final fixes are now included and verified locally.
|
Use tiered polling with safer defaults, configurable options, and mark entities unavailable after repeated poll failures instead of holding stale values indefinitely. Co-authored-by: Cursor <cursoragent@cursor.com>
Use per-category staleness for unknown values, unreachable-only unavailable after long silence, partial UDP failure recovery, and signed grid power from ongrid_power. Co-authored-by: Cursor <cursoragent@cursor.com>
Poll ES.GetStatus on every fast cycle for ongrid_power and derive non-negative export from the jaapp sign convention, with GetMode fallback and glitch smoothing. Co-authored-by: Cursor <cursoragent@cursor.com>
Channel sums from PV.GetStatus often over-report; align with jaapp and use es.pv_power as the primary total solar power value. Co-authored-by: Cursor <cursoragent@cursor.com>
Compare PV1 against active PV2–PV4 readings and apply deciwatt correction conditionally so a future firmware fix is not double-scaled. Co-authored-by: Cursor <cursoragent@cursor.com>
…aps. Derive Selling/Charging/Idle from bat_power and ES.GetStatus grid export instead of ES.GetMode ongrid alone, and keep PV category fresh when cached channel data is still valid after a missed PV.GetStatus poll. Co-authored-by: Cursor <cursoragent@cursor.com>
Treat positive ongrid_power from ES.GetStatus as export on Venus A/D, hold the last ongrid reading across brief 0 W UDP glitches, and centralize export calculation for grid power and battery status. Co-authored-by: Cursor <cursoragent@cursor.com>
Defer the first poll by 45s (configurable), skip redundant GetDevice/discovery and connection test on reload, delay scanner's initial broadcast, remove the misleading Passive Power 100 W default, and log ES.SetMode only on real writes. Co-authored-by: Cursor <cursoragent@cursor.com>
ES.GetStatus pv_power is often zero on MPPT devices; only use it when positive and otherwise sum corrected PV1–PV4 from PV.GetStatus. Co-authored-by: Cursor <cursoragent@cursor.com>
Prefer PV channel sum including retained snapshots; only report 0 W after a fresh PV.GetStatus poll, never from ES aggregate zero alone. Co-authored-by: Cursor <cursoragent@cursor.com>
Total PV now sums PV1–4 because GetStatus swears 0W while the app still shows 14W at dusk — same firmware that panics when HA dares to say hello. Co-authored-by: Cursor <cursoragent@cursor.com>
Drop indefinite sensor hold and limit coordinator ongrid glitch preserve to a single poll cycle so feed-in correctly returns to 0 W when export stops. Co-authored-by: Cursor <cursoragent@cursor.com>
Suspicious-zero rollback kept the full previous frame including export power; now accept zero ongrid/PV/CT readings while still protecting SOC. Co-authored-by: Cursor <cursoragent@cursor.com>
Scale PV1 only against reliable sibling MPPT power readings, fall back to ES.GetMode ongrid when GetStatus reports zero export, and add maintainer docs so firmware glitches are not reintroduced.
Keep README and Open API quirks documentation in English so contributors share one reference language.
- Add detailed debug logging for every scaling decision/skip in _scale_pv1_power_if_needed - Relax ratio check to 3.0-30.0 when sibling baseline < 80 W (common when PV2-PV4 drop near zero) - Update quirks documentation to mention symmetric low-light limitation Addresses cases where PV1 remained incorrectly scaled due to ratio not matching at very low power.
…or set_passive_mode and manual schedules (modeled after jaapp) - Replace fragile hard-coded power=0 in select Manual (caused idle) - Add button entities for quick mode switching - Add services: set_passive_mode, set_manual_schedule, set_manual_schedules, clear_manual_schedules - Update select to use neutral Manual config and safe Passive default - Add Platform.BUTTON and service registration
- Hoist MarstekRuntimeData / MarstekConfigEntry type alias early in __init__.py - Move coordinator/services imports after the alias is published - Switch platform + services files to if TYPE_CHECKING: import of the alias (prevents 'cannot import name ... from partially initialized module' when services/button/select etc. are pulled in during package init) This was triggered by the recent addition of button/services mode controls.
- Extend _build_mode_button_config to handle Passive and UPS (was incorrectly falling back to Auto for Ups) - Select now pushes commanded mode into coordinator.data on success (consistent with buttons + services) - Add 8-second protection on _last_confirmed_option + time tracking: recent user selections stick in the select UI even if a concurrent poll or device lag temporarily reports a different value - Clean up _build_mode_command and failure paths - Keeps last stable value during unknowns (as before) Attack on the 'always jumps back to Auto' issue. Auto/AI should stick reliably; Manual/Passive still benefit from services for non-neutral configs.
- Refactor async_setup_entry: avoid blocking sleeps and long first refresh. Use fast UDP probe for immediate ConfigEntryNotReady (delay=0) and schedule the full spaced poll via async_request_refresh() (or after startup_delay). This prevents asyncio.CancelledError from surfacing as 'setup cancelled'. - Slow discovery scanner to 300s (less UDP bursts after reload). - Preserve last-known device_mode and ct_state across transient ES data gaps. - Accept non-numeric ct_state values from ES.GetMode.
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
ES.GetStatus/ES.GetModefields (energy counters, CT power fields,pv_power) to avoid entity flicker in Home Assistantversion/verpayload variants)Battery Stored Energysensor (kWh) frombat_cap * bat_socTest plan
PV.GetStatus/ES.GetStatus/ES.GetModeon device10.1.1.26unknown/0flicker no longer appears for energy and CT sensors during intermittent response dropsBattery Stored Energyvalue matches expected formula from API fields (bat_capandbat_soc)Tested on Venus D (app reports firmware v147).