Allow customizing display name for energy device (#20033)

* Allow customizing display name for energy device

* use display name in device settings list
This commit is contained in:
karwosts 2024-04-12 11:31:59 -07:00 committed by GitHub
parent e0087bd142
commit 0118a5bf4c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 83 additions and 21 deletions

View File

@ -95,6 +95,7 @@ export type EnergySolarForecasts = {
export interface DeviceConsumptionEnergyPreference { export interface DeviceConsumptionEnergyPreference {
// This is an ever increasing value // This is an ever increasing value
stat_consumption: string; stat_consumption: string;
name?: string;
} }
export interface FlowFromGridSourceEnergyPreference { export interface FlowFromGridSourceEnergyPreference {

View File

@ -1,5 +1,5 @@
import "@material/mwc-button/mwc-button"; import "@material/mwc-button/mwc-button";
import { mdiDelete, mdiDevices } from "@mdi/js"; import { mdiDelete, mdiDevices, mdiPencil } from "@mdi/js";
import { CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
@ -83,18 +83,24 @@ export class EnergyDeviceSettings extends LitElement {
${this.preferences.device_consumption.map((device) => { ${this.preferences.device_consumption.map((device) => {
const entityState = this.hass.states[device.stat_consumption]; const entityState = this.hass.states[device.stat_consumption];
return html` return html`
<div class="row"> <div class="row" .device=${device}>
<ha-state-icon <ha-state-icon
.hass=${this.hass} .hass=${this.hass}
.stateObj=${entityState} .stateObj=${entityState}
></ha-state-icon> ></ha-state-icon>
<span class="content" <span class="content"
>${getStatisticLabel( >${device.name ||
getStatisticLabel(
this.hass, this.hass,
device.stat_consumption, device.stat_consumption,
this.statsMetadata?.[device.stat_consumption] this.statsMetadata?.[device.stat_consumption]
)}</span )}</span
> >
<ha-icon-button
.label=${this.hass.localize("ui.common.edit")}
@click=${this._editDevice}
.path=${mdiPencil}
></ha-icon-button>
<ha-icon-button <ha-icon-button
.label=${this.hass.localize("ui.common.delete")} .label=${this.hass.localize("ui.common.delete")}
@click=${this._deleteDevice} @click=${this._deleteDevice}
@ -117,6 +123,24 @@ export class EnergyDeviceSettings extends LitElement {
`; `;
} }
private _editDevice(ev) {
const origDevice: DeviceConsumptionEnergyPreference =
ev.currentTarget.closest(".row").device;
showEnergySettingsDeviceDialog(this, {
device: { ...origDevice },
device_consumptions: this.preferences
.device_consumption as DeviceConsumptionEnergyPreference[],
saveCallback: async (newDevice) => {
await this._savePreferences({
...this.preferences,
device_consumption: this.preferences.device_consumption.map((d) =>
d === origDevice ? newDevice : d
),
});
},
});
}
private _addDevice() { private _addDevice() {
showEnergySettingsDeviceDialog(this, { showEnergySettingsDeviceDialog(this, {
device_consumptions: this.preferences device_consumptions: this.preferences

View File

@ -44,9 +44,10 @@ export class DialogEnergyDeviceSettings
this._energy_units = ( this._energy_units = (
await getSensorDeviceClassConvertibleUnits(this.hass, "energy") await getSensorDeviceClassConvertibleUnits(this.hass, "energy")
).units; ).units;
this._excludeList = this._params.device_consumptions.map( this._device = this._params.device;
(entry) => entry.stat_consumption this._excludeList = this._params.device_consumptions
); .map((entry) => entry.stat_consumption)
.filter((id) => id !== this._device?.stat_consumption);
} }
public closeDialog(): void { public closeDialog(): void {
@ -88,6 +89,7 @@ export class DialogEnergyDeviceSettings
.hass=${this.hass} .hass=${this.hass}
.helpMissingEntityUrl=${energyStatisticHelpUrl} .helpMissingEntityUrl=${energyStatisticHelpUrl}
.includeUnitClass=${energyUnitClasses} .includeUnitClass=${energyUnitClasses}
.value=${this._device?.stat_consumption}
.label=${this.hass.localize( .label=${this.hass.localize(
"ui.panel.config.energy.device_consumption.dialog.device_consumption_energy" "ui.panel.config.energy.device_consumption.dialog.device_consumption_energy"
)} )}
@ -96,6 +98,17 @@ export class DialogEnergyDeviceSettings
dialogInitialFocus dialogInitialFocus
></ha-statistic-picker> ></ha-statistic-picker>
<ha-textfield
.label=${this.hass.localize(
"ui.panel.config.energy.device_consumption.dialog.display_name"
)}
type="text"
.disabled=${!this._device}
.value=${this._device?.name || ""}
@change=${this._nameChanged}
>
</ha-textfield>
<mwc-button @click=${this.closeDialog} slot="secondaryAction"> <mwc-button @click=${this.closeDialog} slot="secondaryAction">
${this.hass.localize("ui.common.cancel")} ${this.hass.localize("ui.common.cancel")}
</mwc-button> </mwc-button>
@ -118,6 +131,17 @@ export class DialogEnergyDeviceSettings
this._device = { stat_consumption: ev.detail.value }; this._device = { stat_consumption: ev.detail.value };
} }
private _nameChanged(ev) {
const newDevice = {
...this._device!,
name: ev.target!.value,
} as DeviceConsumptionEnergyPreference;
if (!newDevice.name) {
delete newDevice.name;
}
this._device = newDevice;
}
private async _save() { private async _save() {
try { try {
await this._params!.saveCallback(this._device!); await this._params!.saveCallback(this._device!);
@ -134,6 +158,10 @@ export class DialogEnergyDeviceSettings
ha-statistic-picker { ha-statistic-picker {
width: 100%; width: 100%;
} }
ha-textfield {
margin-top: 16px;
width: 100%;
}
`, `,
]; ];
} }

View File

@ -70,6 +70,7 @@ export interface EnergySettingsWaterDialogParams {
} }
export interface EnergySettingsDeviceDialogParams { export interface EnergySettingsDeviceDialogParams {
device?: DeviceConsumptionEnergyPreference;
device_consumptions: DeviceConsumptionEnergyPreference[]; device_consumptions: DeviceConsumptionEnergyPreference[];
saveCallback: (device: DeviceConsumptionEnergyPreference) => Promise<void>; saveCallback: (device: DeviceConsumptionEnergyPreference) => Promise<void>;
} }

View File

@ -333,7 +333,9 @@ export class HuiEnergyDevicesDetailGraphCard
); );
data.push({ data.push({
label: getStatisticLabel( label:
source.name ||
getStatisticLabel(
this.hass, this.hass,
source.stat_consumption, source.stat_consumption,
statisticsMetaData[source.stat_consumption] statisticsMetaData[source.stat_consumption]

View File

@ -127,11 +127,7 @@ export class HuiEnergyDevicesGraphCard
const statisticId = ( const statisticId = (
this._chartData.datasets[0].data[index] as ScatterDataPoint this._chartData.datasets[0].data[index] as ScatterDataPoint
).y; ).y;
return getStatisticLabel( return this.getDeviceName(statisticId as any as string);
this.hass,
statisticId as any,
this._data?.statsMetadata[statisticId]
);
}, },
}, },
}, },
@ -149,11 +145,7 @@ export class HuiEnergyDevicesGraphCard
callbacks: { callbacks: {
title: (item) => { title: (item) => {
const statisticId = item[0].label; const statisticId = item[0].label;
return getStatisticLabel( return this.getDeviceName(statisticId);
this.hass,
statisticId,
this._data?.statsMetadata[statisticId]
);
}, },
label: (context) => label: (context) =>
`${context.dataset.label}: ${formatNumber( `${context.dataset.label}: ${formatNumber(
@ -181,6 +173,19 @@ export class HuiEnergyDevicesGraphCard
}) })
); );
private getDeviceName(statisticId: string): string {
return (
this._data?.prefs.device_consumption.find(
(d) => d.stat_consumption === statisticId
)?.name ||
getStatisticLabel(
this.hass,
statisticId,
this._data?.statsMetadata[statisticId]
)
);
}
private async _getStatistics(energyData: EnergyData): Promise<void> { private async _getStatistics(energyData: EnergyData): Promise<void> {
const data = energyData.stats; const data = energyData.stats;
const compareData = energyData.statsCompare; const compareData = energyData.statsCompare;

View File

@ -2243,6 +2243,7 @@
"add_device": "Add device", "add_device": "Add device",
"dialog": { "dialog": {
"header": "Add a device", "header": "Add a device",
"display_name": "Display name",
"device_consumption_energy": "Device consumption energy", "device_consumption_energy": "Device consumption energy",
"selected_stat_intro": "Select the energy sensor that measures the device's energy usage in either of {unit}." "selected_stat_intro": "Select the energy sensor that measures the device's energy usage in either of {unit}."
} }