Push map strategy logic down into map card (#24303)

This commit is contained in:
karwosts 2025-02-24 06:13:52 -08:00 committed by GitHub
parent fc4996412e
commit 2b1f301db6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 52 additions and 29 deletions

View File

@ -12,6 +12,7 @@ import memoizeOne from "memoize-one";
import { getColorByIndex } from "../../../common/color/colors";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { deepEqual } from "../../../common/util/deep-equal";
import parseAspectRatio from "../../../common/util/parse-aspect-ratio";
@ -80,14 +81,38 @@ class HuiMapCard extends LitElement implements LovelaceCard {
private _subscribed?: Promise<(() => Promise<void>) | undefined>;
private _getAllEntities(): string[] {
const hass = this.hass!;
const personSources = new Set<string>();
const locationEntities: string[] = [];
Object.values(hass.states).forEach((entity) => {
if (
!("latitude" in entity.attributes) ||
!("longitude" in entity.attributes)
) {
return;
}
locationEntities.push(entity.entity_id);
if (computeStateDomain(entity) === "person" && entity.attributes.source) {
personSources.add(entity.attributes.source);
}
});
return locationEntities.filter((entity) => !personSources.has(entity));
}
public setConfig(config: MapCardConfig): void {
if (!config) {
throw new Error("Error in card configuration.");
}
if (!config.entities?.length && !config.geo_location_sources) {
if (
!config.show_all &&
!config.entities?.length &&
!config.geo_location_sources
) {
throw new Error(
"Either entities or geo_location_sources must be specified"
"Either show_all, entities, or geo_location_sources must be specified"
);
}
if (config.entities && !Array.isArray(config.entities)) {
@ -99,10 +124,17 @@ class HuiMapCard extends LitElement implements LovelaceCard {
) {
throw new Error("Parameter geo_location_sources needs to be an array");
}
this._config = config;
this._configEntities = config.entities
? processConfigEntities<MapEntityConfig>(config.entities)
if (config.show_all && (config.entities || config.geo_location_sources)) {
throw new Error(
"Cannot specify show_all and entities or geo_location_sources"
);
}
this._config = { ...config };
if (this.hass && config.show_all) {
this._config.entities = this._getAllEntities();
}
this._configEntities = this._config.entities
? processConfigEntities<MapEntityConfig>(this._config.entities)
: [];
this._mapEntities = this._getMapEntities();
}
@ -239,6 +271,18 @@ class HuiMapCard extends LitElement implements LovelaceCard {
protected willUpdate(changedProps: PropertyValues): void {
super.willUpdate(changedProps);
if (
this._config?.show_all &&
!this._config?.entities &&
this.hass &&
changedProps.has("hass")
) {
this._config.entities = this._getAllEntities();
this._configEntities = processConfigEntities<MapEntityConfig>(
this._config.entities
);
this._mapEntities = this._getMapEntities();
}
if (
changedProps.has("hass") &&
this._config?.geo_location_sources &&

View File

@ -61,7 +61,7 @@ const cardConfigStruct = assign(
aspect_ratio: optional(string()),
default_zoom: optional(number()),
dark_mode: optional(boolean()),
entities: array(mapEntitiesConfigStruct),
entities: optional(array(mapEntitiesConfigStruct)),
hours_to_show: optional(number()),
geo_location_sources: optional(array(geoSourcesConfigStruct)),
auto_fit: optional(boolean()),

View File

@ -1,6 +1,5 @@
import { ReactiveElement } from "lit";
import { customElement } from "lit/decorators";
import { computeStateDomain } from "../../../../common/entity/compute_state_domain";
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
import type { HomeAssistant } from "../../../../types";
import type { MapCardConfig } from "../../cards/types";
@ -9,32 +8,12 @@ export interface MapViewStrategyConfig {
type: "map";
}
const getMapEntities = (hass: HomeAssistant) => {
const personSources = new Set<string>();
const locationEntities: string[] = [];
Object.values(hass.states).forEach((entity) => {
if (
!("latitude" in entity.attributes) ||
!("longitude" in entity.attributes)
) {
return;
}
locationEntities.push(entity.entity_id);
if (computeStateDomain(entity) === "person" && entity.attributes.source) {
personSources.add(entity.attributes.source);
}
});
return locationEntities.filter((entity) => !personSources.has(entity));
};
@customElement("map-view-strategy")
export class MapViewStrategy extends ReactiveElement {
static async generate(
_config: MapViewStrategyConfig,
hass: HomeAssistant
): Promise<LovelaceViewConfig> {
const entities = getMapEntities(hass);
return {
type: "panel",
title: hass.localize("panel.map"),
@ -43,7 +22,7 @@ export class MapViewStrategy extends ReactiveElement {
{
type: "map",
auto_fit: true,
entities: entities,
show_all: true,
} as MapCardConfig,
],
};