mirror of
https://github.com/home-assistant/frontend.git
synced 2025-05-01 00:37:20 +00:00
Allow gas to be in kWh (#10075)
* Allow gas to be in kWh * Extract some gas unit helpers * Forgot to save a refactor Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
b26c44b2b9
commit
e4b4dc4ae9
@ -453,3 +453,53 @@ export const getEnergySolarForecasts = (hass: HomeAssistant) =>
|
|||||||
hass.callWS<EnergySolarForecasts>({
|
hass.callWS<EnergySolarForecasts>({
|
||||||
type: "energy/solar_forecast",
|
type: "energy/solar_forecast",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const ENERGY_GAS_VOLUME_UNITS = ["m³", "ft³"];
|
||||||
|
export const ENERGY_GAS_ENERGY_UNITS = ["kWh"];
|
||||||
|
export const ENERGY_GAS_UNITS = [
|
||||||
|
...ENERGY_GAS_VOLUME_UNITS,
|
||||||
|
...ENERGY_GAS_ENERGY_UNITS,
|
||||||
|
];
|
||||||
|
|
||||||
|
export type EnergyGasUnit = "volume" | "energy";
|
||||||
|
|
||||||
|
export const getEnergyGasUnitCategory = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
prefs: EnergyPreferences
|
||||||
|
): EnergyGasUnit | undefined => {
|
||||||
|
for (const source of prefs.energy_sources) {
|
||||||
|
if (source.type !== "gas") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const entity = hass.states[source.stat_energy_from];
|
||||||
|
if (entity) {
|
||||||
|
return ENERGY_GAS_VOLUME_UNITS.includes(
|
||||||
|
entity.attributes.unit_of_measurement!
|
||||||
|
)
|
||||||
|
? "volume"
|
||||||
|
: "energy";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getEnergyGasUnit = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
prefs: EnergyPreferences
|
||||||
|
): string | undefined => {
|
||||||
|
for (const source of prefs.energy_sources) {
|
||||||
|
if (source.type !== "gas") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const entity = hass.states[source.stat_energy_from];
|
||||||
|
if (entity?.attributes.unit_of_measurement) {
|
||||||
|
// Wh is normalized to kWh by stats generation
|
||||||
|
return entity.attributes.unit_of_measurement === "Wh"
|
||||||
|
? "kWh"
|
||||||
|
: entity.attributes.unit_of_measurement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
GasSourceTypeEnergyPreference,
|
GasSourceTypeEnergyPreference,
|
||||||
EnergyPreferencesValidation,
|
EnergyPreferencesValidation,
|
||||||
EnergyValidationIssue,
|
EnergyValidationIssue,
|
||||||
|
getEnergyGasUnitCategory,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import {
|
import {
|
||||||
showConfirmationDialog,
|
showConfirmationDialog,
|
||||||
@ -109,6 +110,7 @@ export class EnergyGasSettings extends LitElement {
|
|||||||
|
|
||||||
private _addSource() {
|
private _addSource() {
|
||||||
showEnergySettingsGasDialog(this, {
|
showEnergySettingsGasDialog(this, {
|
||||||
|
unit: getEnergyGasUnitCategory(this.hass, this.preferences),
|
||||||
saveCallback: async (source) => {
|
saveCallback: async (source) => {
|
||||||
await this._savePreferences({
|
await this._savePreferences({
|
||||||
...this.preferences,
|
...this.preferences,
|
||||||
@ -123,6 +125,7 @@ export class EnergyGasSettings extends LitElement {
|
|||||||
ev.currentTarget.closest(".row").source;
|
ev.currentTarget.closest(".row").source;
|
||||||
showEnergySettingsGasDialog(this, {
|
showEnergySettingsGasDialog(this, {
|
||||||
source: { ...origSource },
|
source: { ...origSource },
|
||||||
|
unit: getEnergyGasUnitCategory(this.hass, this.preferences),
|
||||||
saveCallback: async (newSource) => {
|
saveCallback: async (newSource) => {
|
||||||
await this._savePreferences({
|
await this._savePreferences({
|
||||||
...this.preferences,
|
...this.preferences,
|
||||||
|
@ -5,6 +5,9 @@ import { fireEvent } from "../../../../common/dom/fire_event";
|
|||||||
import "../../../../components/ha-dialog";
|
import "../../../../components/ha-dialog";
|
||||||
import {
|
import {
|
||||||
emptyGasEnergyPreference,
|
emptyGasEnergyPreference,
|
||||||
|
ENERGY_GAS_ENERGY_UNITS,
|
||||||
|
ENERGY_GAS_UNITS,
|
||||||
|
ENERGY_GAS_VOLUME_UNITS,
|
||||||
GasSourceTypeEnergyPreference,
|
GasSourceTypeEnergyPreference,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
import { HassDialog } from "../../../../dialogs/make-dialog-manager";
|
||||||
@ -18,8 +21,6 @@ import "../../../../components/ha-radio";
|
|||||||
import "../../../../components/ha-formfield";
|
import "../../../../components/ha-formfield";
|
||||||
import type { HaRadio } from "../../../../components/ha-radio";
|
import type { HaRadio } from "../../../../components/ha-radio";
|
||||||
|
|
||||||
const energyUnits = ["m³"];
|
|
||||||
|
|
||||||
@customElement("dialog-energy-gas-settings")
|
@customElement("dialog-energy-gas-settings")
|
||||||
export class DialogEnergyGasSettings
|
export class DialogEnergyGasSettings
|
||||||
extends LitElement
|
extends LitElement
|
||||||
@ -77,9 +78,19 @@ export class DialogEnergyGasSettings
|
|||||||
|
|
||||||
<ha-statistic-picker
|
<ha-statistic-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.includeUnitOfMeasurement=${energyUnits}
|
.includeUnitOfMeasurement=${this._params.unit === undefined
|
||||||
|
? ENERGY_GAS_UNITS
|
||||||
|
: this._params.unit === "energy"
|
||||||
|
? ENERGY_GAS_ENERGY_UNITS
|
||||||
|
: ENERGY_GAS_VOLUME_UNITS}
|
||||||
.value=${this._source.stat_energy_from}
|
.value=${this._source.stat_energy_from}
|
||||||
.label=${`Gas usage (m³)`}
|
.label=${`Gas usage (${
|
||||||
|
this._params.unit === undefined
|
||||||
|
? "m³ or kWh"
|
||||||
|
: this._params.unit === "energy"
|
||||||
|
? "kWh"
|
||||||
|
: "m³"
|
||||||
|
})`}
|
||||||
entities-only
|
entities-only
|
||||||
@value-changed=${this._statisticChanged}
|
@value-changed=${this._statisticChanged}
|
||||||
></ha-statistic-picker>
|
></ha-statistic-picker>
|
||||||
|
@ -2,6 +2,7 @@ import { fireEvent } from "../../../../common/dom/fire_event";
|
|||||||
import {
|
import {
|
||||||
BatterySourceTypeEnergyPreference,
|
BatterySourceTypeEnergyPreference,
|
||||||
DeviceConsumptionEnergyPreference,
|
DeviceConsumptionEnergyPreference,
|
||||||
|
EnergyGasUnit,
|
||||||
EnergyInfo,
|
EnergyInfo,
|
||||||
FlowFromGridSourceEnergyPreference,
|
FlowFromGridSourceEnergyPreference,
|
||||||
FlowToGridSourceEnergyPreference,
|
FlowToGridSourceEnergyPreference,
|
||||||
@ -44,6 +45,7 @@ export interface EnergySettingsBatteryDialogParams {
|
|||||||
|
|
||||||
export interface EnergySettingsGasDialogParams {
|
export interface EnergySettingsGasDialogParams {
|
||||||
source?: GasSourceTypeEnergyPreference;
|
source?: GasSourceTypeEnergyPreference;
|
||||||
|
unit?: EnergyGasUnit;
|
||||||
saveCallback: (source: GasSourceTypeEnergyPreference) => Promise<void>;
|
saveCallback: (source: GasSourceTypeEnergyPreference) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
EnergyData,
|
EnergyData,
|
||||||
energySourcesByType,
|
energySourcesByType,
|
||||||
getEnergyDataCollection,
|
getEnergyDataCollection,
|
||||||
|
getEnergyGasUnit,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import {
|
import {
|
||||||
calculateStatisticsSumGrowth,
|
calculateStatisticsSumGrowth,
|
||||||
@ -309,7 +310,7 @@ class HuiEnergyDistrubutionCard
|
|||||||
${formatNumber(gasUsage || 0, this.hass.locale, {
|
${formatNumber(gasUsage || 0, this.hass.locale, {
|
||||||
maximumFractionDigits: 1,
|
maximumFractionDigits: 1,
|
||||||
})}
|
})}
|
||||||
m³
|
${getEnergyGasUnit(this.hass, prefs) || "m³"}
|
||||||
</div>
|
</div>
|
||||||
<svg width="80" height="30">
|
<svg width="80" height="30">
|
||||||
<path d="M40 0 v30" id="gas" />
|
<path d="M40 0 v30" id="gas" />
|
||||||
|
@ -24,6 +24,7 @@ import { labDarken } from "../../../../common/color/lab";
|
|||||||
import {
|
import {
|
||||||
EnergyData,
|
EnergyData,
|
||||||
getEnergyDataCollection,
|
getEnergyDataCollection,
|
||||||
|
getEnergyGasUnit,
|
||||||
GasSourceTypeEnergyPreference,
|
GasSourceTypeEnergyPreference,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
||||||
@ -56,6 +57,8 @@ export class HuiEnergyGasGraphCard
|
|||||||
|
|
||||||
@state() private _end = endOfToday();
|
@state() private _end = endOfToday();
|
||||||
|
|
||||||
|
@state() private _unit?: string;
|
||||||
|
|
||||||
public hassSubscribe(): UnsubscribeFunc[] {
|
public hassSubscribe(): UnsubscribeFunc[] {
|
||||||
return [
|
return [
|
||||||
getEnergyDataCollection(this.hass, {
|
getEnergyDataCollection(this.hass, {
|
||||||
@ -92,7 +95,8 @@ export class HuiEnergyGasGraphCard
|
|||||||
.options=${this._createOptions(
|
.options=${this._createOptions(
|
||||||
this._start,
|
this._start,
|
||||||
this._end,
|
this._end,
|
||||||
this.hass.locale
|
this.hass.locale,
|
||||||
|
this._unit
|
||||||
)}
|
)}
|
||||||
chart-type="bar"
|
chart-type="bar"
|
||||||
></ha-chart-base>
|
></ha-chart-base>
|
||||||
@ -109,7 +113,12 @@ export class HuiEnergyGasGraphCard
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _createOptions = memoizeOne(
|
private _createOptions = memoizeOne(
|
||||||
(start: Date, end: Date, locale: FrontendLocaleData): ChartOptions => {
|
(
|
||||||
|
start: Date,
|
||||||
|
end: Date,
|
||||||
|
locale: FrontendLocaleData,
|
||||||
|
unit?: string
|
||||||
|
): ChartOptions => {
|
||||||
const dayDifference = differenceInDays(end, start);
|
const dayDifference = differenceInDays(end, start);
|
||||||
return {
|
return {
|
||||||
parsing: false,
|
parsing: false,
|
||||||
@ -160,7 +169,7 @@ export class HuiEnergyGasGraphCard
|
|||||||
type: "linear",
|
type: "linear",
|
||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: "m³",
|
text: unit,
|
||||||
},
|
},
|
||||||
ticks: {
|
ticks: {
|
||||||
beginAtZero: true,
|
beginAtZero: true,
|
||||||
@ -175,7 +184,7 @@ export class HuiEnergyGasGraphCard
|
|||||||
`${context.dataset.label}: ${formatNumber(
|
`${context.dataset.label}: ${formatNumber(
|
||||||
context.parsed.y,
|
context.parsed.y,
|
||||||
locale
|
locale
|
||||||
)} m³`,
|
)} ${unit}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
filler: {
|
filler: {
|
||||||
@ -209,6 +218,8 @@ export class HuiEnergyGasGraphCard
|
|||||||
(source) => source.type === "gas"
|
(source) => source.type === "gas"
|
||||||
) as GasSourceTypeEnergyPreference[];
|
) as GasSourceTypeEnergyPreference[];
|
||||||
|
|
||||||
|
this._unit = getEnergyGasUnit(this.hass, energyData.prefs) || "m³";
|
||||||
|
|
||||||
const statisticsData = Object.values(energyData.stats);
|
const statisticsData = Object.values(energyData.stats);
|
||||||
const datasets: ChartDataset<"bar">[] = [];
|
const datasets: ChartDataset<"bar">[] = [];
|
||||||
let endTime: Date;
|
let endTime: Date;
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
EnergyData,
|
EnergyData,
|
||||||
energySourcesByType,
|
energySourcesByType,
|
||||||
getEnergyDataCollection,
|
getEnergyDataCollection,
|
||||||
|
getEnergyGasUnit,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import { calculateStatisticSumGrowth } from "../../../../data/history";
|
import { calculateStatisticSumGrowth } from "../../../../data/history";
|
||||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||||
@ -116,6 +117,8 @@ export class HuiEnergySourcesTableCard
|
|||||||
flow.stat_cost || flow.entity_energy_price || flow.number_energy_price
|
flow.stat_cost || flow.entity_energy_price || flow.number_energy_price
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const gasUnit = getEnergyGasUnit(this.hass, this._data.prefs) || "";
|
||||||
|
|
||||||
return html` <ha-card>
|
return html` <ha-card>
|
||||||
${this._config.title
|
${this._config.title
|
||||||
? html`<h1 class="card-header">${this._config.title}</h1>`
|
? html`<h1 class="card-header">${this._config.title}</h1>`
|
||||||
@ -445,6 +448,7 @@ export class HuiEnergySourcesTableCard
|
|||||||
this._data!.stats[source.stat_energy_from]
|
this._data!.stats[source.stat_energy_from]
|
||||||
) || 0;
|
) || 0;
|
||||||
totalGas += energy;
|
totalGas += energy;
|
||||||
|
|
||||||
const cost_stat =
|
const cost_stat =
|
||||||
source.stat_cost ||
|
source.stat_cost ||
|
||||||
this._data!.info.cost_sensors[source.stat_energy_from];
|
this._data!.info.cost_sensors[source.stat_energy_from];
|
||||||
@ -479,7 +483,7 @@ export class HuiEnergySourcesTableCard
|
|||||||
<td
|
<td
|
||||||
class="mdc-data-table__cell mdc-data-table__cell--numeric"
|
class="mdc-data-table__cell mdc-data-table__cell--numeric"
|
||||||
>
|
>
|
||||||
${formatNumber(energy, this.hass.locale)} m³
|
${formatNumber(energy, this.hass.locale)} ${gasUnit}
|
||||||
</td>
|
</td>
|
||||||
${showCosts
|
${showCosts
|
||||||
? html`<td
|
? html`<td
|
||||||
@ -502,7 +506,7 @@ export class HuiEnergySourcesTableCard
|
|||||||
<td
|
<td
|
||||||
class="mdc-data-table__cell mdc-data-table__cell--numeric"
|
class="mdc-data-table__cell mdc-data-table__cell--numeric"
|
||||||
>
|
>
|
||||||
${formatNumber(totalGas, this.hass.locale)} m³
|
${formatNumber(totalGas, this.hass.locale)} ${gasUnit}
|
||||||
</td>
|
</td>
|
||||||
${showCosts
|
${showCosts
|
||||||
? html`<td
|
? html`<td
|
||||||
|
Loading…
x
Reference in New Issue
Block a user