mirror of
https://github.com/home-assistant/frontend.git
synced 2025-12-24 12:49:19 +00:00
Update Energy dashboard layout (#28283)
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
import { mdiDownload, mdiPencil } from "@mdi/js";
|
||||
import { mdiDownload } from "@mdi/js";
|
||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { goBack, navigate } from "../../common/navigate";
|
||||
import { navigate } from "../../common/navigate";
|
||||
import "../../components/ha-alert";
|
||||
import "../../components/ha-icon-button-arrow-prev";
|
||||
import "../../components/ha-list-item";
|
||||
import "../../components/ha-menu-button";
|
||||
import "../../components/ha-top-app-bar-fixed";
|
||||
import type {
|
||||
@@ -23,16 +22,14 @@ import {
|
||||
getSummedData,
|
||||
} from "../../data/energy";
|
||||
import type { LovelaceConfig } from "../../data/lovelace/config/types";
|
||||
import {
|
||||
isStrategyView,
|
||||
type LovelaceViewConfig,
|
||||
} from "../../data/lovelace/config/view";
|
||||
import type { LovelaceViewConfig } from "../../data/lovelace/config/view";
|
||||
import type { StatisticValue } from "../../data/recorder";
|
||||
import { haStyle } from "../../resources/styles";
|
||||
import type { HomeAssistant, PanelInfo } from "../../types";
|
||||
import { fileDownload } from "../../util/file_download";
|
||||
import "../lovelace/components/hui-energy-period-selector";
|
||||
import "../lovelace/hui-root";
|
||||
import type { ExtraActionItem } from "../lovelace/hui-root";
|
||||
import type { Lovelace } from "../lovelace/types";
|
||||
import "../lovelace/views/hui-view";
|
||||
import "../lovelace/views/hui-view-container";
|
||||
@@ -51,37 +48,38 @@ const OVERVIEW_VIEW = {
|
||||
strategy: {
|
||||
type: "energy-overview",
|
||||
collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
|
||||
allow_compare: false,
|
||||
},
|
||||
} as LovelaceViewConfig;
|
||||
|
||||
const ENERGY_VIEW = {
|
||||
path: "electricity",
|
||||
back_path: "/energy",
|
||||
strategy: {
|
||||
type: "energy",
|
||||
collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
|
||||
allow_compare: true,
|
||||
},
|
||||
} as LovelaceViewConfig;
|
||||
|
||||
const WATER_VIEW = {
|
||||
back_path: "/energy",
|
||||
path: "water",
|
||||
strategy: {
|
||||
type: "water",
|
||||
collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
|
||||
allow_compare: true,
|
||||
},
|
||||
} as LovelaceViewConfig;
|
||||
|
||||
const GAS_VIEW = {
|
||||
path: "gas",
|
||||
strategy: {
|
||||
type: "gas",
|
||||
collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
|
||||
},
|
||||
} as LovelaceViewConfig;
|
||||
|
||||
const POWER_VIEW = {
|
||||
back_path: "/energy",
|
||||
path: "power",
|
||||
path: "now",
|
||||
strategy: {
|
||||
type: "power",
|
||||
collection_key: DEFAULT_ENERGY_COLLECTION_KEY,
|
||||
allow_compare: false,
|
||||
collection_key: "energy_dashboard_now",
|
||||
},
|
||||
} as LovelaceViewConfig;
|
||||
|
||||
@@ -101,8 +99,6 @@ class PanelEnergy extends LitElement {
|
||||
|
||||
@state() private _lovelace?: Lovelace;
|
||||
|
||||
@state() private _searchParms = new URLSearchParams(window.location.search);
|
||||
|
||||
@property({ attribute: false }) public route?: {
|
||||
path: string;
|
||||
prefix: string;
|
||||
@@ -114,6 +110,16 @@ class PanelEnergy extends LitElement {
|
||||
@state()
|
||||
private _error?: string;
|
||||
|
||||
private get _extraActionItems(): ExtraActionItem[] {
|
||||
return [
|
||||
{
|
||||
icon: mdiDownload,
|
||||
labelKey: "ui.panel.energy.download_data",
|
||||
action: this._dumpCSV,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
public willUpdate(changedProps: PropertyValues) {
|
||||
super.willUpdate(changedProps);
|
||||
// Initial setup
|
||||
@@ -188,16 +194,11 @@ class PanelEnergy extends LitElement {
|
||||
enableFullEditMode: () => undefined,
|
||||
saveConfig: async () => undefined,
|
||||
deleteConfig: async () => undefined,
|
||||
setEditMode: () => undefined,
|
||||
setEditMode: () => this._navigateConfig(),
|
||||
showToast: () => undefined,
|
||||
};
|
||||
}
|
||||
|
||||
private _back(ev) {
|
||||
ev.stopPropagation();
|
||||
goBack();
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (this._error) {
|
||||
return html`
|
||||
@@ -222,17 +223,6 @@ class PanelEnergy extends LitElement {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const viewPath: string | undefined = this.route!.path.split("/")[1];
|
||||
|
||||
const views = this._lovelace.config?.views || [];
|
||||
const viewIndex = Math.max(
|
||||
views.findIndex((view) => view.path === viewPath),
|
||||
0
|
||||
);
|
||||
const view = views[viewIndex];
|
||||
|
||||
const showBack = this._searchParms.has("historyBack") || viewIndex > 0;
|
||||
|
||||
return html`
|
||||
<hui-root
|
||||
.hass=${this.hass}
|
||||
@@ -240,60 +230,9 @@ class PanelEnergy extends LitElement {
|
||||
.lovelace=${this._lovelace}
|
||||
.route=${this.route}
|
||||
.panel=${this.panel}
|
||||
.extraActionItems=${this._extraActionItems}
|
||||
@reload-energy-panel=${this._reloadConfig}
|
||||
>
|
||||
<div class="toolbar" slot="toolbar">
|
||||
${showBack
|
||||
? html`
|
||||
<ha-icon-button-arrow-prev
|
||||
@click=${this._back}
|
||||
slot="navigationIcon"
|
||||
></ha-icon-button-arrow-prev>
|
||||
`
|
||||
: html`
|
||||
<ha-menu-button
|
||||
slot="navigationIcon"
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
></ha-menu-button>
|
||||
`}
|
||||
${!this.narrow
|
||||
? html`<div class="main-title">
|
||||
${this.hass.localize(
|
||||
`ui.panel.energy.title.${viewPath}` as LocalizeKeys
|
||||
) || this.hass.localize("panel.energy")}
|
||||
</div>`
|
||||
: nothing}
|
||||
|
||||
<hui-energy-period-selector
|
||||
.hass=${this.hass}
|
||||
.collectionKey=${DEFAULT_ENERGY_COLLECTION_KEY}
|
||||
.allowCompare=${isStrategyView(view) && view.strategy.allow_compare}
|
||||
>
|
||||
${this.hass.user?.is_admin
|
||||
? html`
|
||||
<ha-list-item
|
||||
slot="overflow-menu"
|
||||
graphic="icon"
|
||||
@request-selected=${this._navigateConfig}
|
||||
>
|
||||
<ha-svg-icon slot="graphic" .path=${mdiPencil}>
|
||||
</ha-svg-icon>
|
||||
${this.hass!.localize("ui.panel.energy.configure")}
|
||||
</ha-list-item>
|
||||
`
|
||||
: nothing}
|
||||
<ha-list-item
|
||||
slot="overflow-menu"
|
||||
graphic="icon"
|
||||
@request-selected=${this._dumpCSV}
|
||||
>
|
||||
<ha-svg-icon slot="graphic" .path=${mdiDownload}> </ha-svg-icon>
|
||||
${this.hass!.localize("ui.panel.energy.download_data")}
|
||||
</ha-list-item>
|
||||
</hui-energy-period-selector>
|
||||
</div>
|
||||
</hui-root>
|
||||
></hui-root>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -325,29 +264,44 @@ class PanelEnergy extends LitElement {
|
||||
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 views: LovelaceViewConfig[] = [];
|
||||
if (hasEnergy) {
|
||||
views.push(ENERGY_VIEW);
|
||||
}
|
||||
if (hasPower) {
|
||||
views.push(POWER_VIEW);
|
||||
if (hasGas) {
|
||||
views.push(GAS_VIEW);
|
||||
}
|
||||
if (hasWater) {
|
||||
views.push(WATER_VIEW);
|
||||
}
|
||||
if (hasPower) {
|
||||
views.push(POWER_VIEW);
|
||||
}
|
||||
if (views.length > 1) {
|
||||
views.unshift(OVERVIEW_VIEW);
|
||||
}
|
||||
return { views };
|
||||
return {
|
||||
views: views.map((view) => ({
|
||||
...view,
|
||||
title:
|
||||
view.title ||
|
||||
this.hass.localize(
|
||||
`ui.panel.energy.title.${view.path}` as LocalizeKeys
|
||||
),
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
private _navigateConfig(ev) {
|
||||
ev.stopPropagation();
|
||||
private _navigateConfig(ev?: Event) {
|
||||
ev?.stopPropagation();
|
||||
navigate("/config/energy?historyBack=1");
|
||||
}
|
||||
|
||||
private async _dumpCSV(ev) {
|
||||
ev.stopPropagation();
|
||||
private _dumpCSV = async () => {
|
||||
const energyData = getEnergyDataCollection(this.hass, {
|
||||
key: "energy_dashboard",
|
||||
});
|
||||
@@ -659,7 +613,7 @@ class PanelEnergy extends LitElement {
|
||||
});
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
fileDownload(url, "energy.csv");
|
||||
}
|
||||
};
|
||||
|
||||
private _reloadConfig() {
|
||||
this._loadConfig();
|
||||
@@ -669,21 +623,8 @@ class PanelEnergy extends LitElement {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
:host hui-energy-period-selector {
|
||||
flex-grow: 1;
|
||||
padding-left: 32px;
|
||||
padding-inline-start: 32px;
|
||||
padding-inline-end: initial;
|
||||
--disabled-text-color: rgba(var(--rgb-text-primary-color), 0.5);
|
||||
direction: var(--direction);
|
||||
--date-range-picker-max-height: calc(100vh - 80px);
|
||||
}
|
||||
:host([narrow]) hui-energy-period-selector {
|
||||
padding-left: 0px;
|
||||
padding-inline-start: 0px;
|
||||
padding-inline-end: initial;
|
||||
}
|
||||
:host {
|
||||
--ha-view-sections-column-max-width: 100%;
|
||||
-ms-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
|
||||
@@ -17,7 +17,7 @@ const sourceHasCost = (source: Record<string, any>): boolean =>
|
||||
);
|
||||
|
||||
@customElement("energy-overview-view-strategy")
|
||||
export class EnergyViewStrategy extends ReactiveElement {
|
||||
export class EnergyOverviewViewStrategy extends ReactiveElement {
|
||||
static async generate(
|
||||
_config: LovelaceStrategyConfig,
|
||||
hass: HomeAssistant
|
||||
@@ -55,6 +55,9 @@ export class EnergyViewStrategy extends ReactiveElement {
|
||||
const hasBattery = prefs.energy_sources.some(
|
||||
(source) => source.type === "battery"
|
||||
);
|
||||
const hasSolar = prefs.energy_sources.some(
|
||||
(source) => source.type === "solar"
|
||||
);
|
||||
const hasWaterSources = prefs.energy_sources.some(
|
||||
(source) => source.type === "water"
|
||||
);
|
||||
@@ -65,9 +68,6 @@ export class EnergyViewStrategy extends ReactiveElement {
|
||||
(source.type === "battery" && source.stat_rate) ||
|
||||
(source.type === "grid" && source.power?.length)
|
||||
);
|
||||
const hasPowerDevices = prefs.device_consumption.find(
|
||||
(device) => device.stat_rate
|
||||
);
|
||||
const hasCost = prefs.energy_sources.some(
|
||||
(source) =>
|
||||
sourceHasCost(source) ||
|
||||
@@ -78,94 +78,67 @@ export class EnergyViewStrategy extends ReactiveElement {
|
||||
|
||||
const overviewSection: LovelaceSectionConfig = {
|
||||
type: "grid",
|
||||
column_span: 24,
|
||||
cards: [],
|
||||
cards: [
|
||||
{
|
||||
type: "energy-date-selection",
|
||||
collection_key: collectionKey,
|
||||
allow_compare: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
// Only include if we have a grid or battery.
|
||||
if (hasGrid || hasBattery) {
|
||||
if (hasGrid || hasBattery || hasSolar) {
|
||||
overviewSection.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.energy_distribution_title"),
|
||||
type: "energy-distribution",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
}
|
||||
if (hasCost) {
|
||||
overviewSection.cards!.push({
|
||||
type: "energy-sources-table",
|
||||
collection_key: collectionKey,
|
||||
show_only_totals: true,
|
||||
});
|
||||
}
|
||||
view.sections!.push(overviewSection);
|
||||
|
||||
const powerSection: LovelaceSectionConfig = {
|
||||
type: "grid",
|
||||
cards: [
|
||||
{
|
||||
type: "heading",
|
||||
heading: hass.localize("ui.panel.energy.title.power"),
|
||||
tap_action: {
|
||||
action: "navigate",
|
||||
navigation_path: "/energy/power",
|
||||
if (hasCost) {
|
||||
view.sections!.push({
|
||||
type: "grid",
|
||||
cards: [
|
||||
{
|
||||
title: hass.localize(
|
||||
"ui.panel.energy.cards.energy_sources_table_title"
|
||||
),
|
||||
type: "energy-sources-table",
|
||||
collection_key: collectionKey,
|
||||
show_only_totals: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
if (hasPowerDevices) {
|
||||
const showFloorsNAreas = !prefs.device_consumption.some(
|
||||
(d) => d.included_in_stat
|
||||
);
|
||||
powerSection.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.power_sankey_title"),
|
||||
type: "power-sankey",
|
||||
collection_key: collectionKey,
|
||||
group_by_floor: showFloorsNAreas,
|
||||
group_by_area: showFloorsNAreas,
|
||||
grid_options: {
|
||||
columns: 24,
|
||||
},
|
||||
],
|
||||
});
|
||||
powerSection.column_span = 24;
|
||||
view.sections!.push(powerSection);
|
||||
} else if (hasPowerSources) {
|
||||
powerSection.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.power_sources_graph_title"),
|
||||
type: "power-sources-graph",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
view.sections!.push(powerSection);
|
||||
}
|
||||
|
||||
const energySection: LovelaceSectionConfig = {
|
||||
type: "grid",
|
||||
cards: [
|
||||
{
|
||||
type: "heading",
|
||||
heading: hass.localize("ui.panel.energy.title.energy"),
|
||||
tap_action: {
|
||||
action: "navigate",
|
||||
navigation_path: "/energy/electricity",
|
||||
if (hasPowerSources) {
|
||||
view.sections!.push({
|
||||
type: "grid",
|
||||
cards: [
|
||||
{
|
||||
title: hass.localize(
|
||||
"ui.panel.energy.cards.power_sources_graph_title"
|
||||
),
|
||||
type: "power-sources-graph",
|
||||
collection_key: collectionKey,
|
||||
show_legend: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
view.sections!.push(energySection);
|
||||
if (hasGrid || hasBattery) {
|
||||
energySection.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.energy_usage_graph_title"),
|
||||
type: "energy-usage-graph",
|
||||
collection_key: "energy_dashboard",
|
||||
],
|
||||
});
|
||||
}
|
||||
if (prefs!.device_consumption.length > 3) {
|
||||
energySection.cards!.push({
|
||||
title: hass.localize(
|
||||
"ui.panel.energy.cards.energy_top_consumers_title"
|
||||
),
|
||||
type: "energy-devices-graph",
|
||||
collection_key: collectionKey,
|
||||
max_devices: 3,
|
||||
modes: ["bar"],
|
||||
|
||||
if (hasGrid || hasBattery) {
|
||||
view.sections!.push({
|
||||
type: "grid",
|
||||
cards: [
|
||||
{
|
||||
title: hass.localize(
|
||||
"ui.panel.energy.cards.energy_usage_graph_title"
|
||||
),
|
||||
type: "energy-usage-graph",
|
||||
collection_key: "energy_dashboard",
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -173,10 +146,6 @@ export class EnergyViewStrategy extends ReactiveElement {
|
||||
view.sections!.push({
|
||||
type: "grid",
|
||||
cards: [
|
||||
{
|
||||
type: "heading",
|
||||
heading: hass.localize("ui.panel.energy.title.gas"),
|
||||
},
|
||||
{
|
||||
title: hass.localize(
|
||||
"ui.panel.energy.cards.energy_gas_graph_title"
|
||||
@@ -192,14 +161,6 @@ export class EnergyViewStrategy extends ReactiveElement {
|
||||
view.sections!.push({
|
||||
type: "grid",
|
||||
cards: [
|
||||
{
|
||||
type: "heading",
|
||||
heading: hass.localize("ui.panel.energy.title.water"),
|
||||
tap_action: {
|
||||
action: "navigate",
|
||||
navigation_path: "/energy/water",
|
||||
},
|
||||
},
|
||||
hasWaterSources
|
||||
? {
|
||||
title: hass.localize(
|
||||
@@ -225,6 +186,6 @@ export class EnergyViewStrategy extends ReactiveElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"energy-overview-view-strategy": EnergyViewStrategy;
|
||||
"energy-overview-view-strategy": EnergyOverviewViewStrategy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,10 @@ export class EnergyViewStrategy extends ReactiveElement {
|
||||
(d) => d.included_in_stat
|
||||
);
|
||||
|
||||
view.cards!.push({
|
||||
type: "energy-date-selection",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
view.cards!.push({
|
||||
type: "energy-compare",
|
||||
collection_key: "energy_dashboard",
|
||||
@@ -133,11 +137,11 @@ export class EnergyViewStrategy extends ReactiveElement {
|
||||
// Only include if we have at least 1 device in the config.
|
||||
if (prefs.device_consumption.length) {
|
||||
view.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.energy_sankey_title"),
|
||||
type: "energy-sankey",
|
||||
title: hass.localize(
|
||||
"ui.panel.energy.cards.energy_devices_detail_graph_title"
|
||||
),
|
||||
type: "energy-devices-detail-graph",
|
||||
collection_key: "energy_dashboard",
|
||||
group_by_floor: showFloorsNAreas,
|
||||
group_by_area: showFloorsNAreas,
|
||||
});
|
||||
view.cards!.push({
|
||||
title: hass.localize(
|
||||
@@ -147,11 +151,11 @@ export class EnergyViewStrategy extends ReactiveElement {
|
||||
collection_key: "energy_dashboard",
|
||||
});
|
||||
view.cards!.push({
|
||||
title: hass.localize(
|
||||
"ui.panel.energy.cards.energy_devices_detail_graph_title"
|
||||
),
|
||||
type: "energy-devices-detail-graph",
|
||||
title: hass.localize("ui.panel.energy.cards.energy_sankey_title"),
|
||||
type: "energy-sankey",
|
||||
collection_key: "energy_dashboard",
|
||||
group_by_floor: showFloorsNAreas,
|
||||
group_by_area: showFloorsNAreas,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
70
src/panels/energy/strategies/gas-view-strategy.ts
Normal file
70
src/panels/energy/strategies/gas-view-strategy.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { ReactiveElement } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
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 type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
|
||||
|
||||
@customElement("gas-view-strategy")
|
||||
export class GasViewStrategy extends ReactiveElement {
|
||||
static async generate(
|
||||
_config: LovelaceStrategyConfig,
|
||||
hass: HomeAssistant
|
||||
): Promise<LovelaceViewConfig> {
|
||||
const view: LovelaceViewConfig = {
|
||||
type: "sections",
|
||||
sections: [{ type: "grid", cards: [] }],
|
||||
};
|
||||
|
||||
const collectionKey =
|
||||
_config.collection_key || DEFAULT_ENERGY_COLLECTION_KEY;
|
||||
|
||||
const energyCollection = getEnergyDataCollection(hass, {
|
||||
key: collectionKey,
|
||||
});
|
||||
const prefs = energyCollection.prefs;
|
||||
|
||||
const hasGasSources = prefs?.energy_sources.some(
|
||||
(source) => source.type === "gas"
|
||||
);
|
||||
|
||||
// No gas sources available
|
||||
if (!prefs || !hasGasSources) {
|
||||
return view;
|
||||
}
|
||||
|
||||
const section = view.sections![0] as LovelaceSectionConfig;
|
||||
|
||||
section.cards!.push({
|
||||
type: "energy-date-selection",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
section.cards!.push({
|
||||
type: "energy-compare",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
|
||||
section.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.energy_gas_graph_title"),
|
||||
type: "energy-gas-graph",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
|
||||
section.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.energy_sources_table_title"),
|
||||
type: "energy-sources-table",
|
||||
collection_key: collectionKey,
|
||||
types: ["gas"],
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"gas-view-strategy": GasViewStrategy;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ 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 type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
|
||||
|
||||
@customElement("power-view-strategy")
|
||||
export class PowerViewStrategy extends ReactiveElement {
|
||||
@@ -12,7 +13,10 @@ export class PowerViewStrategy extends ReactiveElement {
|
||||
_config: LovelaceStrategyConfig,
|
||||
hass: HomeAssistant
|
||||
): Promise<LovelaceViewConfig> {
|
||||
const view: LovelaceViewConfig = { cards: [] };
|
||||
const view: LovelaceViewConfig = {
|
||||
type: "sections",
|
||||
sections: [{ type: "grid", cards: [] }],
|
||||
};
|
||||
|
||||
const collectionKey =
|
||||
_config.collection_key || DEFAULT_ENERGY_COLLECTION_KEY;
|
||||
@@ -20,6 +24,7 @@ export class PowerViewStrategy extends ReactiveElement {
|
||||
const energyCollection = getEnergyDataCollection(hass, {
|
||||
key: collectionKey,
|
||||
});
|
||||
await energyCollection.refresh();
|
||||
const prefs = energyCollection.prefs;
|
||||
|
||||
const hasPowerSources = prefs?.energy_sources.some(
|
||||
@@ -37,31 +42,32 @@ export class PowerViewStrategy extends ReactiveElement {
|
||||
return view;
|
||||
}
|
||||
|
||||
view.type = "sidebar";
|
||||
const section = view.sections![0] as LovelaceSectionConfig;
|
||||
|
||||
view.cards!.push({
|
||||
type: "energy-compare",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
if (hasPowerSources) {
|
||||
section.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.power_sources_graph_title"),
|
||||
type: "power-sources-graph",
|
||||
collection_key: collectionKey,
|
||||
grid_options: {
|
||||
columns: 36,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (hasPowerDevices) {
|
||||
const showFloorsNAreas = !prefs.device_consumption.some(
|
||||
(d) => d.included_in_stat
|
||||
);
|
||||
view.cards!.push({
|
||||
section.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.power_sankey_title"),
|
||||
type: "power-sankey",
|
||||
collection_key: collectionKey,
|
||||
group_by_floor: showFloorsNAreas,
|
||||
group_by_area: showFloorsNAreas,
|
||||
});
|
||||
}
|
||||
|
||||
if (hasPowerSources) {
|
||||
view.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.power_sources_graph_title"),
|
||||
type: "power-sources-graph",
|
||||
collection_key: collectionKey,
|
||||
grid_options: {
|
||||
columns: 36,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ 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 type { LovelaceSectionConfig } from "../../../data/lovelace/config/section";
|
||||
|
||||
@customElement("water-view-strategy")
|
||||
export class WaterViewStrategy extends ReactiveElement {
|
||||
@@ -12,7 +13,10 @@ export class WaterViewStrategy extends ReactiveElement {
|
||||
_config: LovelaceStrategyConfig,
|
||||
hass: HomeAssistant
|
||||
): Promise<LovelaceViewConfig> {
|
||||
const view: LovelaceViewConfig = { cards: [] };
|
||||
const view: LovelaceViewConfig = {
|
||||
type: "sections",
|
||||
sections: [{ type: "grid", cards: [] }],
|
||||
};
|
||||
|
||||
const collectionKey =
|
||||
_config.collection_key || DEFAULT_ENERGY_COLLECTION_KEY;
|
||||
@@ -32,15 +36,19 @@ export class WaterViewStrategy extends ReactiveElement {
|
||||
return view;
|
||||
}
|
||||
|
||||
view.type = "sidebar";
|
||||
const section = view.sections![0] as LovelaceSectionConfig;
|
||||
|
||||
view.cards!.push({
|
||||
section.cards!.push({
|
||||
type: "energy-date-selection",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
section.cards!.push({
|
||||
type: "energy-compare",
|
||||
collection_key: collectionKey,
|
||||
});
|
||||
|
||||
if (hasWaterSources) {
|
||||
view.cards!.push({
|
||||
section.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.energy_water_graph_title"),
|
||||
type: "energy-water-graph",
|
||||
collection_key: collectionKey,
|
||||
@@ -48,7 +56,7 @@ export class WaterViewStrategy extends ReactiveElement {
|
||||
}
|
||||
|
||||
if (hasWaterSources) {
|
||||
view.cards!.push({
|
||||
section.cards!.push({
|
||||
title: hass.localize(
|
||||
"ui.panel.energy.cards.energy_sources_table_title"
|
||||
),
|
||||
@@ -63,7 +71,7 @@ export class WaterViewStrategy extends ReactiveElement {
|
||||
const showFloorsNAreas = !prefs.device_consumption_water.some(
|
||||
(d) => d.included_in_stat
|
||||
);
|
||||
view.cards!.push({
|
||||
section.cards!.push({
|
||||
title: hass.localize("ui.panel.energy.cards.water_sankey_title"),
|
||||
type: "water-sankey",
|
||||
collection_key: collectionKey,
|
||||
|
||||
@@ -132,7 +132,7 @@ export class HuiPowerSourcesGraphCard
|
||||
compareEnd
|
||||
),
|
||||
legend: {
|
||||
show: true,
|
||||
show: this._config?.show_legend !== false,
|
||||
type: "custom",
|
||||
data: legendData,
|
||||
},
|
||||
|
||||
@@ -235,6 +235,7 @@ export interface WaterSankeyCardConfig extends EnergyCardBaseConfig {
|
||||
export interface PowerSourcesGraphCardConfig extends EnergyCardBaseConfig {
|
||||
type: "power-sources-graph";
|
||||
title?: string;
|
||||
show_legend?: boolean;
|
||||
}
|
||||
|
||||
export interface PowerSankeyCardConfig extends EnergyCardBaseConfig {
|
||||
|
||||
@@ -112,6 +112,12 @@ interface ActionItem {
|
||||
subItems?: SubActionItem[];
|
||||
}
|
||||
|
||||
export interface ExtraActionItem {
|
||||
icon: string;
|
||||
labelKey: LocalizeKeys;
|
||||
action: () => void;
|
||||
}
|
||||
|
||||
interface SubActionItem {
|
||||
icon: string;
|
||||
key: LocalizeKeys;
|
||||
@@ -140,6 +146,8 @@ class HUIRoot extends LitElement {
|
||||
prefix: string;
|
||||
};
|
||||
|
||||
@property({ attribute: false }) public extraActionItems?: ExtraActionItem[];
|
||||
|
||||
@state() private _curView?: number | "hass-unused-entities";
|
||||
|
||||
private _configChangedByUndo = false;
|
||||
@@ -347,6 +355,25 @@ class HUIRoot extends LitElement {
|
||||
},
|
||||
];
|
||||
|
||||
// Add extra action items from parent components
|
||||
if (this.extraActionItems) {
|
||||
this.extraActionItems.forEach((extraItem) => {
|
||||
items.push({
|
||||
icon: extraItem.icon,
|
||||
key: extraItem.labelKey,
|
||||
buttonAction: extraItem.action,
|
||||
overflowAction: (ev: CustomEvent<RequestSelectedDetail>) => {
|
||||
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||
return;
|
||||
}
|
||||
extraItem.action();
|
||||
},
|
||||
visible: true,
|
||||
overflow: this.narrow,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const overflowItems = items.filter((i) => i.visible && i.overflow);
|
||||
const overflowCanPromote =
|
||||
overflowItems.length === 1 && overflowItems[0].overflow_can_promote;
|
||||
|
||||
@@ -42,6 +42,7 @@ const STRATEGIES: Record<LovelaceStrategyConfigType, Record<string, any>> = {
|
||||
import("../../energy/strategies/energy-overview-view-strategy"),
|
||||
energy: () => import("../../energy/strategies/energy-view-strategy"),
|
||||
water: () => import("../../energy/strategies/water-view-strategy"),
|
||||
gas: () => import("../../energy/strategies/gas-view-strategy"),
|
||||
power: () => import("../../energy/strategies/power-view-strategy"),
|
||||
map: () => import("./map/map-view-strategy"),
|
||||
iframe: () => import("./iframe/iframe-view-strategy"),
|
||||
|
||||
@@ -9578,10 +9578,11 @@
|
||||
},
|
||||
"energy": {
|
||||
"title": {
|
||||
"energy": "Energy",
|
||||
"power": "Power",
|
||||
"overview": "Summary",
|
||||
"electricity": "Energy",
|
||||
"gas": "Gas",
|
||||
"water": "Water"
|
||||
"water": "Water",
|
||||
"now": "Now"
|
||||
},
|
||||
"download_data": "[%key:ui::panel::history::download_data%]",
|
||||
"configure": "[%key:ui::dialogs::quick-bar::commands::navigation::energy%]",
|
||||
|
||||
Reference in New Issue
Block a user