Integrations v2.1: Virtual integrations (#80613)

This commit is contained in:
Franck Nijhof
2022-10-21 05:09:06 +02:00
committed by GitHub
parent 6c23de94e1
commit bb287dd0ed
66 changed files with 2968 additions and 2720 deletions

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from pathlib import Path
from typing import Any
from urllib.parse import urlparse
from awesomeversion import (
@@ -158,7 +159,7 @@ def verify_wildcard(value: str):
return value
MANIFEST_SCHEMA = vol.Schema(
INTEGRATION_MANIFEST_SCHEMA = vol.Schema(
{
vol.Required("domain"): str,
vol.Required("name"): str,
@@ -254,14 +255,32 @@ MANIFEST_SCHEMA = vol.Schema(
vol.Optional("loggers"): [str],
vol.Optional("disabled"): str,
vol.Optional("iot_class"): vol.In(SUPPORTED_IOT_CLASSES),
vol.Optional("supported_brands"): vol.Schema({str: str}),
}
)
CUSTOM_INTEGRATION_MANIFEST_SCHEMA = MANIFEST_SCHEMA.extend(
VIRTUAL_INTEGRATION_MANIFEST_SCHEMA = vol.Schema(
{
vol.Required("domain"): str,
vol.Required("name"): str,
vol.Required("integration_type"): "virtual",
vol.Exclusive("iot_standard", "virtual_integration"): vol.Any(
"homekit", "zigbee", "zwave"
),
vol.Exclusive("supported_by", "virtual_integration"): str,
}
)
def manifest_schema(value: dict[str, Any]) -> vol.Schema:
"""Validate integration manifest."""
if value.get("integration_type") == "virtual":
return VIRTUAL_INTEGRATION_MANIFEST_SCHEMA(value)
return INTEGRATION_MANIFEST_SCHEMA(value)
CUSTOM_INTEGRATION_MANIFEST_SCHEMA = INTEGRATION_MANIFEST_SCHEMA.extend(
{
vol.Optional("version"): vol.All(str, verify_version),
vol.Remove("supported_brands"): dict,
}
)
@@ -284,7 +303,7 @@ def validate_manifest(integration: Integration, core_components_dir: Path) -> No
try:
if integration.core:
MANIFEST_SCHEMA(integration.manifest)
manifest_schema(integration.manifest)
else:
CUSTOM_INTEGRATION_MANIFEST_SCHEMA(integration.manifest)
except vol.Invalid as err:
@@ -312,15 +331,19 @@ def validate_manifest(integration: Integration, core_components_dir: Path) -> No
if (
integration.manifest["domain"] not in NO_IOT_CLASS
and "iot_class" not in integration.manifest
and integration.manifest.get("integration_type") != "virtual"
):
integration.add_error("manifest", "Domain is missing an IoT Class")
for domain, _name in integration.manifest.get("supported_brands", {}).items():
if (core_components_dir / domain).exists():
integration.add_warning(
"manifest",
f"Supported brand domain {domain} collides with built-in core integration",
)
if (
integration.manifest.get("integration_type") == "virtual"
and (supported_by := integration.manifest.get("supported_by"))
and not (core_components_dir / supported_by).exists()
):
integration.add_error(
"manifest",
"Virtual integration points to non-existing supported_by integration",
)
if not integration.core:
validate_version(integration)