mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 15:47:12 +00:00
2023.1.3 (#85645)
This commit is contained in:
commit
b297b78086
@ -2,7 +2,7 @@
|
|||||||
"domain": "emulated_kasa",
|
"domain": "emulated_kasa",
|
||||||
"name": "Emulated Kasa",
|
"name": "Emulated Kasa",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/emulated_kasa",
|
"documentation": "https://www.home-assistant.io/integrations/emulated_kasa",
|
||||||
"requirements": ["sense_energy==0.11.0"],
|
"requirements": ["sense_energy==0.11.1"],
|
||||||
"codeowners": ["@kbickar"],
|
"codeowners": ["@kbickar"],
|
||||||
"quality_scale": "internal",
|
"quality_scale": "internal",
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"domain": "frontend",
|
"domain": "frontend",
|
||||||
"name": "Home Assistant Frontend",
|
"name": "Home Assistant Frontend",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/frontend",
|
"documentation": "https://www.home-assistant.io/integrations/frontend",
|
||||||
"requirements": ["home-assistant-frontend==20230104.0"],
|
"requirements": ["home-assistant-frontend==20230110.0"],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"api",
|
"api",
|
||||||
"auth",
|
"auth",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"dependencies": ["application_credentials"],
|
"dependencies": ["application_credentials"],
|
||||||
"documentation": "https://www.home-assistant.io/integrations/calendar.google/",
|
"documentation": "https://www.home-assistant.io/integrations/calendar.google/",
|
||||||
"requirements": ["gcal-sync==4.1.1", "oauth2client==4.1.3"],
|
"requirements": ["gcal-sync==4.1.2", "oauth2client==4.1.3"],
|
||||||
"codeowners": ["@allenporter"],
|
"codeowners": ["@allenporter"],
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["googleapiclient"]
|
"loggers": ["googleapiclient"]
|
||||||
|
@ -58,8 +58,8 @@ SENSOR_TYPES = {
|
|||||||
key="signal",
|
key="signal",
|
||||||
name="signal strength",
|
name="signal strength",
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
|
|
||||||
entity_category=EntityCategory.DIAGNOSTIC,
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
|
icon="mdi:wifi",
|
||||||
),
|
),
|
||||||
"ssid": SensorEntityDescription(
|
"ssid": SensorEntityDescription(
|
||||||
key="ssid",
|
key="ssid",
|
||||||
|
@ -31,7 +31,7 @@ from .const import (
|
|||||||
DOMAIN,
|
DOMAIN,
|
||||||
LOGGER,
|
LOGGER,
|
||||||
)
|
)
|
||||||
from .coordinator import InvalidApiKeyMonitor, OpenUvCoordinator
|
from .coordinator import OpenUvCoordinator
|
||||||
|
|
||||||
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
|
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
|
||||||
|
|
||||||
@ -45,6 +45,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
entry.data.get(CONF_LONGITUDE, hass.config.longitude),
|
entry.data.get(CONF_LONGITUDE, hass.config.longitude),
|
||||||
altitude=entry.data.get(CONF_ELEVATION, hass.config.elevation),
|
altitude=entry.data.get(CONF_ELEVATION, hass.config.elevation),
|
||||||
session=websession,
|
session=websession,
|
||||||
|
check_status_before_request=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_update_protection_data() -> dict[str, Any]:
|
async def async_update_protection_data() -> dict[str, Any]:
|
||||||
@ -53,16 +54,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
high = entry.options.get(CONF_TO_WINDOW, DEFAULT_TO_WINDOW)
|
high = entry.options.get(CONF_TO_WINDOW, DEFAULT_TO_WINDOW)
|
||||||
return await client.uv_protection_window(low=low, high=high)
|
return await client.uv_protection_window(low=low, high=high)
|
||||||
|
|
||||||
invalid_api_key_monitor = InvalidApiKeyMonitor(hass, entry)
|
|
||||||
|
|
||||||
coordinators: dict[str, OpenUvCoordinator] = {
|
coordinators: dict[str, OpenUvCoordinator] = {
|
||||||
coordinator_name: OpenUvCoordinator(
|
coordinator_name: OpenUvCoordinator(
|
||||||
hass,
|
hass,
|
||||||
|
entry=entry,
|
||||||
name=coordinator_name,
|
name=coordinator_name,
|
||||||
latitude=client.latitude,
|
latitude=client.latitude,
|
||||||
longitude=client.longitude,
|
longitude=client.longitude,
|
||||||
update_method=update_method,
|
update_method=update_method,
|
||||||
invalid_api_key_monitor=invalid_api_key_monitor,
|
|
||||||
)
|
)
|
||||||
for coordinator_name, update_method in (
|
for coordinator_name, update_method in (
|
||||||
(DATA_UV, client.uv_index),
|
(DATA_UV, client.uv_index),
|
||||||
@ -70,16 +69,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
# We disable the client's request retry abilities here to avoid a lengthy (and
|
|
||||||
# blocking) startup; then, if the initial update is successful, we re-enable client
|
|
||||||
# request retries:
|
|
||||||
client.disable_request_retries()
|
|
||||||
init_tasks = [
|
init_tasks = [
|
||||||
coordinator.async_config_entry_first_refresh()
|
coordinator.async_config_entry_first_refresh()
|
||||||
for coordinator in coordinators.values()
|
for coordinator in coordinators.values()
|
||||||
]
|
]
|
||||||
await asyncio.gather(*init_tasks)
|
await asyncio.gather(*init_tasks)
|
||||||
client.enable_request_retries()
|
|
||||||
|
|
||||||
hass.data.setdefault(DOMAIN, {})
|
hass.data.setdefault(DOMAIN, {})
|
||||||
hass.data[DOMAIN][entry.entry_id] = coordinators
|
hass.data[DOMAIN][entry.entry_id] = coordinators
|
||||||
|
@ -103,7 +103,6 @@ class OpenUvFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
"""Verify the credentials and create/re-auth the entry."""
|
"""Verify the credentials and create/re-auth the entry."""
|
||||||
websession = aiohttp_client.async_get_clientsession(self.hass)
|
websession = aiohttp_client.async_get_clientsession(self.hass)
|
||||||
client = Client(data.api_key, 0, 0, session=websession)
|
client = Client(data.api_key, 0, 0, session=websession)
|
||||||
client.disable_request_retries()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await client.uv_index()
|
await client.uv_index()
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
"""Define an update coordinator for OpenUV."""
|
"""Define an update coordinator for OpenUV."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
|
||||||
from collections.abc import Awaitable, Callable
|
from collections.abc import Awaitable, Callable
|
||||||
from typing import Any, cast
|
from typing import Any, cast
|
||||||
|
|
||||||
from pyopenuv.errors import InvalidApiKeyError, OpenUvError
|
from pyopenuv.errors import InvalidApiKeyError, OpenUvError
|
||||||
|
|
||||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
|
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.exceptions import ConfigEntryAuthFailed
|
||||||
from homeassistant.helpers.debounce import Debouncer
|
from homeassistant.helpers.debounce import Debouncer
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
@ -18,64 +17,6 @@ from .const import LOGGER
|
|||||||
DEFAULT_DEBOUNCER_COOLDOWN_SECONDS = 15 * 60
|
DEFAULT_DEBOUNCER_COOLDOWN_SECONDS = 15 * 60
|
||||||
|
|
||||||
|
|
||||||
class InvalidApiKeyMonitor:
|
|
||||||
"""Define a monitor for failed API calls (due to bad keys) across coordinators."""
|
|
||||||
|
|
||||||
DEFAULT_FAILED_API_CALL_THRESHOLD = 5
|
|
||||||
|
|
||||||
def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None:
|
|
||||||
"""Initialize."""
|
|
||||||
self._count = 1
|
|
||||||
self._lock = asyncio.Lock()
|
|
||||||
self._reauth_flow_manager = ReauthFlowManager(hass, entry)
|
|
||||||
self.entry = entry
|
|
||||||
|
|
||||||
async def async_increment(self) -> None:
|
|
||||||
"""Increment the counter."""
|
|
||||||
async with self._lock:
|
|
||||||
self._count += 1
|
|
||||||
if self._count > self.DEFAULT_FAILED_API_CALL_THRESHOLD:
|
|
||||||
LOGGER.info("Starting reauth after multiple failed API calls")
|
|
||||||
self._reauth_flow_manager.start_reauth()
|
|
||||||
|
|
||||||
async def async_reset(self) -> None:
|
|
||||||
"""Reset the counter."""
|
|
||||||
async with self._lock:
|
|
||||||
self._count = 0
|
|
||||||
self._reauth_flow_manager.cancel_reauth()
|
|
||||||
|
|
||||||
|
|
||||||
class ReauthFlowManager:
|
|
||||||
"""Define an OpenUV reauth flow manager."""
|
|
||||||
|
|
||||||
def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None:
|
|
||||||
"""Initialize."""
|
|
||||||
self.entry = entry
|
|
||||||
self.hass = hass
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def _get_active_reauth_flow(self) -> FlowResult | None:
|
|
||||||
"""Get an active reauth flow (if it exists)."""
|
|
||||||
return next(
|
|
||||||
iter(self.entry.async_get_active_flows(self.hass, {SOURCE_REAUTH})),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def cancel_reauth(self) -> None:
|
|
||||||
"""Cancel a reauth flow (if appropriate)."""
|
|
||||||
if reauth_flow := self._get_active_reauth_flow():
|
|
||||||
LOGGER.debug("API seems to have recovered; canceling reauth flow")
|
|
||||||
self.hass.config_entries.flow.async_abort(reauth_flow["flow_id"])
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def start_reauth(self) -> None:
|
|
||||||
"""Start a reauth flow (if appropriate)."""
|
|
||||||
if not self._get_active_reauth_flow():
|
|
||||||
LOGGER.debug("Multiple API failures in a row; starting reauth flow")
|
|
||||||
self.entry.async_start_reauth(self.hass)
|
|
||||||
|
|
||||||
|
|
||||||
class OpenUvCoordinator(DataUpdateCoordinator):
|
class OpenUvCoordinator(DataUpdateCoordinator):
|
||||||
"""Define an OpenUV data coordinator."""
|
"""Define an OpenUV data coordinator."""
|
||||||
|
|
||||||
@ -86,11 +27,11 @@ class OpenUvCoordinator(DataUpdateCoordinator):
|
|||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
*,
|
*,
|
||||||
|
entry: ConfigEntry,
|
||||||
name: str,
|
name: str,
|
||||||
latitude: str,
|
latitude: str,
|
||||||
longitude: str,
|
longitude: str,
|
||||||
update_method: Callable[[], Awaitable[dict[str, Any]]],
|
update_method: Callable[[], Awaitable[dict[str, Any]]],
|
||||||
invalid_api_key_monitor: InvalidApiKeyMonitor,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize."""
|
"""Initialize."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
@ -106,7 +47,7 @@ class OpenUvCoordinator(DataUpdateCoordinator):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
self._invalid_api_key_monitor = invalid_api_key_monitor
|
self._entry = entry
|
||||||
self.latitude = latitude
|
self.latitude = latitude
|
||||||
self.longitude = longitude
|
self.longitude = longitude
|
||||||
|
|
||||||
@ -115,10 +56,18 @@ class OpenUvCoordinator(DataUpdateCoordinator):
|
|||||||
try:
|
try:
|
||||||
data = await self.update_method()
|
data = await self.update_method()
|
||||||
except InvalidApiKeyError as err:
|
except InvalidApiKeyError as err:
|
||||||
await self._invalid_api_key_monitor.async_increment()
|
raise ConfigEntryAuthFailed("Invalid API key") from err
|
||||||
raise UpdateFailed(str(err)) from err
|
|
||||||
except OpenUvError as err:
|
except OpenUvError as err:
|
||||||
raise UpdateFailed(str(err)) from err
|
raise UpdateFailed(str(err)) from err
|
||||||
|
|
||||||
await self._invalid_api_key_monitor.async_reset()
|
# OpenUV uses HTTP 403 to indicate both an invalid API key and an API key that
|
||||||
|
# has hit its daily/monthly limit; both cases will result in a reauth flow. If
|
||||||
|
# coordinator update succeeds after a reauth flow has been started, terminate
|
||||||
|
# it:
|
||||||
|
if reauth_flow := next(
|
||||||
|
iter(self._entry.async_get_active_flows(self.hass, {SOURCE_REAUTH})),
|
||||||
|
None,
|
||||||
|
):
|
||||||
|
self.hass.config_entries.flow.async_abort(reauth_flow["flow_id"])
|
||||||
|
|
||||||
return cast(dict[str, Any], data["result"])
|
return cast(dict[str, Any], data["result"])
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "OpenUV",
|
"name": "OpenUV",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/openuv",
|
"documentation": "https://www.home-assistant.io/integrations/openuv",
|
||||||
"requirements": ["pyopenuv==2022.04.0"],
|
"requirements": ["pyopenuv==2023.01.0"],
|
||||||
"codeowners": ["@bachya"],
|
"codeowners": ["@bachya"],
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["pyopenuv"],
|
"loggers": ["pyopenuv"],
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"domain": "sense",
|
"domain": "sense",
|
||||||
"name": "Sense",
|
"name": "Sense",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/sense",
|
"documentation": "https://www.home-assistant.io/integrations/sense",
|
||||||
"requirements": ["sense_energy==0.11.0"],
|
"requirements": ["sense_energy==0.11.1"],
|
||||||
"codeowners": ["@kbickar"],
|
"codeowners": ["@kbickar"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"dhcp": [
|
"dhcp": [
|
||||||
|
@ -509,7 +509,8 @@ class ShellyRpcCoordinator(DataUpdateCoordinator[None]):
|
|||||||
This will be executed on connect or when the config entry
|
This will be executed on connect or when the config entry
|
||||||
is updated.
|
is updated.
|
||||||
"""
|
"""
|
||||||
await self._async_connect_ble_scanner()
|
if not self.entry.data.get(CONF_SLEEP_PERIOD):
|
||||||
|
await self._async_connect_ble_scanner()
|
||||||
|
|
||||||
async def _async_connect_ble_scanner(self) -> None:
|
async def _async_connect_ble_scanner(self) -> None:
|
||||||
"""Connect BLE scanner."""
|
"""Connect BLE scanner."""
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Shelly",
|
"name": "Shelly",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/shelly",
|
"documentation": "https://www.home-assistant.io/integrations/shelly",
|
||||||
"requirements": ["aioshelly==5.2.0"],
|
"requirements": ["aioshelly==5.2.1"],
|
||||||
"dependencies": ["bluetooth", "http"],
|
"dependencies": ["bluetooth", "http"],
|
||||||
"zeroconf": [
|
"zeroconf": [
|
||||||
{
|
{
|
||||||
|
@ -131,7 +131,6 @@ EV_SENSORS = [
|
|||||||
key=sc.EV_TIME_TO_FULLY_CHARGED_UTC,
|
key=sc.EV_TIME_TO_FULLY_CHARGED_UTC,
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
name="EV time to full charge",
|
name="EV time to full charge",
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Tasmota",
|
"name": "Tasmota",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/tasmota",
|
"documentation": "https://www.home-assistant.io/integrations/tasmota",
|
||||||
"requirements": ["hatasmota==0.6.2"],
|
"requirements": ["hatasmota==0.6.3"],
|
||||||
"dependencies": ["mqtt"],
|
"dependencies": ["mqtt"],
|
||||||
"mqtt": ["tasmota/discovery/#"],
|
"mqtt": ["tasmota/discovery/#"],
|
||||||
"codeowners": ["@emontnemery"],
|
"codeowners": ["@emontnemery"],
|
||||||
|
@ -337,7 +337,7 @@ EVENT_SENSORS: tuple[ProtectBinaryEventEntityDescription, ...] = (
|
|||||||
name="Doorbell",
|
name="Doorbell",
|
||||||
device_class=BinarySensorDeviceClass.OCCUPANCY,
|
device_class=BinarySensorDeviceClass.OCCUPANCY,
|
||||||
icon="mdi:doorbell-video",
|
icon="mdi:doorbell-video",
|
||||||
ufp_required_field="feature_flags.has_chime",
|
ufp_required_field="feature_flags.is_doorbell",
|
||||||
ufp_value="is_ringing",
|
ufp_value="is_ringing",
|
||||||
ufp_event_obj="last_ring_event",
|
ufp_event_obj="last_ring_event",
|
||||||
),
|
),
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"integration_type": "hub",
|
"integration_type": "hub",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/unifiprotect",
|
"documentation": "https://www.home-assistant.io/integrations/unifiprotect",
|
||||||
"requirements": ["pyunifiprotect==4.5.2", "unifi-discovery==1.1.7"],
|
"requirements": ["pyunifiprotect==4.6.1", "unifi-discovery==1.1.7"],
|
||||||
"dependencies": ["http", "repairs"],
|
"dependencies": ["http", "repairs"],
|
||||||
"codeowners": ["@briis", "@AngellusMortis", "@bdraco"],
|
"codeowners": ["@briis", "@AngellusMortis", "@bdraco"],
|
||||||
"quality_scale": "platinum",
|
"quality_scale": "platinum",
|
||||||
|
@ -770,7 +770,7 @@ class ProtectMediaSource(MediaSource):
|
|||||||
if camera is None:
|
if camera is None:
|
||||||
raise BrowseError(f"Unknown Camera ID: {camera_id}")
|
raise BrowseError(f"Unknown Camera ID: {camera_id}")
|
||||||
name = camera.name or camera.market_name or camera.type
|
name = camera.name or camera.market_name or camera.type
|
||||||
is_doorbell = camera.feature_flags.has_chime
|
is_doorbell = camera.feature_flags.is_doorbell
|
||||||
has_smart = camera.feature_flags.has_smart_detect
|
has_smart = camera.feature_flags.has_smart_detect
|
||||||
|
|
||||||
thumbnail_url: str | None = None
|
thumbnail_url: str | None = None
|
||||||
|
@ -206,7 +206,7 @@ CAMERA_SENSORS: tuple[ProtectSensorEntityDescription, ...] = (
|
|||||||
name="Last Doorbell Ring",
|
name="Last Doorbell Ring",
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
icon="mdi:doorbell-video",
|
icon="mdi:doorbell-video",
|
||||||
ufp_required_field="feature_flags.has_chime",
|
ufp_required_field="feature_flags.is_doorbell",
|
||||||
ufp_value="last_ring",
|
ufp_value="last_ring",
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
|
@ -8,7 +8,7 @@ from .backports.enum import StrEnum
|
|||||||
APPLICATION_NAME: Final = "HomeAssistant"
|
APPLICATION_NAME: Final = "HomeAssistant"
|
||||||
MAJOR_VERSION: Final = 2023
|
MAJOR_VERSION: Final = 2023
|
||||||
MINOR_VERSION: Final = 1
|
MINOR_VERSION: Final = 1
|
||||||
PATCH_VERSION: Final = "2"
|
PATCH_VERSION: Final = "3"
|
||||||
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
||||||
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
|
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
|
||||||
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 9, 0)
|
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 9, 0)
|
||||||
|
@ -22,7 +22,7 @@ dbus-fast==1.82.0
|
|||||||
fnvhash==0.1.0
|
fnvhash==0.1.0
|
||||||
hass-nabucasa==0.61.0
|
hass-nabucasa==0.61.0
|
||||||
home-assistant-bluetooth==1.9.2
|
home-assistant-bluetooth==1.9.2
|
||||||
home-assistant-frontend==20230104.0
|
home-assistant-frontend==20230110.0
|
||||||
httpx==0.23.2
|
httpx==0.23.2
|
||||||
ifaddr==0.1.7
|
ifaddr==0.1.7
|
||||||
janus==1.0.0
|
janus==1.0.0
|
||||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "homeassistant"
|
name = "homeassistant"
|
||||||
version = "2023.1.2"
|
version = "2023.1.3"
|
||||||
license = {text = "Apache-2.0"}
|
license = {text = "Apache-2.0"}
|
||||||
description = "Open-source home automation platform running on Python 3."
|
description = "Open-source home automation platform running on Python 3."
|
||||||
readme = "README.rst"
|
readme = "README.rst"
|
||||||
|
@ -267,7 +267,7 @@ aiosenseme==0.6.1
|
|||||||
aiosenz==1.0.0
|
aiosenz==1.0.0
|
||||||
|
|
||||||
# homeassistant.components.shelly
|
# homeassistant.components.shelly
|
||||||
aioshelly==5.2.0
|
aioshelly==5.2.1
|
||||||
|
|
||||||
# homeassistant.components.skybell
|
# homeassistant.components.skybell
|
||||||
aioskybell==22.7.0
|
aioskybell==22.7.0
|
||||||
@ -744,7 +744,7 @@ gTTS==2.2.4
|
|||||||
gassist-text==0.0.7
|
gassist-text==0.0.7
|
||||||
|
|
||||||
# homeassistant.components.google
|
# homeassistant.components.google
|
||||||
gcal-sync==4.1.1
|
gcal-sync==4.1.2
|
||||||
|
|
||||||
# homeassistant.components.geniushub
|
# homeassistant.components.geniushub
|
||||||
geniushub-client==0.6.30
|
geniushub-client==0.6.30
|
||||||
@ -858,7 +858,7 @@ hass-nabucasa==0.61.0
|
|||||||
hass_splunk==0.1.1
|
hass_splunk==0.1.1
|
||||||
|
|
||||||
# homeassistant.components.tasmota
|
# homeassistant.components.tasmota
|
||||||
hatasmota==0.6.2
|
hatasmota==0.6.3
|
||||||
|
|
||||||
# homeassistant.components.jewish_calendar
|
# homeassistant.components.jewish_calendar
|
||||||
hdate==0.10.4
|
hdate==0.10.4
|
||||||
@ -888,7 +888,7 @@ hole==0.8.0
|
|||||||
holidays==0.17.2
|
holidays==0.17.2
|
||||||
|
|
||||||
# homeassistant.components.frontend
|
# homeassistant.components.frontend
|
||||||
home-assistant-frontend==20230104.0
|
home-assistant-frontend==20230110.0
|
||||||
|
|
||||||
# homeassistant.components.home_connect
|
# homeassistant.components.home_connect
|
||||||
homeconnect==0.7.2
|
homeconnect==0.7.2
|
||||||
@ -1803,7 +1803,7 @@ pyoctoprintapi==0.1.9
|
|||||||
pyombi==0.1.10
|
pyombi==0.1.10
|
||||||
|
|
||||||
# homeassistant.components.openuv
|
# homeassistant.components.openuv
|
||||||
pyopenuv==2022.04.0
|
pyopenuv==2023.01.0
|
||||||
|
|
||||||
# homeassistant.components.opnsense
|
# homeassistant.components.opnsense
|
||||||
pyopnsense==0.2.0
|
pyopnsense==0.2.0
|
||||||
@ -2109,7 +2109,7 @@ pytrafikverket==0.2.2
|
|||||||
pyudev==0.23.2
|
pyudev==0.23.2
|
||||||
|
|
||||||
# homeassistant.components.unifiprotect
|
# homeassistant.components.unifiprotect
|
||||||
pyunifiprotect==4.5.2
|
pyunifiprotect==4.6.1
|
||||||
|
|
||||||
# homeassistant.components.uptimerobot
|
# homeassistant.components.uptimerobot
|
||||||
pyuptimerobot==22.2.0
|
pyuptimerobot==22.2.0
|
||||||
@ -2269,7 +2269,7 @@ sendgrid==6.8.2
|
|||||||
|
|
||||||
# homeassistant.components.emulated_kasa
|
# homeassistant.components.emulated_kasa
|
||||||
# homeassistant.components.sense
|
# homeassistant.components.sense
|
||||||
sense_energy==0.11.0
|
sense_energy==0.11.1
|
||||||
|
|
||||||
# homeassistant.components.sensirion_ble
|
# homeassistant.components.sensirion_ble
|
||||||
sensirion-ble==0.0.1
|
sensirion-ble==0.0.1
|
||||||
|
@ -242,7 +242,7 @@ aiosenseme==0.6.1
|
|||||||
aiosenz==1.0.0
|
aiosenz==1.0.0
|
||||||
|
|
||||||
# homeassistant.components.shelly
|
# homeassistant.components.shelly
|
||||||
aioshelly==5.2.0
|
aioshelly==5.2.1
|
||||||
|
|
||||||
# homeassistant.components.skybell
|
# homeassistant.components.skybell
|
||||||
aioskybell==22.7.0
|
aioskybell==22.7.0
|
||||||
@ -560,7 +560,7 @@ gTTS==2.2.4
|
|||||||
gassist-text==0.0.7
|
gassist-text==0.0.7
|
||||||
|
|
||||||
# homeassistant.components.google
|
# homeassistant.components.google
|
||||||
gcal-sync==4.1.1
|
gcal-sync==4.1.2
|
||||||
|
|
||||||
# homeassistant.components.geocaching
|
# homeassistant.components.geocaching
|
||||||
geocachingapi==0.2.1
|
geocachingapi==0.2.1
|
||||||
@ -647,7 +647,7 @@ habitipy==0.2.0
|
|||||||
hass-nabucasa==0.61.0
|
hass-nabucasa==0.61.0
|
||||||
|
|
||||||
# homeassistant.components.tasmota
|
# homeassistant.components.tasmota
|
||||||
hatasmota==0.6.2
|
hatasmota==0.6.3
|
||||||
|
|
||||||
# homeassistant.components.jewish_calendar
|
# homeassistant.components.jewish_calendar
|
||||||
hdate==0.10.4
|
hdate==0.10.4
|
||||||
@ -668,7 +668,7 @@ hole==0.8.0
|
|||||||
holidays==0.17.2
|
holidays==0.17.2
|
||||||
|
|
||||||
# homeassistant.components.frontend
|
# homeassistant.components.frontend
|
||||||
home-assistant-frontend==20230104.0
|
home-assistant-frontend==20230110.0
|
||||||
|
|
||||||
# homeassistant.components.home_connect
|
# homeassistant.components.home_connect
|
||||||
homeconnect==0.7.2
|
homeconnect==0.7.2
|
||||||
@ -1283,7 +1283,7 @@ pynzbgetapi==0.2.0
|
|||||||
pyoctoprintapi==0.1.9
|
pyoctoprintapi==0.1.9
|
||||||
|
|
||||||
# homeassistant.components.openuv
|
# homeassistant.components.openuv
|
||||||
pyopenuv==2022.04.0
|
pyopenuv==2023.01.0
|
||||||
|
|
||||||
# homeassistant.components.opnsense
|
# homeassistant.components.opnsense
|
||||||
pyopnsense==0.2.0
|
pyopnsense==0.2.0
|
||||||
@ -1475,7 +1475,7 @@ pytrafikverket==0.2.2
|
|||||||
pyudev==0.23.2
|
pyudev==0.23.2
|
||||||
|
|
||||||
# homeassistant.components.unifiprotect
|
# homeassistant.components.unifiprotect
|
||||||
pyunifiprotect==4.5.2
|
pyunifiprotect==4.6.1
|
||||||
|
|
||||||
# homeassistant.components.uptimerobot
|
# homeassistant.components.uptimerobot
|
||||||
pyuptimerobot==22.2.0
|
pyuptimerobot==22.2.0
|
||||||
@ -1578,7 +1578,7 @@ securetar==2022.2.0
|
|||||||
|
|
||||||
# homeassistant.components.emulated_kasa
|
# homeassistant.components.emulated_kasa
|
||||||
# homeassistant.components.sense
|
# homeassistant.components.sense
|
||||||
sense_energy==0.11.0
|
sense_energy==0.11.1
|
||||||
|
|
||||||
# homeassistant.components.sensirion_ble
|
# homeassistant.components.sensirion_ble
|
||||||
sensirion-ble==0.0.1
|
sensirion-ble==0.0.1
|
||||||
|
@ -213,7 +213,7 @@ async def test_entry_unload_not_connected(hass, mock_rpc_device, monkeypatch):
|
|||||||
assert entry.state is ConfigEntryState.LOADED
|
assert entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
|
||||||
async def test_entry_unload_not_connected_but_we_with_we_are(
|
async def test_entry_unload_not_connected_but_we_think_we_are(
|
||||||
hass, mock_rpc_device, monkeypatch
|
hass, mock_rpc_device, monkeypatch
|
||||||
):
|
):
|
||||||
"""Test entry unload when not connected but we think we are still connected."""
|
"""Test entry unload when not connected but we think we are still connected."""
|
||||||
@ -238,3 +238,17 @@ async def test_entry_unload_not_connected_but_we_with_we_are(
|
|||||||
|
|
||||||
assert not mock_stop_scanner.call_count
|
assert not mock_stop_scanner.call_count
|
||||||
assert entry.state is ConfigEntryState.LOADED
|
assert entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
|
||||||
|
async def test_no_attempt_to_stop_scanner_with_sleepy_devices(hass, mock_rpc_device):
|
||||||
|
"""Test we do not try to stop the scanner if its disabled with a sleepy device."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.shelly.coordinator.async_stop_scanner",
|
||||||
|
) as mock_stop_scanner:
|
||||||
|
entry = await init_integration(hass, 2, sleep_period=7200)
|
||||||
|
assert entry.state is ConfigEntryState.LOADED
|
||||||
|
assert not mock_stop_scanner.call_count
|
||||||
|
|
||||||
|
mock_rpc_device.mock_update()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert not mock_stop_scanner.call_count
|
||||||
|
@ -214,6 +214,7 @@ def doorbell_fixture(camera: Camera, fixed_now: datetime):
|
|||||||
doorbell.feature_flags.has_lcd_screen = True
|
doorbell.feature_flags.has_lcd_screen = True
|
||||||
doorbell.feature_flags.has_speaker = True
|
doorbell.feature_flags.has_speaker = True
|
||||||
doorbell.feature_flags.has_privacy_mask = True
|
doorbell.feature_flags.has_privacy_mask = True
|
||||||
|
doorbell.feature_flags.is_doorbell = True
|
||||||
doorbell.feature_flags.has_chime = True
|
doorbell.feature_flags.has_chime = True
|
||||||
doorbell.feature_flags.has_smart_detect = True
|
doorbell.feature_flags.has_smart_detect = True
|
||||||
doorbell.feature_flags.has_package_camera = True
|
doorbell.feature_flags.has_package_camera = True
|
||||||
|
Loading…
x
Reference in New Issue
Block a user