Compare commits

..

51 Commits

Author SHA1 Message Date
Franck Nijhof 4eddbe7b47 2024.1.2 (#107365) 2024-01-06 13:17:47 +01:00
Franck Nijhof cab833160d Bump version to 2024.1.2 2024-01-06 12:25:05 +01:00
David F. Mulcahey 003d2be477 Fix assertion error when unloading ZHA with pollable entities (#107311) 2024-01-06 12:24:35 +01:00
Sid 5a01b55fd1 enigma2: fix exception when device in deep sleep, fix previous track (#107296)
enigma2: fix exception when device in deep sleep; previous track
2024-01-06 12:24:32 +01:00
Shay Levy 0dbb4105bc Fix Shelly missing Gen value for older devices (#107294) 2024-01-06 12:24:29 +01:00
Joost Lekkerkerker 5ff6284e0f Fix passing correct location id to streamlabs water (#107291) 2024-01-06 12:24:25 +01:00
Aidan Timson 97674cee88 Fix support for play/pause functionality in System Bridge (#103423)
Fix support for play/pause functionality
2024-01-06 12:24:21 +01:00
Franck Nijhof 24a8a512d6 2024.1.1 (#107239) 2024-01-05 16:25:49 +01:00
Franck Nijhof 658f1cf5c5 Bump version to 2024.1.1 2024-01-05 13:01:35 +01:00
Raman Gupta d012817190 Bump zwave-js-server-python to 0.55.3 (#107225)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-01-05 13:01:06 +01:00
Joakim Sørensen 056701d218 Use supported_features_compat in update.install service (#107224) 2024-01-05 13:01:03 +01:00
Petru Paler c3963b26e7 Fix entity property cache creation arguments (#107221) 2024-01-05 13:00:59 +01:00
tronikos 4ade5e46d9 Disable IPv6 in the opower integration to fix AEP utilities (#107203) 2024-01-05 13:00:55 +01:00
Brett Adams c242dcd1f2 Hotfix cache logic bug in Tessie (#107187) 2024-01-05 13:00:52 +01:00
Michael 4e126d68b7 Fix switch states in AVM FRITZ!Box Tools (#107183) 2024-01-05 13:00:49 +01:00
Erwin Douna d7e1a4fa20 Bump to PyTado 0.17.3 (#107181) 2024-01-05 13:00:46 +01:00
J. Nick Koston 3215dfee6d Bump aiohomekit to 3.1.2 (#107177) 2024-01-05 13:00:43 +01:00
Matt Emerick-Law c78d691d30 Bump Orvibo to 1.1.2 (#107162)
* Bump python-orvibo version

Fixes https://github.com/home-assistant/core/issues/106923

* Add version number

* Remove version

* Bump python-orvibo version
2024-01-05 13:00:39 +01:00
Bram Kragten 04bf569308 Update frontend to 20240104.0 (#107155) 2024-01-05 13:00:36 +01:00
Erik Montnemery b8576b8091 Include deprecated constants in wildcard imports (#107114) 2024-01-05 13:00:33 +01:00
J. Nick Koston a7aa5c0e52 Bump habluetooth to 2.0.2 (#107097) 2024-01-05 13:00:29 +01:00
J. Nick Koston d600b76801 Fix missing backwards compatibility layer for water_heater supported_features (#107091) 2024-01-05 13:00:26 +01:00
Erik Montnemery c56d118e8b Deduplicate handling of duplicated constants (#107074)
* Deduplicate handling of duplicated constants

* Use DeprecatedConstant + DeprecatedConstantEnum

* Fixup

* Remove test cases with unnamed tuples
2024-01-05 13:00:23 +01:00
Robert Resch 80b45edb2e Fix mobile_app cloudhook creation (#107068) 2024-01-05 13:00:20 +01:00
Joost Lekkerkerker 5529a85a2b Fix data access in streamlabs water (#107062)
* Fix data access in streamlabs water

* Fix data access in streamlabs water
2024-01-05 13:00:17 +01:00
Joost Lekkerkerker e2acc70128 Use async_register in streamlabswater (#107060) 2024-01-05 13:00:14 +01:00
J. Nick Koston 427077a4c9 Fix missing backwards compatiblity layer for humidifier supported_features (#107026)
fixes #107018
2024-01-05 13:00:10 +01:00
Maciej Bieniek 8c9875c3cc Get Shelly RPC device gen from config entry data (#107019)
Use gen from config entry data
2024-01-05 13:00:07 +01:00
Sid ce5455fefc Bump openwebifpy to 4.0.4 (#107000) 2024-01-05 13:00:04 +01:00
Ståle Storø Hauknes aef129afaf Close stale connections (Airthings BLE) (#106748)
Co-authored-by: J. Nick Koston <nick@koston.org>
2024-01-05 13:00:01 +01:00
Sid 1c94a94ba2 bump openwebifpy to 4.0.3 (#106593) 2024-01-05 12:59:56 +01:00
Patrick Frazer d87baba96f Bump dropmqttapi to 1.0.2 (#106978) 2024-01-05 12:57:58 +01:00
Joe Neuman 5a0997bac0 Fix qBittorrent torrent count when empty (#106903)
* Fix qbittorrent torrent cound when empty

* lint fix

* Change based on comment
2024-01-05 12:57:55 +01:00
Marc Mueller e70af204ee Enable strict typing for airthings_ble (#106815) 2024-01-05 12:57:50 +01:00
Franck Nijhof fb0cc6c5d0 2024.1.0 (#106970) 2024-01-03 18:15:49 +01:00
Franck Nijhof 15cecbd4a4 Bump version to 2024.1.0 2024-01-03 17:13:22 +01:00
Franck Nijhof 8cf47c4925 Bump version to 2024.1.0b8 2024-01-03 15:29:59 +01:00
Bram Kragten cd8d95a04d Update frontend to 20240103.3 (#106963) 2024-01-03 15:29:51 +01:00
Jonas Fors Lellky 015752ff11 Set precision to halves in flexit_bacnet (#106959)
flexit_bacnet: set precision to halves for target temperature
2024-01-03 15:29:48 +01:00
jan iversen 9d697c5026 Only set precision in modbus if not configured. (#106952)
Only set precision if not configured.
2024-01-03 15:29:42 +01:00
Bram Kragten 4595c3edaa Update frontend to 20240103.1 (#106948) 2024-01-03 15:29:38 +01:00
Robert Resch e745542431 Fix creating cloud hook twice for mobile_app (#106945) 2024-01-03 15:29:33 +01:00
Franck Nijhof 2be72fd891 Bump version to 2024.1.0b7 2024-01-03 11:35:43 +01:00
Bram Kragten 2b43f5fcda Update frontend to 20240103.0 (#106942) 2024-01-03 11:35:35 +01:00
Erwin Douna 3295722e70 Change Tado deprecation version to 2024.7.0 (#106938)
Change version to 2024.7.0
2024-01-03 11:35:30 +01:00
Franck Nijhof f98bbf88b1 Bump version to 2024.1.0b6 2024-01-03 09:56:28 +01:00
Michael 0226b3f10c Remove group_members from significant attributes in media player (#106916) 2024-01-03 09:55:55 +01:00
Jan-Philipp Benecke 5986967db7 Avoid triggering ping device tracker home after restore (#106913) 2024-01-03 09:55:52 +01:00
Michael Hansen 95ef2dd7f9 Bump intents to 2024.1.2 (#106909) 2024-01-03 09:55:49 +01:00
Erwin Douna 527d9fbb6b Add try-catch for invalid auth to Tado (#106774)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2024-01-03 09:55:45 +01:00
Michael 5eb1073b4a Apply late review comments on media player (#106727) 2024-01-03 09:55:41 +01:00
109 changed files with 1111 additions and 546 deletions
+1
View File
@@ -49,6 +49,7 @@ homeassistant.components.aftership.*
homeassistant.components.air_quality.*
homeassistant.components.airly.*
homeassistant.components.airnow.*
homeassistant.components.airthings_ble.*
homeassistant.components.airvisual.*
homeassistant.components.airvisual_pro.*
homeassistant.components.airzone.*
@@ -4,7 +4,8 @@ from __future__ import annotations
from datetime import timedelta
import logging
from airthings_ble import AirthingsBluetoothDeviceData
from airthings_ble import AirthingsBluetoothDeviceData, AirthingsDevice
from bleak_retry_connector import close_stale_connections_by_address
from homeassistant.components import bluetooth
from homeassistant.config_entries import ConfigEntry
@@ -30,6 +31,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
is_metric = hass.config.units is METRIC_SYSTEM
assert address is not None
await close_stale_connections_by_address(address)
ble_device = bluetooth.async_ble_device_from_address(hass, address)
if not ble_device:
@@ -37,13 +40,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
f"Could not find Airthings device with address {address}"
)
async def _async_update_method():
async def _async_update_method() -> AirthingsDevice:
"""Get data from Airthings BLE."""
ble_device = bluetooth.async_ble_device_from_address(hass, address)
airthings = AirthingsBluetoothDeviceData(_LOGGER, elevation, is_metric)
try:
data = await airthings.update_device(ble_device)
data = await airthings.update_device(ble_device) # type: ignore[arg-type]
except Exception as err:
raise UpdateFailed(f"Unable to fetch data: {err}") from err
@@ -24,6 +24,7 @@ from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.config_validation import make_entity_service_schema
from homeassistant.helpers.deprecation import (
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -52,12 +53,6 @@ if TYPE_CHECKING:
else:
from homeassistant.backports.functools import cached_property
# As we import constants of the cost module here, we need to add the following
# functions to check for deprecated constants again
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
_LOGGER: Final = logging.getLogger(__name__)
SCAN_INTERVAL: Final = timedelta(seconds=30)
@@ -249,3 +244,13 @@ class AlarmControlPanelEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_A
ATTR_CHANGED_BY: self.changed_by,
ATTR_CODE_ARM_REQUIRED: self.code_arm_required,
}
# As we import constants of the const module here, we need to add the following
# functions to check for deprecated constants again
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -5,6 +5,7 @@ from typing import Final
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -60,10 +61,6 @@ _DEPRECATED_SUPPORT_ALARM_ARM_VACATION: Final = DeprecatedConstantEnum(
AlarmControlPanelEntityFeature.ARM_VACATION, "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
CONDITION_TRIGGERED: Final = "is_triggered"
CONDITION_DISARMED: Final = "is_disarmed"
CONDITION_ARMED_HOME: Final = "is_armed_home"
@@ -71,3 +68,10 @@ CONDITION_ARMED_AWAY: Final = "is_armed_away"
CONDITION_ARMED_NIGHT: Final = "is_armed_night"
CONDITION_ARMED_VACATION: Final = "is_armed_vacation"
CONDITION_ARMED_CUSTOM_BYPASS: Final = "is_armed_custom_bypass"
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -58,6 +58,7 @@ from homeassistant.helpers import condition
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import (
DeprecatedConstant,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -147,10 +148,6 @@ _DEPRECATED_AutomationTriggerInfo = DeprecatedConstant(
TriggerInfo, "TriggerInfo", "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
@bind_hass
def is_on(hass: HomeAssistant, entity_id: str) -> bool:
@@ -1108,3 +1105,11 @@ def websocket_config(
"config": automation.raw_config,
},
)
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -19,6 +19,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
)
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -218,10 +219,6 @@ _DEPRECATED_DEVICE_CLASS_WINDOW = DeprecatedConstantEnum(
BinarySensorDeviceClass.WINDOW, "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
# mypy: disallow-any-generics
@@ -303,3 +300,11 @@ class BinarySensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_)
if (is_on := self.is_on) is None:
return None
return STATE_ON if is_on else STATE_OFF
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -20,6 +20,6 @@
"bluetooth-auto-recovery==1.2.3",
"bluetooth-data-tools==1.19.0",
"dbus-fast==2.21.0",
"habluetooth==2.0.1"
"habluetooth==2.0.2"
]
}
+9 -4
View File
@@ -54,6 +54,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
)
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -123,10 +124,6 @@ _DEPRECATED_SUPPORT_STREAM: Final = DeprecatedConstantEnum(
CameraEntityFeature.STREAM, "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
RTSP_PREFIXES = {"rtsp://", "rtsps://", "rtmp://"}
DEFAULT_CONTENT_TYPE: Final = "image/jpeg"
@@ -1082,3 +1079,11 @@ async def async_handle_record_service(
duration=service_call.data[CONF_DURATION],
lookback=service_call.data[CONF_LOOKBACK],
)
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+6 -2
View File
@@ -5,6 +5,7 @@ from typing import Final
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -47,6 +48,9 @@ _DEPRECATED_STREAM_TYPE_HLS = DeprecatedConstantEnum(StreamType.HLS, "2025.1")
_DEPRECATED_STREAM_TYPE_WEB_RTC = DeprecatedConstantEnum(StreamType.WEB_RTC, "2025.1")
# Both can be removed if no deprecated constant are in this module anymore
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+11 -6
View File
@@ -28,6 +28,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
make_entity_service_schema,
)
from homeassistant.helpers.deprecation import (
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -141,12 +142,6 @@ SET_TEMPERATURE_SCHEMA = vol.All(
),
)
# As we import deprecated constants from the const module, we need to add these two functions
# otherwise this module will be logged for using deprecated constants and not the custom component
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(dir_with_deprecated_constants, module_globals=globals())
# mypy: disallow-any-generics
@@ -734,3 +729,13 @@ async def async_service_temperature_set(
kwargs[value] = temp
await entity.async_set_temperature(**kwargs)
# As we import deprecated constants from the const module, we need to add these two functions
# otherwise this module will be logged for using deprecated constants and not the custom component
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+6 -2
View File
@@ -5,6 +5,7 @@ from functools import partial
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -188,6 +189,9 @@ _DEPRECATED_SUPPORT_AUX_HEAT = DeprecatedConstantEnum(
ClimateEntityFeature.AUX_HEAT, "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -5,6 +5,7 @@ import asyncio
from collections.abc import Awaitable, Callable
from datetime import datetime, timedelta
from enum import Enum
from typing import cast
from hass_nabucasa import Cloud
import voluptuous as vol
@@ -176,6 +177,22 @@ def async_active_subscription(hass: HomeAssistant) -> bool:
return async_is_logged_in(hass) and not hass.data[DOMAIN].subscription_expired
async def async_get_or_create_cloudhook(hass: HomeAssistant, webhook_id: str) -> str:
"""Get or create a cloudhook."""
if not async_is_connected(hass):
raise CloudNotConnected
if not async_is_logged_in(hass):
raise CloudNotAvailable
cloud: Cloud[CloudClient] = hass.data[DOMAIN]
cloudhooks = cloud.client.cloudhooks
if hook := cloudhooks.get(webhook_id):
return cast(str, hook["cloudhook_url"])
return await async_create_cloudhook(hass, webhook_id)
@bind_hass
async def async_create_cloudhook(hass: HomeAssistant, webhook_id: str) -> str:
"""Create a cloudhook."""
@@ -7,5 +7,5 @@
"integration_type": "system",
"iot_class": "local_push",
"quality_scale": "internal",
"requirements": ["hassil==1.5.1", "home-assistant-intents==2023.12.05"]
"requirements": ["hassil==1.5.1", "home-assistant-intents==2024.1.2"]
}
+9 -4
View File
@@ -34,6 +34,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
)
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -143,10 +144,6 @@ _DEPRECATED_SUPPORT_SET_TILT_POSITION = DeprecatedConstantEnum(
CoverEntityFeature.SET_TILT_POSITION, "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(dir_with_deprecated_constants, module_globals=globals())
ATTR_CURRENT_POSITION = "current_position"
ATTR_CURRENT_TILT_POSITION = "current_tilt_position"
ATTR_POSITION = "position"
@@ -493,3 +490,11 @@ class CoverEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
if self._cover_is_last_toggle_direction_open:
return fns["close"]
return fns["open"]
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -6,6 +6,7 @@ from functools import partial
from homeassistant.const import ATTR_GPS_ACCURACY, STATE_HOME # noqa: F401
from homeassistant.core import HomeAssistant
from homeassistant.helpers.deprecation import (
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -57,12 +58,6 @@ from .legacy import ( # noqa: F401
see,
)
# As we import deprecated constants from the const module, we need to add these two functions
# otherwise this module will be logged for using deprecated constants and not the custom component
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
@bind_hass
def is_on(hass: HomeAssistant, entity_id: str) -> bool:
@@ -83,3 +78,13 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
await async_setup_legacy_integration(hass, config)
return True
# As we import deprecated constants from the const module, we need to add these two functions
# otherwise this module will be logged for using deprecated constants and not the custom component
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -9,6 +9,7 @@ from typing import Final
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -44,10 +45,6 @@ _DEPRECATED_SOURCE_TYPE_BLUETOOTH_LE: Final = DeprecatedConstantEnum(
SourceType.BLUETOOTH_LE, "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
CONF_SCAN_INTERVAL: Final = "interval_seconds"
SCAN_INTERVAL: Final = timedelta(seconds=12)
@@ -71,3 +68,10 @@ ATTR_CONSIDER_HOME: Final = "consider_home"
ATTR_IP: Final = "ip"
CONNECTED_DEVICE_REGISTERED: Final = "device_tracker_connected_device_registered"
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -7,5 +7,5 @@
"documentation": "https://www.home-assistant.io/integrations/drop_connect",
"iot_class": "local_push",
"mqtt": ["drop_connect/discovery/#"],
"requirements": ["dropmqttapi==1.0.1"]
"requirements": ["dropmqttapi==1.0.2"]
}
@@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/enigma2",
"iot_class": "local_polling",
"loggers": ["openwebif"],
"requirements": ["openwebifpy==4.0.2"]
"requirements": ["openwebifpy==4.0.4"]
}
@@ -1,6 +1,7 @@
"""Support for Enigma2 media players."""
from __future__ import annotations
from aiohttp.client_exceptions import ClientConnectorError
from openwebif.api import OpenWebIfDevice
from openwebif.enums import RemoteControlCodes
import voluptuous as vol
@@ -20,6 +21,7 @@ from homeassistant.const import (
CONF_USERNAME,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import PlatformNotReady
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@@ -96,9 +98,13 @@ async def async_setup_platform(
source_bouquet=config.get(CONF_SOURCE_BOUQUET),
)
async_add_entities(
[Enigma2Device(config[CONF_NAME], device, await device.get_about())]
)
try:
about = await device.get_about()
except ClientConnectorError as err:
await device.close()
raise PlatformNotReady from err
async_add_entities([Enigma2Device(config[CONF_NAME], device, about)])
class Enigma2Device(MediaPlayerEntity):
@@ -169,8 +175,8 @@ class Enigma2Device(MediaPlayerEntity):
await self._device.send_remote_control_action(RemoteControlCodes.CHANNEL_UP)
async def async_media_previous_track(self) -> None:
"""Send next track command."""
self._device.send_remote_control_action(RemoteControlCodes.CHANNEL_DOWN)
"""Send previous track command."""
await self._device.send_remote_control_action(RemoteControlCodes.CHANNEL_DOWN)
async def async_mute_volume(self, mute: bool) -> None:
"""Mute or unmute."""
+9 -4
View File
@@ -26,6 +26,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
)
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -76,10 +77,6 @@ _DEPRECATED_SUPPORT_PRESET_MODE = DeprecatedConstantEnum(
FanEntityFeature.PRESET_MODE, "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(dir_with_deprecated_constants, module_globals=globals())
SERVICE_INCREASE_SPEED = "increase_speed"
SERVICE_DECREASE_SPEED = "decrease_speed"
SERVICE_OSCILLATE = "oscillate"
@@ -471,3 +468,11 @@ class FanEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
if hasattr(self, "_attr_preset_modes"):
return self._attr_preset_modes
return None
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -19,7 +19,7 @@ from homeassistant.components.climate import (
HVACMode,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, UnitOfTemperature
from homeassistant.const import ATTR_TEMPERATURE, PRECISION_HALVES, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import DeviceInfo
@@ -65,7 +65,7 @@ class FlexitClimateEntity(ClimateEntity):
ClimateEntityFeature.PRESET_MODE | ClimateEntityFeature.TARGET_TEMPERATURE
)
_attr_target_temperature_step = PRECISION_WHOLE
_attr_target_temperature_step = PRECISION_HALVES
_attr_temperature_unit = UnitOfTemperature.CELSIUS
def __init__(self, device: FlexitBACnet) -> None:
+1
View File
@@ -1063,6 +1063,7 @@ class SwitchInfo(TypedDict):
type: str
callback_update: Callable
callback_switch: Callable
init_state: bool
class FritzBoxBaseEntity:
+10 -11
View File
@@ -166,9 +166,7 @@ async def _async_wifi_entities_list(
_LOGGER.debug("WiFi networks list: %s", networks)
return [
FritzBoxWifiSwitch(
avm_wrapper, device_friendly_name, index, data["switch_name"]
)
FritzBoxWifiSwitch(avm_wrapper, device_friendly_name, index, data)
for index, data in networks.items()
]
@@ -310,18 +308,16 @@ class FritzBoxBaseCoordinatorSwitch(CoordinatorEntity[AvmWrapper], SwitchEntity)
await self._async_handle_turn_on_off(turn_on=False)
class FritzBoxBaseSwitch(FritzBoxBaseEntity):
class FritzBoxBaseSwitch(FritzBoxBaseEntity, SwitchEntity):
"""Fritz switch base class."""
_attr_is_on: bool | None = False
def __init__(
self,
avm_wrapper: AvmWrapper,
device_friendly_name: str,
switch_info: SwitchInfo,
) -> None:
"""Init Fritzbox port switch."""
"""Init Fritzbox base switch."""
super().__init__(avm_wrapper, device_friendly_name)
self._description = switch_info["description"]
@@ -330,6 +326,7 @@ class FritzBoxBaseSwitch(FritzBoxBaseEntity):
self._type = switch_info["type"]
self._update = switch_info["callback_update"]
self._switch = switch_info["callback_switch"]
self._attr_is_on = switch_info["init_state"]
self._name = f"{self._friendly_name} {self._description}"
self._unique_id = f"{self._avm_wrapper.unique_id}-{slugify(self._description)}"
@@ -381,7 +378,7 @@ class FritzBoxBaseSwitch(FritzBoxBaseEntity):
self._attr_is_on = turn_on
class FritzBoxPortSwitch(FritzBoxBaseSwitch, SwitchEntity):
class FritzBoxPortSwitch(FritzBoxBaseSwitch):
"""Defines a FRITZ!Box Tools PortForward switch."""
def __init__(
@@ -412,6 +409,7 @@ class FritzBoxPortSwitch(FritzBoxBaseSwitch, SwitchEntity):
type=SWITCH_TYPE_PORTFORWARD,
callback_update=self._async_fetch_update,
callback_switch=self._async_switch_on_off_executor,
init_state=port_mapping["NewEnabled"],
)
super().__init__(avm_wrapper, device_friendly_name, switch_info)
@@ -553,7 +551,7 @@ class FritzBoxProfileSwitch(FritzDeviceBase, SwitchEntity):
return True
class FritzBoxWifiSwitch(FritzBoxBaseSwitch, SwitchEntity):
class FritzBoxWifiSwitch(FritzBoxBaseSwitch):
"""Defines a FRITZ!Box Tools Wifi switch."""
def __init__(
@@ -561,7 +559,7 @@ class FritzBoxWifiSwitch(FritzBoxBaseSwitch, SwitchEntity):
avm_wrapper: AvmWrapper,
device_friendly_name: str,
network_num: int,
network_name: str,
network_data: dict,
) -> None:
"""Init Fritz Wifi switch."""
self._avm_wrapper = avm_wrapper
@@ -571,12 +569,13 @@ class FritzBoxWifiSwitch(FritzBoxBaseSwitch, SwitchEntity):
self._network_num = network_num
switch_info = SwitchInfo(
description=f"Wi-Fi {network_name}",
description=f"Wi-Fi {network_data['switch_name']}",
friendly_name=device_friendly_name,
icon="mdi:wifi",
type=SWITCH_TYPE_WIFINETWORK,
callback_update=self._async_fetch_update,
callback_switch=self._async_switch_on_off_executor,
init_state=network_data["enabled"],
)
super().__init__(self._avm_wrapper, device_friendly_name, switch_info)
@@ -20,5 +20,5 @@
"documentation": "https://www.home-assistant.io/integrations/frontend",
"integration_type": "system",
"quality_scale": "internal",
"requirements": ["home-assistant-frontend==20240102.0"]
"requirements": ["home-assistant-frontend==20240104.0"]
}
@@ -14,6 +14,6 @@
"documentation": "https://www.home-assistant.io/integrations/homekit_controller",
"iot_class": "local_push",
"loggers": ["aiohomekit", "commentjson"],
"requirements": ["aiohomekit==3.1.1"],
"requirements": ["aiohomekit==3.1.2"],
"zeroconf": ["_hap._tcp.local.", "_hap._udp.local."]
}
@@ -24,6 +24,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
PLATFORM_SCHEMA_BASE,
)
from homeassistant.helpers.deprecation import (
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -81,12 +82,6 @@ DEVICE_CLASSES_SCHEMA = vol.All(vol.Lower, vol.Coerce(HumidifierDeviceClass))
# use the HumidifierDeviceClass enum instead.
DEVICE_CLASSES = [cls.value for cls in HumidifierDeviceClass]
# As we import deprecated constants from the const module, we need to add these two functions
# otherwise this module will be logged for using deprecated constants and not the custom component
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
# mypy: disallow-any-generics
@@ -214,7 +209,7 @@ class HumidifierEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_AT
if self.target_humidity is not None:
data[ATTR_HUMIDITY] = self.target_humidity
if HumidifierEntityFeature.MODES in self.supported_features:
if HumidifierEntityFeature.MODES in self.supported_features_compat:
data[ATTR_MODE] = self.mode
return data
@@ -293,3 +288,13 @@ class HumidifierEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_AT
self._report_deprecated_supported_features_values(new_features)
return new_features
return features
# As we import deprecated constants from the const module, we need to add these two functions
# otherwise this module will be logged for using deprecated constants and not the custom component
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+6 -2
View File
@@ -5,6 +5,7 @@ from functools import partial
from homeassistant.helpers.deprecation import (
DeprecatedConstant,
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -66,6 +67,9 @@ _DEPRECATED_SUPPORT_MODES = DeprecatedConstantEnum(
HumidifierEntityFeature.MODES, "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+9 -4
View File
@@ -33,6 +33,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
)
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -70,10 +71,6 @@ class LockEntityFeature(IntFlag):
# Please use the LockEntityFeature enum instead.
_DEPRECATED_SUPPORT_OPEN = DeprecatedConstantEnum(LockEntityFeature.OPEN, "2025.1")
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(dir_with_deprecated_constants, module_globals=globals())
PROP_TO_ATTR = {"changed_by": ATTR_CHANGED_BY, "code_format": ATTR_CODE_FORMAT}
# mypy: disallow-any-generics
@@ -315,3 +312,11 @@ class LockEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
return
self._lock_option_default_code = ""
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -11,7 +11,6 @@ from homeassistant.helpers.significant_change import (
from . import (
ATTR_ENTITY_PICTURE_LOCAL,
ATTR_GROUP_MEMBERS,
ATTR_MEDIA_POSITION,
ATTR_MEDIA_POSITION_UPDATED_AT,
ATTR_MEDIA_VOLUME_LEVEL,
@@ -25,9 +24,8 @@ INSIGNIFICANT_ATTRIBUTES: set[str] = {
SIGNIFICANT_ATTRIBUTES: set[str] = {
ATTR_ENTITY_PICTURE_LOCAL,
ATTR_GROUP_MEMBERS,
*ATTR_TO_PROPERTY,
}
} - INSIGNIFICANT_ATTRIBUTES
@callback
@@ -44,18 +42,10 @@ def async_check_significant_change(
return True
old_attrs_s = set(
{
k: v
for k, v in old_attrs.items()
if k in SIGNIFICANT_ATTRIBUTES - INSIGNIFICANT_ATTRIBUTES
}.items()
{k: v for k, v in old_attrs.items() if k in SIGNIFICANT_ATTRIBUTES}.items()
)
new_attrs_s = set(
{
k: v
for k, v in new_attrs.items()
if k in SIGNIFICANT_ATTRIBUTES - INSIGNIFICANT_ATTRIBUTES
}.items()
{k: v for k, v in new_attrs.items() if k in SIGNIFICANT_ATTRIBUTES}.items()
)
changed_attrs: set[str] = {item[0] for item in old_attrs_s ^ new_attrs_s}
@@ -36,6 +36,7 @@ from .const import (
)
from .helpers import savable_state
from .http_api import RegistrationsView
from .util import async_create_cloud_hook
from .webhook import handle_webhook
PLATFORMS = [Platform.SENSOR, Platform.BINARY_SENSOR, Platform.DEVICE_TRACKER]
@@ -103,26 +104,20 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
registration_name = f"Mobile App: {registration[ATTR_DEVICE_NAME]}"
webhook_register(hass, DOMAIN, registration_name, webhook_id, handle_webhook)
async def create_cloud_hook() -> None:
"""Create a cloud hook."""
hook = await cloud.async_create_cloudhook(hass, webhook_id)
hass.config_entries.async_update_entry(
entry, data={**entry.data, CONF_CLOUDHOOK_URL: hook}
)
async def manage_cloudhook(state: cloud.CloudConnectionState) -> None:
if (
state is cloud.CloudConnectionState.CLOUD_CONNECTED
and CONF_CLOUDHOOK_URL not in entry.data
):
await create_cloud_hook()
await async_create_cloud_hook(hass, webhook_id, entry)
if (
CONF_CLOUDHOOK_URL not in registration
CONF_CLOUDHOOK_URL not in entry.data
and cloud.async_active_subscription(hass)
and cloud.async_is_connected(hass)
):
await create_cloud_hook()
await async_create_cloud_hook(hass, webhook_id, entry)
entry.async_on_unload(cloud.async_listen_connection_change(hass, manage_cloudhook))
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
@@ -35,6 +35,7 @@ from .const import (
SCHEMA_APP_DATA,
)
from .helpers import supports_encryption
from .util import async_create_cloud_hook
class RegistrationsView(HomeAssistantView):
@@ -69,8 +70,8 @@ class RegistrationsView(HomeAssistantView):
webhook_id = secrets.token_hex()
if cloud.async_active_subscription(hass):
data[CONF_CLOUDHOOK_URL] = await cloud.async_create_cloudhook(
hass, webhook_id
data[CONF_CLOUDHOOK_URL] = await async_create_cloud_hook(
hass, webhook_id, None
)
data[CONF_WEBHOOK_ID] = webhook_id
@@ -1,8 +1,11 @@
"""Mobile app utility functions."""
from __future__ import annotations
import asyncio
from typing import TYPE_CHECKING
from homeassistant.components import cloud
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from .const import (
@@ -10,6 +13,7 @@ from .const import (
ATTR_PUSH_TOKEN,
ATTR_PUSH_URL,
ATTR_PUSH_WEBSOCKET_CHANNEL,
CONF_CLOUDHOOK_URL,
DATA_CONFIG_ENTRIES,
DATA_DEVICES,
DATA_NOTIFY,
@@ -53,3 +57,19 @@ def get_notify_service(hass: HomeAssistant, webhook_id: str) -> str | None:
return target_service
return None
_CLOUD_HOOK_LOCK = asyncio.Lock()
async def async_create_cloud_hook(
hass: HomeAssistant, webhook_id: str, entry: ConfigEntry | None
) -> str:
"""Create a cloud hook."""
async with _CLOUD_HOOK_LOCK:
hook = await cloud.async_get_or_create_cloudhook(hass, webhook_id)
if entry:
hass.config_entries.async_update_entry(
entry, data={**entry.data, CONF_CLOUDHOOK_URL: hook}
)
return hook
+1 -1
View File
@@ -190,7 +190,7 @@ BASE_STRUCT_SCHEMA = BASE_COMPONENT_SCHEMA.extend(
vol.Optional(CONF_STRUCTURE): cv.string,
vol.Optional(CONF_SCALE, default=1): number_validator,
vol.Optional(CONF_OFFSET, default=0): number_validator,
vol.Optional(CONF_PRECISION, default=0): cv.positive_int,
vol.Optional(CONF_PRECISION): cv.positive_int,
vol.Optional(
CONF_SWAP,
): vol.In(
@@ -185,10 +185,8 @@ class BaseStructPlatform(BasePlatform, RestoreEntity):
self._swap = config[CONF_SWAP]
self._data_type = config[CONF_DATA_TYPE]
self._structure: str = config[CONF_STRUCTURE]
self._precision = config[CONF_PRECISION]
self._scale = config[CONF_SCALE]
if self._scale < 1 and not self._precision:
self._precision = 2
self._precision = config.get(CONF_PRECISION, 2 if self._scale < 1 else 0)
self._offset = config[CONF_OFFSET]
self._slave_count = config.get(CONF_SLAVE_COUNT, None) or config.get(
CONF_VIRTUAL_COUNT, 0
+8 -4
View File
@@ -38,6 +38,7 @@ from homeassistant.const import (
)
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -70,10 +71,6 @@ _DEPRECATED_MODE_AUTO: Final = DeprecatedConstantEnum(NumberMode.AUTO, "2025.1")
_DEPRECATED_MODE_BOX: Final = DeprecatedConstantEnum(NumberMode.BOX, "2025.1")
_DEPRECATED_MODE_SLIDER: Final = DeprecatedConstantEnum(NumberMode.SLIDER, "2025.1")
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
class NumberDeviceClass(StrEnum):
"""Device class for numbers."""
@@ -481,3 +478,10 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = {
UNIT_CONVERTERS: dict[str, type[BaseUnitConverter]] = {
NumberDeviceClass.TEMPERATURE: TemperatureConverter,
}
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -3,6 +3,7 @@ from __future__ import annotations
from collections.abc import Mapping
import logging
import socket
from typing import Any
from opower import (
@@ -38,7 +39,7 @@ async def _validate_login(
) -> dict[str, str]:
"""Validate login data and return any errors."""
api = Opower(
async_create_clientsession(hass),
async_create_clientsession(hass, family=socket.AF_INET),
login_data[CONF_UTILITY],
login_data[CONF_USERNAME],
login_data[CONF_PASSWORD],
@@ -1,6 +1,7 @@
"""Coordinator to handle Opower connections."""
from datetime import datetime, timedelta
import logging
import socket
from types import MappingProxyType
from typing import Any, cast
@@ -51,7 +52,7 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]):
update_interval=timedelta(hours=12),
)
self.api = Opower(
aiohttp_client.async_get_clientsession(hass),
aiohttp_client.async_get_clientsession(hass, family=socket.AF_INET),
entry_data[CONF_UTILITY],
entry_data[CONF_USERNAME],
entry_data[CONF_PASSWORD],
@@ -5,5 +5,5 @@
"documentation": "https://www.home-assistant.io/integrations/orvibo",
"iot_class": "local_push",
"loggers": ["orvibo"],
"requirements": ["orvibo==1.1.1"]
"requirements": ["orvibo==1.1.2"]
}
@@ -136,7 +136,7 @@ async def async_setup_entry(
class PingDeviceTracker(CoordinatorEntity[PingUpdateCoordinator], ScannerEntity):
"""Representation of a Ping device tracker."""
_first_offline: datetime | None = None
_last_seen: datetime | None = None
def __init__(
self, config_entry: ConfigEntry, coordinator: PingUpdateCoordinator
@@ -171,14 +171,12 @@ class PingDeviceTracker(CoordinatorEntity[PingUpdateCoordinator], ScannerEntity)
def is_connected(self) -> bool:
"""Return true if ping returns is_alive or considered home."""
if self.coordinator.data.is_alive:
self._first_offline = None
return True
self._last_seen = dt_util.utcnow()
now = dt_util.utcnow()
if self._first_offline is None:
self._first_offline = now
return (self._first_offline + self._consider_home_interval) > now
return (
self._last_seen is not None
and (dt_util.utcnow() - self._last_seen) < self._consider_home_interval
)
@property
def entity_registry_enabled_default(self) -> bool:
@@ -165,6 +165,10 @@ def count_torrents_in_states(
coordinator: QBittorrentDataCoordinator, states: list[str]
) -> int:
"""Count the number of torrents in specified states."""
# When torrents are not in the returned data, there are none, return 0.
if "torrents" not in coordinator.data:
return 0
if not states:
return len(coordinator.data["torrents"])
+9 -4
View File
@@ -27,6 +27,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
)
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -92,10 +93,6 @@ _DEPRECATED_SUPPORT_ACTIVITY = DeprecatedConstantEnum(
)
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(dir_with_deprecated_constants, module_globals=globals())
REMOTE_SERVICE_ACTIVITY_SCHEMA = make_entity_service_schema(
{vol.Optional(ATTR_ACTIVITY): cv.string}
)
@@ -262,3 +259,11 @@ class RemoteEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_)
await self.hass.async_add_executor_job(
ft.partial(self.delete_command, **kwargs)
)
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+11 -6
View File
@@ -59,6 +59,7 @@ from homeassistant.helpers.config_validation import (
PLATFORM_SCHEMA_BASE,
)
from homeassistant.helpers.deprecation import (
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -120,12 +121,6 @@ __all__ = [
"SensorStateClass",
]
# As we import deprecated constants from the const module, we need to add these two functions
# otherwise this module will be logged for using deprecated constants and not the custom component
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
# mypy: disallow-any-generics
@@ -955,3 +950,13 @@ def async_rounded_state(hass: HomeAssistant, entity_id: str, state: State) -> st
value = f"{numerical_value:z.{precision}f}"
return value
# As we import deprecated constants from the const module, we need to add these two functions
# otherwise this module will be logged for using deprecated constants and not the custom component
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+8 -4
View File
@@ -38,6 +38,7 @@ from homeassistant.const import (
)
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -468,10 +469,6 @@ _DEPRECATED_STATE_CLASS_TOTAL_INCREASING: Final = DeprecatedConstantEnum(
)
STATE_CLASSES: Final[list[str]] = [cls.value for cls in SensorStateClass]
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
UNIT_CONVERTERS: dict[SensorDeviceClass | str | None, type[BaseUnitConverter]] = {
SensorDeviceClass.ATMOSPHERIC_PRESSURE: PressureConverter,
SensorDeviceClass.CURRENT: ElectricCurrentConverter,
@@ -631,3 +628,10 @@ DEVICE_CLASS_STATE_CLASSES: dict[SensorDeviceClass, set[SensorStateClass]] = {
SensorDeviceClass.WEIGHT: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.WIND_SPEED: {SensorStateClass.MEASUREMENT},
}
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+10 -8
View File
@@ -25,6 +25,7 @@ from homeassistant.helpers.selector import SelectSelector, SelectSelectorConfig
from .const import (
CONF_BLE_SCANNER_MODE,
CONF_GEN,
CONF_SLEEP_PERIOD,
DOMAIN,
LOGGER,
@@ -35,6 +36,7 @@ from .coordinator import async_reconnect_soon
from .utils import (
get_block_device_sleep_period,
get_coap_context,
get_device_entry_gen,
get_info_auth,
get_info_gen,
get_model_name,
@@ -84,7 +86,7 @@ async def validate_input(
"title": rpc_device.name,
CONF_SLEEP_PERIOD: sleep_period,
"model": rpc_device.shelly.get("model"),
"gen": gen,
CONF_GEN: gen,
}
# Gen1
@@ -99,7 +101,7 @@ async def validate_input(
"title": block_device.name,
CONF_SLEEP_PERIOD: get_block_device_sleep_period(block_device.settings),
"model": block_device.model,
"gen": gen,
CONF_GEN: gen,
}
@@ -153,7 +155,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN):
**user_input,
CONF_SLEEP_PERIOD: device_info[CONF_SLEEP_PERIOD],
"model": device_info["model"],
"gen": device_info["gen"],
CONF_GEN: device_info[CONF_GEN],
},
)
errors["base"] = "firmware_not_fully_provisioned"
@@ -190,7 +192,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN):
CONF_HOST: self.host,
CONF_SLEEP_PERIOD: device_info[CONF_SLEEP_PERIOD],
"model": device_info["model"],
"gen": device_info["gen"],
CONF_GEN: device_info[CONF_GEN],
},
)
errors["base"] = "firmware_not_fully_provisioned"
@@ -288,7 +290,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN):
"host": self.host,
CONF_SLEEP_PERIOD: self.device_info[CONF_SLEEP_PERIOD],
"model": self.device_info["model"],
"gen": self.device_info["gen"],
CONF_GEN: self.device_info[CONF_GEN],
},
)
self._set_confirm_only()
@@ -321,7 +323,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN):
except (DeviceConnectionError, InvalidAuthError, FirmwareUnsupported):
return self.async_abort(reason="reauth_unsuccessful")
if self.entry.data.get("gen", 1) != 1:
if get_device_entry_gen(self.entry) != 1:
user_input[CONF_USERNAME] = "admin"
try:
await validate_input(self.hass, host, info, user_input)
@@ -334,7 +336,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN):
await self.hass.config_entries.async_reload(self.entry.entry_id)
return self.async_abort(reason="reauth_successful")
if self.entry.data.get("gen", 1) in BLOCK_GENERATIONS:
if get_device_entry_gen(self.entry) in BLOCK_GENERATIONS:
schema = {
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
@@ -363,7 +365,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN):
def async_supports_options_flow(cls, config_entry: ConfigEntry) -> bool:
"""Return options flow support for this handler."""
return (
config_entry.data.get("gen") in RPC_GENERATIONS
get_device_entry_gen(config_entry) in RPC_GENERATIONS
and not config_entry.data.get(CONF_SLEEP_PERIOD)
and config_entry.data.get("model") != MODEL_WALL_DISPLAY
)
+2
View File
@@ -214,3 +214,5 @@ DEVICES_WITHOUT_FIRMWARE_CHANGELOG = (
MODEL_MOTION_2,
MODEL_VALVE,
)
CONF_GEN = "gen"
@@ -57,7 +57,11 @@ from .const import (
UPDATE_PERIOD_MULTIPLIER,
BLEScannerMode,
)
from .utils import get_rpc_device_wakeup_period, update_device_fw_info
from .utils import (
get_device_entry_gen,
get_rpc_device_wakeup_period,
update_device_fw_info,
)
_DeviceT = TypeVar("_DeviceT", bound="BlockDevice|RpcDevice")
@@ -135,7 +139,7 @@ class ShellyCoordinatorBase(DataUpdateCoordinator[None], Generic[_DeviceT]):
manufacturer="Shelly",
model=aioshelly.const.MODEL_NAMES.get(self.model, self.model),
sw_version=self.sw_version,
hw_version=f"gen{self.device.gen} ({self.model})",
hw_version=f"gen{get_device_entry_gen(self.entry)} ({self.model})",
configuration_url=f"http://{self.entry.data[CONF_HOST]}",
)
self.device_id = device_entry.id
+3 -2
View File
@@ -34,6 +34,7 @@ from homeassistant.util.dt import utcnow
from .const import (
BASIC_INPUTS_EVENTS_TYPES,
CONF_COAP_PORT,
CONF_GEN,
DEFAULT_COAP_PORT,
DEVICES_WITHOUT_FIRMWARE_CHANGELOG,
DOMAIN,
@@ -281,7 +282,7 @@ def get_info_auth(info: dict[str, Any]) -> bool:
def get_info_gen(info: dict[str, Any]) -> int:
"""Return the device generation from shelly info."""
return int(info.get("gen", 1))
return int(info.get(CONF_GEN, 1))
def get_model_name(info: dict[str, Any]) -> str:
@@ -325,7 +326,7 @@ def get_rpc_entity_name(
def get_device_entry_gen(entry: ConfigEntry) -> int:
"""Return the device generation from config entry."""
return entry.data.get("gen", 1)
return entry.data.get(CONF_GEN, 1)
def get_rpc_key_instances(keys_dict: dict[str, Any], key: str) -> list[str]:
+11 -6
View File
@@ -17,6 +17,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
PLATFORM_SCHEMA_BASE,
)
from homeassistant.helpers.deprecation import (
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -53,12 +54,6 @@ TURN_ON_SCHEMA = {
vol.Optional(ATTR_VOLUME_LEVEL): cv.small_float,
}
# As we import deprecated constants from the const module, we need to add these two functions
# otherwise this module will be logged for using deprecated constants and not the custom component
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
class SirenTurnOnServiceParameters(TypedDict, total=False):
"""Represent possible parameters to siren.turn_on service data dict type."""
@@ -218,3 +213,13 @@ class SirenEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
self._report_deprecated_supported_features_values(new_features)
return new_features
return features
# As we import deprecated constants from the const module, we need to add these two functions
# otherwise this module will be logged for using deprecated constants and not the custom component
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+6 -2
View File
@@ -6,6 +6,7 @@ from typing import Final
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -47,6 +48,9 @@ _DEPRECATED_SUPPORT_DURATION: Final = DeprecatedConstantEnum(
SirenEntityFeature.DURATION, "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -107,12 +107,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
def set_away_mode(service: ServiceCall) -> None:
"""Set the StreamLabsWater Away Mode."""
away_mode = service.data.get(ATTR_AWAY_MODE)
location_id = (
service.data.get(CONF_LOCATION_ID) or list(coordinator.data.values())[0]
)
location_id = service.data.get(CONF_LOCATION_ID) or list(coordinator.data)[0]
client.update_location(location_id, away_mode)
hass.services.register(
hass.services.async_register(
DOMAIN, SERVICE_SET_AWAY_MODE, set_away_mode, schema=SET_AWAY_MODE_SCHEMA
)
@@ -44,7 +44,7 @@ class StreamlabsCoordinator(DataUpdateCoordinator[dict[str, StreamlabsData]]):
def _update_data(self) -> dict[str, StreamlabsData]:
locations = self.client.get_locations()
res = {}
for location in locations:
for location in locations["locations"]:
location_id = location["locationId"]
water_usage = self.client.get_water_usage_summary(location_id)
res[location_id] = StreamlabsData(
@@ -27,7 +27,7 @@ async def async_setup_entry(
entities = []
for location_id in coordinator.data.values():
for location_id in coordinator.data:
entities.extend(
[
StreamLabsDailyUsage(coordinator, location_id),
+9 -4
View File
@@ -23,6 +23,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
)
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -66,10 +67,6 @@ _DEPRECATED_DEVICE_CLASS_SWITCH = DeprecatedConstantEnum(
SwitchDeviceClass.SWITCH, "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
# mypy: disallow-any-generics
@@ -133,3 +130,11 @@ class SwitchEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_)
if hasattr(self, "entity_description"):
return self.entity_description.device_class
return None
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
@@ -118,10 +118,8 @@ class SystemBridgeMediaPlayer(SystemBridgeEntity, MediaPlayerEntity):
features |= MediaPlayerEntityFeature.PREVIOUS_TRACK
if data.media.is_next_enabled:
features |= MediaPlayerEntityFeature.NEXT_TRACK
if data.media.is_pause_enabled:
features |= MediaPlayerEntityFeature.PAUSE
if data.media.is_play_enabled:
features |= MediaPlayerEntityFeature.PLAY
if data.media.is_pause_enabled or data.media.is_play_enabled:
features |= MediaPlayerEntityFeature.PAUSE | MediaPlayerEntityFeature.PLAY
if data.media.is_stop_enabled:
features |= MediaPlayerEntityFeature.STOP
@@ -4,6 +4,7 @@ from __future__ import annotations
import logging
from typing import Any
import PyTado
from PyTado.interface import Tado
import requests.exceptions
import voluptuous as vol
@@ -136,6 +137,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
)
except exceptions.HomeAssistantError:
return self.async_abort(reason="import_failed")
except PyTado.exceptions.TadoWrongCredentialsException:
return self.async_abort(reason="import_failed_invalid_auth")
home_id = validate_result[UNIQUE_ID]
await self.async_set_unique_id(home_id)
@@ -55,12 +55,14 @@ async def async_get_scanner(
translation_key = "import_aborted"
if import_result.get("reason") == "import_failed":
translation_key = "import_failed"
if import_result.get("reason") == "import_failed_invalid_auth":
translation_key = "import_failed_invalid_auth"
async_create_issue(
hass,
DOMAIN,
"deprecated_yaml_import_device_tracker",
breaks_in_ha_version="2024.6.0",
breaks_in_ha_version="2024.7.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key=translation_key,
+1 -1
View File
@@ -14,5 +14,5 @@
},
"iot_class": "cloud_polling",
"loggers": ["PyTado"],
"requirements": ["python-tado==0.17.0"]
"requirements": ["python-tado==0.17.3"]
}
+5 -1
View File
@@ -133,9 +133,13 @@
"title": "Import aborted",
"description": "Configuring the Tado Device Tracker using YAML is being removed.\n The import was aborted, due to an existing config entry being the same as the data being imported in the YAML. Remove the YAML device tracker configuration and restart Home Assistant. Please use the UI to configure Tado."
},
"failed_to_import": {
"import_failed": {
"title": "Failed to import",
"description": "Failed to import the configuration for the Tado Device Tracker. Please use the UI to configure Tado. Don't forget to delete the YAML configuration."
},
"import_failed_invalid_auth": {
"title": "Failed to import, invalid credentials",
"description": "Failed to import the configuration for the Tado Device Tracker, due to invalid credentials. Please fix the YAML configuration and restart Home Assistant. Alternatively you can use the UI to configure Tado. Don't forget to delete the YAML configuration, once the import is successful."
}
}
}
@@ -41,7 +41,6 @@ class TessieStateUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
self.vin = vin
self.session = async_get_clientsession(hass)
self.data = self._flatten(data)
self.did_first_update = False
async def _async_update_data(self) -> dict[str, Any]:
"""Update vehicle data using Tessie API."""
@@ -50,7 +49,7 @@ class TessieStateUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
session=self.session,
api_key=self.api_key,
vin=self.vin,
use_cache=self.did_first_update,
use_cache=False,
)
except ClientResponseError as e:
if e.status == HTTPStatus.UNAUTHORIZED:
@@ -58,7 +57,6 @@ class TessieStateUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
raise ConfigEntryAuthFailed from e
raise e
self.did_first_update = True
if vehicle["state"] == TessieStatus.ONLINE:
# Vehicle is online, all data is fresh
return self._flatten(vehicle)
+2 -2
View File
@@ -140,7 +140,7 @@ async def async_install(entity: UpdateEntity, service_call: ServiceCall) -> None
# If version is specified, but not supported by the entity.
if (
version is not None
and UpdateEntityFeature.SPECIFIC_VERSION not in entity.supported_features
and UpdateEntityFeature.SPECIFIC_VERSION not in entity.supported_features_compat
):
raise HomeAssistantError(
f"Installing a specific version is not supported for {entity.entity_id}"
@@ -149,7 +149,7 @@ async def async_install(entity: UpdateEntity, service_call: ServiceCall) -> None
# If backup is requested, but not supported by the entity.
if (
backup := service_call.data[ATTR_BACKUP]
) and UpdateEntityFeature.BACKUP not in entity.supported_features:
) and UpdateEntityFeature.BACKUP not in entity.supported_features_compat:
raise HomeAssistantError(f"Backup is not supported for {entity.entity_id}")
# Update is already in progress.
@@ -30,6 +30,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
)
from homeassistant.helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -86,10 +87,6 @@ _DEPRECATED_SUPPORT_AWAY_MODE = DeprecatedConstantEnum(
WaterHeaterEntityFeature.AWAY_MODE, "2025.1"
)
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(dir_with_deprecated_constants, module_globals=globals())
ATTR_MAX_TEMP = "max_temp"
ATTR_MIN_TEMP = "min_temp"
ATTR_AWAY_MODE = "away_mode"
@@ -241,7 +238,7 @@ class WaterHeaterEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
),
}
if WaterHeaterEntityFeature.OPERATION_MODE in self.supported_features:
if WaterHeaterEntityFeature.OPERATION_MODE in self.supported_features_compat:
data[ATTR_OPERATION_LIST] = self.operation_list
return data
@@ -277,7 +274,7 @@ class WaterHeaterEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
),
}
supported_features = self.supported_features
supported_features = self.supported_features_compat
if WaterHeaterEntityFeature.OPERATION_MODE in supported_features:
data[ATTR_OPERATION_MODE] = self.current_operation
@@ -441,3 +438,11 @@ async def async_service_temperature_set(
kwargs[value] = temp
await entity.async_set_temperature(**kwargs)
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = ft.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = ft.partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+3 -3
View File
@@ -216,9 +216,9 @@ class PollableSensor(Sensor):
async def async_will_remove_from_hass(self) -> None:
"""Disconnect entity object when removed."""
assert self._cancel_refresh_handle
self._cancel_refresh_handle()
self._cancel_refresh_handle = None
if self._cancel_refresh_handle is not None:
self._cancel_refresh_handle()
self._cancel_refresh_handle = None
self.debug("stopped polling during device removal")
await super().async_will_remove_from_hass()
@@ -9,7 +9,7 @@
"iot_class": "local_push",
"loggers": ["zwave_js_server"],
"quality_scale": "platinum",
"requirements": ["pyserial==3.5", "zwave-js-server-python==0.55.2"],
"requirements": ["pyserial==3.5", "zwave-js-server-python==0.55.3"],
"usb": [
{
"vid": "0658",
+222 -171
View File
@@ -2,12 +2,21 @@
from __future__ import annotations
from enum import StrEnum
from typing import Any, Final
from functools import partial
from typing import Final
from .helpers.deprecation import (
DeprecatedConstant,
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
APPLICATION_NAME: Final = "HomeAssistant"
MAJOR_VERSION: Final = 2024
MINOR_VERSION: Final = 1
PATCH_VERSION: Final = "0b5"
PATCH_VERSION: Final = "2"
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 11, 0)
@@ -307,148 +316,131 @@ EVENT_SHOPPING_LIST_UPDATED: Final = "shopping_list_updated"
# #### DEVICE CLASSES ####
# DEVICE_CLASS_* below are deprecated as of 2021.12
# use the SensorDeviceClass enum instead.
_DEPRECATED_DEVICE_CLASS_AQI: Final = ("aqi", "SensorDeviceClass.AQI", "2025.1")
_DEPRECATED_DEVICE_CLASS_BATTERY: Final = (
_DEPRECATED_DEVICE_CLASS_AQI: Final = DeprecatedConstant(
"aqi", "SensorDeviceClass.AQI", "2025.1"
)
_DEPRECATED_DEVICE_CLASS_BATTERY: Final = DeprecatedConstant(
"battery",
"SensorDeviceClass.BATTERY",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_CO: Final = (
_DEPRECATED_DEVICE_CLASS_CO: Final = DeprecatedConstant(
"carbon_monoxide",
"SensorDeviceClass.CO",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_CO2: Final = (
_DEPRECATED_DEVICE_CLASS_CO2: Final = DeprecatedConstant(
"carbon_dioxide",
"SensorDeviceClass.CO2",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_CURRENT: Final = (
_DEPRECATED_DEVICE_CLASS_CURRENT: Final = DeprecatedConstant(
"current",
"SensorDeviceClass.CURRENT",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_DATE: Final = ("date", "SensorDeviceClass.DATE", "2025.1")
_DEPRECATED_DEVICE_CLASS_ENERGY: Final = (
_DEPRECATED_DEVICE_CLASS_DATE: Final = DeprecatedConstant(
"date", "SensorDeviceClass.DATE", "2025.1"
)
_DEPRECATED_DEVICE_CLASS_ENERGY: Final = DeprecatedConstant(
"energy",
"SensorDeviceClass.ENERGY",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_FREQUENCY: Final = (
_DEPRECATED_DEVICE_CLASS_FREQUENCY: Final = DeprecatedConstant(
"frequency",
"SensorDeviceClass.FREQUENCY",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_GAS: Final = ("gas", "SensorDeviceClass.GAS", "2025.1")
_DEPRECATED_DEVICE_CLASS_HUMIDITY: Final = (
_DEPRECATED_DEVICE_CLASS_GAS: Final = DeprecatedConstant(
"gas", "SensorDeviceClass.GAS", "2025.1"
)
_DEPRECATED_DEVICE_CLASS_HUMIDITY: Final = DeprecatedConstant(
"humidity",
"SensorDeviceClass.HUMIDITY",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_ILLUMINANCE: Final = (
_DEPRECATED_DEVICE_CLASS_ILLUMINANCE: Final = DeprecatedConstant(
"illuminance",
"SensorDeviceClass.ILLUMINANCE",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_MONETARY: Final = (
_DEPRECATED_DEVICE_CLASS_MONETARY: Final = DeprecatedConstant(
"monetary",
"SensorDeviceClass.MONETARY",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_NITROGEN_DIOXIDE = (
_DEPRECATED_DEVICE_CLASS_NITROGEN_DIOXIDE: Final = DeprecatedConstant(
"nitrogen_dioxide",
"SensorDeviceClass.NITROGEN_DIOXIDE",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_NITROGEN_MONOXIDE = (
_DEPRECATED_DEVICE_CLASS_NITROGEN_MONOXIDE: Final = DeprecatedConstant(
"nitrogen_monoxide",
"SensorDeviceClass.NITROGEN_MONOXIDE",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_NITROUS_OXIDE = (
_DEPRECATED_DEVICE_CLASS_NITROUS_OXIDE: Final = DeprecatedConstant(
"nitrous_oxide",
"SensorDeviceClass.NITROUS_OXIDE",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_OZONE: Final = ("ozone", "SensorDeviceClass.OZONE", "2025.1")
_DEPRECATED_DEVICE_CLASS_PM1: Final = ("pm1", "SensorDeviceClass.PM1", "2025.1")
_DEPRECATED_DEVICE_CLASS_PM10: Final = ("pm10", "SensorDeviceClass.PM10", "2025.1")
_DEPRECATED_DEVICE_CLASS_PM25: Final = ("pm25", "SensorDeviceClass.PM25", "2025.1")
_DEPRECATED_DEVICE_CLASS_POWER_FACTOR: Final = (
_DEPRECATED_DEVICE_CLASS_OZONE: Final = DeprecatedConstant(
"ozone", "SensorDeviceClass.OZONE", "2025.1"
)
_DEPRECATED_DEVICE_CLASS_PM1: Final = DeprecatedConstant(
"pm1", "SensorDeviceClass.PM1", "2025.1"
)
_DEPRECATED_DEVICE_CLASS_PM10: Final = DeprecatedConstant(
"pm10", "SensorDeviceClass.PM10", "2025.1"
)
_DEPRECATED_DEVICE_CLASS_PM25: Final = DeprecatedConstant(
"pm25", "SensorDeviceClass.PM25", "2025.1"
)
_DEPRECATED_DEVICE_CLASS_POWER_FACTOR: Final = DeprecatedConstant(
"power_factor",
"SensorDeviceClass.POWER_FACTOR",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_POWER: Final = ("power", "SensorDeviceClass.POWER", "2025.1")
_DEPRECATED_DEVICE_CLASS_PRESSURE: Final = (
_DEPRECATED_DEVICE_CLASS_POWER: Final = DeprecatedConstant(
"power", "SensorDeviceClass.POWER", "2025.1"
)
_DEPRECATED_DEVICE_CLASS_PRESSURE: Final = DeprecatedConstant(
"pressure",
"SensorDeviceClass.PRESSURE",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_SIGNAL_STRENGTH: Final = (
_DEPRECATED_DEVICE_CLASS_SIGNAL_STRENGTH: Final = DeprecatedConstant(
"signal_strength",
"SensorDeviceClass.SIGNAL_STRENGTH",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_SULPHUR_DIOXIDE = (
_DEPRECATED_DEVICE_CLASS_SULPHUR_DIOXIDE: Final = DeprecatedConstant(
"sulphur_dioxide",
"SensorDeviceClass.SULPHUR_DIOXIDE",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_TEMPERATURE: Final = (
_DEPRECATED_DEVICE_CLASS_TEMPERATURE: Final = DeprecatedConstant(
"temperature",
"SensorDeviceClass.TEMPERATURE",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_TIMESTAMP: Final = (
_DEPRECATED_DEVICE_CLASS_TIMESTAMP: Final = DeprecatedConstant(
"timestamp",
"SensorDeviceClass.TIMESTAMP",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS = (
_DEPRECATED_DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS: Final = DeprecatedConstant(
"volatile_organic_compounds",
"SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS",
"2025.1",
)
_DEPRECATED_DEVICE_CLASS_VOLTAGE: Final = (
_DEPRECATED_DEVICE_CLASS_VOLTAGE: Final = DeprecatedConstant(
"voltage",
"SensorDeviceClass.VOLTAGE",
"2025.1",
)
# Can be removed if no deprecated constant are in this module anymore
def __getattr__(name: str) -> Any:
"""Check if the not found name is a deprecated constant.
If it is, print a deprecation warning and return the value of the constant.
Otherwise raise AttributeError.
"""
module_globals = globals()
if f"_DEPRECATED_{name}" not in module_globals:
raise AttributeError(f"Module {__name__} has no attribute {name!r}")
# Avoid circular import
from .helpers.deprecation import ( # pylint: disable=import-outside-toplevel
check_if_deprecated_constant,
)
return check_if_deprecated_constant(name, module_globals)
# Can be removed if no deprecated constant are in this module anymore
def __dir__() -> list[str]:
"""Return dir() with deprecated constants."""
# Copied method from homeassistant.helpers.deprecattion#dir_with_deprecated_constants to avoid import cycle
module_globals = globals()
return list(module_globals) + [
name.removeprefix("_DEPRECATED_")
for name in module_globals
if name.startswith("_DEPRECATED_")
]
# #### STATES ####
STATE_ON: Final = "on"
STATE_OFF: Final = "off"
@@ -621,7 +613,7 @@ class UnitOfApparentPower(StrEnum):
VOLT_AMPERE = "VA"
_DEPRECATED_POWER_VOLT_AMPERE: Final = (
_DEPRECATED_POWER_VOLT_AMPERE: Final = DeprecatedConstantEnum(
UnitOfApparentPower.VOLT_AMPERE,
"2025.1",
)
@@ -637,17 +629,17 @@ class UnitOfPower(StrEnum):
BTU_PER_HOUR = "BTU/h"
_DEPRECATED_POWER_WATT: Final = (
_DEPRECATED_POWER_WATT: Final = DeprecatedConstantEnum(
UnitOfPower.WATT,
"2025.1",
)
"""Deprecated: please use UnitOfPower.WATT."""
_DEPRECATED_POWER_KILO_WATT: Final = (
_DEPRECATED_POWER_KILO_WATT: Final = DeprecatedConstantEnum(
UnitOfPower.KILO_WATT,
"2025.1",
)
"""Deprecated: please use UnitOfPower.KILO_WATT."""
_DEPRECATED_POWER_BTU_PER_HOUR: Final = (
_DEPRECATED_POWER_BTU_PER_HOUR: Final = DeprecatedConstantEnum(
UnitOfPower.BTU_PER_HOUR,
"2025.1",
)
@@ -668,17 +660,17 @@ class UnitOfEnergy(StrEnum):
WATT_HOUR = "Wh"
_DEPRECATED_ENERGY_KILO_WATT_HOUR: Final = (
_DEPRECATED_ENERGY_KILO_WATT_HOUR: Final = DeprecatedConstantEnum(
UnitOfEnergy.KILO_WATT_HOUR,
"2025.1",
)
"""Deprecated: please use UnitOfEnergy.KILO_WATT_HOUR."""
_DEPRECATED_ENERGY_MEGA_WATT_HOUR: Final = (
_DEPRECATED_ENERGY_MEGA_WATT_HOUR: Final = DeprecatedConstantEnum(
UnitOfEnergy.MEGA_WATT_HOUR,
"2025.1",
)
"""Deprecated: please use UnitOfEnergy.MEGA_WATT_HOUR."""
_DEPRECATED_ENERGY_WATT_HOUR: Final = (
_DEPRECATED_ENERGY_WATT_HOUR: Final = DeprecatedConstantEnum(
UnitOfEnergy.WATT_HOUR,
"2025.1",
)
@@ -693,12 +685,12 @@ class UnitOfElectricCurrent(StrEnum):
AMPERE = "A"
_DEPRECATED_ELECTRIC_CURRENT_MILLIAMPERE: Final = (
_DEPRECATED_ELECTRIC_CURRENT_MILLIAMPERE: Final = DeprecatedConstantEnum(
UnitOfElectricCurrent.MILLIAMPERE,
"2025.1",
)
"""Deprecated: please use UnitOfElectricCurrent.MILLIAMPERE."""
_DEPRECATED_ELECTRIC_CURRENT_AMPERE: Final = (
_DEPRECATED_ELECTRIC_CURRENT_AMPERE: Final = DeprecatedConstantEnum(
UnitOfElectricCurrent.AMPERE,
"2025.1",
)
@@ -713,12 +705,12 @@ class UnitOfElectricPotential(StrEnum):
VOLT = "V"
_DEPRECATED_ELECTRIC_POTENTIAL_MILLIVOLT: Final = (
_DEPRECATED_ELECTRIC_POTENTIAL_MILLIVOLT: Final = DeprecatedConstantEnum(
UnitOfElectricPotential.MILLIVOLT,
"2025.1",
)
"""Deprecated: please use UnitOfElectricPotential.MILLIVOLT."""
_DEPRECATED_ELECTRIC_POTENTIAL_VOLT: Final = (
_DEPRECATED_ELECTRIC_POTENTIAL_VOLT: Final = DeprecatedConstantEnum(
UnitOfElectricPotential.VOLT,
"2025.1",
)
@@ -742,17 +734,17 @@ class UnitOfTemperature(StrEnum):
KELVIN = "K"
_DEPRECATED_TEMP_CELSIUS: Final = (
_DEPRECATED_TEMP_CELSIUS: Final = DeprecatedConstantEnum(
UnitOfTemperature.CELSIUS,
"2025.1",
)
"""Deprecated: please use UnitOfTemperature.CELSIUS"""
_DEPRECATED_TEMP_FAHRENHEIT: Final = (
_DEPRECATED_TEMP_FAHRENHEIT: Final = DeprecatedConstantEnum(
UnitOfTemperature.FAHRENHEIT,
"2025.1",
)
"""Deprecated: please use UnitOfTemperature.FAHRENHEIT"""
_DEPRECATED_TEMP_KELVIN: Final = (
_DEPRECATED_TEMP_KELVIN: Final = DeprecatedConstantEnum(
UnitOfTemperature.KELVIN,
"2025.1",
)
@@ -774,47 +766,47 @@ class UnitOfTime(StrEnum):
YEARS = "y"
_DEPRECATED_TIME_MICROSECONDS: Final = (
_DEPRECATED_TIME_MICROSECONDS: Final = DeprecatedConstantEnum(
UnitOfTime.MICROSECONDS,
"2025.1",
)
"""Deprecated: please use UnitOfTime.MICROSECONDS."""
_DEPRECATED_TIME_MILLISECONDS: Final = (
_DEPRECATED_TIME_MILLISECONDS: Final = DeprecatedConstantEnum(
UnitOfTime.MILLISECONDS,
"2025.1",
)
"""Deprecated: please use UnitOfTime.MILLISECONDS."""
_DEPRECATED_TIME_SECONDS: Final = (
_DEPRECATED_TIME_SECONDS: Final = DeprecatedConstantEnum(
UnitOfTime.SECONDS,
"2025.1",
)
"""Deprecated: please use UnitOfTime.SECONDS."""
_DEPRECATED_TIME_MINUTES: Final = (
_DEPRECATED_TIME_MINUTES: Final = DeprecatedConstantEnum(
UnitOfTime.MINUTES,
"2025.1",
)
"""Deprecated: please use UnitOfTime.MINUTES."""
_DEPRECATED_TIME_HOURS: Final = (
_DEPRECATED_TIME_HOURS: Final = DeprecatedConstantEnum(
UnitOfTime.HOURS,
"2025.1",
)
"""Deprecated: please use UnitOfTime.HOURS."""
_DEPRECATED_TIME_DAYS: Final = (
_DEPRECATED_TIME_DAYS: Final = DeprecatedConstantEnum(
UnitOfTime.DAYS,
"2025.1",
)
"""Deprecated: please use UnitOfTime.DAYS."""
_DEPRECATED_TIME_WEEKS: Final = (
_DEPRECATED_TIME_WEEKS: Final = DeprecatedConstantEnum(
UnitOfTime.WEEKS,
"2025.1",
)
"""Deprecated: please use UnitOfTime.WEEKS."""
_DEPRECATED_TIME_MONTHS: Final = (
_DEPRECATED_TIME_MONTHS: Final = DeprecatedConstantEnum(
UnitOfTime.MONTHS,
"2025.1",
)
"""Deprecated: please use UnitOfTime.MONTHS."""
_DEPRECATED_TIME_YEARS: Final = (
_DEPRECATED_TIME_YEARS: Final = DeprecatedConstantEnum(
UnitOfTime.YEARS,
"2025.1",
)
@@ -835,42 +827,42 @@ class UnitOfLength(StrEnum):
MILES = "mi"
_DEPRECATED_LENGTH_MILLIMETERS: Final = (
_DEPRECATED_LENGTH_MILLIMETERS: Final = DeprecatedConstantEnum(
UnitOfLength.MILLIMETERS,
"2025.1",
)
"""Deprecated: please use UnitOfLength.MILLIMETERS."""
_DEPRECATED_LENGTH_CENTIMETERS: Final = (
_DEPRECATED_LENGTH_CENTIMETERS: Final = DeprecatedConstantEnum(
UnitOfLength.CENTIMETERS,
"2025.1",
)
"""Deprecated: please use UnitOfLength.CENTIMETERS."""
_DEPRECATED_LENGTH_METERS: Final = (
_DEPRECATED_LENGTH_METERS: Final = DeprecatedConstantEnum(
UnitOfLength.METERS,
"2025.1",
)
"""Deprecated: please use UnitOfLength.METERS."""
_DEPRECATED_LENGTH_KILOMETERS: Final = (
_DEPRECATED_LENGTH_KILOMETERS: Final = DeprecatedConstantEnum(
UnitOfLength.KILOMETERS,
"2025.1",
)
"""Deprecated: please use UnitOfLength.KILOMETERS."""
_DEPRECATED_LENGTH_INCHES: Final = (
_DEPRECATED_LENGTH_INCHES: Final = DeprecatedConstantEnum(
UnitOfLength.INCHES,
"2025.1",
)
"""Deprecated: please use UnitOfLength.INCHES."""
_DEPRECATED_LENGTH_FEET: Final = (
_DEPRECATED_LENGTH_FEET: Final = DeprecatedConstantEnum(
UnitOfLength.FEET,
"2025.1",
)
"""Deprecated: please use UnitOfLength.FEET."""
_DEPRECATED_LENGTH_YARD: Final = (
_DEPRECATED_LENGTH_YARD: Final = DeprecatedConstantEnum(
UnitOfLength.YARDS,
"2025.1",
)
"""Deprecated: please use UnitOfLength.YARDS."""
_DEPRECATED_LENGTH_MILES: Final = (
_DEPRECATED_LENGTH_MILES: Final = DeprecatedConstantEnum(
UnitOfLength.MILES,
"2025.1",
)
@@ -887,22 +879,22 @@ class UnitOfFrequency(StrEnum):
GIGAHERTZ = "GHz"
_DEPRECATED_FREQUENCY_HERTZ: Final = (
_DEPRECATED_FREQUENCY_HERTZ: Final = DeprecatedConstantEnum(
UnitOfFrequency.HERTZ,
"2025.1",
)
"""Deprecated: please use UnitOfFrequency.HERTZ"""
_DEPRECATED_FREQUENCY_KILOHERTZ: Final = (
_DEPRECATED_FREQUENCY_KILOHERTZ: Final = DeprecatedConstantEnum(
UnitOfFrequency.KILOHERTZ,
"2025.1",
)
"""Deprecated: please use UnitOfFrequency.KILOHERTZ"""
_DEPRECATED_FREQUENCY_MEGAHERTZ: Final = (
_DEPRECATED_FREQUENCY_MEGAHERTZ: Final = DeprecatedConstantEnum(
UnitOfFrequency.MEGAHERTZ,
"2025.1",
)
"""Deprecated: please use UnitOfFrequency.MEGAHERTZ"""
_DEPRECATED_FREQUENCY_GIGAHERTZ: Final = (
_DEPRECATED_FREQUENCY_GIGAHERTZ: Final = DeprecatedConstantEnum(
UnitOfFrequency.GIGAHERTZ,
"2025.1",
)
@@ -924,47 +916,47 @@ class UnitOfPressure(StrEnum):
PSI = "psi"
_DEPRECATED_PRESSURE_PA: Final = (
_DEPRECATED_PRESSURE_PA: Final = DeprecatedConstantEnum(
UnitOfPressure.PA,
"2025.1",
)
"""Deprecated: please use UnitOfPressure.PA"""
_DEPRECATED_PRESSURE_HPA: Final = (
_DEPRECATED_PRESSURE_HPA: Final = DeprecatedConstantEnum(
UnitOfPressure.HPA,
"2025.1",
)
"""Deprecated: please use UnitOfPressure.HPA"""
_DEPRECATED_PRESSURE_KPA: Final = (
_DEPRECATED_PRESSURE_KPA: Final = DeprecatedConstantEnum(
UnitOfPressure.KPA,
"2025.1",
)
"""Deprecated: please use UnitOfPressure.KPA"""
_DEPRECATED_PRESSURE_BAR: Final = (
_DEPRECATED_PRESSURE_BAR: Final = DeprecatedConstantEnum(
UnitOfPressure.BAR,
"2025.1",
)
"""Deprecated: please use UnitOfPressure.BAR"""
_DEPRECATED_PRESSURE_CBAR: Final = (
_DEPRECATED_PRESSURE_CBAR: Final = DeprecatedConstantEnum(
UnitOfPressure.CBAR,
"2025.1",
)
"""Deprecated: please use UnitOfPressure.CBAR"""
_DEPRECATED_PRESSURE_MBAR: Final = (
_DEPRECATED_PRESSURE_MBAR: Final = DeprecatedConstantEnum(
UnitOfPressure.MBAR,
"2025.1",
)
"""Deprecated: please use UnitOfPressure.MBAR"""
_DEPRECATED_PRESSURE_MMHG: Final = (
_DEPRECATED_PRESSURE_MMHG: Final = DeprecatedConstantEnum(
UnitOfPressure.MMHG,
"2025.1",
)
"""Deprecated: please use UnitOfPressure.MMHG"""
_DEPRECATED_PRESSURE_INHG: Final = (
_DEPRECATED_PRESSURE_INHG: Final = DeprecatedConstantEnum(
UnitOfPressure.INHG,
"2025.1",
)
"""Deprecated: please use UnitOfPressure.INHG"""
_DEPRECATED_PRESSURE_PSI: Final = (
_DEPRECATED_PRESSURE_PSI: Final = DeprecatedConstantEnum(
UnitOfPressure.PSI,
"2025.1",
)
@@ -979,12 +971,12 @@ class UnitOfSoundPressure(StrEnum):
WEIGHTED_DECIBEL_A = "dBA"
_DEPRECATED_SOUND_PRESSURE_DB: Final = (
_DEPRECATED_SOUND_PRESSURE_DB: Final = DeprecatedConstantEnum(
UnitOfSoundPressure.DECIBEL,
"2025.1",
)
"""Deprecated: please use UnitOfSoundPressure.DECIBEL"""
_DEPRECATED_SOUND_PRESSURE_WEIGHTED_DBA: Final = (
_DEPRECATED_SOUND_PRESSURE_WEIGHTED_DBA: Final = DeprecatedConstantEnum(
UnitOfSoundPressure.WEIGHTED_DECIBEL_A,
"2025.1",
)
@@ -1010,33 +1002,33 @@ class UnitOfVolume(StrEnum):
British/Imperial fluid ounces are not yet supported"""
_DEPRECATED_VOLUME_LITERS: Final = (
_DEPRECATED_VOLUME_LITERS: Final = DeprecatedConstantEnum(
UnitOfVolume.LITERS,
"2025.1",
)
"""Deprecated: please use UnitOfVolume.LITERS"""
_DEPRECATED_VOLUME_MILLILITERS: Final = (
_DEPRECATED_VOLUME_MILLILITERS: Final = DeprecatedConstantEnum(
UnitOfVolume.MILLILITERS,
"2025.1",
)
"""Deprecated: please use UnitOfVolume.MILLILITERS"""
_DEPRECATED_VOLUME_CUBIC_METERS: Final = (
_DEPRECATED_VOLUME_CUBIC_METERS: Final = DeprecatedConstantEnum(
UnitOfVolume.CUBIC_METERS,
"2025.1",
)
"""Deprecated: please use UnitOfVolume.CUBIC_METERS"""
_DEPRECATED_VOLUME_CUBIC_FEET: Final = (
_DEPRECATED_VOLUME_CUBIC_FEET: Final = DeprecatedConstantEnum(
UnitOfVolume.CUBIC_FEET,
"2025.1",
)
"""Deprecated: please use UnitOfVolume.CUBIC_FEET"""
_DEPRECATED_VOLUME_GALLONS: Final = (
_DEPRECATED_VOLUME_GALLONS: Final = DeprecatedConstantEnum(
UnitOfVolume.GALLONS,
"2025.1",
)
"""Deprecated: please use UnitOfVolume.GALLONS"""
_DEPRECATED_VOLUME_FLUID_OUNCE: Final = (
_DEPRECATED_VOLUME_FLUID_OUNCE: Final = DeprecatedConstantEnum(
UnitOfVolume.FLUID_OUNCES,
"2025.1",
)
@@ -1051,12 +1043,12 @@ class UnitOfVolumeFlowRate(StrEnum):
CUBIC_FEET_PER_MINUTE = "ft³/m"
_DEPRECATED_VOLUME_FLOW_RATE_CUBIC_METERS_PER_HOUR: Final = (
_DEPRECATED_VOLUME_FLOW_RATE_CUBIC_METERS_PER_HOUR: Final = DeprecatedConstantEnum(
UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
"2025.1",
)
"""Deprecated: please use UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR"""
_DEPRECATED_VOLUME_FLOW_RATE_CUBIC_FEET_PER_MINUTE: Final = (
_DEPRECATED_VOLUME_FLOW_RATE_CUBIC_FEET_PER_MINUTE: Final = DeprecatedConstantEnum(
UnitOfVolumeFlowRate.CUBIC_FEET_PER_MINUTE,
"2025.1",
)
@@ -1079,32 +1071,32 @@ class UnitOfMass(StrEnum):
STONES = "st"
_DEPRECATED_MASS_GRAMS: Final = (
_DEPRECATED_MASS_GRAMS: Final = DeprecatedConstantEnum(
UnitOfMass.GRAMS,
"2025.1",
)
"""Deprecated: please use UnitOfMass.GRAMS"""
_DEPRECATED_MASS_KILOGRAMS: Final = (
_DEPRECATED_MASS_KILOGRAMS: Final = DeprecatedConstantEnum(
UnitOfMass.KILOGRAMS,
"2025.1",
)
"""Deprecated: please use UnitOfMass.KILOGRAMS"""
_DEPRECATED_MASS_MILLIGRAMS: Final = (
_DEPRECATED_MASS_MILLIGRAMS: Final = DeprecatedConstantEnum(
UnitOfMass.MILLIGRAMS,
"2025.1",
)
"""Deprecated: please use UnitOfMass.MILLIGRAMS"""
_DEPRECATED_MASS_MICROGRAMS: Final = (
_DEPRECATED_MASS_MICROGRAMS: Final = DeprecatedConstantEnum(
UnitOfMass.MICROGRAMS,
"2025.1",
)
"""Deprecated: please use UnitOfMass.MICROGRAMS"""
_DEPRECATED_MASS_OUNCES: Final = (
_DEPRECATED_MASS_OUNCES: Final = DeprecatedConstantEnum(
UnitOfMass.OUNCES,
"2025.1",
)
"""Deprecated: please use UnitOfMass.OUNCES"""
_DEPRECATED_MASS_POUNDS: Final = (
_DEPRECATED_MASS_POUNDS: Final = DeprecatedConstantEnum(
UnitOfMass.POUNDS,
"2025.1",
)
@@ -1135,12 +1127,12 @@ class UnitOfIrradiance(StrEnum):
# Irradiation units
_DEPRECATED_IRRADIATION_WATTS_PER_SQUARE_METER: Final = (
_DEPRECATED_IRRADIATION_WATTS_PER_SQUARE_METER: Final = DeprecatedConstantEnum(
UnitOfIrradiance.WATTS_PER_SQUARE_METER,
"2025.1",
)
"""Deprecated: please use UnitOfIrradiance.WATTS_PER_SQUARE_METER"""
_DEPRECATED_IRRADIATION_BTUS_PER_HOUR_SQUARE_FOOT: Final = (
_DEPRECATED_IRRADIATION_BTUS_PER_HOUR_SQUARE_FOOT: Final = DeprecatedConstantEnum(
UnitOfIrradiance.BTUS_PER_HOUR_SQUARE_FOOT,
"2025.1",
)
@@ -1185,19 +1177,21 @@ class UnitOfPrecipitationDepth(StrEnum):
# Precipitation units
_DEPRECATED_PRECIPITATION_INCHES: Final = (UnitOfPrecipitationDepth.INCHES, "2025.1")
_DEPRECATED_PRECIPITATION_INCHES: Final = DeprecatedConstantEnum(
UnitOfPrecipitationDepth.INCHES, "2025.1"
)
"""Deprecated: please use UnitOfPrecipitationDepth.INCHES"""
_DEPRECATED_PRECIPITATION_MILLIMETERS: Final = (
_DEPRECATED_PRECIPITATION_MILLIMETERS: Final = DeprecatedConstantEnum(
UnitOfPrecipitationDepth.MILLIMETERS,
"2025.1",
)
"""Deprecated: please use UnitOfPrecipitationDepth.MILLIMETERS"""
_DEPRECATED_PRECIPITATION_MILLIMETERS_PER_HOUR: Final = (
_DEPRECATED_PRECIPITATION_MILLIMETERS_PER_HOUR: Final = DeprecatedConstantEnum(
UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
"2025.1",
)
"""Deprecated: please use UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR"""
_DEPRECATED_PRECIPITATION_INCHES_PER_HOUR: Final = (
_DEPRECATED_PRECIPITATION_INCHES_PER_HOUR: Final = DeprecatedConstantEnum(
UnitOfVolumetricFlux.INCHES_PER_HOUR,
"2025.1",
)
@@ -1223,33 +1217,39 @@ class UnitOfSpeed(StrEnum):
MILES_PER_HOUR = "mph"
_DEPRECATED_SPEED_FEET_PER_SECOND: Final = (UnitOfSpeed.FEET_PER_SECOND, "2025.1")
_DEPRECATED_SPEED_FEET_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfSpeed.FEET_PER_SECOND, "2025.1"
)
"""Deprecated: please use UnitOfSpeed.FEET_PER_SECOND"""
_DEPRECATED_SPEED_METERS_PER_SECOND: Final = (UnitOfSpeed.METERS_PER_SECOND, "2025.1")
_DEPRECATED_SPEED_METERS_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfSpeed.METERS_PER_SECOND, "2025.1"
)
"""Deprecated: please use UnitOfSpeed.METERS_PER_SECOND"""
_DEPRECATED_SPEED_KILOMETERS_PER_HOUR: Final = (
_DEPRECATED_SPEED_KILOMETERS_PER_HOUR: Final = DeprecatedConstantEnum(
UnitOfSpeed.KILOMETERS_PER_HOUR,
"2025.1",
)
"""Deprecated: please use UnitOfSpeed.KILOMETERS_PER_HOUR"""
_DEPRECATED_SPEED_KNOTS: Final = (UnitOfSpeed.KNOTS, "2025.1")
_DEPRECATED_SPEED_KNOTS: Final = DeprecatedConstantEnum(UnitOfSpeed.KNOTS, "2025.1")
"""Deprecated: please use UnitOfSpeed.KNOTS"""
_DEPRECATED_SPEED_MILES_PER_HOUR: Final = (UnitOfSpeed.MILES_PER_HOUR, "2025.1")
_DEPRECATED_SPEED_MILES_PER_HOUR: Final = DeprecatedConstantEnum(
UnitOfSpeed.MILES_PER_HOUR, "2025.1"
)
"""Deprecated: please use UnitOfSpeed.MILES_PER_HOUR"""
_DEPRECATED_SPEED_MILLIMETERS_PER_DAY: Final = (
_DEPRECATED_SPEED_MILLIMETERS_PER_DAY: Final = DeprecatedConstantEnum(
UnitOfVolumetricFlux.MILLIMETERS_PER_DAY,
"2025.1",
)
"""Deprecated: please use UnitOfVolumetricFlux.MILLIMETERS_PER_DAY"""
_DEPRECATED_SPEED_INCHES_PER_DAY: Final = (
_DEPRECATED_SPEED_INCHES_PER_DAY: Final = DeprecatedConstantEnum(
UnitOfVolumetricFlux.INCHES_PER_DAY,
"2025.1",
)
"""Deprecated: please use UnitOfVolumetricFlux.INCHES_PER_DAY"""
_DEPRECATED_SPEED_INCHES_PER_HOUR: Final = (
_DEPRECATED_SPEED_INCHES_PER_HOUR: Final = DeprecatedConstantEnum(
UnitOfVolumetricFlux.INCHES_PER_HOUR,
"2025.1",
)
@@ -1288,47 +1288,87 @@ class UnitOfInformation(StrEnum):
YOBIBYTES = "YiB"
_DEPRECATED_DATA_BITS: Final = (UnitOfInformation.BITS, "2025.1")
_DEPRECATED_DATA_BITS: Final = DeprecatedConstantEnum(UnitOfInformation.BITS, "2025.1")
"""Deprecated: please use UnitOfInformation.BITS"""
_DEPRECATED_DATA_KILOBITS: Final = (UnitOfInformation.KILOBITS, "2025.1")
_DEPRECATED_DATA_KILOBITS: Final = DeprecatedConstantEnum(
UnitOfInformation.KILOBITS, "2025.1"
)
"""Deprecated: please use UnitOfInformation.KILOBITS"""
_DEPRECATED_DATA_MEGABITS: Final = (UnitOfInformation.MEGABITS, "2025.1")
_DEPRECATED_DATA_MEGABITS: Final = DeprecatedConstantEnum(
UnitOfInformation.MEGABITS, "2025.1"
)
"""Deprecated: please use UnitOfInformation.MEGABITS"""
_DEPRECATED_DATA_GIGABITS: Final = (UnitOfInformation.GIGABITS, "2025.1")
_DEPRECATED_DATA_GIGABITS: Final = DeprecatedConstantEnum(
UnitOfInformation.GIGABITS, "2025.1"
)
"""Deprecated: please use UnitOfInformation.GIGABITS"""
_DEPRECATED_DATA_BYTES: Final = (UnitOfInformation.BYTES, "2025.1")
_DEPRECATED_DATA_BYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.BYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.BYTES"""
_DEPRECATED_DATA_KILOBYTES: Final = (UnitOfInformation.KILOBYTES, "2025.1")
_DEPRECATED_DATA_KILOBYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.KILOBYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.KILOBYTES"""
_DEPRECATED_DATA_MEGABYTES: Final = (UnitOfInformation.MEGABYTES, "2025.1")
_DEPRECATED_DATA_MEGABYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.MEGABYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.MEGABYTES"""
_DEPRECATED_DATA_GIGABYTES: Final = (UnitOfInformation.GIGABYTES, "2025.1")
_DEPRECATED_DATA_GIGABYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.GIGABYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.GIGABYTES"""
_DEPRECATED_DATA_TERABYTES: Final = (UnitOfInformation.TERABYTES, "2025.1")
_DEPRECATED_DATA_TERABYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.TERABYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.TERABYTES"""
_DEPRECATED_DATA_PETABYTES: Final = (UnitOfInformation.PETABYTES, "2025.1")
_DEPRECATED_DATA_PETABYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.PETABYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.PETABYTES"""
_DEPRECATED_DATA_EXABYTES: Final = (UnitOfInformation.EXABYTES, "2025.1")
_DEPRECATED_DATA_EXABYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.EXABYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.EXABYTES"""
_DEPRECATED_DATA_ZETTABYTES: Final = (UnitOfInformation.ZETTABYTES, "2025.1")
_DEPRECATED_DATA_ZETTABYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.ZETTABYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.ZETTABYTES"""
_DEPRECATED_DATA_YOTTABYTES: Final = (UnitOfInformation.YOTTABYTES, "2025.1")
_DEPRECATED_DATA_YOTTABYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.YOTTABYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.YOTTABYTES"""
_DEPRECATED_DATA_KIBIBYTES: Final = (UnitOfInformation.KIBIBYTES, "2025.1")
_DEPRECATED_DATA_KIBIBYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.KIBIBYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.KIBIBYTES"""
_DEPRECATED_DATA_MEBIBYTES: Final = (UnitOfInformation.MEBIBYTES, "2025.1")
_DEPRECATED_DATA_MEBIBYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.MEBIBYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.MEBIBYTES"""
_DEPRECATED_DATA_GIBIBYTES: Final = (UnitOfInformation.GIBIBYTES, "2025.1")
_DEPRECATED_DATA_GIBIBYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.GIBIBYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.GIBIBYTES"""
_DEPRECATED_DATA_TEBIBYTES: Final = (UnitOfInformation.TEBIBYTES, "2025.1")
_DEPRECATED_DATA_TEBIBYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.TEBIBYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.TEBIBYTES"""
_DEPRECATED_DATA_PEBIBYTES: Final = (UnitOfInformation.PEBIBYTES, "2025.1")
_DEPRECATED_DATA_PEBIBYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.PEBIBYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.PEBIBYTES"""
_DEPRECATED_DATA_EXBIBYTES: Final = (UnitOfInformation.EXBIBYTES, "2025.1")
_DEPRECATED_DATA_EXBIBYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.EXBIBYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.EXBIBYTES"""
_DEPRECATED_DATA_ZEBIBYTES: Final = (UnitOfInformation.ZEBIBYTES, "2025.1")
_DEPRECATED_DATA_ZEBIBYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.ZEBIBYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.ZEBIBYTES"""
_DEPRECATED_DATA_YOBIBYTES: Final = (UnitOfInformation.YOBIBYTES, "2025.1")
_DEPRECATED_DATA_YOBIBYTES: Final = DeprecatedConstantEnum(
UnitOfInformation.YOBIBYTES, "2025.1"
)
"""Deprecated: please use UnitOfInformation.YOBIBYTES"""
@@ -1349,57 +1389,57 @@ class UnitOfDataRate(StrEnum):
GIBIBYTES_PER_SECOND = "GiB/s"
_DEPRECATED_DATA_RATE_BITS_PER_SECOND: Final = (
_DEPRECATED_DATA_RATE_BITS_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfDataRate.BITS_PER_SECOND,
"2025.1",
)
"""Deprecated: please use UnitOfDataRate.BITS_PER_SECOND"""
_DEPRECATED_DATA_RATE_KILOBITS_PER_SECOND: Final = (
_DEPRECATED_DATA_RATE_KILOBITS_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfDataRate.KILOBITS_PER_SECOND,
"2025.1",
)
"""Deprecated: please use UnitOfDataRate.KILOBITS_PER_SECOND"""
_DEPRECATED_DATA_RATE_MEGABITS_PER_SECOND: Final = (
_DEPRECATED_DATA_RATE_MEGABITS_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfDataRate.MEGABITS_PER_SECOND,
"2025.1",
)
"""Deprecated: please use UnitOfDataRate.MEGABITS_PER_SECOND"""
_DEPRECATED_DATA_RATE_GIGABITS_PER_SECOND: Final = (
_DEPRECATED_DATA_RATE_GIGABITS_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfDataRate.GIGABITS_PER_SECOND,
"2025.1",
)
"""Deprecated: please use UnitOfDataRate.GIGABITS_PER_SECOND"""
_DEPRECATED_DATA_RATE_BYTES_PER_SECOND: Final = (
_DEPRECATED_DATA_RATE_BYTES_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfDataRate.BYTES_PER_SECOND,
"2025.1",
)
"""Deprecated: please use UnitOfDataRate.BYTES_PER_SECOND"""
_DEPRECATED_DATA_RATE_KILOBYTES_PER_SECOND: Final = (
_DEPRECATED_DATA_RATE_KILOBYTES_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfDataRate.KILOBYTES_PER_SECOND,
"2025.1",
)
"""Deprecated: please use UnitOfDataRate.KILOBYTES_PER_SECOND"""
_DEPRECATED_DATA_RATE_MEGABYTES_PER_SECOND: Final = (
_DEPRECATED_DATA_RATE_MEGABYTES_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfDataRate.MEGABYTES_PER_SECOND,
"2025.1",
)
"""Deprecated: please use UnitOfDataRate.MEGABYTES_PER_SECOND"""
_DEPRECATED_DATA_RATE_GIGABYTES_PER_SECOND: Final = (
_DEPRECATED_DATA_RATE_GIGABYTES_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfDataRate.GIGABYTES_PER_SECOND,
"2025.1",
)
"""Deprecated: please use UnitOfDataRate.GIGABYTES_PER_SECOND"""
_DEPRECATED_DATA_RATE_KIBIBYTES_PER_SECOND: Final = (
_DEPRECATED_DATA_RATE_KIBIBYTES_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfDataRate.KIBIBYTES_PER_SECOND,
"2025.1",
)
"""Deprecated: please use UnitOfDataRate.KIBIBYTES_PER_SECOND"""
_DEPRECATED_DATA_RATE_MEBIBYTES_PER_SECOND: Final = (
_DEPRECATED_DATA_RATE_MEBIBYTES_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfDataRate.MEBIBYTES_PER_SECOND,
"2025.1",
)
"""Deprecated: please use UnitOfDataRate.MEBIBYTES_PER_SECOND"""
_DEPRECATED_DATA_RATE_GIBIBYTES_PER_SECOND: Final = (
_DEPRECATED_DATA_RATE_GIBIBYTES_PER_SECOND: Final = DeprecatedConstantEnum(
UnitOfDataRate.GIBIBYTES_PER_SECOND,
"2025.1",
)
@@ -1540,8 +1580,12 @@ class EntityCategory(StrEnum):
# ENTITY_CATEGOR* below are deprecated as of 2021.12
# use the EntityCategory enum instead.
_DEPRECATED_ENTITY_CATEGORY_CONFIG: Final = (EntityCategory.CONFIG, "2025.1")
_DEPRECATED_ENTITY_CATEGORY_DIAGNOSTIC: Final = (EntityCategory.DIAGNOSTIC, "2025.1")
_DEPRECATED_ENTITY_CATEGORY_CONFIG: Final = DeprecatedConstantEnum(
EntityCategory.CONFIG, "2025.1"
)
_DEPRECATED_ENTITY_CATEGORY_DIAGNOSTIC: Final = DeprecatedConstantEnum(
EntityCategory.DIAGNOSTIC, "2025.1"
)
ENTITY_CATEGORIES: Final[list[str]] = [cls.value for cls in EntityCategory]
# The ID of the Home Assistant Media Player Cast App
@@ -1558,3 +1602,10 @@ SIGNAL_BOOTSTRAP_INTEGRATIONS = "bootstrap_integrations"
FORMAT_DATE: Final = "%Y-%m-%d"
FORMAT_TIME: Final = "%H:%M:%S"
FORMAT_DATETIME: Final = f"{FORMAT_DATE} {FORMAT_TIME}"
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+19 -35
View File
@@ -81,6 +81,12 @@ from .exceptions import (
ServiceNotFound,
Unauthorized,
)
from .helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
from .helpers.json import json_dumps
from .util import dt as dt_util, location
from .util.async_ import (
@@ -147,41 +153,11 @@ class ConfigSource(enum.StrEnum):
# SOURCE_* are deprecated as of Home Assistant 2022.2, use ConfigSource instead
_DEPRECATED_SOURCE_DISCOVERED = (ConfigSource.DISCOVERED, "2025.1")
_DEPRECATED_SOURCE_STORAGE = (ConfigSource.STORAGE, "2025.1")
_DEPRECATED_SOURCE_YAML = (ConfigSource.YAML, "2025.1")
# Can be removed if no deprecated constant are in this module anymore
def __getattr__(name: str) -> Any:
"""Check if the not found name is a deprecated constant.
If it is, print a deprecation warning and return the value of the constant.
Otherwise raise AttributeError.
"""
module_globals = globals()
if f"_DEPRECATED_{name}" not in module_globals:
raise AttributeError(f"Module {__name__} has no attribute {name!r}")
# Avoid circular import
from .helpers.deprecation import ( # pylint: disable=import-outside-toplevel
check_if_deprecated_constant,
)
return check_if_deprecated_constant(name, module_globals)
# Can be removed if no deprecated constant are in this module anymore
def __dir__() -> list[str]:
"""Return dir() with deprecated constants."""
# Copied method from homeassistant.helpers.deprecattion#dir_with_deprecated_constants to avoid import cycle
module_globals = globals()
return list(module_globals) + [
name.removeprefix("_DEPRECATED_")
for name in module_globals
if name.startswith("_DEPRECATED_")
]
_DEPRECATED_SOURCE_DISCOVERED = DeprecatedConstantEnum(
ConfigSource.DISCOVERED, "2025.1"
)
_DEPRECATED_SOURCE_STORAGE = DeprecatedConstantEnum(ConfigSource.STORAGE, "2025.1")
_DEPRECATED_SOURCE_YAML = DeprecatedConstantEnum(ConfigSource.YAML, "2025.1")
# How long to wait until things that run on startup have to finish.
@@ -2554,3 +2530,11 @@ class Config:
if self._original_unit_system:
data["unit_system"] = self._original_unit_system
return await super().async_save(data)
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = functools.partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = functools.partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+9 -4
View File
@@ -17,6 +17,7 @@ from .core import HomeAssistant, callback
from .exceptions import HomeAssistantError
from .helpers.deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -59,10 +60,6 @@ _DEPRECATED_RESULT_TYPE_SHOW_PROGRESS_DONE = DeprecatedConstantEnum(
)
_DEPRECATED_RESULT_TYPE_MENU = DeprecatedConstantEnum(FlowResultType.MENU, "2025.1")
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
# Event that is fired when a flow is progressed via external or progress source.
EVENT_DATA_ENTRY_FLOW_PROGRESSED = "data_entry_flow_progressed"
@@ -700,3 +697,11 @@ def _create_abort_data(
reason=reason,
description_placeholders=description_placeholders,
)
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+22 -21
View File
@@ -9,12 +9,6 @@ import inspect
import logging
from typing import Any, NamedTuple, ParamSpec, TypeVar
from homeassistant.core import HomeAssistant, async_get_hass
from homeassistant.exceptions import HomeAssistantError
from homeassistant.loader import async_suggest_report_issue
from .frame import MissingIntegrationFrame, get_integration_frame
_ObjectT = TypeVar("_ObjectT", bound=object)
_R = TypeVar("_R")
_P = ParamSpec("_P")
@@ -175,6 +169,13 @@ def _print_deprecation_warning_internal(
*,
log_when_no_integration_is_found: bool,
) -> None:
# pylint: disable=import-outside-toplevel
from homeassistant.core import HomeAssistant, async_get_hass
from homeassistant.exceptions import HomeAssistantError
from homeassistant.loader import async_suggest_report_issue
from .frame import MissingIntegrationFrame, get_integration_frame
logger = logging.getLogger(module_name)
if breaks_in_ha_version:
breaks_in = f" which will be removed in HA Core {breaks_in_ha_version}"
@@ -265,18 +266,6 @@ def check_if_deprecated_constant(name: str, module_globals: dict[str, Any]) -> A
f"{deprecated_const.enum.__class__.__name__}.{deprecated_const.enum.name}"
)
breaks_in_ha_version = deprecated_const.breaks_in_ha_version
elif isinstance(deprecated_const, tuple):
# Use DeprecatedConstant and DeprecatedConstant instead, where possible
# Used to avoid import cycles.
if len(deprecated_const) == 3:
value = deprecated_const[0]
replacement = deprecated_const[1]
breaks_in_ha_version = deprecated_const[2]
elif len(deprecated_const) == 2 and isinstance(deprecated_const[0], Enum):
enum = deprecated_const[0]
value = enum.value
replacement = f"{enum.__class__.__name__}.{enum.name}"
breaks_in_ha_version = deprecated_const[1]
if value is None or replacement is None:
msg = (
@@ -303,10 +292,22 @@ def check_if_deprecated_constant(name: str, module_globals: dict[str, Any]) -> A
return value
def dir_with_deprecated_constants(module_globals: dict[str, Any]) -> list[str]:
def dir_with_deprecated_constants(module_globals_keys: list[str]) -> list[str]:
"""Return dir() with deprecated constants."""
return list(module_globals) + [
return module_globals_keys + [
name.removeprefix(_PREFIX_DEPRECATED)
for name in module_globals
for name in module_globals_keys
if name.startswith(_PREFIX_DEPRECATED)
]
def all_with_deprecated_constants(module_globals: dict[str, Any]) -> list[str]:
"""Generate a list for __all___ with deprecated constants."""
# Iterate over a copy in case the globals dict is mutated by another thread
# while we loop over it.
module_globals_keys = list(module_globals)
return [itm for itm in module_globals_keys if not itm.startswith("_")] + [
name.removeprefix(_PREFIX_DEPRECATED)
for name in module_globals_keys
if name.startswith(_PREFIX_DEPRECATED)
]
+9 -4
View File
@@ -24,6 +24,7 @@ from . import storage
from .debounce import Debouncer
from .deprecation import (
DeprecatedConstantEnum,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
@@ -75,10 +76,6 @@ _DEPRECATED_DISABLED_INTEGRATION = DeprecatedConstantEnum(
)
_DEPRECATED_DISABLED_USER = DeprecatedConstantEnum(DeviceEntryDisabler.USER, "2025.1")
# Both can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(dir_with_deprecated_constants, module_globals=globals())
class DeviceInfo(TypedDict, total=False):
"""Entity device information for device registry."""
@@ -1113,3 +1110,11 @@ def _normalize_connections(connections: set[tuple[str, str]]) -> set[tuple[str,
(key, format_mac(value)) if key == CONNECTION_NETWORK_MAC else (key, value)
for key, value in connections
}
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())
+1 -1
View File
@@ -292,7 +292,7 @@ class CachedProperties(type):
Pop cached_properties and store it in the namespace.
"""
namespace["_CachedProperties__cached_properties"] = cached_properties or set()
return super().__new__(mcs, name, bases, namespace)
return super().__new__(mcs, name, bases, namespace, **kwargs)
def __init__(
cls,
+3 -3
View File
@@ -24,12 +24,12 @@ dbus-fast==2.21.0
fnv-hash-fast==0.5.0
ha-av==10.1.1
ha-ffmpeg==3.1.0
habluetooth==2.0.1
habluetooth==2.0.2
hass-nabucasa==0.75.1
hassil==1.5.1
home-assistant-bluetooth==1.11.0
home-assistant-frontend==20240102.0
home-assistant-intents==2023.12.05
home-assistant-frontend==20240104.0
home-assistant-intents==2024.1.2
httpx==0.26.0
ifaddr==0.2.0
janus==1.0.0
+10
View File
@@ -250,6 +250,16 @@ disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.airthings_ble.*]
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_decorators = true
disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.airvisual.*]
check_untyped_defs = true
disallow_incomplete_defs = true
+6 -2
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "homeassistant"
version = "2024.1.0b5"
version = "2024.1.2"
license = {text = "Apache-2.0"}
description = "Open-source home automation platform running on Python 3."
readme = "README.rst"
@@ -176,7 +176,8 @@ disable = [
"duplicate-bases", # PLE0241
"format-needs-mapping", # F502
"function-redefined", # F811
"invalid-all-format", # PLE0605
# Needed because ruff does not understand type of __all__ generated by a function
# "invalid-all-format", # PLE0605
"invalid-all-object", # PLE0604
"invalid-character-backspace", # PLE2510
"invalid-character-esc", # PLE2513
@@ -673,6 +674,9 @@ ignore = [
"COM819",
"ISC001",
"ISC002",
# Disabled because ruff does not understand type of __all__ generated by a function
"PLE0605",
]
[tool.ruff.flake8-import-conventions.extend-aliases]
+9 -9
View File
@@ -257,7 +257,7 @@ aioguardian==2022.07.0
aioharmony==0.2.10
# homeassistant.components.homekit_controller
aiohomekit==3.1.1
aiohomekit==3.1.2
# homeassistant.components.http
aiohttp-fast-url-dispatcher==0.3.0
@@ -716,7 +716,7 @@ dovado==0.4.1
dremel3dpy==2.1.1
# homeassistant.components.drop_connect
dropmqttapi==1.0.1
dropmqttapi==1.0.2
# homeassistant.components.dsmr
dsmr-parser==1.3.1
@@ -998,7 +998,7 @@ ha-philipsjs==3.1.1
habitipy==0.2.0
# homeassistant.components.bluetooth
habluetooth==2.0.1
habluetooth==2.0.2
# homeassistant.components.cloud
hass-nabucasa==0.75.1
@@ -1038,10 +1038,10 @@ hole==0.8.0
holidays==0.39
# homeassistant.components.frontend
home-assistant-frontend==20240102.0
home-assistant-frontend==20240104.0
# homeassistant.components.conversation
home-assistant-intents==2023.12.05
home-assistant-intents==2024.1.2
# homeassistant.components.home_connect
homeconnect==0.7.2
@@ -1425,7 +1425,7 @@ openhomedevice==2.2.0
opensensemap-api==0.2.0
# homeassistant.components.enigma2
openwebifpy==4.0.2
openwebifpy==4.0.4
# homeassistant.components.luci
openwrt-luci-rpc==1.1.16
@@ -1443,7 +1443,7 @@ oralb-ble==0.17.6
oru==0.1.11
# homeassistant.components.orvibo
orvibo==1.1.1
orvibo==1.1.2
# homeassistant.components.ourgroceries
ourgroceries==1.5.4
@@ -2241,7 +2241,7 @@ python-smarttub==0.0.36
python-songpal==0.16
# homeassistant.components.tado
python-tado==0.17.0
python-tado==0.17.3
# homeassistant.components.telegram_bot
python-telegram-bot==13.1
@@ -2893,7 +2893,7 @@ zigpy==0.60.4
zm-py==0.5.2
# homeassistant.components.zwave_js
zwave-js-server-python==0.55.2
zwave-js-server-python==0.55.3
# homeassistant.components.zwave_me
zwave-me-ws==0.4.3
+7 -7
View File
@@ -233,7 +233,7 @@ aioguardian==2022.07.0
aioharmony==0.2.10
# homeassistant.components.homekit_controller
aiohomekit==3.1.1
aiohomekit==3.1.2
# homeassistant.components.http
aiohttp-fast-url-dispatcher==0.3.0
@@ -585,7 +585,7 @@ discovery30303==0.2.1
dremel3dpy==2.1.1
# homeassistant.components.drop_connect
dropmqttapi==1.0.1
dropmqttapi==1.0.2
# homeassistant.components.dsmr
dsmr-parser==1.3.1
@@ -803,7 +803,7 @@ ha-philipsjs==3.1.1
habitipy==0.2.0
# homeassistant.components.bluetooth
habluetooth==2.0.1
habluetooth==2.0.2
# homeassistant.components.cloud
hass-nabucasa==0.75.1
@@ -831,10 +831,10 @@ hole==0.8.0
holidays==0.39
# homeassistant.components.frontend
home-assistant-frontend==20240102.0
home-assistant-frontend==20240104.0
# homeassistant.components.conversation
home-assistant-intents==2023.12.05
home-assistant-intents==2024.1.2
# homeassistant.components.home_connect
homeconnect==0.7.2
@@ -1696,7 +1696,7 @@ python-smarttub==0.0.36
python-songpal==0.16
# homeassistant.components.tado
python-tado==0.17.0
python-tado==0.17.3
# homeassistant.components.telegram_bot
python-telegram-bot==13.1
@@ -2189,7 +2189,7 @@ zigpy-znp==0.12.1
zigpy==0.60.4
# homeassistant.components.zwave_js
zwave-js-server-python==0.55.2
zwave-js-server-python==0.55.3
# homeassistant.components.zwave_me
zwave-me-ws==0.4.3
+12 -2
View File
@@ -92,7 +92,7 @@ import homeassistant.util.uuid as uuid_util
import homeassistant.util.yaml.loader as yaml_loader
from tests.testing_config.custom_components.test_constant_deprecation import (
import_deprecated_costant,
import_deprecated_constant,
)
_LOGGER = logging.getLogger(__name__)
@@ -1482,6 +1482,7 @@ def import_and_test_deprecated_constant_enum(
- Assert value is the same as the replacement
- Assert a warning is logged
- Assert the deprecated constant is included in the modules.__dir__()
- Assert the deprecated constant is included in the modules.__all__()
"""
import_and_test_deprecated_constant(
caplog,
@@ -1507,8 +1508,9 @@ def import_and_test_deprecated_constant(
- Assert value is the same as the replacement
- Assert a warning is logged
- Assert the deprecated constant is included in the modules.__dir__()
- Assert the deprecated constant is included in the modules.__all__()
"""
value = import_deprecated_costant(module, constant_name)
value = import_deprecated_constant(module, constant_name)
assert value == replacement
assert (
module.__name__,
@@ -1523,3 +1525,11 @@ def import_and_test_deprecated_constant(
# verify deprecated constant is included in dir()
assert constant_name in dir(module)
assert constant_name in module.__all__
def help_test_all(module: ModuleType) -> None:
"""Test module.__all__ is correctly set."""
assert set(module.__all__) == {
itm for itm in module.__dir__() if not itm.startswith("_")
}
@@ -6,7 +6,16 @@ import pytest
from homeassistant.components import alarm_control_panel
from tests.common import import_and_test_deprecated_constant_enum
from tests.common import help_test_all, import_and_test_deprecated_constant_enum
@pytest.mark.parametrize(
"module",
[alarm_control_panel, alarm_control_panel.const],
)
def test_all(module: ModuleType) -> None:
"""Test module.__all__ is correctly set."""
help_test_all(module)
@pytest.mark.parametrize(
+6
View File
@@ -59,6 +59,7 @@ from tests.common import (
async_capture_events,
async_fire_time_changed,
async_mock_service,
help_test_all,
import_and_test_deprecated_constant,
mock_restore_cache,
)
@@ -2569,6 +2570,11 @@ async def test_websocket_config(
assert msg["error"]["code"] == "not_found"
def test_all() -> None:
"""Test module.__all__ is correctly set."""
help_test_all(automation)
@pytest.mark.parametrize(
("constant_name", "replacement"),
[
@@ -14,6 +14,7 @@ from tests.common import (
MockConfigEntry,
MockModule,
MockPlatform,
help_test_all,
import_and_test_deprecated_constant_enum,
mock_config_flow,
mock_integration,
@@ -197,6 +198,11 @@ async def test_entity_category_config_raises_error(
)
def test_all() -> None:
"""Test module.__all__ is correctly set."""
help_test_all(binary_sensor)
@pytest.mark.parametrize(
"device_class",
list(binary_sensor.BinarySensorDeviceClass),
@@ -367,6 +367,38 @@ async def test_we_switch_adapters_on_failure(
cancel_hci1()
async def test_passing_subclassed_str_as_address(
hass: HomeAssistant,
two_adapters: None,
enable_bluetooth: None,
install_bleak_catcher,
) -> None:
"""Ensure the client wrapper can handle a subclassed str as the address."""
_, cancel_hci0, cancel_hci1 = _generate_scanners_with_fake_devices(hass)
class SubclassedStr(str):
pass
address = SubclassedStr("00:00:00:00:00:01")
client = bleak.BleakClient(address)
class FakeBleakClient(BaseFakeBleakClient):
"""Fake bleak client."""
async def connect(self, *args, **kwargs):
"""Connect."""
return True
with patch(
"habluetooth.wrappers.get_platform_client_backend_type",
return_value=FakeBleakClient,
):
assert await client.connect() is True
cancel_hci0()
cancel_hci1()
async def test_raise_after_shutdown(
hass: HomeAssistant,
two_adapters: None,
+10 -1
View File
@@ -27,7 +27,7 @@ from homeassistant.setup import async_setup_component
from .common import EMPTY_8_6_JPEG, WEBRTC_ANSWER, mock_turbo_jpeg
from tests.common import import_and_test_deprecated_constant_enum
from tests.common import help_test_all, import_and_test_deprecated_constant_enum
from tests.typing import ClientSessionGenerator, WebSocketGenerator
STREAM_SOURCE = "rtsp://127.0.0.1/stream"
@@ -962,6 +962,15 @@ async def test_use_stream_for_stills(
assert await resp.read() == b"stream_keyframe_image"
@pytest.mark.parametrize(
"module",
[camera, camera.const],
)
def test_all(module: ModuleType) -> None:
"""Test module.__all__ is correctly set."""
help_test_all(module)
@pytest.mark.parametrize(
"enum",
list(camera.const.StreamType),
+10
View File
@@ -36,6 +36,7 @@ from tests.common import (
MockModule,
MockPlatform,
async_mock_service,
help_test_all,
import_and_test_deprecated_constant,
import_and_test_deprecated_constant_enum,
mock_integration,
@@ -157,6 +158,15 @@ def _create_tuples(enum: Enum, constant_prefix: str) -> list[tuple[Enum, str]]:
return result
@pytest.mark.parametrize(
"module",
[climate, climate.const],
)
def test_all(module: ModuleType) -> None:
"""Test module.__all__ is correctly set."""
help_test_all(module)
@pytest.mark.parametrize(
("enum", "constant_prefix"),
_create_tuples(climate.ClimateEntityFeature, "SUPPORT_")
+1
View File
@@ -109,6 +109,7 @@ async def cloud_fixture() -> AsyncGenerator[MagicMock, None]:
is_connected = PropertyMock(side_effect=mock_is_connected)
type(mock_cloud).is_connected = is_connected
type(mock_cloud.iot).connected = is_connected
# Properties that we mock as attributes.
mock_cloud.expiration_date = utcnow()
+62 -2
View File
@@ -1,12 +1,18 @@
"""Test the cloud component."""
from collections.abc import Callable, Coroutine
from typing import Any
from unittest.mock import patch
from unittest.mock import MagicMock, patch
from hass_nabucasa import Cloud
import pytest
from homeassistant.components import cloud
from homeassistant.components.cloud.const import DOMAIN
from homeassistant.components.cloud import (
CloudNotAvailable,
CloudNotConnected,
async_get_or_create_cloudhook,
)
from homeassistant.components.cloud.const import DOMAIN, PREF_CLOUDHOOKS
from homeassistant.components.cloud.prefs import STORAGE_KEY
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.core import Context, HomeAssistant
@@ -214,3 +220,57 @@ async def test_remote_ui_url(hass: HomeAssistant, mock_cloud_fixture) -> None:
cl.client.prefs._prefs["remote_domain"] = "example.com"
assert cloud.async_remote_ui_url(hass) == "https://example.com"
async def test_async_get_or_create_cloudhook(
hass: HomeAssistant,
cloud: MagicMock,
set_cloud_prefs: Callable[[dict[str, Any]], Coroutine[Any, Any, None]],
) -> None:
"""Test async_get_or_create_cloudhook."""
assert await async_setup_component(hass, "cloud", {"cloud": {}})
await hass.async_block_till_done()
webhook_id = "mock-webhook-id"
cloudhook_url = "https://cloudhook.nabu.casa/abcdefg"
with patch(
"homeassistant.components.cloud.async_create_cloudhook",
return_value=cloudhook_url,
) as async_create_cloudhook_mock:
# create cloudhook as it does not exist
assert (await async_get_or_create_cloudhook(hass, webhook_id)) == cloudhook_url
async_create_cloudhook_mock.assert_called_once_with(hass, webhook_id)
await set_cloud_prefs(
{
PREF_CLOUDHOOKS: {
webhook_id: {
"webhook_id": webhook_id,
"cloudhook_id": "random-id",
"cloudhook_url": cloudhook_url,
"managed": True,
}
}
}
)
async_create_cloudhook_mock.reset_mock()
# get cloudhook as it exists
assert await async_get_or_create_cloudhook(hass, webhook_id) == cloudhook_url
async_create_cloudhook_mock.assert_not_called()
# Simulate logged out
cloud.id_token = None
# Not logged in
with pytest.raises(CloudNotAvailable):
await async_get_or_create_cloudhook(hass, webhook_id)
# Simulate disconnected
cloud.iot.state = "disconnected"
# Not connected
with pytest.raises(CloudNotConnected):
await async_get_or_create_cloudhook(hass, webhook_id)
@@ -249,7 +249,7 @@
'speech': dict({
'plain': dict({
'extra_data': None,
'speech': 'Turned on light',
'speech': 'Turned on the light',
}),
}),
}),
@@ -279,7 +279,7 @@
'speech': dict({
'plain': dict({
'extra_data': None,
'speech': 'Turned on light',
'speech': 'Turned on the light',
}),
}),
}),
@@ -309,7 +309,7 @@
'speech': dict({
'plain': dict({
'extra_data': None,
'speech': 'Turned on light',
'speech': 'Turned on the light',
}),
}),
}),
@@ -339,7 +339,7 @@
'speech': dict({
'plain': dict({
'extra_data': None,
'speech': 'Turned on light',
'speech': 'Turned on the light',
}),
}),
}),
+15 -15
View File
@@ -85,7 +85,7 @@ async def test_http_processing_intent(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -135,7 +135,7 @@ async def test_http_processing_intent_target_ha_agent(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -186,7 +186,7 @@ async def test_http_processing_intent_entity_added_removed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -222,7 +222,7 @@ async def test_http_processing_intent_entity_added_removed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -255,7 +255,7 @@ async def test_http_processing_intent_entity_added_removed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -331,7 +331,7 @@ async def test_http_processing_intent_alias_added_removed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -364,7 +364,7 @@ async def test_http_processing_intent_alias_added_removed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -449,7 +449,7 @@ async def test_http_processing_intent_entity_renamed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -483,7 +483,7 @@ async def test_http_processing_intent_entity_renamed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -540,7 +540,7 @@ async def test_http_processing_intent_entity_renamed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -624,7 +624,7 @@ async def test_http_processing_intent_entity_exposed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -656,7 +656,7 @@ async def test_http_processing_intent_entity_exposed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -740,7 +740,7 @@ async def test_http_processing_intent_entity_exposed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -769,7 +769,7 @@ async def test_http_processing_intent_entity_exposed(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
@@ -855,7 +855,7 @@ async def test_http_processing_intent_conversion_not_expose_new(
"speech": {
"plain": {
"extra_data": None,
"speech": "Turned on light",
"speech": "Turned on the light",
}
},
"language": hass.config.language,
+6 -1
View File
@@ -16,7 +16,7 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from tests.common import import_and_test_deprecated_constant_enum
from tests.common import help_test_all, import_and_test_deprecated_constant_enum
async def test_services(hass: HomeAssistant, enable_custom_integrations: None) -> None:
@@ -127,6 +127,11 @@ def _create_tuples(enum: Enum, constant_prefix: str) -> list[tuple[Enum, str]]:
return result
def test_all() -> None:
"""Test module.__all__ is correctly set."""
help_test_all(cover)
@pytest.mark.parametrize(
("enum", "constant_prefix"),
_create_tuples(cover.CoverEntityFeature, "SUPPORT_")
@@ -34,6 +34,7 @@ from . import common
from tests.common import (
assert_setup_component,
async_fire_time_changed,
help_test_all,
import_and_test_deprecated_constant_enum,
mock_registry,
mock_restore_cache,
@@ -685,6 +686,15 @@ def test_see_schema_allowing_ios_calls() -> None:
)
@pytest.mark.parametrize(
"module",
[device_tracker, device_tracker.const],
)
def test_all(module: ModuleType) -> None:
"""Test module.__all__ is correctly set."""
help_test_all(module)
@pytest.mark.parametrize(("enum"), list(SourceType))
@pytest.mark.parametrize(
"module",
+6 -1
View File
@@ -15,7 +15,7 @@ from homeassistant.core import HomeAssistant
import homeassistant.helpers.entity_registry as er
from homeassistant.setup import async_setup_component
from tests.common import import_and_test_deprecated_constant_enum
from tests.common import help_test_all, import_and_test_deprecated_constant_enum
from tests.testing_config.custom_components.test.fan import MockFan
@@ -150,6 +150,11 @@ async def test_preset_mode_validation(
assert exc.value.translation_key == "not_valid_preset_mode"
def test_all() -> None:
"""Test module.__all__ is correctly set."""
help_test_all(fan)
@pytest.mark.parametrize(("enum"), list(fan.FanEntityFeature))
def test_deprecated_constants(
caplog: pytest.LogCaptureFixture,
+15 -1
View File
@@ -7,12 +7,13 @@ import pytest
from homeassistant.components import humidifier
from homeassistant.components.humidifier import (
ATTR_MODE,
HumidifierEntity,
HumidifierEntityFeature,
)
from homeassistant.core import HomeAssistant
from tests.common import import_and_test_deprecated_constant_enum
from tests.common import help_test_all, import_and_test_deprecated_constant_enum
class MockHumidifierEntity(HumidifierEntity):
@@ -53,6 +54,15 @@ def _create_tuples(enum: Enum, constant_prefix: str) -> list[tuple[Enum, str]]:
return result
@pytest.mark.parametrize(
"module",
[humidifier, humidifier.const],
)
def test_all(module: ModuleType) -> None:
"""Test module.__all__ is correctly set."""
help_test_all(module)
@pytest.mark.parametrize(
("enum", "constant_prefix"),
_create_tuples(humidifier.HumidifierEntityFeature, "SUPPORT_")
@@ -75,6 +85,8 @@ def test_deprecated_supported_features_ints(caplog: pytest.LogCaptureFixture) ->
"""Test deprecated supported features ints."""
class MockHumidifierEntity(HumidifierEntity):
_attr_mode = "mode1"
@property
def supported_features(self) -> int:
"""Return supported features."""
@@ -89,3 +101,5 @@ def test_deprecated_supported_features_ints(caplog: pytest.LogCaptureFixture) ->
caplog.clear()
assert entity.supported_features_compat is HumidifierEntityFeature(1)
assert "is using deprecated supported features values" not in caplog.text
assert entity.state_attributes[ATTR_MODE] == "mode1"
+6 -1
View File
@@ -28,7 +28,7 @@ from homeassistant.helpers.typing import UNDEFINED, UndefinedType
from .conftest import MockLock
from tests.common import import_and_test_deprecated_constant_enum
from tests.common import help_test_all, import_and_test_deprecated_constant_enum
async def help_test_async_lock_service(
@@ -371,6 +371,11 @@ async def test_lock_with_illegal_default_code(
assert exc.value.translation_key == "add_default_code"
def test_all() -> None:
"""Test module.__all__ is correctly set."""
help_test_all(lock)
@pytest.mark.parametrize(("enum"), list(LockEntityFeature))
def test_deprecated_constants(
caplog: pytest.LogCaptureFixture,
@@ -51,7 +51,11 @@ async def test_significant_state_change() -> None:
{ATTR_ENTITY_PICTURE_LOCAL: "new_value"},
True,
),
({ATTR_GROUP_MEMBERS: "old_value"}, {ATTR_GROUP_MEMBERS: "new_value"}, True),
(
{ATTR_GROUP_MEMBERS: ["old1", "old2"]},
{ATTR_GROUP_MEMBERS: ["old1", "new"]},
False,
),
({ATTR_INPUT_SOURCE: "old_value"}, {ATTR_INPUT_SOURCE: "new_value"}, True),
(
{ATTR_MEDIA_ALBUM_ARTIST: "old_value"},
+6 -4
View File
@@ -88,15 +88,17 @@ async def _test_create_cloud_hook(
), patch(
"homeassistant.components.cloud.async_is_connected", return_value=True
), patch(
"homeassistant.components.cloud.async_create_cloudhook", autospec=True
) as mock_create_cloudhook:
"homeassistant.components.cloud.async_get_or_create_cloudhook", autospec=True
) as mock_async_get_or_create_cloudhook:
cloud_hook = "https://hook-url"
mock_create_cloudhook.return_value = cloud_hook
mock_async_get_or_create_cloudhook.return_value = cloud_hook
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert config_entry.state is ConfigEntryState.LOADED
await additional_steps(config_entry, mock_create_cloudhook, cloud_hook)
await additional_steps(
config_entry, mock_async_get_or_create_cloudhook, cloud_hook
)
async def test_create_cloud_hook_on_setup(
+6 -1
View File
@@ -4,7 +4,12 @@ import pytest
from homeassistant.components.number import const
from tests.common import import_and_test_deprecated_constant_enum
from tests.common import help_test_all, import_and_test_deprecated_constant_enum
def test_all() -> None:
"""Test module.__all__ is correctly set."""
help_test_all(const)
@pytest.mark.parametrize(("enum"), list(const.NumberMode))
+10 -1
View File
@@ -22,7 +22,11 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant
from tests.common import async_mock_service, import_and_test_deprecated_constant_enum
from tests.common import (
async_mock_service,
help_test_all,
import_and_test_deprecated_constant_enum,
)
TEST_PLATFORM = {DOMAIN: {CONF_PLATFORM: "test"}}
SERVICE_SEND_COMMAND = "send_command"
@@ -143,6 +147,11 @@ async def test_delete_command(hass: HomeAssistant) -> None:
assert call.data[ATTR_ENTITY_ID] == ENTITY_ID
def test_all() -> None:
"""Test module.__all__ is correctly set."""
help_test_all(remote)
@pytest.mark.parametrize(("enum"), list(remote.RemoteEntityFeature))
def test_deprecated_constants(
caplog: pytest.LogCaptureFixture,
+10
View File
@@ -52,6 +52,7 @@ from tests.common import (
MockModule,
MockPlatform,
async_mock_restore_state_shutdown_restart,
help_test_all,
import_and_test_deprecated_constant_enum,
mock_config_flow,
mock_integration,
@@ -2524,6 +2525,15 @@ async def test_entity_category_config_raises_error(
assert not hass.states.get("sensor.test")
@pytest.mark.parametrize(
"module",
[sensor, sensor.const],
)
def test_all(module: ModuleType) -> None:
"""Test module.__all__ is correctly set."""
help_test_all(module)
@pytest.mark.parametrize(("enum"), list(sensor.SensorStateClass))
@pytest.mark.parametrize(("module"), [sensor, sensor.const])
def test_deprecated_constants(
+4 -2
View File
@@ -12,6 +12,7 @@ from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.shelly.const import (
CONF_GEN,
CONF_SLEEP_PERIOD,
DOMAIN,
REST_SENSORS_UPDATE_INTERVAL,
@@ -30,7 +31,7 @@ MOCK_MAC = "123456789ABC"
async def init_integration(
hass: HomeAssistant,
gen: int,
gen: int | None,
model=MODEL_25,
sleep_period=0,
options: dict[str, Any] | None = None,
@@ -41,8 +42,9 @@ async def init_integration(
CONF_HOST: "192.168.1.37",
CONF_SLEEP_PERIOD: sleep_period,
"model": model,
"gen": gen,
}
if gen is not None:
data[CONF_GEN] = gen
entry = MockConfigEntry(
domain=DOMAIN, data=data, unique_id=MOCK_MAC, options=options
+8
View File
@@ -301,3 +301,11 @@ async def test_no_attempt_to_stop_scanner_with_sleepy_devices(
mock_rpc_device.mock_update()
await hass.async_block_till_done()
assert not mock_stop_scanner.call_count
async def test_entry_missing_gen(hass: HomeAssistant, mock_block_device) -> None:
"""Test successful Gen1 device init when gen is missing in entry data."""
entry = await init_integration(hass, None)
assert entry.state is ConfigEntryState.LOADED
assert hass.states.get("switch.test_name_channel_1").state is STATE_ON
+10 -1
View File
@@ -13,7 +13,7 @@ from homeassistant.components.siren import (
from homeassistant.components.siren.const import SirenEntityFeature
from homeassistant.core import HomeAssistant
from tests.common import import_and_test_deprecated_constant_enum
from tests.common import help_test_all, import_and_test_deprecated_constant_enum
class MockSirenEntity(SirenEntity):
@@ -110,6 +110,15 @@ async def test_missing_tones_dict(hass: HomeAssistant) -> None:
process_turn_on_params(siren, {"tone": 3})
@pytest.mark.parametrize(
"module",
[siren, siren.const],
)
def test_all(module: ModuleType) -> None:
"""Test module.__all__ is correctly set."""
help_test_all(module)
@pytest.mark.parametrize(("enum"), list(SirenEntityFeature))
@pytest.mark.parametrize(("module"), [siren, siren.const])
def test_deprecated_constants(
+10 -1
View File
@@ -9,7 +9,11 @@ from homeassistant.setup import async_setup_component
from . import common
from tests.common import MockUser, import_and_test_deprecated_constant_enum
from tests.common import (
MockUser,
help_test_all,
import_and_test_deprecated_constant_enum,
)
@pytest.fixture(autouse=True)
@@ -82,6 +86,11 @@ async def test_switch_context(
assert state2.context.user_id == hass_admin_user.id
def test_all() -> None:
"""Test module.__all__ is correctly set."""
help_test_all(switch)
@pytest.mark.parametrize(("enum"), list(switch.SwitchDeviceClass))
def test_deprecated_constants(
caplog: pytest.LogCaptureFixture,
+22
View File
@@ -3,6 +3,7 @@ from http import HTTPStatus
from ipaddress import ip_address
from unittest.mock import MagicMock, patch
import PyTado
import pytest
import requests
@@ -346,6 +347,27 @@ async def test_import_step_validation_failed(hass: HomeAssistant) -> None:
assert result["reason"] == "import_failed"
async def test_import_step_device_authentication_failed(hass: HomeAssistant) -> None:
"""Test import step with device tracker authentication failed."""
with patch(
"homeassistant.components.tado.config_flow.Tado",
side_effect=PyTado.exceptions.TadoWrongCredentialsException,
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
"username": "test-username",
"password": "test-password",
"home_id": 1,
},
)
await hass.async_block_till_done()
assert result["type"] == FlowResultType.ABORT
assert result["reason"] == "import_failed_invalid_auth"
async def test_import_step_unique_id_configured(hass: HomeAssistant) -> None:
"""Test import step with unique ID already configured."""
entry = MockConfigEntry(

Some files were not shown because too many files have changed in this diff Show More