UI: battery hold and grid charge icons (#16650)

This commit is contained in:
Michael Geers 2024-10-16 14:31:26 +02:00 • committed by GitHub
parent a0b40c1d63
commit 971ff9a580
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 62 additions and 16 deletions

View file

@ -362,7 +362,7 @@ export default {
}
return this.battery
.filter(({ capacity }) => capacity > 0)
.map(({ soc, capacity }) => {
.map(({ soc = 0, capacity }) => {
const multipleBatteries = this.battery.length > 1;
const energy = this.fmtWh(
(capacity / 100) * soc * 1e3,

View file

@ -4,10 +4,17 @@ import BatteryIcon from "./BatteryIcon.vue";
<template>
<Story :layout="{ type: 'grid', width: 150 }">
<Variant title="empty"> <BatteryIcon :soc="10" /> </Variant>
<Variant title="quarter"> <BatteryIcon :soc="30" /> </Variant>
<Variant title="half"> <BatteryIcon :soc="50" /> </Variant>
<Variant title="three quarter"> <BatteryIcon :soc="70" /> </Variant>
<Variant title="full"> <BatteryIcon :soc="90" /> </Variant>
<Variant title="0%"> <BatteryIcon :soc="0" /> </Variant>
<Variant title="10%"> <BatteryIcon :soc="10" /> </Variant>
<Variant title="20%"> <BatteryIcon :soc="20" /> </Variant>
<Variant title="30%"> <BatteryIcon :soc="30" /> </Variant>
<Variant title="40%"> <BatteryIcon :soc="40" /> </Variant>
<Variant title="50%"> <BatteryIcon :soc="50" /> </Variant>
<Variant title="60%"> <BatteryIcon :soc="60" /> </Variant>
<Variant title="70%"> <BatteryIcon :soc="70" /> </Variant>
<Variant title="80%"> <BatteryIcon :soc="80" /> </Variant>
<Variant title="90%"> <BatteryIcon :soc="90" /> </Variant>
<Variant title="hold"> <BatteryIcon hold /> </Variant>
<Variant title="grid charge"> <BatteryIcon grid-charge /> </Variant>
</Story>
</template>

View file

@ -5,7 +5,17 @@
fill="currentColor"
d="M35 9.996h-3v-4a2 2 0 00-2-2H18a2 2 0 00-2 2v4h-3a2 2 0 00-2 2v30a2 2 0 002 2h22a2 2 0 002-2v-30a2 2 0 00-2-2zm-15-2h8v2h-8v-2zm13 32H15v-26h18v26z"
/>
<path fill="currentColor" :d="socRect" />
<path
v-if="gridCharge"
fill="currentColor"
d="M21.956,26.739l0,8.261l4.088,0l0,-8.261l3.066,3.033l2.89,-2.859l-8,-7.913l-8,7.913l2.89,2.859l3.066,-3.033Z"
/>
<path
v-else-if="hold"
fill="currentColor"
d="M21.943,22.053l0,9.943l-3,0l0,-9.943l3,-0Zm7,-0l0,9.943l-3,-0l0,-9.943l3,-0Z"
/>
<path v-else fill="currentColor" :d="socRect" />
</svg>
</template>
@ -16,6 +26,8 @@ export default {
name: "BatteryIcon",
props: {
soc: { type: Number, default: 0 },
hold: { type: Boolean, default: false },
gridCharge: { type: Boolean, default: false },
},
computed: {
socRect() {

View file

@ -15,6 +15,8 @@
:pvExport="pvExport"
:batteryCharge="batteryCharge"
:batteryDischarge="batteryDischarge"
:batteryGridCharge="batteryGridChargeActive"
:batteryHold="batteryHold"
:pvProduction="pvProduction"
:homePower="homePower"
:batterySoc="batterySoc"
@ -90,13 +92,19 @@
icon="battery"
:power="batteryDischarge"
:powerUnit="powerUnit"
:soc="batterySoc"
:iconProps="{
hold: batteryHold,
soc: batterySoc,
gridCharge: batteryGridChargeActive,
}"
:details="batterySoc"
:detailsFmt="batteryFmt"
detailsClickable
data-testid="energyflow-entry-batterydischarge"
@details-clicked="openBatterySettingsModal"
/>
>
<template v-if="batteryGridChargeActive" #subline> &nbsp; </template>
</EnergyflowEntry>
<EnergyflowEntry
:name="$t('main.energyflow.gridImport')"
icon="powersupply"
@ -137,7 +145,7 @@
})
"
icon="vehicle"
:vehicleIcons="vehicleIcons"
:iconProps="{ names: vehicleIcons }"
:power="loadpointsPower"
:powerUnit="powerUnit"
:details="
@ -157,7 +165,11 @@
icon="battery"
:power="batteryCharge"
:powerUnit="powerUnit"
:soc="batterySoc"
:iconProps="{
hold: batteryHold,
soc: batterySoc,
gridCharge: batteryGridChargeActive,
}"
:details="batterySoc"
:detailsFmt="batteryFmt"
detailsClickable

View file

@ -2,8 +2,8 @@
<div class="mb-2 entry" :class="{ 'evcc-gray': !active }">
<div class="d-flex justify-content-between">
<span class="d-flex flex-nowrap">
<BatteryIcon v-if="isBattery" :soc="soc" />
<VehicleIcon v-else-if="isVehicle" :names="vehicleIcons" />
<BatteryIcon v-if="isBattery" v-bind="iconProps" />
<VehicleIcon v-else-if="isVehicle" v-bind="iconProps" />
<component :is="`shopicon-regular-${icon}`" v-else></component>
</span>
<div class="d-block text-nowrap flex-grow-1 ms-3 text-truncate">
@ -49,11 +49,10 @@ export default {
props: {
name: { type: String },
icon: { type: String },
vehicleIcons: { type: Array },
iconProps: { type: Object, default: () => ({}) },
power: { type: Number },
powerTooltip: { type: Array },
powerUnit: { type: String },
soc: { type: Number },
details: { type: Number },
detailsFmt: { type: Function },
detailsTooltip: { type: Array },

View file

@ -91,7 +91,7 @@
<VehicleIcon :names="[lp.icon]" />
</LabelBar>
<LabelBar v-bind="labelBarProps('bottom', 'batteryCharge')">
<BatteryIcon :soc="batterySoc" />
<BatteryIcon :soc="batterySoc" :gridCharge="batteryGridCharge" />
</LabelBar>
<LabelBar v-bind="labelBarProps('bottom', 'gridExport')">
<shopicon-regular-powersupply></shopicon-regular-powersupply>
@ -102,6 +102,7 @@
</div>
<div class="label-scale-name">Out</div>
</div>
<BatteryIcon hold class="battery-hold" :class="{ 'battery-hold--active': batteryHold }" />
</div>
</template>
@ -127,6 +128,8 @@ export default {
loadpoints: { type: Array, default: () => [] },
batteryCharge: { type: Number, default: 0 },
batteryDischarge: { type: Number, default: 0 },
batteryHold: { type: Boolean, default: false },
batteryGridCharge: { type: Boolean, default: false },
pvProduction: { type: Number, default: 0 },
homePower: { type: Number, default: 0 },
batterySoc: { type: Number, default: 0 },
@ -303,4 +306,17 @@ html.dark .grid-import {
.visualization--ready :deep(.label-bar-icon) {
transition-duration: var(--evcc-transition-very-fast), 500ms;
}
.battery-hold {
position: absolute;
top: 2.5rem;
right: -0.25rem;
color: var(--evcc-gray);
opacity: 0;
transition-property: opacity;
transition-duration: var(--evcc-transition-medium);
transition-timing-function: linear;
}
.battery-hold--active {
opacity: 1;
}
</style>