Add PV tooltip (#6226)
This commit is contained in:
parent
93c7c6a1fd
commit
8d18248185
5 changed files with 109 additions and 65 deletions
|
|
@ -14,6 +14,7 @@ import Energyflow from "./Energyflow.vue";
|
|||
:loadpointsPower="4200"
|
||||
:activeLoadpointsCount="3"
|
||||
siteTitle="Home"
|
||||
:pv="[{ power: 5000 }, { power: 2300 }]"
|
||||
/>
|
||||
</Variant>
|
||||
<Variant title="battery and grid">
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
:pvProduction="pvProduction"
|
||||
:homePower="homePower"
|
||||
:batterySoc="batterySoc"
|
||||
:valuesInKw="valuesInKw"
|
||||
:powerInKw="powerInKw"
|
||||
:vehicleIcons="vehicleIcons"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -56,26 +56,28 @@
|
|||
:name="$t('main.energyflow.pvProduction')"
|
||||
icon="sun"
|
||||
:power="pvProduction"
|
||||
:valuesInKw="valuesInKw"
|
||||
:powerTooltip="pvTooltip"
|
||||
:powerInKw="powerInKw"
|
||||
/>
|
||||
<EnergyflowEntry
|
||||
v-if="batteryConfigured"
|
||||
:name="$t('main.energyflow.batteryDischarge')"
|
||||
icon="battery"
|
||||
:soc="batterySoc"
|
||||
:power="batteryDischarge"
|
||||
:valuesInKw="valuesInKw"
|
||||
:tooltip="batteryTooltip"
|
||||
:powerInKw="powerInKw"
|
||||
:soc="batterySoc"
|
||||
:details="batterySoc"
|
||||
:detailsFmt="batteryFmt"
|
||||
:detailsTooltip="batteryTooltip"
|
||||
/>
|
||||
<EnergyflowEntry
|
||||
:name="$t('main.energyflow.gridImport')"
|
||||
icon="powersupply"
|
||||
:power="gridImport"
|
||||
:valuesInKw="valuesInKw"
|
||||
:price="tariffGrid"
|
||||
:currency="currency"
|
||||
:co2="tariffCo2"
|
||||
:tooltip="detailsTooltip(tariffGrid, tariffCo2)"
|
||||
:powerInKw="powerInKw"
|
||||
:details="detailsValue(tariffGrid, tariffCo2)"
|
||||
:detailsFmt="detailsFmt"
|
||||
:detailsTooltip="detailsTooltip(tariffGrid, tariffCo2)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -93,11 +95,12 @@
|
|||
:name="$t('main.energyflow.homePower')"
|
||||
icon="home"
|
||||
:power="homePower"
|
||||
:valuesInKw="valuesInKw"
|
||||
:price="tariffEffectivePrice"
|
||||
:currency="currency"
|
||||
:co2="tariffEffectiveCo2"
|
||||
:tooltip="detailsTooltip(tariffEffectivePrice, tariffEffectiveCo2)"
|
||||
:powerInKw="powerInKw"
|
||||
:details="detailsValue(tariffEffectivePrice, tariffEffectiveCo2)"
|
||||
:detailsFmt="detailsFmt"
|
||||
:detailsTooltip="
|
||||
detailsTooltip(tariffEffectivePrice, tariffEffectiveCo2)
|
||||
"
|
||||
/>
|
||||
<EnergyflowEntry
|
||||
:name="
|
||||
|
|
@ -108,29 +111,32 @@
|
|||
icon="vehicle"
|
||||
:vehicleIcons="vehicleIcons"
|
||||
:power="loadpointsPower"
|
||||
:valuesInKw="valuesInKw"
|
||||
:price="tariffEffectivePrice"
|
||||
:currency="currency"
|
||||
:co2="tariffEffectiveCo2"
|
||||
:tooltip="detailsTooltip(tariffEffectivePrice, tariffEffectiveCo2)"
|
||||
:powerInKw="powerInKw"
|
||||
:details="detailsValue(tariffEffectivePrice, tariffEffectiveCo2)"
|
||||
:detailsFmt="detailsFmt"
|
||||
:detailsTooltip="
|
||||
detailsTooltip(tariffEffectivePrice, tariffEffectiveCo2)
|
||||
"
|
||||
/>
|
||||
<EnergyflowEntry
|
||||
v-if="batteryConfigured"
|
||||
:name="$t('main.energyflow.batteryCharge')"
|
||||
icon="battery"
|
||||
:soc="batterySoc"
|
||||
:power="batteryCharge"
|
||||
:valuesInKw="valuesInKw"
|
||||
:tooltip="batteryTooltip"
|
||||
:powerInKw="powerInKw"
|
||||
:soc="batterySoc"
|
||||
:details="batterySoc"
|
||||
:detailsFmt="batteryFmt"
|
||||
:detailsTooltip="batteryTooltip"
|
||||
/>
|
||||
<EnergyflowEntry
|
||||
:name="$t('main.energyflow.pvExport')"
|
||||
icon="powersupply"
|
||||
:power="pvExport"
|
||||
:valuesInKw="valuesInKw"
|
||||
:price="-tariffFeedIn"
|
||||
:currency="currency"
|
||||
:tooltip="detailsTooltip(-tariffFeedIn)"
|
||||
:powerInKw="powerInKw"
|
||||
:details="detailsValue(-tariffFeedIn)"
|
||||
:detailsFmt="detailsFmt"
|
||||
:detailsTooltip="detailsTooltip(-tariffFeedIn)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -146,6 +152,7 @@ import EnergyflowEntry from "./EnergyflowEntry.vue";
|
|||
import formatter from "../../mixins/formatter";
|
||||
import AnimatedNumber from "../AnimatedNumber.vue";
|
||||
import settings from "../../settings";
|
||||
import { showGridPrice, showGridCo2 } from "../../gridDetails";
|
||||
|
||||
export default {
|
||||
name: "Energyflow",
|
||||
|
|
@ -156,6 +163,7 @@ export default {
|
|||
gridPower: { type: Number, default: 0 },
|
||||
homePower: { type: Number, default: 0 },
|
||||
pvConfigured: Boolean,
|
||||
pv: { type: Array },
|
||||
pvPower: { type: Number, default: 0 },
|
||||
loadpointsPower: { type: Number, default: 0 },
|
||||
activeLoadpointsCount: { type: Number, default: 0 },
|
||||
|
|
@ -199,7 +207,7 @@ export default {
|
|||
pvExport: function () {
|
||||
return Math.max(0, this.gridPower * -1);
|
||||
},
|
||||
valuesInKw: function () {
|
||||
powerInKw: function () {
|
||||
return this.gridImport + this.selfConsumption + this.pvExport > 1000;
|
||||
},
|
||||
inPower: function () {
|
||||
|
|
@ -211,6 +219,12 @@ export default {
|
|||
detailsHeight: function () {
|
||||
return this.detailsOpen ? this.detailsCompleteHeight + "px" : 0;
|
||||
},
|
||||
pvTooltip() {
|
||||
if (!Array.isArray(this.pv) || this.pv.length <= 1) {
|
||||
return;
|
||||
}
|
||||
return this.pv.map(({ power }) => this.fmtKw(power, this.powerInKw));
|
||||
},
|
||||
batteryTooltip() {
|
||||
if (!Array.isArray(this.battery)) {
|
||||
return;
|
||||
|
|
@ -221,6 +235,9 @@ export default {
|
|||
return this.$t("main.energyflow.batteryTooltip", { energy, total, soc });
|
||||
});
|
||||
},
|
||||
batteryFmt() {
|
||||
return (soc) => `${Math.round(soc)}%`;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener("resize", this.updateHeight);
|
||||
|
|
@ -243,8 +260,22 @@ export default {
|
|||
}
|
||||
return result;
|
||||
},
|
||||
detailsValue(price, co2) {
|
||||
if (showGridPrice() && !isNaN(price)) {
|
||||
return price;
|
||||
}
|
||||
if (showGridCo2() && !isNaN(co2)) {
|
||||
return co2;
|
||||
}
|
||||
},
|
||||
detailsFmt(value) {
|
||||
if (showGridPrice()) {
|
||||
return this.fmtPricePerKWh(value, this.currency, true);
|
||||
}
|
||||
return this.fmtCo2Short(value);
|
||||
},
|
||||
kw: function (watt) {
|
||||
return this.fmtKw(watt, this.valuesInKw);
|
||||
return this.fmtKw(watt, this.powerInKw);
|
||||
},
|
||||
toggleDetails: function () {
|
||||
this.updateHeight();
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@
|
|||
</span>
|
||||
<span class="text-end text-nowrap ps-1 fw-bold d-flex">
|
||||
<div ref="details" class="fw-normal" data-bs-toggle="tooltip" title=" " @click.stop="">
|
||||
<span v-if="showPrice()"><AnimatedNumber :to="price" :format="fmtPrice" /></span>
|
||||
<span v-if="showCo2()"><AnimatedNumber :to="co2" :format="fmtCo2Short" /></span>
|
||||
<span v-if="hasSoc">{{ soc }}%</span>
|
||||
<AnimatedNumber v-if="details !== undefined" :to="details" :format="detailsFmt" />
|
||||
</div>
|
||||
<div ref="power" class="power" data-bs-toggle="tooltip" title=" " @click.stop="">
|
||||
<AnimatedNumber :to="power" :format="kw" />
|
||||
</div>
|
||||
<AnimatedNumber :to="power" :format="kw" class="power" />
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -28,7 +28,6 @@ import BatteryIcon from "./BatteryIcon.vue";
|
|||
import formatter from "../../mixins/formatter";
|
||||
import AnimatedNumber from "../AnimatedNumber.vue";
|
||||
import VehicleIcon from "../VehicleIcon";
|
||||
import { showGridPrice, showGridCo2 } from "../../gridDetails";
|
||||
|
||||
export default {
|
||||
name: "EnergyflowEntry",
|
||||
|
|
@ -37,17 +36,17 @@ export default {
|
|||
props: {
|
||||
name: { type: String },
|
||||
icon: { type: String },
|
||||
power: { type: Number },
|
||||
soc: { type: Number },
|
||||
price: { type: Number },
|
||||
co2: { type: Number },
|
||||
valuesInKw: { type: Boolean },
|
||||
vehicleIcons: { type: Array },
|
||||
currency: { type: String },
|
||||
tooltip: { type: Array },
|
||||
power: { type: Number },
|
||||
powerTooltip: { type: Array },
|
||||
powerInKw: { type: Boolean },
|
||||
soc: { type: Number },
|
||||
details: { type: Number },
|
||||
detailsFmt: { type: Function },
|
||||
detailsTooltip: { type: Array },
|
||||
},
|
||||
data() {
|
||||
return { tooltipInstance: null };
|
||||
return { powerTooltipInstance: null, detailsTooltipInstance: null };
|
||||
},
|
||||
computed: {
|
||||
active: function () {
|
||||
|
|
@ -59,42 +58,54 @@ export default {
|
|||
isVehicle: function () {
|
||||
return this.icon === "vehicle";
|
||||
},
|
||||
hasSoc: function () {
|
||||
return this.isBattery && !isNaN(this.soc);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
tooltip(newVal, oldVal) {
|
||||
powerTooltip(newVal, oldVal) {
|
||||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||||
this.updateTooltip();
|
||||
this.updatePowerTooltip();
|
||||
}
|
||||
},
|
||||
detailsTooltip(newVal, oldVal) {
|
||||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||||
this.updateDetailsTooltip();
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted: function () {
|
||||
this.updateTooltip();
|
||||
this.updatePowerTooltip();
|
||||
this.updateDetailsTooltip();
|
||||
},
|
||||
methods: {
|
||||
showPrice() {
|
||||
return showGridPrice() && !isNaN(this.price);
|
||||
},
|
||||
showCo2() {
|
||||
return showGridCo2() && !isNaN(this.co2);
|
||||
},
|
||||
kw: function (watt) {
|
||||
return this.fmtKw(watt, this.valuesInKw);
|
||||
return this.fmtKw(watt, this.powerInKw);
|
||||
},
|
||||
fmtPrice: function (price) {
|
||||
return this.fmtPricePerKWh(price, this.currency, true);
|
||||
updatePowerTooltip() {
|
||||
this.powerTooltipInstance = this.updateTooltip(
|
||||
this.powerTooltipInstance,
|
||||
this.powerTooltip,
|
||||
this.$refs.power
|
||||
);
|
||||
},
|
||||
updateTooltip: function () {
|
||||
if (!Array.isArray(this.tooltip) || !this.tooltip.length) {
|
||||
updateDetailsTooltip() {
|
||||
this.detailsTooltipInstance = this.updateTooltip(
|
||||
this.detailsTooltipInstance,
|
||||
this.detailsTooltip,
|
||||
this.$refs.details
|
||||
);
|
||||
},
|
||||
updateTooltip: function (instance, content, ref) {
|
||||
if (!Array.isArray(content) || !content.length) {
|
||||
if (instance) {
|
||||
instance.dispose();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!this.tooltipInstance) {
|
||||
this.tooltipInstance = new Tooltip(this.$refs.details, { html: true });
|
||||
if (!instance) {
|
||||
instance = new Tooltip(ref, { html: true });
|
||||
}
|
||||
const html = `<div class="text-end">${this.tooltip.join("<br/>")}</div>`;
|
||||
this.tooltipInstance.setContent({ ".tooltip-inner": html });
|
||||
const html = `<div class="text-end">${content.join("<br/>")}</div>`;
|
||||
instance.setContent({ ".tooltip-inner": html });
|
||||
return instance;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ export default {
|
|||
pvProduction: { type: Number, default: 0 },
|
||||
homePower: { type: Number, default: 0 },
|
||||
batterySoc: { type: Number, default: 0 },
|
||||
valuesInKw: { type: Boolean, default: false },
|
||||
powerInKw: { type: Boolean, default: false },
|
||||
vehicleIcons: { type: Array },
|
||||
},
|
||||
data: function () {
|
||||
|
|
@ -148,7 +148,7 @@ export default {
|
|||
},
|
||||
fmtBarValue: function (watt) {
|
||||
const valueInKw = this.powerLabelEnoughSpace(watt);
|
||||
return this.fmtKw(watt, this.valuesInKw, valueInKw);
|
||||
return this.fmtKw(watt, this.powerInKw, valueInKw);
|
||||
},
|
||||
powerLabelAvailableSpace(power) {
|
||||
if (this.totalAdjusted === 0) return 0;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ export default {
|
|||
homePower: Number,
|
||||
pvConfigured: Boolean,
|
||||
pvPower: Number,
|
||||
pv: Array,
|
||||
batteryConfigured: Boolean,
|
||||
batteryPower: Number,
|
||||
batterySoc: Number,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue