Use EntityFeature constants in homekit (#69535)
This commit is contained in:
parent
9834197f71
commit
71b298f3ed
9 changed files with 70 additions and 74 deletions
|
@ -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 (
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue