mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 07:07:28 +00:00
deCONZ use siren platform (#56397)
* Add siren.py * Working siren platform with 100% test coverage * Also add test file... * Add test to verify that switch platform cleans up legacy entities now that sirens are their own platform * Update homeassistant/components/deconz/siren.py Co-authored-by: jjlawren <jjlawren@users.noreply.github.com>
This commit is contained in:
parent
6b6e26c96d
commit
bf7c2753d5
@ -12,6 +12,7 @@ from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
|||||||
from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN
|
from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN
|
||||||
from homeassistant.components.scene import DOMAIN as SCENE_DOMAIN
|
from homeassistant.components.scene import DOMAIN as SCENE_DOMAIN
|
||||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||||
|
from homeassistant.components.siren import DOMAIN as SIREN_DOMAIN
|
||||||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__package__)
|
LOGGER = logging.getLogger(__package__)
|
||||||
@ -41,6 +42,7 @@ PLATFORMS = [
|
|||||||
LOCK_DOMAIN,
|
LOCK_DOMAIN,
|
||||||
SCENE_DOMAIN,
|
SCENE_DOMAIN,
|
||||||
SENSOR_DOMAIN,
|
SENSOR_DOMAIN,
|
||||||
|
SIREN_DOMAIN,
|
||||||
SWITCH_DOMAIN,
|
SWITCH_DOMAIN,
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -69,10 +71,11 @@ FANS = ["Fan"]
|
|||||||
# Locks
|
# Locks
|
||||||
LOCK_TYPES = ["Door Lock", "ZHADoorLock"]
|
LOCK_TYPES = ["Door Lock", "ZHADoorLock"]
|
||||||
|
|
||||||
|
# Sirens
|
||||||
|
SIRENS = ["Warning device"]
|
||||||
|
|
||||||
# Switches
|
# Switches
|
||||||
POWER_PLUGS = ["On/Off light", "On/Off plug-in unit", "Smart plug"]
|
POWER_PLUGS = ["On/Off light", "On/Off plug-in unit", "Smart plug"]
|
||||||
SIRENS = ["Warning device"]
|
|
||||||
SWITCH_TYPES = POWER_PLUGS + SIRENS
|
|
||||||
|
|
||||||
CONF_ANGLE = "angle"
|
CONF_ANGLE = "angle"
|
||||||
CONF_GESTURE = "gesture"
|
CONF_GESTURE = "gesture"
|
||||||
|
@ -34,7 +34,8 @@ from .const import (
|
|||||||
LOCK_TYPES,
|
LOCK_TYPES,
|
||||||
NEW_GROUP,
|
NEW_GROUP,
|
||||||
NEW_LIGHT,
|
NEW_LIGHT,
|
||||||
SWITCH_TYPES,
|
POWER_PLUGS,
|
||||||
|
SIRENS,
|
||||||
)
|
)
|
||||||
from .deconz_device import DeconzDevice
|
from .deconz_device import DeconzDevice
|
||||||
from .gateway import get_gateway_from_config_entry
|
from .gateway import get_gateway_from_config_entry
|
||||||
@ -42,14 +43,16 @@ from .gateway import get_gateway_from_config_entry
|
|||||||
CONTROLLER = ["Configuration tool"]
|
CONTROLLER = ["Configuration tool"]
|
||||||
DECONZ_GROUP = "is_deconz_group"
|
DECONZ_GROUP = "is_deconz_group"
|
||||||
|
|
||||||
|
OTHER_LIGHT_RESOURCE_TYPES = (
|
||||||
|
CONTROLLER + COVER_TYPES + LOCK_TYPES + POWER_PLUGS + SIRENS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
"""Set up the deCONZ lights and groups from a config entry."""
|
"""Set up the deCONZ lights and groups from a config entry."""
|
||||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||||
gateway.entities[DOMAIN] = set()
|
gateway.entities[DOMAIN] = set()
|
||||||
|
|
||||||
other_light_resource_types = CONTROLLER + COVER_TYPES + LOCK_TYPES + SWITCH_TYPES
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_add_light(lights=gateway.api.lights.values()):
|
def async_add_light(lights=gateway.api.lights.values()):
|
||||||
"""Add light from deCONZ."""
|
"""Add light from deCONZ."""
|
||||||
@ -57,7 +60,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
|
|
||||||
for light in lights:
|
for light in lights:
|
||||||
if (
|
if (
|
||||||
light.type not in other_light_resource_types
|
light.type not in OTHER_LIGHT_RESOURCE_TYPES
|
||||||
and light.unique_id not in gateway.entities[DOMAIN]
|
and light.unique_id not in gateway.entities[DOMAIN]
|
||||||
):
|
):
|
||||||
entities.append(DeconzLight(light, gateway))
|
entities.append(DeconzLight(light, gateway))
|
||||||
|
78
homeassistant/components/deconz/siren.py
Normal file
78
homeassistant/components/deconz/siren.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
"""Support for deCONZ siren."""
|
||||||
|
|
||||||
|
from pydeconz.light import Siren
|
||||||
|
|
||||||
|
from homeassistant.components.siren import (
|
||||||
|
ATTR_DURATION,
|
||||||
|
DOMAIN,
|
||||||
|
SUPPORT_DURATION,
|
||||||
|
SUPPORT_TURN_OFF,
|
||||||
|
SUPPORT_TURN_ON,
|
||||||
|
SirenEntity,
|
||||||
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
|
from .const import NEW_LIGHT
|
||||||
|
from .deconz_device import DeconzDevice
|
||||||
|
from .gateway import get_gateway_from_config_entry
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
|
"""Set up sirens for deCONZ component."""
|
||||||
|
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||||
|
gateway.entities[DOMAIN] = set()
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_add_siren(lights=gateway.api.lights.values()):
|
||||||
|
"""Add siren from deCONZ."""
|
||||||
|
entities = []
|
||||||
|
|
||||||
|
for light in lights:
|
||||||
|
|
||||||
|
if (
|
||||||
|
isinstance(light, Siren)
|
||||||
|
and light.unique_id not in gateway.entities[DOMAIN]
|
||||||
|
):
|
||||||
|
entities.append(DeconzSiren(light, gateway))
|
||||||
|
|
||||||
|
if entities:
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
config_entry.async_on_unload(
|
||||||
|
async_dispatcher_connect(
|
||||||
|
hass, gateway.async_signal_new_device(NEW_LIGHT), async_add_siren
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
async_add_siren()
|
||||||
|
|
||||||
|
|
||||||
|
class DeconzSiren(DeconzDevice, SirenEntity):
|
||||||
|
"""Representation of a deCONZ siren."""
|
||||||
|
|
||||||
|
TYPE = DOMAIN
|
||||||
|
|
||||||
|
def __init__(self, device, gateway) -> None:
|
||||||
|
"""Set up siren."""
|
||||||
|
super().__init__(device, gateway)
|
||||||
|
|
||||||
|
self._attr_supported_features = (
|
||||||
|
SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_DURATION
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self):
|
||||||
|
"""Return true if siren is on."""
|
||||||
|
return self._device.is_on
|
||||||
|
|
||||||
|
async def async_turn_on(self, **kwargs):
|
||||||
|
"""Turn on siren."""
|
||||||
|
data = {}
|
||||||
|
if (duration := kwargs.get(ATTR_DURATION)) is not None:
|
||||||
|
data["duration"] = duration * 10
|
||||||
|
await self._device.turn_on(**data)
|
||||||
|
|
||||||
|
async def async_turn_off(self, **kwargs):
|
||||||
|
"""Turn off siren."""
|
||||||
|
await self._device.turn_off()
|
@ -3,7 +3,7 @@ from homeassistant.components.switch import DOMAIN, SwitchEntity
|
|||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
|
||||||
from .const import NEW_LIGHT, POWER_PLUGS, SIRENS
|
from .const import DOMAIN as DECONZ_DOMAIN, NEW_LIGHT, POWER_PLUGS, SIRENS
|
||||||
from .deconz_device import DeconzDevice
|
from .deconz_device import DeconzDevice
|
||||||
from .gateway import get_gateway_from_config_entry
|
from .gateway import get_gateway_from_config_entry
|
||||||
|
|
||||||
@ -16,6 +16,17 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||||
gateway.entities[DOMAIN] = set()
|
gateway.entities[DOMAIN] = set()
|
||||||
|
|
||||||
|
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||||
|
|
||||||
|
# Siren platform replacing sirens in switch platform added in 2021.10
|
||||||
|
for light in gateway.api.lights.values():
|
||||||
|
if light.type not in SIRENS:
|
||||||
|
continue
|
||||||
|
if entity_id := entity_registry.async_get_entity_id(
|
||||||
|
DOMAIN, DECONZ_DOMAIN, light.unique_id
|
||||||
|
):
|
||||||
|
entity_registry.async_remove(entity_id)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_add_switch(lights=gateway.api.lights.values()):
|
def async_add_switch(lights=gateway.api.lights.values()):
|
||||||
"""Add switch from deCONZ."""
|
"""Add switch from deCONZ."""
|
||||||
@ -29,11 +40,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
):
|
):
|
||||||
entities.append(DeconzPowerPlug(light, gateway))
|
entities.append(DeconzPowerPlug(light, gateway))
|
||||||
|
|
||||||
elif (
|
|
||||||
light.type in SIRENS and light.unique_id not in gateway.entities[DOMAIN]
|
|
||||||
):
|
|
||||||
entities.append(DeconzSiren(light, gateway))
|
|
||||||
|
|
||||||
if entities:
|
if entities:
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
@ -63,22 +69,3 @@ class DeconzPowerPlug(DeconzDevice, SwitchEntity):
|
|||||||
async def async_turn_off(self, **kwargs):
|
async def async_turn_off(self, **kwargs):
|
||||||
"""Turn off switch."""
|
"""Turn off switch."""
|
||||||
await self._device.set_state(on=False)
|
await self._device.set_state(on=False)
|
||||||
|
|
||||||
|
|
||||||
class DeconzSiren(DeconzDevice, SwitchEntity):
|
|
||||||
"""Representation of a deCONZ siren."""
|
|
||||||
|
|
||||||
TYPE = DOMAIN
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_on(self):
|
|
||||||
"""Return true if switch is on."""
|
|
||||||
return self._device.is_on
|
|
||||||
|
|
||||||
async def async_turn_on(self, **kwargs):
|
|
||||||
"""Turn on switch."""
|
|
||||||
await self._device.turn_on()
|
|
||||||
|
|
||||||
async def async_turn_off(self, **kwargs):
|
|
||||||
"""Turn off switch."""
|
|
||||||
await self._device.turn_off()
|
|
||||||
|
@ -25,6 +25,7 @@ from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
|||||||
from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN
|
from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN
|
||||||
from homeassistant.components.scene import DOMAIN as SCENE_DOMAIN
|
from homeassistant.components.scene import DOMAIN as SCENE_DOMAIN
|
||||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||||
|
from homeassistant.components.siren import DOMAIN as SIREN_DOMAIN
|
||||||
from homeassistant.components.ssdp import (
|
from homeassistant.components.ssdp import (
|
||||||
ATTR_SSDP_LOCATION,
|
ATTR_SSDP_LOCATION,
|
||||||
ATTR_UPNP_MANUFACTURER_URL,
|
ATTR_UPNP_MANUFACTURER_URL,
|
||||||
@ -163,7 +164,8 @@ async def test_gateway_setup(hass, aioclient_mock):
|
|||||||
assert forward_entry_setup.mock_calls[6][1] == (config_entry, LOCK_DOMAIN)
|
assert forward_entry_setup.mock_calls[6][1] == (config_entry, LOCK_DOMAIN)
|
||||||
assert forward_entry_setup.mock_calls[7][1] == (config_entry, SCENE_DOMAIN)
|
assert forward_entry_setup.mock_calls[7][1] == (config_entry, SCENE_DOMAIN)
|
||||||
assert forward_entry_setup.mock_calls[8][1] == (config_entry, SENSOR_DOMAIN)
|
assert forward_entry_setup.mock_calls[8][1] == (config_entry, SENSOR_DOMAIN)
|
||||||
assert forward_entry_setup.mock_calls[9][1] == (config_entry, SWITCH_DOMAIN)
|
assert forward_entry_setup.mock_calls[9][1] == (config_entry, SIREN_DOMAIN)
|
||||||
|
assert forward_entry_setup.mock_calls[10][1] == (config_entry, SWITCH_DOMAIN)
|
||||||
|
|
||||||
|
|
||||||
async def test_gateway_retry(hass):
|
async def test_gateway_retry(hass):
|
||||||
|
132
tests/components/deconz/test_siren.py
Normal file
132
tests/components/deconz/test_siren.py
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
"""deCONZ switch platform tests."""
|
||||||
|
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from homeassistant.components.deconz.const import DOMAIN as DECONZ_DOMAIN
|
||||||
|
from homeassistant.components.siren import ATTR_DURATION, DOMAIN as SIREN_DOMAIN
|
||||||
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_ENTITY_ID,
|
||||||
|
SERVICE_TURN_OFF,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
|
)
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
|
from .test_gateway import (
|
||||||
|
DECONZ_WEB_REQUEST,
|
||||||
|
mock_deconz_put_request,
|
||||||
|
setup_deconz_integration,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sirens(hass, aioclient_mock, mock_deconz_websocket):
|
||||||
|
"""Test that siren entities are created."""
|
||||||
|
data = {
|
||||||
|
"lights": {
|
||||||
|
"1": {
|
||||||
|
"name": "Warning device",
|
||||||
|
"type": "Warning device",
|
||||||
|
"state": {"alert": "lselect", "reachable": True},
|
||||||
|
"uniqueid": "00:00:00:00:00:00:00:00-00",
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "Unsupported siren",
|
||||||
|
"type": "Not a siren",
|
||||||
|
"state": {"reachable": True},
|
||||||
|
"uniqueid": "00:00:00:00:00:00:00:01-00",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
with patch.dict(DECONZ_WEB_REQUEST, data):
|
||||||
|
config_entry = await setup_deconz_integration(hass, aioclient_mock)
|
||||||
|
|
||||||
|
assert len(hass.states.async_all()) == 2
|
||||||
|
assert hass.states.get("siren.warning_device").state == STATE_ON
|
||||||
|
assert not hass.states.get("siren.unsupported_siren")
|
||||||
|
|
||||||
|
event_changed_light = {
|
||||||
|
"t": "event",
|
||||||
|
"e": "changed",
|
||||||
|
"r": "lights",
|
||||||
|
"id": "1",
|
||||||
|
"state": {"alert": None},
|
||||||
|
}
|
||||||
|
await mock_deconz_websocket(data=event_changed_light)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get("siren.warning_device").state == STATE_OFF
|
||||||
|
|
||||||
|
# Verify service calls
|
||||||
|
|
||||||
|
mock_deconz_put_request(aioclient_mock, config_entry.data, "/lights/1/state")
|
||||||
|
|
||||||
|
# Service turn on siren
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
SIREN_DOMAIN,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
{ATTR_ENTITY_ID: "siren.warning_device"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert aioclient_mock.mock_calls[1][2] == {"alert": "lselect"}
|
||||||
|
|
||||||
|
# Service turn off siren
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
SIREN_DOMAIN,
|
||||||
|
SERVICE_TURN_OFF,
|
||||||
|
{ATTR_ENTITY_ID: "siren.warning_device"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert aioclient_mock.mock_calls[2][2] == {"alert": "none"}
|
||||||
|
|
||||||
|
# Service turn on siren with duration
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
SIREN_DOMAIN,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
{ATTR_ENTITY_ID: "siren.warning_device", ATTR_DURATION: 10},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert aioclient_mock.mock_calls[3][2] == {"alert": "lselect", "ontime": 100}
|
||||||
|
|
||||||
|
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||||
|
|
||||||
|
states = hass.states.async_all()
|
||||||
|
assert len(states) == 2
|
||||||
|
for state in states:
|
||||||
|
assert state.state == STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
await hass.config_entries.async_remove(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(hass.states.async_all()) == 0
|
||||||
|
|
||||||
|
|
||||||
|
async def test_remove_legacy_siren_switch(hass, aioclient_mock):
|
||||||
|
"""Test that switch platform cleans up legacy siren entities."""
|
||||||
|
unique_id = "00:00:00:00:00:00:00:00-00"
|
||||||
|
|
||||||
|
registry = er.async_get(hass)
|
||||||
|
switch_siren_entity = registry.async_get_or_create(
|
||||||
|
SWITCH_DOMAIN, DECONZ_DOMAIN, unique_id
|
||||||
|
)
|
||||||
|
|
||||||
|
assert switch_siren_entity
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"lights": {
|
||||||
|
"1": {
|
||||||
|
"name": "Warning device",
|
||||||
|
"type": "Warning device",
|
||||||
|
"state": {"alert": "lselect", "reachable": True},
|
||||||
|
"uniqueid": unique_id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
with patch.dict(DECONZ_WEB_REQUEST, data):
|
||||||
|
await setup_deconz_integration(hass, aioclient_mock)
|
||||||
|
|
||||||
|
assert not registry.async_get(switch_siren_entity.entity_id)
|
@ -107,76 +107,3 @@ async def test_power_plugs(hass, aioclient_mock, mock_deconz_websocket):
|
|||||||
await hass.config_entries.async_remove(config_entry.entry_id)
|
await hass.config_entries.async_remove(config_entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(hass.states.async_all()) == 0
|
assert len(hass.states.async_all()) == 0
|
||||||
|
|
||||||
|
|
||||||
async def test_sirens(hass, aioclient_mock, mock_deconz_websocket):
|
|
||||||
"""Test that siren entities are created."""
|
|
||||||
data = {
|
|
||||||
"lights": {
|
|
||||||
"1": {
|
|
||||||
"name": "Warning device",
|
|
||||||
"type": "Warning device",
|
|
||||||
"state": {"alert": "lselect", "reachable": True},
|
|
||||||
"uniqueid": "00:00:00:00:00:00:00:00-00",
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"name": "Unsupported switch",
|
|
||||||
"type": "Not a switch",
|
|
||||||
"state": {"reachable": True},
|
|
||||||
"uniqueid": "00:00:00:00:00:00:00:01-00",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
with patch.dict(DECONZ_WEB_REQUEST, data):
|
|
||||||
config_entry = await setup_deconz_integration(hass, aioclient_mock)
|
|
||||||
|
|
||||||
assert len(hass.states.async_all()) == 2
|
|
||||||
assert hass.states.get("switch.warning_device").state == STATE_ON
|
|
||||||
assert not hass.states.get("switch.unsupported_switch")
|
|
||||||
|
|
||||||
event_changed_light = {
|
|
||||||
"t": "event",
|
|
||||||
"e": "changed",
|
|
||||||
"r": "lights",
|
|
||||||
"id": "1",
|
|
||||||
"state": {"alert": None},
|
|
||||||
}
|
|
||||||
await mock_deconz_websocket(data=event_changed_light)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert hass.states.get("switch.warning_device").state == STATE_OFF
|
|
||||||
|
|
||||||
# Verify service calls
|
|
||||||
|
|
||||||
mock_deconz_put_request(aioclient_mock, config_entry.data, "/lights/1/state")
|
|
||||||
|
|
||||||
# Service turn on siren
|
|
||||||
|
|
||||||
await hass.services.async_call(
|
|
||||||
SWITCH_DOMAIN,
|
|
||||||
SERVICE_TURN_ON,
|
|
||||||
{ATTR_ENTITY_ID: "switch.warning_device"},
|
|
||||||
blocking=True,
|
|
||||||
)
|
|
||||||
assert aioclient_mock.mock_calls[1][2] == {"alert": "lselect"}
|
|
||||||
|
|
||||||
# Service turn off siren
|
|
||||||
|
|
||||||
await hass.services.async_call(
|
|
||||||
SWITCH_DOMAIN,
|
|
||||||
SERVICE_TURN_OFF,
|
|
||||||
{ATTR_ENTITY_ID: "switch.warning_device"},
|
|
||||||
blocking=True,
|
|
||||||
)
|
|
||||||
assert aioclient_mock.mock_calls[2][2] == {"alert": "none"}
|
|
||||||
|
|
||||||
await hass.config_entries.async_unload(config_entry.entry_id)
|
|
||||||
|
|
||||||
states = hass.states.async_all()
|
|
||||||
assert len(states) == 2
|
|
||||||
for state in states:
|
|
||||||
assert state.state == STATE_UNAVAILABLE
|
|
||||||
|
|
||||||
await hass.config_entries.async_remove(config_entry.entry_id)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
assert len(hass.states.async_all()) == 0
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user