mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 11:46:42 +00:00
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:
parent
2c0c48106d
commit
7ce166e40f
@ -54,10 +54,7 @@ export const generateEntityFilter = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (deviceClasses) {
|
if (deviceClasses) {
|
||||||
const dc = stateObj.attributes.device_class;
|
const dc = stateObj.attributes.device_class || "none";
|
||||||
if (!dc) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!deviceClasses.has(dc)) {
|
if (!deviceClasses.has(dc)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5,15 +5,10 @@ import type { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
|
|||||||
import type { LovelaceSectionRawConfig } from "../../../../data/lovelace/config/section";
|
import type { LovelaceSectionRawConfig } from "../../../../data/lovelace/config/section";
|
||||||
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
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 {
|
import {
|
||||||
AREA_STRATEGY_GROUP_ICONS,
|
AREA_STRATEGY_GROUP_ICONS,
|
||||||
AREA_STRATEGY_GROUP_LABELS,
|
AREA_STRATEGY_GROUP_LABELS,
|
||||||
|
computeAreaTileCardConfig,
|
||||||
getAreaGroupedEntities,
|
getAreaGroupedEntities,
|
||||||
} from "./helpers/area-strategy-helper";
|
} from "./helpers/area-strategy-helper";
|
||||||
|
|
||||||
@ -28,41 +23,6 @@ export interface AreaViewStrategyConfig {
|
|||||||
groups_options?: Record<string, EntitiesDisplay>;
|
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 = (
|
const computeHeadingCard = (
|
||||||
heading: string,
|
heading: string,
|
||||||
icon: string
|
icon: string
|
||||||
@ -114,9 +74,10 @@ export class AreaViewStrategy extends ReactiveElement {
|
|||||||
config.groups_options
|
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) {
|
if (lights.length > 0) {
|
||||||
sections.push({
|
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 {
|
return {
|
||||||
type: "sections",
|
type: "sections",
|
||||||
header: {
|
header: {
|
||||||
|
@ -3,9 +3,12 @@ import { customElement } from "lit/decorators";
|
|||||||
import type { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
|
import type { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
|
||||||
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
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 type { EntitiesDisplay } from "./area-view-strategy";
|
||||||
|
import {
|
||||||
|
computeAreaTileCardConfig,
|
||||||
|
getAreaGroupedEntities,
|
||||||
|
} from "./helpers/area-strategy-helper";
|
||||||
|
import { computeAreaPath, getAreas } from "./helpers/areas-strategy-helpers";
|
||||||
|
|
||||||
interface AreaOptions {
|
interface AreaOptions {
|
||||||
groups_options?: Record<string, EntitiesDisplay>;
|
groups_options?: Record<string, EntitiesDisplay>;
|
||||||
@ -49,8 +52,11 @@ export class AreasViewStrategy extends ReactiveElement {
|
|||||||
...groups.climate,
|
...groups.climate,
|
||||||
...groups.media_players,
|
...groups.media_players,
|
||||||
...groups.security,
|
...groups.security,
|
||||||
|
...groups.others,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const computeTileCard = computeAreaTileCardConfig(hass, area.name);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "grid",
|
type: "grid",
|
||||||
cards: [
|
cards: [
|
||||||
@ -72,10 +78,7 @@ export class AreasViewStrategy extends ReactiveElement {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
...(entities.length
|
...(entities.length
|
||||||
? entities.map((entity) => ({
|
? entities.map(computeTileCard)
|
||||||
type: "tile",
|
|
||||||
entity: entity,
|
|
||||||
}))
|
|
||||||
: [
|
: [
|
||||||
{
|
{
|
||||||
type: "markdown",
|
type: "markdown",
|
||||||
|
@ -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 type { EntityFilterFunc } from "../../../../../common/entity/entity_filter";
|
||||||
import { generateEntityFilter } 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 { orderCompare } from "../../../../../common/string/compare";
|
||||||
|
import type { LovelaceCardConfig } from "../../../../../data/lovelace/config/card";
|
||||||
import type { HomeAssistant } from "../../../../../types";
|
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 = [
|
export const AREA_STRATEGY_GROUPS = [
|
||||||
"lights",
|
"lights",
|
||||||
"climate",
|
"climate",
|
||||||
"media_players",
|
"media_players",
|
||||||
"security",
|
"security",
|
||||||
|
"others",
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export const AREA_STRATEGY_GROUP_ICONS = {
|
export const AREA_STRATEGY_GROUP_ICONS = {
|
||||||
@ -15,6 +27,7 @@ export const AREA_STRATEGY_GROUP_ICONS = {
|
|||||||
climate: "mdi:home-thermometer",
|
climate: "mdi:home-thermometer",
|
||||||
media_players: "mdi:multimedia",
|
media_players: "mdi:multimedia",
|
||||||
security: "mdi:security",
|
security: "mdi:security",
|
||||||
|
others: "mdi:shape",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Todo be replace by translation when validated
|
// Todo be replace by translation when validated
|
||||||
@ -23,6 +36,7 @@ export const AREA_STRATEGY_GROUP_LABELS = {
|
|||||||
climate: "Climate",
|
climate: "Climate",
|
||||||
media_players: "Entertainment",
|
media_players: "Entertainment",
|
||||||
security: "Security",
|
security: "Security",
|
||||||
|
others: "Others",
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AreaStrategyGroup = (typeof AREA_STRATEGY_GROUPS)[number];
|
export type AreaStrategyGroup = (typeof AREA_STRATEGY_GROUPS)[number];
|
||||||
@ -75,9 +89,15 @@ export const getAreaGroupedEntities = (
|
|||||||
"shade",
|
"shade",
|
||||||
"shutter",
|
"shutter",
|
||||||
"window",
|
"window",
|
||||||
|
"none",
|
||||||
],
|
],
|
||||||
entity_category: "none",
|
entity_category: "none",
|
||||||
}),
|
}),
|
||||||
|
generateEntityFilter(hass, {
|
||||||
|
domain: "fan",
|
||||||
|
area: area,
|
||||||
|
entity_category: "none",
|
||||||
|
}),
|
||||||
generateEntityFilter(hass, {
|
generateEntityFilter(hass, {
|
||||||
domain: "binary_sensor",
|
domain: "binary_sensor",
|
||||||
area: area,
|
area: area,
|
||||||
@ -109,6 +129,11 @@ export const getAreaGroupedEntities = (
|
|||||||
area: area,
|
area: area,
|
||||||
entity_category: "none",
|
entity_category: "none",
|
||||||
}),
|
}),
|
||||||
|
generateEntityFilter(hass, {
|
||||||
|
domain: "camera",
|
||||||
|
area: area,
|
||||||
|
entity_category: "none",
|
||||||
|
}),
|
||||||
generateEntityFilter(hass, {
|
generateEntityFilter(hass, {
|
||||||
domain: "binary_sensor",
|
domain: "binary_sensor",
|
||||||
device_class: ["door", "garage_door"],
|
device_class: ["door", "garage_door"],
|
||||||
@ -116,6 +141,28 @@ export const getAreaGroupedEntities = (
|
|||||||
entity_category: "none",
|
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(
|
return Object.fromEntries(
|
||||||
@ -147,3 +194,55 @@ export const getAreaGroupedEntities = (
|
|||||||
})
|
})
|
||||||
) as AreaEntitiesByGroup;
|
) 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,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user