Skip to content

Commit f8923ed

Browse files
authored
Split Energy panel into overview and electricity view (home-assistant#27534)
1 parent 20d0548 commit f8923ed

File tree

8 files changed

+422
-109
lines changed

8 files changed

+422
-109
lines changed

src/panels/energy/ha-panel-energy.ts

Lines changed: 118 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
1+
import type { CSSResultGroup, PropertyValues } from "lit";
22
import { LitElement, css, html, nothing } from "lit";
33
import { mdiPencil, mdiDownload } from "@mdi/js";
44
import { customElement, property, state } from "lit/decorators";
55
import "../../components/ha-menu-button";
66
import "../../components/ha-icon-button-arrow-prev";
77
import "../../components/ha-list-item";
88
import "../../components/ha-top-app-bar-fixed";
9+
import "../../components/ha-alert";
910
import type { LovelaceConfig } from "../../data/lovelace/config/types";
1011
import { haStyle } from "../../resources/styles";
1112
import type { HomeAssistant } from "../../types";
@@ -21,6 +22,7 @@ import type {
2122
GasSourceTypeEnergyPreference,
2223
WaterSourceTypeEnergyPreference,
2324
DeviceConsumptionEnergyPreference,
25+
EnergyCollection,
2426
} from "../../data/energy";
2527
import {
2628
computeConsumptionData,
@@ -30,12 +32,27 @@ import {
3032
import { fileDownload } from "../../util/file_download";
3133
import type { StatisticValue } from "../../data/recorder";
3234

35+
export const DEFAULT_ENERGY_COLLECTION_KEY = "energy_dashboard";
36+
3337
const ENERGY_LOVELACE_CONFIG: LovelaceConfig = {
3438
views: [
3539
{
3640
strategy: {
37-
type: "energy",
41+
type: "energy-overview",
42+
collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
43+
},
44+
},
45+
{
46+
strategy: {
47+
type: "energy-electricity",
48+
collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
3849
},
50+
path: "electricity",
51+
},
52+
{
53+
type: "panel",
54+
path: "setup",
55+
cards: [{ type: "custom:energy-setup-wizard-card" }],
3956
},
4057
],
4158
};
@@ -46,13 +63,30 @@ class PanelEnergy extends LitElement {
4663

4764
@property({ type: Boolean, reflect: true }) public narrow = false;
4865

49-
@state() private _viewIndex = 0;
50-
5166
@state() private _lovelace?: Lovelace;
5267

5368
@state() private _searchParms = new URLSearchParams(window.location.search);
5469

55-
public willUpdate(changedProps: PropertyValues) {
70+
@state() private _error?: string;
71+
72+
@property({ attribute: false }) public route?: {
73+
path: string;
74+
prefix: string;
75+
};
76+
77+
private _energyCollection?: EnergyCollection;
78+
79+
get _viewPath(): string | undefined {
80+
const viewPath: string | undefined = this.route!.path.split("/")[1];
81+
return viewPath ? decodeURI(viewPath) : undefined;
82+
}
83+
84+
public connectedCallback() {
85+
super.connectedCallback();
86+
this._loadPrefs();
87+
}
88+
89+
public async willUpdate(changedProps: PropertyValues) {
5690
if (!this.hasUpdated) {
5791
this.hass.loadFragmentTranslation("lovelace");
5892
}
@@ -62,22 +96,71 @@ class PanelEnergy extends LitElement {
6296
const oldHass = changedProps.get("hass") as this["hass"];
6397
if (oldHass?.locale !== this.hass.locale) {
6498
this._setLovelace();
65-
}
66-
if (oldHass && oldHass.localize !== this.hass.localize) {
99+
} else if (oldHass && oldHass.localize !== this.hass.localize) {
67100
this._reloadView();
68101
}
69102
}
70103

104+
private async _loadPrefs() {
105+
if (this._viewPath === "setup") {
106+
await import("./cards/energy-setup-wizard-card");
107+
} else {
108+
this._energyCollection = getEnergyDataCollection(this.hass, {
109+
key: DEFAULT_ENERGY_COLLECTION_KEY,
110+
});
111+
try {
112+
// Have to manually refresh here as we don't want to subscribe yet
113+
await this._energyCollection.refresh();
114+
} catch (err: any) {
115+
if (err.code === "not_found") {
116+
navigate("/energy/setup");
117+
}
118+
this._error = err.message;
119+
return;
120+
}
121+
const prefs = this._energyCollection.prefs!;
122+
if (
123+
prefs.device_consumption.length === 0 &&
124+
prefs.energy_sources.length === 0
125+
) {
126+
// No energy sources available, start from scratch
127+
navigate("/energy/setup");
128+
}
129+
}
130+
}
131+
71132
private _back(ev) {
72133
ev.stopPropagation();
73134
goBack();
74135
}
75136

76-
protected render(): TemplateResult {
137+
protected render() {
138+
if (!this._energyCollection?.prefs) {
139+
// Still loading
140+
return html`<div class="centered">
141+
<ha-spinner size="large"></ha-spinner>
142+
</div>`;
143+
}
144+
const { prefs } = this._energyCollection;
145+
const isSingleView = prefs.energy_sources.every((source) =>
146+
["grid", "solar", "battery"].includes(source.type)
147+
);
148+
let viewPath = this._viewPath;
149+
if (isSingleView) {
150+
// if only electricity sources, show electricity view directly
151+
viewPath = "electricity";
152+
}
153+
const viewIndex = Math.max(
154+
ENERGY_LOVELACE_CONFIG.views.findIndex((view) => view.path === viewPath),
155+
0
156+
);
157+
const showBack =
158+
this._searchParms.has("historyBack") || (!isSingleView && viewIndex > 0);
159+
77160
return html`
78161
<div class="header">
79162
<div class="toolbar">
80-
${this._searchParms.has("historyBack")
163+
${showBack
81164
? html`
82165
<ha-icon-button-arrow-prev
83166
@click=${this._back}
@@ -99,7 +182,7 @@ class PanelEnergy extends LitElement {
99182
100183
<hui-energy-period-selector
101184
.hass=${this.hass}
102-
collection-key="energy_dashboard"
185+
.collectionKey=${DEFAULT_ENERGY_COLLECTION_KEY}
103186
>
104187
${this.hass.user?.is_admin
105188
? html` <ha-list-item
@@ -127,12 +210,21 @@ class PanelEnergy extends LitElement {
127210
.hass=${this.hass}
128211
@reload-energy-panel=${this._reloadView}
129212
>
130-
<hui-view
131-
.hass=${this.hass}
132-
.narrow=${this.narrow}
133-
.lovelace=${this._lovelace}
134-
.index=${this._viewIndex}
135-
></hui-view>
213+
${this._error
214+
? html`<div class="centered">
215+
<ha-alert alert-type="error">
216+
An error occurred while fetching your energy preferences:
217+
${this._error}
218+
</ha-alert>
219+
</div>`
220+
: this._lovelace
221+
? html`<hui-view
222+
.hass=${this.hass}
223+
.narrow=${this.narrow}
224+
.lovelace=${this._lovelace}
225+
.index=${viewIndex}
226+
></hui-view>`
227+
: nothing}
136228
</hui-view-container>
137229
`;
138230
}
@@ -160,9 +252,7 @@ class PanelEnergy extends LitElement {
160252

161253
private async _dumpCSV(ev) {
162254
ev.stopPropagation();
163-
const energyData = getEnergyDataCollection(this.hass, {
164-
key: "energy_dashboard",
165-
});
255+
const energyData = this._energyCollection!;
166256

167257
if (!energyData.prefs || !energyData.state.stats) {
168258
return;
@@ -459,11 +549,11 @@ class PanelEnergy extends LitElement {
459549
}
460550

461551
private _reloadView() {
462-
// Force strategy to be re-run by make a copy of the view
552+
// Force strategy to be re-run by making a copy of the view
463553
const config = this._lovelace!.config;
464554
this._lovelace = {
465555
...this._lovelace!,
466-
config: { ...config, views: [{ ...config.views[0] }] },
556+
config: { ...config, views: config.views.map((view) => ({ ...view })) },
467557
};
468558
}
469559

@@ -565,6 +655,13 @@ class PanelEnergy extends LitElement {
565655
flex: 1 1 100%;
566656
max-width: 100%;
567657
}
658+
.centered {
659+
width: 100%;
660+
height: 100%;
661+
display: flex;
662+
align-items: center;
663+
justify-content: center;
664+
}
568665
`,
569666
];
570667
}

0 commit comments

Comments
 (0)