From 71b298f3ede816d84cf85b2b1ad1231575b5dbaf Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Thu, 7 Apr 2022 09:09:27 +0200 Subject: [PATCH] Use EntityFeature constants in homekit (#69535) --- .../components/homekit/accessories.py | 25 ++++++++-------- .../components/homekit/type_covers.py | 10 +++---- homeassistant/components/homekit/type_fans.py | 12 ++++---- .../components/homekit/type_media_players.py | 20 ++++++------- .../components/homekit/type_remotes.py | 4 +-- .../homekit/type_security_systems.py | 29 +++++++++---------- .../components/homekit/type_switches.py | 7 ++--- .../components/homekit/type_thermostats.py | 23 +++++++-------- homeassistant/components/homekit/util.py | 14 +++++---- 9 files changed, 70 insertions(+), 74 deletions(-) diff --git a/homeassistant/components/homekit/accessories.py b/homeassistant/components/homekit/accessories.py index 1d06fa04a57..9d428573b5b 100644 --- a/homeassistant/components/homekit/accessories.py +++ b/homeassistant/components/homekit/accessories.py @@ -10,9 +10,9 @@ from pyhap.accessory_driver import AccessoryDriver from pyhap.const import CATEGORY_OTHER from pyhap.util import callback as pyhap_callback -from homeassistant.components import cover +from homeassistant.components.cover import CoverDeviceClass, CoverEntityFeature from homeassistant.components.media_player import MediaPlayerDeviceClass -from homeassistant.components.remote import SUPPORT_ACTIVITY +from homeassistant.components.remote import RemoteEntityFeature from homeassistant.components.sensor import SensorDeviceClass from homeassistant.const import ( ATTR_BATTERY_CHARGING, @@ -134,23 +134,24 @@ def get_accessory( # noqa: C901 device_class = state.attributes.get(ATTR_DEVICE_CLASS) if device_class in ( - cover.CoverDeviceClass.GARAGE, - cover.CoverDeviceClass.GATE, - ) and features & (cover.SUPPORT_OPEN | cover.SUPPORT_CLOSE): + CoverDeviceClass.GARAGE, + CoverDeviceClass.GATE, + ) and features & (CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE): a_type = "GarageDoorOpener" elif ( - device_class == cover.CoverDeviceClass.WINDOW - and features & cover.SUPPORT_SET_POSITION + device_class == CoverDeviceClass.WINDOW + and features & CoverEntityFeature.SET_POSITION ): a_type = "Window" - elif features & cover.SUPPORT_SET_POSITION: + elif features & CoverEntityFeature.SET_POSITION: a_type = "WindowCovering" - elif features & (cover.SUPPORT_OPEN | cover.SUPPORT_CLOSE): + elif features & (CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE): a_type = "WindowCoveringBasic" - elif features & cover.SUPPORT_SET_TILT_POSITION: + elif features & CoverEntityFeature.SET_TILT_POSITION: # WindowCovering and WindowCoveringBasic both support tilt # only WindowCovering can handle the covers that are missing - # SUPPORT_SET_POSITION, SUPPORT_OPEN, and SUPPORT_CLOSE + # CoverEntityFeature.SET_POSITION, CoverEntityFeature.OPEN, + # and CoverEntityFeature.CLOSE a_type = "WindowCovering" elif state.domain == "fan": @@ -214,7 +215,7 @@ def get_accessory( # noqa: C901 elif state.domain == "vacuum": a_type = "Vacuum" - elif state.domain == "remote" and features & SUPPORT_ACTIVITY: + elif state.domain == "remote" and features & RemoteEntityFeature.ACTIVITY: a_type = "ActivityRemote" elif state.domain in ( diff --git a/homeassistant/components/homekit/type_covers.py b/homeassistant/components/homekit/type_covers.py index 51d0480bde3..5879609644c 100644 --- a/homeassistant/components/homekit/type_covers.py +++ b/homeassistant/components/homekit/type_covers.py @@ -13,9 +13,7 @@ from homeassistant.components.cover import ( ATTR_POSITION, ATTR_TILT_POSITION, DOMAIN, - SUPPORT_SET_POSITION, - SUPPORT_SET_TILT_POSITION, - SUPPORT_STOP, + CoverEntityFeature, ) from homeassistant.const import ( ATTR_ENTITY_ID, @@ -201,11 +199,11 @@ class OpeningDeviceBase(HomeAccessory): state = self.hass.states.get(self.entity_id) self.features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) - self._supports_stop = self.features & SUPPORT_STOP + self._supports_stop = self.features & CoverEntityFeature.STOP self.chars = [] if self._supports_stop: self.chars.append(CHAR_HOLD_POSITION) - self._supports_tilt = self.features & SUPPORT_SET_TILT_POSITION + self._supports_tilt = self.features & CoverEntityFeature.SET_TILT_POSITION if self._supports_tilt: self.chars.extend([CHAR_TARGET_TILT_ANGLE, CHAR_CURRENT_TILT_ANGLE]) @@ -276,7 +274,7 @@ class OpeningDevice(OpeningDeviceBase, HomeAccessory): CHAR_CURRENT_POSITION, value=0 ) target_args = {"value": 0} - if self.features & SUPPORT_SET_POSITION: + if self.features & CoverEntityFeature.SET_POSITION: target_args["setter_callback"] = self.move_cover else: # If its tilt only we lock the position state to 0 (closed) diff --git a/homeassistant/components/homekit/type_fans.py b/homeassistant/components/homekit/type_fans.py index 82d254cb9a5..ecc73f5e731 100644 --- a/homeassistant/components/homekit/type_fans.py +++ b/homeassistant/components/homekit/type_fans.py @@ -17,9 +17,7 @@ from homeassistant.components.fan import ( SERVICE_SET_DIRECTION, SERVICE_SET_PERCENTAGE, SERVICE_SET_PRESET_MODE, - SUPPORT_DIRECTION, - SUPPORT_OSCILLATE, - SUPPORT_SET_SPEED, + FanEntityFeature, ) from homeassistant.const import ( ATTR_ENTITY_ID, @@ -66,11 +64,11 @@ class Fan(HomeAccessory): percentage_step = state.attributes.get(ATTR_PERCENTAGE_STEP, 1) self.preset_modes = state.attributes.get(ATTR_PRESET_MODES) - if features & SUPPORT_DIRECTION: + if features & FanEntityFeature.DIRECTION: self.chars.append(CHAR_ROTATION_DIRECTION) - if features & SUPPORT_OSCILLATE: + if features & FanEntityFeature.OSCILLATE: self.chars.append(CHAR_SWING_MODE) - if features & SUPPORT_SET_SPEED: + if features & FanEntityFeature.SET_SPEED: self.chars.append(CHAR_ROTATION_SPEED) if self.preset_modes and len(self.preset_modes) == 1: self.chars.append(CHAR_TARGET_FAN_STATE) @@ -138,7 +136,7 @@ class Fan(HomeAccessory): # the fan to 100% than to the desired speed. # # Setting the speed will take care of turning - # on the fan if SUPPORT_SET_SPEED is set. + # on the fan if FanEntityFeature.SET_SPEED is set. if not self.char_speed or CHAR_ROTATION_SPEED not in char_values: self.set_state(1) else: diff --git a/homeassistant/components/homekit/type_media_players.py b/homeassistant/components/homekit/type_media_players.py index 8faa1385e18..b26016b8adc 100644 --- a/homeassistant/components/homekit/type_media_players.py +++ b/homeassistant/components/homekit/type_media_players.py @@ -10,12 +10,7 @@ from homeassistant.components.media_player import ( ATTR_MEDIA_VOLUME_MUTED, DOMAIN, SERVICE_SELECT_SOURCE, - SUPPORT_PAUSE, - SUPPORT_PLAY, - SUPPORT_SELECT_SOURCE, - SUPPORT_VOLUME_MUTE, - SUPPORT_VOLUME_SET, - SUPPORT_VOLUME_STEP, + MediaPlayerEntityFeature, ) from homeassistant.const import ( ATTR_ENTITY_ID, @@ -218,7 +213,7 @@ class TelevisionMediaPlayer(RemoteInputSelectAccessory): def __init__(self, *args): """Initialize a Television Media Player accessory object.""" super().__init__( - SUPPORT_SELECT_SOURCE, + MediaPlayerEntityFeature.SELECT_SOURCE, ATTR_INPUT_SOURCE, ATTR_INPUT_SOURCE_LIST, *args, @@ -228,12 +223,17 @@ class TelevisionMediaPlayer(RemoteInputSelectAccessory): self.chars_speaker = [] - self._supports_play_pause = features & (SUPPORT_PLAY | SUPPORT_PAUSE) - if features & SUPPORT_VOLUME_MUTE or features & SUPPORT_VOLUME_STEP: + self._supports_play_pause = features & ( + MediaPlayerEntityFeature.PLAY | MediaPlayerEntityFeature.PAUSE + ) + if ( + features & MediaPlayerEntityFeature.VOLUME_MUTE + or features & MediaPlayerEntityFeature.VOLUME_STEP + ): self.chars_speaker.extend( (CHAR_NAME, CHAR_ACTIVE, CHAR_VOLUME_CONTROL_TYPE, CHAR_VOLUME_SELECTOR) ) - if features & SUPPORT_VOLUME_SET: + if features & MediaPlayerEntityFeature.VOLUME_SET: self.chars_speaker.append(CHAR_VOLUME) if CHAR_VOLUME_SELECTOR in self.chars_speaker: diff --git a/homeassistant/components/homekit/type_remotes.py b/homeassistant/components/homekit/type_remotes.py index be1ab2a4f94..aa064cfc012 100644 --- a/homeassistant/components/homekit/type_remotes.py +++ b/homeassistant/components/homekit/type_remotes.py @@ -9,7 +9,7 @@ from homeassistant.components.remote import ( ATTR_ACTIVITY_LIST, ATTR_CURRENT_ACTIVITY, DOMAIN as REMOTE_DOMAIN, - SUPPORT_ACTIVITY, + RemoteEntityFeature, ) from homeassistant.const import ( ATTR_ENTITY_ID, @@ -203,7 +203,7 @@ class ActivityRemote(RemoteInputSelectAccessory): def __init__(self, *args): """Initialize a Activity Remote accessory object.""" super().__init__( - SUPPORT_ACTIVITY, + RemoteEntityFeature.ACTIVITY, ATTR_CURRENT_ACTIVITY, ATTR_ACTIVITY_LIST, *args, diff --git a/homeassistant/components/homekit/type_security_systems.py b/homeassistant/components/homekit/type_security_systems.py index d76fbf0f534..f9c881339ce 100644 --- a/homeassistant/components/homekit/type_security_systems.py +++ b/homeassistant/components/homekit/type_security_systems.py @@ -3,13 +3,9 @@ import logging from pyhap.const import CATEGORY_ALARM_SYSTEM -from homeassistant.components.alarm_control_panel import DOMAIN -from homeassistant.components.alarm_control_panel.const import ( - SUPPORT_ALARM_ARM_AWAY, - SUPPORT_ALARM_ARM_HOME, - SUPPORT_ALARM_ARM_NIGHT, - SUPPORT_ALARM_ARM_VACATION, - SUPPORT_ALARM_TRIGGER, +from homeassistant.components.alarm_control_panel import ( + DOMAIN, + AlarmControlPanelEntityFeature, ) from homeassistant.const import ( ATTR_CODE, @@ -91,11 +87,11 @@ class SecuritySystem(HomeAccessory): supported_states = state.attributes.get( ATTR_SUPPORTED_FEATURES, ( - SUPPORT_ALARM_ARM_HOME - | SUPPORT_ALARM_ARM_VACATION - | SUPPORT_ALARM_ARM_AWAY - | SUPPORT_ALARM_ARM_NIGHT - | SUPPORT_ALARM_TRIGGER + AlarmControlPanelEntityFeature.ARM_HOME + | AlarmControlPanelEntityFeature.ARM_VACATION + | AlarmControlPanelEntityFeature.ARM_AWAY + | AlarmControlPanelEntityFeature.ARM_NIGHT + | AlarmControlPanelEntityFeature.TRIGGER ), ) @@ -108,15 +104,18 @@ class SecuritySystem(HomeAccessory): current_supported_states = [HK_ALARM_DISARMED, HK_ALARM_TRIGGERED] target_supported_services = [HK_ALARM_DISARMED] - if supported_states & SUPPORT_ALARM_ARM_HOME: + if supported_states & AlarmControlPanelEntityFeature.ARM_HOME: current_supported_states.append(HK_ALARM_STAY_ARMED) target_supported_services.append(HK_ALARM_STAY_ARMED) - if supported_states & (SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_VACATION): + if supported_states & ( + AlarmControlPanelEntityFeature.ARM_AWAY + | AlarmControlPanelEntityFeature.ARM_VACATION + ): current_supported_states.append(HK_ALARM_AWAY_ARMED) target_supported_services.append(HK_ALARM_AWAY_ARMED) - if supported_states & SUPPORT_ALARM_ARM_NIGHT: + if supported_states & AlarmControlPanelEntityFeature.ARM_NIGHT: current_supported_states.append(HK_ALARM_NIGHT_ARMED) target_supported_services.append(HK_ALARM_NIGHT_ARMED) diff --git a/homeassistant/components/homekit/type_switches.py b/homeassistant/components/homekit/type_switches.py index 7bc529d7e40..1598df015c5 100644 --- a/homeassistant/components/homekit/type_switches.py +++ b/homeassistant/components/homekit/type_switches.py @@ -20,8 +20,7 @@ from homeassistant.components.vacuum import ( SERVICE_RETURN_TO_BASE, SERVICE_START, STATE_CLEANING, - SUPPORT_RETURN_HOME, - SUPPORT_START, + VacuumEntityFeature, ) from homeassistant.const import ( ATTR_ENTITY_ID, @@ -188,10 +187,10 @@ class Vacuum(Switch): features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) if value: - sup_start = features & SUPPORT_START + sup_start = features & VacuumEntityFeature.START service = SERVICE_START if sup_start else SERVICE_TURN_ON else: - sup_return_home = features & SUPPORT_RETURN_HOME + sup_return_home = features & VacuumEntityFeature.RETURN_HOME service = SERVICE_RETURN_TO_BASE if sup_return_home else SERVICE_TURN_OFF self.async_call_service( diff --git a/homeassistant/components/homekit/type_thermostats.py b/homeassistant/components/homekit/type_thermostats.py index 1e20d1bc710..dbdffa1f03f 100644 --- a/homeassistant/components/homekit/type_thermostats.py +++ b/homeassistant/components/homekit/type_thermostats.py @@ -3,6 +3,7 @@ import logging from pyhap.const import CATEGORY_THERMOSTAT +from homeassistant.components.climate import ClimateEntityFeature from homeassistant.components.climate.const import ( ATTR_CURRENT_HUMIDITY, ATTR_CURRENT_TEMPERATURE, @@ -48,11 +49,6 @@ from homeassistant.components.climate.const import ( SERVICE_SET_HVAC_MODE as SERVICE_SET_HVAC_MODE_THERMOSTAT, SERVICE_SET_SWING_MODE, SERVICE_SET_TEMPERATURE as SERVICE_SET_TEMPERATURE_THERMOSTAT, - SUPPORT_FAN_MODE, - SUPPORT_SWING_MODE, - SUPPORT_TARGET_HUMIDITY, - SUPPORT_TARGET_TEMPERATURE, - SUPPORT_TARGET_TEMPERATURE_RANGE, SWING_BOTH, SWING_HORIZONTAL, SWING_OFF, @@ -199,12 +195,12 @@ class Thermostat(HomeAccessory): min_humidity = attributes.get(ATTR_MIN_HUMIDITY, DEFAULT_MIN_HUMIDITY) features = attributes.get(ATTR_SUPPORTED_FEATURES, 0) - if features & SUPPORT_TARGET_TEMPERATURE_RANGE: + if features & ClimateEntityFeature.TARGET_TEMPERATURE_RANGE: self.chars.extend( (CHAR_COOLING_THRESHOLD_TEMPERATURE, CHAR_HEATING_THRESHOLD_TEMPERATURE) ) - if features & SUPPORT_TARGET_HUMIDITY: + if features & ClimateEntityFeature.TARGET_HUMIDITY: self.chars.extend((CHAR_TARGET_HUMIDITY, CHAR_CURRENT_HUMIDITY)) serv_thermostat = self.add_preload_service(SERV_THERMOSTAT, self.chars) @@ -288,7 +284,7 @@ class Thermostat(HomeAccessory): fan_modes = {} self.ordered_fan_speeds = [] - if features & SUPPORT_FAN_MODE: + if features & ClimateEntityFeature.FAN_MODE: fan_modes = { fan_mode.lower(): fan_mode for fan_mode in attributes.get(ATTR_FAN_MODES) or [] @@ -304,7 +300,7 @@ class Thermostat(HomeAccessory): self.fan_modes = fan_modes if ( - features & SUPPORT_SWING_MODE + features & ClimateEntityFeature.SWING_MODE and (swing_modes := attributes.get(ATTR_SWING_MODES)) and PRE_DEFINED_SWING_MODES.intersection(swing_modes) ): @@ -459,14 +455,14 @@ class Thermostat(HomeAccessory): if CHAR_TARGET_TEMPERATURE in char_values: hc_target_temp = char_values[CHAR_TARGET_TEMPERATURE] - if features & SUPPORT_TARGET_TEMPERATURE: + if features & ClimateEntityFeature.TARGET_TEMPERATURE: service = SERVICE_SET_TEMPERATURE_THERMOSTAT temperature = self._temperature_to_states(hc_target_temp) events.append( f"{CHAR_TARGET_TEMPERATURE} to {char_values[CHAR_TARGET_TEMPERATURE]}°C" ) params[ATTR_TEMPERATURE] = temperature - elif features & SUPPORT_TARGET_TEMPERATURE_RANGE: + elif features & ClimateEntityFeature.TARGET_TEMPERATURE_RANGE: # Homekit will send us a target temperature # even if the device does not support it _LOGGER.debug( @@ -657,7 +653,10 @@ class Thermostat(HomeAccessory): # Update target temperature target_temp = _get_target_temperature(new_state, self._unit) - if target_temp is None and features & SUPPORT_TARGET_TEMPERATURE_RANGE: + if ( + target_temp is None + and features & ClimateEntityFeature.TARGET_TEMPERATURE_RANGE + ): # Homekit expects a target temperature # even if the device does not support it hc_hvac_mode = self.char_target_heat_cool.value diff --git a/homeassistant/components/homekit/util.py b/homeassistant/components/homekit/util.py index be5c166b71d..8b010f85fb6 100644 --- a/homeassistant/components/homekit/util.py +++ b/homeassistant/components/homekit/util.py @@ -25,8 +25,9 @@ from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN from homeassistant.components.media_player import ( DOMAIN as MEDIA_PLAYER_DOMAIN, MediaPlayerDeviceClass, + MediaPlayerEntityFeature, ) -from homeassistant.components.remote import DOMAIN as REMOTE_DOMAIN, SUPPORT_ACTIVITY +from homeassistant.components.remote import DOMAIN as REMOTE_DOMAIN, RemoteEntityFeature from homeassistant.const import ( ATTR_CODE, ATTR_DEVICE_CLASS, @@ -296,14 +297,14 @@ def get_media_player_features(state: State) -> list[str]: supported_modes = [] if features & ( - media_player.const.SUPPORT_TURN_ON | media_player.const.SUPPORT_TURN_OFF + MediaPlayerEntityFeature.TURN_ON | MediaPlayerEntityFeature.TURN_OFF ): supported_modes.append(FEATURE_ON_OFF) - if features & (media_player.const.SUPPORT_PLAY | media_player.const.SUPPORT_PAUSE): + if features & (MediaPlayerEntityFeature.PLAY | MediaPlayerEntityFeature.PAUSE): supported_modes.append(FEATURE_PLAY_PAUSE) - if features & (media_player.const.SUPPORT_PLAY | media_player.const.SUPPORT_STOP): + if features & (MediaPlayerEntityFeature.PLAY | MediaPlayerEntityFeature.STOP): supported_modes.append(FEATURE_PLAY_STOP) - if features & media_player.const.SUPPORT_VOLUME_MUTE: + if features & MediaPlayerEntityFeature.VOLUME_MUTE: supported_modes.append(FEATURE_TOGGLE_MUTE) return supported_modes @@ -568,5 +569,6 @@ def state_needs_accessory_mode(state: State) -> bool: state.domain == MEDIA_PLAYER_DOMAIN and state.attributes.get(ATTR_DEVICE_CLASS) == MediaPlayerDeviceClass.TV or state.domain == REMOTE_DOMAIN - and state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) & SUPPORT_ACTIVITY + and state.attributes.get(ATTR_SUPPORTED_FEATURES, 0) + & RemoteEntityFeature.ACTIVITY )