Add Starlink reboot button (#85729)

This commit is contained in:
Jack Boswell 2023-01-16 20:22:19 +13:00 committed by GitHub
parent 176eb01016
commit 8c235357a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 83 additions and 26 deletions

View File

@ -8,7 +8,7 @@ from homeassistant.core import HomeAssistant
from .const import DOMAIN from .const import DOMAIN
from .coordinator import StarlinkUpdateCoordinator from .coordinator import StarlinkUpdateCoordinator
PLATFORMS: list[Platform] = [Platform.BINARY_SENSOR, Platform.SENSOR] PLATFORMS: list[Platform] = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.SENSOR]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:

View File

@ -16,7 +16,7 @@ from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN from .const import DOMAIN
from .coordinator import StarlinkData, StarlinkUpdateCoordinator from .coordinator import StarlinkData
from .entity import StarlinkEntity from .entity import StarlinkEntity
@ -51,16 +51,6 @@ class StarlinkBinarySensorEntity(StarlinkEntity, BinarySensorEntity):
entity_description: StarlinkBinarySensorEntityDescription entity_description: StarlinkBinarySensorEntityDescription
def __init__(
self,
coordinator: StarlinkUpdateCoordinator,
description: StarlinkBinarySensorEntityDescription,
) -> None:
"""Initialize the binary sensor."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{self.coordinator.data.status['id']}_{description.key}"
@property @property
def is_on(self) -> bool | None: def is_on(self) -> bool | None:
"""Calculate the binary sensor value from the entity description.""" """Calculate the binary sensor value from the entity description."""

View File

@ -0,0 +1,66 @@
"""Contains buttons exposed by the Starlink integration."""
from __future__ import annotations
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from homeassistant.components.button import (
ButtonDeviceClass,
ButtonEntity,
ButtonEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .coordinator import StarlinkUpdateCoordinator
from .entity import StarlinkEntity
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up all binary sensors for this entry."""
coordinator = hass.data[DOMAIN][entry.entry_id]
async_add_entities(
StarlinkButtonEntity(coordinator, description) for description in BUTTONS
)
@dataclass
class StarlinkButtonEntityDescriptionMixin:
"""Mixin for required keys."""
press_fn: Callable[[StarlinkUpdateCoordinator], Awaitable[None]]
@dataclass
class StarlinkButtonEntityDescription(
ButtonEntityDescription, StarlinkButtonEntityDescriptionMixin
):
"""Describes a Starlink button entity."""
class StarlinkButtonEntity(StarlinkEntity, ButtonEntity):
"""A ButtonEntity for Starlink devices. Handles creating unique IDs."""
entity_description: StarlinkButtonEntityDescription
async def async_press(self) -> None:
"""Press the button."""
return await self.entity_description.press_fn(self.coordinator)
BUTTONS = [
StarlinkButtonEntityDescription(
key="reboot",
name="Reboot",
device_class=ButtonDeviceClass.RESTART,
entity_category=EntityCategory.DIAGNOSTIC,
press_fn=lambda coordinator: coordinator.reboot_starlink(),
)
]

View File

@ -12,10 +12,12 @@ from starlink_grpc import (
GrpcError, GrpcError,
ObstructionDict, ObstructionDict,
StatusDict, StatusDict,
reboot,
status_data, status_data,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -53,3 +55,11 @@ class StarlinkUpdateCoordinator(DataUpdateCoordinator[StarlinkData]):
return StarlinkData(*status) return StarlinkData(*status)
except GrpcError as exc: except GrpcError as exc:
raise UpdateFailed from exc raise UpdateFailed from exc
async def reboot_starlink(self):
"""Reboot the Starlink system tied to this coordinator."""
async with async_timeout.timeout(4):
try:
await self.hass.async_add_executor_job(reboot, self.channel_context)
except GrpcError as exc:
raise HomeAssistantError from exc

View File

@ -1,7 +1,7 @@
"""Contains base entity classes for Starlink entities.""" """Contains base entity classes for Starlink entities."""
from __future__ import annotations from __future__ import annotations
from homeassistant.helpers.entity import DeviceInfo, Entity from homeassistant.helpers.entity import DeviceInfo, Entity, EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN from .const import DOMAIN
@ -14,8 +14,7 @@ class StarlinkEntity(CoordinatorEntity[StarlinkUpdateCoordinator], Entity):
_attr_has_entity_name = True _attr_has_entity_name = True
def __init__( def __init__(
self, self, coordinator: StarlinkUpdateCoordinator, description: EntityDescription
coordinator: StarlinkUpdateCoordinator,
) -> None: ) -> None:
"""Initialize the device info and set the update coordinator.""" """Initialize the device info and set the update coordinator."""
super().__init__(coordinator) super().__init__(coordinator)
@ -30,3 +29,5 @@ class StarlinkEntity(CoordinatorEntity[StarlinkUpdateCoordinator], Entity):
manufacturer="SpaceX", manufacturer="SpaceX",
model="Starlink", model="Starlink",
) )
self._attr_unique_id = f"{self.coordinator.data.status['id']}_{description.key}"
self.entity_description = description

View File

@ -19,7 +19,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType from homeassistant.helpers.typing import StateType
from .const import DOMAIN from .const import DOMAIN
from .coordinator import StarlinkData, StarlinkUpdateCoordinator from .coordinator import StarlinkData
from .entity import StarlinkEntity from .entity import StarlinkEntity
@ -53,16 +53,6 @@ class StarlinkSensorEntity(StarlinkEntity, SensorEntity):
entity_description: StarlinkSensorEntityDescription entity_description: StarlinkSensorEntityDescription
def __init__(
self,
coordinator: StarlinkUpdateCoordinator,
description: StarlinkSensorEntityDescription,
) -> None:
"""Initialize the sensor."""
super().__init__(coordinator)
self.entity_description = description
self._attr_unique_id = f"{self.coordinator.data.status['id']}_{description.key}"
@property @property
def native_value(self) -> StateType | datetime: def native_value(self) -> StateType | datetime:
"""Calculate the sensor value from the entity description.""" """Calculate the sensor value from the entity description."""