From 4c7e1fe0609a0c676bb4adacf0c1b3f19566904b Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Fri, 1 Apr 2022 18:40:43 +0200 Subject: [PATCH] Cleanup ENTITY_CATEGORIES_SCHEMA (#66549) Co-authored-by: Paulus Schoutsen Co-authored-by: epenet --- homeassistant/components/knx/schema.py | 26 +++++++++---------- .../components/mobile_app/webhook.py | 4 +-- homeassistant/components/mqtt/mixins.py | 4 +-- homeassistant/helpers/entity.py | 15 +++-------- tests/helpers/test_entity.py | 5 +++- 5 files changed, 25 insertions(+), 29 deletions(-) diff --git a/homeassistant/components/knx/schema.py b/homeassistant/components/knx/schema.py index 555fcfc575b..5c5b05db62d 100644 --- a/homeassistant/components/knx/schema.py +++ b/homeassistant/components/knx/schema.py @@ -31,7 +31,7 @@ from homeassistant.const import ( Platform, ) import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.entity import validate_entity_category +from homeassistant.helpers.entity import ENTITY_CATEGORIES_SCHEMA from .const import ( CONF_INVERT, @@ -262,7 +262,7 @@ class BinarySensorSchema(KNXPlatformSchema): ), vol.Optional(CONF_DEVICE_CLASS): BINARY_SENSOR_DEVICE_CLASSES_SCHEMA, vol.Optional(CONF_RESET_AFTER): cv.positive_float, - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ), ) @@ -298,7 +298,7 @@ class ButtonSchema(KNXPlatformSchema): vol.Exclusive( CONF_TYPE, "length_or_type", msg=length_or_type_msg ): object, - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ), vol.Any( @@ -442,7 +442,7 @@ class ClimateSchema(KNXPlatformSchema): ): vol.In(HVAC_MODES), vol.Optional(CONF_MIN_TEMP): vol.Coerce(float), vol.Optional(CONF_MAX_TEMP): vol.Coerce(float), - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ), ) @@ -497,7 +497,7 @@ class CoverSchema(KNXPlatformSchema): vol.Optional(CONF_INVERT_POSITION, default=False): cv.boolean, vol.Optional(CONF_INVERT_ANGLE, default=False): cv.boolean, vol.Optional(CONF_DEVICE_CLASS): COVER_DEVICE_CLASSES_SCHEMA, - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ), ) @@ -560,7 +560,7 @@ class FanSchema(KNXPlatformSchema): vol.Optional(CONF_OSCILLATION_ADDRESS): ga_list_validator, vol.Optional(CONF_OSCILLATION_STATE_ADDRESS): ga_list_validator, vol.Optional(CONF_MAX_STEP): cv.byte, - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ) @@ -664,7 +664,7 @@ class LightSchema(KNXPlatformSchema): vol.Optional(CONF_MAX_KELVIN, default=DEFAULT_MAX_KELVIN): vol.All( vol.Coerce(int), vol.Range(min=1) ), - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ), vol.Any( @@ -744,7 +744,7 @@ class NumberSchema(KNXPlatformSchema): vol.Optional(CONF_MAX): vol.Coerce(float), vol.Optional(CONF_MIN): vol.Coerce(float), vol.Optional(CONF_STEP): cv.positive_float, - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ), number_limit_sub_validator, @@ -766,7 +766,7 @@ class SceneSchema(KNXPlatformSchema): vol.Required(CONF_SCENE_NUMBER): vol.All( vol.Coerce(int), vol.Range(min=1, max=64) ), - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ) @@ -797,7 +797,7 @@ class SelectSchema(KNXPlatformSchema): ], vol.Required(KNX_ADDRESS): ga_list_validator, vol.Optional(CONF_STATE_ADDRESS): ga_list_validator, - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ), select_options_sub_validator, @@ -822,7 +822,7 @@ class SensorSchema(KNXPlatformSchema): vol.Optional(CONF_STATE_CLASS): STATE_CLASSES_SCHEMA, vol.Required(CONF_TYPE): sensor_type_validator, vol.Required(CONF_STATE_ADDRESS): ga_list_validator, - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ) @@ -843,7 +843,7 @@ class SwitchSchema(KNXPlatformSchema): vol.Optional(CONF_RESPOND_TO_READ, default=False): cv.boolean, vol.Required(KNX_ADDRESS): ga_list_validator, vol.Optional(CONF_STATE_ADDRESS): ga_list_validator, - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ) @@ -890,7 +890,7 @@ class WeatherSchema(KNXPlatformSchema): vol.Optional(CONF_KNX_DAY_NIGHT_ADDRESS): ga_list_validator, vol.Optional(CONF_KNX_AIR_PRESSURE_ADDRESS): ga_list_validator, vol.Optional(CONF_KNX_HUMIDITY_ADDRESS): ga_list_validator, - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, } ), ) diff --git a/homeassistant/components/mobile_app/webhook.py b/homeassistant/components/mobile_app/webhook.py index 860b8ef7b53..eb93aba59cb 100644 --- a/homeassistant/components/mobile_app/webhook.py +++ b/homeassistant/components/mobile_app/webhook.py @@ -45,7 +45,7 @@ from homeassistant.helpers import ( template, ) from homeassistant.helpers.dispatcher import async_dispatcher_send -from homeassistant.helpers.entity import validate_entity_category +from homeassistant.helpers.entity import ENTITY_CATEGORIES_SCHEMA from homeassistant.util.decorator import Registry from .const import ( @@ -446,7 +446,7 @@ def _validate_state_class_sensor(value: dict): vol.Optional(ATTR_SENSOR_STATE, default=None): vol.Any( None, bool, str, int, float ), - vol.Optional(ATTR_SENSOR_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(ATTR_SENSOR_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, vol.Optional(ATTR_SENSOR_ICON, default="mdi:cellphone"): cv.icon, vol.Optional(ATTR_SENSOR_STATE_CLASS): vol.In(SENSOSR_STATE_CLASSES), }, diff --git a/homeassistant/components/mqtt/mixins.py b/homeassistant/components/mqtt/mixins.py index 09efb384196..bf3431c5324 100644 --- a/homeassistant/components/mqtt/mixins.py +++ b/homeassistant/components/mqtt/mixins.py @@ -37,11 +37,11 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_send, ) from homeassistant.helpers.entity import ( + ENTITY_CATEGORIES_SCHEMA, DeviceInfo, Entity, EntityCategory, async_generate_entity_id, - validate_entity_category, ) from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.reload import async_setup_reload_service @@ -212,7 +212,7 @@ MQTT_ENTITY_COMMON_SCHEMA = MQTT_AVAILABILITY_SCHEMA.extend( { vol.Optional(CONF_DEVICE): MQTT_ENTITY_DEVICE_INFO_SCHEMA, vol.Optional(CONF_ENABLED_BY_DEFAULT, default=True): cv.boolean, - vol.Optional(CONF_ENTITY_CATEGORY): validate_entity_category, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, vol.Optional(CONF_ICON): cv.icon, vol.Optional(CONF_JSON_ATTRS_TOPIC): valid_subscribe_topic, vol.Optional(CONF_JSON_ATTRS_TEMPLATE): cv.template, diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index f6869787f5b..2b5604832d5 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -12,7 +12,7 @@ import logging import math import sys from timeit import default_timer as timer -from typing import Any, Literal, TypedDict, final +from typing import Any, Final, Literal, TypedDict, final import voluptuous as vol @@ -28,7 +28,6 @@ from homeassistant.const import ( ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT, DEVICE_DEFAULT_NAME, - ENTITY_CATEGORIES, STATE_OFF, STATE_ON, STATE_UNAVAILABLE, @@ -65,15 +64,6 @@ SOURCE_PLATFORM_CONFIG = "platform_config" FLOAT_PRECISION = abs(int(math.floor(math.log10(abs(sys.float_info.epsilon))))) - 1 -def validate_entity_category(value: Any | None) -> EntityCategory: - """Validate entity category configuration.""" - value = vol.In(ENTITY_CATEGORIES)(value) - return EntityCategory(value) - - -ENTITY_CATEGORIES_SCHEMA = validate_entity_category - - @callback @bind_hass def entity_sources(hass: HomeAssistant) -> dict[str, dict[str, str]]: @@ -214,6 +204,9 @@ class EntityCategory(StrEnum): SYSTEM = "system" +ENTITY_CATEGORIES_SCHEMA: Final = vol.Coerce(EntityCategory) + + class EntityPlatformState(Enum): """The platform state of an entity.""" diff --git a/tests/helpers/test_entity.py b/tests/helpers/test_entity.py index 9130de04e0f..5bd04742195 100644 --- a/tests/helpers/test_entity.py +++ b/tests/helpers/test_entity.py @@ -927,5 +927,8 @@ def test_entity_category_schema(value, expected): def test_entity_category_schema_error(value): """Test entity category schema.""" schema = vol.Schema(entity.ENTITY_CATEGORIES_SCHEMA) - with pytest.raises(vol.Invalid): + with pytest.raises( + vol.Invalid, + match=r"expected EntityCategory or one of 'config', 'diagnostic', 'system'", + ): schema(value)