diff --git a/src/panels/energy/constants.ts b/src/panels/energy/constants.ts
new file mode 100644
index 0000000000..e682c7314f
--- /dev/null
+++ b/src/panels/energy/constants.ts
@@ -0,0 +1,2 @@
+export const DEFAULT_ENERGY_COLLECTION_KEY = "energy_dashboard";
+export const DEFAULT_POWER_COLLECTION_KEY = "energy_dashboard_now";
diff --git a/src/panels/energy/ha-panel-energy.ts b/src/panels/energy/ha-panel-energy.ts
index eca00a476d..e5616547f7 100644
--- a/src/panels/energy/ha-panel-energy.ts
+++ b/src/panels/energy/ha-panel-energy.ts
@@ -1,78 +1,20 @@
import type { CSSResultGroup, PropertyValues } from "lit";
-import { LitElement, css, html, nothing } from "lit";
+import { LitElement, css, html } from "lit";
import { customElement, property, state } from "lit/decorators";
import { navigate } from "../../common/navigate";
-import type { LocalizeKeys } from "../../common/translations/localize";
import "../../components/ha-alert";
import "../../components/ha-icon-button-arrow-prev";
import "../../components/ha-menu-button";
import "../../components/ha-top-app-bar-fixed";
-import type { EnergyPreferences } from "../../data/energy";
-import { getEnergyDataCollection } from "../../data/energy";
import type { LovelaceConfig } from "../../data/lovelace/config/types";
-import type { LovelaceViewConfig } from "../../data/lovelace/config/view";
import { haStyle } from "../../resources/styles";
import type { HomeAssistant, PanelInfo } from "../../types";
+import { generateLovelaceDashboardStrategy } from "../lovelace/strategies/get-strategy";
import "../lovelace/hui-root";
import type { Lovelace } from "../lovelace/types";
import "../lovelace/views/hui-view";
import "../lovelace/views/hui-view-container";
-export const DEFAULT_ENERGY_COLLECTION_KEY = "energy_dashboard";
-export const DEFAULT_POWER_COLLECTION_KEY = "energy_dashboard_now";
-
-const EMPTY_PREFERENCES: EnergyPreferences = {
- energy_sources: [],
- device_consumption: [],
- device_consumption_water: [],
-};
-
-const OVERVIEW_VIEW = {
- path: "overview",
- strategy: {
- type: "energy-overview",
- collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
- },
-} as LovelaceViewConfig;
-
-const ENERGY_VIEW = {
- path: "electricity",
- strategy: {
- type: "energy",
- collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
- },
-} as LovelaceViewConfig;
-
-const WATER_VIEW = {
- path: "water",
- strategy: {
- type: "water",
- collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
- },
-} as LovelaceViewConfig;
-
-const GAS_VIEW = {
- path: "gas",
- strategy: {
- type: "gas",
- collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
- },
-} as LovelaceViewConfig;
-
-const POWER_VIEW = {
- path: "now",
- strategy: {
- type: "power",
- collection_key: DEFAULT_POWER_COLLECTION_KEY,
- },
-} as LovelaceViewConfig;
-
-const WIZARD_VIEW = {
- type: "panel",
- path: "setup",
- cards: [{ type: "custom:energy-setup-wizard-card" }],
-};
-
@customElement("ha-panel-energy")
class PanelEnergy extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@@ -88,9 +30,6 @@ class PanelEnergy extends LitElement {
prefix: string;
};
- @state()
- private _prefs?: EnergyPreferences;
-
@state() private _searchParms = new URLSearchParams(window.location.search);
@state()
@@ -115,35 +54,16 @@ class PanelEnergy extends LitElement {
}
}
- private _fetchEnergyPrefs = async (): Promise<
- EnergyPreferences | undefined
- > => {
- const collection = getEnergyDataCollection(this.hass, {
- key: DEFAULT_ENERGY_COLLECTION_KEY,
- });
- try {
- await collection.refresh();
- } catch (err: any) {
- if (err.code === "not_found") {
- return undefined;
- }
- throw err;
- }
- return collection.prefs;
- };
-
private async _loadConfig() {
try {
this._error = undefined;
- const prefs = await this._fetchEnergyPrefs();
- this._prefs = prefs || EMPTY_PREFERENCES;
+ await this._setLovelace();
} catch (err) {
// eslint-disable-next-line no-console
- console.error("Failed to load prefs:", err);
- this._prefs = EMPTY_PREFERENCES;
+ console.error("Failed to load energy config:", err);
this._error = (err as Error).message || "Unknown error";
+ return;
}
- await this._setLovelace();
// Check if current path is valid, navigate to first view if not
const views = this._lovelace!.config?.views || [];
@@ -158,7 +78,10 @@ class PanelEnergy extends LitElement {
}
private async _setLovelace() {
- const config = await this._generateLovelaceConfig();
+ const config: LovelaceConfig = await generateLovelaceDashboardStrategy(
+ { strategy: { type: "energy" } },
+ this.hass
+ );
this._lovelace = {
config: config,
@@ -188,8 +111,7 @@ class PanelEnergy extends LitElement {
`;
}
- if (!this._prefs) {
- // Still loading
+ if (!this._lovelace) {
return html`
@@ -197,10 +119,6 @@ class PanelEnergy extends LitElement {
`;
}
- if (!this._lovelace) {
- return nothing;
- }
-
return html`
{
- if (
- !this._prefs ||
- (this._prefs.device_consumption.length === 0 &&
- this._prefs.energy_sources.length === 0)
- ) {
- await import("./cards/energy-setup-wizard-card");
- return {
- views: [WIZARD_VIEW],
- };
- }
-
- const hasEnergy = this._prefs.energy_sources.some((source) =>
- ["grid", "solar", "battery"].includes(source.type)
- );
-
- const hasPowerSource = this._prefs.energy_sources.some((source) => {
- if (source.type === "solar" && source.stat_rate) return true;
- if (source.type === "battery" && source.stat_rate) return true;
- if (source.type === "grid") {
- return !!source.stat_rate || !!source.power_config;
- }
- return false;
- });
-
- const hasDevicePower = this._prefs.device_consumption.some(
- (device) => device.stat_rate
- );
-
- const hasPower = hasPowerSource || hasDevicePower;
-
- const hasWater =
- this._prefs.energy_sources.some((source) => source.type === "water") ||
- this._prefs.device_consumption_water?.length > 0;
-
- const hasGas = this._prefs.energy_sources.some(
- (source) => source.type === "gas"
- );
-
- const hasDeviceConsumption = this._prefs.device_consumption.length > 0;
-
- const views: LovelaceViewConfig[] = [];
- if (hasEnergy || hasDeviceConsumption) {
- views.push(ENERGY_VIEW);
- }
- if (hasGas) {
- views.push(GAS_VIEW);
- }
- if (hasWater) {
- views.push(WATER_VIEW);
- }
- if (hasPower) {
- views.push(POWER_VIEW);
- }
- if (
- hasPowerSource ||
- [hasEnergy, hasGas, hasWater].filter(Boolean).length > 1
- ) {
- views.unshift(OVERVIEW_VIEW);
- }
- return {
- views: views.map((view) => ({
- ...view,
- title:
- view.title ||
- this.hass.localize(
- `ui.panel.energy.title.${view.path}` as LocalizeKeys
- ),
- })),
- };
- }
-
private _navigateConfig(ev?: Event) {
ev?.stopPropagation();
const viewPath = this.route?.path?.split("/")[1] || "";
diff --git a/src/panels/energy/strategies/energy-dashboard-strategy.ts b/src/panels/energy/strategies/energy-dashboard-strategy.ts
new file mode 100644
index 0000000000..a5bd9bef7e
--- /dev/null
+++ b/src/panels/energy/strategies/energy-dashboard-strategy.ts
@@ -0,0 +1,170 @@
+import { ReactiveElement } from "lit";
+import { customElement } from "lit/decorators";
+import { getEnergyDataCollection } from "../../../data/energy";
+import type { EnergyPreferences } from "../../../data/energy";
+import type { LovelaceStrategyConfig } from "../../../data/lovelace/config/strategy";
+import type { LovelaceConfig } from "../../../data/lovelace/config/types";
+import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
+import type { LocalizeKeys } from "../../../common/translations/localize";
+import type { HomeAssistant } from "../../../types";
+import {
+ DEFAULT_ENERGY_COLLECTION_KEY,
+ DEFAULT_POWER_COLLECTION_KEY,
+} from "../constants";
+
+const OVERVIEW_VIEW = {
+ path: "overview",
+ strategy: {
+ type: "energy-overview",
+ collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
+ },
+} as LovelaceViewConfig;
+
+const ENERGY_VIEW = {
+ path: "electricity",
+ strategy: {
+ type: "energy",
+ collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
+ },
+} as LovelaceViewConfig;
+
+const WATER_VIEW = {
+ path: "water",
+ strategy: {
+ type: "water",
+ collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
+ },
+} as LovelaceViewConfig;
+
+const GAS_VIEW = {
+ path: "gas",
+ strategy: {
+ type: "gas",
+ collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
+ },
+} as LovelaceViewConfig;
+
+const POWER_VIEW = {
+ path: "now",
+ strategy: {
+ type: "power",
+ collection_key: DEFAULT_POWER_COLLECTION_KEY,
+ },
+} as LovelaceViewConfig;
+
+const WIZARD_VIEW = {
+ type: "panel",
+ path: "setup",
+ cards: [{ type: "custom:energy-setup-wizard-card" }],
+};
+
+const EMPTY_PREFERENCES: EnergyPreferences = {
+ energy_sources: [],
+ device_consumption: [],
+ device_consumption_water: [],
+};
+
+export interface EnergyDashboardStrategyConfig extends LovelaceStrategyConfig {
+ type: "energy";
+}
+
+@customElement("energy-dashboard-strategy")
+export class EnergyDashboardStrategy extends ReactiveElement {
+ static async generate(
+ _config: EnergyDashboardStrategyConfig,
+ hass: HomeAssistant
+ ): Promise {
+ const prefs = await fetchEnergyPrefs(hass);
+
+ if (
+ !prefs ||
+ (prefs.device_consumption.length === 0 &&
+ prefs.energy_sources.length === 0)
+ ) {
+ await import("../cards/energy-setup-wizard-card");
+ return {
+ views: [WIZARD_VIEW],
+ };
+ }
+
+ const hasEnergy = prefs.energy_sources.some((source) =>
+ ["grid", "solar", "battery"].includes(source.type)
+ );
+
+ const hasPowerSource = prefs.energy_sources.some((source) => {
+ if (source.type === "solar" && source.stat_rate) return true;
+ if (source.type === "battery" && source.stat_rate) return true;
+ if (source.type === "grid") {
+ return !!source.stat_rate || !!source.power_config;
+ }
+ return false;
+ });
+
+ const hasDevicePower = prefs.device_consumption.some(
+ (device) => device.stat_rate
+ );
+
+ const hasPower = hasPowerSource || hasDevicePower;
+
+ const hasWater =
+ prefs.energy_sources.some((source) => source.type === "water") ||
+ prefs.device_consumption_water?.length > 0;
+
+ const hasGas = prefs.energy_sources.some((source) => source.type === "gas");
+
+ const hasDeviceConsumption = prefs.device_consumption.length > 0;
+
+ const views: LovelaceViewConfig[] = [];
+ if (hasEnergy || hasDeviceConsumption) {
+ views.push(ENERGY_VIEW);
+ }
+ if (hasGas) {
+ views.push(GAS_VIEW);
+ }
+ if (hasWater) {
+ views.push(WATER_VIEW);
+ }
+ if (hasPower) {
+ views.push(POWER_VIEW);
+ }
+ if (
+ hasPowerSource ||
+ [hasEnergy, hasGas, hasWater].filter(Boolean).length > 1
+ ) {
+ views.unshift(OVERVIEW_VIEW);
+ }
+ return {
+ views: views.map((view) => ({
+ ...view,
+ title:
+ view.title ||
+ hass.localize(`ui.panel.energy.title.${view.path}` as LocalizeKeys),
+ })),
+ };
+ }
+
+ static noEditor = true;
+}
+
+async function fetchEnergyPrefs(
+ hass: HomeAssistant
+): Promise {
+ const collection = getEnergyDataCollection(hass, {
+ key: DEFAULT_ENERGY_COLLECTION_KEY,
+ });
+ try {
+ await collection.refresh();
+ } catch (err: any) {
+ if (err.code === "not_found") {
+ return EMPTY_PREFERENCES;
+ }
+ throw err;
+ }
+ return collection.prefs || EMPTY_PREFERENCES;
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "energy-dashboard-strategy": EnergyDashboardStrategy;
+ }
+}
diff --git a/src/panels/energy/strategies/energy-overview-view-strategy.ts b/src/panels/energy/strategies/energy-overview-view-strategy.ts
index 2905ce0cfe..8a8523f893 100644
--- a/src/panels/energy/strategies/energy-overview-view-strategy.ts
+++ b/src/panels/energy/strategies/energy-overview-view-strategy.ts
@@ -5,7 +5,7 @@ import { getEnergyDataCollection } from "../../../data/energy";
import type { HomeAssistant } from "../../../types";
import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
import type { LovelaceStrategyConfig } from "../../../data/lovelace/config/strategy";
-import { DEFAULT_ENERGY_COLLECTION_KEY } from "../ha-panel-energy";
+import { DEFAULT_ENERGY_COLLECTION_KEY } from "../constants";
@customElement("energy-overview-view-strategy")
export class EnergyOverviewViewStrategy extends ReactiveElement {
diff --git a/src/panels/energy/strategies/energy-view-strategy.ts b/src/panels/energy/strategies/energy-view-strategy.ts
index dea22e7a3f..5f620f8ad7 100644
--- a/src/panels/energy/strategies/energy-view-strategy.ts
+++ b/src/panels/energy/strategies/energy-view-strategy.ts
@@ -6,7 +6,7 @@ import type { LovelaceCardConfig } from "../../../data/lovelace/config/card";
import type { LovelaceStrategyConfig } from "../../../data/lovelace/config/strategy";
import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
import type { HomeAssistant } from "../../../types";
-import { DEFAULT_ENERGY_COLLECTION_KEY } from "../ha-panel-energy";
+import { DEFAULT_ENERGY_COLLECTION_KEY } from "../constants";
import { shouldShowFloorsAndAreas } from "./show-floors-and-areas";
import {
LARGE_SCREEN_CONDITION,
diff --git a/src/panels/energy/strategies/gas-view-strategy.ts b/src/panels/energy/strategies/gas-view-strategy.ts
index 59a754daa7..15e9d74800 100644
--- a/src/panels/energy/strategies/gas-view-strategy.ts
+++ b/src/panels/energy/strategies/gas-view-strategy.ts
@@ -4,7 +4,7 @@ import { getEnergyDataCollection } from "../../../data/energy";
import type { HomeAssistant } from "../../../types";
import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
import type { LovelaceStrategyConfig } from "../../../data/lovelace/config/strategy";
-import { DEFAULT_ENERGY_COLLECTION_KEY } from "../ha-panel-energy";
+import { DEFAULT_ENERGY_COLLECTION_KEY } from "../constants";
import type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
@customElement("gas-view-strategy")
diff --git a/src/panels/energy/strategies/power-view-strategy.ts b/src/panels/energy/strategies/power-view-strategy.ts
index f223fa8e16..1c3e9110c7 100644
--- a/src/panels/energy/strategies/power-view-strategy.ts
+++ b/src/panels/energy/strategies/power-view-strategy.ts
@@ -4,7 +4,7 @@ import { getEnergyDataCollection } from "../../../data/energy";
import type { LovelaceStrategyConfig } from "../../../data/lovelace/config/strategy";
import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
import type { HomeAssistant } from "../../../types";
-import { DEFAULT_ENERGY_COLLECTION_KEY } from "../ha-panel-energy";
+import { DEFAULT_ENERGY_COLLECTION_KEY } from "../constants";
import { shouldShowFloorsAndAreas } from "./show-floors-and-areas";
import type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
import type { LovelaceBadgeConfig } from "../../../data/lovelace/config/badge";
diff --git a/src/panels/energy/strategies/water-view-strategy.ts b/src/panels/energy/strategies/water-view-strategy.ts
index 64209107b3..258aeaa794 100644
--- a/src/panels/energy/strategies/water-view-strategy.ts
+++ b/src/panels/energy/strategies/water-view-strategy.ts
@@ -5,7 +5,7 @@ import type { LovelaceSectionConfig } from "../../../data/lovelace/config/sectio
import type { LovelaceStrategyConfig } from "../../../data/lovelace/config/strategy";
import type { LovelaceViewConfig } from "../../../data/lovelace/config/view";
import type { HomeAssistant } from "../../../types";
-import { DEFAULT_ENERGY_COLLECTION_KEY } from "../ha-panel-energy";
+import { DEFAULT_ENERGY_COLLECTION_KEY } from "../constants";
import { shouldShowFloorsAndAreas } from "./show-floors-and-areas";
@customElement("water-view-strategy")
diff --git a/src/panels/lovelace/strategies/get-strategy.ts b/src/panels/lovelace/strategies/get-strategy.ts
index 5295902508..139a64a8c5 100644
--- a/src/panels/lovelace/strategies/get-strategy.ts
+++ b/src/panels/lovelace/strategies/get-strategy.ts
@@ -34,6 +34,7 @@ const STRATEGIES: Record> = {
iframe: () => import("./iframe/iframe-dashboard-strategy"),
areas: () => import("./areas/areas-dashboard-strategy"),
home: () => import("./home/home-dashboard-strategy"),
+ energy: () => import("../../energy/strategies/energy-dashboard-strategy"),
},
view: {
"original-states": () =>