From f4211e3fa31a438978b52f5ec47501aa1c236d7b Mon Sep 17 00:00:00 2001 From: Zack Arnett Date: Thu, 19 Mar 2020 14:39:14 -0400 Subject: [PATCH] Find Entites: Filter Unavailable - Used and unused entities required (#5208) * Update Find Entities * lint * Filter until max - entitiesFill-> entitiesFallback * Comment - Move unav - unk filter to picker * lint * Var name update * remove unnessary check * add it back and fix logic * use typescript ? in condition * comments * lint * Compute used once * pass in hass * Return set * fix merge * Optimize unused entities in find --- .../lovelace/cards/hui-alarm-panel-card.ts | 9 +-- src/panels/lovelace/cards/hui-button-card.ts | 10 +-- .../lovelace/cards/hui-entities-card.ts | 9 +-- src/panels/lovelace/cards/hui-gauge-card.ts | 9 +-- src/panels/lovelace/cards/hui-glance-card.ts | 10 +-- .../lovelace/cards/hui-history-graph-card.ts | 9 +-- src/panels/lovelace/cards/hui-light-card.ts | 9 +-- src/panels/lovelace/cards/hui-map-card.ts | 9 +-- .../lovelace/cards/hui-media-control-card.ts | 9 +-- .../cards/hui-picture-elements-card.ts | 9 +-- .../lovelace/cards/hui-picture-entity-card.ts | 10 +-- .../lovelace/cards/hui-picture-glance-card.ts | 10 +-- .../lovelace/cards/hui-plant-status-card.ts | 9 +-- src/panels/lovelace/cards/hui-sensor-card.ts | 9 +-- .../lovelace/cards/hui-thermostat-card.ts | 9 +-- .../cards/hui-weather-forecast-card.ts | 9 +-- .../common/compute-unused-entities.ts | 31 ++++--- src/panels/lovelace/common/find-entites.ts | 81 +++++++++++-------- .../editor/card-editor/hui-card-picker.ts | 26 ++++-- .../lovelace/editor/get-card-stub-config.ts | 10 +-- .../unused-entities/hui-unused-entities.ts | 3 +- src/panels/lovelace/types.ts | 5 +- 22 files changed, 149 insertions(+), 155 deletions(-) diff --git a/src/panels/lovelace/cards/hui-alarm-panel-card.ts b/src/panels/lovelace/cards/hui-alarm-panel-card.ts index 6f7955d685..66e11ab72b 100644 --- a/src/panels/lovelace/cards/hui-alarm-panel-card.ts +++ b/src/panels/lovelace/cards/hui-alarm-panel-card.ts @@ -25,7 +25,6 @@ import { AlarmPanelCardConfig } from "./types"; import { PaperInputElement } from "@polymer/paper-input/paper-input"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { findEntities } from "../common/find-entites"; -import { LovelaceConfig } from "../../../data/lovelace"; import { fireEvent } from "../../../common/dom/fire_event"; const ICONS = { @@ -51,18 +50,16 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ) { const includeDomains = ["alarm_control_panel"]; const maxEntities = 1; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, includeDomains ); diff --git a/src/panels/lovelace/cards/hui-button-card.ts b/src/panels/lovelace/cards/hui-button-card.ts index 009d1172b3..7a988c30a3 100644 --- a/src/panels/lovelace/cards/hui-button-card.ts +++ b/src/panels/lovelace/cards/hui-button-card.ts @@ -30,7 +30,7 @@ import { ButtonCardConfig } from "./types"; import { actionHandler } from "../common/directives/action-handler-directive"; import { hasAction } from "../common/has-action"; import { handleAction } from "../common/handle-action"; -import { ActionHandlerEvent, LovelaceConfig } from "../../../data/lovelace"; +import { ActionHandlerEvent } from "../../../data/lovelace"; import { computeActiveState } from "../../../common/entity/compute_active_state"; import { iconColorCSS } from "../../../common/style/icon_color_css"; import { findEntities } from "../common/find-entites"; @@ -46,17 +46,15 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): object { const maxEntities = 1; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, ["light", "switch"] ); diff --git a/src/panels/lovelace/cards/hui-entities-card.ts b/src/panels/lovelace/cards/hui-entities-card.ts index a68b82e015..5175d256dd 100644 --- a/src/panels/lovelace/cards/hui-entities-card.ts +++ b/src/panels/lovelace/cards/hui-entities-card.ts @@ -27,7 +27,6 @@ import { createHeaderFooterElement } from "../create-element/create-header-foote import { LovelaceHeaderFooterConfig } from "../header-footer/types"; import { DOMAINS_TOGGLE } from "../../../common/const"; import { computeDomain } from "../../../common/entity/compute_domain"; -import { LovelaceConfig } from "../../../data/lovelace"; import { findEntities } from "../common/find-entites"; @customElement("hui-entities-card") @@ -41,17 +40,15 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ) { const maxEntities = 3; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, ["light", "switch", "sensor"] ); diff --git a/src/panels/lovelace/cards/hui-gauge-card.ts b/src/panels/lovelace/cards/hui-gauge-card.ts index ad79b717a5..b6a2cded8e 100644 --- a/src/panels/lovelace/cards/hui-gauge-card.ts +++ b/src/panels/lovelace/cards/hui-gauge-card.ts @@ -22,7 +22,6 @@ import { fireEvent } from "../../../common/dom/fire_event"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import { LovelaceCard, LovelaceCardEditor } from "../types"; import { GaugeCardConfig } from "./types"; -import { LovelaceConfig } from "../../../data/lovelace"; import { findEntities } from "../common/find-entites"; import { HassEntity } from "home-assistant-js-websocket/dist/types"; @@ -44,9 +43,8 @@ class HuiGaugeCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): object { const includeDomains = ["sensor"]; const maxEntities = 1; @@ -56,10 +54,9 @@ class HuiGaugeCard extends LitElement implements LovelaceCard { const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, includeDomains, entityFilter ); diff --git a/src/panels/lovelace/cards/hui-glance-card.ts b/src/panels/lovelace/cards/hui-glance-card.ts index ff789b1e1d..5062eb4c11 100644 --- a/src/panels/lovelace/cards/hui-glance-card.ts +++ b/src/panels/lovelace/cards/hui-glance-card.ts @@ -27,7 +27,7 @@ import { processConfigEntities } from "../common/process-config-entities"; import { GlanceCardConfig, GlanceConfigEntity } from "./types"; import { actionHandler } from "../common/directives/action-handler-directive"; import { hasAction } from "../common/has-action"; -import { ActionHandlerEvent, LovelaceConfig } from "../../../data/lovelace"; +import { ActionHandlerEvent } from "../../../data/lovelace"; import { handleAction } from "../common/handle-action"; import { computeDomain } from "../../../common/entity/compute_domain"; import { UNAVAILABLE, UNKNOWN } from "../../../data/entity"; @@ -44,18 +44,16 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): GlanceCardConfig { const includeDomains = ["sensor"]; const maxEntities = 3; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, includeDomains ); diff --git a/src/panels/lovelace/cards/hui-history-graph-card.ts b/src/panels/lovelace/cards/hui-history-graph-card.ts index 25922076fc..37a6705510 100644 --- a/src/panels/lovelace/cards/hui-history-graph-card.ts +++ b/src/panels/lovelace/cards/hui-history-graph-card.ts @@ -20,7 +20,6 @@ import { HomeAssistant } from "../../../types"; import { HistoryGraphCardConfig } from "./types"; import { LovelaceCard } from "../types"; import { EntityConfig } from "../entity-rows/types"; -import { LovelaceConfig } from "../../../data/lovelace"; import { findEntities } from "../common/find-entites"; @customElement("hui-history-graph-card") @@ -34,18 +33,16 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): object { const includeDomains = ["sensor"]; const maxEntities = 1; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, includeDomains ); diff --git a/src/panels/lovelace/cards/hui-light-card.ts b/src/panels/lovelace/cards/hui-light-card.ts index 29a7791afc..c0d07f1042 100644 --- a/src/panels/lovelace/cards/hui-light-card.ts +++ b/src/panels/lovelace/cards/hui-light-card.ts @@ -29,7 +29,6 @@ import { toggleEntity } from "../common/entity/toggle-entity"; import { LightCardConfig } from "./types"; import { supportsFeature } from "../../../common/entity/supports-feature"; import { SUPPORT_BRIGHTNESS } from "../../../data/light"; -import { LovelaceConfig } from "../../../data/lovelace"; import { findEntities } from "../common/find-entites"; import { UNAVAILABLE } from "../../../data/entity"; @@ -44,18 +43,16 @@ export class HuiLightCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): object { const includeDomains = ["light"]; const maxEntities = 1; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, includeDomains ); diff --git a/src/panels/lovelace/cards/hui-map-card.ts b/src/panels/lovelace/cards/hui-map-card.ts index 269b0deebf..b6cbbe351c 100644 --- a/src/panels/lovelace/cards/hui-map-card.ts +++ b/src/panels/lovelace/cards/hui-map-card.ts @@ -30,7 +30,6 @@ import { EntityConfig } from "../entity-rows/types"; import { processConfigEntities } from "../common/process-config-entities"; import { MapCardConfig } from "./types"; import { classMap } from "lit-html/directives/class-map"; -import { LovelaceConfig } from "../../../data/lovelace"; import { findEntities } from "../common/find-entites"; @customElement("hui-map-card") @@ -44,18 +43,16 @@ class HuiMapCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): object { const includeDomains = ["device_tracker"]; const maxEntities = 2; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, includeDomains ); diff --git a/src/panels/lovelace/cards/hui-media-control-card.ts b/src/panels/lovelace/cards/hui-media-control-card.ts index ec371db6de..28d04eeed1 100644 --- a/src/panels/lovelace/cards/hui-media-control-card.ts +++ b/src/panels/lovelace/cards/hui-media-control-card.ts @@ -30,7 +30,6 @@ import { stateIcon } from "../../../common/entity/state_icon"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import { contrast } from "../common/color/contrast"; import { findEntities } from "../common/find-entites"; -import { LovelaceConfig } from "../../../data/lovelace"; import { UNAVAILABLE, UNKNOWN } from "../../../data/entity"; import { SUPPORT_PAUSE, @@ -176,18 +175,16 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): object { const includeDomains = ["media_player"]; const maxEntities = 1; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, includeDomains ); diff --git a/src/panels/lovelace/cards/hui-picture-elements-card.ts b/src/panels/lovelace/cards/hui-picture-elements-card.ts index 001d50ecd1..64491e73d6 100644 --- a/src/panels/lovelace/cards/hui-picture-elements-card.ts +++ b/src/panels/lovelace/cards/hui-picture-elements-card.ts @@ -15,24 +15,21 @@ import { HomeAssistant } from "../../../types"; import { LovelaceElementConfig, LovelaceElement } from "../elements/types"; import { PictureElementsCardConfig } from "./types"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; -import { LovelaceConfig } from "../../../data/lovelace"; import { findEntities } from "../common/find-entites"; @customElement("hui-picture-elements-card") class HuiPictureElementsCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): PictureElementsCardConfig { const maxEntities = 1; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, ["sensor", "binary_sensor"] ); diff --git a/src/panels/lovelace/cards/hui-picture-entity-card.ts b/src/panels/lovelace/cards/hui-picture-entity-card.ts index 4a409da1b5..8d18cd79e3 100644 --- a/src/panels/lovelace/cards/hui-picture-entity-card.ts +++ b/src/panels/lovelace/cards/hui-picture-entity-card.ts @@ -27,7 +27,7 @@ import { PictureEntityCardConfig } from "./types"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { actionHandler } from "../common/directives/action-handler-directive"; import { hasAction } from "../common/has-action"; -import { ActionHandlerEvent, LovelaceConfig } from "../../../data/lovelace"; +import { ActionHandlerEvent } from "../../../data/lovelace"; import { handleAction } from "../common/handle-action"; import { findEntities } from "../common/find-entites"; @@ -42,17 +42,15 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): object { const maxEntities = 1; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, ["light", "switch"] ); diff --git a/src/panels/lovelace/cards/hui-picture-glance-card.ts b/src/panels/lovelace/cards/hui-picture-glance-card.ts index 7c1c1f027d..3bfa381dd8 100644 --- a/src/panels/lovelace/cards/hui-picture-glance-card.ts +++ b/src/panels/lovelace/cards/hui-picture-glance-card.ts @@ -29,7 +29,7 @@ import { hasConfigOrEntityChanged } from "../common/has-changed"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { actionHandler } from "../common/directives/action-handler-directive"; import { hasAction } from "../common/has-action"; -import { ActionHandlerEvent, LovelaceConfig } from "../../../data/lovelace"; +import { ActionHandlerEvent } from "../../../data/lovelace"; import { handleAction } from "../common/handle-action"; import { findEntities } from "../common/find-entites"; @@ -46,17 +46,15 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): PictureGlanceCardConfig { const maxEntities = 2; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, ["sensor", "binary_sensor"] ); diff --git a/src/panels/lovelace/cards/hui-plant-status-card.ts b/src/panels/lovelace/cards/hui-plant-status-card.ts index 9b7fd8a86d..074b6b7ec5 100644 --- a/src/panels/lovelace/cards/hui-plant-status-card.ts +++ b/src/panels/lovelace/cards/hui-plant-status-card.ts @@ -22,7 +22,6 @@ import { hasConfigOrEntityChanged } from "../common/has-changed"; import { PlantStatusCardConfig, PlantAttributeTarget } from "./types"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { actionHandler } from "../common/directives/action-handler-directive"; -import { LovelaceConfig } from "../../../data/lovelace"; import { findEntities } from "../common/find-entites"; const SENSORS = { @@ -44,18 +43,16 @@ class HuiPlantStatusCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): object { const includeDomains = ["plant"]; const maxEntities = 1; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, includeDomains ); diff --git a/src/panels/lovelace/cards/hui-sensor-card.ts b/src/panels/lovelace/cards/hui-sensor-card.ts index adfbb5da2f..ed0548f7a3 100644 --- a/src/panels/lovelace/cards/hui-sensor-card.ts +++ b/src/panels/lovelace/cards/hui-sensor-card.ts @@ -26,7 +26,6 @@ import { fetchRecent } from "../../../data/history"; import { SensorCardConfig } from "./types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import { actionHandler } from "../common/directives/action-handler-directive"; -import { LovelaceConfig } from "../../../data/lovelace"; import { findEntities } from "../common/find-entites"; import { HassEntity } from "home-assistant-js-websocket/dist/types"; @@ -179,9 +178,8 @@ class HuiSensorCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): object { const includeDomains = ["sensor"]; const maxEntities = 1; @@ -194,10 +192,9 @@ class HuiSensorCard extends LitElement implements LovelaceCard { const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, includeDomains, entityFilter ); diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index 24985d52b5..daa6a74860 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -34,7 +34,6 @@ import { } from "../../../data/climate"; import { HassEntity } from "home-assistant-js-websocket"; import { actionHandler } from "../common/directives/action-handler-directive"; -import { LovelaceConfig } from "../../../data/lovelace"; import { findEntities } from "../common/find-entites"; import { UNAVAILABLE } from "../../../data/entity"; @@ -59,18 +58,16 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): object { const includeDomains = ["climate"]; const maxEntities = 1; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, includeDomains ); diff --git a/src/panels/lovelace/cards/hui-weather-forecast-card.ts b/src/panels/lovelace/cards/hui-weather-forecast-card.ts index ceb3ec0dd8..0aa377518a 100644 --- a/src/panels/lovelace/cards/hui-weather-forecast-card.ts +++ b/src/panels/lovelace/cards/hui-weather-forecast-card.ts @@ -24,7 +24,6 @@ import { fireEvent } from "../../../common/dom/fire_event"; import { toggleAttribute } from "../../../common/dom/toggle_attribute"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { actionHandler } from "../common/directives/action-handler-directive"; -import { LovelaceConfig } from "../../../data/lovelace"; import { findEntities } from "../common/find-entites"; const cardinalDirections = [ @@ -76,18 +75,16 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { public static getStubConfig( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): object { const includeDomains = ["weather"]; const maxEntities = 1; const foundEntities = findEntities( hass, - lovelaceConfig, maxEntities, entities, - entitiesFill, + entitiesFallback, includeDomains ); diff --git a/src/panels/lovelace/common/compute-unused-entities.ts b/src/panels/lovelace/common/compute-unused-entities.ts index abedb58454..eb704fbbaa 100755 --- a/src/panels/lovelace/common/compute-unused-entities.ts +++ b/src/panels/lovelace/common/compute-unused-entities.ts @@ -61,7 +61,7 @@ const addEntities = (entities: Set, obj) => { } }; -export const computeUsedEntities = (config) => { +export const computeUsedEntities = (config: LovelaceConfig): Set => { const entities = new Set(); config.views.forEach((view) => addEntities(entities, view)); return entities; @@ -70,13 +70,26 @@ export const computeUsedEntities = (config) => { export const computeUnusedEntities = ( hass: HomeAssistant, config: LovelaceConfig -): string[] => { +): Set => { const usedEntities = computeUsedEntities(config); - return Object.keys(hass.states) - .filter( - (entity) => - !usedEntities.has(entity) && - !EXCLUDED_DOMAINS.includes(entity.split(".", 1)[0]) - ) - .sort(); + const unusedEntities = calcUnusedEntities(hass, usedEntities); + return unusedEntities; +}; + +export const calcUnusedEntities = ( + hass: HomeAssistant, + usedEntities: Set +): Set => { + const unusedEntities: Set = new Set(); + + for (const entity of Object.keys(hass.states)) { + if ( + !usedEntities.has(entity) && + !EXCLUDED_DOMAINS.includes(entity.split(".", 1)[0]) + ) { + unusedEntities.add(entity); + } + } + + return unusedEntities; }; diff --git a/src/panels/lovelace/common/find-entites.ts b/src/panels/lovelace/common/find-entites.ts index b9c00ecd44..c6eca98d39 100644 --- a/src/panels/lovelace/common/find-entites.ts +++ b/src/panels/lovelace/common/find-entites.ts @@ -1,59 +1,72 @@ -import { - computeUnusedEntities, - computeUsedEntities, -} from "./compute-unused-entities"; import { HomeAssistant } from "../../../types"; -import { LovelaceConfig } from "../../../data/lovelace"; import { computeDomain } from "../../../common/entity/compute_domain"; import { HassEntity } from "home-assistant-js-websocket"; +const arrayFilter = ( + array: any[], + conditions: Array<(value: any) => boolean>, + maxSize: number +) => { + if (!maxSize || maxSize > array.length) { + maxSize = array.length; + } + + const filteredArray: any[] = []; + + for (let i = 0; i < array.length && filteredArray.length < maxSize; i++) { + let meetsConditions = true; + + for (const condition of conditions) { + if (!condition(array[i])) { + meetsConditions = false; + break; + } + } + + if (meetsConditions) { + filteredArray.push(array[i]); + } + } + + return filteredArray; +}; + export const findEntities = ( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, maxEntities: number, - entities?: string[], - entitiesFill?: string[], + entities: string[], + entitiesFallback: string[], includeDomains?: string[], entityFilter?: (stateObj: HassEntity) => boolean ) => { let entityIds: string[]; - entityIds = !entities?.length - ? computeUnusedEntities(hass, lovelaceConfig) - : entities; + const conditions: Array<(value: string) => boolean> = []; - if (includeDomains && includeDomains.length) { - entityIds = entityIds.filter((eid) => - includeDomains!.includes(computeDomain(eid)) - ); + if (includeDomains?.length) { + conditions.push((eid) => includeDomains!.includes(computeDomain(eid))); } if (entityFilter) { - entityIds = entityIds.filter( + conditions.push( (eid) => hass.states[eid] && entityFilter(hass.states[eid]) ); } - if (entityIds.length < (maxEntities || 1)) { - let fillEntityIds = - entitiesFill && entitiesFill.length - ? entitiesFill - : [...computeUsedEntities(lovelaceConfig)]; + entityIds = arrayFilter(entities, conditions, maxEntities); - if (includeDomains && includeDomains.length) { - fillEntityIds = fillEntityIds.filter((eid) => - includeDomains!.includes(computeDomain(eid)) - ); - } + if (entityIds.length < maxEntities && entitiesFallback.length) { + const fallbackEntityIds = findEntities( + hass, + maxEntities - entityIds.length, + entitiesFallback, + [], + includeDomains, + entityFilter + ); - if (entityFilter) { - fillEntityIds = fillEntityIds.filter( - (eid) => hass.states[eid] && entityFilter(hass.states[eid]) - ); - } - - entityIds = [...entityIds, ...fillEntityIds]; + entityIds.push(...fallbackEntityIds); } - return entityIds.slice(0, maxEntities); + return entityIds; }; diff --git a/src/panels/lovelace/editor/card-editor/hui-card-picker.ts b/src/panels/lovelace/editor/card-editor/hui-card-picker.ts index 0b3f89a202..fbdc7cc6bf 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-picker.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-picker.ts @@ -19,9 +19,10 @@ import { fireEvent } from "../../../../common/dom/fire_event"; import { createCardElement } from "../../create-element/create-card-element"; import { getCardStubConfig } from "../get-card-stub-config"; import { - computeUnusedEntities, computeUsedEntities, + calcUnusedEntities, } from "../../common/compute-unused-entities"; +import { UNKNOWN, UNAVAILABLE } from "../../../../data/entity"; const previewCards: string[] = [ "alarm-panel", @@ -137,8 +138,22 @@ export class HuiCardPicker extends LitElement { return; } - this._unusedEntities = computeUnusedEntities(this.hass, this.lovelace); - this._usedEntities = [...computeUsedEntities(this.lovelace)]; + const usedEntities = computeUsedEntities(this.lovelace); + const unusedEntities = calcUnusedEntities(this.hass, usedEntities); + + this._usedEntities = [...usedEntities].filter( + (eid) => + this.hass!.states[eid] && + this.hass!.states[eid].state !== UNKNOWN && + this.hass!.states[eid].state !== UNAVAILABLE + ); + this._unusedEntities = [...unusedEntities].filter( + (eid) => + this.hass!.states[eid] && + this.hass!.states[eid].state !== UNKNOWN && + this.hass!.states[eid].state !== UNAVAILABLE + ); + this.requestUpdate(); } @@ -241,10 +256,9 @@ export class HuiCardPicker extends LitElement { if (this.hass && this.lovelace) { cardConfig = await getCardStubConfig( this.hass, - this.lovelace, type, - this._unusedEntities, - this._usedEntities + this._unusedEntities!, + this._usedEntities! ); if (!noElement) { diff --git a/src/panels/lovelace/editor/get-card-stub-config.ts b/src/panels/lovelace/editor/get-card-stub-config.ts index e8a1feff92..fce349e1f4 100644 --- a/src/panels/lovelace/editor/get-card-stub-config.ts +++ b/src/panels/lovelace/editor/get-card-stub-config.ts @@ -1,13 +1,12 @@ import { HomeAssistant } from "../../../types"; -import { LovelaceCardConfig, LovelaceConfig } from "../../../data/lovelace"; +import { LovelaceCardConfig } from "../../../data/lovelace"; import { getCardElementClass } from "../create-element/create-card-element"; export const getCardStubConfig = async ( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, type: string, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ): Promise => { let cardConfig: LovelaceCardConfig = { type }; @@ -16,9 +15,8 @@ export const getCardStubConfig = async ( if (elClass && elClass.getStubConfig) { const classStubConfig = elClass.getStubConfig( hass, - lovelaceConfig, entities, - entitiesFill + entitiesFallback ); cardConfig = { ...cardConfig, ...classStubConfig }; diff --git a/src/panels/lovelace/editor/unused-entities/hui-unused-entities.ts b/src/panels/lovelace/editor/unused-entities/hui-unused-entities.ts index 824012984d..5e3211039f 100644 --- a/src/panels/lovelace/editor/unused-entities/hui-unused-entities.ts +++ b/src/panels/lovelace/editor/unused-entities/hui-unused-entities.ts @@ -201,7 +201,8 @@ export class HuiUnusedEntities extends LitElement { return; } this._selectedEntities = []; - this._unusedEntities = computeUnusedEntities(this.hass, this._config!); + const unusedEntities = computeUnusedEntities(this.hass, this._config!); + this._unusedEntities = [...unusedEntities].sort(); } private _handleSelectionChanged( diff --git a/src/panels/lovelace/types.ts b/src/panels/lovelace/types.ts index 2a923180fb..bede948a08 100644 --- a/src/panels/lovelace/types.ts +++ b/src/panels/lovelace/types.ts @@ -40,9 +40,8 @@ export interface LovelaceCard extends HTMLElement { export interface LovelaceCardConstructor extends Constructor { getStubConfig?: ( hass: HomeAssistant, - lovelaceConfig: LovelaceConfig, - entities?: string[], - entitiesFill?: string[] + entities: string[], + entitiesFallback: string[] ) => LovelaceCardConfig; getConfigElement?: () => LovelaceCardEditor; }