Add open
state to LockEntity (#111968)
* Add `open` state to LockEntity * Add tests * Fixes * Fix tests * strings and icons * Adjust demo open lock * Fix lock and tests * fix import * Fix strings * mute ruff * Change sequence * Sequence2 * Group on states * Fix ruff * Fix tests * Add more test cases * Sorting
This commit is contained in:
parent
189c07d502
commit
7862596ef3
18 changed files with 377 additions and 37 deletions
|
@ -16,7 +16,13 @@ from homeassistant.components.lock import (
|
|||
STATE_UNLOCKED,
|
||||
STATE_UNLOCKING,
|
||||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID, EVENT_STATE_CHANGED, Platform
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
EVENT_STATE_CHANGED,
|
||||
STATE_OPEN,
|
||||
STATE_OPENING,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
|
@ -87,6 +93,26 @@ async def test_unlocking(hass: HomeAssistant) -> None:
|
|||
assert state_changes[1].data["new_state"].state == STATE_UNLOCKED
|
||||
|
||||
|
||||
@patch.object(demo_lock, "LOCK_UNLOCK_DELAY", 0)
|
||||
async def test_opening(hass: HomeAssistant) -> None:
|
||||
"""Test the opening of a lock."""
|
||||
state = hass.states.get(OPENABLE_LOCK)
|
||||
assert state.state == STATE_LOCKED
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state_changes = async_capture_events(hass, EVENT_STATE_CHANGED)
|
||||
await hass.services.async_call(
|
||||
LOCK_DOMAIN, SERVICE_OPEN, {ATTR_ENTITY_ID: OPENABLE_LOCK}, blocking=False
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert state_changes[0].data["entity_id"] == OPENABLE_LOCK
|
||||
assert state_changes[0].data["new_state"].state == STATE_OPENING
|
||||
|
||||
assert state_changes[1].data["entity_id"] == OPENABLE_LOCK
|
||||
assert state_changes[1].data["new_state"].state == STATE_OPEN
|
||||
|
||||
|
||||
@patch.object(demo_lock, "LOCK_UNLOCK_DELAY", 0)
|
||||
async def test_jammed_when_locking(hass: HomeAssistant) -> None:
|
||||
"""Test the locking of a lock jams."""
|
||||
|
@ -114,12 +140,3 @@ async def test_opening_mocked(hass: HomeAssistant) -> None:
|
|||
LOCK_DOMAIN, SERVICE_OPEN, {ATTR_ENTITY_ID: OPENABLE_LOCK}, blocking=True
|
||||
)
|
||||
assert len(calls) == 1
|
||||
|
||||
|
||||
async def test_opening(hass: HomeAssistant) -> None:
|
||||
"""Test the opening of a lock."""
|
||||
await hass.services.async_call(
|
||||
LOCK_DOMAIN, SERVICE_OPEN, {ATTR_ENTITY_ID: OPENABLE_LOCK}, blocking=True
|
||||
)
|
||||
state = hass.states.get(OPENABLE_LOCK)
|
||||
assert state.state == STATE_UNLOCKED
|
||||
|
|
|
@ -19,13 +19,17 @@ from homeassistant.const import (
|
|||
SERVICE_RELOAD,
|
||||
STATE_CLOSED,
|
||||
STATE_HOME,
|
||||
STATE_JAMMED,
|
||||
STATE_LOCKED,
|
||||
STATE_LOCKING,
|
||||
STATE_NOT_HOME,
|
||||
STATE_OFF,
|
||||
STATE_ON,
|
||||
STATE_OPEN,
|
||||
STATE_OPENING,
|
||||
STATE_UNKNOWN,
|
||||
STATE_UNLOCKED,
|
||||
STATE_UNLOCKING,
|
||||
)
|
||||
from homeassistant.core import CoreState, HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
@ -769,6 +773,48 @@ async def test_is_on(hass: HomeAssistant) -> None:
|
|||
(STATE_ON, True),
|
||||
(STATE_OFF, False),
|
||||
),
|
||||
(
|
||||
("lock", "lock"),
|
||||
(STATE_OPEN, STATE_LOCKED),
|
||||
(STATE_LOCKED, STATE_LOCKED),
|
||||
(STATE_UNLOCKED, True),
|
||||
(STATE_LOCKED, False),
|
||||
),
|
||||
(
|
||||
("lock", "lock"),
|
||||
(STATE_OPENING, STATE_LOCKED),
|
||||
(STATE_LOCKED, STATE_LOCKED),
|
||||
(STATE_UNLOCKED, True),
|
||||
(STATE_LOCKED, False),
|
||||
),
|
||||
(
|
||||
("lock", "lock"),
|
||||
(STATE_UNLOCKING, STATE_LOCKED),
|
||||
(STATE_LOCKED, STATE_LOCKED),
|
||||
(STATE_UNLOCKED, True),
|
||||
(STATE_LOCKED, False),
|
||||
),
|
||||
(
|
||||
("lock", "lock"),
|
||||
(STATE_LOCKING, STATE_LOCKED),
|
||||
(STATE_LOCKED, STATE_LOCKED),
|
||||
(STATE_UNLOCKED, True),
|
||||
(STATE_LOCKED, False),
|
||||
),
|
||||
(
|
||||
("lock", "lock"),
|
||||
(STATE_JAMMED, STATE_LOCKED),
|
||||
(STATE_LOCKED, STATE_LOCKED),
|
||||
(STATE_LOCKED, False),
|
||||
(STATE_LOCKED, False),
|
||||
),
|
||||
(
|
||||
("cover", "lock"),
|
||||
(STATE_OPEN, STATE_OPEN),
|
||||
(STATE_CLOSED, STATE_LOCKED),
|
||||
(STATE_ON, True),
|
||||
(STATE_OFF, False),
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_is_on_and_state_mixed_domains(
|
||||
|
@ -1247,6 +1293,8 @@ async def test_group_mixed_domains_off(hass: HomeAssistant) -> None:
|
|||
[
|
||||
(("locked", "locked", "unlocked"), "unlocked"),
|
||||
(("locked", "locked", "locked"), "locked"),
|
||||
(("locked", "locked", "open"), "unlocked"),
|
||||
(("locked", "unlocked", "open"), "unlocked"),
|
||||
],
|
||||
)
|
||||
async def test_group_locks(hass: HomeAssistant, states, group_state) -> None:
|
||||
|
|
|
@ -18,6 +18,7 @@ from homeassistant.const import (
|
|||
STATE_JAMMED,
|
||||
STATE_LOCKED,
|
||||
STATE_LOCKING,
|
||||
STATE_OPEN,
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
STATE_UNLOCKED,
|
||||
|
@ -204,8 +205,8 @@ async def test_service_calls_openable(hass: HomeAssistant) -> None:
|
|||
{ATTR_ENTITY_ID: "lock.lock_group"},
|
||||
blocking=True,
|
||||
)
|
||||
assert hass.states.get("lock.openable_lock").state == STATE_UNLOCKED
|
||||
assert hass.states.get("lock.another_openable_lock").state == STATE_UNLOCKED
|
||||
assert hass.states.get("lock.openable_lock").state == STATE_OPEN
|
||||
assert hass.states.get("lock.another_openable_lock").state == STATE_OPEN
|
||||
|
||||
await hass.services.async_call(
|
||||
LOCK_DOMAIN,
|
||||
|
|
|
@ -16,7 +16,12 @@ from homeassistant.components.lock import (
|
|||
STATE_UNLOCKED,
|
||||
STATE_UNLOCKING,
|
||||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID, EVENT_STATE_CHANGED, Platform
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
EVENT_STATE_CHANGED,
|
||||
STATE_OPEN,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
|
@ -103,4 +108,4 @@ async def test_opening(hass: HomeAssistant) -> None:
|
|||
LOCK_DOMAIN, SERVICE_OPEN, {ATTR_ENTITY_ID: OPENABLE_LOCK}, blocking=True
|
||||
)
|
||||
state = hass.states.get(OPENABLE_LOCK)
|
||||
assert state.state == STATE_UNLOCKED
|
||||
assert state.state == STATE_OPEN
|
||||
|
|
|
@ -10,6 +10,8 @@ from homeassistant.const import (
|
|||
STATE_JAMMED,
|
||||
STATE_LOCKED,
|
||||
STATE_LOCKING,
|
||||
STATE_OPEN,
|
||||
STATE_OPENING,
|
||||
STATE_UNLOCKED,
|
||||
STATE_UNLOCKING,
|
||||
EntityCategory,
|
||||
|
@ -32,7 +34,7 @@ def stub_blueprint_populate_autouse(stub_blueprint_populate: None) -> None:
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def calls(hass):
|
||||
def calls(hass: HomeAssistant):
|
||||
"""Track calls to a mock service."""
|
||||
return async_mock_service(hass, "test", "automation")
|
||||
|
||||
|
@ -67,6 +69,8 @@ async def test_get_conditions(
|
|||
"is_unlocking",
|
||||
"is_locking",
|
||||
"is_jammed",
|
||||
"is_open",
|
||||
"is_opening",
|
||||
]
|
||||
]
|
||||
conditions = await async_get_device_automations(
|
||||
|
@ -121,6 +125,8 @@ async def test_get_conditions_hidden_auxiliary(
|
|||
"is_unlocking",
|
||||
"is_locking",
|
||||
"is_jammed",
|
||||
"is_open",
|
||||
"is_opening",
|
||||
]
|
||||
]
|
||||
conditions = await async_get_device_automations(
|
||||
|
@ -243,6 +249,42 @@ async def test_if_state(
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"trigger": {"platform": "event", "event_type": "test_event6"},
|
||||
"condition": [
|
||||
{
|
||||
"condition": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device_entry.id,
|
||||
"entity_id": entry.id,
|
||||
"type": "is_opening",
|
||||
}
|
||||
],
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data_template": {
|
||||
"some": "is_opening - {{ trigger.platform }} - {{ trigger.event.event_type }}"
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"trigger": {"platform": "event", "event_type": "test_event7"},
|
||||
"condition": [
|
||||
{
|
||||
"condition": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device_entry.id,
|
||||
"entity_id": entry.id,
|
||||
"type": "is_open",
|
||||
}
|
||||
],
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data_template": {
|
||||
"some": "is_open - {{ trigger.platform }} - {{ trigger.event.event_type }}"
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
@ -277,6 +319,18 @@ async def test_if_state(
|
|||
assert len(calls) == 5
|
||||
assert calls[4].data["some"] == "is_jammed - event - test_event5"
|
||||
|
||||
hass.states.async_set(entry.entity_id, STATE_OPENING)
|
||||
hass.bus.async_fire("test_event6")
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 6
|
||||
assert calls[5].data["some"] == "is_opening - event - test_event6"
|
||||
|
||||
hass.states.async_set(entry.entity_id, STATE_OPEN)
|
||||
hass.bus.async_fire("test_event7")
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 7
|
||||
assert calls[6].data["some"] == "is_open - event - test_event7"
|
||||
|
||||
|
||||
async def test_if_state_legacy(
|
||||
hass: HomeAssistant,
|
||||
|
|
|
@ -7,11 +7,13 @@ from pytest_unordered import unordered
|
|||
|
||||
from homeassistant.components import automation
|
||||
from homeassistant.components.device_automation import DeviceAutomationType
|
||||
from homeassistant.components.lock import DOMAIN
|
||||
from homeassistant.components.lock import DOMAIN, LockEntityFeature
|
||||
from homeassistant.const import (
|
||||
STATE_JAMMED,
|
||||
STATE_LOCKED,
|
||||
STATE_LOCKING,
|
||||
STATE_OPEN,
|
||||
STATE_OPENING,
|
||||
STATE_UNLOCKED,
|
||||
STATE_UNLOCKING,
|
||||
EntityCategory,
|
||||
|
@ -37,7 +39,7 @@ def stub_blueprint_populate_autouse(stub_blueprint_populate: None) -> None:
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def calls(hass):
|
||||
def calls(hass: HomeAssistant):
|
||||
"""Track calls to a mock service."""
|
||||
return async_mock_service(hass, "test", "automation")
|
||||
|
||||
|
@ -55,7 +57,11 @@ async def test_get_triggers(
|
|||
connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
|
||||
)
|
||||
entity_entry = entity_registry.async_get_or_create(
|
||||
DOMAIN, "test", "5678", device_id=device_entry.id
|
||||
DOMAIN,
|
||||
"test",
|
||||
"5678",
|
||||
device_id=device_entry.id,
|
||||
supported_features=LockEntityFeature.OPEN,
|
||||
)
|
||||
expected_triggers = [
|
||||
{
|
||||
|
@ -66,7 +72,15 @@ async def test_get_triggers(
|
|||
"entity_id": entity_entry.id,
|
||||
"metadata": {"secondary": False},
|
||||
}
|
||||
for trigger in ["locked", "unlocked", "unlocking", "locking", "jammed"]
|
||||
for trigger in [
|
||||
"locked",
|
||||
"unlocked",
|
||||
"unlocking",
|
||||
"locking",
|
||||
"jammed",
|
||||
"open",
|
||||
"opening",
|
||||
]
|
||||
]
|
||||
triggers = await async_get_device_automations(
|
||||
hass, DeviceAutomationType.TRIGGER, device_entry.id
|
||||
|
@ -104,6 +118,7 @@ async def test_get_triggers_hidden_auxiliary(
|
|||
device_id=device_entry.id,
|
||||
entity_category=entity_category,
|
||||
hidden_by=hidden_by,
|
||||
supported_features=LockEntityFeature.OPEN,
|
||||
)
|
||||
expected_triggers = [
|
||||
{
|
||||
|
@ -114,7 +129,15 @@ async def test_get_triggers_hidden_auxiliary(
|
|||
"entity_id": entity_entry.id,
|
||||
"metadata": {"secondary": True},
|
||||
}
|
||||
for trigger in ["locked", "unlocked", "unlocking", "locking", "jammed"]
|
||||
for trigger in [
|
||||
"locked",
|
||||
"unlocked",
|
||||
"unlocking",
|
||||
"locking",
|
||||
"jammed",
|
||||
"open",
|
||||
"opening",
|
||||
]
|
||||
]
|
||||
triggers = await async_get_device_automations(
|
||||
hass, DeviceAutomationType.TRIGGER, device_entry.id
|
||||
|
@ -141,7 +164,7 @@ async def test_get_trigger_capabilities(
|
|||
triggers = await async_get_device_automations(
|
||||
hass, DeviceAutomationType.TRIGGER, device_entry.id
|
||||
)
|
||||
assert len(triggers) == 5
|
||||
assert len(triggers) == 7
|
||||
for trigger in triggers:
|
||||
capabilities = await async_get_device_automation_capabilities(
|
||||
hass, DeviceAutomationType.TRIGGER, trigger
|
||||
|
@ -172,7 +195,7 @@ async def test_get_trigger_capabilities_legacy(
|
|||
triggers = await async_get_device_automations(
|
||||
hass, DeviceAutomationType.TRIGGER, device_entry.id
|
||||
)
|
||||
assert len(triggers) == 5
|
||||
assert len(triggers) == 7
|
||||
for trigger in triggers:
|
||||
trigger["entity_id"] = entity_registry.async_get(trigger["entity_id"]).entity_id
|
||||
capabilities = await async_get_device_automation_capabilities(
|
||||
|
@ -247,6 +270,25 @@ async def test_if_fires_on_state_change(
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device_entry.id,
|
||||
"entity_id": entry.id,
|
||||
"type": "open",
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data_template": {
|
||||
"some": (
|
||||
"open - {{ trigger.platform}} - "
|
||||
"{{ trigger.entity_id}} - {{ trigger.from_state.state}} - "
|
||||
"{{ trigger.to_state.state}} - {{ trigger.for }}"
|
||||
)
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
@ -269,6 +311,15 @@ async def test_if_fires_on_state_change(
|
|||
== f"unlocked - device - {entry.entity_id} - locked - unlocked - None"
|
||||
)
|
||||
|
||||
# Fake that the entity is opens.
|
||||
hass.states.async_set(entry.entity_id, STATE_OPEN)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 3
|
||||
assert (
|
||||
calls[2].data["some"]
|
||||
== f"open - device - {entry.entity_id} - unlocked - open - None"
|
||||
)
|
||||
|
||||
|
||||
async def test_if_fires_on_state_change_legacy(
|
||||
hass: HomeAssistant,
|
||||
|
@ -439,6 +490,28 @@ async def test_if_fires_on_state_change_with_for(
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device_entry.id,
|
||||
"entity_id": entry.id,
|
||||
"type": "opening",
|
||||
"for": {"seconds": 5},
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data_template": {
|
||||
"some": (
|
||||
"turn_on {{ trigger.platform }}"
|
||||
" - {{ trigger.entity_id }}"
|
||||
" - {{ trigger.from_state.state }}"
|
||||
" - {{ trigger.to_state.state }}"
|
||||
" - {{ trigger.for }}"
|
||||
)
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
@ -492,3 +565,15 @@ async def test_if_fires_on_state_change_with_for(
|
|||
calls[3].data["some"]
|
||||
== f"turn_on device - {entry.entity_id} - jammed - locking - 0:00:05"
|
||||
)
|
||||
|
||||
hass.states.async_set(entry.entity_id, STATE_OPENING)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 4
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=27))
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 5
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
calls[4].data["some"]
|
||||
== f"turn_on device - {entry.entity_id} - locking - opening - 0:00:05"
|
||||
)
|
||||
|
|
|
@ -22,6 +22,7 @@ from homeassistant.components.lock import (
|
|||
STATE_UNLOCKING,
|
||||
LockEntityFeature,
|
||||
)
|
||||
from homeassistant.const import STATE_OPEN, STATE_OPENING
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ServiceValidationError
|
||||
import homeassistant.helpers.entity_registry as er
|
||||
|
@ -55,6 +56,8 @@ async def test_lock_default(hass: HomeAssistant, mock_lock_entity: MockLock) ->
|
|||
assert mock_lock_entity.is_locked is None
|
||||
assert mock_lock_entity.is_locking is None
|
||||
assert mock_lock_entity.is_unlocking is None
|
||||
assert mock_lock_entity.is_opening is None
|
||||
assert mock_lock_entity.is_open is None
|
||||
|
||||
|
||||
async def test_lock_states(hass: HomeAssistant, mock_lock_entity: MockLock) -> None:
|
||||
|
@ -85,6 +88,19 @@ async def test_lock_states(hass: HomeAssistant, mock_lock_entity: MockLock) -> N
|
|||
assert mock_lock_entity.state == STATE_JAMMED
|
||||
assert not mock_lock_entity.is_locked
|
||||
|
||||
mock_lock_entity._attr_is_jammed = False
|
||||
mock_lock_entity._attr_is_opening = True
|
||||
assert mock_lock_entity.is_opening
|
||||
assert mock_lock_entity.state == STATE_OPENING
|
||||
assert mock_lock_entity.is_opening
|
||||
|
||||
mock_lock_entity._attr_is_opening = False
|
||||
mock_lock_entity._attr_is_open = True
|
||||
assert not mock_lock_entity.is_opening
|
||||
assert mock_lock_entity.state == STATE_OPEN
|
||||
assert not mock_lock_entity.is_opening
|
||||
assert mock_lock_entity.is_open
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("code_format", "supported_features"),
|
||||
|
|
|
@ -14,9 +14,11 @@ async def test_reproducing_states(
|
|||
"""Test reproducing Lock states."""
|
||||
hass.states.async_set("lock.entity_locked", "locked", {})
|
||||
hass.states.async_set("lock.entity_unlocked", "unlocked", {})
|
||||
hass.states.async_set("lock.entity_opened", "open", {})
|
||||
|
||||
lock_calls = async_mock_service(hass, "lock", "lock")
|
||||
unlock_calls = async_mock_service(hass, "lock", "unlock")
|
||||
open_calls = async_mock_service(hass, "lock", "open")
|
||||
|
||||
# These calls should do nothing as entities already in desired state
|
||||
await async_reproduce_state(
|
||||
|
@ -24,11 +26,13 @@ async def test_reproducing_states(
|
|||
[
|
||||
State("lock.entity_locked", "locked"),
|
||||
State("lock.entity_unlocked", "unlocked", {}),
|
||||
State("lock.entity_opened", "open", {}),
|
||||
],
|
||||
)
|
||||
|
||||
assert len(lock_calls) == 0
|
||||
assert len(unlock_calls) == 0
|
||||
assert len(open_calls) == 0
|
||||
|
||||
# Test invalid state is handled
|
||||
await async_reproduce_state(hass, [State("lock.entity_locked", "not_supported")])
|
||||
|
@ -36,13 +40,15 @@ async def test_reproducing_states(
|
|||
assert "not_supported" in caplog.text
|
||||
assert len(lock_calls) == 0
|
||||
assert len(unlock_calls) == 0
|
||||
assert len(open_calls) == 0
|
||||
|
||||
# Make sure correct services are called
|
||||
await async_reproduce_state(
|
||||
hass,
|
||||
[
|
||||
State("lock.entity_locked", "unlocked"),
|
||||
State("lock.entity_locked", "open"),
|
||||
State("lock.entity_unlocked", "locked"),
|
||||
State("lock.entity_opened", "unlocked"),
|
||||
# Should not raise
|
||||
State("lock.non_existing", "on"),
|
||||
],
|
||||
|
@ -54,4 +60,8 @@ async def test_reproducing_states(
|
|||
|
||||
assert len(unlock_calls) == 1
|
||||
assert unlock_calls[0].domain == "lock"
|
||||
assert unlock_calls[0].data == {"entity_id": "lock.entity_locked"}
|
||||
assert unlock_calls[0].data == {"entity_id": "lock.entity_opened"}
|
||||
|
||||
assert len(open_calls) == 1
|
||||
assert open_calls[0].domain == "lock"
|
||||
assert open_calls[0].data == {"entity_id": "lock.entity_locked"}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue