Merge pull request #51488 from home-assistant/rc

This commit is contained in:
Paulus Schoutsen 2021-06-04 10:50:36 -07:00 committed by GitHub
commit 1da9ac38e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 59 additions and 29 deletions

View File

@ -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",

View File

@ -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"
} }

View File

@ -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",

View File

@ -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"

View File

@ -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": [

View File

@ -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

View File

@ -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"

View File

@ -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()

View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"})