Dispatch when esphome static info changes (#94876)

pull/94911/head
J. Nick Koston 2023-06-20 02:45:30 -05:00 committed by GitHub
parent 185aaa9e07
commit 2b1660c0f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 20 deletions

View File

@ -45,7 +45,10 @@ from homeassistant.helpers import template
import homeassistant.helpers.config_validation as cv
import homeassistant.helpers.device_registry as dr
from homeassistant.helpers.device_registry import format_mac
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.dispatcher import (
async_dispatcher_connect,
async_dispatcher_send,
)
from homeassistant.helpers.entity import DeviceInfo, Entity
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_state_change_event
@ -709,7 +712,7 @@ async def platform_async_setup_entry(
old_infos.pop(info.key)
else:
# Create new entity
entity = entity_type(entry_data, component_key, info.key, state_type)
entity = entity_type(entry_data, component_key, info, state_type)
add_entities.append(entity)
new_infos[info.key] = info
@ -722,8 +725,15 @@ async def platform_async_setup_entry(
# Then update the actual info
entry_data.info[component_key] = new_infos
# Add entities to Home Assistant
async_add_entities(add_entities)
async_dispatcher_send(
hass,
entry_data.signal_component_static_info_updated(component_key),
new_infos,
)
if add_entities:
# Add entities to Home Assistant
async_add_entities(add_entities)
entry_data.cleanup_callbacks.append(
async_dispatcher_connect(
@ -774,18 +784,20 @@ class EsphomeEntity(Entity, Generic[_InfoT, _StateT]):
"""Define a base esphome entity."""
_attr_should_poll = False
_static_info: _InfoT
def __init__(
self,
entry_data: RuntimeEntryData,
component_key: str,
key: int,
entity_info: EntityInfo,
state_type: type[_StateT],
) -> None:
"""Initialize."""
self._entry_data = entry_data
self._component_key = component_key
self._key = key
self._key = entity_info.key
self._static_info = cast(_InfoT, entity_info)
self._state_type = state_type
if entry_data.device_info is not None and entry_data.device_info.friendly_name:
self._attr_has_entity_name = True
@ -814,6 +826,25 @@ class EsphomeEntity(Entity, Generic[_InfoT, _StateT]):
)
)
self.async_on_remove(
async_dispatcher_connect(
self.hass,
self._entry_data.signal_component_static_info_updated(
self._component_key
),
self._on_static_info_update,
)
)
@callback
def _on_static_info_update(self, static_infos: dict[int, EntityInfo]) -> None:
"""Save the static info for this entity when it changes.
This method can be overridden in child classes to know
when the static info changes.
"""
self._static_info = cast(_InfoT, static_infos[self._key])
@callback
def _on_state_update(self) -> None:
# Behavior can be changed in child classes
@ -837,16 +868,6 @@ class EsphomeEntity(Entity, Generic[_InfoT, _StateT]):
def _api_version(self) -> APIVersion:
return self._entry_data.api_version
@property
def _static_info(self) -> _InfoT:
# Check if value is in info database. Use a single lookup.
info = self._entry_data.info[self._component_key].get(self._key)
if info is not None:
return cast(_InfoT, info)
# This entity is in the removal project and has been removed from .info
# already, look in old_info
return cast(_InfoT, self._entry_data.old_info[self._component_key][self._key])
@property
def _device_info(self) -> EsphomeDeviceInfo:
assert self._entry_data.device_info is not None

View File

@ -129,6 +129,10 @@ class RuntimeEntryData:
"""Return the signal to listen to for updates on static info."""
return f"esphome_{self.entry_id}_on_list"
def signal_component_static_info_updated(self, component_key: str) -> str:
"""Return the signal to listen to for updates on static info for a specific component_key."""
return f"esphome_{self.entry_id}_static_info_updated_{component_key}"
@callback
def async_update_ble_connection_limits(self, free: int, limit: int) -> None:
"""Update the BLE connection limits."""

View File

@ -52,22 +52,22 @@ class EsphomeNumber(EsphomeEntity[NumberInfo, NumberState], NumberEntity):
@property
def native_min_value(self) -> float:
"""Return the minimum value."""
return super()._static_info.min_value
return self._static_info.min_value
@property
def native_max_value(self) -> float:
"""Return the maximum value."""
return super()._static_info.max_value
return self._static_info.max_value
@property
def native_step(self) -> float:
"""Return the increment/decrement step."""
return super()._static_info.step
return self._static_info.step
@property
def native_unit_of_measurement(self) -> str | None:
"""Return the unit of measurement."""
return super()._static_info.unit_of_measurement
return self._static_info.unit_of_measurement
@property
def mode(self) -> NumberMode: