Improve heating UI (#11837)

This commit is contained in:
Michael Geers 2024-01-24 10:48:05 +01:00 • committed by GitHub
parent 61039b8db9
commit 19ea3fb60c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 114 additions and 5 deletions

View file

@ -35,16 +35,18 @@ export default {
heating: Boolean,
},
emits: ["limit-soc-updated"],
computed: {
options: function () {
const result = [];
for (let soc = 20; soc <= 100; soc += 5) {
for (let soc = 20; soc <= 100; soc += this.step) {
let text = this.fmtSocOption(soc, this.rangePerSoc, distanceUnit(), this.heating);
result.push({ soc, text });
}
return result;
},
step: function () {
return this.heating ? 1 : 5;
},
title: function () {
return this.heating
? this.$t("main.vehicle.tempLimit")

View file

@ -21,6 +21,7 @@
:label="vehicleSocTitle"
:value="formattedSoc"
:extraValue="range ? `${fmtNumber(range, 0)} ${rangeUnit}` : null"
data-testid="current-soc"
align="start"
/>
<LabelAndValue
@ -29,6 +30,7 @@
:label="$t('main.loadpoint.charged')"
:value="fmtEnergy(chargedEnergy)"
:extraValue="chargedSoc"
data-testid="current-energy"
align="start"
/>
<ChargingPlan

View file

@ -59,7 +59,7 @@
type="range"
min="0"
max="100"
step="5"
:step="step"
:value="visibleLimitSoc"
class="slider"
:class="{ 'slider--active': sliderActive }"
@ -85,6 +85,7 @@ export default {
vehicleTargetSoc: Number,
enabled: Boolean,
charging: Boolean,
heating: Boolean,
minSoc: Number,
effectivePlanSoc: Number,
effectiveLimitSoc: Number,
@ -105,6 +106,9 @@ export default {
};
},
computed: {
step: function () {
return this.heating ? 1 : 5;
},
vehicleSocDisplayWidth: function () {
if (this.socBasedCharging) {
if (this.vehicleSoc >= 0) {

View file

@ -3,6 +3,7 @@
</template>
<script>
import { DEFAULT_LOCALE } from "../i18n";
import formatter from "../mixins/formatter";
import { CO2_TYPE } from "../units";
@ -16,6 +17,7 @@ export default {
enabled: Boolean,
connected: Boolean,
charging: Boolean,
heating: Boolean,
effectivePlanTime: String,
planProjectedStart: String,
planActive: Boolean,
@ -51,6 +53,13 @@ export default {
},
message: function () {
const t = (key, data) => {
if (this.heating) {
// check for special heating status translation
const name = `main.heatingStatus.${key}`;
if (this.$te(name, DEFAULT_LOCALE)) {
return this.$t(name, data);
}
}
return this.$t(`main.vehicleStatus.${key}`, data);
};

View file

@ -34,6 +34,8 @@ export const LOCALES = {
"zh-Hans": ["Chinese (Simplified)", "简体中文"],
};
export const DEFAULT_LOCALE = "en";
function getBrowserLocale() {
const navigatorLocale =
navigator.languages !== undefined ? navigator.languages[0] : navigator.language;
@ -72,8 +74,8 @@ export default function setupI18n() {
legacy: true,
silentFallbackWarn: true,
silentTranslationWarn: true,
locale: "en",
fallbackLocale: "en",
locale: DEFAULT_LOCALE,
fallbackLocale: DEFAULT_LOCALE,
messages: { en },
});
setI18nLanguage(i18n.global, getLocale());

View file

@ -191,6 +191,12 @@ pvExport = "Einspeisung"
pvProduction = "Erzeugung"
selfConsumption = "Eigenverbrauch"
[main.heatingStatus]
charging = "Heize …"
cheapEnergyCharging = "Heize mit günstiger Energie: {price} (Grenze {limit})"
cleanEnergyCharging = "Heize mit sauberer Energie: {co2} (Grenze {limit})"
waitForVehicle = "Bereit. Warte auf Heizung …"
[main.loadpoint]
avgPrice = "⌀ Preis"
charged = "Geladen"

View file

@ -188,6 +188,12 @@ pvExport = "Grid export"
pvProduction = "Production"
selfConsumption = "Self-consumption"
[main.heatingStatus]
charging = "Heating…"
cheapEnergyCharging = "Heating with cheap energy: {price} (limit {limit})"
cleanEnergyCharging = "Heating with clean energy: {co2} (limit {limit})"
waitForVehicle = "Ready. Waiting for heater…"
[main.loadpoint]
avgPrice = "⌀ Price"
charged = "Charged"

51
tests/heating.evcc.yaml Normal file
View file

@ -0,0 +1,51 @@
interval: 10s
site:
title: Hello World
meters:
grid: grid
meters:
- name: grid
type: custom
power:
source: js
script: |
1000
- name: charger_meter
type: custom
power:
source: js
script: |
500
loadpoints:
- title: Water Heater
charger: charger
meter: charger_meter
mode: now
chargers:
- name: charger
icon: waterheater
type: custom
enable:
source: js
script:
enabled:
source: js
script: |
true
status:
source: js
script: |
"C"
maxcurrent:
source: js
script: |
16
soc:
source: js
script: |
55
features: [integrateddevice, heating]

27
tests/heating.spec.js Normal file
View file

@ -0,0 +1,27 @@
const { test, expect } = require("@playwright/test");
const { start, stop } = require("./evcc");
test.beforeAll(async () => {
await start("heating.evcc.yaml");
});
test.afterAll(async () => {
await stop();
});
test.beforeEach(async ({ page }) => {
await page.goto("/");
});
test.describe("loadpoint", async () => {
test("initial values", async ({ page }) => {
await expect(page.getByTestId("current-soc")).toContainText("55.0°C");
await expect(page.getByTestId("limit-soc")).toContainText("100.0°C");
});
test("change limit in 1° steps", async ({ page }) => {
await page.getByTestId("limit-soc").getByRole("combobox").selectOption("69.0°C");
await expect(page.getByTestId("limit-soc")).toContainText("69.0°C");
page.reload();
await expect(page.getByTestId("limit-soc")).toContainText("69.0°C");
});
});