mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 09:47:13 +00:00
Separate august keypads into their own device (#33665)
The keypad has its own unique id so its better represented as its own device. This fixes showing the keypad battery state for the lock in the UI.
This commit is contained in:
parent
b09b5729a3
commit
7dd42bc32d
@ -262,6 +262,13 @@ class AugustData(AugustSubscriberMixin):
|
||||
await self._async_update_device_detail(
|
||||
self._locks_by_id[device_id], self._api.async_get_lock_detail
|
||||
)
|
||||
# keypads are always attached to locks
|
||||
if (
|
||||
device_id in self._device_detail_by_id
|
||||
and self._device_detail_by_id[device_id].keypad is not None
|
||||
):
|
||||
keypad = self._device_detail_by_id[device_id].keypad
|
||||
self._device_detail_by_id[keypad.device_id] = keypad
|
||||
elif device_id in self._doorbells_by_id:
|
||||
await self._async_update_device_detail(
|
||||
self._doorbells_by_id[device_id],
|
||||
|
@ -7,6 +7,7 @@ from homeassistant.components.sensor import DEVICE_CLASS_BATTERY
|
||||
from homeassistant.const import ATTR_ENTITY_PICTURE, UNIT_PERCENTAGE
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.entity_registry import async_get_registry
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
|
||||
from .const import (
|
||||
@ -33,21 +34,12 @@ def _retrieve_device_battery_state(detail):
|
||||
|
||||
def _retrieve_linked_keypad_battery_state(detail):
|
||||
"""Get the latest state of the sensor."""
|
||||
if detail.keypad is None:
|
||||
return None
|
||||
|
||||
return detail.keypad.battery_percentage
|
||||
return detail.battery_percentage
|
||||
|
||||
|
||||
SENSOR_TYPES_BATTERY = {
|
||||
"device_battery": {
|
||||
"name": "Battery",
|
||||
"state_provider": _retrieve_device_battery_state,
|
||||
},
|
||||
"linked_keypad_battery": {
|
||||
"name": "Keypad Battery",
|
||||
"state_provider": _retrieve_linked_keypad_battery_state,
|
||||
},
|
||||
"device_battery": {"state_provider": _retrieve_device_battery_state},
|
||||
"linked_keypad_battery": {"state_provider": _retrieve_linked_keypad_battery_state},
|
||||
}
|
||||
|
||||
|
||||
@ -55,7 +47,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up the August sensors."""
|
||||
data = hass.data[DOMAIN][config_entry.entry_id][DATA_AUGUST]
|
||||
devices = []
|
||||
|
||||
migrate_unique_id_devices = []
|
||||
operation_sensors = []
|
||||
batteries = {
|
||||
"device_battery": [],
|
||||
@ -68,30 +60,62 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
batteries["linked_keypad_battery"].append(device)
|
||||
operation_sensors.append(device)
|
||||
|
||||
for sensor_type in SENSOR_TYPES_BATTERY:
|
||||
for device in batteries[sensor_type]:
|
||||
state_provider = SENSOR_TYPES_BATTERY[sensor_type]["state_provider"]
|
||||
detail = data.get_device_detail(device.device_id)
|
||||
state = state_provider(detail)
|
||||
sensor_name = SENSOR_TYPES_BATTERY[sensor_type]["name"]
|
||||
if state is None:
|
||||
_LOGGER.debug(
|
||||
"Not adding battery sensor %s for %s because it is not present",
|
||||
sensor_name,
|
||||
device.device_name,
|
||||
)
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
"Adding battery sensor %s for %s", sensor_name, device.device_name,
|
||||
)
|
||||
devices.append(AugustBatterySensor(data, sensor_type, device))
|
||||
for device in batteries["device_battery"]:
|
||||
state_provider = SENSOR_TYPES_BATTERY["device_battery"]["state_provider"]
|
||||
detail = data.get_device_detail(device.device_id)
|
||||
if detail is None or state_provider(detail) is None:
|
||||
_LOGGER.debug(
|
||||
"Not adding battery sensor for %s because it is not present",
|
||||
device.device_name,
|
||||
)
|
||||
continue
|
||||
_LOGGER.debug(
|
||||
"Adding battery sensor for %s", device.device_name,
|
||||
)
|
||||
devices.append(AugustBatterySensor(data, "device_battery", device, device))
|
||||
|
||||
for device in batteries["linked_keypad_battery"]:
|
||||
detail = data.get_device_detail(device.device_id)
|
||||
|
||||
if detail.keypad is None:
|
||||
_LOGGER.debug(
|
||||
"Not adding keypad battery sensor for %s because it is not present",
|
||||
device.device_name,
|
||||
)
|
||||
continue
|
||||
_LOGGER.debug(
|
||||
"Adding keypad battery sensor for %s", device.device_name,
|
||||
)
|
||||
keypad_battery_sensor = AugustBatterySensor(
|
||||
data, "linked_keypad_battery", detail.keypad, device
|
||||
)
|
||||
devices.append(keypad_battery_sensor)
|
||||
migrate_unique_id_devices.append(keypad_battery_sensor)
|
||||
|
||||
for device in operation_sensors:
|
||||
devices.append(AugustOperatorSensor(data, device))
|
||||
|
||||
await _async_migrate_old_unique_ids(hass, migrate_unique_id_devices)
|
||||
|
||||
async_add_entities(devices, True)
|
||||
|
||||
|
||||
async def _async_migrate_old_unique_ids(hass, devices):
|
||||
"""Keypads now have their own serial number."""
|
||||
registry = await async_get_registry(hass)
|
||||
for device in devices:
|
||||
old_entity_id = registry.async_get_entity_id(
|
||||
"sensor", DOMAIN, device.old_unique_id
|
||||
)
|
||||
if old_entity_id is not None:
|
||||
_LOGGER.debug(
|
||||
"Migrating unique_id from [%s] to [%s]",
|
||||
device.old_unique_id,
|
||||
device.unique_id,
|
||||
)
|
||||
registry.async_update_entity(old_entity_id, new_unique_id=device.unique_id)
|
||||
|
||||
|
||||
class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, Entity):
|
||||
"""Representation of an August lock operation sensor."""
|
||||
|
||||
@ -194,12 +218,13 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, Entity):
|
||||
class AugustBatterySensor(AugustEntityMixin, Entity):
|
||||
"""Representation of an August sensor."""
|
||||
|
||||
def __init__(self, data, sensor_type, device):
|
||||
def __init__(self, data, sensor_type, device, old_device):
|
||||
"""Initialize the sensor."""
|
||||
super().__init__(data, device)
|
||||
self._data = data
|
||||
self._sensor_type = sensor_type
|
||||
self._device = device
|
||||
self._old_device = old_device
|
||||
self._state = None
|
||||
self._available = False
|
||||
self._update_from_data()
|
||||
@ -228,8 +253,7 @@ class AugustBatterySensor(AugustEntityMixin, Entity):
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
device_name = self._device.device_name
|
||||
sensor_name = SENSOR_TYPES_BATTERY[self._sensor_type]["name"]
|
||||
return f"{device_name} {sensor_name}"
|
||||
return f"{device_name} Battery"
|
||||
|
||||
@callback
|
||||
def _update_from_data(self):
|
||||
@ -242,3 +266,8 @@ class AugustBatterySensor(AugustEntityMixin, Entity):
|
||||
def unique_id(self) -> str:
|
||||
"""Get the unique id of the device sensor."""
|
||||
return f"{self._device_id}_{self._sensor_type}"
|
||||
|
||||
@property
|
||||
def old_unique_id(self) -> str:
|
||||
"""Get the old unique id of the device sensor."""
|
||||
return f"{self._old_device.device_id}_{self._sensor_type}"
|
||||
|
@ -71,21 +71,12 @@ async def test_create_lock_with_linked_keypad(hass):
|
||||
assert entry
|
||||
assert entry.unique_id == "A6697750D607098BAE8D6BAA11EF8063_device_battery"
|
||||
|
||||
sensor_a6697750d607098bae8d6baa11ef8063_name_keypad_battery = hass.states.get(
|
||||
"sensor.a6697750d607098bae8d6baa11ef8063_name_keypad_battery"
|
||||
)
|
||||
assert sensor_a6697750d607098bae8d6baa11ef8063_name_keypad_battery.state == "60"
|
||||
assert (
|
||||
sensor_a6697750d607098bae8d6baa11ef8063_name_keypad_battery.attributes[
|
||||
"unit_of_measurement"
|
||||
]
|
||||
== "%"
|
||||
)
|
||||
entry = entity_registry.async_get(
|
||||
"sensor.a6697750d607098bae8d6baa11ef8063_name_keypad_battery"
|
||||
)
|
||||
state = hass.states.get("sensor.front_door_lock_keypad_battery")
|
||||
assert state.state == "60"
|
||||
assert state.attributes["unit_of_measurement"] == "%"
|
||||
entry = entity_registry.async_get("sensor.front_door_lock_keypad_battery")
|
||||
assert entry
|
||||
assert entry.unique_id == "A6697750D607098BAE8D6BAA11EF8063_linked_keypad_battery"
|
||||
assert entry.unique_id == "5bc65c24e6ef2a263e1450a8_linked_keypad_battery"
|
||||
|
||||
|
||||
async def test_create_lock_with_low_battery_linked_keypad(hass):
|
||||
@ -110,21 +101,12 @@ async def test_create_lock_with_low_battery_linked_keypad(hass):
|
||||
assert entry
|
||||
assert entry.unique_id == "A6697750D607098BAE8D6BAA11EF8063_device_battery"
|
||||
|
||||
sensor_a6697750d607098bae8d6baa11ef8063_name_keypad_battery = hass.states.get(
|
||||
"sensor.a6697750d607098bae8d6baa11ef8063_name_keypad_battery"
|
||||
)
|
||||
assert sensor_a6697750d607098bae8d6baa11ef8063_name_keypad_battery.state == "10"
|
||||
assert (
|
||||
sensor_a6697750d607098bae8d6baa11ef8063_name_keypad_battery.attributes[
|
||||
"unit_of_measurement"
|
||||
]
|
||||
== "%"
|
||||
)
|
||||
entry = entity_registry.async_get(
|
||||
"sensor.a6697750d607098bae8d6baa11ef8063_name_keypad_battery"
|
||||
)
|
||||
state = hass.states.get("sensor.front_door_lock_keypad_battery")
|
||||
assert state.state == "10"
|
||||
assert state.attributes["unit_of_measurement"] == "%"
|
||||
entry = entity_registry.async_get("sensor.front_door_lock_keypad_battery")
|
||||
assert entry
|
||||
assert entry.unique_id == "A6697750D607098BAE8D6BAA11EF8063_linked_keypad_battery"
|
||||
assert entry.unique_id == "5bc65c24e6ef2a263e1450a8_linked_keypad_battery"
|
||||
|
||||
# No activity means it will be unavailable until someone unlocks/locks it
|
||||
lock_operator_sensor = entity_registry.async_get(
|
||||
|
Loading…
x
Reference in New Issue
Block a user