diff --git a/homeassistant/components/homekit/__init__.py b/homeassistant/components/homekit/__init__.py index cfa734559fc..2bc7da6d24a 100644 --- a/homeassistant/components/homekit/__init__.py +++ b/homeassistant/components/homekit/__init__.py @@ -12,16 +12,14 @@ import voluptuous as vol from homeassistant.components import device_automation, network, zeroconf from homeassistant.components.binary_sensor import ( - DEVICE_CLASS_BATTERY_CHARGING, - DEVICE_CLASS_MOTION, - DEVICE_CLASS_OCCUPANCY, DOMAIN as BINARY_SENSOR_DOMAIN, + BinarySensorDeviceClass, ) from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN from homeassistant.components.http import HomeAssistantView from homeassistant.components.humidifier import DOMAIN as HUMIDIFIER_DOMAIN from homeassistant.components.network.const import MDNS_TARGET_IP -from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN +from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN, SensorDeviceClass from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.const import ( ATTR_BATTERY_CHARGING, @@ -35,8 +33,6 @@ from homeassistant.const import ( CONF_IP_ADDRESS, CONF_NAME, CONF_PORT, - DEVICE_CLASS_BATTERY, - DEVICE_CLASS_HUMIDITY, EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP, SERVICE_RELOAD, @@ -669,11 +665,11 @@ class HomeKit: ent_reg = entity_registry.async_get(self.hass) device_lookup = ent_reg.async_get_device_class_lookup( { - (BINARY_SENSOR_DOMAIN, DEVICE_CLASS_BATTERY_CHARGING), - (BINARY_SENSOR_DOMAIN, DEVICE_CLASS_MOTION), - (BINARY_SENSOR_DOMAIN, DEVICE_CLASS_OCCUPANCY), - (SENSOR_DOMAIN, DEVICE_CLASS_BATTERY), - (SENSOR_DOMAIN, DEVICE_CLASS_HUMIDITY), + (BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.BATTERY_CHARGING), + (BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.MOTION), + (BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.OCCUPANCY), + (SENSOR_DOMAIN, SensorDeviceClass.BATTERY), + (SENSOR_DOMAIN, SensorDeviceClass.HUMIDITY), } ) @@ -860,14 +856,14 @@ class HomeKit: or ent_reg_ent.device_id is None or ent_reg_ent.device_id not in device_lookup or (ent_reg_ent.device_class or ent_reg_ent.original_device_class) - in (DEVICE_CLASS_BATTERY_CHARGING, DEVICE_CLASS_BATTERY) + in (BinarySensorDeviceClass.BATTERY_CHARGING, SensorDeviceClass.BATTERY) ): return if ATTR_BATTERY_CHARGING not in state.attributes: battery_charging_binary_sensor_entity_id = device_lookup[ ent_reg_ent.device_id - ].get((BINARY_SENSOR_DOMAIN, DEVICE_CLASS_BATTERY_CHARGING)) + ].get((BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.BATTERY_CHARGING)) if battery_charging_binary_sensor_entity_id: self._config.setdefault(state.entity_id, {}).setdefault( CONF_LINKED_BATTERY_CHARGING_SENSOR, @@ -876,7 +872,7 @@ class HomeKit: if ATTR_BATTERY_LEVEL not in state.attributes: battery_sensor_entity_id = device_lookup[ent_reg_ent.device_id].get( - (SENSOR_DOMAIN, DEVICE_CLASS_BATTERY) + (SENSOR_DOMAIN, SensorDeviceClass.BATTERY) ) if battery_sensor_entity_id: self._config.setdefault(state.entity_id, {}).setdefault( @@ -885,7 +881,7 @@ class HomeKit: if state.entity_id.startswith(f"{CAMERA_DOMAIN}."): motion_binary_sensor_entity_id = device_lookup[ent_reg_ent.device_id].get( - (BINARY_SENSOR_DOMAIN, DEVICE_CLASS_MOTION) + (BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.MOTION) ) if motion_binary_sensor_entity_id: self._config.setdefault(state.entity_id, {}).setdefault( @@ -893,7 +889,7 @@ class HomeKit: motion_binary_sensor_entity_id, ) doorbell_binary_sensor_entity_id = device_lookup[ent_reg_ent.device_id].get( - (BINARY_SENSOR_DOMAIN, DEVICE_CLASS_OCCUPANCY) + (BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.OCCUPANCY) ) if doorbell_binary_sensor_entity_id: self._config.setdefault(state.entity_id, {}).setdefault( @@ -904,7 +900,7 @@ class HomeKit: if state.entity_id.startswith(f"{HUMIDIFIER_DOMAIN}."): current_humidity_sensor_entity_id = device_lookup[ ent_reg_ent.device_id - ].get((SENSOR_DOMAIN, DEVICE_CLASS_HUMIDITY)) + ].get((SENSOR_DOMAIN, SensorDeviceClass.HUMIDITY)) if current_humidity_sensor_entity_id: self._config.setdefault(state.entity_id, {}).setdefault( CONF_LINKED_HUMIDITY_SENSOR, diff --git a/homeassistant/components/homekit/accessories.py b/homeassistant/components/homekit/accessories.py index ca12daa33b3..6af4b4a8d89 100644 --- a/homeassistant/components/homekit/accessories.py +++ b/homeassistant/components/homekit/accessories.py @@ -7,13 +7,9 @@ from pyhap.const import CATEGORY_OTHER from pyhap.util import callback as pyhap_callback from homeassistant.components import cover -from homeassistant.components.cover import ( - DEVICE_CLASS_GARAGE, - DEVICE_CLASS_GATE, - DEVICE_CLASS_WINDOW, -) -from homeassistant.components.media_player import DEVICE_CLASS_TV +from homeassistant.components.media_player import MediaPlayerDeviceClass from homeassistant.components.remote import SUPPORT_ACTIVITY +from homeassistant.components.sensor import SensorDeviceClass from homeassistant.const import ( ATTR_BATTERY_CHARGING, ATTR_BATTERY_LEVEL, @@ -27,11 +23,6 @@ from homeassistant.const import ( ATTR_UNIT_OF_MEASUREMENT, CONF_NAME, CONF_TYPE, - DEVICE_CLASS_CO, - DEVICE_CLASS_CO2, - DEVICE_CLASS_HUMIDITY, - DEVICE_CLASS_ILLUMINANCE, - DEVICE_CLASS_TEMPERATURE, LIGHT_LUX, PERCENTAGE, STATE_ON, @@ -58,7 +49,6 @@ from .const import ( CONF_LINKED_BATTERY_SENSOR, CONF_LOW_BATTERY_THRESHOLD, DEFAULT_LOW_BATTERY_THRESHOLD, - DEVICE_CLASS_PM25, DOMAIN, EVENT_HOMEKIT_CHANGED, HK_CHARGING, @@ -126,12 +116,17 @@ def get_accessory(hass, driver, state, aid, config): # noqa: C901 elif state.domain == "cover": device_class = state.attributes.get(ATTR_DEVICE_CLASS) - if device_class in (DEVICE_CLASS_GARAGE, DEVICE_CLASS_GATE) and features & ( - cover.SUPPORT_OPEN | cover.SUPPORT_CLOSE + if ( + device_class + in ( + cover.CoverDeviceClass.GARAGE, + cover.CoverDeviceClass.GATE, + ) + and features & (cover.SUPPORT_OPEN | cover.SUPPORT_CLOSE) ): a_type = "GarageDoorOpener" elif ( - device_class == DEVICE_CLASS_WINDOW + device_class == cover.CoverDeviceClass.WINDOW and features & cover.SUPPORT_SET_POSITION ): a_type = "Window" @@ -161,7 +156,7 @@ def get_accessory(hass, driver, state, aid, config): # noqa: C901 device_class = state.attributes.get(ATTR_DEVICE_CLASS) feature_list = config.get(CONF_FEATURE_LIST, []) - if device_class == DEVICE_CLASS_TV: + if device_class == MediaPlayerDeviceClass.TV: a_type = "TelevisionMediaPlayer" elif validate_media_player_features(state, feature_list): a_type = "MediaPlayer" @@ -170,20 +165,23 @@ def get_accessory(hass, driver, state, aid, config): # noqa: C901 device_class = state.attributes.get(ATTR_DEVICE_CLASS) unit = state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) - if device_class == DEVICE_CLASS_TEMPERATURE or unit in ( + if device_class == SensorDeviceClass.TEMPERATURE or unit in ( TEMP_CELSIUS, TEMP_FAHRENHEIT, ): a_type = "TemperatureSensor" - elif device_class == DEVICE_CLASS_HUMIDITY and unit == PERCENTAGE: + elif device_class == SensorDeviceClass.HUMIDITY and unit == PERCENTAGE: a_type = "HumiditySensor" - elif device_class == DEVICE_CLASS_PM25 or DEVICE_CLASS_PM25 in state.entity_id: + elif ( + device_class == SensorDeviceClass.PM25 + or SensorDeviceClass.PM25 in state.entity_id + ): a_type = "AirQualitySensor" - elif device_class == DEVICE_CLASS_CO: + elif device_class == SensorDeviceClass.CO: a_type = "CarbonMonoxideSensor" - elif device_class == DEVICE_CLASS_CO2 or "co2" in state.entity_id: + elif device_class == SensorDeviceClass.CO2 or "co2" in state.entity_id: a_type = "CarbonDioxideSensor" - elif device_class == DEVICE_CLASS_ILLUMINANCE or unit in ("lm", LIGHT_LUX): + elif device_class == SensorDeviceClass.ILLUMINANCE or unit in ("lm", LIGHT_LUX): a_type = "LightSensor" elif state.domain == "switch": diff --git a/homeassistant/components/homekit/const.py b/homeassistant/components/homekit/const.py index 8494327bb68..1dd40d0fa31 100644 --- a/homeassistant/components/homekit/const.py +++ b/homeassistant/components/homekit/const.py @@ -234,18 +234,6 @@ PROP_MIN_STEP = "minStep" PROP_CELSIUS = {"minValue": -273, "maxValue": 999} PROP_VALID_VALUES = "ValidValues" -# #### Device Classes #### -DEVICE_CLASS_DOOR = "door" -DEVICE_CLASS_GARAGE_DOOR = "garage_door" -DEVICE_CLASS_GAS = "gas" -DEVICE_CLASS_MOISTURE = "moisture" -DEVICE_CLASS_MOTION = "motion" -DEVICE_CLASS_OCCUPANCY = "occupancy" -DEVICE_CLASS_OPENING = "opening" -DEVICE_CLASS_PM25 = "pm25" -DEVICE_CLASS_SMOKE = "smoke" -DEVICE_CLASS_WINDOW = "window" - # #### Thresholds #### THRESHOLD_CO = 25 THRESHOLD_CO2 = 1000 diff --git a/homeassistant/components/homekit/type_covers.py b/homeassistant/components/homekit/type_covers.py index b9153ef1372..51d0480bde3 100644 --- a/homeassistant/components/homekit/type_covers.py +++ b/homeassistant/components/homekit/type_covers.py @@ -319,7 +319,7 @@ class OpeningDevice(OpeningDeviceBase, HomeAccessory): @TYPES.register("Window") class Window(OpeningDevice): - """Generate a Window accessory for a cover entity with DEVICE_CLASS_WINDOW. + """Generate a Window accessory for a cover entity with WINDOW device class. The entity must support: set_cover_position. """ diff --git a/homeassistant/components/homekit/type_humidifiers.py b/homeassistant/components/homekit/type_humidifiers.py index 2f4866e395a..a468efd42b4 100644 --- a/homeassistant/components/homekit/type_humidifiers.py +++ b/homeassistant/components/homekit/type_humidifiers.py @@ -3,14 +3,13 @@ import logging from pyhap.const import CATEGORY_HUMIDIFIER +from homeassistant.components.humidifier import HumidifierDeviceClass from homeassistant.components.humidifier.const import ( ATTR_HUMIDITY, ATTR_MAX_HUMIDITY, ATTR_MIN_HUMIDITY, DEFAULT_MAX_HUMIDITY, DEFAULT_MIN_HUMIDITY, - DEVICE_CLASS_DEHUMIDIFIER, - DEVICE_CLASS_HUMIDIFIER, DOMAIN, SERVICE_SET_HUMIDITY, ) @@ -46,13 +45,13 @@ HC_HUMIDIFIER = 1 HC_DEHUMIDIFIER = 2 HC_HASS_TO_HOMEKIT_DEVICE_CLASS = { - DEVICE_CLASS_HUMIDIFIER: HC_HUMIDIFIER, - DEVICE_CLASS_DEHUMIDIFIER: HC_DEHUMIDIFIER, + HumidifierDeviceClass.HUMIDIFIER: HC_HUMIDIFIER, + HumidifierDeviceClass.DEHUMIDIFIER: HC_DEHUMIDIFIER, } HC_HASS_TO_HOMEKIT_DEVICE_CLASS_NAME = { - DEVICE_CLASS_HUMIDIFIER: "Humidifier", - DEVICE_CLASS_DEHUMIDIFIER: "Dehumidifier", + HumidifierDeviceClass.HUMIDIFIER: "Humidifier", + HumidifierDeviceClass.DEHUMIDIFIER: "Dehumidifier", } HC_DEVICE_CLASS_TO_TARGET_CHAR = { @@ -75,7 +74,9 @@ class HumidifierDehumidifier(HomeAccessory): super().__init__(*args, category=CATEGORY_HUMIDIFIER) self.chars = [] state = self.hass.states.get(self.entity_id) - device_class = state.attributes.get(ATTR_DEVICE_CLASS, DEVICE_CLASS_HUMIDIFIER) + device_class = state.attributes.get( + ATTR_DEVICE_CLASS, HumidifierDeviceClass.HUMIDIFIER + ) self._hk_device_class = HC_HASS_TO_HOMEKIT_DEVICE_CLASS[device_class] self._target_humidity_char_name = HC_DEVICE_CLASS_TO_TARGET_CHAR[ diff --git a/homeassistant/components/homekit/type_sensors.py b/homeassistant/components/homekit/type_sensors.py index 148b705b23f..598d49155ec 100644 --- a/homeassistant/components/homekit/type_sensors.py +++ b/homeassistant/components/homekit/type_sensors.py @@ -7,6 +7,7 @@ from typing import NamedTuple from pyhap.const import CATEGORY_SENSOR +from homeassistant.components.binary_sensor import BinarySensorDeviceClass from homeassistant.const import ( ATTR_DEVICE_CLASS, ATTR_UNIT_OF_MEASUREMENT, @@ -36,15 +37,6 @@ from .const import ( CHAR_MOTION_DETECTED, CHAR_OCCUPANCY_DETECTED, CHAR_SMOKE_DETECTED, - DEVICE_CLASS_DOOR, - DEVICE_CLASS_GARAGE_DOOR, - DEVICE_CLASS_GAS, - DEVICE_CLASS_MOISTURE, - DEVICE_CLASS_MOTION, - DEVICE_CLASS_OCCUPANCY, - DEVICE_CLASS_OPENING, - DEVICE_CLASS_SMOKE, - DEVICE_CLASS_WINDOW, PROP_CELSIUS, SERV_AIR_QUALITY_SENSOR, SERV_CARBON_DIOXIDE_SENSOR, @@ -78,17 +70,27 @@ BINARY_SENSOR_SERVICE_MAP: dict[str, SI] = { SERV_CARBON_MONOXIDE_SENSOR, CHAR_CARBON_MONOXIDE_DETECTED, int ), DEVICE_CLASS_CO2: SI(SERV_CARBON_DIOXIDE_SENSOR, CHAR_CARBON_DIOXIDE_DETECTED, int), - DEVICE_CLASS_DOOR: SI(SERV_CONTACT_SENSOR, CHAR_CONTACT_SENSOR_STATE, int), - DEVICE_CLASS_GARAGE_DOOR: SI(SERV_CONTACT_SENSOR, CHAR_CONTACT_SENSOR_STATE, int), - DEVICE_CLASS_GAS: SI( + BinarySensorDeviceClass.DOOR: SI( + SERV_CONTACT_SENSOR, CHAR_CONTACT_SENSOR_STATE, int + ), + BinarySensorDeviceClass.GARAGE_DOOR: SI( + SERV_CONTACT_SENSOR, CHAR_CONTACT_SENSOR_STATE, int + ), + BinarySensorDeviceClass.GAS: SI( SERV_CARBON_MONOXIDE_SENSOR, CHAR_CARBON_MONOXIDE_DETECTED, int ), - DEVICE_CLASS_MOISTURE: SI(SERV_LEAK_SENSOR, CHAR_LEAK_DETECTED, int), - DEVICE_CLASS_MOTION: SI(SERV_MOTION_SENSOR, CHAR_MOTION_DETECTED, bool), - DEVICE_CLASS_OCCUPANCY: SI(SERV_OCCUPANCY_SENSOR, CHAR_OCCUPANCY_DETECTED, int), - DEVICE_CLASS_OPENING: SI(SERV_CONTACT_SENSOR, CHAR_CONTACT_SENSOR_STATE, int), - DEVICE_CLASS_SMOKE: SI(SERV_SMOKE_SENSOR, CHAR_SMOKE_DETECTED, int), - DEVICE_CLASS_WINDOW: SI(SERV_CONTACT_SENSOR, CHAR_CONTACT_SENSOR_STATE, int), + BinarySensorDeviceClass.MOISTURE: SI(SERV_LEAK_SENSOR, CHAR_LEAK_DETECTED, int), + BinarySensorDeviceClass.MOTION: SI(SERV_MOTION_SENSOR, CHAR_MOTION_DETECTED, bool), + BinarySensorDeviceClass.OCCUPANCY: SI( + SERV_OCCUPANCY_SENSOR, CHAR_OCCUPANCY_DETECTED, int + ), + BinarySensorDeviceClass.OPENING: SI( + SERV_CONTACT_SENSOR, CHAR_CONTACT_SENSOR_STATE, int + ), + BinarySensorDeviceClass.SMOKE: SI(SERV_SMOKE_SENSOR, CHAR_SMOKE_DETECTED, int), + BinarySensorDeviceClass.WINDOW: SI( + SERV_CONTACT_SENSOR, CHAR_CONTACT_SENSOR_STATE, int + ), } @@ -284,7 +286,7 @@ class BinarySensor(HomeAccessory): service_char = ( BINARY_SENSOR_SERVICE_MAP[device_class] if device_class in BINARY_SENSOR_SERVICE_MAP - else BINARY_SENSOR_SERVICE_MAP[DEVICE_CLASS_OCCUPANCY] + else BINARY_SENSOR_SERVICE_MAP[BinarySensorDeviceClass.OCCUPANCY] ) self.format = service_char.format diff --git a/homeassistant/components/homekit/util.py b/homeassistant/components/homekit/util.py index 11b0f6cf925..894bfcf8985 100644 --- a/homeassistant/components/homekit/util.py +++ b/homeassistant/components/homekit/util.py @@ -14,8 +14,8 @@ from homeassistant.components import binary_sensor, media_player, sensor from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN from homeassistant.components.media_player import ( - DEVICE_CLASS_TV, DOMAIN as MEDIA_PLAYER_DOMAIN, + MediaPlayerDeviceClass, ) from homeassistant.components.remote import DOMAIN as REMOTE_DOMAIN, SUPPORT_ACTIVITY from homeassistant.const import ( @@ -502,7 +502,7 @@ def state_needs_accessory_mode(state): return ( state.domain == MEDIA_PLAYER_DOMAIN - and state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TV + and state.attributes.get(ATTR_DEVICE_CLASS) == MediaPlayerDeviceClass.TV or state.domain == REMOTE_DOMAIN and state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) & SUPPORT_ACTIVITY ) diff --git a/tests/components/homekit/test_type_cameras.py b/tests/components/homekit/test_type_cameras.py index 05c809910cf..ba2dadc2a19 100644 --- a/tests/components/homekit/test_type_cameras.py +++ b/tests/components/homekit/test_type_cameras.py @@ -8,6 +8,10 @@ from pyhap.accessory_driver import AccessoryDriver import pytest from homeassistant.components import camera, ffmpeg +from homeassistant.components.binary_sensor import ( + DEVICE_CLASS_MOTION, + DEVICE_CLASS_OCCUPANCY, +) from homeassistant.components.camera.img_util import TurboJPEGSingleton from homeassistant.components.homekit.accessories import HomeBridge from homeassistant.components.homekit.const import ( @@ -20,8 +24,6 @@ from homeassistant.components.homekit.const import ( CONF_STREAM_SOURCE, CONF_SUPPORT_AUDIO, CONF_VIDEO_CODEC, - DEVICE_CLASS_MOTION, - DEVICE_CLASS_OCCUPANCY, SERV_DOORBELL, SERV_MOTION_SENSOR, SERV_STATELESS_PROGRAMMABLE_SWITCH, diff --git a/tests/components/homekit/test_type_sensors.py b/tests/components/homekit/test_type_sensors.py index 7ad48bfbce6..98e44de7575 100644 --- a/tests/components/homekit/test_type_sensors.py +++ b/tests/components/homekit/test_type_sensors.py @@ -1,7 +1,7 @@ """Test different accessory types: Sensors.""" +from homeassistant.components.binary_sensor import DEVICE_CLASS_MOTION from homeassistant.components.homekit import get_accessory from homeassistant.components.homekit.const import ( - DEVICE_CLASS_MOTION, PROP_CELSIUS, THRESHOLD_CO, THRESHOLD_CO2,