Merge pull request #66829 from home-assistant/rc

This commit is contained in:
Paulus Schoutsen
2022-02-18 12:52:13 -08:00
committed by GitHub
13 changed files with 67 additions and 20 deletions

View File

@@ -3,7 +3,7 @@
"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": [ "requirements": [
"home-assistant-frontend==20220203.0" "home-assistant-frontend==20220203.1"
], ],
"dependencies": [ "dependencies": [
"api", "api",

View File

@@ -3,7 +3,7 @@
"name": "Philips Hue", "name": "Philips Hue",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/hue", "documentation": "https://www.home-assistant.io/integrations/hue",
"requirements": ["aiohue==4.2.0"], "requirements": ["aiohue==4.2.1"],
"ssdp": [ "ssdp": [
{ {
"manufacturer": "Royal Philips Electronics", "manufacturer": "Royal Philips Electronics",

View File

@@ -3,7 +3,7 @@
"name": "Insteon", "name": "Insteon",
"documentation": "https://www.home-assistant.io/integrations/insteon", "documentation": "https://www.home-assistant.io/integrations/insteon",
"requirements": [ "requirements": [
"pyinsteon==1.0.14" "pyinsteon==1.0.16"
], ],
"codeowners": [ "codeowners": [
"@teharris1" "@teharris1"

View File

@@ -24,6 +24,7 @@ from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryNotReady
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from homeassistant.util.async_ import run_callback_threadsafe
from .bridge import ( from .bridge import (
SamsungTVBridge, SamsungTVBridge,
@@ -117,6 +118,19 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
# Initialize bridge # Initialize bridge
bridge = await _async_create_bridge_with_updated_data(hass, entry) bridge = await _async_create_bridge_with_updated_data(hass, entry)
# Ensure new token gets saved against the config_entry
def _update_token() -> None:
"""Update config entry with the new token."""
hass.config_entries.async_update_entry(
entry, data={**entry.data, CONF_TOKEN: bridge.token}
)
def new_token_callback() -> None:
"""Update config entry with the new token."""
run_callback_threadsafe(hass.loop, _update_token)
bridge.register_new_token_callback(new_token_callback)
def stop_bridge(event: Event) -> None: def stop_bridge(event: Event) -> None:
"""Stop SamsungTV bridge connection.""" """Stop SamsungTV bridge connection."""
bridge.stop() bridge.stop()

View File

@@ -98,11 +98,16 @@ class SamsungTVBridge(ABC):
self.host = host self.host = host
self.token: str | None = None self.token: str | None = None
self._remote: Remote | None = None self._remote: Remote | None = None
self._callback: CALLBACK_TYPE | None = None self._reauth_callback: CALLBACK_TYPE | None = None
self._new_token_callback: CALLBACK_TYPE | None = None
def register_reauth_callback(self, func: CALLBACK_TYPE) -> None: def register_reauth_callback(self, func: CALLBACK_TYPE) -> None:
"""Register a callback function.""" """Register a callback function."""
self._callback = func self._reauth_callback = func
def register_new_token_callback(self, func: CALLBACK_TYPE) -> None:
"""Register a callback function."""
self._new_token_callback = func
@abstractmethod @abstractmethod
def try_connect(self) -> str | None: def try_connect(self) -> str | None:
@@ -176,10 +181,15 @@ class SamsungTVBridge(ABC):
except OSError: except OSError:
LOGGER.debug("Could not establish connection") LOGGER.debug("Could not establish connection")
def _notify_callback(self) -> None: def _notify_reauth_callback(self) -> None:
"""Notify access denied callback.""" """Notify access denied callback."""
if self._callback is not None: if self._reauth_callback is not None:
self._callback() self._reauth_callback()
def _notify_new_token_callback(self) -> None:
"""Notify new token callback."""
if self._new_token_callback is not None:
self._new_token_callback()
class SamsungTVLegacyBridge(SamsungTVBridge): class SamsungTVLegacyBridge(SamsungTVBridge):
@@ -245,7 +255,7 @@ class SamsungTVLegacyBridge(SamsungTVBridge):
# 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
except AccessDenied: except AccessDenied:
self._notify_callback() self._notify_reauth_callback()
raise raise
except (ConnectionClosed, OSError): except (ConnectionClosed, OSError):
pass pass
@@ -355,7 +365,7 @@ class SamsungTVWSBridge(SamsungTVBridge):
# 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
except ConnectionFailure: except ConnectionFailure:
self._notify_callback() self._notify_reauth_callback()
except (WebSocketException, OSError): except (WebSocketException, OSError):
self._remote = None self._remote = None
else: else:
@@ -365,6 +375,7 @@ class SamsungTVWSBridge(SamsungTVBridge):
self._remote.token, self._remote.token,
) )
self.token = self._remote.token self.token = self._remote.token
self._notify_new_token_callback()
return self._remote return self._remote
def stop(self) -> None: def stop(self) -> None:

View File

@@ -353,6 +353,13 @@ class TuyaClimateEntity(TuyaEntity, ClimateEntity):
if temperature is None: if temperature is None:
return None return None
if self._current_temperature.scale == 0 and self._current_temperature.step != 1:
# The current temperature can have a scale of 0 or 1 and is used for
# rounding, Home Assistant doesn't need to round but we will always
# need to divide the value by 10^1 in case of 0 as scale.
# https://developer.tuya.com/en/docs/iot/shift-temperature-scale-follow-the-setting-of-app-account-center?id=Ka9qo7so58efq#title-7-Round%20values
temperature = temperature / 10
return self._current_temperature.scale_value(temperature) return self._current_temperature.scale_value(temperature)
@property @property

View File

@@ -47,7 +47,7 @@ class LgWebOSNotificationService(BaseNotificationService):
await self._client.connect() await self._client.connect()
data = kwargs.get(ATTR_DATA) data = kwargs.get(ATTR_DATA)
icon_path = data.get(CONF_ICON, "") if data else None icon_path = data.get(CONF_ICON) if data else None
await self._client.send_message(message, icon_path=icon_path) await self._client.send_message(message, icon_path=icon_path)
except WebOsTvPairError: except WebOsTvPairError:
_LOGGER.error("Pairing with TV failed") _LOGGER.error("Pairing with TV failed")

View File

@@ -7,7 +7,7 @@ from .backports.enum import StrEnum
MAJOR_VERSION: Final = 2022 MAJOR_VERSION: Final = 2022
MINOR_VERSION: Final = 2 MINOR_VERSION: Final = 2
PATCH_VERSION: Final = "8" PATCH_VERSION: Final = "9"
__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)

View File

@@ -15,7 +15,7 @@ ciso8601==2.2.0
cryptography==35.0.0 cryptography==35.0.0
emoji==1.6.3 emoji==1.6.3
hass-nabucasa==0.52.0 hass-nabucasa==0.52.0
home-assistant-frontend==20220203.0 home-assistant-frontend==20220203.1
httpx==0.21.3 httpx==0.21.3
ifaddr==0.1.7 ifaddr==0.1.7
jinja2==3.0.3 jinja2==3.0.3

View File

@@ -191,7 +191,7 @@ aiohomekit==0.6.11
aiohttp_cors==0.7.0 aiohttp_cors==0.7.0
# homeassistant.components.hue # homeassistant.components.hue
aiohue==4.2.0 aiohue==4.2.1
# homeassistant.components.homewizard # homeassistant.components.homewizard
aiohwenergy==0.8.0 aiohwenergy==0.8.0
@@ -842,7 +842,7 @@ hole==0.7.0
holidays==0.12 holidays==0.12
# homeassistant.components.frontend # homeassistant.components.frontend
home-assistant-frontend==20220203.0 home-assistant-frontend==20220203.1
# homeassistant.components.zwave # homeassistant.components.zwave
homeassistant-pyozw==0.1.10 homeassistant-pyozw==0.1.10
@@ -1582,7 +1582,7 @@ pyialarm==1.9.0
pyicloud==0.10.2 pyicloud==0.10.2
# homeassistant.components.insteon # homeassistant.components.insteon
pyinsteon==1.0.14 pyinsteon==1.0.16
# homeassistant.components.intesishome # homeassistant.components.intesishome
pyintesishome==1.7.6 pyintesishome==1.7.6

View File

@@ -141,7 +141,7 @@ aiohomekit==0.6.11
aiohttp_cors==0.7.0 aiohttp_cors==0.7.0
# homeassistant.components.hue # homeassistant.components.hue
aiohue==4.2.0 aiohue==4.2.1
# homeassistant.components.homewizard # homeassistant.components.homewizard
aiohwenergy==0.8.0 aiohwenergy==0.8.0
@@ -543,7 +543,7 @@ hole==0.7.0
holidays==0.12 holidays==0.12
# homeassistant.components.frontend # homeassistant.components.frontend
home-assistant-frontend==20220203.0 home-assistant-frontend==20220203.1
# homeassistant.components.zwave # homeassistant.components.zwave
homeassistant-pyozw==0.1.10 homeassistant-pyozw==0.1.10
@@ -987,7 +987,7 @@ pyialarm==1.9.0
pyicloud==0.10.2 pyicloud==0.10.2
# homeassistant.components.insteon # homeassistant.components.insteon
pyinsteon==1.0.14 pyinsteon==1.0.16
# homeassistant.components.ipma # homeassistant.components.ipma
pyipma==2.0.5 pyipma==2.0.5

View File

@@ -1,6 +1,6 @@
[metadata] [metadata]
name = homeassistant name = homeassistant
version = 2022.2.8 version = 2022.2.9
author = The Home Assistant Authors author = The Home Assistant Authors
author_email = hello@home-assistant.io author_email = hello@home-assistant.io
license = Apache-2.0 license = Apache-2.0

View File

@@ -36,6 +36,21 @@ async def test_notify(hass, client):
assert client.connect.call_count == 1 assert client.connect.call_count == 1
client.send_message.assert_called_with(MESSAGE, icon_path=ICON_PATH) client.send_message.assert_called_with(MESSAGE, icon_path=ICON_PATH)
await hass.services.async_call(
NOTIFY_DOMAIN,
TV_NAME,
{
ATTR_MESSAGE: MESSAGE,
CONF_SERVICE_DATA: {
"OTHER_DATA": "not_used",
},
},
blocking=True,
)
assert client.mock_calls[0] == call.connect()
assert client.connect.call_count == 1
client.send_message.assert_called_with(MESSAGE, icon_path=None)
async def test_notify_not_connected(hass, client, monkeypatch): async def test_notify_not_connected(hass, client, monkeypatch):
"""Test sending a message when client is not connected.""" """Test sending a message when client is not connected."""