Merge pull request #48954 from home-assistant/rc

This commit is contained in:
Paulus Schoutsen 2021-04-09 12:03:40 -07:00 committed by GitHub
commit 7b7cfd71de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 105 additions and 23 deletions

View File

@ -473,7 +473,7 @@ class CastDevice(MediaPlayerEntity):
self.hass, self.hass,
refresh_token.id, refresh_token.id,
media_id, media_id,
timedelta(minutes=5), timedelta(seconds=media_source.DEFAULT_EXPIRY_TIME),
) )
# prepend external URL # prepend external URL

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==20210407.2" "home-assistant-frontend==20210407.3"
], ],
"dependencies": [ "dependencies": [
"api", "api",

View File

@ -148,7 +148,7 @@ class HassIO:
This method return a coroutine. This method return a coroutine.
""" """
return self.send_command("/discovery", method="get") return self.send_command("/discovery", method="get", timeout=60)
@api_data @api_data
def get_discovery_message(self, uuid): def get_discovery_message(self, uuid):

View File

@ -3,7 +3,7 @@
"name": "Kodi", "name": "Kodi",
"documentation": "https://www.home-assistant.io/integrations/kodi", "documentation": "https://www.home-assistant.io/integrations/kodi",
"requirements": [ "requirements": [
"pykodi==0.2.3" "pykodi==0.2.5"
], ],
"codeowners": [ "codeowners": [
"@OnFreund", "@OnFreund",

View File

@ -19,6 +19,8 @@ from . import local_source, models
from .const import DOMAIN, URI_SCHEME, URI_SCHEME_REGEX from .const import DOMAIN, URI_SCHEME, URI_SCHEME_REGEX
from .error import Unresolvable from .error import Unresolvable
DEFAULT_EXPIRY_TIME = 3600 * 24
def is_media_source_id(media_content_id: str): def is_media_source_id(media_content_id: str):
"""Test if identifier is a media source.""" """Test if identifier is a media source."""
@ -105,7 +107,7 @@ async def websocket_browse_media(hass, connection, msg):
{ {
vol.Required("type"): "media_source/resolve_media", vol.Required("type"): "media_source/resolve_media",
vol.Required(ATTR_MEDIA_CONTENT_ID): str, vol.Required(ATTR_MEDIA_CONTENT_ID): str,
vol.Optional("expires", default=30): int, vol.Optional("expires", default=DEFAULT_EXPIRY_TIME): int,
} }
) )
@websocket_api.async_response @websocket_api.async_response

View File

@ -116,12 +116,9 @@ class NotifyEventsNotificationService(BaseNotificationService):
def send_message(self, message, **kwargs): def send_message(self, message, **kwargs):
"""Send a message.""" """Send a message."""
token = self.token
data = kwargs.get(ATTR_DATA) or {} data = kwargs.get(ATTR_DATA) or {}
token = data.get(ATTR_TOKEN, self.token)
msg = self.prepare_message(message, data) msg = self.prepare_message(message, data)
if data.get(ATTR_TOKEN, "").trim():
token = data[ATTR_TOKEN]
msg.send(token) msg.send(token)

View File

@ -122,7 +122,7 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
ATTR_API_FEELS_LIKE_TEMPERATURE: current_weather.temperature("celsius").get( ATTR_API_FEELS_LIKE_TEMPERATURE: current_weather.temperature("celsius").get(
"feels_like" "feels_like"
), ),
ATTR_API_DEW_POINT: (round(current_weather.dewpoint / 100, 1)), ATTR_API_DEW_POINT: self._fmt_dewpoint(current_weather.dewpoint),
ATTR_API_PRESSURE: current_weather.pressure.get("press"), ATTR_API_PRESSURE: current_weather.pressure.get("press"),
ATTR_API_HUMIDITY: current_weather.humidity, ATTR_API_HUMIDITY: current_weather.humidity,
ATTR_API_WIND_BEARING: current_weather.wind().get("deg"), ATTR_API_WIND_BEARING: current_weather.wind().get("deg"),
@ -178,6 +178,12 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
return forecast return forecast
@staticmethod
def _fmt_dewpoint(dewpoint):
if dewpoint is not None:
return round(dewpoint / 100, 1)
return None
@staticmethod @staticmethod
def _get_rain(rain): def _get_rain(rain):
"""Get rain data from weather data.""" """Get rain data from weather data."""

View File

@ -7,7 +7,7 @@ from homeassistant.components.media_player.const import (
) )
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
LIVE_TV_SECTION = "-4" LIVE_TV_SECTION = -4
class PlexSession: class PlexSession:

View File

@ -1,10 +1,15 @@
"""Support for Rituals Perfume Genie switches.""" """Support for Rituals Perfume Genie switches."""
from datetime import timedelta from datetime import timedelta
import logging
import aiohttp
from homeassistant.components.switch import SwitchEntity from homeassistant.components.switch import SwitchEntity
from .const import DOMAIN from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=30) SCAN_INTERVAL = timedelta(seconds=30)
ON_STATE = "1" ON_STATE = "1"
@ -33,6 +38,7 @@ class DiffuserSwitch(SwitchEntity):
def __init__(self, diffuser): def __init__(self, diffuser):
"""Initialize the switch.""" """Initialize the switch."""
self._diffuser = diffuser self._diffuser = diffuser
self._available = True
@property @property
def device_info(self): def device_info(self):
@ -53,7 +59,7 @@ class DiffuserSwitch(SwitchEntity):
@property @property
def available(self): def available(self):
"""Return if the device is available.""" """Return if the device is available."""
return self._diffuser.data["hub"]["status"] == AVAILABLE_STATE return self._available
@property @property
def name(self): def name(self):
@ -89,4 +95,10 @@ class DiffuserSwitch(SwitchEntity):
async def async_update(self): async def async_update(self):
"""Update the data of the device.""" """Update the data of the device."""
await self._diffuser.update_data() try:
await self._diffuser.update_data()
except aiohttp.ClientError:
self._available = False
_LOGGER.error("Unable to retrieve data from rituals.sense-company.com")
else:
self._available = self._diffuser.data["hub"]["status"] == AVAILABLE_STATE

View File

@ -1,7 +1,9 @@
"""Sensor that can display the current Home Assistant versions.""" """Sensor that can display the current Home Assistant versions."""
from datetime import timedelta from datetime import timedelta
import logging
from pyhaversion import HaVersion, HaVersionChannel, HaVersionSource from pyhaversion import HaVersion, HaVersionChannel, HaVersionSource
from pyhaversion.exceptions import HaVersionFetchException, HaVersionParseException
import voluptuous as vol import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
@ -59,6 +61,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
} }
) )
_LOGGER: logging.Logger = logging.getLogger(__name__)
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the Version sensor platform.""" """Set up the Version sensor platform."""
@ -114,7 +118,14 @@ class VersionData:
@Throttle(TIME_BETWEEN_UPDATES) @Throttle(TIME_BETWEEN_UPDATES)
async def async_update(self): async def async_update(self):
"""Get the latest version information.""" """Get the latest version information."""
await self.api.get_version() try:
await self.api.get_version()
except HaVersionFetchException as exception:
_LOGGER.warning(exception)
except HaVersionParseException as exception:
_LOGGER.warning(
"Could not parse data received for %s - %s", self.api.source, exception
)
class VersionSensor(SensorEntity): class VersionSensor(SensorEntity):

View File

@ -7,7 +7,7 @@
"bellows==0.23.1", "bellows==0.23.1",
"pyserial==3.5", "pyserial==3.5",
"pyserial-asyncio==0.5", "pyserial-asyncio==0.5",
"zha-quirks==0.0.55", "zha-quirks==0.0.56",
"zigpy-cc==0.5.2", "zigpy-cc==0.5.2",
"zigpy-deconz==0.12.0", "zigpy-deconz==0.12.0",
"zigpy==0.33.0", "zigpy==0.33.0",

View File

@ -1,7 +1,7 @@
"""Constants used by Home Assistant components.""" """Constants used by Home Assistant components."""
MAJOR_VERSION = 2021 MAJOR_VERSION = 2021
MINOR_VERSION = 4 MINOR_VERSION = 4
PATCH_VERSION = "1" PATCH_VERSION = "2"
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__ = f"{__short_version__}.{PATCH_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER = (3, 8, 0) REQUIRED_PYTHON_VER = (3, 8, 0)

View File

@ -16,7 +16,7 @@ defusedxml==0.6.0
distro==1.5.0 distro==1.5.0
emoji==1.2.0 emoji==1.2.0
hass-nabucasa==0.42.0 hass-nabucasa==0.42.0
home-assistant-frontend==20210407.2 home-assistant-frontend==20210407.3
httpx==0.17.1 httpx==0.17.1
jinja2>=2.11.3 jinja2>=2.11.3
netdisco==2.8.2 netdisco==2.8.2

View File

@ -763,7 +763,7 @@ hole==0.5.1
holidays==0.10.5.2 holidays==0.10.5.2
# homeassistant.components.frontend # homeassistant.components.frontend
home-assistant-frontend==20210407.2 home-assistant-frontend==20210407.3
# homeassistant.components.zwave # homeassistant.components.zwave
homeassistant-pyozw==0.1.10 homeassistant-pyozw==0.1.10
@ -1476,7 +1476,7 @@ pykira==0.1.1
pykmtronic==0.0.3 pykmtronic==0.0.3
# homeassistant.components.kodi # homeassistant.components.kodi
pykodi==0.2.3 pykodi==0.2.5
# homeassistant.components.kulersky # homeassistant.components.kulersky
pykulersky==0.5.2 pykulersky==0.5.2
@ -2372,7 +2372,7 @@ zengge==0.2
zeroconf==0.29.0 zeroconf==0.29.0
# homeassistant.components.zha # homeassistant.components.zha
zha-quirks==0.0.55 zha-quirks==0.0.56
# homeassistant.components.zhong_hong # homeassistant.components.zhong_hong
zhong_hong_hvac==1.0.9 zhong_hong_hvac==1.0.9

View File

@ -412,7 +412,7 @@ hole==0.5.1
holidays==0.10.5.2 holidays==0.10.5.2
# homeassistant.components.frontend # homeassistant.components.frontend
home-assistant-frontend==20210407.2 home-assistant-frontend==20210407.3
# homeassistant.components.zwave # homeassistant.components.zwave
homeassistant-pyozw==0.1.10 homeassistant-pyozw==0.1.10
@ -518,6 +518,9 @@ netdisco==2.8.2
# homeassistant.components.nexia # homeassistant.components.nexia
nexia==0.9.5 nexia==0.9.5
# homeassistant.components.notify_events
notify-events==1.0.4
# homeassistant.components.nsw_fuel_station # homeassistant.components.nsw_fuel_station
nsw-fuel-api-client==1.0.10 nsw-fuel-api-client==1.0.10
@ -784,7 +787,7 @@ pykira==0.1.1
pykmtronic==0.0.3 pykmtronic==0.0.3
# homeassistant.components.kodi # homeassistant.components.kodi
pykodi==0.2.3 pykodi==0.2.5
# homeassistant.components.kulersky # homeassistant.components.kulersky
pykulersky==0.5.2 pykulersky==0.5.2
@ -1230,7 +1233,7 @@ zeep[async]==4.0.0
zeroconf==0.29.0 zeroconf==0.29.0
# homeassistant.components.zha # homeassistant.components.zha
zha-quirks==0.0.55 zha-quirks==0.0.56
# homeassistant.components.zha # homeassistant.components.zha
zigpy-cc==0.5.2 zigpy-cc==0.5.2

View File

@ -0,0 +1 @@
"""Tests for the notify_events integration."""

View File

@ -0,0 +1,12 @@
"""The tests for notify_events."""
from homeassistant.components.notify_events.const import DOMAIN
from homeassistant.setup import async_setup_component
async def test_setup(hass):
"""Test setup of the integration."""
config = {"notify_events": {"token": "ABC"}}
assert await async_setup_component(hass, DOMAIN, config)
await hass.async_block_till_done()
assert DOMAIN in hass.data

View File

@ -0,0 +1,38 @@
"""The tests for notify_events."""
from homeassistant.components.notify import ATTR_DATA, ATTR_MESSAGE, DOMAIN
from homeassistant.components.notify_events.notify import (
ATTR_LEVEL,
ATTR_PRIORITY,
ATTR_TOKEN,
)
from tests.common import async_mock_service
async def test_send_msg(hass):
"""Test notify.events service."""
notify_calls = async_mock_service(hass, DOMAIN, "events")
await hass.services.async_call(
DOMAIN,
"events",
{
ATTR_MESSAGE: "message content",
ATTR_DATA: {
ATTR_TOKEN: "XYZ",
ATTR_LEVEL: "warning",
ATTR_PRIORITY: "high",
},
},
blocking=True,
)
assert len(notify_calls) == 1
call = notify_calls[-1]
assert call.domain == DOMAIN
assert call.service == "events"
assert call.data.get(ATTR_MESSAGE) == "message content"
assert call.data.get(ATTR_DATA).get(ATTR_TOKEN) == "XYZ"
assert call.data.get(ATTR_DATA).get(ATTR_LEVEL) == "warning"
assert call.data.get(ATTR_DATA).get(ATTR_PRIORITY) == "high"