Remove KNX yaml config from hass.data (#124050)

* Remove KNX yaml config from `hass.data`

* Use HassKey
This commit is contained in:
Matthias Alphart 2024-09-09 09:01:21 +02:00 committed by GitHub
parent 17ab45da43
commit 713689491b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 124 additions and 132 deletions

View File

@ -5,6 +5,7 @@ from __future__ import annotations
import contextlib
import logging
from pathlib import Path
from typing import Final
import voluptuous as vol
from xknx import XKNX
@ -59,9 +60,9 @@ from .const import (
CONF_KNX_TUNNELING_TCP,
CONF_KNX_TUNNELING_TCP_SECURE,
DATA_HASS_CONFIG,
DATA_KNX_CONFIG,
DOMAIN,
KNX_ADDRESS,
KNX_MODULE_KEY,
SUPPORTED_PLATFORMS_UI,
SUPPORTED_PLATFORMS_YAML,
TELEGRAM_LOG_DEFAULT,
@ -97,6 +98,7 @@ from .websocket import register_panel
_LOGGER = logging.getLogger(__name__)
_KNX_YAML_CONFIG: Final = "knx_yaml_config"
CONFIG_SCHEMA = vol.Schema(
{
@ -148,7 +150,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Start the KNX integration."""
hass.data[DATA_HASS_CONFIG] = config
if (conf := config.get(DOMAIN)) is not None:
hass.data[DATA_KNX_CONFIG] = dict(conf)
hass.data[_KNX_YAML_CONFIG] = dict(conf)
register_knx_services(hass)
return True
@ -156,16 +158,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Load a config entry."""
# `config` is None when reloading the integration
# or no `knx` key in configuration.yaml
if (config := hass.data.get(DATA_KNX_CONFIG)) is None:
# `_KNX_YAML_CONFIG` is only set in async_setup.
# It's None when reloading the integration or no `knx` key in configuration.yaml
config = hass.data.pop(_KNX_YAML_CONFIG, None)
if config is None:
_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
config = CONFIG_SCHEMA({DOMAIN: {}})[DOMAIN]
else:
@ -176,22 +174,22 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
except XKNXException as ex:
raise ConfigEntryNotReady from ex
hass.data[DATA_KNX_CONFIG] = config
hass.data[DOMAIN] = knx_module
hass.data[KNX_MODULE_KEY] = knx_module
if CONF_KNX_EXPOSE in config:
for expose_config in config[CONF_KNX_EXPOSE]:
knx_module.exposures.append(
create_knx_exposure(hass, knx_module.xknx, expose_config)
)
configured_platforms_yaml = {
platform for platform in SUPPORTED_PLATFORMS_YAML if platform in config
}
await hass.config_entries.async_forward_entry_setups(
entry,
{
Platform.SENSOR, # always forward sensor for system entities (telegram counter, etc.)
*SUPPORTED_PLATFORMS_UI, # forward all platforms that support UI entity management
*{ # forward yaml-only managed platforms on demand
platform for platform in SUPPORTED_PLATFORMS_YAML if platform in config
},
*configured_platforms_yaml, # forward yaml-only managed platforms on demand,
},
)
@ -210,30 +208,30 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unloading the KNX platforms."""
# if not loaded directly return
if not hass.data.get(DOMAIN):
knx_module = hass.data.get(KNX_MODULE_KEY)
if not knx_module:
# if not loaded directly return
return True
knx_module: KNXModule = hass.data[DOMAIN]
for exposure in knx_module.exposures:
exposure.async_remove()
configured_platforms_yaml = {
platform
for platform in SUPPORTED_PLATFORMS_YAML
if platform in knx_module.config_yaml
}
unload_ok = await hass.config_entries.async_unload_platforms(
entry,
{
Platform.SENSOR, # always unload system entities (telegram counter, etc.)
*SUPPORTED_PLATFORMS_UI, # unload all platforms that support UI entity management
*{ # unload yaml-only managed platforms if configured
platform
for platform in SUPPORTED_PLATFORMS_YAML
if platform in hass.data[DATA_KNX_CONFIG]
},
*configured_platforms_yaml, # unload yaml-only managed platforms if configured,
},
)
if unload_ok:
await knx_module.stop()
hass.data.pop(DOMAIN)
hass.data.pop(DATA_KNX_CONFIG)
return unload_ok
@ -267,7 +265,7 @@ async def async_remove_config_entry_device(
hass: HomeAssistant, config_entry: ConfigEntry, device_entry: DeviceEntry
) -> bool:
"""Remove a config entry from a device."""
knx_module: KNXModule = hass.data[DOMAIN]
knx_module = hass.data[KNX_MODULE_KEY]
if not device_entry.identifiers.isdisjoint(
knx_module.interface_device.device_info["identifiers"]
):
@ -287,7 +285,7 @@ class KNXModule:
) -> None:
"""Initialize KNX module."""
self.hass = hass
self.config = config
self.config_yaml = config
self.connected = False
self.exposures: list[KNXExposeSensor | KNXExposeTime] = []
self.service_exposures: dict[str, KNXExposeSensor | KNXExposeTime] = {}
@ -489,7 +487,7 @@ class KNXModule:
def register_event_callback(self) -> TelegramQueue.Callback:
"""Register callback for knx_event within XKNX TelegramQueue."""
address_filters = []
for filter_set in self.config[CONF_EVENT]:
for filter_set in self.config_yaml[CONF_EVENT]:
_filters = list(map(AddressFilter, filter_set[KNX_ADDRESS]))
address_filters.extend(_filters)
if (dpt := filter_set.get(CONF_TYPE)) and (

View File

@ -23,7 +23,7 @@ from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import ConfigType
from . import KNXModule
from .const import ATTR_COUNTER, ATTR_SOURCE, DATA_KNX_CONFIG, DOMAIN
from .const import ATTR_COUNTER, ATTR_SOURCE, KNX_MODULE_KEY
from .knx_entity import KnxYamlEntity
from .schema import BinarySensorSchema
@ -34,12 +34,11 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the KNX binary sensor platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: ConfigType = hass.data[DATA_KNX_CONFIG]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.BINARY_SENSOR]
async_add_entities(
KNXBinarySensor(knx_module, entity_config)
for entity_config in config[Platform.BINARY_SENSOR]
KNXBinarySensor(knx_module, entity_config) for entity_config in config
)

View File

@ -12,7 +12,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType
from . import KNXModule
from .const import CONF_PAYLOAD_LENGTH, DATA_KNX_CONFIG, DOMAIN, KNX_ADDRESS
from .const import CONF_PAYLOAD_LENGTH, KNX_ADDRESS, KNX_MODULE_KEY
from .knx_entity import KnxYamlEntity
@ -22,13 +22,10 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the KNX binary sensor platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: ConfigType = hass.data[DATA_KNX_CONFIG]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.BUTTON]
async_add_entities(
KNXButton(knx_module, entity_config)
for entity_config in config[Platform.BUTTON]
)
async_add_entities(KNXButton(knx_module, entity_config) for entity_config in config)
class KNXButton(KnxYamlEntity, ButtonEntity):

View File

@ -31,7 +31,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType
from . import KNXModule
from .const import CONTROLLER_MODES, CURRENT_HVAC_ACTIONS, DATA_KNX_CONFIG, DOMAIN
from .const import CONTROLLER_MODES, CURRENT_HVAC_ACTIONS, KNX_MODULE_KEY
from .knx_entity import KnxYamlEntity
from .schema import ClimateSchema
@ -45,8 +45,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up climate(s) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.CLIMATE]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.CLIMATE]
async_add_entities(
KNXClimate(knx_module, entity_config) for entity_config in config

View File

@ -58,6 +58,7 @@ from .const import (
CONF_KNX_TUNNELING_TCP_SECURE,
DEFAULT_ROUTING_IA,
DOMAIN,
KNX_MODULE_KEY,
TELEGRAM_LOG_DEFAULT,
TELEGRAM_LOG_MAX,
KNXConfigEntryData,
@ -182,7 +183,9 @@ class KNXCommonFlow(ABC, ConfigEntryBaseFlow):
CONF_KNX_ROUTING: CONF_KNX_ROUTING.capitalize(),
}
if isinstance(self, OptionsFlow) and (knx_module := self.hass.data.get(DOMAIN)):
if isinstance(self, OptionsFlow) and (
knx_module := self.hass.data.get(KNX_MODULE_KEY)
):
xknx = knx_module.xknx
else:
xknx = XKNX()

View File

@ -4,15 +4,20 @@ from __future__ import annotations
from collections.abc import Awaitable, Callable
from enum import Enum
from typing import Final, TypedDict
from typing import TYPE_CHECKING, Final, TypedDict
from xknx.dpt.dpt_20 import HVACControllerMode
from xknx.telegram import Telegram
from homeassistant.components.climate import HVACAction, HVACMode
from homeassistant.const import Platform
from homeassistant.util.hass_dict import HassKey
if TYPE_CHECKING:
from . import KNXModule
DOMAIN: Final = "knx"
KNX_MODULE_KEY: HassKey[KNXModule] = HassKey(DOMAIN)
# Address is used for configuration and services by the same functions so the key has to match
KNX_ADDRESS: Final = "address"
@ -68,8 +73,6 @@ CONF_RESPOND_TO_READ: Final = "respond_to_read"
CONF_STATE_ADDRESS: Final = "state_address"
CONF_SYNC_STATE: Final = "sync_state"
# yaml config merged with config entry data
DATA_KNX_CONFIG: Final = "knx_config"
# original hass yaml config
DATA_HASS_CONFIG: Final = "knx_hass_config"

View File

@ -26,7 +26,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType
from . import KNXModule
from .const import DATA_KNX_CONFIG, DOMAIN
from .const import KNX_MODULE_KEY
from .knx_entity import KnxYamlEntity
from .schema import CoverSchema
@ -37,8 +37,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up cover(s) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.COVER]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.COVER]
async_add_entities(KNXCover(knx_module, entity_config) for entity_config in config)

View File

@ -27,9 +27,8 @@ from .const import (
CONF_RESPOND_TO_READ,
CONF_STATE_ADDRESS,
CONF_SYNC_STATE,
DATA_KNX_CONFIG,
DOMAIN,
KNX_ADDRESS,
KNX_MODULE_KEY,
)
from .knx_entity import KnxYamlEntity
@ -40,8 +39,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up entities for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.DATE]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.DATE]
async_add_entities(
KNXDateEntity(knx_module, entity_config) for entity_config in config

View File

@ -28,9 +28,8 @@ from .const import (
CONF_RESPOND_TO_READ,
CONF_STATE_ADDRESS,
CONF_SYNC_STATE,
DATA_KNX_CONFIG,
DOMAIN,
KNX_ADDRESS,
KNX_MODULE_KEY,
)
from .knx_entity import KnxYamlEntity
@ -41,8 +40,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up entities for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.DATETIME]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.DATETIME]
async_add_entities(
KNXDateTimeEntity(knx_module, entity_config) for entity_config in config

View File

@ -16,9 +16,8 @@ from homeassistant.helpers import selector
from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo
from homeassistant.helpers.typing import ConfigType
from . import KNXModule, trigger
from .const import DOMAIN
from .project import KNXProject
from . import trigger
from .const import DOMAIN, KNX_MODULE_KEY
from .trigger import (
CONF_KNX_DESTINATION,
CONF_KNX_GROUP_VALUE_READ,
@ -47,7 +46,7 @@ async def async_get_triggers(
"""List device triggers for KNX devices."""
triggers = []
knx: KNXModule = hass.data[DOMAIN]
knx = hass.data[KNX_MODULE_KEY]
if knx.interface_device.device.id == device_id:
# Add trigger for KNX telegrams to interface device
triggers.append(
@ -67,7 +66,7 @@ async def async_get_trigger_capabilities(
hass: HomeAssistant, config: ConfigType
) -> dict[str, vol.Schema]:
"""List trigger capabilities."""
project: KNXProject = hass.data[DOMAIN].project
project = hass.data[KNX_MODULE_KEY].project
options = [
selector.SelectOptionDict(value=ga.address, label=f"{ga.address} - {ga.name}")
for ga in project.group_addresses.values()

View File

@ -18,6 +18,7 @@ from .const import (
CONF_KNX_SECURE_DEVICE_AUTHENTICATION,
CONF_KNX_SECURE_USER_PASSWORD,
DOMAIN,
KNX_MODULE_KEY,
)
TO_REDACT = {
@ -33,7 +34,7 @@ async def async_get_config_entry_diagnostics(
) -> dict[str, Any]:
"""Return diagnostics for a config entry."""
diag: dict[str, Any] = {}
knx_module = hass.data[DOMAIN]
knx_module = hass.data[KNX_MODULE_KEY]
diag["xknx"] = {
"version": knx_module.xknx.version,
"current_address": str(knx_module.xknx.current_address),

View File

@ -20,7 +20,7 @@ from homeassistant.util.percentage import (
from homeassistant.util.scaling import int_states_in_range
from . import KNXModule
from .const import DATA_KNX_CONFIG, DOMAIN, KNX_ADDRESS
from .const import KNX_ADDRESS, KNX_MODULE_KEY
from .knx_entity import KnxYamlEntity
from .schema import FanSchema
@ -33,8 +33,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up fan(s) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.FAN]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.FAN]
async_add_entities(KNXFan(knx_module, entity_config) for entity_config in config)

View File

@ -29,7 +29,7 @@ from homeassistant.helpers.typing import ConfigType
import homeassistant.util.color as color_util
from . import KNXModule
from .const import CONF_SYNC_STATE, DATA_KNX_CONFIG, DOMAIN, KNX_ADDRESS, ColorTempModes
from .const import CONF_SYNC_STATE, DOMAIN, KNX_ADDRESS, KNX_MODULE_KEY, ColorTempModes
from .knx_entity import KnxUiEntity, KnxUiEntityPlatformController, KnxYamlEntity
from .schema import LightSchema
from .storage.const import (
@ -65,7 +65,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up light(s) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
knx_module = hass.data[KNX_MODULE_KEY]
platform = async_get_current_platform()
knx_module.config_store.add_platform(
platform=Platform.LIGHT,
@ -77,7 +77,7 @@ async def async_setup_entry(
)
entities: list[KnxYamlEntity | KnxUiEntity] = []
if yaml_platform_config := hass.data[DATA_KNX_CONFIG].get(Platform.LIGHT):
if yaml_platform_config := knx_module.config_yaml.get(Platform.LIGHT):
entities.extend(
KnxYamlLight(knx_module, entity_config)
for entity_config in yaml_platform_config

View File

@ -19,7 +19,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import KNXModule
from .const import DATA_KNX_CONFIG, DOMAIN, KNX_ADDRESS
from .const import DOMAIN, KNX_ADDRESS, KNX_MODULE_KEY
from .knx_entity import KnxYamlEntity
@ -32,8 +32,9 @@ async def async_get_service(
if discovery_info is None:
return None
if platform_config := hass.data[DATA_KNX_CONFIG].get(Platform.NOTIFY):
xknx: XKNX = hass.data[DOMAIN].xknx
knx_module = hass.data[KNX_MODULE_KEY]
if platform_config := knx_module.config_yaml.get(Platform.NOTIFY):
xknx: XKNX = hass.data[KNX_MODULE_KEY].xknx
notification_devices = [
_create_notification_instance(xknx, device_config)
@ -87,8 +88,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up notify(s) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.NOTIFY]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.NOTIFY]
async_add_entities(KNXNotify(knx_module, entity_config) for entity_config in config)

View File

@ -23,13 +23,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType
from . import KNXModule
from .const import (
CONF_RESPOND_TO_READ,
CONF_STATE_ADDRESS,
DATA_KNX_CONFIG,
DOMAIN,
KNX_ADDRESS,
)
from .const import CONF_RESPOND_TO_READ, CONF_STATE_ADDRESS, KNX_ADDRESS, KNX_MODULE_KEY
from .knx_entity import KnxYamlEntity
from .schema import NumberSchema
@ -40,8 +34,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up number(s) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.NUMBER]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.NUMBER]
async_add_entities(KNXNumber(knx_module, entity_config) for entity_config in config)

View File

@ -14,7 +14,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType
from . import KNXModule
from .const import DATA_KNX_CONFIG, DOMAIN, KNX_ADDRESS
from .const import KNX_ADDRESS, KNX_MODULE_KEY
from .knx_entity import KnxYamlEntity
from .schema import SceneSchema
@ -25,8 +25,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up scene(s) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.SCENE]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.SCENE]
async_add_entities(KNXScene(knx_module, entity_config) for entity_config in config)

View File

@ -26,9 +26,8 @@ from .const import (
CONF_RESPOND_TO_READ,
CONF_STATE_ADDRESS,
CONF_SYNC_STATE,
DATA_KNX_CONFIG,
DOMAIN,
KNX_ADDRESS,
KNX_MODULE_KEY,
)
from .knx_entity import KnxYamlEntity
from .schema import SelectSchema
@ -40,8 +39,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up select(s) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.SELECT]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.SELECT]
async_add_entities(KNXSelect(knx_module, entity_config) for entity_config in config)

View File

@ -34,7 +34,7 @@ from homeassistant.helpers.typing import ConfigType, StateType
from homeassistant.util.enum import try_parse_enum
from . import KNXModule
from .const import ATTR_SOURCE, DATA_KNX_CONFIG, DOMAIN
from .const import ATTR_SOURCE, KNX_MODULE_KEY
from .knx_entity import KnxYamlEntity
from .schema import SensorSchema
@ -115,13 +115,13 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up sensor(s) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
knx_module = hass.data[KNX_MODULE_KEY]
entities: list[SensorEntity] = []
entities.extend(
KNXSystemSensor(knx_module, description)
for description in SYSTEM_ENTITY_DESCRIPTIONS
)
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG].get(Platform.SENSOR)
config: list[ConfigType] | None = knx_module.config_yaml.get(Platform.SENSOR)
if config:
entities.extend(
KNXSensor(knx_module, entity_config) for entity_config in config

View File

@ -22,6 +22,7 @@ from homeassistant.helpers.service import async_register_admin_service
from .const import (
DOMAIN,
KNX_ADDRESS,
KNX_MODULE_KEY,
SERVICE_KNX_ATTR_PAYLOAD,
SERVICE_KNX_ATTR_REMOVE,
SERVICE_KNX_ATTR_RESPONSE,
@ -85,7 +86,7 @@ def register_knx_services(hass: HomeAssistant) -> None:
def get_knx_module(hass: HomeAssistant) -> KNXModule:
"""Return KNXModule instance."""
try:
return hass.data[DOMAIN] # type: ignore[no-any-return]
return hass.data[KNX_MODULE_KEY]
except KeyError as err:
raise HomeAssistantError("KNX entry not loaded") from err

View File

@ -31,9 +31,9 @@ from .const import (
CONF_INVERT,
CONF_RESPOND_TO_READ,
CONF_SYNC_STATE,
DATA_KNX_CONFIG,
DOMAIN,
KNX_ADDRESS,
KNX_MODULE_KEY,
)
from .knx_entity import KnxUiEntity, KnxUiEntityPlatformController, KnxYamlEntity
from .schema import SwitchSchema
@ -53,7 +53,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up switch(es) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
knx_module = hass.data[KNX_MODULE_KEY]
platform = async_get_current_platform()
knx_module.config_store.add_platform(
platform=Platform.SWITCH,
@ -65,7 +65,7 @@ async def async_setup_entry(
)
entities: list[KnxYamlEntity | KnxUiEntity] = []
if yaml_platform_config := hass.data[DATA_KNX_CONFIG].get(Platform.SWITCH):
if yaml_platform_config := knx_module.config_yaml.get(Platform.SWITCH):
entities.extend(
KnxYamlSwitch(knx_module, entity_config)
for entity_config in yaml_platform_config

View File

@ -23,13 +23,7 @@ from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import ConfigType
from . import KNXModule
from .const import (
CONF_RESPOND_TO_READ,
CONF_STATE_ADDRESS,
DATA_KNX_CONFIG,
DOMAIN,
KNX_ADDRESS,
)
from .const import CONF_RESPOND_TO_READ, CONF_STATE_ADDRESS, KNX_ADDRESS, KNX_MODULE_KEY
from .knx_entity import KnxYamlEntity
@ -39,8 +33,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up sensor(s) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.TEXT]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.TEXT]
async_add_entities(KNXText(knx_module, entity_config) for entity_config in config)

View File

@ -27,9 +27,8 @@ from .const import (
CONF_RESPOND_TO_READ,
CONF_STATE_ADDRESS,
CONF_SYNC_STATE,
DATA_KNX_CONFIG,
DOMAIN,
KNX_ADDRESS,
KNX_MODULE_KEY,
)
from .knx_entity import KnxYamlEntity
@ -40,8 +39,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up entities for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.TIME]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.TIME]
async_add_entities(
KNXTimeEntity(knx_module, entity_config) for entity_config in config

View File

@ -20,7 +20,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType
from . import KNXModule
from .const import DATA_KNX_CONFIG, DOMAIN
from .const import KNX_MODULE_KEY
from .knx_entity import KnxYamlEntity
from .schema import WeatherSchema
@ -31,8 +31,8 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up switch(es) for KNX platform."""
knx_module: KNXModule = hass.data[DOMAIN]
config: list[ConfigType] = hass.data[DATA_KNX_CONFIG][Platform.WEATHER]
knx_module = hass.data[KNX_MODULE_KEY]
config: list[ConfigType] = knx_module.config_yaml[Platform.WEATHER]
async_add_entities(
KNXWeather(knx_module, entity_config) for entity_config in config

View File

@ -21,7 +21,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.typing import UNDEFINED
from homeassistant.util.ulid import ulid_now
from .const import DOMAIN
from .const import DOMAIN, KNX_MODULE_KEY
from .storage.config_store import ConfigStoreException
from .storage.const import CONF_DATA
from .storage.entity_store_schema import (
@ -38,7 +38,6 @@ from .telegrams import SIGNAL_KNX_TELEGRAM, TelegramDict
if TYPE_CHECKING:
from . import KNXModule
URL_BASE: Final = "/knx_static"
@ -126,7 +125,7 @@ def provide_knx(
) -> None:
"""Add KNX Module to call function."""
try:
knx: KNXModule = hass.data[DOMAIN]
knx = hass.data[KNX_MODULE_KEY]
except KeyError:
_send_not_loaded_error(connection, msg["id"])
return
@ -142,7 +141,7 @@ def provide_knx(
) -> None:
"""Add KNX Module to call function."""
try:
knx: KNXModule = hass.data[DOMAIN]
knx = hass.data[KNX_MODULE_KEY]
except KeyError:
_send_not_loaded_error(connection, msg["id"])
return

View File

@ -6,7 +6,11 @@ import logging
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.knx.const import CONF_PAYLOAD_LENGTH, DOMAIN, KNX_ADDRESS
from homeassistant.components.knx.const import (
CONF_PAYLOAD_LENGTH,
KNX_ADDRESS,
KNX_MODULE_KEY,
)
from homeassistant.components.knx.schema import ButtonSchema
from homeassistant.const import CONF_NAME, CONF_PAYLOAD, CONF_TYPE
from homeassistant.core import HomeAssistant
@ -134,4 +138,4 @@ async def test_button_invalid(
assert record.levelname == "ERROR"
assert "Setup failed for 'knx': Invalid config." in record.message
assert hass.states.get("button.test") is None
assert hass.data.get(DOMAIN) is None
assert hass.data.get(KNX_MODULE_KEY) is None

View File

@ -6,8 +6,10 @@ from typing import Any
import pytest
from homeassistant.components.knx import DOMAIN
from homeassistant.components.knx.const import CONF_KNX_TELEGRAM_LOG_SIZE
from homeassistant.components.knx.const import (
CONF_KNX_TELEGRAM_LOG_SIZE,
KNX_MODULE_KEY,
)
from homeassistant.components.knx.telegrams import TelegramDict
from homeassistant.core import HomeAssistant
@ -76,7 +78,7 @@ async def test_store_telegam_history(
)
await knx.assert_write("2/2/2", (1, 2, 3, 4))
assert len(hass.data[DOMAIN].telegrams.recent_telegrams) == 2
assert len(hass.data[KNX_MODULE_KEY].telegrams.recent_telegrams) == 2
with pytest.raises(KeyError):
hass_storage["knx/telegrams_history.json"]
@ -93,7 +95,7 @@ async def test_load_telegam_history(
"""Test telegram history restoration."""
hass_storage["knx/telegrams_history.json"] = {"version": 1, "data": MOCK_TELEGRAMS}
await knx.setup_integration({})
loaded_telegrams = hass.data[DOMAIN].telegrams.recent_telegrams
loaded_telegrams = hass.data[KNX_MODULE_KEY].telegrams.recent_telegrams
assert assert_telegram_history(loaded_telegrams)
# TelegramDict "payload" is a tuple, this shall be restored when loading from JSON
assert isinstance(loaded_telegrams[1]["payload"], tuple)
@ -114,4 +116,4 @@ async def test_remove_telegam_history(
await knx.setup_integration({}, add_entry_to_hass=False)
# Store.async_remove() is mocked by hass_storage - check that data was removed.
assert "knx/telegrams_history.json" not in hass_storage
assert not hass.data[DOMAIN].telegrams.recent_telegrams
assert not hass.data[KNX_MODULE_KEY].telegrams.recent_telegrams

View File

@ -5,8 +5,9 @@ from unittest.mock import patch
import pytest
from homeassistant.components.knx import DOMAIN, KNX_ADDRESS, SwitchSchema
from homeassistant.components.knx.const import KNX_ADDRESS, KNX_MODULE_KEY
from homeassistant.components.knx.project import STORAGE_KEY as KNX_PROJECT_STORAGE_KEY
from homeassistant.components.knx.schema import SwitchSchema
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant
@ -66,7 +67,7 @@ async def test_knx_project_file_process(
await knx.setup_integration({})
client = await hass_ws_client(hass)
assert not hass.data[DOMAIN].project.loaded
assert not hass.data[KNX_MODULE_KEY].project.loaded
await client.send_json(
{
@ -89,7 +90,7 @@ async def test_knx_project_file_process(
parse_mock.assert_called_once_with()
assert res["success"], res
assert hass.data[DOMAIN].project.loaded
assert hass.data[KNX_MODULE_KEY].project.loaded
assert hass_storage[KNX_PROJECT_STORAGE_KEY]["data"] == _parse_result
@ -101,7 +102,7 @@ async def test_knx_project_file_process_error(
"""Test knx/project_file_process exception handling."""
await knx.setup_integration({})
client = await hass_ws_client(hass)
assert not hass.data[DOMAIN].project.loaded
assert not hass.data[KNX_MODULE_KEY].project.loaded
await client.send_json(
{
@ -122,7 +123,7 @@ async def test_knx_project_file_process_error(
parse_mock.assert_called_once_with()
assert res["error"], res
assert not hass.data[DOMAIN].project.loaded
assert not hass.data[KNX_MODULE_KEY].project.loaded
async def test_knx_project_file_remove(
@ -136,13 +137,13 @@ async def test_knx_project_file_remove(
await knx.setup_integration({})
assert hass_storage[KNX_PROJECT_STORAGE_KEY]
client = await hass_ws_client(hass)
assert hass.data[DOMAIN].project.loaded
assert hass.data[KNX_MODULE_KEY].project.loaded
await client.send_json({"id": 6, "type": "knx/project_file_remove"})
res = await client.receive_json()
assert res["success"], res
assert not hass.data[DOMAIN].project.loaded
assert not hass.data[KNX_MODULE_KEY].project.loaded
assert not hass_storage.get(KNX_PROJECT_STORAGE_KEY)
@ -155,7 +156,7 @@ async def test_knx_get_project(
"""Test retrieval of kxnproject from store."""
await knx.setup_integration({})
client = await hass_ws_client(hass)
assert hass.data[DOMAIN].project.loaded
assert hass.data[KNX_MODULE_KEY].project.loaded
await client.send_json({"id": 3, "type": "knx/get_knx_project"})
res = await client.receive_json()