From da7d0cd57c66575a3735fbdc25a24a1f4f6384b1 Mon Sep 17 00:00:00 2001 From: w531t4 <41222371+w531t4@users.noreply.github.com> Date: Sun, 9 Feb 2025 00:48:38 -0500 Subject: [PATCH] Fix counting of hidden entities and devices Evaluation an entity's hidden property in the strategy options, is now included in Helper.#areaFilterCallback(). --- src/Helper.ts | 32 +++++++++++--------- src/mushroom-strategy.ts | 57 ++++++++++------------------------- src/types/strategy/generic.ts | 5 ++- 3 files changed, 36 insertions(+), 58 deletions(-) diff --git a/src/Helper.ts b/src/Helper.ts index 45b215f..e6ee596 100644 --- a/src/Helper.ts +++ b/src/Helper.ts @@ -287,12 +287,12 @@ class Helper { * The result excludes hidden and disabled entities. * * @param {AreaRegistryEntry} area Area entity. - * @param {string} domain The domain of the entity-id. + * @param {string} [domain] The domain of the entity-id. * * @return {EntityRegistryEntry[]} Array of device entities. * @static */ - static getDeviceEntities(area: AreaRegistryEntry, domain: string): EntityRegistryEntry[] { + static getDeviceEntities(area: AreaRegistryEntry, domain?: string): EntityRegistryEntry[] { if (!this.isInitialized()) { console.warn("Helper class should be initialized before calling this method!"); } @@ -414,12 +414,12 @@ class Helper { * Callback function for filtering entities. * * Entities of which all the conditions below are met are kept: - * 1. The entity is not hidden and is not disabled. - * 2. The entity's domain matches the given domain. - * 3. The entity itself or else the entity's linked device is linked to the given area. - * (See variable areaMatch) + * 1. The entity is not hidden and the entity's device is not hidden by the strategy options. + * 2. The entity is not hidden and is not disabled by Hass. + * 3. The entity's domain matches the given domain. + * 4. The entity itself or else the entity's device is linked to the given area. * - * @param {EntityRegistryEntry} entity The current hass entity to evaluate. + * @param {EntityRegistryEntry} entity The current Hass entity to evaluate. * @this {AreaFilterContext} * * @return {boolean} True to keep the entity. @@ -432,16 +432,20 @@ class Helper { domain: string, }, entity: EntityRegistryEntry): boolean { - const entityUnhidden = entity.hidden_by === null && entity.disabled_by === null; - const domainMatches = entity.entity_id.startsWith(`${this.domain}.`); + const cardOptions = Helper.strategyOptions.card_options?.[entity.entity_id]; + const deviceOptions = Helper.strategyOptions.card_options?.[entity.device_id ?? "null"]; + + const entityUnhidden = + !cardOptions?.hidden && !deviceOptions?.hidden // Condition 1. + && entity.hidden_by === null && entity.disabled_by === null; // Condition 2. + const domainMatches = this.domain === undefined || entity.entity_id.startsWith(`${this.domain}.`); // Condition 3. + // Condition 4. const entityLinked = this.area.area_id === "undisclosed" - // Undisclosed area; - // nor the entity itself, neither the entity's linked device (if any) is linked to any area. + // Undisclosed area. ? !entity.area_id && (this.areaDeviceIds.includes(entity.device_id ?? "") || !entity.device_id) - // Area is a hass entity; - // The entity itself or the entity's device is linked to the given area. - // Note: entity.area_id is set to null when using device's area. + // Area is a hass entity. Note: entity.area_id is set to null when using device's area. : entity.area_id === this.area.area_id || (!entity.area_id && this.areaDeviceIds.includes(entity.device_id ?? "")); + return (entityUnhidden && domainMatches && entityLinked); } diff --git a/src/mushroom-strategy.ts b/src/mushroom-strategy.ts index 18648db..a4d6f53 100644 --- a/src/mushroom-strategy.ts +++ b/src/mushroom-strategy.ts @@ -107,11 +107,11 @@ class MushroomStrategy extends HTMLTemplateElement { const className = Helper.sanitizeClassName(domain + "Card"); - let domainCards = []; + let domainCards: EntityCardConfig[] = []; try { domainCards = await import(`./cards/${className}`).then(cardModule => { - let domainCards = []; + let domainCards: EntityCardConfig[] = []; const entities = Helper.getDeviceEntities(area, domain); let configEntityHidden = Helper.strategyOptions.domains[domain ?? "_"].hide_config_entities @@ -132,7 +132,7 @@ class MushroomStrategy extends HTMLTemplateElement { ).createCard(); if (domain === "sensor") { - // Create a card for each entity-sensor of the current area. + // Create a card for each sensor-entity of the current area. const sensorStates = Helper.getStateEntities(area, "sensor"); const sensorCards: EntityCardConfig[] = []; @@ -140,18 +140,15 @@ class MushroomStrategy extends HTMLTemplateElement { // Find the state of the current sensor. const sensorState = sensorStates.find(state => state.entity_id === sensor.entity_id); let cardOptions = Helper.strategyOptions.card_options?.[sensor.entity_id]; - let deviceOptions = Helper.strategyOptions.card_options?.[sensor.device_id ?? "null"]; - if (!cardOptions?.hidden && !deviceOptions?.hidden) { - if (sensorState?.attributes.unit_of_measurement) { - cardOptions = { - ...{ - type: "custom:mini-graph-card", - entities: [sensor.entity_id], - }, - ...cardOptions, - }; - } + if (sensorState?.attributes.unit_of_measurement) { + cardOptions = { + ...{ + type: "custom:mini-graph-card", + entities: [sensor.entity_id], + }, + ...cardOptions, + }; sensorCards.push(new SensorCard(sensor, cardOptions).getCard()); } @@ -178,11 +175,6 @@ class MushroomStrategy extends HTMLTemplateElement { deviceOptions = Helper.strategyOptions.card_options?.[entity.device_id]; } - // Don't include the entity if hidden in the strategy options. - if (cardOptions?.hidden || deviceOptions?.hidden) { - continue; - } - // Don't include the config-entity if hidden in the strategy options. if (entity.entity_category === "config" && configEntityHidden) { continue; @@ -193,7 +185,7 @@ class MushroomStrategy extends HTMLTemplateElement { if (domain === "binary_sensor") { // Horizontally group every two binary sensor cards. - const horizontalCards = []; + const horizontalCards: EntityCardConfig[] = []; for (let i = 0; i < domainCards.length; i += 2) { horizontalCards.push({ @@ -226,22 +218,10 @@ class MushroomStrategy extends HTMLTemplateElement { if (!Helper.strategyOptions.domains.default.hidden) { // Create cards for any other domain. - // Collect device entities of the current area. - const areaDevices = Helper.devices.filter((device) => device.area_id === area.area_id) - .map((device) => device.id); - - // Collect the remaining entities of which all conditions below are met: - // 1. The entity is not hidden. - // 2. The entity's domain isn't exposed (entities of exposed domains are already included). - // 3. The entity is linked to a device which is linked to the current area, - // or the entity itself is linked to the current area. - const miscellaneousEntities = Helper.entities.filter((entity) => { - const entityLinked = areaDevices.includes(entity.device_id ?? "null") || entity.area_id === area.area_id; - const entityUnhidden = entity.hidden_by === null && entity.disabled_by === null; - const domainExposed = exposedDomainIds.includes(entity.entity_id.split(".", 1)[0]); - - return entityUnhidden && !domainExposed && entityLinked; - }); + // Collect entities of the current area and unexposed domains. + const miscellaneousEntities = Helper.getDeviceEntities(area).filter( + entity => !exposedDomainIds.includes(entity.entity_id.split(".", 1)[0]) + ); // Create a column of miscellaneous entity cards. if (miscellaneousEntities.length) { @@ -257,11 +237,6 @@ class MushroomStrategy extends HTMLTemplateElement { let cardOptions = Helper.strategyOptions.card_options?.[entity.entity_id]; let deviceOptions = Helper.strategyOptions.card_options?.[entity.device_id ?? "null"]; - // Don't include the entity if hidden in the strategy options. - if (cardOptions?.hidden || deviceOptions?.hidden) { - continue; - } - // Don't include the config-entity if hidden in the strategy options if (entity.entity_category === "config" && Helper.strategyOptions.domains["_"].hide_config_entities) { continue; diff --git a/src/types/strategy/generic.ts b/src/types/strategy/generic.ts index 821d5fc..12197d5 100644 --- a/src/types/strategy/generic.ts +++ b/src/types/strategy/generic.ts @@ -186,13 +186,12 @@ export namespace generic { * * @property {AreaRegistryEntry} area Area Entity. * @property {string[]} areaDeviceIds The id of devices which are linked to the area entity. - * @property {string} domain Domain of the entity. - * Example: `light`. + * @property {string} [domain] Domain of the entity. Example: `light`. */ export interface AreaFilterContext { area: AreaRegistryEntry; areaDeviceIds: string[]; - domain: string; + domain?: string; } /**