Use EntityFeature constants in homekit (#69535)

This commit is contained in:
epenet 2022-04-07 09:09:27 +02:00 committed by GitHub
parent 9834197f71
commit 71b298f3ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 70 additions and 74 deletions

View file

@ -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 (

View file

@ -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)

View file

@ -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:

View file

@ -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:

View file

@ -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,

View file

@ -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)

View file

@ -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(

View file

@ -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

View file

@ -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
)