Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop recording attributes #1729

Merged
merged 1 commit into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 63 additions & 19 deletions custom_components/battery_notes/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Binary Sensor platform for battery_notes."""

from __future__ import annotations

from collections.abc import Callable
Expand Down Expand Up @@ -88,6 +89,7 @@ class BatteryNotesBinarySensorEntityDescription(

unique_id_suffix: str


PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_NAME): cv.string,
Expand All @@ -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."""
Expand All @@ -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,
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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."""

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -474,7 +498,6 @@ def _handle_results(
self.async_write_ha_state()
return


@callback
def _update_state(self, result):

Expand All @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down
89 changes: 64 additions & 25 deletions custom_components/battery_notes/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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"
)
Expand All @@ -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"
)
Expand Down