Skip to content
Open
2 changes: 1 addition & 1 deletion src/components/entity/ha-statistic-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import "../ha-combo-box-item";
import "../ha-generic-picker";
import type { HaGenericPicker } from "../ha-generic-picker";
import "../ha-icon-button";
import "../ha-input-helper-text";
import type {
PickerComboBoxItem,
PickerComboBoxSearchFn,
Expand Down Expand Up @@ -465,6 +464,7 @@ export class HaStatisticPicker extends LitElement {
.hideClearIcon=${this.hideClearIcon}
.searchFn=${this._searchFn}
.valueRenderer=${this._valueRenderer}
.helper=${this.helper}
@value-changed=${this._valueChanged}
>
</ha-generic-picker>
Expand Down
8 changes: 8 additions & 0 deletions src/data/energy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,16 @@ export type EnergySolarForecasts = Record<string, EnergySolarForecast>;
export interface DeviceConsumptionEnergyPreference {
// This is an ever increasing value
stat_consumption: string;
stat_power?: string;
name?: string;
included_in_stat?: string;
}

export interface FlowFromGridSourceEnergyPreference {
// kWh meter
stat_energy_from: string;
// W meter
stat_power_from?: string;

// $ meter
stat_cost: string | null;
Expand All @@ -121,6 +124,8 @@ export interface FlowFromGridSourceEnergyPreference {
export interface FlowToGridSourceEnergyPreference {
// kWh meter
stat_energy_to: string;
// W meter
stat_power_to?: string;

// $ meter
stat_compensation: string | null;
Expand All @@ -143,13 +148,16 @@ export interface SolarSourceTypeEnergyPreference {
type: "solar";

stat_energy_from: string;
stat_power_from?: string;
config_entry_solar_forecast: string[] | null;
}

export interface BatterySourceTypeEnergyPreference {
type: "battery";
stat_energy_from: string;
stat_energy_to: string;
stat_power_from?: string;
stat_power_to?: string;
}
export interface GasSourceTypeEnergyPreference {
type: "gas";
Expand Down
78 changes: 69 additions & 9 deletions src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { HomeAssistant } from "../../../../types";
import type { EnergySettingsBatteryDialogParams } from "./show-dialogs-energy";

const energyUnitClasses = ["energy"];
const powerUnitClasses = ["power"];

@customElement("dialog-energy-battery-settings")
export class DialogEnergyBatterySettings
Expand All @@ -32,10 +33,14 @@ export class DialogEnergyBatterySettings

@state() private _energy_units?: string[];

@state() private _power_units?: string[];

@state() private _error?: string;

private _excludeList?: string[];

private _excludeListPower?: string[];

public async showDialog(
params: EnergySettingsBatteryDialogParams
): Promise<void> {
Expand All @@ -46,6 +51,9 @@ export class DialogEnergyBatterySettings
this._energy_units = (
await getSensorDeviceClassConvertibleUnits(this.hass, "energy")
).units;
this._power_units = (
await getSensorDeviceClassConvertibleUnits(this.hass, "power")
).units;
const allSources: string[] = [];
this._params.battery_sources.forEach((entry) => {
allSources.push(entry.stat_energy_from);
Expand All @@ -56,6 +64,16 @@ export class DialogEnergyBatterySettings
id !== this._source?.stat_energy_from &&
id !== this._source?.stat_energy_to
);
const allPowerSources: string[] = [];
this._params.battery_sources.forEach((entry) => {
if (entry.stat_power_from) allPowerSources.push(entry.stat_power_from);
if (entry.stat_power_to) allPowerSources.push(entry.stat_power_to);
});
this._excludeListPower = allPowerSources.filter(
(id) =>
id !== this._source?.stat_power_from &&
id !== this._source?.stat_power_to
);
}

public closeDialog() {
Expand All @@ -72,8 +90,6 @@ export class DialogEnergyBatterySettings
return nothing;
}

const pickableUnit = this._energy_units?.join(", ") || "";

return html`
<ha-dialog
open
Expand All @@ -85,12 +101,6 @@ export class DialogEnergyBatterySettings
@closed=${this.closeDialog}
>
${this._error ? html`<p class="error">${this._error}</p>` : ""}
<div>
${this.hass.localize(
"ui.panel.config.energy.battery.dialog.entity_para",
{ unit: pickableUnit }
)}
</div>

<ha-statistic-picker
.hass=${this.hass}
Expand All @@ -105,6 +115,10 @@ export class DialogEnergyBatterySettings
this._source.stat_energy_from,
]}
@value-changed=${this._statisticToChanged}
.helper=${this.hass.localize(
"ui.panel.config.energy.battery.dialog.entity_para",
{ unit: this._energy_units?.join(", ") || "" }
)}
dialogInitialFocus
></ha-statistic-picker>

Expand All @@ -121,6 +135,40 @@ export class DialogEnergyBatterySettings
this._source.stat_energy_to,
]}
@value-changed=${this._statisticFromChanged}
.helper=${this.hass.localize(
"ui.panel.config.energy.battery.dialog.entity_para",
{ unit: this._energy_units?.join(", ") || "" }
)}
></ha-statistic-picker>

<ha-statistic-picker
.hass=${this.hass}
.includeUnitClass=${powerUnitClasses}
.value=${this._source.stat_power_to}
.label=${this.hass.localize(
"ui.panel.config.energy.battery.dialog.power_into_battery"
)}
.excludeStatistics=${this._excludeListPower}
@value-changed=${this._powerToChanged}
.helper=${this.hass.localize(
"ui.panel.config.energy.battery.dialog.entity_para",
{ unit: this._power_units?.join(", ") || "" }
)}
></ha-statistic-picker>

<ha-statistic-picker
.hass=${this.hass}
.includeUnitClass=${powerUnitClasses}
.value=${this._source.stat_power_from}
.label=${this.hass.localize(
"ui.panel.config.energy.battery.dialog.power_out_of_battery"
)}
.excludeStatistics=${this._excludeListPower}
@value-changed=${this._powerFromChanged}
.helper=${this.hass.localize(
"ui.panel.config.energy.battery.dialog.entity_para",
{ unit: this._power_units?.join(", ") || "" }
)}
></ha-statistic-picker>

<ha-button
Expand Down Expand Up @@ -150,6 +198,14 @@ export class DialogEnergyBatterySettings
this._source = { ...this._source!, stat_energy_from: ev.detail.value };
}

private _powerToChanged(ev: CustomEvent<{ value: string }>) {
this._source = { ...this._source!, stat_power_to: ev.detail.value };
}

private _powerFromChanged(ev: CustomEvent<{ value: string }>) {
this._source = { ...this._source!, stat_power_from: ev.detail.value };
}

private async _save() {
try {
await this._params!.saveCallback(this._source!);
Expand All @@ -168,7 +224,11 @@ export class DialogEnergyBatterySettings
--mdc-dialog-max-width: 430px;
}
ha-statistic-picker {
width: 100%;
display: block;
margin-bottom: var(--ha-space-4);
}
ha-statistic-picker:last-of-type {
margin-bottom: 0;
}
`,
];
Expand Down
60 changes: 50 additions & 10 deletions src/panels/config/energy/dialogs/dialog-energy-device-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type { HomeAssistant } from "../../../../types";
import type { EnergySettingsDeviceDialogParams } from "./show-dialogs-energy";

const energyUnitClasses = ["energy"];
const powerUnitClasses = ["power"];

@customElement("dialog-energy-device-settings")
export class DialogEnergyDeviceSettings
Expand All @@ -35,10 +36,14 @@ export class DialogEnergyDeviceSettings

@state() private _energy_units?: string[];

@state() private _power_units?: string[];

@state() private _error?: string;

private _excludeList?: string[];

private _excludeListPower?: string[];

private _possibleParents: DeviceConsumptionEnergyPreference[] = [];

public async showDialog(
Expand All @@ -50,9 +55,15 @@ export class DialogEnergyDeviceSettings
this._energy_units = (
await getSensorDeviceClassConvertibleUnits(this.hass, "energy")
).units;
this._power_units = (
await getSensorDeviceClassConvertibleUnits(this.hass, "power")
).units;
this._excludeList = this._params.device_consumptions
.map((entry) => entry.stat_consumption)
.filter((id) => id !== this._device?.stat_consumption);
this._excludeListPower = this._params.device_consumptions
.map((entry) => entry.stat_power)
.filter((id) => id && id !== this._device?.stat_power) as string[];
}

private _computePossibleParents() {
Expand Down Expand Up @@ -93,8 +104,6 @@ export class DialogEnergyDeviceSettings
return nothing;
}

const pickableUnit = this._energy_units?.join(", ") || "";

return html`
<ha-dialog
open
Expand All @@ -108,12 +117,6 @@ export class DialogEnergyDeviceSettings
@closed=${this.closeDialog}
>
${this._error ? html`<p class="error">${this._error}</p>` : ""}
<div>
${this.hass.localize(
"ui.panel.config.energy.device_consumption.dialog.selected_stat_intro",
{ unit: pickableUnit }
)}
</div>

<ha-statistic-picker
.hass=${this.hass}
Expand All @@ -125,9 +128,28 @@ export class DialogEnergyDeviceSettings
)}
.excludeStatistics=${this._excludeList}
@value-changed=${this._statisticChanged}
.helper=${this.hass.localize(
"ui.panel.config.energy.device_consumption.dialog.selected_stat_intro",
{ unit: this._energy_units?.join(", ") || "" }
)}
dialogInitialFocus
></ha-statistic-picker>

<ha-statistic-picker
.hass=${this.hass}
.includeUnitClass=${powerUnitClasses}
.value=${this._device?.stat_power}
.label=${this.hass.localize(
"ui.panel.config.energy.device_consumption.dialog.device_consumption_power"
)}
.excludeStatistics=${this._excludeListPower}
@value-changed=${this._powerStatisticChanged}
.helper=${this.hass.localize(
"ui.panel.config.energy.device_consumption.dialog.device_consumption_power_helper",
{ unit: this._power_units?.join(", ") || "" }
)}
></ha-statistic-picker>

<ha-textfield
.label=${this.hass.localize(
"ui.panel.config.energy.device_consumption.dialog.display_name"
Expand Down Expand Up @@ -210,6 +232,20 @@ export class DialogEnergyDeviceSettings
this._computePossibleParents();
}

private _powerStatisticChanged(ev: CustomEvent<{ value: string }>) {
if (!this._device) {
return;
}
const newDevice = {
...this._device,
stat_power: ev.detail.value,
} as DeviceConsumptionEnergyPreference;
if (!newDevice.stat_power) {
delete newDevice.stat_power;
}
this._device = newDevice;
}

private _nameChanged(ev) {
const newDevice = {
...this._device!,
Expand Down Expand Up @@ -245,15 +281,19 @@ export class DialogEnergyDeviceSettings
return [
haStyleDialog,
css`
ha-statistic-picker {
display: block;
margin-bottom: var(--ha-space-2);
}
ha-statistic-picker {
width: 100%;
}
ha-select {
margin-top: 16px;
margin-top: var(--ha-space-4);
width: 100%;
}
ha-textfield {
margin-top: 16px;
margin-top: var(--ha-space-4);
width: 100%;
}
`,
Expand Down
Loading
Loading