Area dashboard improvement (#24690)

* Add more domains in the areas dashboard and strip area name from the entity name

* Display cover without device classes

* Remove useless test
This commit is contained in:
Paul Bottein 2025-03-19 23:19:58 +01:00 committed by GitHub
parent 2c0c48106d
commit 7ce166e40f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 126 additions and 53 deletions

View File

@ -54,10 +54,7 @@ export const generateEntityFilter = (
}
}
if (deviceClasses) {
const dc = stateObj.attributes.device_class;
if (!dc) {
return false;
}
const dc = stateObj.attributes.device_class || "none";
if (!deviceClasses.has(dc)) {
return false;
}

View File

@ -5,15 +5,10 @@ import type { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
import type { LovelaceSectionRawConfig } from "../../../../data/lovelace/config/section";
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
import type { HomeAssistant } from "../../../../types";
import { supportsAlarmModesCardFeature } from "../../card-features/hui-alarm-modes-card-feature";
import { supportsCoverOpenCloseCardFeature } from "../../card-features/hui-cover-open-close-card-feature";
import { supportsLightBrightnessCardFeature } from "../../card-features/hui-light-brightness-card-feature";
import { supportsLockCommandsCardFeature } from "../../card-features/hui-lock-commands-card-feature";
import { supportsTargetTemperatureCardFeature } from "../../card-features/hui-target-temperature-card-feature";
import type { LovelaceCardFeatureConfig } from "../../card-features/types";
import {
AREA_STRATEGY_GROUP_ICONS,
AREA_STRATEGY_GROUP_LABELS,
computeAreaTileCardConfig,
getAreaGroupedEntities,
} from "./helpers/area-strategy-helper";
@ -28,41 +23,6 @@ export interface AreaViewStrategyConfig {
groups_options?: Record<string, EntitiesDisplay>;
}
const computeTileCardConfig =
(hass: HomeAssistant) =>
(entity: string): LovelaceCardConfig => {
const stateObj = hass.states[entity];
let feature: LovelaceCardFeatureConfig | undefined;
if (supportsLightBrightnessCardFeature(stateObj)) {
feature = {
type: "light-brightness",
};
} else if (supportsCoverOpenCloseCardFeature(stateObj)) {
feature = {
type: "cover-open-close",
};
} else if (supportsTargetTemperatureCardFeature(stateObj)) {
feature = {
type: "target-temperature",
};
} else if (supportsAlarmModesCardFeature(stateObj)) {
feature = {
type: "alarm-modes",
};
} else if (supportsLockCommandsCardFeature(stateObj)) {
feature = {
type: "lock-commands",
};
}
return {
type: "tile",
entity: entity,
features: feature ? [feature] : undefined,
};
};
const computeHeadingCard = (
heading: string,
icon: string
@ -114,9 +74,10 @@ export class AreaViewStrategy extends ReactiveElement {
config.groups_options
);
const computeTileCard = computeTileCardConfig(hass);
const computeTileCard = computeAreaTileCardConfig(hass, area.name, true);
const { lights, climate, media_players, security } = groupedEntities;
const { lights, climate, media_players, security, others } =
groupedEntities;
if (lights.length > 0) {
sections.push({
@ -170,6 +131,19 @@ export class AreaViewStrategy extends ReactiveElement {
});
}
if (others.length > 0) {
sections.push({
type: "grid",
cards: [
computeHeadingCard(
AREA_STRATEGY_GROUP_LABELS.others,
AREA_STRATEGY_GROUP_ICONS.others
),
...others.map(computeTileCard),
],
});
}
return {
type: "sections",
header: {

View File

@ -3,9 +3,12 @@ import { customElement } from "lit/decorators";
import type { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
import type { HomeAssistant } from "../../../../types";
import { getAreaGroupedEntities } from "./helpers/area-strategy-helper";
import { computeAreaPath, getAreas } from "./helpers/areas-strategy-helpers";
import type { EntitiesDisplay } from "./area-view-strategy";
import {
computeAreaTileCardConfig,
getAreaGroupedEntities,
} from "./helpers/area-strategy-helper";
import { computeAreaPath, getAreas } from "./helpers/areas-strategy-helpers";
interface AreaOptions {
groups_options?: Record<string, EntitiesDisplay>;
@ -49,8 +52,11 @@ export class AreasViewStrategy extends ReactiveElement {
...groups.climate,
...groups.media_players,
...groups.security,
...groups.others,
];
const computeTileCard = computeAreaTileCardConfig(hass, area.name);
return {
type: "grid",
cards: [
@ -72,10 +78,7 @@ export class AreasViewStrategy extends ReactiveElement {
},
},
...(entities.length
? entities.map((entity) => ({
type: "tile",
entity: entity,
}))
? entities.map(computeTileCard)
: [
{
type: "markdown",

View File

@ -1,13 +1,25 @@
import { computeDomain } from "../../../../../common/entity/compute_domain";
import { computeStateName } from "../../../../../common/entity/compute_state_name";
import type { EntityFilterFunc } from "../../../../../common/entity/entity_filter";
import { generateEntityFilter } from "../../../../../common/entity/entity_filter";
import { stripPrefixFromEntityName } from "../../../../../common/entity/strip_prefix_from_entity_name";
import { orderCompare } from "../../../../../common/string/compare";
import type { LovelaceCardConfig } from "../../../../../data/lovelace/config/card";
import type { HomeAssistant } from "../../../../../types";
import { supportsAlarmModesCardFeature } from "../../../card-features/hui-alarm-modes-card-feature";
import { supportsCoverOpenCloseCardFeature } from "../../../card-features/hui-cover-open-close-card-feature";
import { supportsLightBrightnessCardFeature } from "../../../card-features/hui-light-brightness-card-feature";
import { supportsLockCommandsCardFeature } from "../../../card-features/hui-lock-commands-card-feature";
import { supportsTargetTemperatureCardFeature } from "../../../card-features/hui-target-temperature-card-feature";
import type { LovelaceCardFeatureConfig } from "../../../card-features/types";
import type { TileCardConfig } from "../../../cards/types";
export const AREA_STRATEGY_GROUPS = [
"lights",
"climate",
"media_players",
"security",
"others",
] as const;
export const AREA_STRATEGY_GROUP_ICONS = {
@ -15,6 +27,7 @@ export const AREA_STRATEGY_GROUP_ICONS = {
climate: "mdi:home-thermometer",
media_players: "mdi:multimedia",
security: "mdi:security",
others: "mdi:shape",
};
// Todo be replace by translation when validated
@ -23,6 +36,7 @@ export const AREA_STRATEGY_GROUP_LABELS = {
climate: "Climate",
media_players: "Entertainment",
security: "Security",
others: "Others",
};
export type AreaStrategyGroup = (typeof AREA_STRATEGY_GROUPS)[number];
@ -75,9 +89,15 @@ export const getAreaGroupedEntities = (
"shade",
"shutter",
"window",
"none",
],
entity_category: "none",
}),
generateEntityFilter(hass, {
domain: "fan",
area: area,
entity_category: "none",
}),
generateEntityFilter(hass, {
domain: "binary_sensor",
area: area,
@ -109,6 +129,11 @@ export const getAreaGroupedEntities = (
area: area,
entity_category: "none",
}),
generateEntityFilter(hass, {
domain: "camera",
area: area,
entity_category: "none",
}),
generateEntityFilter(hass, {
domain: "binary_sensor",
device_class: ["door", "garage_door"],
@ -116,6 +141,28 @@ export const getAreaGroupedEntities = (
entity_category: "none",
}),
],
others: [
generateEntityFilter(hass, {
domain: "vacuum",
area: area,
entity_category: "none",
}),
generateEntityFilter(hass, {
domain: "lawn_mower",
area: area,
entity_category: "none",
}),
generateEntityFilter(hass, {
domain: "valve",
area: area,
entity_category: "none",
}),
generateEntityFilter(hass, {
domain: "switch",
area: area,
entity_category: "none",
}),
],
};
return Object.fromEntries(
@ -147,3 +194,55 @@ export const getAreaGroupedEntities = (
})
) as AreaEntitiesByGroup;
};
export const computeAreaTileCardConfig =
(hass: HomeAssistant, prefix: string, includeFeature?: boolean) =>
(entity: string): LovelaceCardConfig => {
const stateObj = hass.states[entity];
const additionalCardConfig: Partial<TileCardConfig> = {};
const domain = computeDomain(entity);
if (domain === "camera") {
additionalCardConfig.show_entity_picture = true;
}
let feature: LovelaceCardFeatureConfig | undefined;
if (includeFeature) {
if (supportsLightBrightnessCardFeature(stateObj)) {
feature = {
type: "light-brightness",
};
} else if (supportsCoverOpenCloseCardFeature(stateObj)) {
feature = {
type: "cover-open-close",
};
} else if (supportsTargetTemperatureCardFeature(stateObj)) {
feature = {
type: "target-temperature",
};
} else if (supportsAlarmModesCardFeature(stateObj)) {
feature = {
type: "alarm-modes",
};
} else if (supportsLockCommandsCardFeature(stateObj)) {
feature = {
type: "lock-commands",
};
}
}
if (feature) {
additionalCardConfig.features = [feature];
}
const name = computeStateName(stateObj);
const stripedName = stripPrefixFromEntityName(name, prefix.toLowerCase());
return {
type: "tile",
entity: entity,
name: stripedName,
...additionalCardConfig,
};
};