Skip to content

Commit

Permalink
Merge pull request #69935 from home-assistant/rc
Browse files Browse the repository at this point in the history
  • Loading branch information
balloob committed Apr 12, 2022
2 parents a1fddc3 + 25fc64a commit 398c7be
Show file tree
Hide file tree
Showing 39 changed files with 430 additions and 128 deletions.
3 changes: 2 additions & 1 deletion homeassistant/components/cast/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,8 @@ def turn_on(self):

# The only way we can turn the Chromecast is on is by launching an app
if self._chromecast.cast_type == pychromecast.const.CAST_TYPE_CHROMECAST:
self._chromecast.play_media(CAST_SPLASH, "image/png")
app_data = {"media_id": CAST_SPLASH, "media_type": "image/png"}
quick_play(self._chromecast, "default_media_receiver", app_data)
else:
self._chromecast.start_app(pychromecast.config.APP_MEDIA_RECEIVER)

Expand Down
16 changes: 10 additions & 6 deletions homeassistant/components/climate/device_condition.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,19 @@ def async_condition_from_config(
hass: HomeAssistant, config: ConfigType
) -> condition.ConditionCheckerType:
"""Create a function to test a device condition."""
if config[CONF_TYPE] == "is_hvac_mode":
attribute = const.ATTR_HVAC_MODE
else:
attribute = const.ATTR_PRESET_MODE

def test_is_state(hass: HomeAssistant, variables: TemplateVarsType) -> bool:
"""Test if an entity is a certain state."""
state = hass.states.get(config[ATTR_ENTITY_ID])
return state.attributes.get(attribute) == config[attribute] if state else False
if (state := hass.states.get(config[ATTR_ENTITY_ID])) is None:
return False

if config[CONF_TYPE] == "is_hvac_mode":
return state.state == config[const.ATTR_HVAC_MODE]

return (
state.attributes.get(const.ATTR_PRESET_MODE)
== config[const.ATTR_PRESET_MODE]
)

return test_is_state

Expand Down
16 changes: 9 additions & 7 deletions homeassistant/components/devolo_home_control/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ def __init__(
self, homecontrol: HomeControl, device_instance: Zwave, element_uid: str
) -> None:
"""Initialize a devolo binary sensor."""
self._binary_sensor_property = device_instance.binary_sensor_property.get(
self._binary_sensor_property = device_instance.binary_sensor_property[
element_uid
)
]

super().__init__(
homecontrol=homecontrol,
Expand All @@ -82,10 +82,12 @@ def __init__(
)

if self._attr_device_class is None:
if device_instance.binary_sensor_property.get(element_uid).sub_type != "":
self._attr_name += f" {device_instance.binary_sensor_property.get(element_uid).sub_type}"
if device_instance.binary_sensor_property[element_uid].sub_type != "":
self._attr_name += (
f" {device_instance.binary_sensor_property[element_uid].sub_type}"
)
else:
self._attr_name += f" {device_instance.binary_sensor_property.get(element_uid).sensor_type}"
self._attr_name += f" {device_instance.binary_sensor_property[element_uid].sensor_type}"

self._value = self._binary_sensor_property.state

Expand Down Expand Up @@ -114,9 +116,9 @@ def __init__(
key: int,
) -> None:
"""Initialize a devolo remote control."""
self._remote_control_property = device_instance.remote_control_property.get(
self._remote_control_property = device_instance.remote_control_property[
element_uid
)
]

super().__init__(
homecontrol=homecontrol,
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/devolo_home_control/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def __init__(
@property
def current_cover_position(self) -> int:
"""Return the current position. 0 is closed. 100 is open."""
return self._value
return int(self._value)

@property
def is_closed(self) -> bool:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __init__(

self.subscriber: Subscriber | None = None
self.sync_callback = self._sync
self._value: int
self._value: float

async def async_added_to_hass(self) -> None:
"""Call when entity is added to hass."""
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/devolo_home_control/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"domain": "devolo_home_control",
"name": "devolo Home Control",
"documentation": "https://www.home-assistant.io/integrations/devolo_home_control",
"requirements": ["devolo-home-control-api==0.17.4"],
"requirements": ["devolo-home-control-api==0.18.1"],
"after_dependencies": ["zeroconf"],
"config_flow": true,
"codeowners": ["@2Fake", "@Shutgun"],
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/devolo_home_control/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class DevoloMultiLevelDeviceEntity(DevoloDeviceEntity, SensorEntity):
"""Abstract representation of a multi level sensor within devolo Home Control."""

@property
def native_value(self) -> int:
def native_value(self) -> float:
"""Return the state of the sensor."""
return self._value

Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/devolo_home_control/siren.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ def __init__(
)
self._attr_available_tones = [
*range(
self._multi_level_switch_property.min,
self._multi_level_switch_property.max + 1,
int(self._multi_level_switch_property.min),
int(self._multi_level_switch_property.max) + 1,
)
]
self._attr_supported_features = (
Expand Down
6 changes: 3 additions & 3 deletions homeassistant/components/devolo_home_control/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ def __init__(
device_instance=device_instance,
element_uid=element_uid,
)
self._binary_switch_property = self._device_instance.binary_switch_property.get(
self._attr_unique_id
)
self._binary_switch_property = self._device_instance.binary_switch_property[
self._attr_unique_id # type: ignore[index]
]
self._attr_is_on = self._binary_switch_property.state

def turn_on(self, **kwargs: Any) -> None:
Expand Down
18 changes: 12 additions & 6 deletions homeassistant/components/fibaro/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import annotations

import asyncio
from contextlib import suppress
from functools import partial

from homeassistant.components.light import (
Expand Down Expand Up @@ -198,16 +199,21 @@ def is_on(self) -> bool | None:
Dimmable and RGB lights can be on based on different
properties, so we need to check here several values.
JSON for HC2 uses always string, HC3 uses int for integers.
"""
props = self.fibaro_device.properties
if self.current_binary_state:
return True
if "brightness" in props and props.brightness != "0":
return True
if "currentProgram" in props and props.currentProgram != "0":
return True
if "currentProgramID" in props and props.currentProgramID != "0":
return True
with suppress(ValueError, TypeError):
if "brightness" in props and int(props.brightness) != 0:
return True
with suppress(ValueError, TypeError):
if "currentProgram" in props and int(props.currentProgram) != 0:
return True
with suppress(ValueError, TypeError):
if "currentProgramID" in props and int(props.currentProgramID) != 0:
return True

return False

Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/google/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
session = config_entry_oauth2_flow.OAuth2Session(hass, entry, implementation)
# Force a token refresh to fix a bug where tokens were persisted with
# expires_in (relative time delta) and expires_at (absolute time) swapped.
if session.token["expires_at"] >= datetime(2070, 1, 1).timestamp():
# A google session token typically only lasts a few days between refresh.
now = datetime.now()
if session.token["expires_at"] >= (now + timedelta(days=365)).timestamp():
session.token["expires_in"] = 0
session.token["expires_at"] = datetime.now().timestamp()
session.token["expires_at"] = now.timestamp()
try:
await session.async_ensure_token_valid()
except aiohttp.ClientResponseError as err:
Expand Down
30 changes: 21 additions & 9 deletions homeassistant/components/hassio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
dev_reg = await async_get_registry(hass)
coordinator = HassioDataUpdateCoordinator(hass, entry, dev_reg)
hass.data[ADDONS_COORDINATOR] = coordinator
await coordinator.async_refresh()
await coordinator.async_config_entry_first_refresh()

hass.config_entries.async_setup_platforms(entry, PLATFORMS)

Expand Down Expand Up @@ -848,8 +848,8 @@ async def _async_update_data(self) -> dict[str, Any]:
new_data[DATA_KEY_ADDONS] = {
addon[ATTR_SLUG]: {
**addon,
**((addons_stats or {}).get(addon[ATTR_SLUG], {})),
ATTR_AUTO_UPDATE: addons_info.get(addon[ATTR_SLUG], {}).get(
**((addons_stats or {}).get(addon[ATTR_SLUG]) or {}),
ATTR_AUTO_UPDATE: (addons_info.get(addon[ATTR_SLUG]) or {}).get(
ATTR_AUTO_UPDATE, False
),
ATTR_CHANGELOG: (addons_changelogs or {}).get(addon[ATTR_SLUG]),
Expand Down Expand Up @@ -952,15 +952,27 @@ async def force_data_refresh(self) -> None:

async def _update_addon_stats(self, slug):
"""Update single addon stats."""
stats = await self.hassio.get_addon_stats(slug)
return (slug, stats)
try:
stats = await self.hassio.get_addon_stats(slug)
return (slug, stats)
except HassioAPIError as err:
_LOGGER.warning("Could not fetch stats for %s: %s", slug, err)
return (slug, None)

async def _update_addon_changelog(self, slug):
"""Return the changelog for an add-on."""
changelog = await self.hassio.get_addon_changelog(slug)
return (slug, changelog)
try:
changelog = await self.hassio.get_addon_changelog(slug)
return (slug, changelog)
except HassioAPIError as err:
_LOGGER.warning("Could not fetch changelog for %s: %s", slug, err)
return (slug, None)

async def _update_addon_info(self, slug):
"""Return the info for an add-on."""
info = await self.hassio.get_addon_info(slug)
return (slug, info)
try:
info = await self.hassio.get_addon_info(slug)
return (slug, info)
except HassioAPIError as err:
_LOGGER.warning("Could not fetch info for %s: %s", slug, err)
return (slug, None)
6 changes: 0 additions & 6 deletions homeassistant/components/knx/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,3 @@ async def async_added_to_hass(self) -> None:
await super().async_added_to_hass()
if self._device.mode is not None:
self._device.mode.register_device_updated_cb(self.after_update_callback)

async def async_will_remove_from_hass(self) -> None:
"""Disconnect device object when removed."""
await super().async_will_remove_from_hass()
if self._device.mode is not None:
self._device.mode.unregister_device_updated_cb(self.after_update_callback)
3 changes: 2 additions & 1 deletion homeassistant/components/knx/knx_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ async def async_added_to_hass(self) -> None:

async def async_will_remove_from_hass(self) -> None:
"""Disconnect device object when removed."""
self._device.unregister_device_updated_cb(self.after_update_callback)
# will also remove callbacks
self._device.shutdown()
2 changes: 1 addition & 1 deletion homeassistant/components/knx/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "KNX",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/knx",
"requirements": ["xknx==0.20.1"],
"requirements": ["xknx==0.20.2"],
"codeowners": ["@Julius2342", "@farmio", "@marvin-w"],
"quality_scale": "silver",
"iot_class": "local_push",
Expand Down
3 changes: 3 additions & 0 deletions homeassistant/components/media_player/browse_media.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ def async_process_play_media_url(
"""Update a media URL with authentication if it points at Home Assistant."""
parsed = yarl.URL(media_content_id)

if parsed.scheme and parsed.scheme not in ("http", "https"):
return media_content_id

if parsed.is_absolute():
if not is_hass_url(hass, media_content_id):
return media_content_id
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/motion_blinds/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ async def async_setup_entry(
platform.async_register_entity_service(
SERVICE_SET_ABSOLUTE_POSITION,
SET_ABSOLUTE_POSITION_SCHEMA,
SERVICE_SET_ABSOLUTE_POSITION,
"async_set_absolute_position",
)


Expand Down
4 changes: 1 addition & 3 deletions homeassistant/components/mpd/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ async def async_play_media(self, media_type, media_id, **kwargs):
if media_source.is_media_source_id(media_id):
media_type = MEDIA_TYPE_MUSIC
play_item = await media_source.async_resolve_media(self.hass, media_id)
media_id = play_item.url
media_id = async_process_play_media_url(self.hass, play_item.url)

if media_type == MEDIA_TYPE_PLAYLIST:
_LOGGER.debug("Playing playlist: %s", media_id)
Expand All @@ -476,8 +476,6 @@ async def async_play_media(self, media_type, media_id, **kwargs):
await self._client.load(media_id)
await self._client.play()
else:
media_id = async_process_play_media_url(self.hass, media_id)

await self._client.clear()
self._currentplaylist = None
await self._client.add(media_id)
Expand Down
3 changes: 1 addition & 2 deletions homeassistant/components/overkiz/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ def _select_option_open_closed_pedestrian(
OverkizCommandParam.CLOSED: OverkizCommand.CLOSE,
OverkizCommandParam.OPEN: OverkizCommand.OPEN,
OverkizCommandParam.PEDESTRIAN: OverkizCommand.SET_PEDESTRIAN_POSITION,
}[OverkizCommandParam(option)],
None,
}[OverkizCommandParam(option)]
)


Expand Down

0 comments on commit 398c7be

Please sign in to comment.