Add support for entity category for necessary KNX platforms (#58357)

This commit is contained in:
Marvin Wichmann 2021-10-25 05:12:26 +02:00 committed by GitHub
parent f3a1c81e22
commit e9ca511327
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 84 additions and 10 deletions

View File

@ -9,6 +9,7 @@ from xknx.devices import BinarySensor as XknxBinarySensor
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.const import (
CONF_DEVICE_CLASS,
CONF_ENTITY_CATEGORY,
CONF_NAME,
STATE_ON,
STATE_UNAVAILABLE,
@ -64,6 +65,7 @@ class KNXBinarySensor(KnxEntity, BinarySensorEntity, RestoreEntity):
reset_after=config.get(BinarySensorSchema.CONF_RESET_AFTER),
)
)
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
self._attr_device_class = config.get(CONF_DEVICE_CLASS)
self._attr_force_update = self._device.ignore_internal_state
self._attr_unique_id = str(self._device.remote_value.group_address_state)

View File

@ -17,7 +17,12 @@ from homeassistant.components.climate.const import (
SUPPORT_PRESET_MODE,
SUPPORT_TARGET_TEMPERATURE,
)
from homeassistant.const import ATTR_TEMPERATURE, CONF_NAME, TEMP_CELSIUS
from homeassistant.const import (
ATTR_TEMPERATURE,
CONF_ENTITY_CATEGORY,
CONF_NAME,
TEMP_CELSIUS,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -176,6 +181,7 @@ class KNXClimate(KnxEntity, ClimateEntity):
def __init__(self, xknx: XKNX, config: ConfigType) -> None:
"""Initialize of a KNX climate device."""
super().__init__(_create_climate(xknx, config))
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
self._attr_supported_features = SUPPORT_TARGET_TEMPERATURE
if self.preset_modes:
self._attr_supported_features |= SUPPORT_PRESET_MODE

View File

@ -23,7 +23,7 @@ from homeassistant.components.cover import (
SUPPORT_STOP_TILT,
CoverEntity,
)
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME
from homeassistant.const import CONF_DEVICE_CLASS, CONF_ENTITY_CATEGORY, CONF_NAME
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -109,6 +109,7 @@ class KNXCover(KnxEntity, CoverEntity):
)
)
self._unsubscribe_auto_updater: Callable[[], None] | None = None
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
self._attr_device_class = config.get(CONF_DEVICE_CLASS) or (
DEVICE_CLASS_BLIND if self._device.supports_angle else None

View File

@ -8,7 +8,7 @@ from xknx import XKNX
from xknx.devices import Fan as XknxFan
from homeassistant.components.fan import SUPPORT_OSCILLATE, SUPPORT_SET_SPEED, FanEntity
from homeassistant.const import CONF_NAME
from homeassistant.const import CONF_ENTITY_CATEGORY, CONF_NAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
@ -65,6 +65,7 @@ class KNXFan(KnxEntity, FanEntity):
)
# FanSpeedMode.STEP if max_step is set
self._step_range: tuple[int, int] | None = (1, max_step) if max_step else None
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
self._attr_unique_id = str(self._device.speed.group_address)

View File

@ -23,7 +23,7 @@ from homeassistant.components.light import (
COLOR_MODE_XY,
LightEntity,
)
from homeassistant.const import CONF_NAME
from homeassistant.const import CONF_ENTITY_CATEGORY, CONF_NAME
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -242,6 +242,7 @@ class KNXLight(KnxEntity, LightEntity):
self._attr_min_mireds = color_util.color_temperature_kelvin_to_mired(
self._max_kelvin
)
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
self._attr_unique_id = self._device_unique_id()
def _device_unique_id(self) -> str:

View File

@ -8,6 +8,7 @@ from xknx.devices import NumericValue
from homeassistant.components.number import NumberEntity
from homeassistant.const import (
CONF_ENTITY_CATEGORY,
CONF_MODE,
CONF_NAME,
CONF_TYPE,
@ -74,6 +75,7 @@ class KNXNumber(KnxEntity, NumberEntity, RestoreEntity):
NumberSchema.CONF_STEP,
self._device.sensor_value.dpt_class.resolution,
)
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
self._attr_unique_id = str(self._device.sensor_value.group_address)
self._attr_unit_of_measurement = self._device.unit_of_measurement()
self._device.sensor_value.value = max(0, self._attr_min_value)

View File

@ -7,7 +7,7 @@ from xknx import XKNX
from xknx.devices import Scene as XknxScene
from homeassistant.components.scene import Scene
from homeassistant.const import CONF_NAME
from homeassistant.const import CONF_ENTITY_CATEGORY, CONF_NAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
@ -49,6 +49,7 @@ class KNXScene(KnxEntity, Scene):
scene_number=config[SceneSchema.CONF_SCENE_NUMBER],
)
)
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
self._attr_unique_id = (
f"{self._device.scene_value.group_address}_{self._device.scene_number}"
)

View File

@ -22,6 +22,7 @@ from homeassistant.components.number.const import MODE_AUTO, MODE_BOX, MODE_SLID
from homeassistant.components.sensor import CONF_STATE_CLASS, STATE_CLASSES_SCHEMA
from homeassistant.const import (
CONF_DEVICE_CLASS,
CONF_ENTITY_CATEGORY,
CONF_ENTITY_ID,
CONF_HOST,
CONF_MODE,
@ -30,6 +31,7 @@ from homeassistant.const import (
CONF_TYPE,
)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import ENTITY_CATEGORIES_SCHEMA
from .const import (
CONF_INVERT,
@ -253,6 +255,7 @@ class BinarySensorSchema(KNXPlatformSchema):
),
vol.Optional(CONF_DEVICE_CLASS): vol.In(BINARY_SENSOR_DEVICE_CLASSES),
vol.Optional(CONF_RESET_AFTER): cv.positive_float,
vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
}
),
)
@ -371,6 +374,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): ENTITY_CATEGORIES_SCHEMA,
}
),
)
@ -425,6 +429,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): vol.In(COVER_DEVICE_CLASSES),
vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
}
),
)
@ -487,6 +492,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): ENTITY_CATEGORIES_SCHEMA,
}
)
@ -590,6 +596,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): ENTITY_CATEGORIES_SCHEMA,
}
),
vol.Any(
@ -669,6 +676,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): ENTITY_CATEGORIES_SCHEMA,
}
),
number_limit_sub_validator,
@ -690,6 +698,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): ENTITY_CATEGORIES_SCHEMA,
}
)
@ -722,6 +731,7 @@ class SelectSchema(KNXPlatformSchema):
],
vol.Required(KNX_ADDRESS): ga_list_validator,
vol.Optional(CONF_STATE_ADDRESS): ga_list_validator,
vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
}
),
select_options_sub_validator,
@ -746,6 +756,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): ENTITY_CATEGORIES_SCHEMA,
}
)
@ -766,6 +777,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): ENTITY_CATEGORIES_SCHEMA,
}
)
@ -812,6 +824,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): ENTITY_CATEGORIES_SCHEMA,
}
),
)

View File

@ -5,7 +5,12 @@ from xknx import XKNX
from xknx.devices import Device as XknxDevice, RawValue
from homeassistant.components.select import SelectEntity
from homeassistant.const import CONF_NAME, STATE_UNAVAILABLE, STATE_UNKNOWN
from homeassistant.const import (
CONF_ENTITY_CATEGORY,
CONF_NAME,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.restore_state import RestoreEntity
@ -66,6 +71,7 @@ class KNXSelect(KnxEntity, SelectEntity, RestoreEntity):
}
self._attr_options = list(self._option_payloads)
self._attr_current_option = None
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
self._attr_unique_id = str(self._device.remote_value.group_address)
async def async_added_to_hass(self) -> None:

View File

@ -11,7 +11,7 @@ from homeassistant.components.sensor import (
DEVICE_CLASSES,
SensorEntity,
)
from homeassistant.const import CONF_NAME, CONF_TYPE
from homeassistant.const import CONF_ENTITY_CATEGORY, CONF_NAME, CONF_TYPE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType
@ -65,6 +65,7 @@ class KNXSensor(KnxEntity, SensorEntity):
else None
)
self._attr_force_update = self._device.always_callback
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
self._attr_unique_id = str(self._device.sensor_value.group_address_state)
self._attr_native_unit_of_measurement = self._device.unit_of_measurement()
self._attr_state_class = config.get(CONF_STATE_CLASS)

View File

@ -7,7 +7,13 @@ from xknx import XKNX
from xknx.devices import Switch as XknxSwitch
from homeassistant.components.switch import SwitchEntity
from homeassistant.const import CONF_NAME, STATE_ON, STATE_UNAVAILABLE, STATE_UNKNOWN
from homeassistant.const import (
CONF_ENTITY_CATEGORY,
CONF_NAME,
STATE_ON,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.restore_state import RestoreEntity
@ -52,6 +58,7 @@ class KNXSwitch(KnxEntity, SwitchEntity, RestoreEntity):
invert=config[SwitchSchema.CONF_INVERT],
)
)
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
self._attr_unique_id = str(self._device.switch.group_address)
async def async_added_to_hass(self) -> None:

View File

@ -5,7 +5,7 @@ from xknx import XKNX
from xknx.devices import Weather as XknxWeather
from homeassistant.components.weather import WeatherEntity
from homeassistant.const import CONF_NAME, TEMP_CELSIUS
from homeassistant.const import CONF_ENTITY_CATEGORY, CONF_NAME, TEMP_CELSIUS
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
@ -78,6 +78,7 @@ class KNXWeather(KnxEntity, WeatherEntity):
"""Initialize of a KNX sensor."""
super().__init__(_create_weather(xknx, config))
self._attr_unique_id = str(self._device._temperature.group_address_state)
self._attr_entity_category = config.get(CONF_ENTITY_CATEGORY)
@property
def temperature(self) -> float | None:

View File

@ -4,8 +4,17 @@ from unittest.mock import patch
from homeassistant.components.knx.const import CONF_STATE_ADDRESS, CONF_SYNC_STATE
from homeassistant.components.knx.schema import BinarySensorSchema
from homeassistant.const import CONF_NAME, STATE_OFF, STATE_ON
from homeassistant.const import (
CONF_ENTITY_CATEGORY,
CONF_NAME,
ENTITY_CATEGORY_DIAGNOSTIC,
STATE_OFF,
STATE_ON,
)
from homeassistant.core import HomeAssistant, State
from homeassistant.helpers.entity_registry import (
async_get_registry as async_get_entity_registry,
)
from homeassistant.util import dt
from .conftest import KNXTestKit
@ -13,6 +22,29 @@ from .conftest import KNXTestKit
from tests.common import async_capture_events, async_fire_time_changed
async def test_binary_sensor_entity_category(hass: HomeAssistant, knx: KNXTestKit):
"""Test KNX binary sensor entity category."""
await knx.setup_integration(
{
BinarySensorSchema.PLATFORM_NAME: [
{
CONF_NAME: "test_normal",
CONF_STATE_ADDRESS: "1/1/1",
CONF_ENTITY_CATEGORY: ENTITY_CATEGORY_DIAGNOSTIC,
},
]
}
)
assert len(hass.states.async_all()) == 1
await knx.assert_read("1/1/1")
await knx.receive_response("1/1/1", True)
registry = await async_get_entity_registry(hass)
entity = registry.async_get("binary_sensor.test_normal")
assert entity.entity_category == ENTITY_CATEGORY_DIAGNOSTIC
async def test_binary_sensor(hass: HomeAssistant, knx: KNXTestKit):
"""Test KNX binary sensor and inverted binary_sensor."""
await knx.setup_integration(