Make recorder.purge_entities require at least one entity filter value (#110066)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
karwosts 2024-04-22 11:10:18 -07:00 committed by GitHub
parent 0ed56694b0
commit 2ac44f6083
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 37 additions and 17 deletions

View file

@ -7,6 +7,7 @@ from typing import cast
import voluptuous as vol
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant, ServiceCall, callback
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entityfilter import generate_filter
@ -36,15 +37,28 @@ SERVICE_PURGE_SCHEMA = vol.Schema(
ATTR_DOMAINS = "domains"
ATTR_ENTITY_GLOBS = "entity_globs"
SERVICE_PURGE_ENTITIES_SCHEMA = vol.Schema(
{
vol.Optional(ATTR_DOMAINS, default=[]): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(ATTR_ENTITY_GLOBS, default=[]): vol.All(
cv.ensure_list, [cv.string]
SERVICE_PURGE_ENTITIES_SCHEMA = vol.All(
vol.Schema(
{
vol.Optional(ATTR_ENTITY_ID, default=[]): cv.entity_ids,
vol.Optional(ATTR_DOMAINS, default=[]): vol.All(
cv.ensure_list, [cv.string]
),
vol.Optional(ATTR_ENTITY_GLOBS, default=[]): vol.All(
cv.ensure_list, [cv.string]
),
vol.Optional(ATTR_KEEP_DAYS, default=0): cv.positive_int,
}
),
vol.Any(
vol.Schema({vol.Required(ATTR_ENTITY_ID): vol.IsTrue()}, extra=vol.ALLOW_EXTRA),
vol.Schema({vol.Required(ATTR_DOMAINS): vol.IsTrue()}, extra=vol.ALLOW_EXTRA),
vol.Schema(
{vol.Required(ATTR_ENTITY_GLOBS): vol.IsTrue()}, extra=vol.ALLOW_EXTRA
),
vol.Optional(ATTR_KEEP_DAYS, default=0): cv.positive_int,
}
).extend(cv.ENTITY_SERVICE_FIELDS)
msg="At least one of entity_id, domains, or entity_globs must have a value",
),
)
SERVICE_ENABLE_SCHEMA = vol.Schema({})
SERVICE_DISABLE_SCHEMA = vol.Schema({})

View file

@ -20,20 +20,21 @@ purge:
boolean:
purge_entities:
target:
entity: {}
fields:
entity_id:
required: false
selector:
entity:
multiple: true
domains:
example: "sun"
required: false
default: []
selector:
object:
entity_globs:
example: "domain*.object_id*"
required: false
default: []
selector:
object:

View file

@ -41,6 +41,10 @@
"name": "Purge entities",
"description": "Starts a purge task to remove the data related to specific entities from your database.",
"fields": {
"entity_id": {
"name": "Entities to remove",
"description": "List of entities for which the data is to be removed from the recorder database."
},
"domains": {
"name": "Domains to remove",
"description": "List of domains for which the data needs to be removed from the recorder database."

View file

@ -9,6 +9,7 @@ from freezegun import freeze_time
import pytest
from sqlalchemy.exc import DatabaseError, OperationalError
from sqlalchemy.orm.session import Session
from voluptuous.error import MultipleInvalid
from homeassistant.components import recorder
from homeassistant.components.recorder.const import SupportedDialect
@ -1446,20 +1447,20 @@ async def test_purge_entities(
_add_purge_records(hass)
# Confirm calling service without arguments matches all records (default filter behavior)
# Confirm calling service without arguments is invalid
with session_scope(hass=hass) as session:
states = session.query(States)
assert states.count() == 190
await _purge_entities(hass, [], [], [])
with pytest.raises(MultipleInvalid):
await _purge_entities(hass, [], [], [])
with session_scope(hass=hass, read_only=True) as session:
states = session.query(States)
assert states.count() == 0
assert states.count() == 190
# The states_meta table should be empty
states_meta_remain = session.query(StatesMeta)
assert states_meta_remain.count() == 0
assert states_meta_remain.count() == 4
async def _add_test_states(hass: HomeAssistant, wait_recording_done: bool = True):