"""Button support for SwitchBot devices.""" import logging from typing import override import switchbot from switchbot import SwitchbotModel from homeassistant.components.button import ButtonEntity from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util import dt as dt_util from .const import CONF_LOCK_NIGHTLATCH, DEFAULT_LOCK_NIGHTLATCH from .coordinator import SwitchbotConfigEntry, SwitchbotDataUpdateCoordinator from .entity import SwitchbotEntity, exception_handler _LOGGER = logging.getLogger(__name__) PARALLEL_UPDATES = 0 async def async_setup_entry( hass: HomeAssistant, entry: SwitchbotConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up Switchbot button platform.""" coordinator = entry.runtime_data entities: list[ButtonEntity] = [] if isinstance(coordinator.device, switchbot.SwitchbotAirPurifier): entities.append(LightSensorButton(coordinator)) if isinstance(coordinator.device, switchbot.SwitchbotArtFrame): entities.extend( [ SwitchBotArtFrameNextButton(coordinator, "next_image"), SwitchBotArtFramePrevButton(coordinator, "previous_image"), ] ) if isinstance(coordinator.device, switchbot.SwitchbotMeterProCO2): entities.append(SwitchBotMeterProCO2SyncDateTimeButton(coordinator)) if ( isinstance(coordinator.device, switchbot.SwitchbotLock) and coordinator.model is SwitchbotModel.LOCK_ULTRA and entry.options.get(CONF_LOCK_NIGHTLATCH, DEFAULT_LOCK_NIGHTLATCH) ): entities.append(HalfLockButton(coordinator)) if entities: async_add_entities(entities) class LightSensorButton(SwitchbotEntity, ButtonEntity): """Representation of a Switchbot light sensor button.""" _attr_translation_key = "light_sensor" _device: switchbot.SwitchbotAirPurifier def __init__(self, coordinator: SwitchbotDataUpdateCoordinator) -> None: """Initialize the Switchbot light sensor button.""" super().__init__(coordinator) self._attr_unique_id = f"{coordinator.base_unique_id}_light_sensor" @exception_handler @override async def async_press(self) -> None: """Handle the button press.""" _LOGGER.debug("Toggling light sensor mode for %s", self._address) await self._device.open_light_sensitive_switch() class SwitchBotArtFrameButtonBase(SwitchbotEntity, ButtonEntity): """Base class for Art Frame buttons.""" _device: switchbot.SwitchbotArtFrame def __init__( self, coordinator: SwitchbotDataUpdateCoordinator, translation_key: str ) -> None: """Initialize the button base.""" super().__init__(coordinator) self._attr_unique_id = f"{coordinator.base_unique_id}_{translation_key}" self._attr_translation_key = translation_key class SwitchBotArtFrameNextButton(SwitchBotArtFrameButtonBase): """Representation of a next image button.""" @exception_handler @override async def async_press(self) -> None: """Handle the button press.""" _LOGGER.debug("Pressing next image button %s", self._address) await self._device.next_image() class SwitchBotArtFramePrevButton(SwitchBotArtFrameButtonBase): """Representation of a previous image button.""" @exception_handler @override async def async_press(self) -> None: """Handle the button press.""" _LOGGER.debug("Pressing previous image button %s", self._address) await self._device.prev_image() class SwitchBotMeterProCO2SyncDateTimeButton(SwitchbotEntity, ButtonEntity): """Button to sync date and time on Meter Pro CO2.""" _device: switchbot.SwitchbotMeterProCO2 _attr_entity_category = EntityCategory.CONFIG _attr_translation_key = "sync_datetime" def __init__(self, coordinator: SwitchbotDataUpdateCoordinator) -> None: """Initialize the sync time button.""" super().__init__(coordinator) self._attr_unique_id = f"{coordinator.base_unique_id}_sync_datetime" @exception_handler @override async def async_press(self) -> None: """Sync time with Home Assistant.""" now = dt_util.now() # Get UTC offset components utc_offset = now.utcoffset() utc_offset_hours, utc_offset_minutes = 0, 0 if utc_offset is not None: total_seconds = int(utc_offset.total_seconds()) utc_offset_hours = total_seconds // 3600 utc_offset_minutes = abs(total_seconds % 3600) // 60 timestamp = int(now.timestamp()) _LOGGER.debug( "Syncing time for %s: timestamp=%s," " utc_offset_hours=%s, utc_offset_minutes=%s", self._address, timestamp, utc_offset_hours, utc_offset_minutes, ) await self._device.set_datetime( timestamp=timestamp, utc_offset_hours=utc_offset_hours, utc_offset_minutes=utc_offset_minutes, ) class HalfLockButton(SwitchbotEntity, ButtonEntity): """Representation of a Half Lock button for Lock Ultra.""" _attr_translation_key = "half_lock" _device: switchbot.SwitchbotLock def __init__(self, coordinator: SwitchbotDataUpdateCoordinator) -> None: """Initialize the Half Lock button.""" super().__init__(coordinator) self._attr_unique_id = f"{coordinator.base_unique_id}_half_lock" @exception_handler @override async def async_press(self) -> None: """Handle the button press.""" _LOGGER.debug("Sending half lock command for %s", self._address) await self._device.half_lock()