From 4c087ef9077463ee9e47d9963c4c74d55ff6ce8d Mon Sep 17 00:00:00 2001 From: Andrew Jackson Date: Mon, 3 Jun 2024 16:42:18 +0100 Subject: [PATCH] Stop recording attributes --- .../battery_notes/binary_sensor.py | 82 +++++++++++++---- custom_components/battery_notes/sensor.py | 89 +++++++++++++------ 2 files changed, 127 insertions(+), 44 deletions(-) diff --git a/custom_components/battery_notes/binary_sensor.py b/custom_components/battery_notes/binary_sensor.py index 79bead111..45697a482 100644 --- a/custom_components/battery_notes/binary_sensor.py +++ b/custom_components/battery_notes/binary_sensor.py @@ -1,4 +1,5 @@ """Binary Sensor platform for battery_notes.""" + from __future__ import annotations from collections.abc import Callable @@ -88,6 +89,7 @@ class BatteryNotesBinarySensorEntityDescription( unique_id_suffix: str + PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Optional(CONF_NAME): cv.string, @@ -96,6 +98,7 @@ class BatteryNotesBinarySensorEntityDescription( } ) + @callback def async_add_to_device(hass: HomeAssistant, entry: ConfigEntry) -> str | None: """Add our config entry to the device.""" @@ -105,10 +108,13 @@ def async_add_to_device(hass: HomeAssistant, entry: ConfigEntry) -> str | None: if device_id: if device_registry.async_get(device_id): - device_registry.async_update_device(device_id, add_config_entry_id=entry.entry_id) + device_registry.async_update_device( + device_id, add_config_entry_id=entry.entry_id + ) return device_id return None + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, @@ -148,7 +154,9 @@ async def async_registry_updated(event: Event) -> None: device_id, remove_config_entry_id=config_entry.entry_id ) - coordinator: BatteryNotesCoordinator = hass.data[DOMAIN][DATA].devices[config_entry.entry_id].coordinator + coordinator: BatteryNotesCoordinator = ( + hass.data[DOMAIN][DATA].devices[config_entry.entry_id].coordinator + ) config_entry.async_on_unload( async_track_entity_registry_updated_event( @@ -208,6 +216,7 @@ async def async_setup_platform( await async_setup_reload_service(hass, DOMAIN, PLATFORMS) + class _TemplateAttribute: """Attribute value linked to template result.""" @@ -302,7 +311,10 @@ def handle_result( self.on_update(validated) return -class BatteryNotesBatteryLowTemplateSensor(BinarySensorEntity, CoordinatorEntity[BatteryNotesCoordinator]): + +class BatteryNotesBatteryLowTemplateSensor( + BinarySensorEntity, CoordinatorEntity[BatteryNotesCoordinator] +): """Represents a low battery threshold binary sensor.""" _attr_should_poll = False @@ -337,15 +349,25 @@ def __init__( self._attr_has_entity_name = True if coordinator.source_entity_id and not coordinator.device_id: - self._attr_translation_placeholders = {"device_name": coordinator.device_name + " "} - self.entity_id = f"binary_sensor.{coordinator.device_name.lower()}_{description.key}" + self._attr_translation_placeholders = { + "device_name": coordinator.device_name + " " + } + self.entity_id = ( + f"binary_sensor.{coordinator.device_name.lower()}_{description.key}" + ) elif coordinator.source_entity_id and coordinator.device_id: - source_entity_domain, source_object_id = split_entity_id(coordinator.source_entity_id) - self._attr_translation_placeholders = {"device_name": coordinator.source_entity_name + " "} + source_entity_domain, source_object_id = split_entity_id( + coordinator.source_entity_id + ) + self._attr_translation_placeholders = { + "device_name": coordinator.source_entity_name + " " + } self.entity_id = f"binary_sensor.{source_object_id}_{description.key}" else: self._attr_translation_placeholders = {"device_name": ""} - self.entity_id = f"binary_sensor.{coordinator.device_name.lower()}_{description.key}" + self.entity_id = ( + f"binary_sensor.{coordinator.device_name.lower()}_{description.key}" + ) self._template = template self._state: bool | None = None @@ -397,7 +419,9 @@ def add_template_attribute( @callback def _async_setup_templates(self) -> None: """Set up templates.""" - self.add_template_attribute("_state", Template(self._template), None, self._update_state) + self.add_template_attribute( + "_state", Template(self._template), None, self._update_state + ) @callback def _async_template_startup( @@ -474,7 +498,6 @@ def _handle_results( self.async_write_ha_state() return - @callback def _update_state(self, result): @@ -489,18 +512,25 @@ def _update_state(self, result): self._state = state self.coordinator.battery_low_template_state = state - _LOGGER.debug("%s binary sensor battery_low set to: %s via template", self.entity_id, state) - + _LOGGER.debug( + "%s binary sensor battery_low set to: %s via template", + self.entity_id, + state, + ) @property def is_on(self) -> bool | None: """Return true if sensor is on.""" return self._state -class BatteryNotesBatteryLowSensor(BinarySensorEntity, CoordinatorEntity[BatteryNotesCoordinator]): + +class BatteryNotesBatteryLowSensor( + BinarySensorEntity, CoordinatorEntity[BatteryNotesCoordinator] +): """Represents a low battery threshold binary sensor.""" _attr_should_poll = False + _unrecorded_attributes = frozenset({ATTR_BATTERY_LOW_THRESHOLD}) def __init__( self, @@ -517,15 +547,25 @@ def __init__( self._attr_has_entity_name = True if coordinator.source_entity_id and not coordinator.device_id: - self._attr_translation_placeholders = {"device_name": coordinator.device_name + " "} - self.entity_id = f"binary_sensor.{coordinator.device_name.lower()}_{description.key}" + self._attr_translation_placeholders = { + "device_name": coordinator.device_name + " " + } + self.entity_id = ( + f"binary_sensor.{coordinator.device_name.lower()}_{description.key}" + ) elif coordinator.source_entity_id and coordinator.device_id: - source_entity_domain, source_object_id = split_entity_id(coordinator.source_entity_id) - self._attr_translation_placeholders = {"device_name": coordinator.source_entity_name + " "} + source_entity_domain, source_object_id = split_entity_id( + coordinator.source_entity_id + ) + self._attr_translation_placeholders = { + "device_name": coordinator.source_entity_name + " " + } self.entity_id = f"binary_sensor.{source_object_id}_{description.key}" else: self._attr_translation_placeholders = {"device_name": ""} - self.entity_id = f"binary_sensor.{coordinator.device_name.lower()}_{description.key}" + self.entity_id = ( + f"binary_sensor.{coordinator.device_name.lower()}_{description.key}" + ) self.entity_description = description self._attr_unique_id = unique_id @@ -574,7 +614,11 @@ def _handle_coordinator_update(self) -> None: self.async_write_ha_state() - _LOGGER.debug("%s binary sensor battery_low set to: %s", self.coordinator.wrapped_battery.entity_id, self.coordinator.battery_low) + _LOGGER.debug( + "%s binary sensor battery_low set to: %s", + self.coordinator.wrapped_battery.entity_id, + self.coordinator.battery_low, + ) @property def extra_state_attributes(self) -> dict[str, str] | None: diff --git a/custom_components/battery_notes/sensor.py b/custom_components/battery_notes/sensor.py index 289bed1e6..914e7709f 100644 --- a/custom_components/battery_notes/sensor.py +++ b/custom_components/battery_notes/sensor.py @@ -265,6 +265,21 @@ class BatteryNotesBatteryPlusSensor( _attr_should_poll = False _wrapped_attributes = None + _unrecorded_attributes = frozenset( + { + ATTR_BATTERY_QUANTITY, + ATTR_BATTERY_TYPE, + ATTR_BATTERY_TYPE_AND_QUANTITY, + ATTR_BATTERY_LOW, + ATTR_BATTERY_LOW_THRESHOLD, + ATTR_BATTERY_LAST_REPORTED, + ATTR_BATTERY_LAST_REPORTED_LEVEL, + ATTR_BATTERY_LAST_REPLACED, + ATTR_DEVICE_ID, + ATTR_SOURCE_ENTITY_ID, + ATTR_DEVICE_NAME, + } + ) def __init__( self, @@ -288,20 +303,30 @@ def __init__( self._attr_has_entity_name = True if coordinator.source_entity_id and not coordinator.device_id: - self._attr_translation_placeholders = {"device_name": coordinator.device_name + " "} - self.entity_id = f"sensor.{coordinator.device_name.lower()}_{description.key}" + self._attr_translation_placeholders = { + "device_name": coordinator.device_name + " " + } + self.entity_id = ( + f"sensor.{coordinator.device_name.lower()}_{description.key}" + ) elif coordinator.source_entity_id and coordinator.device_id: - source_entity_domain, source_object_id = split_entity_id(coordinator.source_entity_id) - self._attr_translation_placeholders = {"device_name": coordinator.source_entity_name + " "} + source_entity_domain, source_object_id = split_entity_id( + coordinator.source_entity_id + ) + self._attr_translation_placeholders = { + "device_name": coordinator.source_entity_name + " " + } self.entity_id = f"sensor.{source_object_id}_{description.key}" else: self._attr_translation_placeholders = {"device_name": ""} - self.entity_id = f"sensor.{coordinator.device_name.lower()}_{description.key}" + self.entity_id = ( + f"sensor.{coordinator.device_name.lower()}_{description.key}" + ) _LOGGER.debug( "Setting up %s with wrapped battery %s", self.entity_id, - self.coordinator.wrapped_battery.entity_id + self.coordinator.wrapped_battery.entity_id, ) self.entity_description = description @@ -548,6 +573,7 @@ class BatteryNotesTypeSensor(RestoreSensor, SensorEntity): _attr_should_poll = False entity_description: BatteryNotesSensorEntityDescription + _unrecorded_attributes = frozenset({ATTR_BATTERY_QUANTITY, ATTR_BATTERY_TYPE}) def __init__( self, @@ -568,15 +594,25 @@ def __init__( self._attr_has_entity_name = True if coordinator.source_entity_id and not coordinator.device_id: - self._attr_translation_placeholders = {"device_name": coordinator.device_name + " "} - self.entity_id = f"sensor.{coordinator.device_name.lower()}_{description.key}" + self._attr_translation_placeholders = { + "device_name": coordinator.device_name + " " + } + self.entity_id = ( + f"sensor.{coordinator.device_name.lower()}_{description.key}" + ) elif coordinator.source_entity_id and coordinator.device_id: - source_entity_domain, source_object_id = split_entity_id(coordinator.source_entity_id) - self._attr_translation_placeholders = {"device_name": coordinator.source_entity_name + " "} + source_entity_domain, source_object_id = split_entity_id( + coordinator.source_entity_id + ) + self._attr_translation_placeholders = { + "device_name": coordinator.source_entity_name + " " + } self.entity_id = f"sensor.{source_object_id}_{description.key}" else: self._attr_translation_placeholders = {"device_name": ""} - self.entity_id = f"sensor.{coordinator.device_name.lower()}_{description.key}" + self.entity_id = ( + f"sensor.{coordinator.device_name.lower()}_{description.key}" + ) self.entity_description = description self._attr_unique_id = unique_id @@ -657,15 +693,25 @@ def __init__( self._attr_has_entity_name = True if coordinator.source_entity_id and not coordinator.device_id: - self._attr_translation_placeholders = {"device_name": coordinator.device_name + " "} - self.entity_id = f"sensor.{coordinator.device_name.lower()}_{description.key}" + self._attr_translation_placeholders = { + "device_name": coordinator.device_name + " " + } + self.entity_id = ( + f"sensor.{coordinator.device_name.lower()}_{description.key}" + ) elif coordinator.source_entity_id and coordinator.device_id: - source_entity_domain, source_object_id = split_entity_id(coordinator.source_entity_id) - self._attr_translation_placeholders = {"device_name": coordinator.source_entity_name + " "} + source_entity_domain, source_object_id = split_entity_id( + coordinator.source_entity_id + ) + self._attr_translation_placeholders = { + "device_name": coordinator.source_entity_name + " " + } self.entity_id = f"sensor.{source_object_id}_{description.key}" else: self._attr_translation_placeholders = {"device_name": ""} - self.entity_id = f"sensor.{coordinator.device_name.lower()}_{description.key}" + self.entity_id = ( + f"sensor.{coordinator.device_name.lower()}_{description.key}" + ) self._attr_device_class = description.device_class self._attr_unique_id = unique_id @@ -674,7 +720,6 @@ def __init__( self.entity_description = description self._native_value = None - self._set_native_value(log_on_error=False) device_registry = dr.async_get(hass) @@ -699,10 +744,7 @@ def _set_native_value(self, log_on_error=True): entry = self.coordinator.store.async_get_device(self._device_id) if entry: - if ( - LAST_REPLACED in entry - and entry[LAST_REPLACED] is not None - ): + if LAST_REPLACED in entry and entry[LAST_REPLACED] is not None: last_replaced_date = datetime.fromisoformat( str(entry[LAST_REPLACED]) + "+00:00" ) @@ -721,10 +763,7 @@ def _handle_coordinator_update(self) -> None: entry = self.coordinator.store.async_get_device(self._device_id) if entry: - if ( - LAST_REPLACED in entry - and entry[LAST_REPLACED] is not None - ): + if LAST_REPLACED in entry and entry[LAST_REPLACED] is not None: last_replaced_date = datetime.fromisoformat( str(entry[LAST_REPLACED]) + "+00:00" )