124 files

This commit is contained in:
Home Assistant Version Control
2026-08-31 15:02:40 +00:00
parent 33de328a33
commit 9742f385a3
124 changed files with 13907 additions and 1376 deletions
@@ -29,11 +29,13 @@ from ..const import (
CONF_ADVANCED_SCHEDULE_TIME,
CONF_ADVANCED_SEASONAL,
CONF_ARCHIVE_ONEOFF_DAYS,
CONF_BATTERY_LOW_PERCENT,
CONF_BUDGET_ALERT_THRESHOLD,
CONF_BUDGET_ALERTS_ENABLED,
CONF_BUDGET_CURRENCY,
CONF_BUDGET_MONTHLY,
CONF_BUDGET_YEARLY,
CONF_DEFAULT_CONSUMABLE_THRESHOLD,
CONF_DEFAULT_WARNING_DAYS,
CONF_DELETE_ARCHIVED_ONEOFF_DAYS,
CONF_DISABLED_TEMPLATE_IDS,
@@ -59,16 +61,21 @@ from ..const import (
CONF_QUIET_HOURS_END,
CONF_QUIET_HOURS_START,
CONF_REMINDER_LEAD_DAYS,
CONF_ROW_ACTION_NOTICE,
CONF_ROW_ACTION_STYLE,
CONF_SHOPPING_LIST_ENTITY,
CONF_SNOOZE_DURATION_HOURS,
CONF_WARRANTY_REMINDER_DAYS,
CONF_WARRANTY_REMINDER_ENABLED,
CONF_WEEKLY_DIGEST_ENABLED,
DEFAULT_ARCHIVE_ONEOFF_DAYS,
DEFAULT_BATTERY_LOW_PERCENT,
DEFAULT_BUDGET_CURRENCY,
DEFAULT_CONSUMABLE_THRESHOLD,
DEFAULT_DELETE_ARCHIVED_ONEOFF_DAYS,
DEFAULT_OBJECTS_TABLE_COLUMNS,
DEFAULT_PANEL_ENABLED,
DEFAULT_ROW_ACTION_STYLE,
DEFAULT_SNOOZE_DURATION_HOURS,
DEFAULT_WARNING_DAYS,
DEFAULT_WARRANTY_REMINDER_DAYS,
@@ -105,7 +112,12 @@ _LOGGER = logging.getLogger(__name__)
_ALLOWED_SETTING_KEYS = ALLOWED_SETTING_KEYS
def _build_full_settings(options: Mapping[str, Any], *, notify_targets: list[str] | None = None) -> dict[str, Any]:
def _build_full_settings(
options: Mapping[str, Any],
*,
notify_targets: list[str] | None = None,
battery_notes: dict[str, Any] | None = None,
) -> dict[str, Any]:
"""Build a full settings dict from global entry options.
``notify_targets`` is the shared pickable-notify-target list (see
@@ -148,6 +160,12 @@ def _build_full_settings(options: Mapping[str, Any], *, notify_targets: list[str
},
"general": {
"default_warning_days": options.get(CONF_DEFAULT_WARNING_DAYS, DEFAULT_WARNING_DAYS),
# #146: household "low" floors for discovery + the battery fleet.
"default_consumable_threshold": options.get(CONF_DEFAULT_CONSUMABLE_THRESHOLD, DEFAULT_CONSUMABLE_THRESHOLD),
"battery_low_percent": options.get(CONF_BATTERY_LOW_PERCENT, DEFAULT_BATTERY_LOW_PERCENT),
# Computed, never stored: what Battery Notes currently reports
# (default + up to 5 named override devices) — the Settings hint.
"battery_notes": battery_notes,
"notifications_enabled": options.get(CONF_NOTIFICATIONS_ENABLED, False),
"notify_service": options.get(CONF_NOTIFY_SERVICE, ""),
# v2.67: buy-task shopping sync target ("" = off).
@@ -161,6 +179,11 @@ def _build_full_settings(options: Mapping[str, Any], *, notify_targets: list[str
# <config>/custom_sentences/ (the only place the classic
# conversation agent reads them from).
"install_assist_sentences": options.get(CONF_INSTALL_ASSIST_SENTENCES, False),
# #145: task-row action style + the one-time "new look" notice
# (set by the 5→6 migration for existing installs, cleared by the
# panel banner).
"row_action_style": options.get(CONF_ROW_ACTION_STYLE, DEFAULT_ROW_ACTION_STYLE),
"row_action_notice_pending": options.get(CONF_ROW_ACTION_NOTICE, False),
},
"notifications": {
"due_soon_enabled": options.get(CONF_NOTIFY_DUE_SOON_ENABLED, True),
@@ -229,11 +252,14 @@ async def ws_get_settings(
msg: dict[str, Any],
) -> None:
"""Return all global settings."""
from ..helpers.battery_fleet import battery_notes_summary
bn = battery_notes_summary(hass)
global_entry = _get_global_entry(hass)
if global_entry is None:
connection.send_result(
msg["id"],
_build_full_settings({}, notify_targets=build_notify_targets(hass)),
_build_full_settings({}, notify_targets=build_notify_targets(hass), battery_notes=bn),
)
return
@@ -243,6 +269,7 @@ async def ws_get_settings(
_build_full_settings(
options,
notify_targets=build_notify_targets(hass, current=options.get(CONF_NOTIFY_SERVICE, "")),
battery_notes=bn,
),
)
@@ -621,6 +648,12 @@ def sanitize_settings_input(settings_input: dict[str, Any]) -> tuple[dict[str, A
if CONF_NOTIFICATION_TITLE_STYLE in filtered and filtered[CONF_NOTIFICATION_TITLE_STYLE] not in NOTIFICATION_TITLE_STYLES:
del filtered[CONF_NOTIFICATION_TITLE_STYLE]
# #145: same treatment for the row-action style.
from ..const import ROW_ACTION_STYLES
if CONF_ROW_ACTION_STYLE in filtered and filtered[CONF_ROW_ACTION_STYLE] not in ROW_ACTION_STYLES:
del filtered[CONF_ROW_ACTION_STYLE]
# v1.4.6 (#44 follow-up): drop quiet-hours time strings that aren't valid
# HH:MM[:SS]. The HA TimeSelector in the options-flow rejects empty / bad
# strings as "Invalid time" and that error blocks the entire form save —