329 files

This commit is contained in:
Home Assistant Version Control
2026-08-06 13:56:25 +00:00
parent 0df89406fa
commit 7afe7add1d
330 changed files with 13098 additions and 5942 deletions
@@ -11,10 +11,17 @@ from typing import Any
import voluptuous as vol
from homeassistant.components import websocket_api
from homeassistant.core import HomeAssistant
from homeassistant.core import HomeAssistant, callback
from ..const import DOMAIN, MAX_ENTITY_ID_LENGTH
from ..helpers.battery_fleet import compute_overview, fleet_excluded_entities, has_batteries, has_battery_notes
from ..helpers.battery_fleet import (
async_compute_overview,
async_level_history,
fleet_excluded_entities,
has_batteries,
has_battery_notes,
read_batteries,
)
from ..helpers.battery_fleet_setup import (
async_mark_replaced,
async_setup_battery_fleet,
@@ -28,8 +35,12 @@ from ..helpers.permissions import require_write
@websocket_api.websocket_command({vol.Required("type"): f"{DOMAIN}/battery_fleet/overview"})
@websocket_api.async_response
async def ws_battery_fleet_overview(hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]) -> None:
"""Return the live fleet overview (low now, needs grouped, forecast)."""
ov = compute_overview(hass)
"""Return the live fleet overview (low now, needs grouped, forecast).
Goes through the ASYNC path so the ~dates use the discharge-trend
regression where the recorder data supports it (type table otherwise).
"""
ov = await async_compute_overview(hass)
fleet = find_fleet_entry(hass)
connection.send_result(
msg["id"],
@@ -71,6 +82,40 @@ async def ws_battery_fleet_overview(hass: HomeAssistant, connection: websocket_a
)
@websocket_api.websocket_command({vol.Required("type"): f"{DOMAIN}/battery_fleet/status"})
@callback
def ws_battery_fleet_status(hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]) -> None:
"""The two booleans behind the panel's one-click-setup button — cheap.
The panel used to ask the FULL overview on every load just to decide
whether to render the button, which runs the trend machinery (one
recorder regression per healthy battery on a cold cache after every HA
restart). This answers ``available`` (any trackable battery) and
``configured`` (a fleet object exists) without reading the fleet at all.
"""
fleet = find_fleet_entry(hass)
connection.send_result(
msg["id"],
{"available": has_batteries(hass), "configured": fleet is not None},
)
@websocket_api.websocket_command({vol.Required("type"): f"{DOMAIN}/battery_fleet/overview_history"})
@websocket_api.async_response
async def ws_battery_fleet_history(hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]) -> None:
"""Per-battery 30 d level history for the roster sparklines (read tier,
like overview — it renders the same data a user already sees as numbers).
Fetched lazily by the panel when the roster is expanded; the recorder
work behind it is 6 h-cached per entity (misses included), so repeated
opens are cheap. ``{series: {entity_id: {points: [[epoch_s, level]…],
threshold}}}`` — the threshold is the same one the trend forecast asks
about, so the frontend can draw the projection down to it.
"""
series = await async_level_history(hass, read_batteries(hass))
connection.send_result(msg["id"], {"series": series})
@websocket_api.websocket_command(
{
vol.Required("type"): f"{DOMAIN}/battery_fleet/setup",