From 1042b800c5755a953071fabb5afe496c97d05683 Mon Sep 17 00:00:00 2001 From: Michael Geers Date: Wed, 31 Jul 2024 11:43:25 +0200 Subject: [PATCH] Config UI: show circuit status (#15110) --- assets/js/components/Config/DeviceTags.vue | 24 +++++++---- .../Config/defaultYaml/circuits.yaml | 8 ++-- assets/js/views/Config.vue | 42 ++++++++++++++++++- i18n/de.toml | 2 + i18n/en.toml | 2 + 5 files changed, 66 insertions(+), 12 deletions(-) diff --git a/assets/js/components/Config/DeviceTags.vue b/assets/js/components/Config/DeviceTags.vue index 28dfe54ae6..1fc6f2acb0 100644 --- a/assets/js/components/Config/DeviceTags.vue +++ b/assets/js/components/Config/DeviceTags.vue @@ -11,7 +11,11 @@
{{ fmtDeviceValue(entry) }}
@@ -29,15 +33,14 @@ export default { mixins: [formatter], computed: { entries() { - return Object.entries(this.tags).map(([name, { value, error, options }]) => { - return { name, value, error, options }; - }); + return Object.entries(this.tags).map( + ([name, { value, error, warning, muted, options }]) => { + return { name, value, error, warning, muted, options }; + } + ); }, }, methods: { - hasError(entry) { - return !!entry.error; - }, fmtDeviceValue(entry) { const { name, value, options = {} } = entry; if (value === null || value === undefined) { @@ -71,6 +74,10 @@ export default { return this.fmtPricePerKWh(value, options.currency, true); case "co2": return this.fmtCo2Short(value); + case "powerRange": + return `${this.fmtKw(value[0])} / ${this.fmtKw(value[1])}`; + case "currentRange": + return `${this.fmtNumber(value[0], 1)} A / ${this.fmtNumber(value[1], 1)} A`; case "configured": return value ? this.$t("config.deviceValue.yes") @@ -101,6 +108,9 @@ export default { .value--error { color: var(--bs-danger); } +.value--warning { + color: var(--bs-warning); +} .value--muted { color: var(--evcc-gray) !important; } diff --git a/assets/js/components/Config/defaultYaml/circuits.yaml b/assets/js/components/Config/defaultYaml/circuits.yaml index 6cdbc02ca1..49fc696d4e 100644 --- a/assets/js/components/Config/defaultYaml/circuits.yaml +++ b/assets/js/components/Config/defaultYaml/circuits.yaml @@ -1,18 +1,18 @@ # - name: main # unique name, used as reference, e.g. as parent in other circuits # title: Main Circuit # used in the UI # maxcurrent: 63 # 63A main circuit breaker (optional) -# maxpower: 30000 # 30kW (optional) +# maxPower: 30000 # 30kW (optional) # meter: grid # associated meter to monitor the power consumption (optional) # parent: # no parent, this is the root circuit # - name: garage # unique name, used as reference, e.g. to associate loadpoints # title: Garage # used in the UI # maxcurrent: 24 # allow individual phase use up to 24A -# maxpower: 11000 # limit total power to 11kW +# maxPower: 11000 # limit total power to 11kW # meter: garage # dedicated meter for the garage # parent: main # parent to the main circuit # - name: carport # unique name, used as reference, e.g. to associate loadpoints # title: Carport # used in the UI -# maxcurrent: 32 # 32A circuit breaker -# maxpower: # no limit, only check current +# maxCurrent: 32 # 32A circuit breaker +# maxPower: # no limit, only check current # meter: # no meter, using data from loadpoints # parent: main # parent to the main circuit diff --git a/assets/js/views/Config.vue b/assets/js/views/Config.vue index c33d1b706f..779b008b16 100644 --- a/assets/js/views/Config.vue +++ b/assets/js/views/Config.vue @@ -220,7 +220,22 @@ > status < 500, @@ -615,6 +636,25 @@ export default { yamlTags(key) { return { configured: { value: this.yamlConfigState[key] } }; }, + circuitTags(circuit) { + const data = store.state?.circuits[circuit.name] || {}; + const result = {}; + if (data.maxPower) { + result.powerRange = { + value: [data.power || 0, data.maxPower], + warning: data.power >= data.maxPower, + }; + } else { + result.power = { value: data.power || 0, muted: true }; + } + if (data.maxCurrent) { + result.currentRange = { + value: [data.current || 0, data.maxCurrent], + warning: data.current >= data.maxCurrent, + }; + } + return result; + }, deviceError(type, name) { const fatal = store.state?.fatal || {}; return fatal.class === type && fatal.device === name; diff --git a/i18n/de.toml b/i18n/de.toml index 4cb1c7605c..257f6a79ba 100644 --- a/i18n/de.toml +++ b/i18n/de.toml @@ -55,6 +55,7 @@ co2 = "Netz-CO₂" configured = "Konfiguriert" currency = "Währung" current = "Strom" +currentRange = "Strom" enabled = "Aktiviert" energy = "Energie" feedinPrice = "Einspeisevergütung" @@ -66,6 +67,7 @@ phaseCurrents = "Strom L1..L3" phasePowers = "Leistung L1..L3" phaseVoltages = "Spannung L1..L3" power = "Leistung" +powerRange = "Leistung" range = "Reichweite" soc = "SoC" socLimit = "SoC Begrenzung" diff --git a/i18n/en.toml b/i18n/en.toml index 4efb262f57..9ebaaed554 100644 --- a/i18n/en.toml +++ b/i18n/en.toml @@ -55,6 +55,7 @@ co2 = "Grid CO₂" configured = "Configured" currency = "Currency" current = "Current" +currentRange = "Current" enabled = "Enabled" energy = "Energy" feedinPrice = "Feed-in price" @@ -66,6 +67,7 @@ phaseCurrents = "Current L1..L3" phasePowers = "Power L1..L3" phaseVoltages = "Voltage L1..L3" power = "Power" +powerRange = "Power" range = "Range" soc = "SoC" socLimit = "Limit"