Update entity feature constants google_assistant (#98335)
* Update entity feature constants google_assistant * Update tests * Direct import * Some missed constants * Add fan and cover feature imports
This commit is contained in:
parent
fa6ffd994a
commit
e5f7d83912
3 changed files with 158 additions and 105 deletions
|
@ -28,8 +28,16 @@ from homeassistant.components import (
|
|||
switch,
|
||||
vacuum,
|
||||
)
|
||||
from homeassistant.components.alarm_control_panel import AlarmControlPanelEntityFeature
|
||||
from homeassistant.components.camera import CameraEntityFeature
|
||||
from homeassistant.components.climate import ClimateEntityFeature
|
||||
from homeassistant.components.cover import CoverEntityFeature
|
||||
from homeassistant.components.fan import FanEntityFeature
|
||||
from homeassistant.components.humidifier import HumidifierEntityFeature
|
||||
from homeassistant.components.light import LightEntityFeature
|
||||
from homeassistant.components.lock import STATE_JAMMED, STATE_UNLOCKING
|
||||
from homeassistant.components.media_player import MediaType
|
||||
from homeassistant.components.media_player import MediaPlayerEntityFeature, MediaType
|
||||
from homeassistant.components.vacuum import VacuumEntityFeature
|
||||
from homeassistant.const import (
|
||||
ATTR_ASSUMED_STATE,
|
||||
ATTR_BATTERY_LEVEL,
|
||||
|
@ -302,7 +310,7 @@ class CameraStreamTrait(_Trait):
|
|||
def supported(domain, features, device_class, _):
|
||||
"""Test if state is supported."""
|
||||
if domain == camera.DOMAIN:
|
||||
return features & camera.SUPPORT_STREAM
|
||||
return features & CameraEntityFeature.STREAM
|
||||
|
||||
return False
|
||||
|
||||
|
@ -612,7 +620,7 @@ class LocatorTrait(_Trait):
|
|||
@staticmethod
|
||||
def supported(domain, features, device_class, _):
|
||||
"""Test if state is supported."""
|
||||
return domain == vacuum.DOMAIN and features & vacuum.SUPPORT_LOCATE
|
||||
return domain == vacuum.DOMAIN and features & VacuumEntityFeature.LOCATE
|
||||
|
||||
def sync_attributes(self):
|
||||
"""Return locator attributes for a sync request."""
|
||||
|
@ -652,7 +660,7 @@ class EnergyStorageTrait(_Trait):
|
|||
@staticmethod
|
||||
def supported(domain, features, device_class, _):
|
||||
"""Test if state is supported."""
|
||||
return domain == vacuum.DOMAIN and features & vacuum.SUPPORT_BATTERY
|
||||
return domain == vacuum.DOMAIN and features & VacuumEntityFeature.BATTERY
|
||||
|
||||
def sync_attributes(self):
|
||||
"""Return EnergyStorage attributes for a sync request."""
|
||||
|
@ -710,7 +718,7 @@ class StartStopTrait(_Trait):
|
|||
if domain == vacuum.DOMAIN:
|
||||
return True
|
||||
|
||||
if domain == cover.DOMAIN and features & cover.SUPPORT_STOP:
|
||||
if domain == cover.DOMAIN and features & CoverEntityFeature.STOP:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
@ -721,7 +729,7 @@ class StartStopTrait(_Trait):
|
|||
if domain == vacuum.DOMAIN:
|
||||
return {
|
||||
"pausable": self.state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||
& vacuum.SUPPORT_PAUSE
|
||||
& VacuumEntityFeature.PAUSE
|
||||
!= 0
|
||||
}
|
||||
if domain == cover.DOMAIN:
|
||||
|
@ -991,7 +999,7 @@ class TemperatureSettingTrait(_Trait):
|
|||
response["thermostatHumidityAmbient"] = current_humidity
|
||||
|
||||
if operation in (climate.HVACMode.AUTO, climate.HVACMode.HEAT_COOL):
|
||||
if supported & climate.SUPPORT_TARGET_TEMPERATURE_RANGE:
|
||||
if supported & ClimateEntityFeature.TARGET_TEMPERATURE_RANGE:
|
||||
response["thermostatTemperatureSetpointHigh"] = round(
|
||||
TemperatureConverter.convert(
|
||||
attrs[climate.ATTR_TARGET_TEMP_HIGH],
|
||||
|
@ -1093,7 +1101,7 @@ class TemperatureSettingTrait(_Trait):
|
|||
supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)
|
||||
svc_data = {ATTR_ENTITY_ID: self.state.entity_id}
|
||||
|
||||
if supported & climate.SUPPORT_TARGET_TEMPERATURE_RANGE:
|
||||
if supported & ClimateEntityFeature.TARGET_TEMPERATURE_RANGE:
|
||||
svc_data[climate.ATTR_TARGET_TEMP_HIGH] = temp_high
|
||||
svc_data[climate.ATTR_TARGET_TEMP_LOW] = temp_low
|
||||
else:
|
||||
|
@ -1311,11 +1319,11 @@ class ArmDisArmTrait(_Trait):
|
|||
}
|
||||
|
||||
state_to_support = {
|
||||
STATE_ALARM_ARMED_HOME: alarm_control_panel.const.SUPPORT_ALARM_ARM_HOME,
|
||||
STATE_ALARM_ARMED_AWAY: alarm_control_panel.const.SUPPORT_ALARM_ARM_AWAY,
|
||||
STATE_ALARM_ARMED_NIGHT: alarm_control_panel.const.SUPPORT_ALARM_ARM_NIGHT,
|
||||
STATE_ALARM_ARMED_CUSTOM_BYPASS: alarm_control_panel.const.SUPPORT_ALARM_ARM_CUSTOM_BYPASS,
|
||||
STATE_ALARM_TRIGGERED: alarm_control_panel.const.SUPPORT_ALARM_TRIGGER,
|
||||
STATE_ALARM_ARMED_HOME: AlarmControlPanelEntityFeature.ARM_HOME,
|
||||
STATE_ALARM_ARMED_AWAY: AlarmControlPanelEntityFeature.ARM_AWAY,
|
||||
STATE_ALARM_ARMED_NIGHT: AlarmControlPanelEntityFeature.ARM_NIGHT,
|
||||
STATE_ALARM_ARMED_CUSTOM_BYPASS: AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS,
|
||||
STATE_ALARM_TRIGGERED: AlarmControlPanelEntityFeature.TRIGGER,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
@ -1454,9 +1462,9 @@ class FanSpeedTrait(_Trait):
|
|||
def supported(domain, features, device_class, _):
|
||||
"""Test if state is supported."""
|
||||
if domain == fan.DOMAIN:
|
||||
return features & fan.SUPPORT_SET_SPEED
|
||||
return features & FanEntityFeature.SET_SPEED
|
||||
if domain == climate.DOMAIN:
|
||||
return features & climate.SUPPORT_FAN_MODE
|
||||
return features & ClimateEntityFeature.FAN_MODE
|
||||
return False
|
||||
|
||||
def sync_attributes(self):
|
||||
|
@ -1468,7 +1476,7 @@ class FanSpeedTrait(_Trait):
|
|||
if domain == fan.DOMAIN:
|
||||
reversible = bool(
|
||||
self.state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||
& fan.SUPPORT_DIRECTION
|
||||
& FanEntityFeature.DIRECTION
|
||||
)
|
||||
|
||||
result.update(
|
||||
|
@ -1604,7 +1612,7 @@ class ModesTrait(_Trait):
|
|||
@staticmethod
|
||||
def supported(domain, features, device_class, _):
|
||||
"""Test if state is supported."""
|
||||
if domain == fan.DOMAIN and features & fan.SUPPORT_PRESET_MODE:
|
||||
if domain == fan.DOMAIN and features & FanEntityFeature.PRESET_MODE:
|
||||
return True
|
||||
|
||||
if domain == input_select.DOMAIN:
|
||||
|
@ -1613,16 +1621,16 @@ class ModesTrait(_Trait):
|
|||
if domain == select.DOMAIN:
|
||||
return True
|
||||
|
||||
if domain == humidifier.DOMAIN and features & humidifier.SUPPORT_MODES:
|
||||
if domain == humidifier.DOMAIN and features & HumidifierEntityFeature.MODES:
|
||||
return True
|
||||
|
||||
if domain == light.DOMAIN and features & light.SUPPORT_EFFECT:
|
||||
if domain == light.DOMAIN and features & LightEntityFeature.EFFECT:
|
||||
return True
|
||||
|
||||
if domain != media_player.DOMAIN:
|
||||
return False
|
||||
|
||||
return features & media_player.SUPPORT_SELECT_SOUND_MODE
|
||||
return features & MediaPlayerEntityFeature.SELECT_SOUND_MODE
|
||||
|
||||
def _generate(self, name, settings):
|
||||
"""Generate a list of modes."""
|
||||
|
@ -1812,7 +1820,7 @@ class InputSelectorTrait(_Trait):
|
|||
def supported(domain, features, device_class, _):
|
||||
"""Test if state is supported."""
|
||||
if domain == media_player.DOMAIN and (
|
||||
features & media_player.SUPPORT_SELECT_SOURCE
|
||||
features & MediaPlayerEntityFeature.SELECT_SOURCE
|
||||
):
|
||||
return True
|
||||
|
||||
|
@ -1910,13 +1918,13 @@ class OpenCloseTrait(_Trait):
|
|||
response["discreteOnlyOpenClose"] = True
|
||||
elif (
|
||||
self.state.domain == cover.DOMAIN
|
||||
and features & cover.SUPPORT_SET_POSITION == 0
|
||||
and features & CoverEntityFeature.SET_POSITION == 0
|
||||
):
|
||||
response["discreteOnlyOpenClose"] = True
|
||||
|
||||
if (
|
||||
features & cover.SUPPORT_OPEN == 0
|
||||
and features & cover.SUPPORT_CLOSE == 0
|
||||
features & CoverEntityFeature.OPEN == 0
|
||||
and features & CoverEntityFeature.CLOSE == 0
|
||||
):
|
||||
response["queryOnlyOpenClose"] = True
|
||||
|
||||
|
@ -1985,7 +1993,7 @@ class OpenCloseTrait(_Trait):
|
|||
elif position == 100:
|
||||
service = cover.SERVICE_OPEN_COVER
|
||||
should_verify = True
|
||||
elif features & cover.SUPPORT_SET_POSITION:
|
||||
elif features & CoverEntityFeature.SET_POSITION:
|
||||
service = cover.SERVICE_SET_COVER_POSITION
|
||||
if position > 0:
|
||||
should_verify = True
|
||||
|
@ -2026,7 +2034,8 @@ class VolumeTrait(_Trait):
|
|||
"""Test if trait is supported."""
|
||||
if domain == media_player.DOMAIN:
|
||||
return features & (
|
||||
media_player.SUPPORT_VOLUME_SET | media_player.SUPPORT_VOLUME_STEP
|
||||
MediaPlayerEntityFeature.VOLUME_SET
|
||||
| MediaPlayerEntityFeature.VOLUME_STEP
|
||||
)
|
||||
|
||||
return False
|
||||
|
@ -2035,7 +2044,9 @@ class VolumeTrait(_Trait):
|
|||
"""Return volume attributes for a sync request."""
|
||||
features = self.state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||
return {
|
||||
"volumeCanMuteAndUnmute": bool(features & media_player.SUPPORT_VOLUME_MUTE),
|
||||
"volumeCanMuteAndUnmute": bool(
|
||||
features & MediaPlayerEntityFeature.VOLUME_MUTE
|
||||
),
|
||||
"commandOnlyVolume": self.state.attributes.get(ATTR_ASSUMED_STATE, False),
|
||||
# Volume amounts in SET_VOLUME and VOLUME_RELATIVE are on a scale
|
||||
# from 0 to this value.
|
||||
|
@ -2078,7 +2089,7 @@ class VolumeTrait(_Trait):
|
|||
|
||||
if not (
|
||||
self.state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||
& media_player.SUPPORT_VOLUME_SET
|
||||
& MediaPlayerEntityFeature.VOLUME_SET
|
||||
):
|
||||
raise SmartHomeError(ERR_NOT_SUPPORTED, "Command not supported")
|
||||
|
||||
|
@ -2088,13 +2099,13 @@ class VolumeTrait(_Trait):
|
|||
relative = params["relativeSteps"]
|
||||
features = self.state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||
|
||||
if features & media_player.SUPPORT_VOLUME_SET:
|
||||
if features & MediaPlayerEntityFeature.VOLUME_SET:
|
||||
current = self.state.attributes.get(media_player.ATTR_MEDIA_VOLUME_LEVEL)
|
||||
target = max(0.0, min(1.0, current + relative / 100))
|
||||
|
||||
await self._set_volume_absolute(data, target)
|
||||
|
||||
elif features & media_player.SUPPORT_VOLUME_STEP:
|
||||
elif features & MediaPlayerEntityFeature.VOLUME_STEP:
|
||||
svc = media_player.SERVICE_VOLUME_UP
|
||||
if relative < 0:
|
||||
svc = media_player.SERVICE_VOLUME_DOWN
|
||||
|
@ -2116,7 +2127,7 @@ class VolumeTrait(_Trait):
|
|||
|
||||
if not (
|
||||
self.state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||
& media_player.SUPPORT_VOLUME_MUTE
|
||||
& MediaPlayerEntityFeature.VOLUME_MUTE
|
||||
):
|
||||
raise SmartHomeError(ERR_NOT_SUPPORTED, "Command not supported")
|
||||
|
||||
|
@ -2158,14 +2169,14 @@ def _verify_pin_challenge(data, state, challenge):
|
|||
|
||||
|
||||
MEDIA_COMMAND_SUPPORT_MAPPING = {
|
||||
COMMAND_MEDIA_NEXT: media_player.SUPPORT_NEXT_TRACK,
|
||||
COMMAND_MEDIA_PAUSE: media_player.SUPPORT_PAUSE,
|
||||
COMMAND_MEDIA_PREVIOUS: media_player.SUPPORT_PREVIOUS_TRACK,
|
||||
COMMAND_MEDIA_RESUME: media_player.SUPPORT_PLAY,
|
||||
COMMAND_MEDIA_SEEK_RELATIVE: media_player.SUPPORT_SEEK,
|
||||
COMMAND_MEDIA_SEEK_TO_POSITION: media_player.SUPPORT_SEEK,
|
||||
COMMAND_MEDIA_SHUFFLE: media_player.SUPPORT_SHUFFLE_SET,
|
||||
COMMAND_MEDIA_STOP: media_player.SUPPORT_STOP,
|
||||
COMMAND_MEDIA_NEXT: MediaPlayerEntityFeature.NEXT_TRACK,
|
||||
COMMAND_MEDIA_PAUSE: MediaPlayerEntityFeature.PAUSE,
|
||||
COMMAND_MEDIA_PREVIOUS: MediaPlayerEntityFeature.PREVIOUS_TRACK,
|
||||
COMMAND_MEDIA_RESUME: MediaPlayerEntityFeature.PLAY,
|
||||
COMMAND_MEDIA_SEEK_RELATIVE: MediaPlayerEntityFeature.SEEK,
|
||||
COMMAND_MEDIA_SEEK_TO_POSITION: MediaPlayerEntityFeature.SEEK,
|
||||
COMMAND_MEDIA_SHUFFLE: MediaPlayerEntityFeature.SHUFFLE_SET,
|
||||
COMMAND_MEDIA_STOP: MediaPlayerEntityFeature.STOP,
|
||||
}
|
||||
|
||||
MEDIA_COMMAND_ATTRIBUTES = {
|
||||
|
@ -2350,7 +2361,7 @@ class ChannelTrait(_Trait):
|
|||
"""Test if state is supported."""
|
||||
if (
|
||||
domain == media_player.DOMAIN
|
||||
and (features & media_player.SUPPORT_PLAY_MEDIA)
|
||||
and (features & MediaPlayerEntityFeature.PLAY_MEDIA)
|
||||
and device_class == media_player.MediaPlayerDeviceClass.TV
|
||||
):
|
||||
return True
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue