HEX
Server: Apache/2.4.63 (Unix)
System: Linux Synopilou92 4.4.302+ #72806 SMP Mon Jul 21 23:16:00 CST 2025 x86_64
User: pilou92 (1026)
PHP: 8.0.30
Disabled: NONE
Upload Files
File: /volume1/docker/homeassistant2025/custom_components/uconnect/button.py
"""Buttones for Uconnect integration."""

from __future__ import annotations
from typing import Final, Callable

import logging

from homeassistant.core import HomeAssistant
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.button import (
    ButtonDeviceClass,
    ButtonEntityDescription,
    ButtonEntity,
)

from py_uconnect.client import Vehicle
from py_uconnect.command import *

from .const import DOMAIN, CONF_ADD_COMMAND_ENTITIES
from .coordinator import UconnectDataUpdateCoordinator
from .entity import UconnectEntity


@dataclass
class UconnectButtonEntityDescription(ButtonEntityDescription):
    """A class that describes custom switch entities."""

    command: Command = None


BUTTON_DESCRIPTIONS: Final[tuple[UconnectButtonEntityDescription, ...]] = (
    UconnectButtonEntityDescription(
        key="button_location",
        name="Refresh Location",
        icon="mdi:crosshairs-gps",
        command=COMMAND_REFRESH_LOCATION,
        device_class=ButtonDeviceClass.UPDATE,
    ),
    UconnectButtonEntityDescription(
        key="button_deep_refresh",
        name="Deep Refresh",
        icon="mdi:refresh",
        command=COMMAND_DEEP_REFRESH,
        device_class=ButtonDeviceClass.UPDATE,
    ),
    UconnectButtonEntityDescription(
        key="button_charge",
        name="Charge Now",
        icon="mdi:ev-station",
        command=COMMAND_CHARGE,
        device_class=ButtonDeviceClass.UPDATE,
    ),
    UconnectButtonEntityDescription(
        key="button_lights",
        name="Lights",
        icon="mdi:car-light-dimmed",
        command=COMMAND_LIGHTS,
        device_class=ButtonDeviceClass.UPDATE,
    ),
    UconnectButtonEntityDescription(
        key="button_lights_horn",
        name="Lights & Horn",
        icon="mdi:bugle",
        command=COMMAND_LIGHTS_HORN,
        device_class=ButtonDeviceClass.UPDATE,
    ),
)


async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    # Do not add entities if not configured
    if not config_entry.options.get(CONF_ADD_COMMAND_ENTITIES):
        return

    coordinator: UconnectDataUpdateCoordinator = hass.data[DOMAIN][
        config_entry.unique_id
    ]
    entities: list[UconnectButton] = []

    for vehicle in coordinator.client.vehicles.values():
        entities.append(UconnectButtonUpdate(coordinator, vehicle))

        for description in BUTTON_DESCRIPTIONS:
            if description.command.name in vehicle.supported_commands:
                entities.append(UconnectButton(coordinator, description, vehicle))

    async_add_entities(entities)
    return True


class UconnectButton(ButtonEntity, UconnectEntity):
    def __init__(
        self,
        coordinator: UconnectDataUpdateCoordinator,
        description: UconnectButtonEntityDescription,
        vehicle: Vehicle,
    ):
        UconnectEntity.__init__(self, coordinator, vehicle)

        self.entity_description: UconnectButtonEntityDescription = description
        self._attr_name = f"{vehicle.make} {
            vehicle.nickname or vehicle.model} {description.name}"
        self._attr_unique_id = f"{DOMAIN}_{vehicle.vin}_{description.key}"

    @property
    def icon(self):
        return self.entity_description.icon

    async def async_press(self, **kwargs):
        await self.coordinator.async_command(
            self.vehicle.vin, self.entity_description.command
        )


class UconnectButtonUpdate(ButtonEntity, UconnectEntity):
    def __init__(
        self,
        coordinator: UconnectDataUpdateCoordinator,
        vehicle: Vehicle,
    ):
        UconnectEntity.__init__(self, coordinator, vehicle)

        self._attr_name = f"{vehicle.make} {
            vehicle.nickname or vehicle.model} Update Data"
        self._attr_unique_id = f"{DOMAIN}_{vehicle.vin}_update"

    @property
    def icon(self):
        return "mdi:update"

    async def async_press(self, **kwargs):
        await self.coordinator.async_refresh()