Update statistics meta data on entity_id change (#52755)
This commit is contained in:
parent
8c36f5c627
commit
e541bcd54d
3 changed files with 86 additions and 2 deletions
|
@ -12,7 +12,8 @@ from sqlalchemy.ext import baked
|
||||||
from sqlalchemy.orm.scoping import scoped_session
|
from sqlalchemy.orm.scoping import scoped_session
|
||||||
|
|
||||||
from homeassistant.const import PRESSURE_PA, TEMP_CELSIUS
|
from homeassistant.const import PRESSURE_PA, TEMP_CELSIUS
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import Event, HomeAssistant, callback
|
||||||
|
from homeassistant.helpers import entity_registry
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
import homeassistant.util.pressure as pressure_util
|
import homeassistant.util.pressure as pressure_util
|
||||||
import homeassistant.util.temperature as temperature_util
|
import homeassistant.util.temperature as temperature_util
|
||||||
|
@ -73,6 +74,31 @@ def async_setup(hass: HomeAssistant) -> None:
|
||||||
hass.data[STATISTICS_BAKERY] = baked.bakery()
|
hass.data[STATISTICS_BAKERY] = baked.bakery()
|
||||||
hass.data[STATISTICS_META_BAKERY] = baked.bakery()
|
hass.data[STATISTICS_META_BAKERY] = baked.bakery()
|
||||||
|
|
||||||
|
def entity_id_changed(event: Event) -> None:
|
||||||
|
"""Handle entity_id changed."""
|
||||||
|
old_entity_id = event.data["old_entity_id"]
|
||||||
|
entity_id = event.data["entity_id"]
|
||||||
|
with session_scope(hass=hass) as session:
|
||||||
|
session.query(StatisticsMeta).filter(
|
||||||
|
StatisticsMeta.statistic_id == old_entity_id
|
||||||
|
and StatisticsMeta.source == DOMAIN
|
||||||
|
).update({StatisticsMeta.statistic_id: entity_id})
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def entity_registry_changed_filter(event: Event) -> bool:
|
||||||
|
"""Handle entity_id changed filter."""
|
||||||
|
if event.data["action"] != "update" or "old_entity_id" not in event.data:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
if hass.is_running:
|
||||||
|
hass.bus.async_listen(
|
||||||
|
entity_registry.EVENT_ENTITY_REGISTRY_UPDATED,
|
||||||
|
entity_id_changed,
|
||||||
|
event_filter=entity_registry_changed_filter,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_start_time() -> datetime:
|
def get_start_time() -> datetime:
|
||||||
"""Return start time."""
|
"""Return start time."""
|
||||||
|
|
|
@ -16,6 +16,7 @@ from homeassistant.const import TEMP_CELSIUS
|
||||||
from homeassistant.setup import setup_component
|
from homeassistant.setup import setup_component
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
from tests.common import mock_registry
|
||||||
from tests.components.recorder.common import wait_recording_done
|
from tests.components.recorder.common import wait_recording_done
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,6 +94,63 @@ def test_compile_hourly_statistics(hass_recorder):
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_rename_entity(hass_recorder):
|
||||||
|
"""Test statistics is migrated when entity_id is changed."""
|
||||||
|
hass = hass_recorder()
|
||||||
|
recorder = hass.data[DATA_INSTANCE]
|
||||||
|
setup_component(hass, "sensor", {})
|
||||||
|
|
||||||
|
entity_reg = mock_registry(hass)
|
||||||
|
reg_entry = entity_reg.async_get_or_create(
|
||||||
|
"sensor",
|
||||||
|
"test",
|
||||||
|
"unique_0000",
|
||||||
|
suggested_object_id="test1",
|
||||||
|
)
|
||||||
|
assert reg_entry.entity_id == "sensor.test1"
|
||||||
|
|
||||||
|
zero, four, states = record_states(hass)
|
||||||
|
hist = history.get_significant_states(hass, zero, four)
|
||||||
|
assert dict(states) == dict(hist)
|
||||||
|
|
||||||
|
for kwargs in ({}, {"statistic_ids": ["sensor.test1"]}):
|
||||||
|
stats = statistics_during_period(hass, zero, **kwargs)
|
||||||
|
assert stats == {}
|
||||||
|
stats = get_last_statistics(hass, 0, "sensor.test1")
|
||||||
|
assert stats == {}
|
||||||
|
|
||||||
|
recorder.do_adhoc_statistics(period="hourly", start=zero)
|
||||||
|
wait_recording_done(hass)
|
||||||
|
expected_1 = {
|
||||||
|
"statistic_id": "sensor.test1",
|
||||||
|
"start": process_timestamp_to_utc_isoformat(zero),
|
||||||
|
"mean": approx(14.915254237288135),
|
||||||
|
"min": approx(10.0),
|
||||||
|
"max": approx(20.0),
|
||||||
|
"last_reset": None,
|
||||||
|
"state": None,
|
||||||
|
"sum": None,
|
||||||
|
}
|
||||||
|
expected_stats1 = [
|
||||||
|
{**expected_1, "statistic_id": "sensor.test1"},
|
||||||
|
]
|
||||||
|
expected_stats2 = [
|
||||||
|
{**expected_1, "statistic_id": "sensor.test2"},
|
||||||
|
]
|
||||||
|
expected_stats99 = [
|
||||||
|
{**expected_1, "statistic_id": "sensor.test99"},
|
||||||
|
]
|
||||||
|
|
||||||
|
stats = statistics_during_period(hass, zero)
|
||||||
|
assert stats == {"sensor.test1": expected_stats1, "sensor.test2": expected_stats2}
|
||||||
|
|
||||||
|
entity_reg.async_update_entity(reg_entry.entity_id, new_entity_id="sensor.test99")
|
||||||
|
hass.block_till_done()
|
||||||
|
|
||||||
|
stats = statistics_during_period(hass, zero)
|
||||||
|
assert stats == {"sensor.test99": expected_stats99, "sensor.test2": expected_stats2}
|
||||||
|
|
||||||
|
|
||||||
def record_states(hass):
|
def record_states(hass):
|
||||||
"""Record some test states.
|
"""Record some test states.
|
||||||
|
|
||||||
|
|
|
@ -610,7 +610,7 @@ def enable_statistics():
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def hass_recorder(enable_statistics):
|
def hass_recorder(enable_statistics, hass_storage):
|
||||||
"""Home Assistant fixture with in-memory recorder."""
|
"""Home Assistant fixture with in-memory recorder."""
|
||||||
hass = get_test_home_assistant()
|
hass = get_test_home_assistant()
|
||||||
stats = recorder.Recorder.async_hourly_statistics if enable_statistics else None
|
stats = recorder.Recorder.async_hourly_statistics if enable_statistics else None
|
||||||
|
|
Loading…
Add table
Reference in a new issue