mirror of
https://github.com/home-assistant/core.git
synced 2025-11-09 02:49:40 +00:00
Add support for glob matching to entity filters (#36913)
* Added GLOB capability to entityfilter and every place that uses it. All existing tests are passing * added tests for components affected by glob change * fixed flake8 error * mocking the correct listener * mocking correct bus method in azure test * tests passing in 3.7 and 3.8 * fixed formatting issue from rebase/conflict * Checking against glob patterns in more performant way * perf improvments and reverted unnecessarily adjusted tests * added new benchmark test around filters * no longer using get with default in entityfilter * changed filter name and removed logbook from filter benchmark * simplified benchmark tests from feedback * fixed apache tests and returned include exclude schemas to normal * fixed azure event hub tests to properly go through component logic * fixed azure test and clean up for other tests * renaming test files to match standard * merged mqtt statestream test changes with base * removed dependency on recorder filter schema from history * fixed recorder tests after merge and a bunch of lint errors
This commit is contained in:
@@ -18,6 +18,8 @@ from homeassistant.components.script import EVENT_SCRIPT_STARTED
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_NAME,
|
||||
CONF_DOMAINS,
|
||||
CONF_ENTITIES,
|
||||
EVENT_HOMEASSISTANT_START,
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
EVENT_STATE_CHANGED,
|
||||
@@ -26,6 +28,10 @@ from homeassistant.const import (
|
||||
STATE_ON,
|
||||
)
|
||||
import homeassistant.core as ha
|
||||
from homeassistant.helpers.entityfilter import (
|
||||
CONF_ENTITY_GLOBS,
|
||||
convert_include_exclude_filter,
|
||||
)
|
||||
from homeassistant.helpers.json import JSONEncoder
|
||||
from homeassistant.setup import async_setup_component, setup_component
|
||||
import homeassistant.util.dt as dt_util
|
||||
@@ -151,7 +157,9 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
attributes = {"unit_of_measurement": "foo"}
|
||||
eventA = self.create_state_changed_event(pointA, entity_id, 10, attributes)
|
||||
|
||||
entities_filter = logbook._generate_filter_from_config({})
|
||||
entities_filter = convert_include_exclude_filter(
|
||||
logbook.CONFIG_SCHEMA({logbook.DOMAIN: {}})[logbook.DOMAIN]
|
||||
)
|
||||
assert (
|
||||
logbook._keep_event(self.hass, eventA, entities_filter, entity_attr_cache)
|
||||
is False
|
||||
@@ -174,7 +182,9 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
)
|
||||
eventB = self.create_state_changed_event(pointB, entity_id2, 20)
|
||||
|
||||
entities_filter = logbook._generate_filter_from_config({})
|
||||
entities_filter = convert_include_exclude_filter(
|
||||
logbook.CONFIG_SCHEMA({logbook.DOMAIN: {}})[logbook.DOMAIN]
|
||||
)
|
||||
events = [
|
||||
e
|
||||
for e in (
|
||||
@@ -210,7 +220,9 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
)
|
||||
eventB = self.create_state_changed_event(pointB, entity_id2, 20)
|
||||
|
||||
entities_filter = logbook._generate_filter_from_config({})
|
||||
entities_filter = convert_include_exclude_filter(
|
||||
logbook.CONFIG_SCHEMA({logbook.DOMAIN: {}})[logbook.DOMAIN]
|
||||
)
|
||||
events = [
|
||||
e
|
||||
for e in (
|
||||
@@ -244,12 +256,10 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
config = logbook.CONFIG_SCHEMA(
|
||||
{
|
||||
ha.DOMAIN: {},
|
||||
logbook.DOMAIN: {
|
||||
logbook.CONF_EXCLUDE: {logbook.CONF_ENTITIES: [entity_id]}
|
||||
},
|
||||
logbook.DOMAIN: {logbook.CONF_EXCLUDE: {CONF_ENTITIES: [entity_id]}},
|
||||
}
|
||||
)
|
||||
entities_filter = logbook._generate_filter_from_config(config[logbook.DOMAIN])
|
||||
entities_filter = convert_include_exclude_filter(config[logbook.DOMAIN])
|
||||
events = [
|
||||
e
|
||||
for e in (
|
||||
@@ -284,11 +294,11 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
{
|
||||
ha.DOMAIN: {},
|
||||
logbook.DOMAIN: {
|
||||
logbook.CONF_EXCLUDE: {logbook.CONF_DOMAINS: ["switch", "alexa"]}
|
||||
logbook.CONF_EXCLUDE: {CONF_DOMAINS: ["switch", "alexa"]}
|
||||
},
|
||||
}
|
||||
)
|
||||
entities_filter = logbook._generate_filter_from_config(config[logbook.DOMAIN])
|
||||
entities_filter = convert_include_exclude_filter(config[logbook.DOMAIN])
|
||||
events = [
|
||||
e
|
||||
for e in (
|
||||
@@ -309,6 +319,53 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
entries[1], pointB, "blu", domain="sensor", entity_id=entity_id2
|
||||
)
|
||||
|
||||
def test_exclude_events_domain_glob(self):
|
||||
"""Test if events are filtered if domain or glob is excluded in config."""
|
||||
entity_id = "switch.bla"
|
||||
entity_id2 = "sensor.blu"
|
||||
entity_id3 = "sensor.excluded"
|
||||
pointA = dt_util.utcnow()
|
||||
pointB = pointA + timedelta(minutes=logbook.GROUP_BY_MINUTES)
|
||||
pointC = pointB + timedelta(minutes=logbook.GROUP_BY_MINUTES)
|
||||
entity_attr_cache = logbook.EntityAttributeCache(self.hass)
|
||||
|
||||
eventA = self.create_state_changed_event(pointA, entity_id, 10)
|
||||
eventB = self.create_state_changed_event(pointB, entity_id2, 20)
|
||||
eventC = self.create_state_changed_event(pointC, entity_id3, 30)
|
||||
|
||||
config = logbook.CONFIG_SCHEMA(
|
||||
{
|
||||
ha.DOMAIN: {},
|
||||
logbook.DOMAIN: {
|
||||
logbook.CONF_EXCLUDE: {
|
||||
CONF_DOMAINS: ["switch", "alexa"],
|
||||
CONF_ENTITY_GLOBS: "*.excluded",
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
entities_filter = convert_include_exclude_filter(config[logbook.DOMAIN])
|
||||
events = [
|
||||
e
|
||||
for e in (
|
||||
MockLazyEventPartialState(EVENT_HOMEASSISTANT_START),
|
||||
MockLazyEventPartialState(EVENT_ALEXA_SMART_HOME),
|
||||
eventA,
|
||||
eventB,
|
||||
eventC,
|
||||
)
|
||||
if logbook._keep_event(self.hass, e, entities_filter, entity_attr_cache)
|
||||
]
|
||||
entries = list(logbook.humanify(self.hass, events, entity_attr_cache))
|
||||
|
||||
assert len(entries) == 2
|
||||
self.assert_entry(
|
||||
entries[0], name="Home Assistant", message="started", domain=ha.DOMAIN
|
||||
)
|
||||
self.assert_entry(
|
||||
entries[1], pointB, "blu", domain="sensor", entity_id=entity_id2
|
||||
)
|
||||
|
||||
def test_include_events_entity(self):
|
||||
"""Test if events are filtered if entity is included in config."""
|
||||
entity_id = "sensor.bla"
|
||||
@@ -325,13 +382,13 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
ha.DOMAIN: {},
|
||||
logbook.DOMAIN: {
|
||||
logbook.CONF_INCLUDE: {
|
||||
logbook.CONF_DOMAINS: ["homeassistant"],
|
||||
logbook.CONF_ENTITIES: [entity_id2],
|
||||
CONF_DOMAINS: ["homeassistant"],
|
||||
CONF_ENTITIES: [entity_id2],
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
entities_filter = logbook._generate_filter_from_config(config[logbook.DOMAIN])
|
||||
entities_filter = convert_include_exclude_filter(config[logbook.DOMAIN])
|
||||
events = [
|
||||
e
|
||||
for e in (
|
||||
@@ -373,12 +430,12 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
ha.DOMAIN: {},
|
||||
logbook.DOMAIN: {
|
||||
logbook.CONF_INCLUDE: {
|
||||
logbook.CONF_DOMAINS: ["homeassistant", "sensor", "alexa"]
|
||||
CONF_DOMAINS: ["homeassistant", "sensor", "alexa"]
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
entities_filter = logbook._generate_filter_from_config(config[logbook.DOMAIN])
|
||||
entities_filter = convert_include_exclude_filter(config[logbook.DOMAIN])
|
||||
events = [
|
||||
e
|
||||
for e in (
|
||||
@@ -400,6 +457,63 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
entries[2], pointB, "blu", domain="sensor", entity_id=entity_id2
|
||||
)
|
||||
|
||||
def test_include_events_domain_glob(self):
|
||||
"""Test if events are filtered if domain or glob is included in config."""
|
||||
assert setup_component(self.hass, "alexa", {})
|
||||
entity_id = "switch.bla"
|
||||
entity_id2 = "sensor.blu"
|
||||
entity_id3 = "switch.included"
|
||||
pointA = dt_util.utcnow()
|
||||
pointB = pointA + timedelta(minutes=logbook.GROUP_BY_MINUTES)
|
||||
pointC = pointB + timedelta(minutes=logbook.GROUP_BY_MINUTES)
|
||||
entity_attr_cache = logbook.EntityAttributeCache(self.hass)
|
||||
|
||||
event_alexa = MockLazyEventPartialState(
|
||||
EVENT_ALEXA_SMART_HOME,
|
||||
{"request": {"namespace": "Alexa.Discovery", "name": "Discover"}},
|
||||
)
|
||||
|
||||
eventA = self.create_state_changed_event(pointA, entity_id, 10)
|
||||
eventB = self.create_state_changed_event(pointB, entity_id2, 20)
|
||||
eventC = self.create_state_changed_event(pointC, entity_id3, 30)
|
||||
|
||||
config = logbook.CONFIG_SCHEMA(
|
||||
{
|
||||
ha.DOMAIN: {},
|
||||
logbook.DOMAIN: {
|
||||
logbook.CONF_INCLUDE: {
|
||||
CONF_DOMAINS: ["homeassistant", "sensor", "alexa"],
|
||||
CONF_ENTITY_GLOBS: ["*.included"],
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
entities_filter = convert_include_exclude_filter(config[logbook.DOMAIN])
|
||||
events = [
|
||||
e
|
||||
for e in (
|
||||
MockLazyEventPartialState(EVENT_HOMEASSISTANT_START),
|
||||
event_alexa,
|
||||
eventA,
|
||||
eventB,
|
||||
eventC,
|
||||
)
|
||||
if logbook._keep_event(self.hass, e, entities_filter, entity_attr_cache)
|
||||
]
|
||||
entries = list(logbook.humanify(self.hass, events, entity_attr_cache))
|
||||
|
||||
assert len(entries) == 4
|
||||
self.assert_entry(
|
||||
entries[0], name="Home Assistant", message="started", domain=ha.DOMAIN
|
||||
)
|
||||
self.assert_entry(entries[1], name="Amazon Alexa", domain="alexa")
|
||||
self.assert_entry(
|
||||
entries[2], pointB, "blu", domain="sensor", entity_id=entity_id2
|
||||
)
|
||||
self.assert_entry(
|
||||
entries[3], pointC, "included", domain="switch", entity_id=entity_id3
|
||||
)
|
||||
|
||||
def test_include_exclude_events(self):
|
||||
"""Test if events are filtered if include and exclude is configured."""
|
||||
entity_id = "switch.bla"
|
||||
@@ -420,17 +534,17 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
ha.DOMAIN: {},
|
||||
logbook.DOMAIN: {
|
||||
logbook.CONF_INCLUDE: {
|
||||
logbook.CONF_DOMAINS: ["sensor", "homeassistant"],
|
||||
logbook.CONF_ENTITIES: ["switch.bla"],
|
||||
CONF_DOMAINS: ["sensor", "homeassistant"],
|
||||
CONF_ENTITIES: ["switch.bla"],
|
||||
},
|
||||
logbook.CONF_EXCLUDE: {
|
||||
logbook.CONF_DOMAINS: ["switch"],
|
||||
logbook.CONF_ENTITIES: ["sensor.bli"],
|
||||
CONF_DOMAINS: ["switch"],
|
||||
CONF_ENTITIES: ["sensor.bli"],
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
entities_filter = logbook._generate_filter_from_config(config[logbook.DOMAIN])
|
||||
entities_filter = convert_include_exclude_filter(config[logbook.DOMAIN])
|
||||
events = [
|
||||
e
|
||||
for e in (
|
||||
@@ -462,6 +576,83 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
entries[4], pointB, "blu", domain="sensor", entity_id=entity_id2
|
||||
)
|
||||
|
||||
def test_include_exclude_events_with_glob_filters(self):
|
||||
"""Test if events are filtered if include and exclude is configured."""
|
||||
entity_id = "switch.bla"
|
||||
entity_id2 = "sensor.blu"
|
||||
entity_id3 = "sensor.bli"
|
||||
entity_id4 = "light.included"
|
||||
entity_id5 = "switch.included"
|
||||
entity_id6 = "sensor.excluded"
|
||||
pointA = dt_util.utcnow()
|
||||
pointB = pointA + timedelta(minutes=logbook.GROUP_BY_MINUTES)
|
||||
pointC = pointB + timedelta(minutes=logbook.GROUP_BY_MINUTES)
|
||||
entity_attr_cache = logbook.EntityAttributeCache(self.hass)
|
||||
|
||||
eventA1 = self.create_state_changed_event(pointA, entity_id, 10)
|
||||
eventA2 = self.create_state_changed_event(pointA, entity_id2, 10)
|
||||
eventA3 = self.create_state_changed_event(pointA, entity_id3, 10)
|
||||
eventB1 = self.create_state_changed_event(pointB, entity_id, 20)
|
||||
eventB2 = self.create_state_changed_event(pointB, entity_id2, 20)
|
||||
eventC1 = self.create_state_changed_event(pointC, entity_id4, 30)
|
||||
eventC2 = self.create_state_changed_event(pointC, entity_id5, 30)
|
||||
eventC3 = self.create_state_changed_event(pointC, entity_id6, 30)
|
||||
|
||||
config = logbook.CONFIG_SCHEMA(
|
||||
{
|
||||
ha.DOMAIN: {},
|
||||
logbook.DOMAIN: {
|
||||
logbook.CONF_INCLUDE: {
|
||||
CONF_DOMAINS: ["sensor", "homeassistant"],
|
||||
CONF_ENTITIES: ["switch.bla"],
|
||||
CONF_ENTITY_GLOBS: ["*.included"],
|
||||
},
|
||||
logbook.CONF_EXCLUDE: {
|
||||
CONF_DOMAINS: ["switch"],
|
||||
CONF_ENTITY_GLOBS: ["*.excluded"],
|
||||
CONF_ENTITIES: ["sensor.bli"],
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
entities_filter = convert_include_exclude_filter(config[logbook.DOMAIN])
|
||||
events = [
|
||||
e
|
||||
for e in (
|
||||
MockLazyEventPartialState(EVENT_HOMEASSISTANT_START),
|
||||
eventA1,
|
||||
eventA2,
|
||||
eventA3,
|
||||
eventB1,
|
||||
eventB2,
|
||||
eventC1,
|
||||
eventC2,
|
||||
eventC3,
|
||||
)
|
||||
if logbook._keep_event(self.hass, e, entities_filter, entity_attr_cache)
|
||||
]
|
||||
entries = list(logbook.humanify(self.hass, events, entity_attr_cache))
|
||||
|
||||
assert len(entries) == 6
|
||||
self.assert_entry(
|
||||
entries[0], name="Home Assistant", message="started", domain=ha.DOMAIN
|
||||
)
|
||||
self.assert_entry(
|
||||
entries[1], pointA, "bla", domain="switch", entity_id=entity_id
|
||||
)
|
||||
self.assert_entry(
|
||||
entries[2], pointA, "blu", domain="sensor", entity_id=entity_id2
|
||||
)
|
||||
self.assert_entry(
|
||||
entries[3], pointB, "bla", domain="switch", entity_id=entity_id
|
||||
)
|
||||
self.assert_entry(
|
||||
entries[4], pointB, "blu", domain="sensor", entity_id=entity_id2
|
||||
)
|
||||
self.assert_entry(
|
||||
entries[5], pointC, "included", domain="light", entity_id=entity_id4
|
||||
)
|
||||
|
||||
def test_exclude_attribute_changes(self):
|
||||
"""Test if events of attribute changes are filtered."""
|
||||
pointA = dt_util.utcnow()
|
||||
@@ -484,7 +675,9 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
"light.kitchen", pointC, state_100, state_200
|
||||
)
|
||||
|
||||
entities_filter = logbook._generate_filter_from_config({})
|
||||
entities_filter = convert_include_exclude_filter(
|
||||
logbook.CONFIG_SCHEMA({logbook.DOMAIN: {}})[logbook.DOMAIN]
|
||||
)
|
||||
events = [
|
||||
e
|
||||
for e in (eventA, eventB)
|
||||
@@ -1192,6 +1385,7 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
entries[0], name=name, message=message, domain="sun", entity_id=entity_id
|
||||
)
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
def assert_entry(
|
||||
self, entry, when=None, name=None, message=None, domain=None, entity_id=None
|
||||
):
|
||||
@@ -1232,6 +1426,7 @@ class TestComponentLogbook(unittest.TestCase):
|
||||
entity_id, event_time_fired, old_state, new_state
|
||||
)
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
def create_state_changed_event_from_old_new(
|
||||
self, entity_id, event_time_fired, old_state, new_state
|
||||
):
|
||||
@@ -1306,36 +1501,36 @@ async def test_logbook_view_period_entity(hass, hass_client):
|
||||
# Test today entries without filters
|
||||
response = await client.get(f"/api/logbook/{start_date.isoformat()}")
|
||||
assert response.status == 200
|
||||
json = await response.json()
|
||||
assert len(json) == 2
|
||||
assert json[0]["entity_id"] == entity_id_test
|
||||
assert json[1]["entity_id"] == entity_id_second
|
||||
response_json = await response.json()
|
||||
assert len(response_json) == 2
|
||||
assert response_json[0]["entity_id"] == entity_id_test
|
||||
assert response_json[1]["entity_id"] == entity_id_second
|
||||
|
||||
# Test today entries with filter by period
|
||||
response = await client.get(f"/api/logbook/{start_date.isoformat()}?period=1")
|
||||
assert response.status == 200
|
||||
json = await response.json()
|
||||
assert len(json) == 2
|
||||
assert json[0]["entity_id"] == entity_id_test
|
||||
assert json[1]["entity_id"] == entity_id_second
|
||||
response_json = await response.json()
|
||||
assert len(response_json) == 2
|
||||
assert response_json[0]["entity_id"] == entity_id_test
|
||||
assert response_json[1]["entity_id"] == entity_id_second
|
||||
|
||||
# Test today entries with filter by entity_id
|
||||
response = await client.get(
|
||||
f"/api/logbook/{start_date.isoformat()}?entity=switch.test"
|
||||
)
|
||||
assert response.status == 200
|
||||
json = await response.json()
|
||||
assert len(json) == 1
|
||||
assert json[0]["entity_id"] == entity_id_test
|
||||
response_json = await response.json()
|
||||
assert len(response_json) == 1
|
||||
assert response_json[0]["entity_id"] == entity_id_test
|
||||
|
||||
# Test entries for 3 days with filter by entity_id
|
||||
response = await client.get(
|
||||
f"/api/logbook/{start_date.isoformat()}?period=3&entity=switch.test"
|
||||
)
|
||||
assert response.status == 200
|
||||
json = await response.json()
|
||||
assert len(json) == 1
|
||||
assert json[0]["entity_id"] == entity_id_test
|
||||
response_json = await response.json()
|
||||
assert len(response_json) == 1
|
||||
assert response_json[0]["entity_id"] == entity_id_test
|
||||
|
||||
# Tomorrow time 00:00:00
|
||||
start = (dt_util.utcnow() + timedelta(days=1)).date()
|
||||
@@ -1344,25 +1539,25 @@ async def test_logbook_view_period_entity(hass, hass_client):
|
||||
# Test tomorrow entries without filters
|
||||
response = await client.get(f"/api/logbook/{start_date.isoformat()}")
|
||||
assert response.status == 200
|
||||
json = await response.json()
|
||||
assert len(json) == 0
|
||||
response_json = await response.json()
|
||||
assert len(response_json) == 0
|
||||
|
||||
# Test tomorrow entries with filter by entity_id
|
||||
response = await client.get(
|
||||
f"/api/logbook/{start_date.isoformat()}?entity=switch.test"
|
||||
)
|
||||
assert response.status == 200
|
||||
json = await response.json()
|
||||
assert len(json) == 0
|
||||
response_json = await response.json()
|
||||
assert len(response_json) == 0
|
||||
|
||||
# Test entries from tomorrow to 3 days ago with filter by entity_id
|
||||
response = await client.get(
|
||||
f"/api/logbook/{start_date.isoformat()}?period=3&entity=switch.test"
|
||||
)
|
||||
assert response.status == 200
|
||||
json = await response.json()
|
||||
assert len(json) == 1
|
||||
assert json[0]["entity_id"] == entity_id_test
|
||||
response_json = await response.json()
|
||||
assert len(response_json) == 1
|
||||
assert response_json[0]["entity_id"] == entity_id_test
|
||||
|
||||
|
||||
async def test_logbook_describe_event(hass, hass_client):
|
||||
@@ -1409,8 +1604,8 @@ async def test_exclude_described_event(hass, hass_client):
|
||||
{
|
||||
logbook.DOMAIN: {
|
||||
logbook.CONF_EXCLUDE: {
|
||||
logbook.CONF_DOMAINS: ["sensor"],
|
||||
logbook.CONF_ENTITIES: [entity_id],
|
||||
CONF_DOMAINS: ["sensor"],
|
||||
CONF_ENTITIES: [entity_id],
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1488,10 +1683,10 @@ async def test_logbook_view_end_time_entity(hass, hass_client):
|
||||
f"/api/logbook/{start_date.isoformat()}?end_time={end_time}"
|
||||
)
|
||||
assert response.status == 200
|
||||
json = await response.json()
|
||||
assert len(json) == 2
|
||||
assert json[0]["entity_id"] == entity_id_test
|
||||
assert json[1]["entity_id"] == entity_id_second
|
||||
response_json = await response.json()
|
||||
assert len(response_json) == 2
|
||||
assert response_json[0]["entity_id"] == entity_id_test
|
||||
assert response_json[1]["entity_id"] == entity_id_second
|
||||
|
||||
# Test entries for 3 days with filter by entity_id
|
||||
end_time = start + timedelta(hours=72)
|
||||
@@ -1499,9 +1694,9 @@ async def test_logbook_view_end_time_entity(hass, hass_client):
|
||||
f"/api/logbook/{start_date.isoformat()}?end_time={end_time}&entity=switch.test"
|
||||
)
|
||||
assert response.status == 200
|
||||
json = await response.json()
|
||||
assert len(json) == 1
|
||||
assert json[0]["entity_id"] == entity_id_test
|
||||
response_json = await response.json()
|
||||
assert len(response_json) == 1
|
||||
assert response_json[0]["entity_id"] == entity_id_test
|
||||
|
||||
# Tomorrow time 00:00:00
|
||||
start = dt_util.utcnow()
|
||||
@@ -1513,9 +1708,9 @@ async def test_logbook_view_end_time_entity(hass, hass_client):
|
||||
f"/api/logbook/{start_date.isoformat()}?end_time={end_time}&entity=switch.test"
|
||||
)
|
||||
assert response.status == 200
|
||||
json = await response.json()
|
||||
assert len(json) == 1
|
||||
assert json[0]["entity_id"] == entity_id_test
|
||||
response_json = await response.json()
|
||||
assert len(response_json) == 1
|
||||
assert response_json[0]["entity_id"] == entity_id_test
|
||||
|
||||
|
||||
async def test_logbook_entity_filter_with_automations(hass, hass_client):
|
||||
|
||||
Reference in New Issue
Block a user