mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-29 04:06:35 +00:00
More support for no-grid energy dashboard (#25644)
* More support for no-grid energy dashboard * Update src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com> * lint --------- Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
This commit is contained in:
parent
9d6a7e7e6f
commit
b3f0a6328e
@ -64,7 +64,9 @@ export class EnergyViewStrategy extends ReactiveElement {
|
|||||||
(source) => source.type === "solar"
|
(source) => source.type === "solar"
|
||||||
);
|
);
|
||||||
const hasGas = prefs.energy_sources.some((source) => source.type === "gas");
|
const hasGas = prefs.energy_sources.some((source) => source.type === "gas");
|
||||||
|
const hasBattery = prefs.energy_sources.some(
|
||||||
|
(source) => source.type === "battery"
|
||||||
|
);
|
||||||
const hasWater = prefs.energy_sources.some(
|
const hasWater = prefs.energy_sources.some(
|
||||||
(source) => source.type === "water"
|
(source) => source.type === "water"
|
||||||
);
|
);
|
||||||
@ -74,8 +76,8 @@ export class EnergyViewStrategy extends ReactiveElement {
|
|||||||
collection_key: "energy_dashboard",
|
collection_key: "energy_dashboard",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only include if we have a grid source.
|
// Only include if we have a grid or battery.
|
||||||
if (hasGrid) {
|
if (hasGrid || hasBattery) {
|
||||||
view.cards!.push({
|
view.cards!.push({
|
||||||
title: hass.localize("ui.panel.energy.cards.energy_usage_graph_title"),
|
title: hass.localize("ui.panel.energy.cards.energy_usage_graph_title"),
|
||||||
type: "energy-usage-graph",
|
type: "energy-usage-graph",
|
||||||
@ -110,8 +112,8 @@ export class EnergyViewStrategy extends ReactiveElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only include if we have a grid.
|
// Only include if we have a grid or battery.
|
||||||
if (hasGrid) {
|
if (hasGrid || hasBattery) {
|
||||||
view.cards!.push({
|
view.cards!.push({
|
||||||
title: hass.localize("ui.panel.energy.cards.energy_distribution_title"),
|
title: hass.localize("ui.panel.energy.cards.energy_distribution_title"),
|
||||||
type: "energy-distribution",
|
type: "energy-distribution",
|
||||||
@ -120,7 +122,7 @@ export class EnergyViewStrategy extends ReactiveElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasGrid || hasSolar || hasGas || hasWater) {
|
if (hasGrid || hasSolar || hasGas || hasWater || hasBattery) {
|
||||||
view.cards!.push({
|
view.cards!.push({
|
||||||
title: hass.localize(
|
title: hass.localize(
|
||||||
"ui.panel.energy.cards.energy_sources_table_title"
|
"ui.panel.energy.cards.energy_sources_table_title"
|
||||||
|
@ -102,14 +102,13 @@ class HuiEnergyDistrubutionCard
|
|||||||
const prefs = this._data.prefs;
|
const prefs = this._data.prefs;
|
||||||
const types = energySourcesByType(prefs);
|
const types = energySourcesByType(prefs);
|
||||||
|
|
||||||
// The strategy only includes this card if we have a grid.
|
const hasGrid =
|
||||||
const hasConsumption = true;
|
!!types.grid?.[0].flow_from.length || !!types.grid?.[0].flow_to.length;
|
||||||
|
|
||||||
const hasSolarProduction = types.solar !== undefined;
|
const hasSolarProduction = types.solar !== undefined;
|
||||||
const hasBattery = types.battery !== undefined;
|
const hasBattery = types.battery !== undefined;
|
||||||
const hasGas = types.gas !== undefined;
|
const hasGas = types.gas !== undefined;
|
||||||
const hasWater = types.water !== undefined;
|
const hasWater = types.water !== undefined;
|
||||||
const hasReturnToGrid = hasConsumption && types.grid![0].flow_to.length > 0;
|
const hasReturnToGrid = !!types.grid?.[0].flow_to.length;
|
||||||
|
|
||||||
const { summedData, compareSummedData: _ } = getSummedData(this._data);
|
const { summedData, compareSummedData: _ } = getSummedData(this._data);
|
||||||
const { consumption, compareConsumption: __ } = computeConsumptionData(
|
const { consumption, compareConsumption: __ } = computeConsumptionData(
|
||||||
@ -163,14 +162,14 @@ class HuiEnergyDistrubutionCard
|
|||||||
}
|
}
|
||||||
let batteryFromGrid: null | number = null;
|
let batteryFromGrid: null | number = null;
|
||||||
let batteryToGrid: null | number = null;
|
let batteryToGrid: null | number = null;
|
||||||
if (hasBattery) {
|
if (hasBattery && hasGrid) {
|
||||||
batteryToGrid = consumption.total.battery_to_grid;
|
batteryToGrid = consumption.total.battery_to_grid;
|
||||||
batteryFromGrid = consumption.total.grid_to_battery;
|
batteryFromGrid = consumption.total.grid_to_battery;
|
||||||
}
|
}
|
||||||
|
|
||||||
let solarToBattery: null | number = null;
|
let solarToBattery: null | number = null;
|
||||||
let solarToGrid: null | number = null;
|
let solarToGrid: null | number = null;
|
||||||
if (hasSolarProduction) {
|
if (hasSolarProduction && hasGrid) {
|
||||||
solarToGrid = consumption.total.solar_to_grid;
|
solarToGrid = consumption.total.solar_to_grid;
|
||||||
}
|
}
|
||||||
if (hasSolarProduction && hasBattery) {
|
if (hasSolarProduction && hasBattery) {
|
||||||
@ -182,7 +181,9 @@ class HuiEnergyDistrubutionCard
|
|||||||
batteryConsumption = Math.max(consumption.total.used_battery, 0);
|
batteryConsumption = Math.max(consumption.total.used_battery, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const gridConsumption = Math.max(consumption.total.used_grid, 0);
|
const gridConsumption = hasGrid
|
||||||
|
? Math.max(consumption.total.used_grid, 0)
|
||||||
|
: 0;
|
||||||
|
|
||||||
const totalHomeConsumption = Math.max(0, consumption.total.used_total);
|
const totalHomeConsumption = Math.max(0, consumption.total.used_total);
|
||||||
|
|
||||||
@ -206,7 +207,11 @@ class HuiEnergyDistrubutionCard
|
|||||||
// This fallback is used in the demo
|
// This fallback is used in the demo
|
||||||
let electricityMapUrl = "https://app.electricitymap.org";
|
let electricityMapUrl = "https://app.electricitymap.org";
|
||||||
|
|
||||||
if (this._data.co2SignalEntity && this._data.fossilEnergyConsumption) {
|
if (
|
||||||
|
hasGrid &&
|
||||||
|
this._data.co2SignalEntity &&
|
||||||
|
this._data.fossilEnergyConsumption
|
||||||
|
) {
|
||||||
// Calculate high carbon consumption
|
// Calculate high carbon consumption
|
||||||
const highCarbonEnergy = Object.values(
|
const highCarbonEnergy = Object.values(
|
||||||
this._data.fossilEnergyConsumption
|
this._data.fossilEnergyConsumption
|
||||||
@ -225,7 +230,7 @@ class HuiEnergyDistrubutionCard
|
|||||||
if (gridConsumption !== totalFromGrid) {
|
if (gridConsumption !== totalFromGrid) {
|
||||||
// Only get the part that was used for consumption and not the battery
|
// Only get the part that was used for consumption and not the battery
|
||||||
highCarbonConsumption =
|
highCarbonConsumption =
|
||||||
highCarbonEnergy * (gridConsumption / totalFromGrid);
|
highCarbonEnergy * (gridConsumption! / totalFromGrid);
|
||||||
} else {
|
} else {
|
||||||
highCarbonConsumption = highCarbonEnergy;
|
highCarbonConsumption = highCarbonEnergy;
|
||||||
}
|
}
|
||||||
@ -378,41 +383,43 @@ class HuiEnergyDistrubutionCard
|
|||||||
</div>`
|
</div>`
|
||||||
: ""}
|
: ""}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="circle-container grid">
|
${hasGrid
|
||||||
<div class="circle">
|
? html`<div class="circle-container grid">
|
||||||
<ha-svg-icon .path=${mdiTransmissionTower}></ha-svg-icon>
|
<div class="circle">
|
||||||
${returnedToGrid !== null
|
<ha-svg-icon .path=${mdiTransmissionTower}></ha-svg-icon>
|
||||||
? html`<span class="return">
|
${returnedToGrid !== null
|
||||||
<ha-svg-icon
|
? html`<span class="return">
|
||||||
class="small"
|
<ha-svg-icon
|
||||||
.path=${mdiArrowLeft}
|
class="small"
|
||||||
></ha-svg-icon
|
.path=${mdiArrowLeft}
|
||||||
>${formatConsumptionShort(
|
></ha-svg-icon
|
||||||
|
>${formatConsumptionShort(
|
||||||
|
this.hass,
|
||||||
|
returnedToGrid,
|
||||||
|
"kWh"
|
||||||
|
)}
|
||||||
|
</span>`
|
||||||
|
: ""}
|
||||||
|
<span class="consumption">
|
||||||
|
${hasReturnToGrid
|
||||||
|
? html`<ha-svg-icon
|
||||||
|
class="small"
|
||||||
|
.path=${mdiArrowRight}
|
||||||
|
></ha-svg-icon>`
|
||||||
|
: ""}${formatConsumptionShort(
|
||||||
this.hass,
|
this.hass,
|
||||||
returnedToGrid,
|
totalFromGrid,
|
||||||
"kWh"
|
"kWh"
|
||||||
)}
|
)}
|
||||||
</span>`
|
</span>
|
||||||
: ""}
|
</div>
|
||||||
<span class="consumption">
|
<span class="label"
|
||||||
${hasReturnToGrid
|
>${this.hass.localize(
|
||||||
? html`<ha-svg-icon
|
"ui.panel.lovelace.cards.energy.energy_distribution.grid"
|
||||||
class="small"
|
)}</span
|
||||||
.path=${mdiArrowRight}
|
>
|
||||||
></ha-svg-icon>`
|
</div> `
|
||||||
: ""}${formatConsumptionShort(
|
: html`<div class="grid-spacer"></div>`}
|
||||||
this.hass,
|
|
||||||
totalFromGrid,
|
|
||||||
"kWh"
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span class="label"
|
|
||||||
>${this.hass.localize(
|
|
||||||
"ui.panel.lovelace.cards.energy.energy_distribution.grid"
|
|
||||||
)}</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div class="circle-container home">
|
<div class="circle-container home">
|
||||||
<div
|
<div
|
||||||
class="circle ${classMap({
|
class="circle ${classMap({
|
||||||
@ -480,22 +487,27 @@ class HuiEnergyDistrubutionCard
|
|||||||
shape-rendering="geometricPrecision"
|
shape-rendering="geometricPrecision"
|
||||||
/>`
|
/>`
|
||||||
: ""}
|
: ""}
|
||||||
<circle
|
${hasGrid
|
||||||
|
? svg`<circle
|
||||||
class="grid"
|
class="grid"
|
||||||
cx="40"
|
cx="40"
|
||||||
cy="40"
|
cy="40"
|
||||||
r="38"
|
r="38"
|
||||||
stroke-dasharray="${homeHighCarbonCircumference ??
|
stroke-dasharray="${
|
||||||
CIRCLE_CIRCUMFERENCE -
|
homeHighCarbonCircumference ??
|
||||||
homeSolarCircumference! -
|
CIRCLE_CIRCUMFERENCE -
|
||||||
(homeBatteryCircumference ||
|
homeSolarCircumference! -
|
||||||
0)} ${homeHighCarbonCircumference !== undefined
|
(homeBatteryCircumference || 0)
|
||||||
? CIRCLE_CIRCUMFERENCE - homeHighCarbonCircumference
|
} ${
|
||||||
: homeSolarCircumference! +
|
homeHighCarbonCircumference !== undefined
|
||||||
(homeBatteryCircumference || 0)}"
|
? CIRCLE_CIRCUMFERENCE - homeHighCarbonCircumference
|
||||||
|
: homeSolarCircumference! +
|
||||||
|
(homeBatteryCircumference || 0)
|
||||||
|
}"
|
||||||
stroke-dashoffset="0"
|
stroke-dashoffset="0"
|
||||||
shape-rendering="geometricPrecision"
|
shape-rendering="geometricPrecision"
|
||||||
/>
|
/>`
|
||||||
|
: nothing}
|
||||||
</svg>`
|
</svg>`
|
||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
@ -619,15 +631,19 @@ class HuiEnergyDistrubutionCard
|
|||||||
d="M55,100 v-15 c0,-35 10,-30 30,-30 h20"
|
d="M55,100 v-15 c0,-35 10,-30 30,-30 h20"
|
||||||
vector-effect="non-scaling-stroke"
|
vector-effect="non-scaling-stroke"
|
||||||
></path>
|
></path>
|
||||||
<path
|
${
|
||||||
id="battery-grid"
|
hasGrid
|
||||||
class=${classMap({
|
? svg`<path
|
||||||
"battery-from-grid": Boolean(batteryFromGrid),
|
id="battery-grid"
|
||||||
"battery-to-grid": Boolean(batteryToGrid),
|
class=${classMap({
|
||||||
})}
|
"battery-from-grid": Boolean(batteryFromGrid),
|
||||||
d="M45,100 v-15 c0,-35 -10,-30 -30,-30 h-20"
|
"battery-to-grid": Boolean(batteryToGrid),
|
||||||
vector-effect="non-scaling-stroke"
|
})}
|
||||||
></path>
|
d="M45,100 v-15 c0,-35 -10,-30 -30,-30 h-20"
|
||||||
|
vector-effect="non-scaling-stroke"
|
||||||
|
></path>`
|
||||||
|
: nothing
|
||||||
|
}
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
${hasBattery && hasSolarProduction
|
${hasBattery && hasSolarProduction
|
||||||
@ -638,12 +654,14 @@ class HuiEnergyDistrubutionCard
|
|||||||
vector-effect="non-scaling-stroke"
|
vector-effect="non-scaling-stroke"
|
||||||
></path>`
|
></path>`
|
||||||
: ""}
|
: ""}
|
||||||
<path
|
${hasGrid
|
||||||
class="grid"
|
? svg`<path
|
||||||
id="grid"
|
class="grid"
|
||||||
d="M0,${hasBattery ? 50 : hasSolarProduction ? 56 : 53} H100"
|
id="grid"
|
||||||
vector-effect="non-scaling-stroke"
|
d="M0,${hasBattery ? 50 : hasSolarProduction ? 56 : 53} H100"
|
||||||
></path>
|
vector-effect="non-scaling-stroke"
|
||||||
|
></path>`
|
||||||
|
: nothing}
|
||||||
${solarToGrid && this._animate
|
${solarToGrid && this._animate
|
||||||
? svg`<circle
|
? svg`<circle
|
||||||
r="1"
|
r="1"
|
||||||
@ -839,6 +857,10 @@ class HuiEnergyDistrubutionCard
|
|||||||
.spacer {
|
.spacer {
|
||||||
width: 84px;
|
width: 84px;
|
||||||
}
|
}
|
||||||
|
.grid-spacer {
|
||||||
|
width: 84px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
.circle {
|
.circle {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user