mirror of
https://github.com/home-assistant/core.git
synced 2025-08-09 15:45:08 +02:00
Fix optimistic covers (#149962)
This commit is contained in:
@@ -216,6 +216,7 @@ class AbstractTemplateCover(AbstractTemplateEntity, CoverEntity):
|
|||||||
|
|
||||||
_entity_id_format = ENTITY_ID_FORMAT
|
_entity_id_format = ENTITY_ID_FORMAT
|
||||||
_optimistic_entity = True
|
_optimistic_entity = True
|
||||||
|
_extra_optimistic_options = (CONF_POSITION,)
|
||||||
|
|
||||||
# The super init is not called because TemplateEntity and TriggerEntity will call AbstractTemplateEntity.__init__.
|
# The super init is not called because TemplateEntity and TriggerEntity will call AbstractTemplateEntity.__init__.
|
||||||
# This ensures that the __init__ on AbstractTemplateEntity is not called twice.
|
# This ensures that the __init__ on AbstractTemplateEntity is not called twice.
|
||||||
|
@@ -20,6 +20,7 @@ class AbstractTemplateEntity(Entity):
|
|||||||
|
|
||||||
_entity_id_format: str
|
_entity_id_format: str
|
||||||
_optimistic_entity: bool = False
|
_optimistic_entity: bool = False
|
||||||
|
_extra_optimistic_options: tuple[str, ...] | None = None
|
||||||
_template: Template | None = None
|
_template: Template | None = None
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -35,9 +36,14 @@ class AbstractTemplateEntity(Entity):
|
|||||||
if self._optimistic_entity:
|
if self._optimistic_entity:
|
||||||
self._template = config.get(CONF_STATE)
|
self._template = config.get(CONF_STATE)
|
||||||
|
|
||||||
self._attr_assumed_state = self._template is None or config.get(
|
optimistic = self._template is None
|
||||||
CONF_OPTIMISTIC, False
|
if self._extra_optimistic_options:
|
||||||
)
|
optimistic = optimistic and all(
|
||||||
|
config.get(option) is None
|
||||||
|
for option in self._extra_optimistic_options
|
||||||
|
)
|
||||||
|
|
||||||
|
self._attr_assumed_state = optimistic or config.get(CONF_OPTIMISTIC, False)
|
||||||
|
|
||||||
if (object_id := config.get(CONF_OBJECT_ID)) is not None:
|
if (object_id := config.get(CONF_OBJECT_ID)) is not None:
|
||||||
self.entity_id = async_generate_entity_id(
|
self.entity_id = async_generate_entity_id(
|
||||||
|
@@ -239,6 +239,7 @@ async def setup_position_cover(
|
|||||||
{
|
{
|
||||||
TEST_OBJECT_ID: {
|
TEST_OBJECT_ID: {
|
||||||
**COVER_ACTIONS,
|
**COVER_ACTIONS,
|
||||||
|
"set_cover_position": SET_COVER_POSITION,
|
||||||
"position_template": position_template,
|
"position_template": position_template,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -249,6 +250,7 @@ async def setup_position_cover(
|
|||||||
count,
|
count,
|
||||||
{
|
{
|
||||||
**NAMED_COVER_ACTIONS,
|
**NAMED_COVER_ACTIONS,
|
||||||
|
"set_cover_position": SET_COVER_POSITION,
|
||||||
"position": position_template,
|
"position": position_template,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -258,6 +260,7 @@ async def setup_position_cover(
|
|||||||
count,
|
count,
|
||||||
{
|
{
|
||||||
**NAMED_COVER_ACTIONS,
|
**NAMED_COVER_ACTIONS,
|
||||||
|
"set_cover_position": SET_COVER_POSITION,
|
||||||
"position": position_template,
|
"position": position_template,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -565,6 +568,7 @@ async def test_template_position(
|
|||||||
position: int | None,
|
position: int | None,
|
||||||
expected: str,
|
expected: str,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
calls: list[ServiceCall],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the position_template attribute."""
|
"""Test the position_template attribute."""
|
||||||
hass.states.async_set(TEST_STATE_ENTITY_ID, CoverState.OPEN)
|
hass.states.async_set(TEST_STATE_ENTITY_ID, CoverState.OPEN)
|
||||||
@@ -580,6 +584,19 @@ async def test_template_position(
|
|||||||
assert state.state == expected
|
assert state.state == expected
|
||||||
assert "ValueError" not in caplog.text
|
assert "ValueError" not in caplog.text
|
||||||
|
|
||||||
|
# Test to make sure optimistic is not set with only a position template.
|
||||||
|
await hass.services.async_call(
|
||||||
|
COVER_DOMAIN,
|
||||||
|
SERVICE_SET_COVER_POSITION,
|
||||||
|
{ATTR_ENTITY_ID: TEST_ENTITY_ID, "position": 10},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get(TEST_ENTITY_ID)
|
||||||
|
assert state.attributes.get("current_position") == position
|
||||||
|
assert state.state == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("count", [1])
|
@pytest.mark.parametrize("count", [1])
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
Reference in New Issue
Block a user