mirror of
https://github.com/home-assistant/core.git
synced 2025-07-29 16:17:20 +00:00
Merge pull request #51488 from home-assistant/rc
This commit is contained in:
commit
1da9ac38e8
@ -3,7 +3,7 @@
|
|||||||
"name": "Elgato Light",
|
"name": "Elgato Light",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/elgato",
|
"documentation": "https://www.home-assistant.io/integrations/elgato",
|
||||||
"requirements": ["elgato==2.1.0"],
|
"requirements": ["elgato==2.1.1"],
|
||||||
"zeroconf": ["_elg._tcp.local."],
|
"zeroconf": ["_elg._tcp.local."],
|
||||||
"codeowners": ["@frenck"],
|
"codeowners": ["@frenck"],
|
||||||
"quality_scale": "platinum",
|
"quality_scale": "platinum",
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/iaqualink/",
|
"documentation": "https://www.home-assistant.io/integrations/iaqualink/",
|
||||||
"codeowners": ["@flz"],
|
"codeowners": ["@flz"],
|
||||||
"requirements": ["iaqualink==0.3.4"],
|
"requirements": ["iaqualink==0.3.90"],
|
||||||
"iot_class": "cloud_polling"
|
"iot_class": "cloud_polling"
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""Support the ISY-994 controllers."""
|
"""Support the ISY-994 controllers."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from aiohttp import CookieJar
|
from aiohttp import CookieJar
|
||||||
@ -171,8 +172,14 @@ async def async_setup_entry(
|
|||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with async_timeout.timeout(30):
|
async with async_timeout.timeout(30):
|
||||||
await isy.initialize()
|
await isy.initialize()
|
||||||
|
except asyncio.TimeoutError as err:
|
||||||
|
_LOGGER.error(
|
||||||
|
"Timed out initializing the ISY; device may be busy, trying again later: %s",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
raise ConfigEntryNotReady from err
|
||||||
except ISYInvalidAuthError as err:
|
except ISYInvalidAuthError as err:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Invalid credentials for the ISY, please adjust settings and try again: %s",
|
"Invalid credentials for the ISY, please adjust settings and try again: %s",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"domain": "knx",
|
"domain": "knx",
|
||||||
"name": "KNX",
|
"name": "KNX",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/knx",
|
"documentation": "https://www.home-assistant.io/integrations/knx",
|
||||||
"requirements": ["xknx==0.18.2"],
|
"requirements": ["xknx==0.18.4"],
|
||||||
"codeowners": ["@Julius2342", "@farmio", "@marvin-w"],
|
"codeowners": ["@Julius2342", "@farmio", "@marvin-w"],
|
||||||
"quality_scale": "silver",
|
"quality_scale": "silver",
|
||||||
"iot_class": "local_push"
|
"iot_class": "local_push"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/lyric",
|
"documentation": "https://www.home-assistant.io/integrations/lyric",
|
||||||
"dependencies": ["http"],
|
"dependencies": ["http"],
|
||||||
"requirements": ["aiolyric==1.0.6"],
|
"requirements": ["aiolyric==1.0.7"],
|
||||||
"codeowners": ["@timmo001"],
|
"codeowners": ["@timmo001"],
|
||||||
"quality_scale": "silver",
|
"quality_scale": "silver",
|
||||||
"dhcp": [
|
"dhcp": [
|
||||||
|
@ -99,7 +99,6 @@ from .const import (
|
|||||||
DEFAULT_SCAN_INTERVAL,
|
DEFAULT_SCAN_INTERVAL,
|
||||||
DEFAULT_STRUCTURE_PREFIX,
|
DEFAULT_STRUCTURE_PREFIX,
|
||||||
DEFAULT_TEMP_UNIT,
|
DEFAULT_TEMP_UNIT,
|
||||||
MINIMUM_SCAN_INTERVAL,
|
|
||||||
MODBUS_DOMAIN as DOMAIN,
|
MODBUS_DOMAIN as DOMAIN,
|
||||||
PLATFORMS,
|
PLATFORMS,
|
||||||
)
|
)
|
||||||
@ -139,27 +138,30 @@ def control_scan_interval(config: dict) -> dict:
|
|||||||
|
|
||||||
for entry in hub[conf_key]:
|
for entry in hub[conf_key]:
|
||||||
scan_interval = entry.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
|
scan_interval = entry.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
|
||||||
if scan_interval < MINIMUM_SCAN_INTERVAL:
|
if scan_interval == 0:
|
||||||
if scan_interval == 0:
|
continue
|
||||||
continue
|
if scan_interval < 5:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"%s %s scan_interval(%d) is adjusted to minimum(%d)",
|
"%s %s scan_interval(%d) is lower than 5 seconds, "
|
||||||
|
"which may cause Home Assistant stability issues",
|
||||||
component,
|
component,
|
||||||
entry.get(CONF_NAME),
|
entry.get(CONF_NAME),
|
||||||
scan_interval,
|
scan_interval,
|
||||||
MINIMUM_SCAN_INTERVAL,
|
|
||||||
)
|
)
|
||||||
scan_interval = MINIMUM_SCAN_INTERVAL
|
|
||||||
entry[CONF_SCAN_INTERVAL] = scan_interval
|
entry[CONF_SCAN_INTERVAL] = scan_interval
|
||||||
minimum_scan_interval = min(scan_interval, minimum_scan_interval)
|
minimum_scan_interval = min(scan_interval, minimum_scan_interval)
|
||||||
if CONF_TIMEOUT in hub and hub[CONF_TIMEOUT] > minimum_scan_interval - 1:
|
if (
|
||||||
|
CONF_TIMEOUT in hub
|
||||||
|
and hub[CONF_TIMEOUT] > minimum_scan_interval - 1
|
||||||
|
and minimum_scan_interval > 1
|
||||||
|
):
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"Modbus %s timeout(%d) is adjusted(%d) due to scan_interval",
|
"Modbus %s timeout(%d) is adjusted(%d) due to scan_interval",
|
||||||
hub.get(CONF_NAME, ""),
|
hub.get(CONF_NAME, ""),
|
||||||
hub[CONF_TIMEOUT],
|
hub[CONF_TIMEOUT],
|
||||||
minimum_scan_interval - 1,
|
minimum_scan_interval - 1,
|
||||||
)
|
)
|
||||||
hub[CONF_TIMEOUT] = minimum_scan_interval - 1
|
hub[CONF_TIMEOUT] = minimum_scan_interval - 1
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,7 +90,6 @@ SERVICE_WRITE_REGISTER = "write_register"
|
|||||||
|
|
||||||
# integration names
|
# integration names
|
||||||
DEFAULT_HUB = "modbus_hub"
|
DEFAULT_HUB = "modbus_hub"
|
||||||
MINIMUM_SCAN_INTERVAL = 5 # seconds
|
|
||||||
DEFAULT_SCAN_INTERVAL = 15 # seconds
|
DEFAULT_SCAN_INTERVAL = 15 # seconds
|
||||||
DEFAULT_SLAVE = 1
|
DEFAULT_SLAVE = 1
|
||||||
DEFAULT_STRUCTURE_PREFIX = ">f"
|
DEFAULT_STRUCTURE_PREFIX = ">f"
|
||||||
|
@ -184,7 +184,9 @@ class SamsungTVLegacyBridge(SamsungTVBridge):
|
|||||||
if self._remote is None:
|
if self._remote is None:
|
||||||
# We need to create a new instance to reconnect.
|
# We need to create a new instance to reconnect.
|
||||||
try:
|
try:
|
||||||
LOGGER.debug("Create SamsungRemote")
|
LOGGER.debug(
|
||||||
|
"Create SamsungTVLegacyBridge for %s (%s)", CONF_NAME, self.host
|
||||||
|
)
|
||||||
self._remote = Remote(self.config.copy())
|
self._remote = Remote(self.config.copy())
|
||||||
# This is only happening when the auth was switched to DENY
|
# This is only happening when the auth was switched to DENY
|
||||||
# A removed auth will lead to socket timeout because waiting for auth popup is just an open socket
|
# A removed auth will lead to socket timeout because waiting for auth popup is just an open socket
|
||||||
@ -199,7 +201,7 @@ class SamsungTVLegacyBridge(SamsungTVBridge):
|
|||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""Stop Bridge."""
|
"""Stop Bridge."""
|
||||||
LOGGER.debug("Stopping SamsungRemote")
|
LOGGER.debug("Stopping SamsungTVLegacyBridge")
|
||||||
self.close_remote()
|
self.close_remote()
|
||||||
|
|
||||||
|
|
||||||
@ -272,7 +274,7 @@ class SamsungTVWSBridge(SamsungTVBridge):
|
|||||||
# We need to create a new instance to reconnect.
|
# We need to create a new instance to reconnect.
|
||||||
try:
|
try:
|
||||||
LOGGER.debug(
|
LOGGER.debug(
|
||||||
"Create SamsungTVWS for %s (%s)", VALUE_CONF_NAME, self.host
|
"Create SamsungTVWSBridge for %s (%s)", CONF_NAME, self.host
|
||||||
)
|
)
|
||||||
self._remote = SamsungTVWS(
|
self._remote = SamsungTVWS(
|
||||||
host=self.host,
|
host=self.host,
|
||||||
@ -293,5 +295,5 @@ class SamsungTVWSBridge(SamsungTVBridge):
|
|||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""Stop Bridge."""
|
"""Stop Bridge."""
|
||||||
LOGGER.debug("Stopping SamsungTVWS")
|
LOGGER.debug("Stopping SamsungTVWSBridge")
|
||||||
self.close_remote()
|
self.close_remote()
|
||||||
|
@ -224,6 +224,7 @@ class SamsungTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
|
|
||||||
async def async_step_ssdp(self, discovery_info: DiscoveryInfoType):
|
async def async_step_ssdp(self, discovery_info: DiscoveryInfoType):
|
||||||
"""Handle a flow initialized by ssdp discovery."""
|
"""Handle a flow initialized by ssdp discovery."""
|
||||||
|
LOGGER.debug("Samsung device found via SSDP: %s", discovery_info)
|
||||||
self._udn = _strip_uuid(discovery_info[ATTR_UPNP_UDN])
|
self._udn = _strip_uuid(discovery_info[ATTR_UPNP_UDN])
|
||||||
await self._async_set_unique_id_from_udn()
|
await self._async_set_unique_id_from_udn()
|
||||||
await self._async_start_discovery_for_host(
|
await self._async_start_discovery_for_host(
|
||||||
@ -242,6 +243,7 @@ class SamsungTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
|
|
||||||
async def async_step_dhcp(self, discovery_info: DiscoveryInfoType):
|
async def async_step_dhcp(self, discovery_info: DiscoveryInfoType):
|
||||||
"""Handle a flow initialized by dhcp discovery."""
|
"""Handle a flow initialized by dhcp discovery."""
|
||||||
|
LOGGER.debug("Samsung device found via DHCP: %s", discovery_info)
|
||||||
self._mac = discovery_info[MAC_ADDRESS]
|
self._mac = discovery_info[MAC_ADDRESS]
|
||||||
await self._async_start_discovery_for_host(discovery_info[IP_ADDRESS])
|
await self._async_start_discovery_for_host(discovery_info[IP_ADDRESS])
|
||||||
await self._async_set_device_unique_id()
|
await self._async_set_device_unique_id()
|
||||||
@ -250,6 +252,7 @@ class SamsungTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
|
|
||||||
async def async_step_zeroconf(self, discovery_info: DiscoveryInfoType):
|
async def async_step_zeroconf(self, discovery_info: DiscoveryInfoType):
|
||||||
"""Handle a flow initialized by zeroconf discovery."""
|
"""Handle a flow initialized by zeroconf discovery."""
|
||||||
|
LOGGER.debug("Samsung device found via ZEROCONF: %s", discovery_info)
|
||||||
self._mac = format_mac(discovery_info[ATTR_PROPERTIES]["deviceid"])
|
self._mac = format_mac(discovery_info[ATTR_PROPERTIES]["deviceid"])
|
||||||
await self._async_start_discovery_for_host(discovery_info[CONF_HOST])
|
await self._async_start_discovery_for_host(discovery_info[CONF_HOST])
|
||||||
await self._async_set_device_unique_id()
|
await self._async_set_device_unique_id()
|
||||||
|
@ -5,7 +5,7 @@ from typing import Final
|
|||||||
|
|
||||||
MAJOR_VERSION: Final = 2021
|
MAJOR_VERSION: Final = 2021
|
||||||
MINOR_VERSION: Final = 6
|
MINOR_VERSION: Final = 6
|
||||||
PATCH_VERSION: Final = "1"
|
PATCH_VERSION: Final = "2"
|
||||||
__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, 8, 0)
|
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 8, 0)
|
||||||
|
@ -6,6 +6,7 @@ from collections.abc import Awaitable
|
|||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from ssl import SSLContext
|
from ssl import SSLContext
|
||||||
import sys
|
import sys
|
||||||
|
from types import MappingProxyType
|
||||||
from typing import Any, Callable, cast
|
from typing import Any, Callable, cast
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
@ -95,9 +96,14 @@ def _async_create_clientsession(
|
|||||||
"""Create a new ClientSession with kwargs, i.e. for cookies."""
|
"""Create a new ClientSession with kwargs, i.e. for cookies."""
|
||||||
clientsession = aiohttp.ClientSession(
|
clientsession = aiohttp.ClientSession(
|
||||||
connector=_async_get_connector(hass, verify_ssl),
|
connector=_async_get_connector(hass, verify_ssl),
|
||||||
headers={USER_AGENT: SERVER_SOFTWARE},
|
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
# Prevent packages accidentally overriding our default headers
|
||||||
|
# It's important that we identify as Home Assistant
|
||||||
|
# If a package requires a different user agent, override it by passing a headers
|
||||||
|
# dictionary to the request method.
|
||||||
|
# pylint: disable=protected-access
|
||||||
|
clientsession._default_headers = MappingProxyType({USER_AGENT: SERVER_SOFTWARE}) # type: ignore
|
||||||
|
|
||||||
clientsession.close = warn_use(clientsession.close, WARN_CLOSE_MSG) # type: ignore
|
clientsession.close = warn_use(clientsession.close, WARN_CLOSE_MSG) # type: ignore
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ aiolifx_effects==0.2.2
|
|||||||
aiolip==1.1.4
|
aiolip==1.1.4
|
||||||
|
|
||||||
# homeassistant.components.lyric
|
# homeassistant.components.lyric
|
||||||
aiolyric==1.0.6
|
aiolyric==1.0.7
|
||||||
|
|
||||||
# homeassistant.components.keyboard_remote
|
# homeassistant.components.keyboard_remote
|
||||||
aionotify==0.2.0
|
aionotify==0.2.0
|
||||||
@ -533,7 +533,7 @@ ebusdpy==0.0.16
|
|||||||
ecoaliface==0.4.0
|
ecoaliface==0.4.0
|
||||||
|
|
||||||
# homeassistant.components.elgato
|
# homeassistant.components.elgato
|
||||||
elgato==2.1.0
|
elgato==2.1.1
|
||||||
|
|
||||||
# homeassistant.components.eliqonline
|
# homeassistant.components.eliqonline
|
||||||
eliqonline==1.2.2
|
eliqonline==1.2.2
|
||||||
@ -807,7 +807,7 @@ hyperion-py==0.7.4
|
|||||||
iammeter==0.1.7
|
iammeter==0.1.7
|
||||||
|
|
||||||
# homeassistant.components.iaqualink
|
# homeassistant.components.iaqualink
|
||||||
iaqualink==0.3.4
|
iaqualink==0.3.90
|
||||||
|
|
||||||
# homeassistant.components.watson_tts
|
# homeassistant.components.watson_tts
|
||||||
ibm-watson==5.1.0
|
ibm-watson==5.1.0
|
||||||
@ -2375,7 +2375,7 @@ xbox-webapi==2.0.11
|
|||||||
xboxapi==2.0.1
|
xboxapi==2.0.1
|
||||||
|
|
||||||
# homeassistant.components.knx
|
# homeassistant.components.knx
|
||||||
xknx==0.18.2
|
xknx==0.18.4
|
||||||
|
|
||||||
# homeassistant.components.bluesound
|
# homeassistant.components.bluesound
|
||||||
# homeassistant.components.rest
|
# homeassistant.components.rest
|
||||||
|
@ -128,7 +128,7 @@ aiokafka==0.6.0
|
|||||||
aiolip==1.1.4
|
aiolip==1.1.4
|
||||||
|
|
||||||
# homeassistant.components.lyric
|
# homeassistant.components.lyric
|
||||||
aiolyric==1.0.6
|
aiolyric==1.0.7
|
||||||
|
|
||||||
# homeassistant.components.notion
|
# homeassistant.components.notion
|
||||||
aionotion==1.1.0
|
aionotion==1.1.0
|
||||||
@ -291,7 +291,7 @@ dsmr_parser==0.29
|
|||||||
dynalite_devices==0.1.46
|
dynalite_devices==0.1.46
|
||||||
|
|
||||||
# homeassistant.components.elgato
|
# homeassistant.components.elgato
|
||||||
elgato==2.1.0
|
elgato==2.1.1
|
||||||
|
|
||||||
# homeassistant.components.elkm1
|
# homeassistant.components.elkm1
|
||||||
elkm1-lib==0.8.10
|
elkm1-lib==0.8.10
|
||||||
@ -457,7 +457,7 @@ huisbaasje-client==0.1.0
|
|||||||
hyperion-py==0.7.4
|
hyperion-py==0.7.4
|
||||||
|
|
||||||
# homeassistant.components.iaqualink
|
# homeassistant.components.iaqualink
|
||||||
iaqualink==0.3.4
|
iaqualink==0.3.90
|
||||||
|
|
||||||
# homeassistant.components.ping
|
# homeassistant.components.ping
|
||||||
icmplib==2.1.1
|
icmplib==2.1.1
|
||||||
@ -1281,7 +1281,7 @@ wolf_smartset==0.1.8
|
|||||||
xbox-webapi==2.0.11
|
xbox-webapi==2.0.11
|
||||||
|
|
||||||
# homeassistant.components.knx
|
# homeassistant.components.knx
|
||||||
xknx==0.18.2
|
xknx==0.18.4
|
||||||
|
|
||||||
# homeassistant.components.bluesound
|
# homeassistant.components.bluesound
|
||||||
# homeassistant.components.rest
|
# homeassistant.components.rest
|
||||||
|
@ -195,3 +195,14 @@ async def test_async_aiohttp_proxy_stream_client_err(aioclient_mock, camera_clie
|
|||||||
|
|
||||||
resp = await camera_client.get("/api/camera_proxy_stream/camera.config_test")
|
resp = await camera_client.get("/api/camera_proxy_stream/camera.config_test")
|
||||||
assert resp.status == 502
|
assert resp.status == 502
|
||||||
|
|
||||||
|
|
||||||
|
async def test_client_session_immutable_headers(hass):
|
||||||
|
"""Test we can't mutate headers."""
|
||||||
|
session = client.async_get_clientsession(hass)
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
session.headers["user-agent"] = "bla"
|
||||||
|
|
||||||
|
with pytest.raises(AttributeError):
|
||||||
|
session.headers.update({"user-agent": "bla"})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user