mirror of
https://github.com/home-assistant/core.git
synced 2025-08-03 20:55:10 +02:00
Merge pull request #66829 from home-assistant/rc
This commit is contained in:
@@ -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",
|
||||||
|
@@ -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",
|
||||||
|
@@ -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"
|
||||||
|
@@ -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()
|
||||||
|
@@ -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:
|
||||||
|
@@ -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
|
||||||
|
@@ -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")
|
||||||
|
@@ -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)
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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."""
|
||||||
|
Reference in New Issue
Block a user