Add dormakaba_dkey battery sensor (#87975)

* Add dormakaba_dkey battery sensor

* Update .coveragerc

* Apply suggestion from code review

* Update .coveragerc
This commit is contained in:
Erik Montnemery 2023-02-13 11:09:23 +01:00 committed by GitHub
parent 9404a107b2
commit 575f7c4205
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 129 additions and 34 deletions

View File

@ -213,7 +213,9 @@ omit =
homeassistant/components/doorbird/entity.py homeassistant/components/doorbird/entity.py
homeassistant/components/doorbird/util.py homeassistant/components/doorbird/util.py
homeassistant/components/dormakaba_dkey/__init__.py homeassistant/components/dormakaba_dkey/__init__.py
homeassistant/components/dormakaba_dkey/entity.py
homeassistant/components/dormakaba_dkey/lock.py homeassistant/components/dormakaba_dkey/lock.py
homeassistant/components/dormakaba_dkey/sensor.py
homeassistant/components/dovado/* homeassistant/components/dovado/*
homeassistant/components/downloader/* homeassistant/components/downloader/*
homeassistant/components/dsmr_reader/__init__.py homeassistant/components/dsmr_reader/__init__.py

View File

@ -19,7 +19,7 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda
from .const import CONF_ASSOCIATION_DATA, DOMAIN, UPDATE_SECONDS from .const import CONF_ASSOCIATION_DATA, DOMAIN, UPDATE_SECONDS
from .models import DormakabaDkeyData from .models import DormakabaDkeyData
PLATFORMS: list[Platform] = [Platform.LOCK] PLATFORMS: list[Platform] = [Platform.LOCK, Platform.SENSOR]
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)

View File

@ -0,0 +1,56 @@
"""Dormakaba dKey integration base entity."""
from __future__ import annotations
import abc
from py_dormakaba_dkey import DKEYLock
from py_dormakaba_dkey.commands import Notifications
from homeassistant.core import callback
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
)
class DormakabaDkeyEntity(CoordinatorEntity[DataUpdateCoordinator[None]]):
"""Dormakaba dKey base entity."""
_attr_has_entity_name = True
def __init__(
self, coordinator: DataUpdateCoordinator[None], lock: DKEYLock
) -> None:
"""Initialize a Dormakaba dKey entity."""
super().__init__(coordinator)
self._lock = lock
self._attr_device_info = DeviceInfo(
name=lock.device_info.device_name or lock.device_info.device_id,
model="MTL 9291",
sw_version=lock.device_info.sw_version,
connections={(dr.CONNECTION_BLUETOOTH, lock.address)},
)
self._async_update_attrs()
@abc.abstractmethod
@callback
def _async_update_attrs(self) -> None:
"""Handle updating _attr values."""
@callback
def _handle_coordinator_update(self) -> None:
"""Handle data update."""
self._async_update_attrs()
self.async_write_ha_state()
@callback
def _handle_state_update(self, update: Notifications) -> None:
"""Handle data update."""
self.coordinator.async_set_updated_data(None)
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
self.async_on_remove(self._lock.register_callback(self._handle_state_update))
return await super().async_added_to_hass()

View File

@ -4,20 +4,16 @@ from __future__ import annotations
from typing import Any from typing import Any
from py_dormakaba_dkey import DKEYLock from py_dormakaba_dkey import DKEYLock
from py_dormakaba_dkey.commands import Notifications, UnlockStatus from py_dormakaba_dkey.commands import UnlockStatus
from homeassistant.components.lock import LockEntity from homeassistant.components.lock import LockEntity
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import ( from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
CoordinatorEntity,
DataUpdateCoordinator,
)
from .const import DOMAIN from .const import DOMAIN
from .entity import DormakabaDkeyEntity
from .models import DormakabaDkeyData from .models import DormakabaDkeyData
@ -31,7 +27,7 @@ async def async_setup_entry(
async_add_entities([DormakabaDkeyLock(data.coordinator, data.lock)]) async_add_entities([DormakabaDkeyLock(data.coordinator, data.lock)])
class DormakabaDkeyLock(CoordinatorEntity[DataUpdateCoordinator[None]], LockEntity): class DormakabaDkeyLock(DormakabaDkeyEntity, LockEntity):
"""Representation of Dormakaba dKey lock.""" """Representation of Dormakaba dKey lock."""
_attr_has_entity_name = True _attr_has_entity_name = True
@ -40,16 +36,8 @@ class DormakabaDkeyLock(CoordinatorEntity[DataUpdateCoordinator[None]], LockEnti
self, coordinator: DataUpdateCoordinator[None], lock: DKEYLock self, coordinator: DataUpdateCoordinator[None], lock: DKEYLock
) -> None: ) -> None:
"""Initialize a Dormakaba dKey lock.""" """Initialize a Dormakaba dKey lock."""
super().__init__(coordinator)
self._lock = lock
self._attr_unique_id = lock.address self._attr_unique_id = lock.address
self._attr_device_info = DeviceInfo( super().__init__(coordinator, lock)
name=lock.device_info.device_name or lock.device_info.device_id,
model="MTL 9291",
sw_version=lock.device_info.sw_version,
connections={(dr.CONNECTION_BLUETOOTH, lock.address)},
)
self._async_update_attrs()
@callback @callback
def _async_update_attrs(self) -> None: def _async_update_attrs(self) -> None:
@ -66,19 +54,3 @@ class DormakabaDkeyLock(CoordinatorEntity[DataUpdateCoordinator[None]], LockEnti
async def async_unlock(self, **kwargs: Any) -> None: async def async_unlock(self, **kwargs: Any) -> None:
"""Unlock the lock.""" """Unlock the lock."""
await self._lock.unlock() await self._lock.unlock()
@callback
def _handle_coordinator_update(self) -> None:
"""Handle data update."""
self._async_update_attrs()
self.async_write_ha_state()
@callback
def _handle_state_update(self, update: Notifications) -> None:
"""Handle data update."""
self.coordinator.async_set_updated_data(None)
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
self.async_on_remove(self._lock.register_callback(self._handle_state_update))
return await super().async_added_to_hass()

View File

@ -0,0 +1,65 @@
"""Dormakaba dKey integration sensor platform."""
from __future__ import annotations
from py_dormakaba_dkey import DKEYLock
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PERCENTAGE
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import DOMAIN
from .entity import DormakabaDkeyEntity
from .models import DormakabaDkeyData
BINARY_SENSOR_DESCRIPTIONS = (
SensorEntityDescription(
key="battery_level",
name="Battery",
device_class=SensorDeviceClass.BATTERY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the lock platform for Dormakaba dKey."""
data: DormakabaDkeyData = hass.data[DOMAIN][entry.entry_id]
async_add_entities(
DormakabaDkeySensor(data.coordinator, data.lock, description)
for description in BINARY_SENSOR_DESCRIPTIONS
)
class DormakabaDkeySensor(DormakabaDkeyEntity, SensorEntity):
"""Dormakaba dKey sensor."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: DataUpdateCoordinator[None],
lock: DKEYLock,
description: SensorEntityDescription,
) -> None:
"""Initialize a Dormakaba dKey binary sensor."""
self.entity_description = description
self._attr_unique_id = f"{lock.address}_{description.key}"
super().__init__(coordinator, lock)
@callback
def _async_update_attrs(self) -> None:
"""Handle updating _attr values."""
self._attr_native_value = getattr(self._lock, self.entity_description.key)