Add button entities to bmw_connected_drive (#63136)

Co-authored-by: Gerard <gerard33@users.noreply.github.com>
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
Co-authored-by: rikroe <rikroe@users.noreply.github.com>
This commit is contained in:
rikroe 2022-01-06 12:05:25 +01:00 committed by GitHub
parent 77ccf46c9b
commit e9dec5d03a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 129 additions and 0 deletions

View File

@ -120,6 +120,7 @@ omit =
homeassistant/components/bmp280/sensor.py homeassistant/components/bmp280/sensor.py
homeassistant/components/bmw_connected_drive/__init__.py homeassistant/components/bmw_connected_drive/__init__.py
homeassistant/components/bmw_connected_drive/binary_sensor.py homeassistant/components/bmw_connected_drive/binary_sensor.py
homeassistant/components/bmw_connected_drive/button.py
homeassistant/components/bmw_connected_drive/device_tracker.py homeassistant/components/bmw_connected_drive/device_tracker.py
homeassistant/components/bmw_connected_drive/lock.py homeassistant/components/bmw_connected_drive/lock.py
homeassistant/components/bmw_connected_drive/notify.py homeassistant/components/bmw_connected_drive/notify.py

View File

@ -68,6 +68,7 @@ DEFAULT_OPTIONS = {
PLATFORMS = [ PLATFORMS = [
Platform.BINARY_SENSOR, Platform.BINARY_SENSOR,
Platform.BUTTON,
Platform.DEVICE_TRACKER, Platform.DEVICE_TRACKER,
Platform.LOCK, Platform.LOCK,
Platform.NOTIFY, Platform.NOTIFY,
@ -223,6 +224,11 @@ def setup_account(
def execute_service(call: ServiceCall) -> None: def execute_service(call: ServiceCall) -> None:
"""Execute a service for a vehicle.""" """Execute a service for a vehicle."""
_LOGGER.warning(
"BMW Connected Drive services are deprecated. Please migrate to the dedicated button entities. "
"See https://www.home-assistant.io/integrations/bmw_connected_drive/#buttons for details"
)
vin: str | None = call.data.get(ATTR_VIN) vin: str | None = call.data.get(ATTR_VIN)
device_id: str | None = call.data.get(CONF_DEVICE_ID) device_id: str | None = call.data.get(CONF_DEVICE_ID)

View File

@ -0,0 +1,122 @@
"""Support for BMW connected drive button entities."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from bimmer_connected.remote_services import RemoteServiceStatus
from bimmer_connected.vehicle import ConnectedDriveVehicle
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import (
DOMAIN as BMW_DOMAIN,
BMWConnectedDriveAccount,
BMWConnectedDriveBaseEntity,
)
from .const import CONF_ACCOUNT, DATA_ENTRIES
@dataclass
class BMWButtonEntityDescription(ButtonEntityDescription):
"""Class describing BMW button entities."""
enabled_when_read_only: bool = False
remote_function: Callable[
[ConnectedDriveVehicle], RemoteServiceStatus
] | None = None
account_function: Callable[[BMWConnectedDriveAccount], None] | None = None
BUTTON_TYPES: tuple[BMWButtonEntityDescription, ...] = (
BMWButtonEntityDescription(
key="light_flash",
icon="mdi:car-light-alert",
name="Flash Lights",
remote_function=lambda vehicle: vehicle.remote_services.trigger_remote_light_flash(),
),
BMWButtonEntityDescription(
key="sound_horn",
icon="mdi:bullhorn",
name="Sound Horn",
remote_function=lambda vehicle: vehicle.remote_services.trigger_remote_horn(),
),
BMWButtonEntityDescription(
key="activate_air_conditioning",
icon="mdi:hvac",
name="Activate Air Conditioning",
remote_function=lambda vehicle: vehicle.remote_services.trigger_remote_air_conditioning(),
),
BMWButtonEntityDescription(
key="deactivate_air_conditioning",
icon="mdi:hvac-off",
name="Deactivate Air Conditioning",
remote_function=lambda vehicle: vehicle.remote_services.trigger_remote_air_conditioning_stop(),
),
BMWButtonEntityDescription(
key="find_vehicle",
icon="mdi:crosshairs-question",
name="Find Vehicle",
remote_function=lambda vehicle: vehicle.remote_services.trigger_remote_vehicle_finder(),
),
BMWButtonEntityDescription(
key="refresh",
icon="mdi:refresh",
name="Refresh from cloud",
account_function=lambda account: account.update(),
enabled_when_read_only=True,
),
)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the BMW ConnectedDrive buttons from config entry."""
account: BMWConnectedDriveAccount = hass.data[BMW_DOMAIN][DATA_ENTRIES][
config_entry.entry_id
][CONF_ACCOUNT]
entities: list[BMWButton] = []
for vehicle in account.account.vehicles:
entities.extend(
[
BMWButton(account, vehicle, description)
for description in BUTTON_TYPES
if not account.read_only
or (account.read_only and description.enabled_when_read_only)
]
)
async_add_entities(entities)
class BMWButton(BMWConnectedDriveBaseEntity, ButtonEntity):
"""Representation of a BMW Connected Drive button."""
entity_description: BMWButtonEntityDescription
def __init__(
self,
account: BMWConnectedDriveAccount,
vehicle: ConnectedDriveVehicle,
description: BMWButtonEntityDescription,
) -> None:
"""Initialize BMW vehicle sensor."""
super().__init__(account, vehicle)
self.entity_description = description
self._attr_name = f"{vehicle.name} {description.name}"
self._attr_unique_id = f"{vehicle.vin}-{description.key}"
def press(self) -> None:
"""Process the button press."""
if self.entity_description.remote_function:
self.entity_description.remote_function(self._vehicle)
elif self.entity_description.account_function:
self.entity_description.account_function(self._account)