Add WS command cloud/alexa/entities/get (#92121)

* Add WS command cloud/alexa/entities/get

* Fix bugs, add test
This commit is contained in:
Erik Montnemery 2023-04-27 17:10:29 +02:00 committed by GitHub
parent 3aa82e122c
commit 2522c6d697
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 3 deletions

View File

@ -94,7 +94,7 @@ SUPPORTED_SENSOR_DEVICE_CLASSES = {
} }
def _supported_legacy(hass: HomeAssistant, entity_id: str) -> bool: def entity_supported(hass: HomeAssistant, entity_id: str) -> bool:
"""Return if the entity is supported. """Return if the entity is supported.
This is called when migrating from legacy config format to avoid exposing This is called when migrating from legacy config format to avoid exposing
@ -249,12 +249,12 @@ class CloudAlexaConfig(alexa_config.AbstractConfig):
# Backwards compat # Backwards compat
if (default_expose := self._prefs.alexa_default_expose) is None: if (default_expose := self._prefs.alexa_default_expose) is None:
return not auxiliary_entity and _supported_legacy(self.hass, entity_id) return not auxiliary_entity and entity_supported(self.hass, entity_id)
return ( return (
not auxiliary_entity not auxiliary_entity
and split_entity_id(entity_id)[0] in default_expose and split_entity_id(entity_id)[0] in default_expose
and _supported_legacy(self.hass, entity_id) and entity_supported(self.hass, entity_id)
) )
def should_expose(self, entity_id): def should_expose(self, entity_id):

View File

@ -29,6 +29,7 @@ from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util.location import async_detect_location_info from homeassistant.util.location import async_detect_location_info
from .alexa_config import entity_supported as entity_supported_by_alexa
from .const import ( from .const import (
DOMAIN, DOMAIN,
PREF_ALEXA_REPORT_STATE, PREF_ALEXA_REPORT_STATE,
@ -73,6 +74,7 @@ async def async_setup(hass):
websocket_api.async_register_command(hass, google_assistant_list) websocket_api.async_register_command(hass, google_assistant_list)
websocket_api.async_register_command(hass, google_assistant_update) websocket_api.async_register_command(hass, google_assistant_update)
websocket_api.async_register_command(hass, alexa_get)
websocket_api.async_register_command(hass, alexa_list) websocket_api.async_register_command(hass, alexa_list)
websocket_api.async_register_command(hass, alexa_sync) websocket_api.async_register_command(hass, alexa_sync)
@ -668,6 +670,46 @@ async def google_assistant_update(
connection.send_result(msg["id"]) connection.send_result(msg["id"])
@websocket_api.require_admin
@_require_cloud_login
@websocket_api.websocket_command(
{
"type": "cloud/alexa/entities/get",
"entity_id": str,
}
)
@websocket_api.async_response
@_ws_handle_cloud_errors
async def alexa_get(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Get data for a single alexa entity."""
entity_registry = er.async_get(hass)
entity_id: str = msg["entity_id"]
if not entity_registry.async_is_registered(entity_id):
connection.send_error(
msg["id"],
websocket_api.const.ERR_NOT_FOUND,
f"{entity_id} not in the entity registry",
)
return
if entity_id in CLOUD_NEVER_EXPOSED_ENTITIES or not entity_supported_by_alexa(
hass, entity_id
):
connection.send_error(
msg["id"],
websocket_api.const.ERR_NOT_SUPPORTED,
f"{entity_id} not supported by Alexa",
)
return
connection.send_result(msg["id"])
@websocket_api.require_admin @websocket_api.require_admin
@_require_cloud_login @_require_cloud_login
@websocket_api.websocket_command({"type": "cloud/alexa/entities"}) @websocket_api.websocket_command({"type": "cloud/alexa/entities"})

View File

@ -938,6 +938,67 @@ async def test_list_alexa_entities(
} }
async def test_get_alexa_entity(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
hass_ws_client: WebSocketGenerator,
setup_api,
mock_cloud_login,
) -> None:
"""Test that we can get an Alexa entity."""
client = await hass_ws_client(hass)
# Test getting an unknown entity
await client.send_json_auto_id(
{"type": "cloud/alexa/entities/get", "entity_id": "light.kitchen"}
)
response = await client.receive_json()
assert not response["success"]
assert response["error"] == {
"code": "not_found",
"message": "light.kitchen not in the entity registry",
}
# Test getting a blocked entity
entity_registry.async_get_or_create(
"group", "test", "unique", suggested_object_id="all_locks"
)
hass.states.async_set("group.all_locks", "bla")
await client.send_json_auto_id(
{"type": "cloud/alexa/entities/get", "entity_id": "group.all_locks"}
)
response = await client.receive_json()
assert not response["success"]
assert response["error"] == {
"code": "not_supported",
"message": "group.all_locks not supported by Alexa",
}
entity_registry.async_get_or_create(
"light", "test", "unique", suggested_object_id="kitchen"
)
entity_registry.async_get_or_create(
"water_heater", "test", "unique", suggested_object_id="basement"
)
await client.send_json_auto_id(
{"type": "cloud/alexa/entities/get", "entity_id": "light.kitchen"}
)
response = await client.receive_json()
assert response["success"]
assert response["result"] is None
await client.send_json_auto_id(
{"type": "cloud/alexa/entities/get", "entity_id": "water_heater.basement"}
)
response = await client.receive_json()
assert not response["success"]
assert response["error"] == {
"code": "not_supported",
"message": "water_heater.basement not supported by Alexa",
}
async def test_update_alexa_entity( async def test_update_alexa_entity(
hass: HomeAssistant, hass: HomeAssistant,
entity_registry: er.EntityRegistry, entity_registry: er.EntityRegistry,