From 5c79dae4c014a39ea7d4728f07faa312426734d5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 10 Dec 2022 08:55:22 -1000 Subject: [PATCH] Add support for battery to Yale Access Bluetooth (#83691) * Add support for battery level to Yale Access Bluetooth * fix * bump * bump * bump * bump * fix * bump * battery level is always an estimate from voltage, but than again it always is for every device * bump * review * bump again to fix slow start * other one --- homeassistant/components/august/manifest.json | 2 +- .../components/yalexs_ble/manifest.json | 2 +- homeassistant/components/yalexs_ble/sensor.py | 97 ++++++++++++++++--- requirements_all.txt | 4 +- requirements_test_all.txt | 4 +- 5 files changed, 91 insertions(+), 18 deletions(-) diff --git a/homeassistant/components/august/manifest.json b/homeassistant/components/august/manifest.json index b52ed2962c1..5c529ea3b37 100644 --- a/homeassistant/components/august/manifest.json +++ b/homeassistant/components/august/manifest.json @@ -2,7 +2,7 @@ "domain": "august", "name": "August", "documentation": "https://www.home-assistant.io/integrations/august", - "requirements": ["yalexs==1.2.6", "yalexs_ble==1.10.3"], + "requirements": ["yalexs==1.2.6", "yalexs_ble==1.11.4"], "codeowners": ["@bdraco"], "dhcp": [ { diff --git a/homeassistant/components/yalexs_ble/manifest.json b/homeassistant/components/yalexs_ble/manifest.json index fea67b63fa4..cf8f3f53b97 100644 --- a/homeassistant/components/yalexs_ble/manifest.json +++ b/homeassistant/components/yalexs_ble/manifest.json @@ -3,7 +3,7 @@ "name": "Yale Access Bluetooth", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/yalexs_ble", - "requirements": ["yalexs-ble==1.10.3"], + "requirements": ["yalexs-ble==1.11.4"], "dependencies": ["bluetooth"], "codeowners": ["@bdraco"], "bluetooth": [ diff --git a/homeassistant/components/yalexs_ble/sensor.py b/homeassistant/components/yalexs_ble/sensor.py index 19fee1924e6..e66c67fbd26 100644 --- a/homeassistant/components/yalexs_ble/sensor.py +++ b/homeassistant/components/yalexs_ble/sensor.py @@ -1,11 +1,23 @@ """Support for yalexs ble sensors.""" from __future__ import annotations +from collections.abc import Callable +from dataclasses import dataclass + from yalexs_ble import ConnectionInfo, LockInfo, LockState from homeassistant import config_entries -from homeassistant.components.sensor import SensorDeviceClass, SensorEntity -from homeassistant.const import SIGNAL_STRENGTH_DECIBELS_MILLIWATT +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntity, + SensorEntityDescription, + SensorStateClass, +) +from homeassistant.const import ( + ELECTRIC_POTENTIAL_VOLT, + PERCENTAGE, + SIGNAL_STRENGTH_DECIBELS_MILLIWATT, +) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback @@ -15,6 +27,60 @@ from .entity import YALEXSBLEEntity from .models import YaleXSBLEData +@dataclass +class YaleXSBLERequiredKeysMixin: + """Mixin for required keys.""" + + value_fn: Callable[[LockState, LockInfo, ConnectionInfo], int | float | None] + + +@dataclass +class YaleXSBLESensorEntityDescription( + SensorEntityDescription, YaleXSBLERequiredKeysMixin +): + """Describes Yale Access Bluetooth sensor entity.""" + + +SENSORS: tuple[YaleXSBLESensorEntityDescription, ...] = ( + YaleXSBLESensorEntityDescription( + key="", # No key for the original RSSI sensor unique id + name="Signal strength", + device_class=SensorDeviceClass.SIGNAL_STRENGTH, + entity_category=EntityCategory.DIAGNOSTIC, + state_class=SensorStateClass.MEASUREMENT, + has_entity_name=True, + native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, + entity_registry_enabled_default=False, + value_fn=lambda state, info, connection: connection.rssi, + ), + YaleXSBLESensorEntityDescription( + key="battery_level", + name="Battery level", + device_class=SensorDeviceClass.BATTERY, + entity_category=EntityCategory.DIAGNOSTIC, + state_class=SensorStateClass.MEASUREMENT, + has_entity_name=True, + native_unit_of_measurement=PERCENTAGE, + value_fn=lambda state, info, connection: state.battery.percentage + if state.battery + else None, + ), + YaleXSBLESensorEntityDescription( + key="battery_voltage", + name="Battery Voltage", + device_class=SensorDeviceClass.VOLTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + state_class=SensorStateClass.MEASUREMENT, + has_entity_name=True, + native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + entity_registry_enabled_default=False, + value_fn=lambda state, info, connection: state.battery.voltage + if state.battery + else None, + ), +) + + async def async_setup_entry( hass: HomeAssistant, entry: config_entries.ConfigEntry, @@ -22,23 +88,30 @@ async def async_setup_entry( ) -> None: """Set up YALE XS Bluetooth sensors.""" data: YaleXSBLEData = hass.data[DOMAIN][entry.entry_id] - async_add_entities([YaleXSBLERSSISensor(data)]) + async_add_entities(YaleXSBLESensor(description, data) for description in SENSORS) -class YaleXSBLERSSISensor(YALEXSBLEEntity, SensorEntity): - """Yale XS Bluetooth RSSI sensor.""" +class YaleXSBLESensor(YALEXSBLEEntity, SensorEntity): + """Yale XS Bluetooth sensor.""" - _attr_device_class = SensorDeviceClass.SIGNAL_STRENGTH - _attr_entity_category = EntityCategory.DIAGNOSTIC - _attr_entity_registry_enabled_default = False - _attr_has_entity_name = True - _attr_name = "Signal strength" - _attr_native_unit_of_measurement = SIGNAL_STRENGTH_DECIBELS_MILLIWATT + entity_description: YaleXSBLESensorEntityDescription + + def __init__( + self, + description: YaleXSBLESensorEntityDescription, + data: YaleXSBLEData, + ) -> None: + """Initialize the sensor.""" + self.entity_description = description + super().__init__(data) + self._attr_unique_id = f"{data.lock.address}{description.key}" @callback def _async_update_state( self, new_state: LockState, lock_info: LockInfo, connection_info: ConnectionInfo ) -> None: """Update the state.""" - self._attr_native_value = connection_info.rssi + self._attr_native_value = self.entity_description.value_fn( + new_state, lock_info, connection_info + ) super()._async_update_state(new_state, lock_info, connection_info) diff --git a/requirements_all.txt b/requirements_all.txt index 67f2de654f0..c0557c785ac 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2609,13 +2609,13 @@ xs1-api-client==3.0.0 yalesmartalarmclient==0.3.9 # homeassistant.components.yalexs_ble -yalexs-ble==1.10.3 +yalexs-ble==1.11.4 # homeassistant.components.august yalexs==1.2.6 # homeassistant.components.august -yalexs_ble==1.10.3 +yalexs_ble==1.11.4 # homeassistant.components.yeelight yeelight==0.7.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 5b1e0d34110..3c0c48e9244 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1819,13 +1819,13 @@ xmltodict==0.13.0 yalesmartalarmclient==0.3.9 # homeassistant.components.yalexs_ble -yalexs-ble==1.10.3 +yalexs-ble==1.11.4 # homeassistant.components.august yalexs==1.2.6 # homeassistant.components.august -yalexs_ble==1.10.3 +yalexs_ble==1.11.4 # homeassistant.components.yeelight yeelight==0.7.10