Skip to content

Commit

Permalink
use constants instead of strings in schema
Browse files Browse the repository at this point in the history
  • Loading branch information
farmio committed Jul 19, 2024
1 parent 48fe094 commit d0fc065
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 48 deletions.
7 changes: 4 additions & 3 deletions homeassistant/components/knx/storage/config_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions homeassistant/components/knx/storage/const.py
Original file line number Diff line number Diff line change
@@ -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"
54 changes: 33 additions & 21 deletions homeassistant/components/knx/storage/entity_store_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,60 @@

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,
),
msg="One of `Device` or `Name` is required",
),
)


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,
},
}
)
Expand All @@ -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,
}
13 changes: 7 additions & 6 deletions homeassistant/components/knx/storage/knx_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
32 changes: 23 additions & 9 deletions homeassistant/components/knx/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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
20 changes: 11 additions & 9 deletions homeassistant/components/knx/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@

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
from homeassistant.util.ulid import ulid_now

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,
Expand Down Expand Up @@ -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(

Check warning on line 291 in homeassistant/components/knx/websocket.py

View check run for this annotation

Codecov / codecov/patch

homeassistant/components/knx/websocket.py#L290-L291

Added lines #L290 - L291 were not covered by tests
Expand Down Expand Up @@ -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(
Expand All @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down

0 comments on commit d0fc065

Please sign in to comment.