"""The yalexs_ble integration entities.""" from __future__ import annotations from yalexs_ble import ConnectionInfo, LockInfo, LockState from homeassistant.components import bluetooth from homeassistant.core import callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.entity import DeviceInfo, Entity from .const import DOMAIN from .models import YaleXSBLEData class YALEXSBLEEntity(Entity): """Base class for yale xs ble entities.""" _attr_should_poll = False def __init__(self, data: YaleXSBLEData) -> None: """Initialize the entity.""" self._data = data self._device = device = data.lock self._attr_available = False lock_state = device.lock_state lock_info = device.lock_info connection_info = device.connection_info assert lock_state is not None assert connection_info is not None assert lock_info is not None self._attr_unique_id = device.address self._attr_device_info = DeviceInfo( name=data.title, manufacturer=lock_info.manufacturer, model=lock_info.model, connections={(dr.CONNECTION_BLUETOOTH, device.address)}, identifiers={(DOMAIN, lock_info.serial)}, sw_version=lock_info.firmware, ) if device.lock_state: self._async_update_state(lock_state, lock_info, connection_info) @callback def _async_update_state( self, new_state: LockState, lock_info: LockInfo, connection_info: ConnectionInfo ) -> None: """Update the state.""" self._attr_available = bool(not new_state.auth or new_state.auth.successful) @callback def _async_state_changed( self, new_state: LockState, lock_info: LockInfo, connection_info: ConnectionInfo ) -> None: """Handle state changed.""" self._async_update_state(new_state, lock_info, connection_info) self.async_write_ha_state() @callback def _async_device_unavailable( self, _service_info: bluetooth.BluetoothServiceInfoBleak ) -> None: """Handle device not longer being seen by the bluetooth stack.""" self._attr_available = False self.async_write_ha_state() async def async_added_to_hass(self) -> None: """Register callbacks.""" self.async_on_remove( bluetooth.async_track_unavailable( self.hass, self._async_device_unavailable, self._device.address ) ) self.async_on_remove(self._device.register_callback(self._async_state_changed)) return await super().async_added_to_hass() async def async_update(self) -> None: """Request a manual update.""" await self._device.update()