mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 17:57:11 +00:00
Add enable and disable services for recorder (#45778)
This commit is contained in:
parent
470121e5b0
commit
44293a3738
@ -48,6 +48,8 @@ from .util import (
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SERVICE_PURGE = "purge"
|
||||
SERVICE_ENABLE = "enable"
|
||||
SERVICE_DISABLE = "disable"
|
||||
|
||||
ATTR_KEEP_DAYS = "keep_days"
|
||||
ATTR_REPACK = "repack"
|
||||
@ -58,6 +60,8 @@ SERVICE_PURGE_SCHEMA = vol.Schema(
|
||||
vol.Optional(ATTR_REPACK, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
SERVICE_ENABLE_SCHEMA = vol.Schema({})
|
||||
SERVICE_DISABLE_SCHEMA = vol.Schema({})
|
||||
|
||||
DEFAULT_URL = "sqlite:///{hass_config_path}"
|
||||
DEFAULT_DB_FILE = "home-assistant_v2.db"
|
||||
@ -199,6 +203,23 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
DOMAIN, SERVICE_PURGE, async_handle_purge_service, schema=SERVICE_PURGE_SCHEMA
|
||||
)
|
||||
|
||||
async def async_handle_enable_sevice(service):
|
||||
instance.set_enable(True)
|
||||
|
||||
hass.services.async_register(
|
||||
DOMAIN, SERVICE_ENABLE, async_handle_enable_sevice, schema=SERVICE_ENABLE_SCHEMA
|
||||
)
|
||||
|
||||
async def async_handle_disable_service(service):
|
||||
instance.set_enable(False)
|
||||
|
||||
hass.services.async_register(
|
||||
DOMAIN,
|
||||
SERVICE_DISABLE,
|
||||
async_handle_disable_service,
|
||||
schema=SERVICE_DISABLE_SCHEMA,
|
||||
)
|
||||
|
||||
return await instance.async_db_ready
|
||||
|
||||
|
||||
@ -255,6 +276,12 @@ class Recorder(threading.Thread):
|
||||
self.get_session = None
|
||||
self._completed_database_setup = None
|
||||
|
||||
self.enabled = True
|
||||
|
||||
def set_enable(self, enable):
|
||||
"""Enable or disable recording events and states."""
|
||||
self.enabled = enable
|
||||
|
||||
@callback
|
||||
def async_initialize(self):
|
||||
"""Initialize the recorder."""
|
||||
@ -413,6 +440,9 @@ class Recorder(threading.Thread):
|
||||
self._commit_event_session_or_recover()
|
||||
return
|
||||
|
||||
if not self.enabled:
|
||||
return
|
||||
|
||||
try:
|
||||
if event.event_type == EVENT_STATE_CHANGED:
|
||||
dbevent = Events.from_event(event, event_data="{}")
|
||||
|
@ -24,3 +24,9 @@ purge:
|
||||
default: false
|
||||
selector:
|
||||
boolean:
|
||||
|
||||
disable:
|
||||
description: Stop the recording of events and state changes
|
||||
|
||||
enabled:
|
||||
description: Start the recording of events and state changes
|
||||
|
@ -8,13 +8,17 @@ from sqlalchemy.exc import OperationalError
|
||||
from homeassistant.components.recorder import (
|
||||
CONF_DB_URL,
|
||||
CONFIG_SCHEMA,
|
||||
DATA_INSTANCE,
|
||||
DOMAIN,
|
||||
SERVICE_DISABLE,
|
||||
SERVICE_ENABLE,
|
||||
SERVICE_PURGE,
|
||||
SQLITE_URL_PREFIX,
|
||||
Recorder,
|
||||
run_information,
|
||||
run_information_from_instance,
|
||||
run_information_with_session,
|
||||
)
|
||||
from homeassistant.components.recorder.const import DATA_INSTANCE, SQLITE_URL_PREFIX
|
||||
from homeassistant.components.recorder.models import Events, RecorderRuns, States
|
||||
from homeassistant.components.recorder.util import session_scope
|
||||
from homeassistant.const import (
|
||||
@ -24,7 +28,7 @@ from homeassistant.const import (
|
||||
STATE_UNLOCKED,
|
||||
)
|
||||
from homeassistant.core import Context, CoreState, callback
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.setup import async_setup_component, setup_component
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .common import async_wait_recording_done, corrupt_db_file, wait_recording_done
|
||||
@ -518,6 +522,155 @@ def test_run_information(hass_recorder):
|
||||
assert run_info.closed_incorrect is False
|
||||
|
||||
|
||||
def test_has_services(hass_recorder):
|
||||
"""Test the services exist."""
|
||||
hass = hass_recorder()
|
||||
|
||||
assert hass.services.has_service(DOMAIN, SERVICE_DISABLE)
|
||||
assert hass.services.has_service(DOMAIN, SERVICE_ENABLE)
|
||||
assert hass.services.has_service(DOMAIN, SERVICE_PURGE)
|
||||
|
||||
|
||||
def test_service_disable_events_not_recording(hass, hass_recorder):
|
||||
"""Test that events are not recorded when recorder is disabled using service."""
|
||||
hass = hass_recorder()
|
||||
|
||||
assert hass.services.call(
|
||||
DOMAIN,
|
||||
SERVICE_DISABLE,
|
||||
{},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
event_type = "EVENT_TEST"
|
||||
|
||||
events = []
|
||||
|
||||
@callback
|
||||
def event_listener(event):
|
||||
"""Record events from eventbus."""
|
||||
if event.event_type == event_type:
|
||||
events.append(event)
|
||||
|
||||
hass.bus.listen(MATCH_ALL, event_listener)
|
||||
|
||||
event_data1 = {"test_attr": 5, "test_attr_10": "nice"}
|
||||
hass.bus.fire(event_type, event_data1)
|
||||
wait_recording_done(hass)
|
||||
|
||||
assert len(events) == 1
|
||||
event = events[0]
|
||||
|
||||
with session_scope(hass=hass) as session:
|
||||
db_events = list(session.query(Events).filter_by(event_type=event_type))
|
||||
assert len(db_events) == 0
|
||||
|
||||
assert hass.services.call(
|
||||
DOMAIN,
|
||||
SERVICE_ENABLE,
|
||||
{},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
event_data2 = {"attr_one": 5, "attr_two": "nice"}
|
||||
hass.bus.fire(event_type, event_data2)
|
||||
wait_recording_done(hass)
|
||||
|
||||
assert len(events) == 2
|
||||
assert events[0] != events[1]
|
||||
assert events[0].data != events[1].data
|
||||
|
||||
with session_scope(hass=hass) as session:
|
||||
db_events = list(session.query(Events).filter_by(event_type=event_type))
|
||||
assert len(db_events) == 1
|
||||
db_event = db_events[0].to_native()
|
||||
|
||||
event = events[1]
|
||||
|
||||
assert event.event_type == db_event.event_type
|
||||
assert event.data == db_event.data
|
||||
assert event.origin == db_event.origin
|
||||
assert event.time_fired.replace(microsecond=0) == db_event.time_fired.replace(
|
||||
microsecond=0
|
||||
)
|
||||
|
||||
|
||||
def test_service_disable_states_not_recording(hass, hass_recorder):
|
||||
"""Test that state changes are not recorded when recorder is disabled using service."""
|
||||
hass = hass_recorder()
|
||||
|
||||
assert hass.services.call(
|
||||
DOMAIN,
|
||||
SERVICE_DISABLE,
|
||||
{},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
hass.states.set("test.one", "on", {})
|
||||
wait_recording_done(hass)
|
||||
|
||||
with session_scope(hass=hass) as session:
|
||||
assert len(list(session.query(States))) == 0
|
||||
|
||||
assert hass.services.call(
|
||||
DOMAIN,
|
||||
SERVICE_ENABLE,
|
||||
{},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
hass.states.set("test.two", "off", {})
|
||||
wait_recording_done(hass)
|
||||
|
||||
with session_scope(hass=hass) as session:
|
||||
db_states = list(session.query(States))
|
||||
assert len(db_states) == 1
|
||||
assert db_states[0].event_id > 0
|
||||
assert db_states[0].to_native() == _state_empty_context(hass, "test.two")
|
||||
|
||||
|
||||
def test_service_disable_run_information_recorded(tmpdir):
|
||||
"""Test that runs are still recorded when recorder is disabled."""
|
||||
test_db_file = tmpdir.mkdir("sqlite").join("test_run_info.db")
|
||||
dburl = f"{SQLITE_URL_PREFIX}//{test_db_file}"
|
||||
|
||||
hass = get_test_home_assistant()
|
||||
setup_component(hass, DOMAIN, {DOMAIN: {CONF_DB_URL: dburl}})
|
||||
hass.start()
|
||||
wait_recording_done(hass)
|
||||
|
||||
with session_scope(hass=hass) as session:
|
||||
db_run_info = list(session.query(RecorderRuns))
|
||||
assert len(db_run_info) == 1
|
||||
assert db_run_info[0].start is not None
|
||||
assert db_run_info[0].end is None
|
||||
|
||||
assert hass.services.call(
|
||||
DOMAIN,
|
||||
SERVICE_DISABLE,
|
||||
{},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
wait_recording_done(hass)
|
||||
hass.stop()
|
||||
|
||||
hass = get_test_home_assistant()
|
||||
setup_component(hass, DOMAIN, {DOMAIN: {CONF_DB_URL: dburl}})
|
||||
hass.start()
|
||||
wait_recording_done(hass)
|
||||
|
||||
with session_scope(hass=hass) as session:
|
||||
db_run_info = list(session.query(RecorderRuns))
|
||||
assert len(db_run_info) == 2
|
||||
assert db_run_info[0].start is not None
|
||||
assert db_run_info[0].end is not None
|
||||
assert db_run_info[1].start is not None
|
||||
assert db_run_info[1].end is None
|
||||
|
||||
hass.stop()
|
||||
|
||||
|
||||
class CannotSerializeMe:
|
||||
"""A class that the JSONEncoder cannot serialize."""
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user