mirror of
https://github.com/DigiLive/mushroom-strategy.git
synced 2025-08-03 19:44:27 +02:00
Add hiding diagnostic entities (#153)
Config and diagnostic entities are now hidden by default. Their visibility can be defined in the configuration with entries `hide_config_entities` and `hide_diagnostic_entities` for all or individual domains.
This commit is contained in:
@@ -6,6 +6,7 @@ import {DeviceRegistryEntry} from "./types/homeassistant/data/device_registry";
|
||||
import {AreaRegistryEntry} from "./types/homeassistant/data/area_registry";
|
||||
import {generic} from "./types/strategy/generic";
|
||||
import setupCustomLocalize from "./localize";
|
||||
import {applyEntityCategoryFilters} from "./utillties/filters";
|
||||
import StrategyArea = generic.StrategyArea;
|
||||
|
||||
/**
|
||||
@@ -228,7 +229,6 @@ class Helper {
|
||||
* @static
|
||||
*/
|
||||
static getCountTemplate(domain: string, operator: string, value: string): string {
|
||||
// noinspection JSMismatchedCollectionQueryUpdate (False positive per 17-04-2023)
|
||||
/**
|
||||
* Array of entity state-entries, filtered by domain.
|
||||
*
|
||||
@@ -246,22 +246,14 @@ class Helper {
|
||||
console.warn("Helper class should be initialized before calling this method!");
|
||||
}
|
||||
|
||||
// Get the ID of the devices which are linked to the given area.
|
||||
// Get the state of entities which are linked to the given area.
|
||||
for (const area of this.#areas) {
|
||||
const areaDeviceIds = this.#devices.filter((device) => {
|
||||
return device.area_id === area.area_id;
|
||||
}).map((device) => {
|
||||
return device.id;
|
||||
});
|
||||
let entities = this.getDeviceEntities(area, domain);
|
||||
|
||||
// Get the entities of which all conditions of the callback function are met. @see areaFilterCallback.
|
||||
const newStates = this.#entities.filter(
|
||||
this.#areaFilterCallback, {
|
||||
area: area,
|
||||
domain: domain,
|
||||
areaDeviceIds: areaDeviceIds,
|
||||
})
|
||||
.map((entity) => `states['${entity.entity_id}']`);
|
||||
// Exclude hidden Config and Diagnostic entities.
|
||||
entities = applyEntityCategoryFilters(entities, domain);
|
||||
|
||||
const newStates = entities.map((entity) => `states['${entity.entity_id}']`);
|
||||
|
||||
states.push(...newStates);
|
||||
}
|
||||
|
@@ -21,7 +21,8 @@ export const getConfigurationDefaults = (localize: Function): StrategyDefaults =
|
||||
debug: false,
|
||||
domains: {
|
||||
_: {
|
||||
hide_config_entities: false,
|
||||
hide_config_entities: true,
|
||||
hide_diagnostic_entities: true,
|
||||
},
|
||||
default: {
|
||||
title: localize("generic.miscellaneous"),
|
||||
|
@@ -6,6 +6,7 @@ import {LovelaceCardConfig, LovelaceConfig, LovelaceViewConfig} from "./types/ho
|
||||
import {StackCardConfig} from "./types/homeassistant/lovelace/cards/types";
|
||||
import {EntityCardConfig} from "./types/lovelace-mushroom/cards/entity-card-config";
|
||||
import {HassServiceTarget} from "home-assistant-js-websocket";
|
||||
import {applyEntityCategoryFilters} from "./utillties/filters";
|
||||
import StrategyArea = generic.StrategyArea;
|
||||
|
||||
/**
|
||||
@@ -112,10 +113,10 @@ class MushroomStrategy extends HTMLTemplateElement {
|
||||
try {
|
||||
domainCards = await import(`./cards/${className}`).then(cardModule => {
|
||||
let domainCards: EntityCardConfig[] = [];
|
||||
const entities = Helper.getDeviceEntities(area, domain);
|
||||
let configEntityHidden =
|
||||
Helper.strategyOptions.domains[domain ?? "_"].hide_config_entities
|
||||
|| Helper.strategyOptions.domains["_"].hide_config_entities;
|
||||
let entities = Helper.getDeviceEntities(area, domain);
|
||||
|
||||
// Exclude hidden Config and Diagnostic entities.
|
||||
entities = applyEntityCategoryFilters(entities, domain);
|
||||
|
||||
// Set the target for controller cards to entities without an area.
|
||||
if (area.area_id === "undisclosed") {
|
||||
@@ -175,11 +176,6 @@ class MushroomStrategy extends HTMLTemplateElement {
|
||||
deviceOptions = Helper.strategyOptions.card_options?.[entity.device_id];
|
||||
}
|
||||
|
||||
// Don't include the config-entity if hidden in the strategy options.
|
||||
if (entity.entity_category === "config" && configEntityHidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
domainCards.push(new cardModule[className](entity, cardOptions).getCard());
|
||||
}
|
||||
|
||||
@@ -219,10 +215,13 @@ class MushroomStrategy extends HTMLTemplateElement {
|
||||
if (!Helper.strategyOptions.domains.default.hidden) {
|
||||
// Create cards for any other domain.
|
||||
// Collect entities of the current area and unexposed domains.
|
||||
const miscellaneousEntities = Helper.getDeviceEntities(area).filter(
|
||||
let miscellaneousEntities = Helper.getDeviceEntities(area).filter(
|
||||
entity => !exposedDomainIds.includes(entity.entity_id.split(".", 1)[0])
|
||||
);
|
||||
|
||||
// Exclude hidden Config and Diagnostic entities.
|
||||
miscellaneousEntities = applyEntityCategoryFilters(miscellaneousEntities, "default");
|
||||
|
||||
// Create a column of miscellaneous entity cards.
|
||||
if (miscellaneousEntities.length) {
|
||||
let miscellaneousCards: (StackCardConfig | EntityCardConfig)[] = [];
|
||||
@@ -237,11 +236,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 config-entity if hidden in the strategy options
|
||||
if (entity.entity_category === "config" && Helper.strategyOptions.domains["_"].hide_config_entities) {
|
||||
continue;
|
||||
}
|
||||
|
||||
miscellaneousCards.push(new cardModule.MiscellaneousCard(entity, cardOptions).getCard());
|
||||
}
|
||||
|
||||
|
@@ -38,11 +38,14 @@ export namespace generic {
|
||||
* @property {boolean} [hidden] True if the entity should be hidden from the dashboard.
|
||||
* @property {boolean} [hide_config_entities] True if the entity's categorie is "config" and should be hidden from the
|
||||
* dashboard.
|
||||
* @property {boolean} [hide_diagnostic_entities] True if the entity's categorie is "diagnostic" and should be hidden
|
||||
* from the dashboard.
|
||||
*/
|
||||
export interface DomainConfig extends Partial<cards.ControllerCardConfig> {
|
||||
hidden?: boolean;
|
||||
order?: number;
|
||||
hide_config_entities?: boolean
|
||||
hide_diagnostic_entities?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
|
52
src/utillties/filters.ts
Normal file
52
src/utillties/filters.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import {EntityRegistryEntry} from "../types/homeassistant/data/entity_registry";
|
||||
import {Helper} from "../Helper";
|
||||
|
||||
/**
|
||||
* Filter an array of entities by property/value pair
|
||||
*
|
||||
* @param entities The array of entities to filter.
|
||||
* @param property The property to filter on.
|
||||
* @param value The value to match.
|
||||
* @param exclude Whether to exclude entities with the given property/value pair (default: true).
|
||||
*
|
||||
* @returns A new list of entities filtered by the given property/value pair.
|
||||
*/
|
||||
export function filterEntitiesByPropertyValue(
|
||||
entities: EntityRegistryEntry[],
|
||||
property: keyof EntityRegistryEntry,
|
||||
value: any,
|
||||
exclude: boolean = true
|
||||
) {
|
||||
return entities.filter(entity => exclude ? entity[property] !== value : entity[property] === value);
|
||||
}
|
||||
|
||||
export function applyEntityCategoryFilters(entities: EntityRegistryEntry[], domain: string) {
|
||||
if (!Helper.isInitialized()) {
|
||||
throw new Error("The Helper module must be initialized before using this one.");
|
||||
}
|
||||
|
||||
const domainOptions = {
|
||||
...Helper.strategyOptions.domains["_"],
|
||||
...Helper.strategyOptions.domains[domain],
|
||||
};
|
||||
|
||||
let filteredEntityCategory = [];
|
||||
|
||||
if (domainOptions.hide_config_entities) {
|
||||
entities = filterEntitiesByPropertyValue(entities, "entity_category", "config");
|
||||
filteredEntityCategory.push("Config");
|
||||
}
|
||||
|
||||
if (domainOptions.hide_diagnostic_entities) {
|
||||
entities = filterEntitiesByPropertyValue(entities, "entity_category", "diagnostic");
|
||||
filteredEntityCategory.push("Diagnostic");
|
||||
}
|
||||
|
||||
if (Helper.debug && filteredEntityCategory.length > 0) {
|
||||
console.warn(filteredEntityCategory.join(" & ") + " entities are filtered out.");
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
|
@@ -5,6 +5,7 @@ import {LovelaceCardConfig, LovelaceViewConfig} from "../types/homeassistant/dat
|
||||
import {cards} from "../types/strategy/cards";
|
||||
import {TitleCardConfig} from "../types/lovelace-mushroom/cards/title-card-config";
|
||||
import {HassServiceTarget} from "home-assistant-js-websocket";
|
||||
import {applyEntityCategoryFilters} from "../utillties/filters";
|
||||
import abstractCardConfig = cards.AbstractCardConfig;
|
||||
|
||||
/**
|
||||
@@ -42,24 +43,22 @@ abstract class AbstractView {
|
||||
* @private
|
||||
* @readonly
|
||||
*/
|
||||
readonly #domain?: string;
|
||||
readonly #domain: string;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param {string} [domain] The domain which the view is representing.
|
||||
* @param {string} domain The domain which the view is representing.
|
||||
*
|
||||
* @throws {Error} If trying to instantiate this class.
|
||||
* @throws {Error} If the Helper module isn't initialized.
|
||||
*/
|
||||
protected constructor(domain: string = "") {
|
||||
protected constructor(domain: string) {
|
||||
if (!Helper.isInitialized()) {
|
||||
throw new Error("The Helper module must be initialized before using this one.");
|
||||
}
|
||||
|
||||
if (domain) {
|
||||
this.#domain = domain;
|
||||
}
|
||||
this.#domain = domain;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,14 +68,10 @@ abstract class AbstractView {
|
||||
*/
|
||||
async createViewCards(): Promise<(StackCardConfig | TitleCardConfig)[]> {
|
||||
const viewCards: LovelaceCardConfig[] = [];
|
||||
const configEntityHidden =
|
||||
Helper.strategyOptions.domains[this.#domain ?? "_"].hide_config_entities
|
||||
|| Helper.strategyOptions.domains["_"].hide_config_entities;
|
||||
|
||||
// Create cards for each area.
|
||||
for (const area of Helper.areas) {
|
||||
const areaCards: abstractCardConfig[] = [];
|
||||
const entities = Helper.getDeviceEntities(area, this.#domain ?? "");
|
||||
const className = Helper.sanitizeClassName(this.#domain + "Card");
|
||||
const cardModule = await import(`../cards/${className}`);
|
||||
|
||||
@@ -85,6 +80,10 @@ abstract class AbstractView {
|
||||
area_id: [area.area_id],
|
||||
};
|
||||
|
||||
let entities = Helper.getDeviceEntities(area, this.#domain);
|
||||
// Exclude hidden Config and Diagnostic entities.
|
||||
entities = applyEntityCategoryFilters(entities, this.#domain);
|
||||
|
||||
// Set the target for controller cards to entities without an area.
|
||||
if (area.area_id === "undisclosed") {
|
||||
target = {
|
||||
@@ -101,10 +100,6 @@ abstract class AbstractView {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entity.entity_category === "config" && configEntityHidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
areaCards.push(new cardModule[className](entity, cardOptions).getCard());
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@ class HomeView extends AbstractView {
|
||||
* @param {views.ViewConfig} [options={}] Options for the view.
|
||||
*/
|
||||
constructor(options: views.ViewConfig = {}) {
|
||||
super();
|
||||
super("home");
|
||||
|
||||
this.config = Object.assign(this.config, this.#defaultConfig, options);
|
||||
}
|
||||
|
Reference in New Issue
Block a user