Skip to content

Commit

Permalink
Area Card Editor: show a list of relevant entities
Browse files Browse the repository at this point in the history
  • Loading branch information
karwosts committed Jun 19, 2024
1 parent 42b5fa6 commit bcabe27
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 117 deletions.
155 changes: 77 additions & 78 deletions src/panels/lovelace/cards/hui-area-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const SENSOR_DOMAINS = ["sensor"];

const ALERT_DOMAINS = ["binary_sensor"];

const TOGGLE_DOMAINS = ["light", "switch", "fan"];
export const TOGGLE_DOMAINS = ["light", "switch", "fan"];

const OTHER_DOMAINS = ["camera"];

Expand All @@ -83,6 +83,72 @@ const DOMAIN_ICONS = {
},
};

export const getDevicesInArea = memoizeOne(
(areaId: string | undefined, devices: DeviceRegistryEntry[]) =>
new Set(
areaId
? devices
.filter((device) => device.area_id === areaId)
.map((device) => device.id)
: []
)
);

export const getEntitiesByDomain = memoizeOne(
(
areaId: string,
devicesInArea: Set<string>,
registryEntities: EntityRegistryEntry[],
deviceClasses: { [key: string]: string[] } | undefined,
states: HomeAssistant["states"]
) => {
const entitiesInArea = registryEntities
.filter(
(entry) =>
!entry.entity_category &&
!entry.hidden_by &&
(entry.area_id
? entry.area_id === areaId
: entry.device_id && devicesInArea.has(entry.device_id))
)
.map((entry) => entry.entity_id);

const entitiesByDomain: { [domain: string]: HassEntity[] } = {};

for (const entity of entitiesInArea) {
const domain = computeDomain(entity);
if (
!TOGGLE_DOMAINS.includes(domain) &&
!SENSOR_DOMAINS.includes(domain) &&
!ALERT_DOMAINS.includes(domain) &&
!OTHER_DOMAINS.includes(domain)
) {
continue;
}
const stateObj: HassEntity | undefined = states[entity];

if (!stateObj) {
continue;
}

if (
(SENSOR_DOMAINS.includes(domain) || ALERT_DOMAINS.includes(domain)) &&
deviceClasses &&
!deviceClasses[domain].includes(stateObj.attributes.device_class || "")
) {
continue;
}

if (!(domain in entitiesByDomain)) {
entitiesByDomain[domain] = [];
}
entitiesByDomain[domain].push(stateObj);
}

return entitiesByDomain;
}
);

@customElement("hui-area-card")
export class HuiAreaCard
extends SubscribeMixin(LitElement)
Expand Down Expand Up @@ -117,66 +183,10 @@ export class HuiAreaCard
h: number;
} | null = null;

private _entitiesByDomain = memoizeOne(
(
areaId: string,
devicesInArea: Set<string>,
registryEntities: EntityRegistryEntry[],
deviceClasses: { [key: string]: string[] },
states: HomeAssistant["states"]
) => {
const entitiesInArea = registryEntities
.filter(
(entry) =>
!entry.entity_category &&
!entry.hidden_by &&
(entry.area_id
? entry.area_id === areaId
: entry.device_id && devicesInArea.has(entry.device_id))
)
.map((entry) => entry.entity_id);

const entitiesByDomain: { [domain: string]: HassEntity[] } = {};

for (const entity of entitiesInArea) {
const domain = computeDomain(entity);
if (
!TOGGLE_DOMAINS.includes(domain) &&
!SENSOR_DOMAINS.includes(domain) &&
!ALERT_DOMAINS.includes(domain) &&
!OTHER_DOMAINS.includes(domain)
) {
continue;
}
const stateObj: HassEntity | undefined = states[entity];

if (!stateObj) {
continue;
}

if (
(SENSOR_DOMAINS.includes(domain) || ALERT_DOMAINS.includes(domain)) &&
!deviceClasses[domain].includes(
stateObj.attributes.device_class || ""
)
) {
continue;
}

if (!(domain in entitiesByDomain)) {
entitiesByDomain[domain] = [];
}
entitiesByDomain[domain].push(stateObj);
}

return entitiesByDomain;
}
);

private _isOn(domain: string, deviceClass?: string): HassEntity | undefined {
const entities = this._entitiesByDomain(
const entities = getEntitiesByDomain(
this._config!.area,
this._devicesInArea(this._config!.area, this._devices!),
getDevicesInArea(this._config!.area, this._devices!),
this._entities!,
this._deviceClasses,
this.hass.states
Expand All @@ -197,9 +207,9 @@ export class HuiAreaCard
}

private _average(domain: string, deviceClass?: string): string | undefined {
const entities = this._entitiesByDomain(
const entities = getEntitiesByDomain(
this._config!.area,
this._devicesInArea(this._config!.area, this._devices!),
getDevicesInArea(this._config!.area, this._devices!),
this._entities!,
this._deviceClasses,
this.hass.states
Expand Down Expand Up @@ -237,17 +247,6 @@ export class HuiAreaCard
areas.find((area) => area.area_id === areaId) || null
);

private _devicesInArea = memoizeOne(
(areaId: string | undefined, devices: DeviceRegistryEntry[]) =>
new Set(
areaId
? devices
.filter((device) => device.area_id === areaId)
.map((device) => device.id)
: []
)
);

public hassSubscribe(): UnsubscribeFunc[] {
return [
subscribeAreaRegistry(this.hass!.connection, (areas) => {
Expand Down Expand Up @@ -288,7 +287,7 @@ export class HuiAreaCard
}

if (
changedProps.has("_devicesInArea") ||
changedProps.has("_devices") ||
changedProps.has("_areas") ||
changedProps.has("_entities")
) {
Expand All @@ -311,15 +310,15 @@ export class HuiAreaCard

if (
!this._devices ||
!this._devicesInArea(this._config.area, this._devices) ||
!getDevicesInArea(this._config.area, this._devices) ||
!this._entities
) {
return false;
}

const entities = this._entitiesByDomain(
const entities = getEntitiesByDomain(
this._config.area,
this._devicesInArea(this._config.area, this._devices),
getDevicesInArea(this._config.area, this._devices),
this._entities,
this._deviceClasses,
this.hass.states
Expand Down Expand Up @@ -359,9 +358,9 @@ export class HuiAreaCard
return nothing;
}

const entitiesByDomain = this._entitiesByDomain(
const entitiesByDomain = getEntitiesByDomain(
this._config.area,
this._devicesInArea(this._config.area, this._devices),
getDevicesInArea(this._config.area, this._devices),
this._entities,
this._deviceClasses,
this.hass.states
Expand Down
Loading

0 comments on commit bcabe27

Please sign in to comment.