mirror of
https://github.com/home-assistant/core.git
synced 2026-01-06 23:28:04 +00:00
Compare commits
12 Commits
llm-python
...
gj-2024120
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e20bda33a4 | ||
|
|
f2125a1133 | ||
|
|
557caa7ecb | ||
|
|
d973e42c97 | ||
|
|
428c7ced94 | ||
|
|
7b14bd89a0 | ||
|
|
f1f45d6b5b | ||
|
|
50e4311416 | ||
|
|
1a32a2f9c2 | ||
|
|
f9cecc0cd5 | ||
|
|
6fe2612f1d | ||
|
|
43fbb2ab7b |
@@ -3,7 +3,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable, Coroutine, Mapping
|
||||
from datetime import timedelta
|
||||
from functools import partial
|
||||
import logging
|
||||
from typing import Any, cast
|
||||
|
||||
import voluptuous as vol
|
||||
@@ -13,6 +15,7 @@ from homeassistant.const import CONF_ENTITIES, CONF_TYPE
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import entity_registry as er, selector
|
||||
from homeassistant.helpers.entity_platform import EntityPlatform
|
||||
from homeassistant.helpers.schema_config_entry_flow import (
|
||||
SchemaCommonFlowHandler,
|
||||
SchemaConfigFlowHandler,
|
||||
@@ -48,6 +51,8 @@ _STATISTIC_MEASURES = [
|
||||
"sum",
|
||||
]
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def basic_group_options_schema(
|
||||
domain: str | list[str], handler: SchemaCommonFlowHandler | None
|
||||
@@ -424,6 +429,15 @@ def ws_start_preview(
|
||||
)
|
||||
preview_entity.hass = hass
|
||||
preview_entity.registry_entry = entity_registry_entry
|
||||
preview_entity.platform = EntityPlatform(
|
||||
hass=hass,
|
||||
logger=_LOGGER,
|
||||
domain=group_type,
|
||||
platform_name=DOMAIN,
|
||||
platform=None,
|
||||
scan_interval=timedelta(hours=1),
|
||||
entity_namespace=None,
|
||||
)
|
||||
|
||||
connection.send_result(msg["id"])
|
||||
connection.subscriptions[msg["id"]] = preview_entity.async_start_preview(
|
||||
|
||||
@@ -3,15 +3,17 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from datetime import timedelta
|
||||
from typing import Any, cast
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import websocket_api
|
||||
from homeassistant.components.sensor import SensorDeviceClass
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN, SensorDeviceClass
|
||||
from homeassistant.const import CONF_NAME, Platform
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.entity_platform import EntityPlatform
|
||||
from homeassistant.helpers.schema_config_entry_flow import (
|
||||
SchemaCommonFlowHandler,
|
||||
SchemaConfigFlowHandler,
|
||||
@@ -36,7 +38,7 @@ from .const import (
|
||||
DEFAULT_NAME,
|
||||
DOMAIN,
|
||||
)
|
||||
from .sensor import MoldIndicator
|
||||
from .sensor import _LOGGER, MoldIndicator
|
||||
|
||||
|
||||
async def validate_input(
|
||||
@@ -168,6 +170,15 @@ def ws_start_preview(
|
||||
None,
|
||||
)
|
||||
preview_entity.hass = hass
|
||||
preview_entity.platform = EntityPlatform(
|
||||
hass=hass,
|
||||
logger=_LOGGER,
|
||||
domain=SENSOR_DOMAIN,
|
||||
platform_name=DOMAIN,
|
||||
platform=None,
|
||||
scan_interval=timedelta(hours=1),
|
||||
entity_namespace=None,
|
||||
)
|
||||
|
||||
connection.send_result(msg["id"])
|
||||
connection.subscriptions[msg["id"]] = preview_entity.async_start_preview(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""OwnTracks Message handlers."""
|
||||
|
||||
from datetime import timedelta
|
||||
import json
|
||||
import logging
|
||||
|
||||
@@ -9,6 +10,7 @@ from nacl.secret import SecretBox
|
||||
from homeassistant.components import zone as zone_comp
|
||||
from homeassistant.components.device_tracker import SourceType
|
||||
from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE, STATE_HOME
|
||||
from homeassistant.helpers.entity_platform import EntityPlatform
|
||||
from homeassistant.util import decorator, slugify
|
||||
|
||||
from .helper import supports_encryption
|
||||
@@ -317,6 +319,15 @@ async def async_handle_waypoint(hass, name_base, waypoint):
|
||||
)
|
||||
zone.hass = hass
|
||||
zone.entity_id = entity_id
|
||||
zone.platform = EntityPlatform(
|
||||
hass=hass,
|
||||
logger=_LOGGER,
|
||||
domain="zone",
|
||||
platform_name="owntracks",
|
||||
platform=None,
|
||||
scan_interval=timedelta(seconds=15),
|
||||
entity_namespace=None,
|
||||
)
|
||||
zone.async_write_ha_state()
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.const import CONF_ENTITY_ID, CONF_NAME
|
||||
from homeassistant.core import HomeAssistant, callback, split_entity_id
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.entity_platform import EntityPlatform
|
||||
from homeassistant.helpers.schema_config_entry_flow import (
|
||||
SchemaCommonFlowHandler,
|
||||
SchemaConfigFlowHandler,
|
||||
@@ -37,6 +38,7 @@ from homeassistant.helpers.selector import (
|
||||
|
||||
from . import DOMAIN
|
||||
from .sensor import (
|
||||
_LOGGER,
|
||||
CONF_KEEP_LAST_SAMPLE,
|
||||
CONF_MAX_AGE,
|
||||
CONF_PERCENTILE,
|
||||
@@ -232,6 +234,15 @@ async def ws_start_preview(
|
||||
msg["user_input"].get(CONF_PERCENTILE),
|
||||
)
|
||||
preview_entity.hass = hass
|
||||
preview_entity.platform = EntityPlatform(
|
||||
hass=hass,
|
||||
logger=_LOGGER,
|
||||
domain=SENSOR_DOMAIN,
|
||||
platform_name=DOMAIN,
|
||||
platform=None,
|
||||
scan_interval=timedelta(hours=1),
|
||||
entity_namespace=None,
|
||||
)
|
||||
|
||||
connection.send_result(msg["id"])
|
||||
connection.subscriptions[msg["id"]] = await preview_entity.async_start_preview(
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable, Coroutine, Mapping
|
||||
from datetime import timedelta
|
||||
from functools import partial
|
||||
import logging
|
||||
from typing import Any, cast
|
||||
|
||||
import voluptuous as vol
|
||||
@@ -32,6 +34,7 @@ from homeassistant.const import (
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import entity_registry as er, selector
|
||||
from homeassistant.helpers.entity_platform import EntityPlatform
|
||||
from homeassistant.helpers.schema_config_entry_flow import (
|
||||
SchemaCommonFlowHandler,
|
||||
SchemaConfigFlowHandler,
|
||||
@@ -68,6 +71,8 @@ from .sensor import async_create_preview_sensor
|
||||
from .switch import async_create_preview_switch
|
||||
from .template_entity import TemplateEntity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
_SCHEMA_STATE: dict[vol.Marker, Any] = {
|
||||
vol.Required(CONF_STATE): selector.TemplateSelector(),
|
||||
}
|
||||
@@ -524,6 +529,15 @@ def ws_start_preview(
|
||||
preview_entity = CREATE_PREVIEW_ENTITY[template_type](hass, name, msg["user_input"])
|
||||
preview_entity.hass = hass
|
||||
preview_entity.registry_entry = entity_registry_entry
|
||||
preview_entity.platform = EntityPlatform(
|
||||
hass=hass,
|
||||
logger=_LOGGER,
|
||||
domain=template_type,
|
||||
platform_name=DOMAIN,
|
||||
platform=None,
|
||||
scan_interval=timedelta(hours=1),
|
||||
entity_namespace=None,
|
||||
)
|
||||
|
||||
connection.send_result(msg["id"])
|
||||
connection.subscriptions[msg["id"]] = preview_entity.async_start_preview(
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from datetime import timedelta
|
||||
from typing import Any
|
||||
|
||||
import voluptuous as vol
|
||||
@@ -13,6 +14,7 @@ from homeassistant.const import CONF_ENTITY_ID, CONF_NAME
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import selector
|
||||
from homeassistant.helpers.entity_platform import EntityPlatform
|
||||
from homeassistant.helpers.schema_config_entry_flow import (
|
||||
SchemaCommonFlowHandler,
|
||||
SchemaConfigFlowHandler,
|
||||
@@ -20,7 +22,7 @@ from homeassistant.helpers.schema_config_entry_flow import (
|
||||
SchemaFlowFormStep,
|
||||
)
|
||||
|
||||
from .binary_sensor import ThresholdSensor
|
||||
from .binary_sensor import _LOGGER, ThresholdSensor
|
||||
from .const import CONF_HYSTERESIS, CONF_LOWER, CONF_UPPER, DEFAULT_HYSTERESIS, DOMAIN
|
||||
|
||||
|
||||
@@ -140,6 +142,15 @@ def ws_start_preview(
|
||||
None,
|
||||
)
|
||||
preview_entity.hass = hass
|
||||
preview_entity.platform = EntityPlatform(
|
||||
hass=hass,
|
||||
logger=_LOGGER,
|
||||
domain=SENSOR_DOMAIN,
|
||||
platform_name=DOMAIN,
|
||||
platform=None,
|
||||
scan_interval=timedelta(hours=1),
|
||||
entity_namespace=None,
|
||||
)
|
||||
|
||||
connection.send_result(msg["id"])
|
||||
connection.subscriptions[msg["id"]] = preview_entity.async_start_preview(
|
||||
|
||||
@@ -64,7 +64,7 @@ from .event import (
|
||||
async_track_device_registry_updated_event,
|
||||
async_track_entity_registry_updated_event,
|
||||
)
|
||||
from .frame import report_non_thread_safe_operation
|
||||
from .frame import ReportBehavior, report_non_thread_safe_operation, report_usage
|
||||
from .typing import UNDEFINED, StateType, UndefinedType
|
||||
|
||||
timer = time.time
|
||||
@@ -464,9 +464,6 @@ class Entity(
|
||||
# it should be using async_write_ha_state.
|
||||
_async_update_ha_state_reported = False
|
||||
|
||||
# If we reported this entity was added without its platform set
|
||||
_no_platform_reported = False
|
||||
|
||||
# If we reported the name translation placeholders do not match the name
|
||||
_name_translation_placeholders_reported = False
|
||||
|
||||
@@ -722,9 +719,6 @@ class Entity(
|
||||
# value.
|
||||
type.__getattribute__(self.__class__, "name")
|
||||
is type.__getattribute__(Entity, "name")
|
||||
# The check for self.platform guards against integrations not using an
|
||||
# EntityComponent and can be removed in HA Core 2024.1
|
||||
and self.platform
|
||||
):
|
||||
name = self._name_internal(
|
||||
self._object_id_device_class_name,
|
||||
@@ -737,10 +731,6 @@ class Entity(
|
||||
@cached_property
|
||||
def name(self) -> str | UndefinedType | None:
|
||||
"""Return the name of the entity."""
|
||||
# The check for self.platform guards against integrations not using an
|
||||
# EntityComponent and can be removed in HA Core 2024.1
|
||||
if not self.platform:
|
||||
return self._name_internal(None, {})
|
||||
return self._name_internal(
|
||||
self._device_class_name,
|
||||
self.platform.platform_translations,
|
||||
@@ -983,21 +973,14 @@ class Entity(
|
||||
if self.hass is None:
|
||||
raise RuntimeError(f"Attribute hass is None for {self}")
|
||||
|
||||
# The check for self.platform guards against integrations not using an
|
||||
# EntityComponent and can be removed in HA Core 2024.1
|
||||
if self.platform is None and not self._no_platform_reported: # type: ignore[unreachable]
|
||||
report_issue = self._suggest_report_issue() # type: ignore[unreachable]
|
||||
_LOGGER.warning(
|
||||
(
|
||||
"Entity %s (%s) does not have a platform, this may be caused by "
|
||||
"adding it manually instead of with an EntityComponent helper"
|
||||
", please %s"
|
||||
),
|
||||
self.entity_id,
|
||||
type(self),
|
||||
report_issue,
|
||||
# Break if entity is not loaded using EntityComponent
|
||||
# behavior changed from logging in in 2025.1
|
||||
if self.platform is None:
|
||||
report_usage( # type: ignore[unreachable]
|
||||
f"Entity {self.entity_id} ({type(self)}) does not have a platform,"
|
||||
"this may be caused by adding it manually instead of with an EntityComponent helper",
|
||||
core_behavior=ReportBehavior.ERROR,
|
||||
)
|
||||
self._no_platform_reported = True
|
||||
|
||||
if self.entity_id is None:
|
||||
raise NoEntitySpecifiedError(
|
||||
@@ -1499,10 +1482,7 @@ class Entity(
|
||||
|
||||
Not to be extended by integrations.
|
||||
"""
|
||||
# The check for self.platform guards against integrations not using an
|
||||
# EntityComponent and can be removed in HA Core 2024.1
|
||||
if self.platform:
|
||||
del entity_sources(self.hass)[self.entity_id]
|
||||
del entity_sources(self.hass)[self.entity_id]
|
||||
|
||||
@callback
|
||||
def _async_registry_updated(
|
||||
@@ -1632,9 +1612,7 @@ class Entity(
|
||||
|
||||
def _suggest_report_issue(self) -> str:
|
||||
"""Suggest to report an issue."""
|
||||
# The check for self.platform guards against integrations not using an
|
||||
# EntityComponent and can be removed in HA Core 2024.1
|
||||
platform_name = self.platform.platform_name if self.platform else None
|
||||
platform_name = self.platform.platform_name
|
||||
return async_suggest_report_issue(
|
||||
self.hass, integration_domain=platform_name, module=type(self).__module__
|
||||
)
|
||||
|
||||
@@ -6,6 +6,7 @@ import dataclasses
|
||||
from datetime import timedelta
|
||||
from enum import IntFlag
|
||||
import logging
|
||||
import re
|
||||
import threading
|
||||
from typing import Any
|
||||
from unittest.mock import MagicMock, PropertyMock, patch
|
||||
@@ -100,6 +101,8 @@ async def test_async_update_support(hass: HomeAssistant) -> None:
|
||||
|
||||
ent = AsyncEntity()
|
||||
ent.hass = hass
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([ent])
|
||||
|
||||
await ent.async_update_ha_state(True)
|
||||
|
||||
@@ -124,6 +127,8 @@ async def test_device_class(hass: HomeAssistant) -> None:
|
||||
ent = entity.Entity()
|
||||
ent.entity_id = "test.overwrite_hidden_true"
|
||||
ent.hass = hass
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([ent])
|
||||
ent.async_write_ha_state()
|
||||
state = hass.states.get(ent.entity_id)
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) is None
|
||||
@@ -151,6 +156,9 @@ async def test_warn_slow_update(
|
||||
mock_entity.entity_id = "comp_test.test_entity"
|
||||
mock_entity.async_update = async_update
|
||||
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([mock_entity])
|
||||
|
||||
fast_update_time = 0.0000001
|
||||
|
||||
with patch.object(entity, "SLOW_UPDATE_WARNING", fast_update_time):
|
||||
@@ -341,6 +349,9 @@ async def test_async_parallel_updates_with_zero(hass: HomeAssistant) -> None:
|
||||
ent_1 = AsyncEntity("sensor.test_1", 1)
|
||||
ent_2 = AsyncEntity("sensor.test_2", 2)
|
||||
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([ent_1, ent_2])
|
||||
|
||||
try:
|
||||
ent_1.async_schedule_update_ha_state(True)
|
||||
ent_2.async_schedule_update_ha_state(True)
|
||||
@@ -382,6 +393,9 @@ async def test_async_parallel_updates_with_zero_on_sync_update(
|
||||
ent_1 = AsyncEntity("sensor.test_1", 1)
|
||||
ent_2 = AsyncEntity("sensor.test_2", 2)
|
||||
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([ent_1, ent_2])
|
||||
|
||||
try:
|
||||
ent_1.async_schedule_update_ha_state(True)
|
||||
ent_2.async_schedule_update_ha_state(True)
|
||||
@@ -412,7 +426,6 @@ async def test_async_parallel_updates_with_one(hass: HomeAssistant) -> None:
|
||||
self.entity_id = entity_id
|
||||
self.hass = hass
|
||||
self._count = count
|
||||
self.parallel_updates = test_semaphore
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Test update."""
|
||||
@@ -423,6 +436,10 @@ async def test_async_parallel_updates_with_one(hass: HomeAssistant) -> None:
|
||||
ent_2 = AsyncEntity("sensor.test_2", 2)
|
||||
ent_3 = AsyncEntity("sensor.test_3", 3)
|
||||
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
platform.parallel_updates = test_semaphore
|
||||
await platform.async_add_entities([ent_1, ent_2, ent_3])
|
||||
|
||||
await test_lock.acquire()
|
||||
|
||||
try:
|
||||
@@ -488,7 +505,6 @@ async def test_async_parallel_updates_with_two(hass: HomeAssistant) -> None:
|
||||
self.entity_id = entity_id
|
||||
self.hass = hass
|
||||
self._count = count
|
||||
self.parallel_updates = test_semaphore
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Test update."""
|
||||
@@ -500,6 +516,10 @@ async def test_async_parallel_updates_with_two(hass: HomeAssistant) -> None:
|
||||
ent_3 = AsyncEntity("sensor.test_3", 3)
|
||||
ent_4 = AsyncEntity("sensor.test_4", 4)
|
||||
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
platform.parallel_updates = test_semaphore
|
||||
await platform.async_add_entities([ent_1, ent_2, ent_3, ent_4])
|
||||
|
||||
await test_lock.acquire()
|
||||
|
||||
try:
|
||||
@@ -557,7 +577,6 @@ async def test_async_parallel_updates_with_one_using_executor(
|
||||
"""Initialize sync test entity."""
|
||||
self.entity_id = entity_id
|
||||
self.hass = hass
|
||||
self.parallel_updates = test_semaphore
|
||||
|
||||
def update(self) -> None:
|
||||
"""Test update."""
|
||||
@@ -565,6 +584,10 @@ async def test_async_parallel_updates_with_one_using_executor(
|
||||
|
||||
entities = [SyncEntity(f"sensor.test_{i}") for i in range(3)]
|
||||
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
platform.parallel_updates = test_semaphore
|
||||
await platform.async_add_entities(entities)
|
||||
|
||||
await asyncio.gather(
|
||||
*[
|
||||
hass.async_create_task(
|
||||
@@ -583,6 +606,8 @@ async def test_async_remove_no_platform(hass: HomeAssistant) -> None:
|
||||
ent = entity.Entity()
|
||||
ent.hass = hass
|
||||
ent.entity_id = "test.test"
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([ent])
|
||||
ent.async_write_ha_state()
|
||||
assert len(hass.states.async_entity_ids()) == 1
|
||||
await ent.async_remove()
|
||||
@@ -659,6 +684,8 @@ async def test_set_context(hass: HomeAssistant) -> None:
|
||||
ent.hass = hass
|
||||
ent.entity_id = "hello.world"
|
||||
ent.async_set_context(context)
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([ent])
|
||||
ent.async_write_ha_state()
|
||||
assert hass.states.get("hello.world").context == context
|
||||
|
||||
@@ -671,6 +698,8 @@ async def test_set_context_expired(hass: HomeAssistant) -> None:
|
||||
ent = entity.Entity()
|
||||
ent.hass = hass
|
||||
ent.entity_id = "hello.world"
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([ent])
|
||||
ent.async_set_context(context)
|
||||
ent.async_write_ha_state()
|
||||
|
||||
@@ -757,6 +786,8 @@ async def test_capability_attrs(hass: HomeAssistant) -> None:
|
||||
ent = entity.Entity()
|
||||
ent.hass = hass
|
||||
ent.entity_id = "hello.world"
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([ent])
|
||||
ent.async_write_ha_state()
|
||||
|
||||
state = hass.states.get("hello.world")
|
||||
@@ -896,6 +927,8 @@ async def test_float_conversion(hass: HomeAssistant) -> None:
|
||||
ent = entity.Entity()
|
||||
ent.hass = hass
|
||||
ent.entity_id = "hello.world"
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([ent])
|
||||
ent.async_write_ha_state()
|
||||
|
||||
state = hass.states.get("hello.world")
|
||||
@@ -910,6 +943,9 @@ async def test_attribution_attribute(hass: HomeAssistant) -> None:
|
||||
mock_entity.entity_id = "hello.world"
|
||||
mock_entity._attr_attribution = "Home Assistant"
|
||||
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([mock_entity])
|
||||
|
||||
mock_entity.async_schedule_update_ha_state(True)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -963,12 +999,15 @@ def test_entity_category_schema_error(value) -> None:
|
||||
schema(value)
|
||||
|
||||
|
||||
async def test_entity_description_fallback() -> None:
|
||||
async def test_entity_description_fallback(hass: HomeAssistant) -> None:
|
||||
"""Test entity description has same defaults as entity."""
|
||||
ent = entity.Entity()
|
||||
ent_with_description = entity.Entity()
|
||||
ent_with_description.entity_description = entity.EntityDescription(key="test")
|
||||
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([ent, ent_with_description])
|
||||
|
||||
for field in dataclasses.fields(entity.EntityDescription._dataclass):
|
||||
if field.name == "key":
|
||||
continue
|
||||
@@ -1665,31 +1704,23 @@ async def test_warn_using_async_update_ha_state(
|
||||
assert error_message not in caplog.text
|
||||
|
||||
|
||||
async def test_warn_no_platform(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""Test we warn am entity does not have a platform."""
|
||||
async def test_raise_if_no_platform(hass: HomeAssistant) -> None:
|
||||
"""Test we raise if entity does not have a platform."""
|
||||
ent = entity.Entity()
|
||||
ent.hass = hass
|
||||
ent.platform = MockEntityPlatform(hass)
|
||||
ent.entity_id = "hello.world"
|
||||
error_message = "does not have a platform"
|
||||
|
||||
# Without a platform, it should trigger the warning
|
||||
ent.platform = None
|
||||
caplog.clear()
|
||||
ent.async_write_ha_state()
|
||||
assert error_message in caplog.text
|
||||
|
||||
# Without a platform, it should not trigger the warning again
|
||||
caplog.clear()
|
||||
ent.async_write_ha_state()
|
||||
assert error_message not in caplog.text
|
||||
|
||||
# No warning if the entity has a platform
|
||||
caplog.clear()
|
||||
ent.async_write_ha_state()
|
||||
assert error_message not in caplog.text
|
||||
# Without a platform, it should raise
|
||||
error = re.escape(
|
||||
"Detected code that Entity hello.world (<class 'homeassistant.helpers.entity.Entity'>)"
|
||||
" does not have a platform,this may be caused by adding it manually instead"
|
||||
" of with an EntityComponent helper. Please report this issue"
|
||||
)
|
||||
with pytest.raises(
|
||||
RuntimeError,
|
||||
match=error,
|
||||
):
|
||||
ent.async_write_ha_state()
|
||||
|
||||
|
||||
async def test_invalid_state(
|
||||
@@ -1700,6 +1731,9 @@ async def test_invalid_state(
|
||||
ent.entity_id = "test.test"
|
||||
ent.hass = hass
|
||||
|
||||
platform = MockEntityPlatform(hass, domain="test", platform_name="test")
|
||||
await platform.async_add_entities([ent])
|
||||
|
||||
ent._attr_state = "x" * 255
|
||||
ent.async_write_ha_state()
|
||||
assert hass.states.get("test.test").state == "x" * 255
|
||||
@@ -1726,13 +1760,6 @@ async def test_suggest_report_issue_built_in(
|
||||
mock_entity = entity.Entity()
|
||||
mock_entity.entity_id = "comp_test.test_entity"
|
||||
|
||||
suggestion = mock_entity._suggest_report_issue()
|
||||
assert suggestion == (
|
||||
"create a bug report at https://github.com/home-assistant/core/issues"
|
||||
"?q=is%3Aopen+is%3Aissue"
|
||||
)
|
||||
|
||||
mock_integration(hass, MockModule(domain="test"), built_in=True)
|
||||
platform = MockEntityPlatform(hass, domain="comp_test", platform_name="test")
|
||||
await platform.async_add_entities([mock_entity])
|
||||
|
||||
@@ -1756,20 +1783,27 @@ async def test_suggest_report_issue_custom_component(
|
||||
mock_entity = CustomComponentEntity()
|
||||
mock_entity.entity_id = "comp_test.test_entity"
|
||||
|
||||
suggestion = mock_entity._suggest_report_issue()
|
||||
assert suggestion == "report it to the custom integration author"
|
||||
|
||||
mock_integration(
|
||||
hass,
|
||||
MockModule(
|
||||
domain="test", partial_manifest={"issue_tracker": "https://some_url"}
|
||||
),
|
||||
built_in=False,
|
||||
)
|
||||
platform = MockEntityPlatform(hass, domain="comp_test", platform_name="test")
|
||||
await platform.async_add_entities([mock_entity])
|
||||
|
||||
suggestion = mock_entity._suggest_report_issue()
|
||||
assert suggestion == "report it to the author of the 'test' custom integration"
|
||||
|
||||
mock_entity2 = CustomComponentEntity()
|
||||
mock_entity2.entity_id = "comp_test.test_entity2"
|
||||
|
||||
mock_integration(
|
||||
hass,
|
||||
MockModule(
|
||||
domain="test2", partial_manifest={"issue_tracker": "https://some_url"}
|
||||
),
|
||||
built_in=False,
|
||||
)
|
||||
platform = MockEntityPlatform(hass, domain="comp_test2", platform_name="test2")
|
||||
await platform.async_add_entities([mock_entity2])
|
||||
await hass.async_block_till_done()
|
||||
|
||||
suggestion = mock_entity2._suggest_report_issue()
|
||||
assert suggestion == "create a bug report at https://some_url"
|
||||
|
||||
|
||||
@@ -2487,10 +2521,13 @@ async def test_cached_entity_property_override(hass: HomeAssistant) -> None:
|
||||
|
||||
|
||||
async def test_entity_report_deprecated_supported_features_values(
|
||||
hass: HomeAssistant,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test reporting deprecated supported feature values only happens once."""
|
||||
ent = entity.Entity()
|
||||
ent.hass = hass
|
||||
ent.platform = MockEntityPlatform(hass)
|
||||
|
||||
class MockEntityFeatures(IntFlag):
|
||||
VALUE1 = 1
|
||||
@@ -2629,18 +2666,27 @@ async def test_async_write_ha_state_thread_safety(hass: HomeAssistant) -> None:
|
||||
ent = entity.Entity()
|
||||
ent.entity_id = "test.any"
|
||||
ent.hass = hass
|
||||
ent.async_write_ha_state()
|
||||
assert hass.states.get(ent.entity_id)
|
||||
|
||||
ent2 = entity.Entity()
|
||||
ent2.entity_id = "test.any2"
|
||||
ent2.hass = hass
|
||||
|
||||
platform = MockEntityPlatform(hass, domain="test")
|
||||
await platform.async_add_entities([ent, ent2])
|
||||
|
||||
ent._attr_state = "test"
|
||||
ent2._attr_state = "test"
|
||||
|
||||
ent.async_write_ha_state()
|
||||
assert hass.states.get(ent.entity_id).state == "test"
|
||||
|
||||
with pytest.raises(
|
||||
RuntimeError,
|
||||
match="Detected code that calls async_write_ha_state from a thread.",
|
||||
):
|
||||
await hass.async_add_executor_job(ent2.async_write_ha_state)
|
||||
assert not hass.states.get(ent2.entity_id)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get(ent2.entity_id).state != "test"
|
||||
|
||||
|
||||
async def test_async_write_ha_state_thread_safety_always(
|
||||
|
||||
Reference in New Issue
Block a user