diff --git a/src/panels/config/energy/components/ha-energy-grid-settings.ts b/src/panels/config/energy/components/ha-energy-grid-settings.ts
index f55c2d57b00a..f07961c98d59 100644
--- a/src/panels/config/energy/components/ha-energy-grid-settings.ts
+++ b/src/panels/config/energy/components/ha-energy-grid-settings.ts
@@ -366,6 +366,7 @@ export class EnergyGridSettings extends LitElement {
ev.currentTarget.closest(".row").source;
showEnergySettingsGridFlowFromDialog(this, {
source: { ...origSource },
+ metadata: this.statsMetadata?.[origSource.stat_energy_from],
saveCallback: async (source) => {
const flowFrom = energySourcesByType(this.preferences).grid![0]
.flow_from;
@@ -393,6 +394,7 @@ export class EnergyGridSettings extends LitElement {
ev.currentTarget.closest(".row").source;
showEnergySettingsGridFlowToDialog(this, {
source: { ...origSource },
+ metadata: this.statsMetadata?.[origSource.stat_energy_to],
saveCallback: async (source) => {
const flowTo = energySourcesByType(this.preferences).grid![0].flow_to;
diff --git a/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts
index 2dd5ce4e1510..fa628ea6b645 100644
--- a/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts
+++ b/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts
@@ -13,6 +13,7 @@ import { HomeAssistant } from "../../../../types";
import { EnergySettingsBatteryDialogParams } from "./show-dialogs-energy";
import "@material/mwc-button/mwc-button";
import "../../../../components/entity/ha-statistic-picker";
+import { getSensorDeviceClassConvertibleUnits } from "../../../../data/sensor";
const energyUnitClasses = ["energy"];
@@ -27,6 +28,8 @@ export class DialogEnergyBatterySettings
@state() private _source?: BatterySourceTypeEnergyPreference;
+ @state() private _energy_units?: string[];
+
@state() private _error?: string;
public async showDialog(
@@ -36,6 +39,9 @@ export class DialogEnergyBatterySettings
this._source = params.source
? { ...params.source }
: emptyBatteryEnergyPreference();
+ this._energy_units = (
+ await getSensorDeviceClassConvertibleUnits(this.hass, "energy")
+ ).units;
}
public closeDialog(): void {
@@ -50,6 +56,8 @@ export class DialogEnergyBatterySettings
return html``;
}
+ const pickableUnit = this._energy_units?.join(", ") || "";
+
return html`
${this._error ? html`${this._error}
` : ""}
+
+ ${this.hass.localize(
+ "ui.panel.config.energy.battery.dialog.entity_para",
+ { unit: pickableUnit }
+ )}
+
{
this._params = params;
+ this._energy_units = (
+ await getSensorDeviceClassConvertibleUnits(this.hass, "energy")
+ ).units;
}
public closeDialog(): void {
@@ -47,6 +53,8 @@ export class DialogEnergyDeviceSettings
return html``;
}
+ const pickableUnit = this._energy_units?.join(", ") || "";
+
return html`
${this._error}
` : ""}
${this.hass.localize(
- `ui.panel.config.energy.device_consumption.dialog.selected_stat_intro`
+ "ui.panel.config.energy.device_consumption.dialog.selected_stat_intro",
+ { unit: pickableUnit }
)}
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 e616c3a79751..fc8dd9250248 100644
--- a/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts
+++ b/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts
@@ -23,6 +23,7 @@ import {
getDisplayUnit,
isExternalStatistic,
} from "../../../../data/recorder";
+import { getSensorDeviceClassConvertibleUnits } from "../../../../data/sensor";
const gasDeviceClasses = ["gas", "energy"];
const gasUnitClasses = ["volume", "energy"];
@@ -40,10 +41,12 @@ export class DialogEnergyGasSettings
@state() private _costs?: "no-costs" | "number" | "entity" | "statistic";
- @state() private _pickableUnit?: string;
-
@state() private _pickedDisplayUnit?: string | null;
+ @state() private _energy_units?: string[];
+
+ @state() private _gas_units?: string[];
+
@state() private _error?: string;
public async showDialog(
@@ -65,12 +68,17 @@ export class DialogEnergyGasSettings
: this._source.stat_cost
? "statistic"
: "no-costs";
+ this._energy_units = (
+ await getSensorDeviceClassConvertibleUnits(this.hass, "energy")
+ ).units;
+ this._gas_units = (
+ await getSensorDeviceClassConvertibleUnits(this.hass, "gas")
+ ).units;
}
public closeDialog(): void {
this._params = undefined;
this._source = undefined;
- this._pickableUnit = undefined;
this._pickedDisplayUnit = undefined;
this._error = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
@@ -82,15 +90,19 @@ export class DialogEnergyGasSettings
}
const pickableUnit =
- this._pickableUnit ||
- (this._params.allowedGasUnitClass === undefined
- ? "ft³, m³, Wh, kWh, MWh or GJ"
+ this._params.allowedGasUnitClass === undefined
+ ? [...(this._gas_units || []), ...(this._energy_units || [])].join(", ")
: this._params.allowedGasUnitClass === "energy"
- ? "Wh, kWh, MWh or GJ"
- : "ft³ or m³");
+ ? this._energy_units?.join(", ") || ""
+ : this._gas_units?.join(", ") || "";
+
+ const unitPrice = this._pickedDisplayUnit
+ ? `${this.hass.config.currency}/${this._pickedDisplayUnit}`
+ : undefined;
const externalSource =
- this._source.stat_cost && isExternalStatistic(this._source.stat_cost);
+ this._source.stat_energy_from &&
+ isExternalStatistic(this._source.stat_energy_from);
return html`
${this._error ? html`${this._error}
` : ""}
+
+
+ ${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")}
+
+
- ${this.hass.localize(`ui.panel.config.energy.gas.dialog.cost_para`)}
+ ${this.hass.localize("ui.panel.config.energy.gas.dialog.cost_para")}
@@ -158,15 +177,15 @@ export class DialogEnergyGasSettings
.hass=${this.hass}
statistic-types="sum"
.value=${this._source.stat_cost}
- .label=${this.hass.localize(
- `ui.panel.config.energy.gas.dialog.cost_stat_input`
- )}
+ .label=${`${this.hass.localize(
+ "ui.panel.config.energy.gas.dialog.cost_stat_input"
+ )} (${this.hass.config.currency})`}
@value-changed=${this._priceStatChanged}
>`
: ""}
`
: ""}
${this._costs === "number"
? html`
`
: ""}
diff --git a/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts
index 68e9879bf876..f2dd0a0012af 100644
--- a/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts
+++ b/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts
@@ -19,6 +19,12 @@ import "../../../../components/ha-radio";
import "../../../../components/ha-formfield";
import type { HaRadio } from "../../../../components/ha-radio";
import "../../../../components/entity/ha-entity-picker";
+import {
+ getStatisticMetadata,
+ getDisplayUnit,
+ isExternalStatistic,
+} from "../../../../data/recorder";
+import { getSensorDeviceClassConvertibleUnits } from "../../../../data/sensor";
const energyUnitClasses = ["energy"];
@@ -37,6 +43,10 @@ export class DialogEnergyGridFlowSettings
@state() private _costs?: "no-costs" | "number" | "entity" | "statistic";
+ @state() private _pickedDisplayUnit?: string | null;
+
+ @state() private _energy_units?: string[];
+
@state() private _error?: string;
public async showDialog(
@@ -57,11 +67,24 @@ export class DialogEnergyGridFlowSettings
]
? "statistic"
: "no-costs";
+ this._pickedDisplayUnit = getDisplayUnit(
+ this.hass,
+ this._source[
+ this._params.direction === "from"
+ ? "stat_energy_from"
+ : "stat_energy_to"
+ ],
+ params.metadata
+ );
+ this._energy_units = (
+ await getSensorDeviceClassConvertibleUnits(this.hass, "energy")
+ ).units;
}
public closeDialog(): void {
this._params = undefined;
this._source = undefined;
+ this._pickedDisplayUnit = undefined;
this._error = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -71,6 +94,26 @@ export class DialogEnergyGridFlowSettings
return html``;
}
+ const pickableUnit = this._energy_units?.join(", ") || "";
+
+ const unitPrice = this._pickedDisplayUnit
+ ? `${this.hass.config.currency}/${this._pickedDisplayUnit}`
+ : undefined;
+
+ const externalSource =
+ this._source[
+ this._params.direction === "from"
+ ? "stat_energy_from"
+ : "stat_energy_to"
+ ] &&
+ isExternalStatistic(
+ this._source[
+ this._params.direction === "from"
+ ? "stat_energy_from"
+ : "stat_energy_to"
+ ]
+ );
+
return html`
${this._error ? html`${this._error}
` : ""}
- ${this.hass.localize(
- `ui.panel.config.energy.grid.flow_dialog.${this._params.direction}.paragraph`
- )}
+
+ ${this.hass.localize(
+ `ui.panel.config.energy.grid.flow_dialog.${this._params.direction}.paragraph`
+ )}
+
+
+ ${this.hass.localize(
+ `ui.panel.config.energy.grid.flow_dialog.${this._params.direction}.entity_para`,
+ { unit: pickableUnit }
+ )}
+
`
: ""}
@@ -160,6 +211,7 @@ export class DialogEnergyGridFlowSettings
value="entity"
name="costs"
.checked=${this._costs === "entity"}
+ .disabled=${externalSource}
@change=${this._handleCostChanged}
>
@@ -169,9 +221,9 @@ export class DialogEnergyGridFlowSettings
.hass=${this.hass}
include-domains='["sensor", "input_number"]'
.value=${this._source.entity_energy_price}
- .label=${this.hass.localize(
+ .label=${`${this.hass.localize(
`ui.panel.config.energy.grid.flow_dialog.${this._params.direction}.cost_entity_input`
- )}
+ )} ${unitPrice ? ` (${unitPrice})` : ""}`}
@value-changed=${this._priceEntityChanged}
>`
: ""}
@@ -184,22 +236,20 @@ export class DialogEnergyGridFlowSettings
value="number"
name="costs"
.checked=${this._costs === "number"}
+ .disabled=${externalSource}
@change=${this._handleCostChanged}
>
${this._costs === "number"
? html`
`
@@ -261,7 +311,17 @@ export class DialogEnergyGridFlowSettings
};
}
- private _statisticChanged(ev: CustomEvent<{ value: string }>) {
+ private async _statisticChanged(ev: CustomEvent<{ value: string }>) {
+ if (ev.detail.value) {
+ const metadata = await getStatisticMetadata(this.hass, [ev.detail.value]);
+ this._pickedDisplayUnit = getDisplayUnit(
+ this.hass,
+ ev.detail.value,
+ metadata[0]
+ );
+ } else {
+ this._pickedDisplayUnit = undefined;
+ }
this._source = {
...this._source!,
[this._params!.direction === "from"
diff --git a/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts
index 3423932916fc..d6a47eefba2a 100644
--- a/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts
+++ b/src/panels/config/energy/dialogs/dialog-energy-solar-settings.ts
@@ -21,6 +21,7 @@ import type { HaRadio } from "../../../../components/ha-radio";
import { showConfigFlowDialog } from "../../../../dialogs/config-flow/show-dialog-config-flow";
import { ConfigEntry, getConfigEntries } from "../../../../data/config_entries";
import { brandsUrl } from "../../../../util/brands-url";
+import { getSensorDeviceClassConvertibleUnits } from "../../../../data/sensor";
const energyUnitClasses = ["energy"];
@@ -39,6 +40,8 @@ export class DialogEnergySolarSettings
@state() private _forecast?: boolean;
+ @state() private _energy_units?: string[];
+
@state() private _error?: string;
public async showDialog(
@@ -50,6 +53,9 @@ export class DialogEnergySolarSettings
? { ...params.source }
: emptySolarEnergyPreference();
this._forecast = this._source.config_entry_solar_forecast !== null;
+ this._energy_units = (
+ await getSensorDeviceClassConvertibleUnits(this.hass, "energy")
+ ).units;
}
public closeDialog(): void {
@@ -64,6 +70,8 @@ export class DialogEnergySolarSettings
return html``;
}
+ const pickableUnit = this._energy_units?.join(", ") || "";
+
return html`
${this._error ? html`${this._error}
` : ""}
+
+ ${this.hass.localize(
+ "ui.panel.config.energy.solar.dialog.entity_para",
+ { unit: pickableUnit }
+ )}
+
${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`)}
+ ${this.hass.localize("ui.panel.config.energy.water.dialog.cost_para")}
@@ -125,15 +162,15 @@ export class DialogEnergyWaterSettings
.hass=${this.hass}
statistic-types="sum"
.value=${this._source.stat_cost}
- .label=${this.hass.localize(
- `ui.panel.config.energy.water.dialog.cost_stat_input`
- )}
+ .label=${`${this.hass.localize(
+ "ui.panel.config.energy.water.dialog.cost_stat_input"
+ )} (${this.hass.config.currency})`}
@value-changed=${this._priceStatChanged}
>`
: ""}
`
: ""}
${this._costs === "number"
? html`
`
: ""}
@@ -230,6 +268,16 @@ export class DialogEnergyWaterSettings
}
private async _statisticChanged(ev: CustomEvent<{ value: string }>) {
+ if (ev.detail.value) {
+ const metadata = await getStatisticMetadata(this.hass, [ev.detail.value]);
+ this._pickedDisplayUnit = getDisplayUnit(
+ this.hass,
+ ev.detail.value,
+ metadata[0]
+ );
+ } else {
+ this._pickedDisplayUnit = undefined;
+ }
if (isExternalStatistic(ev.detail.value) && this._costs !== "statistic") {
this._costs = "no-costs";
}
diff --git a/src/panels/config/energy/dialogs/show-dialogs-energy.ts b/src/panels/config/energy/dialogs/show-dialogs-energy.ts
index 06eccf7b9c80..c9fea02a61e9 100644
--- a/src/panels/config/energy/dialogs/show-dialogs-energy.ts
+++ b/src/panels/config/energy/dialogs/show-dialogs-energy.ts
@@ -16,6 +16,7 @@ export interface EnergySettingsGridFlowDialogParams {
source?:
| FlowFromGridSourceEnergyPreference
| FlowToGridSourceEnergyPreference;
+ metadata?: StatisticsMetaData;
direction: "from" | "to";
saveCallback: (
source:
@@ -26,11 +27,13 @@ export interface EnergySettingsGridFlowDialogParams {
export interface EnergySettingsGridFlowFromDialogParams {
source?: FlowFromGridSourceEnergyPreference;
+ metadata?: StatisticsMetaData;
saveCallback: (source: FlowFromGridSourceEnergyPreference) => Promise;
}
export interface EnergySettingsGridFlowToDialogParams {
source?: FlowToGridSourceEnergyPreference;
+ metadata?: StatisticsMetaData;
saveCallback: (source: FlowToGridSourceEnergyPreference) => Promise;
}
diff --git a/src/translations/en.json b/src/translations/en.json
index c063af08648e..3cc04a768832 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -1520,30 +1520,30 @@
"from": {
"header": "Configure grid consumption",
"paragraph": "Grid consumption is the energy that flows from the energy grid to your home.",
- "energy_stat": "Consumed Energy (kWh)",
+ "entity_para": "Pick a sensor which measures grid consumption in either of {unit}.",
+ "energy_stat": "Consumed Energy",
"cost_para": "Select how Home Assistant should keep track of the costs of the consumed energy.",
"no_cost": "Do not track costs",
"cost_stat": "Use an entity tracking the total costs",
- "cost_stat_input": "Total Costs Entity",
+ "cost_stat_input": "Entity with the total costs",
"cost_entity": "Use an entity with current price",
"cost_entity_input": "Entity with the current price",
"cost_number": "Use a static price",
- "cost_number_input": "Price per kWh",
- "cost_number_suffix": "{currency}/kWh"
+ "cost_number_input": "Price"
},
"to": {
"header": "Configure grid production",
"paragraph": "Grid production is the energy that flows from your solar panels to the grid.",
- "energy_stat": "Energy returned to the grid (kWh)",
+ "entity_para": "Pick a sensor which measures grid production in either of {unit}.",
+ "energy_stat": "Energy returned to the grid",
"cost_para": "Do you get money back when you return energy to the grid?",
"no_cost": "I do not get money back",
"cost_stat": "Use an entity tracking the total recieved money",
- "cost_stat_input": "Total Compensation Entity",
+ "cost_stat_input": "Entity with the total compensation",
"cost_entity": "Use an entity with current rate",
"cost_entity_input": "Entity with the current rate",
"cost_number": "Use a static rate",
- "cost_number_input": "Rate per kWh",
- "cost_number_suffix": "{currency}/kWh"
+ "cost_number_input": "Rate"
}
}
},
@@ -1560,7 +1560,8 @@
"stat_predicted_production": "Prediction of your solar energy production",
"dialog": {
"header": "Configure solar panels",
- "solar_production_energy": "Solar production energy (kWh)",
+ "entity_para": "Pick a sensor which measures solar energy production in either of {unit}.",
+ "solar_production_energy": "Solar production energy",
"solar_production_forecast": "Solar production forecast",
"solar_production_forecast_description": "Adding solar production forecast information will allow you to quickly see your expected production for today.",
"dont_forecast_production": "Don't forecast production",
@@ -1578,8 +1579,9 @@
"add_battery_system": "Add battery system",
"dialog": {
"header": "Configure battery system",
- "energy_into_battery": "Energy going in to the battery (kWh)",
- "energy_out_of_battery": "Energy coming out of the battery (kWh)"
+ "entity_para": "Pick sensors which measure energy going in to and out of the battery in either of {unit}.",
+ "energy_into_battery": "Energy going in to the battery",
+ "energy_out_of_battery": "Energy coming out of the battery"
}
},
"gas": {
@@ -1592,18 +1594,18 @@
"add_gas_source": "Add gas source",
"dialog": {
"header": "Configure gas consumption",
- "paragraph": "Gas consumption is the volume of gas that flows to your home.",
- "energy_stat": "Consumed Energy (m³)",
- "cost_para": "Select how Home Assistant should keep track of the costs of the consumed energy.",
- "no_cost": "Do not track costs",
- "cost_stat": "Use an entity tracking the total costs",
- "cost_stat_input": "Total Costs Entity",
- "cost_entity": "Use an entity with current price",
- "cost_entity_input": "Entity with the current price per {unit}",
- "cost_number": "Use a static price",
- "cost_number_input": "Price per {unit}",
- "gas_usage": "Gas usage",
- "m3_or_kWh": "ft³, m³, Wh, kWh, MWh or GJ"
+ "paragraph": "Gas consumption is measured either as the volume of gas that flows to your home or as the amount of energy contained in the gas.",
+ "entity_para": "Pick a sensor which measures gas consumption in either of {unit}.",
+ "note_para": "Note: It is not possible to add both sensors measuring a volume of gas and sensors measuring the amount of energy contained in the gas.",
+ "cost_para": "Select how Home Assistant should keep track of the costs of the consumed gas.",
+ "no_cost": "[%key:ui::panel::config::energy::grid::flow_dialog::from::no_cost%]",
+ "cost_stat": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_stat%]",
+ "cost_stat_input": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_stat_input%]",
+ "cost_entity": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_entity%]",
+ "cost_entity_input": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_entity_input%]",
+ "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"
}
},
"water": {
@@ -1617,16 +1619,16 @@
"dialog": {
"header": "Configure water consumption",
"paragraph": "Water consumption is the volume of water that flows to your home.",
- "energy_stat": "Consumed water (m³ or gl)",
+ "entity_para": "Pick a sensor which measures gas consumption in either of {unit}.",
"cost_para": "Select how Home Assistant should keep track of the costs of the consumed water.",
- "no_cost": "Do not track costs",
- "cost_stat": "Use an entity tracking the total costs",
- "cost_stat_input": "Total Costs Entity",
- "cost_entity": "Use an entity with current price",
- "cost_entity_input": "Entity with the current price per m³ or gl",
- "cost_number": "Use a static price",
- "cost_number_input": "Price per m³ or gl",
- "water_usage": "Water usage (m³ or gl)"
+ "no_cost": "[%key:ui::panel::config::energy::grid::flow_dialog::from::no_cost%]",
+ "cost_stat": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_stat%]",
+ "cost_stat_input": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_stat_input%]",
+ "cost_entity": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_entity%]",
+ "cost_entity_input": "[%key:ui::panel::config::energy::grid::flow_dialog::from::cost_entity_input%]",
+ "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"
}
},
"device_consumption": {
@@ -1639,8 +1641,8 @@
"add_device": "Add device",
"dialog": {
"header": "Add a device",
- "device_consumption_energy": "Device consumption energy (kWh)",
- "selected_stat_intro": "Select the entity that represents the device energy usage."
+ "device_consumption_energy": "Device consumption energy",
+ "selected_stat_intro": "Select the energy sensor that measures the device's energy usage in either of {unit}."
}
}
},