From fbb8ff43626e2cfb524a5397f31716b77d16b8ae Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Wed, 19 Oct 2022 12:41:57 +0200 Subject: [PATCH] Integrations v2.1: compatibility with hubs, devices and services (#14114) --- src/components/ha-config-entry-picker.ts | 2 +- src/data/config_entries.ts | 11 +++++++++-- src/data/config_flow.ts | 4 ++-- src/data/integration.ts | 4 +++- src/onboarding/onboarding-integrations.ts | 4 +++- .../energy/dialogs/dialog-energy-solar-settings.ts | 4 ++-- .../config/entities/entity-registry-settings.ts | 2 +- src/panels/config/helpers/dialog-helper-detail.ts | 2 +- src/panels/config/helpers/ha-config-helpers.ts | 13 +++++++------ .../config/integrations/ha-config-integrations.ts | 10 +++++++--- 10 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/components/ha-config-entry-picker.ts b/src/components/ha-config-entry-picker.ts index 0f98d18d49..733598b003 100644 --- a/src/components/ha-config-entry-picker.ts +++ b/src/components/ha-config-entry-picker.ts @@ -105,7 +105,7 @@ class HaConfigEntryPicker extends LitElement { private async _getConfigEntries() { getConfigEntries(this.hass, { - type: "integration", + type: ["device", "hub", "service"], domain: this.integration, }).then((configEntries) => { this._configEntries = configEntries diff --git a/src/data/config_entries.ts b/src/data/config_entries.ts index 42124f53d6..9a13ecbbca 100644 --- a/src/data/config_entries.ts +++ b/src/data/config_entries.ts @@ -1,5 +1,6 @@ import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { HomeAssistant } from "../types"; +import { integrationType } from "./integration"; export interface ConfigEntry { entry_id: string; @@ -54,7 +55,10 @@ export interface ConfigEntryUpdate { export const subscribeConfigEntries = ( hass: HomeAssistant, callbackFunction: (message: ConfigEntryUpdate[]) => void, - filters?: { type?: "helper" | "integration"; domain?: string } + filters?: { + type?: Array; + domain?: string; + } ): Promise => { const params: any = { type: "config_entries/subscribe", @@ -70,7 +74,10 @@ export const subscribeConfigEntries = ( export const getConfigEntries = ( hass: HomeAssistant, - filters?: { type?: "helper" | "integration"; domain?: string } + filters?: { + type?: Array; + domain?: string; + } ): Promise => { const params: any = {}; if (filters) { diff --git a/src/data/config_flow.ts b/src/data/config_flow.ts index 001b321dce..a1b7bfab37 100644 --- a/src/data/config_flow.ts +++ b/src/data/config_flow.ts @@ -3,7 +3,7 @@ import { LocalizeFunc } from "../common/translations/localize"; import { debounce } from "../common/util/debounce"; import { HomeAssistant } from "../types"; import { DataEntryFlowProgress, DataEntryFlowStep } from "./data_entry_flow"; -import { domainToName } from "./integration"; +import { domainToName, integrationType } from "./integration"; export const DISCOVERY_SOURCES = [ "bluetooth", @@ -68,7 +68,7 @@ export const deleteConfigFlow = (hass: HomeAssistant, flowId: string) => export const getConfigFlowHandlers = ( hass: HomeAssistant, - type?: "helper" | "integration" + type?: Array ) => hass.callApi( "GET", diff --git a/src/data/integration.ts b/src/data/integration.ts index 1f99f5478d..d878ef1e17 100644 --- a/src/data/integration.ts +++ b/src/data/integration.ts @@ -1,6 +1,8 @@ import { LocalizeFunc } from "../common/translations/localize"; import { HomeAssistant } from "../types"; +export type integrationType = "device" | "helper" | "hub" | "service"; + export interface IntegrationManifest { is_built_in: boolean; domain: string; @@ -15,6 +17,7 @@ export interface IntegrationManifest { ssdp?: Array<{ manufacturer?: string; modelName?: string; st?: string }>; zeroconf?: string[]; homekit?: { models: string[] }; + integration_type?: integrationType; quality_scale?: "gold" | "internal" | "platinum" | "silver"; iot_class: | "assumed_state" @@ -23,7 +26,6 @@ export interface IntegrationManifest { | "local_polling" | "local_push"; } - export interface IntegrationSetup { domain: string; seconds?: number; diff --git a/src/onboarding/onboarding-integrations.ts b/src/onboarding/onboarding-integrations.ts index ff89d020c0..263ce23108 100644 --- a/src/onboarding/onboarding-integrations.ts +++ b/src/onboarding/onboarding-integrations.ts @@ -180,7 +180,9 @@ class OnboardingIntegrations extends LitElement { } private async _loadConfigEntries() { - const entries = await getConfigEntries(this.hass!, { type: "integration" }); + const entries = await getConfigEntries(this.hass!, { + type: ["device", "hub", "service"], + }); // We filter out the config entries that are automatically created during onboarding. // It is one that we create automatically and it will confuse the user // if it starts showing up during onboarding. diff --git a/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts index d6636687b5..d6ebd03533 100644 --- a/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts +++ b/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts @@ -179,10 +179,10 @@ export class DialogEnergySolarSettings ? [] : domains.length === 1 ? await getConfigEntries(this.hass, { - type: "integration", + type: ["service"], domain: domains[0], }) - : (await getConfigEntries(this.hass, { type: "integration" })).filter( + : (await getConfigEntries(this.hass, { type: ["service"] })).filter( (entry) => domains.includes(entry.domain) ); } diff --git a/src/panels/config/entities/entity-registry-settings.ts b/src/panels/config/entities/entity-registry-settings.ts index e87fd4ea02..0b9731e5a2 100644 --- a/src/panels/config/entities/entity-registry-settings.ts +++ b/src/panels/config/entities/entity-registry-settings.ts @@ -201,7 +201,7 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) { super.firstUpdated(changedProps); if (this.entry.config_entry_id) { getConfigEntries(this.hass, { - type: "helper", + type: ["helper"], domain: this.entry.platform, }).then((entries) => { this._helperConfigEntry = entries.find( diff --git a/src/panels/config/helpers/dialog-helper-detail.ts b/src/panels/config/helpers/dialog-helper-detail.ts index 7f4b0a488a..672f40a26e 100644 --- a/src/panels/config/helpers/dialog-helper-detail.ts +++ b/src/panels/config/helpers/dialog-helper-detail.ts @@ -76,7 +76,7 @@ export class DialogHelperDetail extends LitElement { this._opened = true; await this.updateComplete; Promise.all([ - getConfigFlowHandlers(this.hass, "helper"), + getConfigFlowHandlers(this.hass, ["helper"]), // Ensure the titles are loaded before we render the flows. this.hass.loadBackendTranslation("title", undefined, true), ]).then(([flows]) => { diff --git a/src/panels/config/helpers/ha-config-helpers.ts b/src/panels/config/helpers/ha-config-helpers.ts index e77202eb6c..4861cffa72 100644 --- a/src/panels/config/helpers/ha-config-helpers.ts +++ b/src/panels/config/helpers/ha-config-helpers.ts @@ -249,13 +249,14 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) { }); return; } - const handlers = await getConfigFlowHandlers(this.hass, "helper"); + const handlers = await getConfigFlowHandlers(this.hass, ["helper"]); if (!handlers.includes(domain)) { - const integrations = await getConfigFlowHandlers( - this.hass, - "integration" - ); + const integrations = await getConfigFlowHandlers(this.hass, [ + "device", + "hub", + "service", + ]); if (integrations.includes(domain)) { navigate(`/config/integrations/add?domain=${domain}`, { replace: true, @@ -350,7 +351,7 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) { private async _getConfigEntries() { this._configEntries = groupByOne( - await getConfigEntries(this.hass, { type: "helper" }), + await getConfigEntries(this.hass, { type: ["helper"] }), (entry) => entry.entry_id ); } diff --git a/src/panels/config/integrations/ha-config-integrations.ts b/src/panels/config/integrations/ha-config-integrations.ts index 7e5b1b1646..18cf0bd7ff 100644 --- a/src/panels/config/integrations/ha-config-integrations.ts +++ b/src/panels/config/integrations/ha-config-integrations.ts @@ -228,7 +228,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { ) ); }, - { type: "integration" } + { type: ["device", "hub", "service"] } ), ]; } @@ -693,7 +693,11 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { return; } - const handlers = await getConfigFlowHandlers(this.hass, "integration"); + const handlers = await getConfigFlowHandlers(this.hass, [ + "device", + "hub", + "service", + ]); // Integration exists, so we can just create a flow if (handlers.includes(domain)) { @@ -760,7 +764,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) { }); return; } - const helpers = await getConfigFlowHandlers(this.hass, "helper"); + const helpers = await getConfigFlowHandlers(this.hass, ["helper"]); if (helpers.includes(domain)) { navigate(`/config/helpers/add?domain=${domain}`, { replace: true,