Add websocket list APIs for the registries (#16597)

* Add websocket list APIs for the registries

* Remove identifiers

* Fix tests

* Use ordered dict
This commit is contained in:
Paulus Schoutsen 2018-09-14 11:57:18 +02:00 committed by GitHub
parent 67b5b5bc85
commit 05c0717167
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 210 additions and 19 deletions

View file

@ -13,8 +13,17 @@ from homeassistant.util.yaml import load_yaml, dump
DOMAIN = 'config'
DEPENDENCIES = ['http']
SECTIONS = ('core', 'customize', 'group', 'hassbian', 'automation', 'script',
'entity_registry', 'config_entries')
SECTIONS = (
'automation',
'config_entries',
'core',
'customize',
'device_registry',
'entity_registry',
'group',
'hassbian',
'script',
)
ON_DEMAND = ('zwave',)

View file

@ -0,0 +1,46 @@
"""HTTP views to interact with the device registry."""
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.helpers.device_registry import async_get_registry
from homeassistant.components import websocket_api
DEPENDENCIES = ['websocket_api']
WS_TYPE_LIST = 'config/device_registry/list'
SCHEMA_WS_LIST = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_LIST,
})
async def async_setup(hass):
"""Enable the Entity Registry views."""
hass.components.websocket_api.async_register_command(
WS_TYPE_LIST, websocket_list_devices,
SCHEMA_WS_LIST
)
return True
@callback
def websocket_list_devices(hass, connection, msg):
"""Handle list devices command.
Async friendly.
"""
async def retrieve_entities():
"""Get devices from registry."""
registry = await async_get_registry(hass)
connection.send_message_outside(websocket_api.result_message(
msg['id'], [{
'config_entries': list(entry.config_entries),
'connections': list(entry.connections),
'manufacturer': entry.manufacturer,
'model': entry.model,
'name': entry.name,
'sw_version': entry.sw_version,
'id': entry.id,
} for entry in registry.devices.values()]
))
hass.async_add_job(retrieve_entities())

View file

@ -8,6 +8,11 @@ from homeassistant.helpers import config_validation as cv
DEPENDENCIES = ['websocket_api']
WS_TYPE_LIST = 'config/entity_registry/list'
SCHEMA_WS_LIST = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_LIST,
})
WS_TYPE_GET = 'config/entity_registry/get'
SCHEMA_WS_GET = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_GET,
@ -26,6 +31,10 @@ SCHEMA_WS_UPDATE = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
async def async_setup(hass):
"""Enable the Entity Registry views."""
hass.components.websocket_api.async_register_command(
WS_TYPE_LIST, websocket_list_entities,
SCHEMA_WS_LIST
)
hass.components.websocket_api.async_register_command(
WS_TYPE_GET, websocket_get_entity,
SCHEMA_WS_GET
@ -37,6 +46,29 @@ async def async_setup(hass):
return True
@callback
def websocket_list_entities(hass, connection, msg):
"""Handle list registry entries command.
Async friendly.
"""
async def retrieve_entities():
"""Get entities from registry."""
registry = await async_get_registry(hass)
connection.send_message_outside(websocket_api.result_message(
msg['id'], [{
'config_entry_id': entry.config_entry_id,
'device_id': entry.device_id,
'disabled_by': entry.disabled_by,
'entity_id': entry.entity_id,
'name': entry.name,
'platform': entry.platform,
} for entry in registry.entities.values()]
))
hass.async_add_job(retrieve_entities())
@callback
def websocket_get_entity(hass, connection, msg):
"""Handle get entity registry entry command.

View file

@ -19,7 +19,7 @@ from homeassistant.setup import setup_component, async_setup_component
from homeassistant.config import async_process_component_config
from homeassistant.helpers import (
intent, entity, restore_state, entity_registry,
entity_platform, storage)
entity_platform, storage, device_registry)
from homeassistant.util.unit_system import METRIC_SYSTEM
import homeassistant.util.dt as date_util
import homeassistant.util.yaml as yaml
@ -332,6 +332,19 @@ def mock_registry(hass, mock_entries=None):
return registry
def mock_device_registry(hass, mock_entries=None):
"""Mock the Device Registry."""
registry = device_registry.DeviceRegistry(hass)
registry.devices = mock_entries or OrderedDict()
async def _get_reg():
return registry
hass.data[device_registry.DATA_REGISTRY] = \
hass.loop.create_task(_get_reg())
return registry
class MockUser(auth_models.User):
"""Mock a user in Home Assistant."""

View file

@ -0,0 +1,60 @@
"""Test entity_registry API."""
import pytest
from homeassistant.components.config import device_registry
from tests.common import mock_device_registry
@pytest.fixture
def client(hass, hass_ws_client):
"""Fixture that can interact with the config manager API."""
hass.loop.run_until_complete(device_registry.async_setup(hass))
yield hass.loop.run_until_complete(hass_ws_client(hass))
@pytest.fixture
def registry(hass):
"""Return an empty, loaded, registry."""
return mock_device_registry(hass)
async def test_list_devices(hass, client, registry):
"""Test list entries."""
registry.async_get_or_create(
config_entry='1234',
connections={('ethernet', '12:34:56:78:90:AB:CD:EF')},
identifiers={('bridgeid', '0123')},
manufacturer='manufacturer', model='model')
registry.async_get_or_create(
config_entry='1234',
connections={},
identifiers={('bridgeid', '1234')},
manufacturer='manufacturer', model='model')
await client.send_json({
'id': 5,
'type': 'config/device_registry/list',
})
msg = await client.receive_json()
for entry in msg['result']:
entry.pop('id')
assert msg['result'] == [
{
'config_entries': ['1234'],
'connections': [['ethernet', '12:34:56:78:90:AB:CD:EF']],
'manufacturer': 'manufacturer',
'model': 'model',
'name': None,
'sw_version': None
},
{
'config_entries': ['1234'],
'connections': [],
'manufacturer': 'manufacturer',
'model': 'model',
'name': None,
'sw_version': None
}
]

View file

@ -1,4 +1,6 @@
"""Test entity_registry API."""
from collections import OrderedDict
import pytest
from homeassistant.helpers.entity_registry import RegistryEntry
@ -13,6 +15,49 @@ def client(hass, hass_ws_client):
yield hass.loop.run_until_complete(hass_ws_client(hass))
async def test_list_entities(hass, client):
"""Test list entries."""
entities = OrderedDict()
entities['test_domain.name'] = RegistryEntry(
entity_id='test_domain.name',
unique_id='1234',
platform='test_platform',
name='Hello World'
)
entities['test_domain.no_name'] = RegistryEntry(
entity_id='test_domain.no_name',
unique_id='6789',
platform='test_platform',
)
mock_registry(hass, entities)
await client.send_json({
'id': 5,
'type': 'config/entity_registry/list',
})
msg = await client.receive_json()
assert msg['result'] == [
{
'config_entry_id': None,
'device_id': None,
'disabled_by': None,
'entity_id': 'test_domain.name',
'name': 'Hello World',
'platform': 'test_platform',
},
{
'config_entry_id': None,
'device_id': None,
'disabled_by': None,
'entity_id': 'test_domain.no_name',
'name': None,
'platform': 'test_platform',
}
]
async def test_get_entity(hass, client):
"""Test get entry."""
mock_registry(hass, {

View file

@ -1,28 +1,14 @@
"""Tests for the Device Registry."""
import pytest
from collections import OrderedDict
from homeassistant.helpers import device_registry
def mock_registry(hass, mock_entries=None):
"""Mock the Device Registry."""
registry = device_registry.DeviceRegistry(hass)
registry.devices = mock_entries or OrderedDict()
async def _get_reg():
return registry
hass.data[device_registry.DATA_REGISTRY] = \
hass.loop.create_task(_get_reg())
return registry
from tests.common import mock_device_registry
@pytest.fixture
def registry(hass):
"""Return an empty, loaded, registry."""
return mock_registry(hass)
return mock_device_registry(hass)
async def test_get_or_create_returns_same_entry(registry):