Skip to content

Commit

Permalink
Merge pull request #76964 from home-assistant/rc
Browse files Browse the repository at this point in the history
  • Loading branch information
balloob authored Aug 18, 2022
2 parents 795ed9f + d5b6cca commit c894dde
Show file tree
Hide file tree
Showing 25 changed files with 739 additions and 87 deletions.
5 changes: 3 additions & 2 deletions homeassistant/components/acmeda/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .base import AcmedaBase
from .const import ACMEDA_HUB_UPDATE, DOMAIN
from .helpers import async_add_acmeda_entities
from .hub import PulseHub


async def async_setup_entry(
Expand All @@ -24,7 +25,7 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Acmeda Rollers from a config entry."""
hub = hass.data[DOMAIN][config_entry.entry_id]
hub: PulseHub = hass.data[DOMAIN][config_entry.entry_id]

current: set[int] = set()

Expand Down Expand Up @@ -122,6 +123,6 @@ async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
"""Stop the roller."""
await self.roller.move_stop()

async def async_set_cover_tilt(self, **kwargs):
async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
"""Tilt the roller shutter to a specific position."""
await self.roller.move_to(100 - kwargs[ATTR_POSITION])
40 changes: 15 additions & 25 deletions homeassistant/components/bmw_connected_drive/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,7 @@
SensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
LENGTH_KILOMETERS,
LENGTH_MILES,
PERCENTAGE,
VOLUME_GALLONS,
VOLUME_LITERS,
)
from homeassistant.const import LENGTH, PERCENTAGE, VOLUME
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
Expand All @@ -39,8 +33,7 @@ class BMWSensorEntityDescription(SensorEntityDescription):
"""Describes BMW sensor entity."""

key_class: str | None = None
unit_metric: str | None = None
unit_imperial: str | None = None
unit_type: str | None = None
value: Callable = lambda x, y: x


Expand Down Expand Up @@ -86,56 +79,49 @@ def convert_and_round(
"remaining_battery_percent": BMWSensorEntityDescription(
key="remaining_battery_percent",
key_class="fuel_and_battery",
unit_metric=PERCENTAGE,
unit_imperial=PERCENTAGE,
unit_type=PERCENTAGE,
device_class=SensorDeviceClass.BATTERY,
),
# --- Specific ---
"mileage": BMWSensorEntityDescription(
key="mileage",
icon="mdi:speedometer",
unit_metric=LENGTH_KILOMETERS,
unit_imperial=LENGTH_MILES,
unit_type=LENGTH,
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
),
"remaining_range_total": BMWSensorEntityDescription(
key="remaining_range_total",
key_class="fuel_and_battery",
icon="mdi:map-marker-distance",
unit_metric=LENGTH_KILOMETERS,
unit_imperial=LENGTH_MILES,
unit_type=LENGTH,
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
),
"remaining_range_electric": BMWSensorEntityDescription(
key="remaining_range_electric",
key_class="fuel_and_battery",
icon="mdi:map-marker-distance",
unit_metric=LENGTH_KILOMETERS,
unit_imperial=LENGTH_MILES,
unit_type=LENGTH,
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
),
"remaining_range_fuel": BMWSensorEntityDescription(
key="remaining_range_fuel",
key_class="fuel_and_battery",
icon="mdi:map-marker-distance",
unit_metric=LENGTH_KILOMETERS,
unit_imperial=LENGTH_MILES,
unit_type=LENGTH,
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
),
"remaining_fuel": BMWSensorEntityDescription(
key="remaining_fuel",
key_class="fuel_and_battery",
icon="mdi:gas-station",
unit_metric=VOLUME_LITERS,
unit_imperial=VOLUME_GALLONS,
unit_type=VOLUME,
value=lambda x, hass: convert_and_round(x, hass.config.units.volume, 2),
),
"remaining_fuel_percent": BMWSensorEntityDescription(
key="remaining_fuel_percent",
key_class="fuel_and_battery",
icon="mdi:gas-station",
unit_metric=PERCENTAGE,
unit_imperial=PERCENTAGE,
unit_type=PERCENTAGE,
),
}

Expand Down Expand Up @@ -182,8 +168,12 @@ def __init__(
self._attr_name = f"{vehicle.name} {description.key}"
self._attr_unique_id = f"{vehicle.vin}-{description.key}"

# Force metric system as BMW API apparently only returns metric values now
self._attr_native_unit_of_measurement = description.unit_metric
# Set the correct unit of measurement based on the unit_type
if description.unit_type:
self._attr_native_unit_of_measurement = (
coordinator.hass.config.units.as_dict().get(description.unit_type)
or description.unit_type
)

@callback
def _handle_coordinator_update(self) -> None:
Expand Down
16 changes: 10 additions & 6 deletions homeassistant/components/discord/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import discovery
from homeassistant.helpers.typing import ConfigType

from .const import DOMAIN
from .const import DATA_HASS_CONFIG, DOMAIN

PLATFORMS = [Platform.NOTIFY]


async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Discord component."""

hass.data[DATA_HASS_CONFIG] = config
return True


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Discord from a config entry."""
nextcord.VoiceClient.warn_nacl = False
Expand All @@ -30,11 +38,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:

hass.async_create_task(
discovery.async_load_platform(
hass,
Platform.NOTIFY,
DOMAIN,
hass.data[DOMAIN][entry.entry_id],
hass.data[DOMAIN],
hass, Platform.NOTIFY, DOMAIN, dict(entry.data), hass.data[DATA_HASS_CONFIG]
)
)

Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/discord/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
DOMAIN: Final = "discord"

URL_PLACEHOLDER = {CONF_URL: "https://www.home-assistant.io/integrations/discord"}

DATA_HASS_CONFIG = "discord_hass_config"
5 changes: 2 additions & 3 deletions homeassistant/components/mobile_app/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,8 @@ def is_on(self):
"""Return the state of the binary sensor."""
return self._config[ATTR_SENSOR_STATE]

@callback
def async_restore_last_state(self, last_state):
async def async_restore_last_state(self, last_state):
"""Restore previous state."""

super().async_restore_last_state(last_state)
await super().async_restore_last_state(last_state)
self._config[ATTR_SENSOR_STATE] = last_state.state == STATE_ON
5 changes: 2 additions & 3 deletions homeassistant/components/mobile_app/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,9 @@ async def async_added_to_hass(self):
if (state := await self.async_get_last_state()) is None:
return

self.async_restore_last_state(state)
await self.async_restore_last_state(state)

@callback
def async_restore_last_state(self, last_state):
async def async_restore_last_state(self, last_state):
"""Restore previous state."""
self._config[ATTR_SENSOR_STATE] = last_state.state
self._config[ATTR_SENSOR_ATTRIBUTES] = {
Expand Down
28 changes: 25 additions & 3 deletions homeassistant/components/mobile_app/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

from typing import Any

from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.components.sensor import RestoreSensor, SensorDeviceClass
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_WEBHOOK_ID, STATE_UNKNOWN
from homeassistant.const import CONF_WEBHOOK_ID, STATE_UNKNOWN, TEMP_CELSIUS
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.dispatcher import async_dispatcher_connect
Expand All @@ -27,6 +27,7 @@
DOMAIN,
)
from .entity import MobileAppEntity
from .webhook import _extract_sensor_unique_id


async def async_setup_entry(
Expand Down Expand Up @@ -73,9 +74,30 @@ def handle_sensor_registration(data):
)


class MobileAppSensor(MobileAppEntity, SensorEntity):
class MobileAppSensor(MobileAppEntity, RestoreSensor):
"""Representation of an mobile app sensor."""

async def async_restore_last_state(self, last_state):
"""Restore previous state."""

await super().async_restore_last_state(last_state)

if not (last_sensor_data := await self.async_get_last_sensor_data()):
# Workaround to handle migration to RestoreSensor, can be removed
# in HA Core 2023.4
self._config[ATTR_SENSOR_STATE] = None
webhook_id = self._entry.data[CONF_WEBHOOK_ID]
sensor_unique_id = _extract_sensor_unique_id(webhook_id, self.unique_id)
if (
self.device_class == SensorDeviceClass.TEMPERATURE
and sensor_unique_id == "battery_temperature"
):
self._config[ATTR_SENSOR_UOM] = TEMP_CELSIUS
return

self._config[ATTR_SENSOR_STATE] = last_sensor_data.native_value
self._config[ATTR_SENSOR_UOM] = last_sensor_data.native_unit_of_measurement

@property
def native_value(self):
"""Return the state of the sensor."""
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/netgear/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"domain": "netgear",
"name": "NETGEAR",
"documentation": "https://www.home-assistant.io/integrations/netgear",
"requirements": ["pynetgear==0.10.6"],
"requirements": ["pynetgear==0.10.7"],
"codeowners": ["@hacf-fr", "@Quentame", "@starkillerOG"],
"iot_class": "local_polling",
"config_flow": true,
Expand Down
12 changes: 10 additions & 2 deletions homeassistant/components/notify/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Provides functionality to notify people."""
from __future__ import annotations

import asyncio

import voluptuous as vol

import homeassistant.components.persistent_notification as pn
Expand Down Expand Up @@ -40,13 +42,19 @@
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the notify services."""

platform_setups = async_setup_legacy(hass, config)

# We need to add the component here break the deadlock
# when setting up integrations from config entries as
# they would otherwise wait for notify to be
# setup and thus the config entries would not be able to
# setup their platforms.
# setup their platforms, but we need to do it after
# the dispatcher is connected so we don't miss integrations
# that are registered before the dispatcher is connected
hass.config.components.add(DOMAIN)
await async_setup_legacy(hass, config)

if platform_setups:
await asyncio.wait([asyncio.create_task(setup) for setup in platform_setups])

async def persistent_notification(service: ServiceCall) -> None:
"""Send notification via the built-in persistsent_notify integration."""
Expand Down
21 changes: 11 additions & 10 deletions homeassistant/components/notify/legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import annotations

import asyncio
from collections.abc import Coroutine
from functools import partial
from typing import Any, cast

Expand Down Expand Up @@ -32,7 +33,10 @@
NOTIFY_DISCOVERY_DISPATCHER = "notify_discovery_dispatcher"


async def async_setup_legacy(hass: HomeAssistant, config: ConfigType) -> None:
@callback
def async_setup_legacy(
hass: HomeAssistant, config: ConfigType
) -> list[Coroutine[Any, Any, None]]:
"""Set up legacy notify services."""
hass.data.setdefault(NOTIFY_SERVICES, {})
hass.data.setdefault(NOTIFY_DISCOVERY_DISPATCHER, None)
Expand Down Expand Up @@ -101,15 +105,6 @@ async def async_setup_platform(
)
hass.config.components.add(f"{DOMAIN}.{integration_name}")

setup_tasks = [
asyncio.create_task(async_setup_platform(integration_name, p_config))
for integration_name, p_config in config_per_platform(config, DOMAIN)
if integration_name is not None
]

if setup_tasks:
await asyncio.wait(setup_tasks)

async def async_platform_discovered(
platform: str, info: DiscoveryInfoType | None
) -> None:
Expand All @@ -120,6 +115,12 @@ async def async_platform_discovered(
hass, DOMAIN, async_platform_discovered
)

return [
async_setup_platform(integration_name, p_config)
for integration_name, p_config in config_per_platform(config, DOMAIN)
if integration_name is not None
]


@callback
def check_templates_warn(hass: HomeAssistant, tpl: template.Template) -> None:
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/overkiz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
) or OVERKIZ_DEVICE_TO_PLATFORM.get(device.ui_class):
platforms[platform].append(device)

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

device_registry = dr.async_get(hass)

for gateway in setup.gateways:
Expand All @@ -128,6 +126,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
configuration_url=server.configuration_url,
)

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

return True


Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/slack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from homeassistant.helpers import aiohttp_client, discovery
from homeassistant.helpers.typing import ConfigType

from .const import DATA_CLIENT, DOMAIN
from .const import DATA_CLIENT, DATA_HASS_CONFIG, DOMAIN

_LOGGER = logging.getLogger(__name__)

Expand All @@ -21,6 +21,8 @@

async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Slack component."""
hass.data[DATA_HASS_CONFIG] = config

# Iterate all entries for notify to only get Slack
if Platform.NOTIFY in config:
for entry in config[Platform.NOTIFY]:
Expand Down Expand Up @@ -55,7 +57,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
Platform.NOTIFY,
DOMAIN,
hass.data[DOMAIN][entry.entry_id],
hass.data[DOMAIN],
hass.data[DATA_HASS_CONFIG],
)
)

Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/slack/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@
DATA_CLIENT = "client"
DEFAULT_TIMEOUT_SECONDS = 15
DOMAIN: Final = "slack"

DATA_HASS_CONFIG = "slack_hass_config"
2 changes: 1 addition & 1 deletion homeassistant/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

MAJOR_VERSION: Final = 2022
MINOR_VERSION: Final = 8
PATCH_VERSION: Final = "5"
PATCH_VERSION: Final = "6"
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 9, 0)
Expand Down
Loading

0 comments on commit c894dde

Please sign in to comment.