Skip to content

Commit f32aa78

Browse files
authored
Merge branch 'dev' into feature/zigbee_graph_style_improvements
2 parents 52a0a6f + 7ce166e commit f32aa78

File tree

4 files changed

+126
-53
lines changed

4 files changed

+126
-53
lines changed

src/common/entity/entity_filter.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,7 @@ export const generateEntityFilter = (
5454
}
5555
}
5656
if (deviceClasses) {
57-
const dc = stateObj.attributes.device_class;
58-
if (!dc) {
59-
return false;
60-
}
57+
const dc = stateObj.attributes.device_class || "none";
6158
if (!deviceClasses.has(dc)) {
6259
return false;
6360
}

src/panels/lovelace/strategies/areas/area-view-strategy.ts

+17-43
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,10 @@ import type { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
55
import type { LovelaceSectionRawConfig } from "../../../../data/lovelace/config/section";
66
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
77
import type { HomeAssistant } from "../../../../types";
8-
import { supportsAlarmModesCardFeature } from "../../card-features/hui-alarm-modes-card-feature";
9-
import { supportsCoverOpenCloseCardFeature } from "../../card-features/hui-cover-open-close-card-feature";
10-
import { supportsLightBrightnessCardFeature } from "../../card-features/hui-light-brightness-card-feature";
11-
import { supportsLockCommandsCardFeature } from "../../card-features/hui-lock-commands-card-feature";
12-
import { supportsTargetTemperatureCardFeature } from "../../card-features/hui-target-temperature-card-feature";
13-
import type { LovelaceCardFeatureConfig } from "../../card-features/types";
148
import {
159
AREA_STRATEGY_GROUP_ICONS,
1610
AREA_STRATEGY_GROUP_LABELS,
11+
computeAreaTileCardConfig,
1712
getAreaGroupedEntities,
1813
} from "./helpers/area-strategy-helper";
1914

@@ -28,41 +23,6 @@ export interface AreaViewStrategyConfig {
2823
groups_options?: Record<string, EntitiesDisplay>;
2924
}
3025

31-
const computeTileCardConfig =
32-
(hass: HomeAssistant) =>
33-
(entity: string): LovelaceCardConfig => {
34-
const stateObj = hass.states[entity];
35-
36-
let feature: LovelaceCardFeatureConfig | undefined;
37-
if (supportsLightBrightnessCardFeature(stateObj)) {
38-
feature = {
39-
type: "light-brightness",
40-
};
41-
} else if (supportsCoverOpenCloseCardFeature(stateObj)) {
42-
feature = {
43-
type: "cover-open-close",
44-
};
45-
} else if (supportsTargetTemperatureCardFeature(stateObj)) {
46-
feature = {
47-
type: "target-temperature",
48-
};
49-
} else if (supportsAlarmModesCardFeature(stateObj)) {
50-
feature = {
51-
type: "alarm-modes",
52-
};
53-
} else if (supportsLockCommandsCardFeature(stateObj)) {
54-
feature = {
55-
type: "lock-commands",
56-
};
57-
}
58-
59-
return {
60-
type: "tile",
61-
entity: entity,
62-
features: feature ? [feature] : undefined,
63-
};
64-
};
65-
6626
const computeHeadingCard = (
6727
heading: string,
6828
icon: string
@@ -114,9 +74,10 @@ export class AreaViewStrategy extends ReactiveElement {
11474
config.groups_options
11575
);
11676

117-
const computeTileCard = computeTileCardConfig(hass);
77+
const computeTileCard = computeAreaTileCardConfig(hass, area.name, true);
11878

119-
const { lights, climate, media_players, security } = groupedEntities;
79+
const { lights, climate, media_players, security, others } =
80+
groupedEntities;
12081

12182
if (lights.length > 0) {
12283
sections.push({
@@ -170,6 +131,19 @@ export class AreaViewStrategy extends ReactiveElement {
170131
});
171132
}
172133

134+
if (others.length > 0) {
135+
sections.push({
136+
type: "grid",
137+
cards: [
138+
computeHeadingCard(
139+
AREA_STRATEGY_GROUP_LABELS.others,
140+
AREA_STRATEGY_GROUP_ICONS.others
141+
),
142+
...others.map(computeTileCard),
143+
],
144+
});
145+
}
146+
173147
return {
174148
type: "sections",
175149
header: {

src/panels/lovelace/strategies/areas/areas-view-strategy.ts

+9-6
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ import { customElement } from "lit/decorators";
33
import type { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
44
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
55
import type { HomeAssistant } from "../../../../types";
6-
import { getAreaGroupedEntities } from "./helpers/area-strategy-helper";
7-
import { computeAreaPath, getAreas } from "./helpers/areas-strategy-helpers";
86
import type { EntitiesDisplay } from "./area-view-strategy";
7+
import {
8+
computeAreaTileCardConfig,
9+
getAreaGroupedEntities,
10+
} from "./helpers/area-strategy-helper";
11+
import { computeAreaPath, getAreas } from "./helpers/areas-strategy-helpers";
912

1013
interface AreaOptions {
1114
groups_options?: Record<string, EntitiesDisplay>;
@@ -49,8 +52,11 @@ export class AreasViewStrategy extends ReactiveElement {
4952
...groups.climate,
5053
...groups.media_players,
5154
...groups.security,
55+
...groups.others,
5256
];
5357

58+
const computeTileCard = computeAreaTileCardConfig(hass, area.name);
59+
5460
return {
5561
type: "grid",
5662
cards: [
@@ -72,10 +78,7 @@ export class AreasViewStrategy extends ReactiveElement {
7278
},
7379
},
7480
...(entities.length
75-
? entities.map((entity) => ({
76-
type: "tile",
77-
entity: entity,
78-
}))
81+
? entities.map(computeTileCard)
7982
: [
8083
{
8184
type: "markdown",

src/panels/lovelace/strategies/areas/helpers/area-strategy-helper.ts

+99
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,33 @@
1+
import { computeDomain } from "../../../../../common/entity/compute_domain";
2+
import { computeStateName } from "../../../../../common/entity/compute_state_name";
13
import type { EntityFilterFunc } from "../../../../../common/entity/entity_filter";
24
import { generateEntityFilter } from "../../../../../common/entity/entity_filter";
5+
import { stripPrefixFromEntityName } from "../../../../../common/entity/strip_prefix_from_entity_name";
36
import { orderCompare } from "../../../../../common/string/compare";
7+
import type { LovelaceCardConfig } from "../../../../../data/lovelace/config/card";
48
import type { HomeAssistant } from "../../../../../types";
9+
import { supportsAlarmModesCardFeature } from "../../../card-features/hui-alarm-modes-card-feature";
10+
import { supportsCoverOpenCloseCardFeature } from "../../../card-features/hui-cover-open-close-card-feature";
11+
import { supportsLightBrightnessCardFeature } from "../../../card-features/hui-light-brightness-card-feature";
12+
import { supportsLockCommandsCardFeature } from "../../../card-features/hui-lock-commands-card-feature";
13+
import { supportsTargetTemperatureCardFeature } from "../../../card-features/hui-target-temperature-card-feature";
14+
import type { LovelaceCardFeatureConfig } from "../../../card-features/types";
15+
import type { TileCardConfig } from "../../../cards/types";
516

617
export const AREA_STRATEGY_GROUPS = [
718
"lights",
819
"climate",
920
"media_players",
1021
"security",
22+
"others",
1123
] as const;
1224

1325
export const AREA_STRATEGY_GROUP_ICONS = {
1426
lights: "mdi:lightbulb",
1527
climate: "mdi:home-thermometer",
1628
media_players: "mdi:multimedia",
1729
security: "mdi:security",
30+
others: "mdi:shape",
1831
};
1932

2033
// Todo be replace by translation when validated
@@ -23,6 +36,7 @@ export const AREA_STRATEGY_GROUP_LABELS = {
2336
climate: "Climate",
2437
media_players: "Entertainment",
2538
security: "Security",
39+
others: "Others",
2640
};
2741

2842
export type AreaStrategyGroup = (typeof AREA_STRATEGY_GROUPS)[number];
@@ -75,9 +89,15 @@ export const getAreaGroupedEntities = (
7589
"shade",
7690
"shutter",
7791
"window",
92+
"none",
7893
],
7994
entity_category: "none",
8095
}),
96+
generateEntityFilter(hass, {
97+
domain: "fan",
98+
area: area,
99+
entity_category: "none",
100+
}),
81101
generateEntityFilter(hass, {
82102
domain: "binary_sensor",
83103
area: area,
@@ -109,13 +129,40 @@ export const getAreaGroupedEntities = (
109129
area: area,
110130
entity_category: "none",
111131
}),
132+
generateEntityFilter(hass, {
133+
domain: "camera",
134+
area: area,
135+
entity_category: "none",
136+
}),
112137
generateEntityFilter(hass, {
113138
domain: "binary_sensor",
114139
device_class: ["door", "garage_door"],
115140
area: area,
116141
entity_category: "none",
117142
}),
118143
],
144+
others: [
145+
generateEntityFilter(hass, {
146+
domain: "vacuum",
147+
area: area,
148+
entity_category: "none",
149+
}),
150+
generateEntityFilter(hass, {
151+
domain: "lawn_mower",
152+
area: area,
153+
entity_category: "none",
154+
}),
155+
generateEntityFilter(hass, {
156+
domain: "valve",
157+
area: area,
158+
entity_category: "none",
159+
}),
160+
generateEntityFilter(hass, {
161+
domain: "switch",
162+
area: area,
163+
entity_category: "none",
164+
}),
165+
],
119166
};
120167

121168
return Object.fromEntries(
@@ -147,3 +194,55 @@ export const getAreaGroupedEntities = (
147194
})
148195
) as AreaEntitiesByGroup;
149196
};
197+
198+
export const computeAreaTileCardConfig =
199+
(hass: HomeAssistant, prefix: string, includeFeature?: boolean) =>
200+
(entity: string): LovelaceCardConfig => {
201+
const stateObj = hass.states[entity];
202+
203+
const additionalCardConfig: Partial<TileCardConfig> = {};
204+
205+
const domain = computeDomain(entity);
206+
if (domain === "camera") {
207+
additionalCardConfig.show_entity_picture = true;
208+
}
209+
210+
let feature: LovelaceCardFeatureConfig | undefined;
211+
if (includeFeature) {
212+
if (supportsLightBrightnessCardFeature(stateObj)) {
213+
feature = {
214+
type: "light-brightness",
215+
};
216+
} else if (supportsCoverOpenCloseCardFeature(stateObj)) {
217+
feature = {
218+
type: "cover-open-close",
219+
};
220+
} else if (supportsTargetTemperatureCardFeature(stateObj)) {
221+
feature = {
222+
type: "target-temperature",
223+
};
224+
} else if (supportsAlarmModesCardFeature(stateObj)) {
225+
feature = {
226+
type: "alarm-modes",
227+
};
228+
} else if (supportsLockCommandsCardFeature(stateObj)) {
229+
feature = {
230+
type: "lock-commands",
231+
};
232+
}
233+
}
234+
235+
if (feature) {
236+
additionalCardConfig.features = [feature];
237+
}
238+
239+
const name = computeStateName(stateObj);
240+
const stripedName = stripPrefixFromEntityName(name, prefix.toLowerCase());
241+
242+
return {
243+
type: "tile",
244+
entity: entity,
245+
name: stripedName,
246+
...additionalCardConfig,
247+
};
248+
};

0 commit comments

Comments
 (0)