mirror of
https://github.com/sascha-hemi/hacs_waste_collection_schedule.git
synced 2026-03-21 03:04:09 +01:00
config_flow simplified for basic installation
makes it a lot easier to skip customize and sensor configuration
This commit is contained in:
@@ -5,11 +5,16 @@ import logging
|
||||
import types
|
||||
from datetime import date, datetime
|
||||
from pathlib import Path
|
||||
from typing import Any, Tuple
|
||||
from typing import Any, Tuple, TypedDict, cast
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
import voluptuous as vol
|
||||
from homeassistant.config_entries import ConfigEntry, ConfigFlow, OptionsFlow
|
||||
from homeassistant.config_entries import (
|
||||
ConfigEntry,
|
||||
ConfigFlow,
|
||||
ConfigFlowResult,
|
||||
OptionsFlow,
|
||||
)
|
||||
from homeassistant.const import CONF_NAME, CONF_VALUE_TEMPLATE
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.selector import (
|
||||
@@ -264,28 +269,36 @@ EXAMPLE_DATE_TEMPLATES = {
|
||||
}
|
||||
|
||||
|
||||
class SourceDict(TypedDict):
|
||||
title: str
|
||||
module: str
|
||||
default_params: dict[str, Any]
|
||||
|
||||
|
||||
class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call-arg]
|
||||
"""Config flow."""
|
||||
|
||||
VERSION = CONFIG_VERSION
|
||||
_country = None
|
||||
_source = None
|
||||
_country: str | None = None
|
||||
_source: str | None = None
|
||||
|
||||
_sources: dict = {}
|
||||
_sources: dict[str, list[SourceDict]] = {}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
def __init__(self, *args: list, **kwargs: dict):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._sources = self._get_source_list()
|
||||
self._options: dict = {}
|
||||
|
||||
# Get source list from JSON
|
||||
def _get_source_list(self):
|
||||
def _get_source_list(self) -> dict[str, list[SourceDict]]:
|
||||
p = Path(__file__).with_name("sources.json")
|
||||
with p.open(encoding="utf-8") as json_file:
|
||||
return json.load(json_file)
|
||||
|
||||
# Step 1: User selects country
|
||||
async def async_step_user(self, info):
|
||||
async def async_step_user(
|
||||
self, info: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_COUNTRY_NAME): SelectSelector(
|
||||
@@ -305,7 +318,10 @@ class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call
|
||||
return self.async_show_form(step_id="user", data_schema=SCHEMA)
|
||||
|
||||
# Step 2: User selects source
|
||||
async def async_step_source(self, info=None):
|
||||
async def async_step_source(
|
||||
self, info: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
self._country = cast(str, self._country)
|
||||
sources = self._sources[self._country]
|
||||
sources_options = [SelectOptionDict(value="", label="")] + [
|
||||
SelectOptionDict(
|
||||
@@ -485,7 +501,7 @@ class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call
|
||||
|
||||
async def __validate_args_user_input(
|
||||
self, source: str, args_input: dict[str, Any], module: types.ModuleType
|
||||
) -> Tuple[dict, dict, dict]:
|
||||
) -> Tuple[dict[str, str], dict[str, str], dict[str, Any]]:
|
||||
"""Validate user input for source arguments.
|
||||
|
||||
Args:
|
||||
@@ -497,7 +513,7 @@ class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call
|
||||
Tuple[dict, dict, dict]: errors, description_placeholders, options
|
||||
"""
|
||||
errors = {}
|
||||
description_placeholders: dict = {}
|
||||
description_placeholders: dict[str, str] = {}
|
||||
|
||||
if hasattr(module, "validate_params"):
|
||||
errors.update(module.validate_params(args_input))
|
||||
@@ -525,13 +541,14 @@ class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call
|
||||
return errors, description_placeholders, options
|
||||
|
||||
# Step 3: User fills in source arguments
|
||||
async def async_step_args(self, args_input=None):
|
||||
async def async_step_args(self, args_input=None) -> ConfigFlowResult:
|
||||
self._source = cast(str, self._source)
|
||||
schema, module = await self.__get_arg_schema(
|
||||
self._source, self._extra_info_default_params, args_input
|
||||
)
|
||||
self._title = module.TITLE
|
||||
errors = {}
|
||||
description_placeholders = {}
|
||||
errors: dict[str, str] = {}
|
||||
description_placeholders: dict[str, str] = {}
|
||||
# If all args are filled in
|
||||
if args_input is not None:
|
||||
# if contains method:
|
||||
@@ -547,7 +564,7 @@ class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call
|
||||
}
|
||||
self._options.update(options)
|
||||
self.async_show_form(step_id="options")
|
||||
return await self.async_step_customize_select()
|
||||
return await self.async_step_flow_type()
|
||||
return self.async_show_form(
|
||||
step_id="args",
|
||||
data_schema=schema,
|
||||
@@ -555,9 +572,30 @@ class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call
|
||||
description_placeholders=description_placeholders,
|
||||
)
|
||||
|
||||
async def async_step_flow_type(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
schema = vol.Schema(
|
||||
{
|
||||
vol.Optional("show_customize_config", default=False): bool,
|
||||
vol.Optional("show_sensor_config", default=False): bool,
|
||||
}
|
||||
)
|
||||
|
||||
if user_input is not None:
|
||||
self._show_customize_config = user_input.get("show_customize_config", False)
|
||||
self._show_sensor_config = user_input.get("show_sensor_config", False)
|
||||
if self._show_customize_config:
|
||||
return await self.async_step_customize_select()
|
||||
elif self._show_sensor_config:
|
||||
return await self.async_step_sensor()
|
||||
else:
|
||||
return await self.finish()
|
||||
return self.async_show_form(step_id="flow_type", data_schema=schema)
|
||||
|
||||
async def async_step_customize_select(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
):
|
||||
) -> ConfigFlowResult:
|
||||
schema = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_TYPE): SelectSelector(
|
||||
@@ -577,7 +615,9 @@ class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call
|
||||
return await self.async_step_customize()
|
||||
return self.async_show_form(step_id="customize_select", data_schema=schema)
|
||||
|
||||
async def async_step_customize(self, user_input: dict[str, Any] | None = None):
|
||||
async def async_step_customize(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
types = []
|
||||
if hasattr(self, "_customize_types"):
|
||||
types = self._customize_types
|
||||
@@ -586,7 +626,10 @@ class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call
|
||||
if CONF_CUSTOMIZE not in self._options:
|
||||
self._options[CONF_CUSTOMIZE] = {}
|
||||
if self._customize_index >= len(types):
|
||||
return await self.async_step_sensor()
|
||||
if self._show_sensor_config:
|
||||
return await self.async_step_sensor()
|
||||
else:
|
||||
return await self.finish()
|
||||
|
||||
errors = {}
|
||||
|
||||
@@ -619,7 +662,9 @@ class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
async def async_step_sensor(self, sensor_input: dict[str, Any] | None = None):
|
||||
async def async_step_sensor(
|
||||
self, sensor_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
if not hasattr(self, "sensors"):
|
||||
self.sensors: list[dict[str, Any]] = []
|
||||
errors: dict[str, str] = {}
|
||||
@@ -630,11 +675,7 @@ class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call
|
||||
self.sensors.append(args)
|
||||
if args.get("additional", False) is False:
|
||||
self._options.update({CONF_SENSORS: self.sensors})
|
||||
return self.async_create_entry(
|
||||
title=self._title,
|
||||
data=self._args_data,
|
||||
options=self._options,
|
||||
)
|
||||
return await self.finish()
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="sensor",
|
||||
@@ -643,6 +684,13 @@ class WasteCollectionConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call
|
||||
description_placeholders={"sensor_number": str(len(self.sensors) + 1)},
|
||||
)
|
||||
|
||||
async def finish(self) -> ConfigFlowResult:
|
||||
return self.async_create_entry(
|
||||
title=self._title,
|
||||
data=self._args_data,
|
||||
options=self._options,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(config_entry: ConfigEntry):
|
||||
|
||||
@@ -21,6 +21,18 @@
|
||||
"name": "Quelle"
|
||||
}
|
||||
},
|
||||
"flow_type": {
|
||||
"title": "Konfigurations-detailgrad auswählen",
|
||||
"description": "Wähle den Detailgrad der Konfiguration aus. Leer lassen, für einen Einfachen Kalender ohne Anpassungen und Sensoren.",
|
||||
"data": {
|
||||
"show_customize_config": "Mülltyp Anpassungsmenü Anzeigen",
|
||||
"show_sensor_config": "Sensor Konfiguration Anzeigen"
|
||||
},
|
||||
"data_description": {
|
||||
"show_customize_config": "Wähle dies, wenn du Mülltypen anpassen möchtest.",
|
||||
"show_sensor_config": "Wähle dies, wenn du Sensoren konfigurieren möchtest."
|
||||
}
|
||||
},
|
||||
"customize_select": {
|
||||
"title": "Müll Typ Anpassungen: Select (optional)",
|
||||
"description": "Wähle alle Müll Typen aus, die du anpassen möchtest.",
|
||||
|
||||
@@ -21,6 +21,18 @@
|
||||
"name": "Source"
|
||||
}
|
||||
},
|
||||
"flow_type": {
|
||||
"title": "Select Configuration Details",
|
||||
"description": "Select How detailed you want to configure this integration. Leave empty if you only want to configure a basic calendar.",
|
||||
"data": {
|
||||
"show_customize_config": "Show Collection Event Customize Configurations",
|
||||
"show_sensor_config": "Show Sensor Configurations"
|
||||
},
|
||||
"data_description": {
|
||||
"show_customize_config": "Select this if you want to customize the collection types.",
|
||||
"show_sensor_config": "Select this if you want to configure sensors."
|
||||
}
|
||||
},
|
||||
"customize_select": {
|
||||
"title": "Collection Type Customization: Select (optional)",
|
||||
"description": "Select the collection types you want to customize in the next step.",
|
||||
|
||||
Reference in New Issue
Block a user