mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Expose supported brands via API (#75074)
This commit is contained in:
parent
b54fe14a10
commit
41ec8cd354
@ -21,7 +21,7 @@ repos:
|
||||
- --skip="./.*,*.csv,*.json"
|
||||
- --quiet-level=2
|
||||
exclude_types: [csv, json]
|
||||
exclude: ^tests/fixtures/
|
||||
exclude: ^tests/fixtures/|homeassistant/generated/
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 4.0.1
|
||||
hooks:
|
||||
|
@ -22,6 +22,7 @@ from homeassistant.exceptions import (
|
||||
TemplateError,
|
||||
Unauthorized,
|
||||
)
|
||||
from homeassistant.generated import supported_brands
|
||||
from homeassistant.helpers import config_validation as cv, entity, template
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.event import (
|
||||
@ -68,6 +69,7 @@ def async_register_commands(
|
||||
async_reg(hass, handle_unsubscribe_events)
|
||||
async_reg(hass, handle_validate_config)
|
||||
async_reg(hass, handle_subscribe_entities)
|
||||
async_reg(hass, handle_supported_brands)
|
||||
|
||||
|
||||
def pong_message(iden: int) -> dict[str, Any]:
|
||||
@ -691,3 +693,25 @@ async def handle_validate_config(
|
||||
result[key] = {"valid": True, "error": None}
|
||||
|
||||
connection.send_result(msg["id"], result)
|
||||
|
||||
|
||||
@decorators.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "supported_brands",
|
||||
}
|
||||
)
|
||||
@decorators.async_response
|
||||
async def handle_supported_brands(
|
||||
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
|
||||
) -> None:
|
||||
"""Handle supported brands command."""
|
||||
data = {}
|
||||
for integration in await asyncio.gather(
|
||||
*[
|
||||
async_get_integration(hass, integration)
|
||||
for integration in supported_brands.HAS_SUPPORTED_BRANDS
|
||||
]
|
||||
):
|
||||
data[integration.domain] = integration.manifest["supported_brands"]
|
||||
|
||||
connection.send_result(msg["id"], data)
|
||||
|
15
homeassistant/generated/supported_brands.py
Normal file
15
homeassistant/generated/supported_brands.py
Normal file
@ -0,0 +1,15 @@
|
||||
"""Automatically generated by hassfest.
|
||||
|
||||
To update, run python3 -m script.hassfest
|
||||
"""
|
||||
|
||||
# fmt: off
|
||||
|
||||
HAS_SUPPORTED_BRANDS = (
|
||||
"denonavr",
|
||||
"hunterdouglas_powerview",
|
||||
"motion_blinds",
|
||||
"overkiz",
|
||||
"renault",
|
||||
"wemo"
|
||||
)
|
@ -20,6 +20,7 @@ from . import (
|
||||
requirements,
|
||||
services,
|
||||
ssdp,
|
||||
supported_brands,
|
||||
translations,
|
||||
usb,
|
||||
zeroconf,
|
||||
@ -39,6 +40,7 @@ INTEGRATION_PLUGINS = [
|
||||
requirements,
|
||||
services,
|
||||
ssdp,
|
||||
supported_brands,
|
||||
translations,
|
||||
usb,
|
||||
zeroconf,
|
||||
|
@ -112,6 +112,11 @@ class Integration:
|
||||
"""List of dependencies."""
|
||||
return self.manifest.get("dependencies", [])
|
||||
|
||||
@property
|
||||
def supported_brands(self) -> dict[str]:
|
||||
"""Return dict of supported brands."""
|
||||
return self.manifest.get("supported_brands", {})
|
||||
|
||||
@property
|
||||
def integration_type(self) -> str:
|
||||
"""Get integration_type."""
|
||||
|
55
script/hassfest/supported_brands.py
Normal file
55
script/hassfest/supported_brands.py
Normal file
@ -0,0 +1,55 @@
|
||||
"""Generate supported_brands data."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
from .model import Config, Integration
|
||||
|
||||
BASE = """
|
||||
\"\"\"Automatically generated by hassfest.
|
||||
|
||||
To update, run python3 -m script.hassfest
|
||||
\"\"\"
|
||||
|
||||
# fmt: off
|
||||
|
||||
HAS_SUPPORTED_BRANDS = ({})
|
||||
""".strip()
|
||||
|
||||
|
||||
def generate_and_validate(integrations: dict[str, Integration], config: Config) -> str:
|
||||
"""Validate and generate supported_brands data."""
|
||||
|
||||
brands = [
|
||||
domain
|
||||
for domain, integration in sorted(integrations.items())
|
||||
if integration.supported_brands
|
||||
]
|
||||
|
||||
return BASE.format(json.dumps(brands, indent=4)[1:-1])
|
||||
|
||||
|
||||
def validate(integrations: dict[str, Integration], config: Config) -> None:
|
||||
"""Validate supported_brands data."""
|
||||
supported_brands_path = config.root / "homeassistant/generated/supported_brands.py"
|
||||
config.cache["supported_brands"] = content = generate_and_validate(
|
||||
integrations, config
|
||||
)
|
||||
|
||||
if config.specific_integrations:
|
||||
return
|
||||
|
||||
if supported_brands_path.read_text(encoding="utf-8").strip() != content:
|
||||
config.add_error(
|
||||
"supported_brands",
|
||||
"File supported_brands.py is not up to date. Run python3 -m script.hassfest",
|
||||
fixable=True,
|
||||
)
|
||||
|
||||
|
||||
def generate(integrations: dict[str, Integration], config: Config):
|
||||
"""Generate supported_brands data."""
|
||||
supported_brands_path = config.root / "homeassistant/generated/supported_brands.py"
|
||||
supported_brands_path.write_text(
|
||||
f"{config.cache['supported_brands']}\n", encoding="utf-8"
|
||||
)
|
@ -22,7 +22,13 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
from homeassistant.loader import async_get_integration
|
||||
from homeassistant.setup import DATA_SETUP_TIME, async_setup_component
|
||||
|
||||
from tests.common import MockEntity, MockEntityPlatform, async_mock_service
|
||||
from tests.common import (
|
||||
MockEntity,
|
||||
MockEntityPlatform,
|
||||
MockModule,
|
||||
async_mock_service,
|
||||
mock_integration,
|
||||
)
|
||||
|
||||
STATE_KEY_SHORT_NAMES = {
|
||||
"entity_id": "e",
|
||||
@ -1749,3 +1755,36 @@ async def test_validate_config_invalid(websocket_client, key, config, error):
|
||||
assert msg["type"] == const.TYPE_RESULT
|
||||
assert msg["success"]
|
||||
assert msg["result"] == {key: {"valid": False, "error": error}}
|
||||
|
||||
|
||||
async def test_supported_brands(hass, websocket_client):
|
||||
"""Test supported brands."""
|
||||
mock_integration(
|
||||
hass,
|
||||
MockModule("test", partial_manifest={"supported_brands": {"hello": "World"}}),
|
||||
)
|
||||
mock_integration(
|
||||
hass,
|
||||
MockModule(
|
||||
"abcd", partial_manifest={"supported_brands": {"something": "Something"}}
|
||||
),
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.generated.supported_brands.HAS_SUPPORTED_BRANDS",
|
||||
("abcd", "test"),
|
||||
):
|
||||
await websocket_client.send_json({"id": 7, "type": "supported_brands"})
|
||||
msg = await websocket_client.receive_json()
|
||||
|
||||
assert msg["id"] == 7
|
||||
assert msg["type"] == const.TYPE_RESULT
|
||||
assert msg["success"]
|
||||
assert msg["result"] == {
|
||||
"abcd": {
|
||||
"something": "Something",
|
||||
},
|
||||
"test": {
|
||||
"hello": "World",
|
||||
},
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user