Allow clearing optional weather sources in Options
Optional weather source fields used the current selection as the form default. A cleared field that the frontend omits was refilled with the old sources by voluptuous, and an options key missing from the submission fell back to the original setup data. Optional providers could therefore not be removed in the UI. Pre-fill with suggested values instead, and save omitted optional lists as empty so they override older entry data. No UI strings changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2a0a94c640
commit
30f78fb6a9
2 files changed
+48
-5
No files matched your search
@@ -63,11 +63,21 @@ def _weather_schema(config: dict[str, Any], metrics: tuple[str, ...]):
|
||||
# A temperature source is mandatory: other weather inputs are optional.
|
||||
marker = vol.Required(key, default=selected) if selected else vol.Required(key)
|
||||
else:
|
||||
marker = vol.Optional(key, default=selected)
|
||||
# A default would re-insert old sources whenever a cleared field is
|
||||
# omitted from the submission; a suggested value only pre-fills the form.
|
||||
marker = vol.Optional(key, description={"suggested_value": selected})
|
||||
schema[marker] = _entity_picker(multiple=True)
|
||||
return vol.Schema(schema)
|
||||
|
||||
|
||||
def _with_cleared_weather(user_input: dict[str, Any], metrics: tuple[str, ...]) -> dict[str, Any]:
|
||||
"""Store an omitted optional source list as empty, so it overrides older data."""
|
||||
result = dict(user_input)
|
||||
for metric in metrics:
|
||||
result.setdefault(WEATHER_SOURCES[metric], [])
|
||||
return result
|
||||
|
||||
|
||||
def _weight_schema(rooms: list[str], existing: dict[str, float] | None = None):
|
||||
weights = existing or {}
|
||||
return vol.Schema({
|
||||
@@ -110,14 +120,14 @@ class HeatingMPCConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
if not _valid_weather(self._draft[CONF_ROOMS], user_input):
|
||||
return self.async_show_form(step_id="weather", data_schema=_weather_schema(
|
||||
user_input, WEATHER_MAIN), errors={"base": "invalid_weather"})
|
||||
self._draft.update(user_input)
|
||||
self._draft.update(_with_cleared_weather(user_input, WEATHER_MAIN))
|
||||
return await self.async_step_weather_extra()
|
||||
return self.async_show_form(step_id="weather", data_schema=_weather_schema(
|
||||
self._draft, WEATHER_MAIN))
|
||||
|
||||
async def async_step_weather_extra(self, user_input: dict[str, Any] | None = None):
|
||||
if user_input is not None:
|
||||
self._draft.update(user_input)
|
||||
self._draft.update(_with_cleared_weather(user_input, WEATHER_EXTRA))
|
||||
return await self.async_step_weights()
|
||||
return self.async_show_form(step_id="weather_extra", data_schema=_weather_schema(
|
||||
self._draft, WEATHER_EXTRA))
|
||||
@@ -161,7 +171,7 @@ class HeatingMPCOptionsFlow(config_entries.OptionsFlow):
|
||||
if not _valid_weather(self._draft[CONF_ROOMS], user_input):
|
||||
return self.async_show_form(step_id="weather", data_schema=_weather_schema(
|
||||
user_input, WEATHER_MAIN), errors={"base": "invalid_weather"})
|
||||
self._draft.update(user_input)
|
||||
self._draft.update(_with_cleared_weather(user_input, WEATHER_MAIN))
|
||||
return await self.async_step_weather_extra()
|
||||
return self.async_show_form(step_id="weather", data_schema=_weather_schema(
|
||||
config, WEATHER_MAIN))
|
||||
@@ -169,7 +179,7 @@ class HeatingMPCOptionsFlow(config_entries.OptionsFlow):
|
||||
async def async_step_weather_extra(self, user_input: dict[str, Any] | None = None):
|
||||
config = {**self.config_entry.data, **self.config_entry.options, **self._draft}
|
||||
if user_input is not None:
|
||||
self._draft.update(user_input)
|
||||
self._draft.update(_with_cleared_weather(user_input, WEATHER_EXTRA))
|
||||
return await self.async_step_weights()
|
||||
return self.async_show_form(step_id="weather_extra", data_schema=_weather_schema(
|
||||
config, WEATHER_EXTRA))
|
||||
|
||||
Reference in new issue
Block a user