mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 18:27:51 +00:00
Revert "Remove deprecated supported features warning in ..." (multiple) (#134933)
This commit is contained in:
parent
7a5525951d
commit
298f059488
@ -516,6 +516,19 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
"""Flag supported features."""
|
"""Flag supported features."""
|
||||||
return self._attr_supported_features
|
return self._attr_supported_features
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features_compat(self) -> CameraEntityFeature:
|
||||||
|
"""Return the supported features as CameraEntityFeature.
|
||||||
|
|
||||||
|
Remove this compatibility shim in 2025.1 or later.
|
||||||
|
"""
|
||||||
|
features = self.supported_features
|
||||||
|
if type(features) is int: # noqa: E721
|
||||||
|
new_features = CameraEntityFeature(features)
|
||||||
|
self._report_deprecated_supported_features_values(new_features)
|
||||||
|
return new_features
|
||||||
|
return features
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def is_recording(self) -> bool:
|
def is_recording(self) -> bool:
|
||||||
"""Return true if the device is recording."""
|
"""Return true if the device is recording."""
|
||||||
@ -569,7 +582,7 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
|
|
||||||
self._deprecate_attr_frontend_stream_type_logged = True
|
self._deprecate_attr_frontend_stream_type_logged = True
|
||||||
return self._attr_frontend_stream_type
|
return self._attr_frontend_stream_type
|
||||||
if CameraEntityFeature.STREAM not in self.supported_features:
|
if CameraEntityFeature.STREAM not in self.supported_features_compat:
|
||||||
return None
|
return None
|
||||||
if (
|
if (
|
||||||
self._webrtc_provider
|
self._webrtc_provider
|
||||||
@ -798,7 +811,9 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
async def async_internal_added_to_hass(self) -> None:
|
async def async_internal_added_to_hass(self) -> None:
|
||||||
"""Run when entity about to be added to hass."""
|
"""Run when entity about to be added to hass."""
|
||||||
await super().async_internal_added_to_hass()
|
await super().async_internal_added_to_hass()
|
||||||
self.__supports_stream = self.supported_features & CameraEntityFeature.STREAM
|
self.__supports_stream = (
|
||||||
|
self.supported_features_compat & CameraEntityFeature.STREAM
|
||||||
|
)
|
||||||
await self.async_refresh_providers(write_state=False)
|
await self.async_refresh_providers(write_state=False)
|
||||||
|
|
||||||
async def async_refresh_providers(self, *, write_state: bool = True) -> None:
|
async def async_refresh_providers(self, *, write_state: bool = True) -> None:
|
||||||
@ -838,7 +853,7 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
self, fn: Callable[[HomeAssistant, Camera], Coroutine[None, None, _T | None]]
|
self, fn: Callable[[HomeAssistant, Camera], Coroutine[None, None, _T | None]]
|
||||||
) -> _T | None:
|
) -> _T | None:
|
||||||
"""Get first provider that supports this camera."""
|
"""Get first provider that supports this camera."""
|
||||||
if CameraEntityFeature.STREAM not in self.supported_features:
|
if CameraEntityFeature.STREAM not in self.supported_features_compat:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return await fn(self.hass, self)
|
return await fn(self.hass, self)
|
||||||
@ -896,7 +911,7 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
def camera_capabilities(self) -> CameraCapabilities:
|
def camera_capabilities(self) -> CameraCapabilities:
|
||||||
"""Return the camera capabilities."""
|
"""Return the camera capabilities."""
|
||||||
frontend_stream_types = set()
|
frontend_stream_types = set()
|
||||||
if CameraEntityFeature.STREAM in self.supported_features:
|
if CameraEntityFeature.STREAM in self.supported_features_compat:
|
||||||
if self._supports_native_sync_webrtc or self._supports_native_async_webrtc:
|
if self._supports_native_sync_webrtc or self._supports_native_async_webrtc:
|
||||||
# The camera has a native WebRTC implementation
|
# The camera has a native WebRTC implementation
|
||||||
frontend_stream_types.add(StreamType.WEB_RTC)
|
frontend_stream_types.add(StreamType.WEB_RTC)
|
||||||
@ -916,7 +931,8 @@ class Camera(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
"""
|
"""
|
||||||
super().async_write_ha_state()
|
super().async_write_ha_state()
|
||||||
if self.__supports_stream != (
|
if self.__supports_stream != (
|
||||||
supports_stream := self.supported_features & CameraEntityFeature.STREAM
|
supports_stream := self.supported_features_compat
|
||||||
|
& CameraEntityFeature.STREAM
|
||||||
):
|
):
|
||||||
self.__supports_stream = supports_stream
|
self.__supports_stream = supports_stream
|
||||||
self._invalidate_camera_capabilities_cache()
|
self._invalidate_camera_capabilities_cache()
|
||||||
|
@ -300,6 +300,10 @@ class CoverEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
def supported_features(self) -> CoverEntityFeature:
|
def supported_features(self) -> CoverEntityFeature:
|
||||||
"""Flag supported features."""
|
"""Flag supported features."""
|
||||||
if (features := self._attr_supported_features) is not None:
|
if (features := self._attr_supported_features) is not None:
|
||||||
|
if type(features) is int: # noqa: E721
|
||||||
|
new_features = CoverEntityFeature(features)
|
||||||
|
self._report_deprecated_supported_features_values(new_features)
|
||||||
|
return new_features
|
||||||
return features
|
return features
|
||||||
|
|
||||||
supported_features = (
|
supported_features = (
|
||||||
|
@ -773,6 +773,19 @@ class MediaPlayerEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
"""Flag media player features that are supported."""
|
"""Flag media player features that are supported."""
|
||||||
return self._attr_supported_features
|
return self._attr_supported_features
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features_compat(self) -> MediaPlayerEntityFeature:
|
||||||
|
"""Return the supported features as MediaPlayerEntityFeature.
|
||||||
|
|
||||||
|
Remove this compatibility shim in 2025.1 or later.
|
||||||
|
"""
|
||||||
|
features = self.supported_features
|
||||||
|
if type(features) is int: # noqa: E721
|
||||||
|
new_features = MediaPlayerEntityFeature(features)
|
||||||
|
self._report_deprecated_supported_features_values(new_features)
|
||||||
|
return new_features
|
||||||
|
return features
|
||||||
|
|
||||||
def turn_on(self) -> None:
|
def turn_on(self) -> None:
|
||||||
"""Turn the media player on."""
|
"""Turn the media player on."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
@ -912,85 +925,87 @@ class MediaPlayerEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
@property
|
@property
|
||||||
def support_play(self) -> bool:
|
def support_play(self) -> bool:
|
||||||
"""Boolean if play is supported."""
|
"""Boolean if play is supported."""
|
||||||
return MediaPlayerEntityFeature.PLAY in self.supported_features
|
return MediaPlayerEntityFeature.PLAY in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_pause(self) -> bool:
|
def support_pause(self) -> bool:
|
||||||
"""Boolean if pause is supported."""
|
"""Boolean if pause is supported."""
|
||||||
return MediaPlayerEntityFeature.PAUSE in self.supported_features
|
return MediaPlayerEntityFeature.PAUSE in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_stop(self) -> bool:
|
def support_stop(self) -> bool:
|
||||||
"""Boolean if stop is supported."""
|
"""Boolean if stop is supported."""
|
||||||
return MediaPlayerEntityFeature.STOP in self.supported_features
|
return MediaPlayerEntityFeature.STOP in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_seek(self) -> bool:
|
def support_seek(self) -> bool:
|
||||||
"""Boolean if seek is supported."""
|
"""Boolean if seek is supported."""
|
||||||
return MediaPlayerEntityFeature.SEEK in self.supported_features
|
return MediaPlayerEntityFeature.SEEK in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_volume_set(self) -> bool:
|
def support_volume_set(self) -> bool:
|
||||||
"""Boolean if setting volume is supported."""
|
"""Boolean if setting volume is supported."""
|
||||||
return MediaPlayerEntityFeature.VOLUME_SET in self.supported_features
|
return MediaPlayerEntityFeature.VOLUME_SET in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_volume_mute(self) -> bool:
|
def support_volume_mute(self) -> bool:
|
||||||
"""Boolean if muting volume is supported."""
|
"""Boolean if muting volume is supported."""
|
||||||
return MediaPlayerEntityFeature.VOLUME_MUTE in self.supported_features
|
return MediaPlayerEntityFeature.VOLUME_MUTE in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_previous_track(self) -> bool:
|
def support_previous_track(self) -> bool:
|
||||||
"""Boolean if previous track command supported."""
|
"""Boolean if previous track command supported."""
|
||||||
return MediaPlayerEntityFeature.PREVIOUS_TRACK in self.supported_features
|
return MediaPlayerEntityFeature.PREVIOUS_TRACK in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_next_track(self) -> bool:
|
def support_next_track(self) -> bool:
|
||||||
"""Boolean if next track command supported."""
|
"""Boolean if next track command supported."""
|
||||||
return MediaPlayerEntityFeature.NEXT_TRACK in self.supported_features
|
return MediaPlayerEntityFeature.NEXT_TRACK in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_play_media(self) -> bool:
|
def support_play_media(self) -> bool:
|
||||||
"""Boolean if play media command supported."""
|
"""Boolean if play media command supported."""
|
||||||
return MediaPlayerEntityFeature.PLAY_MEDIA in self.supported_features
|
return MediaPlayerEntityFeature.PLAY_MEDIA in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_select_source(self) -> bool:
|
def support_select_source(self) -> bool:
|
||||||
"""Boolean if select source command supported."""
|
"""Boolean if select source command supported."""
|
||||||
return MediaPlayerEntityFeature.SELECT_SOURCE in self.supported_features
|
return MediaPlayerEntityFeature.SELECT_SOURCE in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_select_sound_mode(self) -> bool:
|
def support_select_sound_mode(self) -> bool:
|
||||||
"""Boolean if select sound mode command supported."""
|
"""Boolean if select sound mode command supported."""
|
||||||
return MediaPlayerEntityFeature.SELECT_SOUND_MODE in self.supported_features
|
return (
|
||||||
|
MediaPlayerEntityFeature.SELECT_SOUND_MODE in self.supported_features_compat
|
||||||
|
)
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_clear_playlist(self) -> bool:
|
def support_clear_playlist(self) -> bool:
|
||||||
"""Boolean if clear playlist command supported."""
|
"""Boolean if clear playlist command supported."""
|
||||||
return MediaPlayerEntityFeature.CLEAR_PLAYLIST in self.supported_features
|
return MediaPlayerEntityFeature.CLEAR_PLAYLIST in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_shuffle_set(self) -> bool:
|
def support_shuffle_set(self) -> bool:
|
||||||
"""Boolean if shuffle is supported."""
|
"""Boolean if shuffle is supported."""
|
||||||
return MediaPlayerEntityFeature.SHUFFLE_SET in self.supported_features
|
return MediaPlayerEntityFeature.SHUFFLE_SET in self.supported_features_compat
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def support_grouping(self) -> bool:
|
def support_grouping(self) -> bool:
|
||||||
"""Boolean if player grouping is supported."""
|
"""Boolean if player grouping is supported."""
|
||||||
return MediaPlayerEntityFeature.GROUPING in self.supported_features
|
return MediaPlayerEntityFeature.GROUPING in self.supported_features_compat
|
||||||
|
|
||||||
async def async_toggle(self) -> None:
|
async def async_toggle(self) -> None:
|
||||||
"""Toggle the power on the media player."""
|
"""Toggle the power on the media player."""
|
||||||
@ -1019,7 +1034,7 @@ class MediaPlayerEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
if (
|
if (
|
||||||
self.volume_level is not None
|
self.volume_level is not None
|
||||||
and self.volume_level < 1
|
and self.volume_level < 1
|
||||||
and MediaPlayerEntityFeature.VOLUME_SET in self.supported_features
|
and MediaPlayerEntityFeature.VOLUME_SET in self.supported_features_compat
|
||||||
):
|
):
|
||||||
await self.async_set_volume_level(
|
await self.async_set_volume_level(
|
||||||
min(1, self.volume_level + self.volume_step)
|
min(1, self.volume_level + self.volume_step)
|
||||||
@ -1037,7 +1052,7 @@ class MediaPlayerEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
if (
|
if (
|
||||||
self.volume_level is not None
|
self.volume_level is not None
|
||||||
and self.volume_level > 0
|
and self.volume_level > 0
|
||||||
and MediaPlayerEntityFeature.VOLUME_SET in self.supported_features
|
and MediaPlayerEntityFeature.VOLUME_SET in self.supported_features_compat
|
||||||
):
|
):
|
||||||
await self.async_set_volume_level(
|
await self.async_set_volume_level(
|
||||||
max(0, self.volume_level - self.volume_step)
|
max(0, self.volume_level - self.volume_step)
|
||||||
@ -1080,7 +1095,7 @@ class MediaPlayerEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
def capability_attributes(self) -> dict[str, Any]:
|
def capability_attributes(self) -> dict[str, Any]:
|
||||||
"""Return capability attributes."""
|
"""Return capability attributes."""
|
||||||
data: dict[str, Any] = {}
|
data: dict[str, Any] = {}
|
||||||
supported_features = self.supported_features
|
supported_features = self.supported_features_compat
|
||||||
|
|
||||||
if (
|
if (
|
||||||
source_list := self.source_list
|
source_list := self.source_list
|
||||||
@ -1286,7 +1301,7 @@ async def websocket_browse_media(
|
|||||||
connection.send_error(msg["id"], "entity_not_found", "Entity not found")
|
connection.send_error(msg["id"], "entity_not_found", "Entity not found")
|
||||||
return
|
return
|
||||||
|
|
||||||
if MediaPlayerEntityFeature.BROWSE_MEDIA not in player.supported_features:
|
if MediaPlayerEntityFeature.BROWSE_MEDIA not in player.supported_features_compat:
|
||||||
connection.send_message(
|
connection.send_message(
|
||||||
websocket_api.error_message(
|
websocket_api.error_message(
|
||||||
msg["id"], ERR_NOT_SUPPORTED, "Player does not support browsing media"
|
msg["id"], ERR_NOT_SUPPORTED, "Player does not support browsing media"
|
||||||
|
@ -312,7 +312,7 @@ class StateVacuumEntity(
|
|||||||
@property
|
@property
|
||||||
def capability_attributes(self) -> dict[str, Any] | None:
|
def capability_attributes(self) -> dict[str, Any] | None:
|
||||||
"""Return capability attributes."""
|
"""Return capability attributes."""
|
||||||
if VacuumEntityFeature.FAN_SPEED in self.supported_features:
|
if VacuumEntityFeature.FAN_SPEED in self.supported_features_compat:
|
||||||
return {ATTR_FAN_SPEED_LIST: self.fan_speed_list}
|
return {ATTR_FAN_SPEED_LIST: self.fan_speed_list}
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -330,7 +330,7 @@ class StateVacuumEntity(
|
|||||||
def state_attributes(self) -> dict[str, Any]:
|
def state_attributes(self) -> dict[str, Any]:
|
||||||
"""Return the state attributes of the vacuum cleaner."""
|
"""Return the state attributes of the vacuum cleaner."""
|
||||||
data: dict[str, Any] = {}
|
data: dict[str, Any] = {}
|
||||||
supported_features = self.supported_features
|
supported_features = self.supported_features_compat
|
||||||
|
|
||||||
if VacuumEntityFeature.BATTERY in supported_features:
|
if VacuumEntityFeature.BATTERY in supported_features:
|
||||||
data[ATTR_BATTERY_LEVEL] = self.battery_level
|
data[ATTR_BATTERY_LEVEL] = self.battery_level
|
||||||
@ -369,6 +369,19 @@ class StateVacuumEntity(
|
|||||||
"""Flag vacuum cleaner features that are supported."""
|
"""Flag vacuum cleaner features that are supported."""
|
||||||
return self._attr_supported_features
|
return self._attr_supported_features
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features_compat(self) -> VacuumEntityFeature:
|
||||||
|
"""Return the supported features as VacuumEntityFeature.
|
||||||
|
|
||||||
|
Remove this compatibility shim in 2025.1 or later.
|
||||||
|
"""
|
||||||
|
features = self.supported_features
|
||||||
|
if type(features) is int: # noqa: E721
|
||||||
|
new_features = VacuumEntityFeature(features)
|
||||||
|
self._report_deprecated_supported_features_values(new_features)
|
||||||
|
return new_features
|
||||||
|
return features
|
||||||
|
|
||||||
def stop(self, **kwargs: Any) -> None:
|
def stop(self, **kwargs: Any) -> None:
|
||||||
"""Stop the vacuum cleaner."""
|
"""Stop the vacuum cleaner."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -7,7 +7,7 @@ import asyncio
|
|||||||
from collections import deque
|
from collections import deque
|
||||||
from collections.abc import Callable, Coroutine, Iterable, Mapping
|
from collections.abc import Callable, Coroutine, Iterable, Mapping
|
||||||
import dataclasses
|
import dataclasses
|
||||||
from enum import Enum, auto
|
from enum import Enum, IntFlag, auto
|
||||||
import functools as ft
|
import functools as ft
|
||||||
import logging
|
import logging
|
||||||
import math
|
import math
|
||||||
@ -1639,6 +1639,31 @@ class Entity(
|
|||||||
self.hass, integration_domain=platform_name, module=type(self).__module__
|
self.hass, integration_domain=platform_name, module=type(self).__module__
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _report_deprecated_supported_features_values(
|
||||||
|
self, replacement: IntFlag
|
||||||
|
) -> None:
|
||||||
|
"""Report deprecated supported features values."""
|
||||||
|
if self._deprecated_supported_features_reported is True:
|
||||||
|
return
|
||||||
|
self._deprecated_supported_features_reported = True
|
||||||
|
report_issue = self._suggest_report_issue()
|
||||||
|
report_issue += (
|
||||||
|
" and reference "
|
||||||
|
"https://developers.home-assistant.io/blog/2023/12/28/support-feature-magic-numbers-deprecation"
|
||||||
|
)
|
||||||
|
_LOGGER.warning(
|
||||||
|
(
|
||||||
|
"Entity %s (%s) is using deprecated supported features"
|
||||||
|
" values which will be removed in HA Core 2025.1. Instead it should use"
|
||||||
|
" %s, please %s"
|
||||||
|
),
|
||||||
|
self.entity_id,
|
||||||
|
type(self),
|
||||||
|
repr(replacement),
|
||||||
|
report_issue,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ToggleEntityDescription(EntityDescription, frozen_or_thawed=True):
|
class ToggleEntityDescription(EntityDescription, frozen_or_thawed=True):
|
||||||
"""A class that describes toggle entities."""
|
"""A class that describes toggle entities."""
|
||||||
|
@ -826,6 +826,26 @@ def test_deprecated_state_constants(
|
|||||||
import_and_test_deprecated_constant_enum(caplog, module, enum, "STATE_", "2025.10")
|
import_and_test_deprecated_constant_enum(caplog, module, enum, "STATE_", "2025.10")
|
||||||
|
|
||||||
|
|
||||||
|
def test_deprecated_supported_features_ints(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
"""Test deprecated supported features ints."""
|
||||||
|
|
||||||
|
class MockCamera(camera.Camera):
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> int:
|
||||||
|
"""Return supported features."""
|
||||||
|
return 1
|
||||||
|
|
||||||
|
entity = MockCamera()
|
||||||
|
assert entity.supported_features_compat is camera.CameraEntityFeature(1)
|
||||||
|
assert "MockCamera" in caplog.text
|
||||||
|
assert "is using deprecated supported features values" in caplog.text
|
||||||
|
assert "Instead it should use" in caplog.text
|
||||||
|
assert "CameraEntityFeature.ON_OFF" in caplog.text
|
||||||
|
caplog.clear()
|
||||||
|
assert entity.supported_features_compat is camera.CameraEntityFeature(1)
|
||||||
|
assert "is using deprecated supported features values" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("mock_camera")
|
@pytest.mark.usefixtures("mock_camera")
|
||||||
async def test_entity_picture_url_changes_on_token_update(hass: HomeAssistant) -> None:
|
async def test_entity_picture_url_changes_on_token_update(hass: HomeAssistant) -> None:
|
||||||
"""Test the token is rotated and entity entity picture cache is cleared."""
|
"""Test the token is rotated and entity entity picture cache is cleared."""
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components import cover
|
from homeassistant.components import cover
|
||||||
from homeassistant.components.cover import CoverState
|
from homeassistant.components.cover import CoverState
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, CONF_PLATFORM, SERVICE_TOGGLE
|
from homeassistant.const import ATTR_ENTITY_ID, CONF_PLATFORM, SERVICE_TOGGLE
|
||||||
@ -153,3 +155,20 @@ def _create_tuples(enum: type[Enum], constant_prefix: str) -> list[tuple[Enum, s
|
|||||||
def test_all() -> None:
|
def test_all() -> None:
|
||||||
"""Test module.__all__ is correctly set."""
|
"""Test module.__all__ is correctly set."""
|
||||||
help_test_all(cover)
|
help_test_all(cover)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deprecated_supported_features_ints(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
"""Test deprecated supported features ints."""
|
||||||
|
|
||||||
|
class MockCoverEntity(cover.CoverEntity):
|
||||||
|
_attr_supported_features = 1
|
||||||
|
|
||||||
|
entity = MockCoverEntity()
|
||||||
|
assert entity.supported_features is cover.CoverEntityFeature(1)
|
||||||
|
assert "MockCoverEntity" in caplog.text
|
||||||
|
assert "is using deprecated supported features values" in caplog.text
|
||||||
|
assert "Instead it should use" in caplog.text
|
||||||
|
assert "CoverEntityFeature.OPEN" in caplog.text
|
||||||
|
caplog.clear()
|
||||||
|
assert entity.supported_features is cover.CoverEntityFeature(1)
|
||||||
|
assert "is using deprecated supported features values" not in caplog.text
|
||||||
|
@ -129,7 +129,7 @@ def test_support_properties(property_suffix: str) -> None:
|
|||||||
entity3 = MediaPlayerEntity()
|
entity3 = MediaPlayerEntity()
|
||||||
entity3._attr_supported_features = feature
|
entity3._attr_supported_features = feature
|
||||||
entity4 = MediaPlayerEntity()
|
entity4 = MediaPlayerEntity()
|
||||||
entity4._attr_supported_features = all_features & ~feature
|
entity4._attr_supported_features = all_features - feature
|
||||||
|
|
||||||
assert getattr(entity1, f"support_{property_suffix}") is False
|
assert getattr(entity1, f"support_{property_suffix}") is False
|
||||||
assert getattr(entity2, f"support_{property_suffix}") is True
|
assert getattr(entity2, f"support_{property_suffix}") is True
|
||||||
@ -447,3 +447,23 @@ async def test_get_async_get_browse_image_quoting(
|
|||||||
url = player.get_browse_image_url("album", media_content_id)
|
url = player.get_browse_image_url("album", media_content_id)
|
||||||
await client.get(url)
|
await client.get(url)
|
||||||
mock_browse_image.assert_called_with("album", media_content_id, None)
|
mock_browse_image.assert_called_with("album", media_content_id, None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deprecated_supported_features_ints(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
"""Test deprecated supported features ints."""
|
||||||
|
|
||||||
|
class MockMediaPlayerEntity(MediaPlayerEntity):
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> int:
|
||||||
|
"""Return supported features."""
|
||||||
|
return 1
|
||||||
|
|
||||||
|
entity = MockMediaPlayerEntity()
|
||||||
|
assert entity.supported_features_compat is MediaPlayerEntityFeature(1)
|
||||||
|
assert "MockMediaPlayerEntity" in caplog.text
|
||||||
|
assert "is using deprecated supported features values" in caplog.text
|
||||||
|
assert "Instead it should use" in caplog.text
|
||||||
|
assert "MediaPlayerEntityFeature.PAUSE" in caplog.text
|
||||||
|
caplog.clear()
|
||||||
|
assert entity.supported_features_compat is MediaPlayerEntityFeature(1)
|
||||||
|
assert "is using deprecated supported features values" not in caplog.text
|
||||||
|
@ -272,6 +272,42 @@ async def test_send_command(hass: HomeAssistant, config_flow_fixture: None) -> N
|
|||||||
assert "test" in strings
|
assert "test" in strings
|
||||||
|
|
||||||
|
|
||||||
|
async def test_supported_features_compat(hass: HomeAssistant) -> None:
|
||||||
|
"""Test StateVacuumEntity using deprecated feature constants features."""
|
||||||
|
|
||||||
|
features = (
|
||||||
|
VacuumEntityFeature.BATTERY
|
||||||
|
| VacuumEntityFeature.FAN_SPEED
|
||||||
|
| VacuumEntityFeature.START
|
||||||
|
| VacuumEntityFeature.STOP
|
||||||
|
| VacuumEntityFeature.PAUSE
|
||||||
|
)
|
||||||
|
|
||||||
|
class _LegacyConstantsStateVacuum(StateVacuumEntity):
|
||||||
|
_attr_supported_features = int(features)
|
||||||
|
_attr_fan_speed_list = ["silent", "normal", "pet hair"]
|
||||||
|
|
||||||
|
entity = _LegacyConstantsStateVacuum()
|
||||||
|
assert isinstance(entity.supported_features, int)
|
||||||
|
assert entity.supported_features == int(features)
|
||||||
|
assert entity.supported_features_compat is (
|
||||||
|
VacuumEntityFeature.BATTERY
|
||||||
|
| VacuumEntityFeature.FAN_SPEED
|
||||||
|
| VacuumEntityFeature.START
|
||||||
|
| VacuumEntityFeature.STOP
|
||||||
|
| VacuumEntityFeature.PAUSE
|
||||||
|
)
|
||||||
|
assert entity.state_attributes == {
|
||||||
|
"battery_level": None,
|
||||||
|
"battery_icon": "mdi:battery-unknown",
|
||||||
|
"fan_speed": None,
|
||||||
|
}
|
||||||
|
assert entity.capability_attributes == {
|
||||||
|
"fan_speed_list": ["silent", "normal", "pet hair"]
|
||||||
|
}
|
||||||
|
assert entity._deprecated_supported_features_reported
|
||||||
|
|
||||||
|
|
||||||
async def test_vacuum_not_log_deprecated_state_warning(
|
async def test_vacuum_not_log_deprecated_state_warning(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_vacuum_entity: MockVacuum,
|
mock_vacuum_entity: MockVacuum,
|
||||||
|
@ -4,6 +4,7 @@ import asyncio
|
|||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
import dataclasses
|
import dataclasses
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from enum import IntFlag
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@ -2485,6 +2486,31 @@ async def test_cached_entity_property_override(hass: HomeAssistant) -> None:
|
|||||||
return "🤡"
|
return "🤡"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_entity_report_deprecated_supported_features_values(
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
) -> None:
|
||||||
|
"""Test reporting deprecated supported feature values only happens once."""
|
||||||
|
ent = entity.Entity()
|
||||||
|
|
||||||
|
class MockEntityFeatures(IntFlag):
|
||||||
|
VALUE1 = 1
|
||||||
|
VALUE2 = 2
|
||||||
|
|
||||||
|
ent._report_deprecated_supported_features_values(MockEntityFeatures(2))
|
||||||
|
assert (
|
||||||
|
"is using deprecated supported features values which will be removed"
|
||||||
|
in caplog.text
|
||||||
|
)
|
||||||
|
assert "MockEntityFeatures.VALUE2" in caplog.text
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
|
ent._report_deprecated_supported_features_values(MockEntityFeatures(2))
|
||||||
|
assert (
|
||||||
|
"is using deprecated supported features values which will be removed"
|
||||||
|
not in caplog.text
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_remove_entity_registry(
|
async def test_remove_entity_registry(
|
||||||
hass: HomeAssistant, entity_registry: er.EntityRegistry
|
hass: HomeAssistant, entity_registry: er.EntityRegistry
|
||||||
) -> None:
|
) -> None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user