diff --git a/homeassistant/components/knx/__init__.py b/homeassistant/components/knx/__init__.py index d19b505d7ff53f..0ee37bbfffc377 100644 --- a/homeassistant/components/knx/__init__.py +++ b/homeassistant/components/knx/__init__.py @@ -209,7 +209,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: return bool(hass.config_entries.async_entries(DOMAIN)) conf = dict(conf) - hass.data[DATA_KNX_CONFIG] = conf # Only import if we haven't before. @@ -226,19 +225,19 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Load a config entry.""" conf = hass.data.get(DATA_KNX_CONFIG) - - # When reloading - if conf is None: - conf = await async_integration_yaml_config(hass, DOMAIN) - if not conf or DOMAIN not in conf: - return False - - conf = conf[DOMAIN] - - # If user didn't have configuration.yaml config, generate defaults + # `conf` is None when reloading the integration or no `knx` key in configuration.yaml if conf is None: - conf = CONFIG_SCHEMA({DOMAIN: dict(entry.data)})[DOMAIN] - + _conf = await async_integration_yaml_config(hass, DOMAIN) + if not _conf or DOMAIN not in _conf: + _LOGGER.warning( + "No `knx:` key found in configuration.yaml. See " + "https://www.home-assistant.io/integrations/knx/ " + "for KNX entity configuration documentation" + ) + # generate defaults + conf = CONFIG_SCHEMA({DOMAIN: {}})[DOMAIN] + else: + conf = _conf[DOMAIN] config = {**conf, **entry.data} try: @@ -366,7 +365,6 @@ def __init__( self.entry.async_on_unload( self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self.stop) ) - self.entry.async_on_unload(self.entry.add_update_listener(async_update_entry)) def init_xknx(self) -> None: @@ -406,7 +404,6 @@ def connection_config(self) -> ConnectionConfig: route_back=self.config.get(ConnectionSchema.CONF_KNX_ROUTE_BACK, False), auto_reconnect=True, ) - return ConnectionConfig(auto_reconnect=True) async def connection_state_changed_cb(self, state: XknxConnectionState) -> None: diff --git a/homeassistant/components/knx/config_flow.py b/homeassistant/components/knx/config_flow.py index 01e71eb37af538..99cdc4807c6cbc 100644 --- a/homeassistant/components/knx/config_flow.py +++ b/homeassistant/components/knx/config_flow.py @@ -44,7 +44,7 @@ class FlowHandler(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 - _tunnels: list + _tunnels: list[GatewayDescriptor] _gateway_ip: str = "" _gateway_port: int = DEFAULT_MCAST_PORT @@ -64,25 +64,6 @@ async def async_step_user(self, user_input: dict | None = None) -> FlowResult: async def async_step_type(self, user_input: dict | None = None) -> FlowResult: """Handle connection type configuration.""" - errors: dict = {} - supported_connection_types = CONF_KNX_INITIAL_CONNECTION_TYPES.copy() - fields = {} - - if user_input is None: - gateways = await scan_for_gateways() - - if gateways: - supported_connection_types.insert(0, CONF_KNX_AUTOMATIC) - self._tunnels = [ - gateway for gateway in gateways if gateway.supports_tunnelling - ] - - fields = { - vol.Required(CONF_KNX_CONNECTION_TYPE): vol.In( - supported_connection_types - ) - } - if user_input is not None: connection_type = user_input[CONF_KNX_CONNECTION_TYPE] if connection_type == CONF_KNX_AUTOMATIC: @@ -99,6 +80,22 @@ async def async_step_type(self, user_input: dict | None = None) -> FlowResult: return await self.async_step_manual_tunnel() + errors: dict = {} + supported_connection_types = CONF_KNX_INITIAL_CONNECTION_TYPES.copy() + fields = {} + gateways = await scan_for_gateways() + + if gateways: + # add automatic only if a gateway responded + supported_connection_types.insert(0, CONF_KNX_AUTOMATIC) + self._tunnels = [ + gateway for gateway in gateways if gateway.supports_tunnelling + ] + + fields = { + vol.Required(CONF_KNX_CONNECTION_TYPE): vol.In(supported_connection_types) + } + return self.async_show_form( step_id="type", data_schema=vol.Schema(fields), errors=errors ) @@ -107,8 +104,6 @@ async def async_step_manual_tunnel( self, user_input: dict | None = None ) -> FlowResult: """General setup.""" - errors: dict = {} - if user_input is not None: return self.async_create_entry( title=f"{CONF_KNX_TUNNELING.capitalize()} @ {user_input[CONF_HOST]}", @@ -129,6 +124,7 @@ async def async_step_manual_tunnel( }, ) + errors: dict = {} fields = { vol.Required(CONF_HOST, default=self._gateway_ip): str, vol.Required(CONF_PORT, default=self._gateway_port): vol.Coerce(int), @@ -149,8 +145,6 @@ async def async_step_manual_tunnel( async def async_step_tunnel(self, user_input: dict | None = None) -> FlowResult: """Select a tunnel from a list. Will be skipped if the gateway scan was unsuccessful or if only one gateway was found.""" - errors: dict = {} - if user_input is not None: gateway: GatewayDescriptor = next( gateway @@ -163,6 +157,7 @@ async def async_step_tunnel(self, user_input: dict | None = None) -> FlowResult: return await self.async_step_manual_tunnel() + errors: dict = {} tunnel_repr = { str(tunnel) for tunnel in self._tunnels if tunnel.supports_tunnelling } @@ -182,8 +177,6 @@ async def async_step_tunnel(self, user_input: dict | None = None) -> FlowResult: async def async_step_routing(self, user_input: dict | None = None) -> FlowResult: """Routing setup.""" - errors: dict = {} - if user_input is not None: return self.async_create_entry( title=CONF_KNX_ROUTING.capitalize(), @@ -205,6 +198,7 @@ async def async_step_routing(self, user_input: dict | None = None) -> FlowResult }, ) + errors: dict = {} fields = { vol.Required( CONF_KNX_INDIVIDUAL_ADDRESS, default=XKNX.DEFAULT_ADDRESS @@ -434,7 +428,7 @@ async def async_step_init( ) -async def scan_for_gateways(stop_on_found: int = 0) -> list: +async def scan_for_gateways(stop_on_found: int = 0) -> list[GatewayDescriptor]: """Scan for gateways within the network.""" xknx = XKNX() gatewayscanner = GatewayScanner(