diff --git a/src/data/energy.ts b/src/data/energy.ts
index c84ff22914..e9976fab43 100644
--- a/src/data/energy.ts
+++ b/src/data/energy.ts
@@ -159,6 +159,9 @@ export interface GasSourceTypeEnergyPreference {
// kWh/volume meter
stat_energy_from: string;
+ // Flow rate (m³/h, L/min, etc.)
+ stat_rate?: string;
+
// $ meter
stat_cost: string | null;
@@ -174,6 +177,9 @@ export interface WaterSourceTypeEnergyPreference {
// volume meter
stat_energy_from: string;
+ // Flow rate (L/min, gal/min, m³/h, etc.)
+ stat_rate?: string;
+
// $ meter
stat_cost: string | null;
@@ -368,6 +374,9 @@ export const getReferencedStatisticIdsPower = (
for (const source of prefs.energy_sources) {
if (source.type === "gas" || source.type === "water") {
+ if (source.stat_rate) {
+ statIDs.push(source.stat_rate);
+ }
continue;
}
@@ -389,6 +398,7 @@ export const getReferencedStatisticIdsPower = (
}
}
statIDs.push(...prefs.device_consumption.map((d) => d.stat_rate));
+ statIDs.push(...prefs.device_consumption_water.map((d) => d.stat_rate));
return statIDs.filter(Boolean) as string[];
};
diff --git a/src/panels/config/energy/dialogs/dialog-energy-device-settings-water.ts b/src/panels/config/energy/dialogs/dialog-energy-device-settings-water.ts
index 8cbf84012e..c07543eda3 100644
--- a/src/panels/config/energy/dialogs/dialog-energy-device-settings-water.ts
+++ b/src/panels/config/energy/dialogs/dialog-energy-device-settings-water.ts
@@ -20,6 +20,7 @@ import type { HomeAssistant, ValueChangedEvent } from "../../../../types";
import type { EnergySettingsDeviceWaterDialogParams } from "./show-dialogs-energy";
const volumeUnitClasses = ["volume"];
+const flowRateUnitClasses = ["volume_flow_rate"];
@customElement("dialog-energy-device-settings-water")
export class DialogEnergyDeviceSettingsWater
@@ -36,10 +37,14 @@ export class DialogEnergyDeviceSettingsWater
@state() private _volume_units?: string[];
+ @state() private _flow_rate_units?: string[];
+
@state() private _error?: string;
private _excludeList?: string[];
+ private _excludeListFlowRate?: string[];
+
private _possibleParents: DeviceConsumptionEnergyPreference[] = [];
public async showDialog(
@@ -51,9 +56,15 @@ export class DialogEnergyDeviceSettingsWater
this._volume_units = (
await getSensorDeviceClassConvertibleUnits(this.hass, "water")
).units;
+ this._flow_rate_units = (
+ await getSensorDeviceClassConvertibleUnits(this.hass, "volume_flow_rate")
+ ).units;
this._excludeList = this._params.device_consumptions
.map((entry) => entry.stat_consumption)
.filter((id) => id !== this._device?.stat_consumption);
+ this._excludeListFlowRate = this._params.device_consumptions
+ .map((entry) => entry.stat_rate)
+ .filter((id) => id && id !== this._device?.stat_rate) as string[];
this._open = true;
}
@@ -92,6 +103,7 @@ export class DialogEnergyDeviceSettingsWater
this._device = undefined;
this._error = undefined;
this._excludeList = undefined;
+ this._excludeListFlowRate = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -134,12 +146,6 @@ export class DialogEnergyDeviceSettingsWater
@closed=${this._dialogClosed}
>
${this._error ? html`
${this._error}
` : ""}
-
- ${this.hass.localize(
- "ui.panel.config.energy.device_consumption_water.dialog.selected_stat_intro",
- { unit: pickableUnit }
- )}
-
+
+
) {
+ if (!this._device) {
+ return;
+ }
+ const newDevice = {
+ ...this._device,
+ stat_rate: ev.detail.value,
+ } as DeviceConsumptionEnergyPreference;
+ if (!newDevice.stat_rate) {
+ delete newDevice.stat_rate;
+ }
+ this._device = newDevice;
+ }
+
private _nameChanged(ev) {
const newDevice = {
...this._device!,
@@ -252,7 +291,9 @@ export class DialogEnergyDeviceSettingsWater
haStyleDialog,
css`
ha-statistic-picker {
+ display: block;
width: 100%;
+ margin-bottom: var(--ha-space-4);
}
ha-select {
display: block;
diff --git a/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts
index bc32aa8d7f..8433269753 100644
--- a/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts
+++ b/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts
@@ -30,6 +30,7 @@ import type { EnergySettingsGasDialogParams } from "./show-dialogs-energy";
const gasDeviceClasses = ["gas", "energy"];
const gasUnitClasses = ["volume", "energy"];
+const flowRateUnitClasses = ["volume_flow_rate"];
@customElement("dialog-energy-gas-settings")
export class DialogEnergyGasSettings
@@ -52,10 +53,14 @@ export class DialogEnergyGasSettings
@state() private _gas_units?: string[];
+ @state() private _flow_rate_units?: string[];
+
@state() private _error?: string;
private _excludeList?: string[];
+ private _excludeListFlowRate?: string[];
+
public async showDialog(
params: EnergySettingsGasDialogParams
): Promise {
@@ -81,9 +86,15 @@ export class DialogEnergyGasSettings
this._gas_units = (
await getSensorDeviceClassConvertibleUnits(this.hass, "gas")
).units;
+ this._flow_rate_units = (
+ await getSensorDeviceClassConvertibleUnits(this.hass, "volume_flow_rate")
+ ).units;
this._excludeList = this._params.gas_sources
.map((entry) => entry.stat_energy_from)
.filter((id) => id !== this._source?.stat_energy_from);
+ this._excludeListFlowRate = this._params.gas_sources
+ .map((entry) => entry.stat_rate)
+ .filter((id) => id && id !== this._source?.stat_rate) as string[];
this._open = true;
}
@@ -99,6 +110,7 @@ export class DialogEnergyGasSettings
this._pickedDisplayUnit = undefined;
this._error = undefined;
this._excludeList = undefined;
+ this._excludeListFlowRate = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -146,12 +158,6 @@ export class DialogEnergyGasSettings
${this.hass.localize("ui.panel.config.energy.gas.dialog.paragraph")}
-
- ${this.hass.localize(
- "ui.panel.config.energy.gas.dialog.entity_para",
- { unit: pickableUnit }
- )}
-
${this.hass.localize("ui.panel.config.energy.gas.dialog.note_para")}
@@ -169,9 +175,28 @@ export class DialogEnergyGasSettings
)}
.excludeStatistics=${this._excludeList}
@value-changed=${this._statisticChanged}
+ .helper=${this.hass.localize(
+ "ui.panel.config.energy.gas.dialog.entity_para",
+ { unit: pickableUnit }
+ )}
autofocus
>
+
+
${this.hass.localize("ui.panel.config.energy.gas.dialog.cost_para")}
@@ -341,6 +366,13 @@ export class DialogEnergyGasSettings
};
}
+ private _flowRateStatisticChanged(ev: ValueChangedEvent) {
+ this._source = {
+ ...this._source!,
+ stat_rate: ev.detail.value || undefined,
+ };
+ }
+
private async _statisticChanged(ev: ValueChangedEvent) {
if (ev.detail.value) {
const metadata = await getStatisticMetadata(this.hass, [ev.detail.value]);
@@ -380,6 +412,10 @@ export class DialogEnergyGasSettings
haStyle,
haStyleDialog,
css`
+ ha-statistic-picker {
+ display: block;
+ margin-bottom: var(--ha-space-4);
+ }
ha-formfield {
display: block;
}
diff --git a/src/panels/config/energy/dialogs/dialog-energy-water-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-water-settings.ts
index 386df18bc4..499f4046e8 100644
--- a/src/panels/config/energy/dialogs/dialog-energy-water-settings.ts
+++ b/src/panels/config/energy/dialogs/dialog-energy-water-settings.ts
@@ -24,6 +24,8 @@ import { haStyle, haStyleDialog } from "../../../../resources/styles";
import type { HomeAssistant, ValueChangedEvent } from "../../../../types";
import type { EnergySettingsWaterDialogParams } from "./show-dialogs-energy";
+const flowRateUnitClasses = ["volume_flow_rate"];
+
@customElement("dialog-energy-water-settings")
export class DialogEnergyWaterSettings
extends LitElement
@@ -41,10 +43,14 @@ export class DialogEnergyWaterSettings
@state() private _water_units?: string[];
+ @state() private _flow_rate_units?: string[];
+
@state() private _error?: string;
private _excludeList?: string[];
+ private _excludeListFlowRate?: string[];
+
public async showDialog(
params: EnergySettingsWaterDialogParams
): Promise {
@@ -62,9 +68,15 @@ export class DialogEnergyWaterSettings
this._water_units = (
await getSensorDeviceClassConvertibleUnits(this.hass, "water")
).units;
+ this._flow_rate_units = (
+ await getSensorDeviceClassConvertibleUnits(this.hass, "volume_flow_rate")
+ ).units;
this._excludeList = this._params.water_sources
.map((entry) => entry.stat_energy_from)
.filter((id) => id !== this._source?.stat_energy_from);
+ this._excludeListFlowRate = this._params.water_sources
+ .map((entry) => entry.stat_rate)
+ .filter((id) => id && id !== this._source?.stat_rate) as string[];
this._open = true;
}
@@ -79,6 +91,7 @@ export class DialogEnergyWaterSettings
this._source = undefined;
this._error = undefined;
this._excludeList = undefined;
+ this._excludeListFlowRate = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -108,19 +121,6 @@ export class DialogEnergyWaterSettings
@closed=${this._dialogClosed}
>
${this._error ? html`${this._error}
` : ""}
-
-
- ${this.hass.localize(
- "ui.panel.config.energy.water.dialog.paragraph"
- )}
-
-
- ${this.hass.localize(
- "ui.panel.config.energy.water.dialog.entity_para",
- { unit: pickableUnit }
- )}
-
-
+
+
${this.hass.localize("ui.panel.config.energy.water.dialog.cost_para")}
@@ -287,6 +306,13 @@ export class DialogEnergyWaterSettings
};
}
+ private _flowRateStatisticChanged(ev: ValueChangedEvent) {
+ this._source = {
+ ...this._source!,
+ stat_rate: ev.detail.value || undefined,
+ };
+ }
+
private async _statisticChanged(ev: ValueChangedEvent) {
if (
ev.detail.value &&
@@ -320,6 +346,10 @@ export class DialogEnergyWaterSettings
haStyle,
haStyleDialog,
css`
+ ha-statistic-picker {
+ display: block;
+ margin-bottom: var(--ha-space-4);
+ }
ha-formfield {
display: block;
}
diff --git a/src/translations/en.json b/src/translations/en.json
index 8866f81cb0..a8cf1b21e9 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -3936,7 +3936,9 @@
"cost_entity_helper_volume": "volume",
"cost_number": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_number%]",
"cost_number_input": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_number%]",
- "gas_usage": "Gas usage"
+ "gas_usage": "Gas consumption",
+ "gas_flow_rate": "Gas flow rate",
+ "flow_rate_para": "Optionally pick a sensor which measures the gas flow rate in either of {unit}."
}
},
"water": {
@@ -3960,7 +3962,9 @@
"cost_entity_helper": "Any entity with a unit of `{currency}/(valid water unit)` (e.g. `{currency}/gal` or `{currency}/m³`) may be used and will be automatically converted.",
"cost_number": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_number%]",
"cost_number_input": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_number%]",
- "water_usage": "Water usage"
+ "water_usage": "Water consumption",
+ "water_flow_rate": "Water flow rate",
+ "flow_rate_para": "Optionally pick a sensor which measures the water flow rate in either of {unit}."
}
},
"device_consumption": {
@@ -3992,7 +3996,8 @@
"header": "Add a water device",
"display_name": "Display name",
"device_consumption_water": "Device water consumption",
- "selected_stat_intro": "Select the water sensor that measures the device's water usage in either of {unit}.",
+ "device_consumption_water_flow_rate": "Device water flow rate",
+ "selected_stat_intro": "Select the water sensor that measures the device's water consumption in either of {unit}.",
"included_in_device": "Upstream device",
"included_in_device_helper": "If this device is already counted by another device (such as a water meter measured by the main water supply), selecting the upstream device prevents duplicate water tracking.",
"no_upstream_devices": "No eligible upstream devices"