diff --git a/homeassistant/components/knx/storage/config_store.py b/homeassistant/components/knx/storage/config_store.py index 9f1ef6c454664e..7ea61e1dd3e63b 100644 --- a/homeassistant/components/knx/storage/config_store.py +++ b/homeassistant/components/knx/storage/config_store.py @@ -5,13 +5,14 @@ from typing import TYPE_CHECKING, Any, Final, TypedDict from homeassistant.config_entries import ConfigEntry -from homeassistant.const import Platform +from homeassistant.const import CONF_PLATFORM, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.storage import Store from homeassistant.util.ulid import ulid_now from ..const import DOMAIN +from .const import CONF_DATA if TYPE_CHECKING: from ..knx_entity import KnxEntity @@ -84,8 +85,8 @@ def get_entity_config(self, entity_id: str) -> dict[str, Any]: raise ConfigStoreException(f"Entity not found: {entity_id}") try: return { - "platform": entry.domain, - "data": self.data["entities"][entry.domain][entry.unique_id], + CONF_PLATFORM: entry.domain, + CONF_DATA: self.data["entities"][entry.domain][entry.unique_id], } except KeyError as err: raise ConfigStoreException(f"Entity data not found: {entity_id}") from err diff --git a/homeassistant/components/knx/storage/const.py b/homeassistant/components/knx/storage/const.py new file mode 100644 index 00000000000000..6453b77ed3b937 --- /dev/null +++ b/homeassistant/components/knx/storage/const.py @@ -0,0 +1,14 @@ +"""Constants used in KNX config store.""" + +from typing import Final + +CONF_DATA: Final = "data" +CONF_ENTITY: Final = "entity" +CONF_DEVICE_INFO: Final = "device_info" +CONF_GA_WRITE: Final = "write" +CONF_GA_STATE: Final = "state" +CONF_GA_PASSIVE: Final = "passive" +CONF_DPT: Final = "dpt" + + +CONF_GA_SWITCH: Final = "ga_switch" diff --git a/homeassistant/components/knx/storage/entity_store_schema.py b/homeassistant/components/knx/storage/entity_store_schema.py index 0d8ad4f088f954..b25fa89f934c70 100644 --- a/homeassistant/components/knx/storage/entity_store_schema.py +++ b/homeassistant/components/knx/storage/entity_store_schema.py @@ -2,32 +2,45 @@ import voluptuous as vol -from homeassistant.const import Platform +from homeassistant.const import ( + CONF_ENTITY_CATEGORY, + CONF_ENTITY_ID, + CONF_NAME, + CONF_PLATFORM, + Platform, +) from homeassistant.helpers import config_validation as cv from homeassistant.helpers.entity import ENTITY_CATEGORIES_SCHEMA -from ..const import SUPPORTED_PLATFORMS_UI +from ..const import ( + CONF_INVERT, + CONF_RESPOND_TO_READ, + CONF_SYNC_STATE, + DOMAIN, + SUPPORTED_PLATFORMS_UI, +) from ..validation import sync_state_validator +from .const import CONF_DATA, CONF_DEVICE_INFO, CONF_ENTITY, CONF_GA_SWITCH from .knx_selector import GASelector BASE_ENTITY_SCHEMA = vol.All( { - vol.Optional("name", default=None): vol.Maybe(str), - vol.Optional("device_info", default=None): vol.Maybe(str), - vol.Optional("entity_category", default=None): vol.Any( + vol.Optional(CONF_NAME, default=None): vol.Maybe(str), + vol.Optional(CONF_DEVICE_INFO, default=None): vol.Maybe(str), + vol.Optional(CONF_ENTITY_CATEGORY, default=None): vol.Any( ENTITY_CATEGORIES_SCHEMA, vol.SetTo(None) ), }, vol.Any( vol.Schema( { - vol.Required("name"): vol.All(str, vol.IsTrue()), + vol.Required(CONF_NAME): vol.All(str, vol.IsTrue()), }, extra=vol.ALLOW_EXTRA, ), vol.Schema( { - vol.Required("device_info"): str, + vol.Required(CONF_DEVICE_INFO): str, }, extra=vol.ALLOW_EXTRA, ), @@ -35,15 +48,14 @@ ), ) - SWITCH_SCHEMA = vol.Schema( { - vol.Required("entity"): BASE_ENTITY_SCHEMA, - vol.Required("knx"): { - vol.Optional("invert", default=False): bool, - vol.Required("ga_switch"): GASelector(write_required=True), - vol.Optional("respond_to_read", default=False): bool, - vol.Optional("sync_state", default=True): sync_state_validator, + vol.Required(CONF_ENTITY): BASE_ENTITY_SCHEMA, + vol.Required(DOMAIN): { + vol.Optional(CONF_INVERT, default=False): bool, + vol.Required(CONF_GA_SWITCH): GASelector(write_required=True), + vol.Optional(CONF_RESPOND_TO_READ, default=False): bool, + vol.Optional(CONF_SYNC_STATE, default=True): sync_state_validator, }, } ) @@ -52,30 +64,30 @@ ENTITY_STORE_DATA_SCHEMA = vol.All( vol.Schema( { - vol.Required("platform"): vol.All( + vol.Required(CONF_PLATFORM): vol.All( vol.Coerce(Platform), vol.In(SUPPORTED_PLATFORMS_UI), ), - vol.Required("data"): dict, + vol.Required(CONF_DATA): dict, }, extra=vol.ALLOW_EXTRA, ), cv.key_value_schemas( - "platform", + CONF_PLATFORM, { Platform.SWITCH: vol.Schema( - {vol.Required("data"): SWITCH_SCHEMA}, extra=vol.ALLOW_EXTRA + {vol.Required(CONF_DATA): SWITCH_SCHEMA}, extra=vol.ALLOW_EXTRA ), }, ), ) CREATE_ENTITY_BASE_SCHEMA = { - vol.Required("platform"): str, - vol.Required("data"): dict, # validated by ENTITY_STORE_DATA_SCHEMA for platform + vol.Required(CONF_PLATFORM): str, + vol.Required(CONF_DATA): dict, # validated by ENTITY_STORE_DATA_SCHEMA for platform } UPDATE_ENTITY_BASE_SCHEMA = { - vol.Required("entity_id"): str, + vol.Required(CONF_ENTITY_ID): str, **CREATE_ENTITY_BASE_SCHEMA, } diff --git a/homeassistant/components/knx/storage/knx_selector.py b/homeassistant/components/knx/storage/knx_selector.py index 4c59825ade9863..396cde67fbdce3 100644 --- a/homeassistant/components/knx/storage/knx_selector.py +++ b/homeassistant/components/knx/storage/knx_selector.py @@ -6,6 +6,7 @@ import voluptuous as vol from ..validation import ga_validator, maybe_ga_validator +from .const import CONF_DPT, CONF_GA_PASSIVE, CONF_GA_STATE, CONF_GA_WRITE class GASelector: @@ -57,24 +58,24 @@ def add_ga_item(key: str, allowed: bool, required: bool) -> None: else: schema[vol.Optional(key, default=None)] = maybe_ga_validator - add_ga_item("write", self.write, self.write_required) - add_ga_item("state", self.state, self.state_required) + add_ga_item(CONF_GA_WRITE, self.write, self.write_required) + add_ga_item(CONF_GA_STATE, self.state, self.state_required) def _add_passive(self, schema: dict[vol.Marker, Any]) -> None: """Add passive group addresses validator to the schema.""" if self.passive: - schema[vol.Optional("passive", default=list)] = vol.Any( + schema[vol.Optional(CONF_GA_PASSIVE, default=list)] = vol.Any( [ga_validator], vol.All( # Coerce `None` to an empty list if passive is allowed vol.IsFalse(), vol.SetTo(list) ), ) else: - schema[vol.Remove("passive")] = object + schema[vol.Remove(CONF_GA_PASSIVE)] = object def _add_dpt(self, schema: dict[vol.Marker, Any]) -> None: """Add DPT validator to the schema.""" if self.dpt is not None: - schema[vol.Required("dpt")] = vol.In([item.value for item in self.dpt]) + schema[vol.Required(CONF_DPT)] = vol.In([item.value for item in self.dpt]) else: - schema[vol.Remove("dpt")] = object + schema[vol.Remove(CONF_DPT)] = object diff --git a/homeassistant/components/knx/switch.py b/homeassistant/components/knx/switch.py index c09293c25369ff..94f5592db9092c 100644 --- a/homeassistant/components/knx/switch.py +++ b/homeassistant/components/knx/switch.py @@ -25,9 +25,23 @@ from homeassistant.helpers.typing import ConfigType from . import KNXModule -from .const import CONF_RESPOND_TO_READ, DATA_KNX_CONFIG, DOMAIN, KNX_ADDRESS +from .const import ( + CONF_INVERT, + CONF_RESPOND_TO_READ, + DATA_KNX_CONFIG, + DOMAIN, + KNX_ADDRESS, +) from .knx_entity import KnxEntity from .schema import SwitchSchema +from .storage.const import ( + CONF_DEVICE_INFO, + CONF_ENTITY, + CONF_GA_PASSIVE, + CONF_GA_STATE, + CONF_GA_SWITCH, + CONF_GA_WRITE, +) async def async_setup_entry( @@ -120,19 +134,19 @@ def __init__( super().__init__( device=XknxSwitch( knx_module.xknx, - name=config["entity"][CONF_NAME], - group_address=config["knx"]["ga_switch"]["write"], + name=config[CONF_ENTITY][CONF_NAME], + group_address=config[DOMAIN][CONF_GA_SWITCH][CONF_GA_WRITE], group_address_state=[ - config["knx"]["ga_switch"]["state"], - *config["knx"]["ga_switch"]["passive"], + config[DOMAIN][CONF_GA_SWITCH][CONF_GA_STATE], + *config[DOMAIN][CONF_GA_SWITCH][CONF_GA_PASSIVE], ], - respond_to_read=config["knx"][CONF_RESPOND_TO_READ], - invert=config["knx"]["invert"], + respond_to_read=config[DOMAIN][CONF_RESPOND_TO_READ], + invert=config[DOMAIN][CONF_INVERT], ) ) - self._attr_entity_category = config["entity"][CONF_ENTITY_CATEGORY] + self._attr_entity_category = config[CONF_ENTITY][CONF_ENTITY_CATEGORY] self._attr_unique_id = unique_id - if device_info := config["entity"].get("device_info"): + if device_info := config[CONF_ENTITY].get(CONF_DEVICE_INFO): self._attr_device_info = DeviceInfo(identifiers={(DOMAIN, device_info)}) knx_module.config_store.entities[unique_id] = self diff --git a/homeassistant/components/knx/websocket.py b/homeassistant/components/knx/websocket.py index 81f7f351a2300e..3f2fe74c705c83 100644 --- a/homeassistant/components/knx/websocket.py +++ b/homeassistant/components/knx/websocket.py @@ -10,6 +10,7 @@ from homeassistant.components import panel_custom, websocket_api from homeassistant.components.http import StaticPathConfig +from homeassistant.const import CONF_ENTITY_ID, CONF_PLATFORM from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.typing import UNDEFINED @@ -17,6 +18,7 @@ from .const import DOMAIN from .storage.config_store import ConfigStoreException +from .storage.const import CONF_DATA from .storage.entity_store_schema import ( CREATE_ENTITY_BASE_SCHEMA, UPDATE_ENTITY_BASE_SCHEMA, @@ -282,8 +284,8 @@ async def ws_create_entity( try: entity_id = await knx.config_store.create_entity( # use validation result so defaults are applied - validated_data["platform"], - validated_data["data"], + validated_data[CONF_PLATFORM], + validated_data[CONF_DATA], ) except ConfigStoreException as err: connection.send_error( @@ -317,9 +319,9 @@ async def ws_update_entity( knx: KNXModule = hass.data[DOMAIN] try: await knx.config_store.update_entity( - validated_data["platform"], - validated_data["entity_id"], - validated_data["data"], + validated_data[CONF_PLATFORM], + validated_data[CONF_ENTITY_ID], + validated_data[CONF_DATA], ) except ConfigStoreException as err: connection.send_error( @@ -335,7 +337,7 @@ async def ws_update_entity( @websocket_api.websocket_command( { vol.Required("type"): "knx/delete_entity", - vol.Required("entity_id"): str, + vol.Required(CONF_ENTITY_ID): str, } ) @websocket_api.async_response @@ -347,7 +349,7 @@ async def ws_delete_entity( """Delete entity from entity store and remove it.""" knx: KNXModule = hass.data[DOMAIN] try: - await knx.config_store.delete_entity(msg["entity_id"]) + await knx.config_store.delete_entity(msg[CONF_ENTITY_ID]) except ConfigStoreException as err: connection.send_error( msg["id"], websocket_api.const.ERR_HOME_ASSISTANT_ERROR, str(err) @@ -380,7 +382,7 @@ def ws_get_entity_entries( @websocket_api.websocket_command( { vol.Required("type"): "knx/get_entity_config", - vol.Required("entity_id"): str, + vol.Required(CONF_ENTITY_ID): str, } ) @callback @@ -392,7 +394,7 @@ def ws_get_entity_config( """Get entity configuration from entity store.""" knx: KNXModule = hass.data[DOMAIN] try: - config_info = knx.config_store.get_entity_config(msg["entity_id"]) + config_info = knx.config_store.get_entity_config(msg[CONF_ENTITY_ID]) except ConfigStoreException as err: connection.send_error( msg["id"], websocket_api.const.ERR_HOME_ASSISTANT_ERROR, str(err)