diff --git a/src/panels/lovelace/common/generate-lovelace-config.ts b/src/panels/lovelace/common/generate-lovelace-config.ts index 0561b1c9db..9627a0364e 100644 --- a/src/panels/lovelace/common/generate-lovelace-config.ts +++ b/src/panels/lovelace/common/generate-lovelace-config.ts @@ -345,7 +345,8 @@ export const generateDefaultViewConfig = ( entityEntries: EntityRegistryEntry[], entities: HassEntities, localize: LocalizeFunc, - energyPrefs?: EnergyPreferences + energyPrefs?: EnergyPreferences, + areaOnly?: boolean ): LovelaceViewConfig => { const states = computeDefaultViewStates(entities, entityEntries); const path = "default_view"; @@ -373,7 +374,7 @@ export const generateDefaultViewConfig = ( path, title, icon, - splittedByAreas.otherEntities, + areaOnly ? {} : splittedByAreas.otherEntities, groupOrders ); @@ -390,7 +391,7 @@ export const generateDefaultViewConfig = ( ); }); - if (energyPrefs) { + if (energyPrefs && !areaOnly) { // Distribution card requires the grid to be configured const grid = energyPrefs.energy_sources.find( (source) => source.type === "grid" diff --git a/src/panels/lovelace/strategies/area-overview-strategy.ts b/src/panels/lovelace/strategies/area-overview-strategy.ts new file mode 100644 index 0000000000..baccfc2fb1 --- /dev/null +++ b/src/panels/lovelace/strategies/area-overview-strategy.ts @@ -0,0 +1,82 @@ +import { STATE_NOT_RUNNING } from "home-assistant-js-websocket"; +import { subscribeOne } from "../../../common/util/subscribe-one"; +import { subscribeAreaRegistry } from "../../../data/area_registry"; +import { subscribeDeviceRegistry } from "../../../data/device_registry"; +import { subscribeEntityRegistry } from "../../../data/entity_registry"; +import { LovelaceViewConfig } from "../../../data/lovelace"; +import { + LovelaceDashboardStrategy, + LovelaceViewStrategy, +} from "./get-strategy"; + +let subscribedRegistries = false; + +export class AreaOverviewStrategy { + static async generateView( + info: Parameters[0] + ): ReturnType { + const hass = info.hass; + const view: LovelaceViewConfig = { cards: [] }; + + if (hass.config.state === STATE_NOT_RUNNING) { + return { + cards: [{ type: "starting" }], + }; + } + + if (hass.config.safe_mode) { + return { + cards: [{ type: "safe-mode" }], + }; + } + + // We leave this here so we always have the freshest data. + if (!subscribedRegistries) { + subscribedRegistries = true; + subscribeAreaRegistry(hass.connection, () => undefined); + subscribeDeviceRegistry(hass.connection, () => undefined); + subscribeEntityRegistry(hass.connection, () => undefined); + } + + const [areaEntries] = await Promise.all([ + subscribeOne(hass.connection, subscribeAreaRegistry), + ]); + + areaEntries.forEach((area) => { + view.cards?.push({ + type: "area", + area: area.area_id, + image: + "https://www.boardandvellum.com/wp-content/uploads/2019/09/16x9-private_offices_vs_open_office_concepts-1242x699.jpg", + }); + }); + + return view; + } + + static async generateDashboard( + info: Parameters[0] + ): ReturnType { + const [areaEntries] = await Promise.all([ + subscribeOne(info.hass.connection, subscribeAreaRegistry), + ]); + + const areaViews = areaEntries.map((area) => ({ + strategy: { + type: "original-states", + options: { areaId: area.area_id }, + }, + title: area.name, + })); + return { + title: info.hass.config.location_name, + views: [ + { + strategy: { type: "area-overview" }, + title: "Overview", + }, + ...areaViews, + ], + }; + } +} diff --git a/src/panels/lovelace/strategies/get-strategy.ts b/src/panels/lovelace/strategies/get-strategy.ts index 0c43803533..6377b4382f 100644 --- a/src/panels/lovelace/strategies/get-strategy.ts +++ b/src/panels/lovelace/strategies/get-strategy.ts @@ -29,6 +29,8 @@ const strategies: Record< (await import("./original-states-strategy")).OriginalStatesStrategy, energy: async () => (await import("../../energy/strategies/energy-strategy")).EnergyStrategy, + "area-overview": async () => + (await import("./area-overview-strategy")).AreaOverviewStrategy, }; const getLovelaceStrategy = async < diff --git a/src/panels/lovelace/strategies/original-states-strategy.ts b/src/panels/lovelace/strategies/original-states-strategy.ts index d8941564a1..3b7aaa731b 100644 --- a/src/panels/lovelace/strategies/original-states-strategy.ts +++ b/src/panels/lovelace/strategies/original-states-strategy.ts @@ -18,6 +18,7 @@ export class OriginalStatesStrategy { info: Parameters[0] ): ReturnType { const hass = info.hass; + const areaId = info.view.strategy?.options?.areaId; if (hass.config.state === STATE_NOT_RUNNING) { return { @@ -66,12 +67,17 @@ export class OriginalStatesStrategy { // User can override default view. If they didn't, we will add one // that contains all entities. const view = generateDefaultViewConfig( - areaEntries, + !areaId + ? areaEntries + : areaEntries.filter( + (area) => area.area_id === info.view.strategy?.options?.area + ), deviceEntries, entityEntries, hass.states, localize, - energyPrefs + energyPrefs, + Boolean(info.view.strategy?.options?.area) ); // Add map of geo locations to default view if loaded