Config UI: keep broken loadpoints editable (#19263)

This commit is contained in:
Michael Geers 2025-03-12 19:54:48 +01:00 • committed by GitHub
parent 19e122be7a
commit 695143f272
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 72 additions and 48 deletions

View file

@ -15,6 +15,7 @@
<div class="w-100">
<slot />
</div>
<div v-if="error" class="invalid-feedback d-block">{{ error }}</div>
<div class="form-text evcc-gray">
<div v-if="example" class="hyphenate">
{{ $t("config.form.example") }}: {{ example }}
@ -42,6 +43,7 @@ export default {
help: String,
optional: Boolean,
deprecated: Boolean,
error: String,
example: String,
docsLink: String,
},

View file

@ -23,9 +23,10 @@
/>
</FormRow>
<FormRow
v-if="values.charger"
v-if="charger || !isNew"
id="loadpointParamCharger"
:label="$t('config.loadpoint.chargerLabel')"
:error="!charger ? $t('config.loadpoint.chargerError') : null"
>
<div class="d-flex">
<PropertyField
@ -35,6 +36,7 @@
class="me-2 flex-grow-1"
readonly
required
:invalid="!charger"
@click.prevent="editCharger"
/>
<button
@ -56,7 +58,7 @@
{{ $t("config.loadpoint.addCharger") }}
</button>
</div>
<div v-if="values.charger || !isNew">
<div v-if="charger || !isNew">
<FormRow
v-if="values.meter"
id="loadpointParamMeter"
@ -97,7 +99,7 @@
</p>
</div>
<div v-if="values.charger">
<div v-if="values.charger || !isNew">
<h6>{{ $t("config.loadpoint.chargingTitle") }}</h6>
<FormRow

View file

@ -1,5 +1,5 @@
<template>
<div v-if="unitValue" class="input-group" :class="sizeClass">
<div v-if="unitValue" class="input-group" :class="inputClasses">
<input
:id="id"
v-model="value"
@ -55,7 +55,7 @@
{ value: true, name: $t('config.options.boolean.yes') },
]"
/>
<select v-else-if="select" :id="id" v-model="value" class="form-select" :class="sizeClass">
<select v-else-if="select" :id="id" v-model="value" class="form-select" :class="inputClasses">
<option v-if="!required" value="">---</option>
<template v-for="({ key, name }, idx) in selectOptions">
<option v-if="key !== null && name !== null" :key="key" :value="key">
@ -69,7 +69,7 @@
:id="id"
v-model="value"
class="form-control"
:class="sizeClass"
:class="inputClasses"
:type="inputType"
:placeholder="placeholder"
:required="required"
@ -80,7 +80,7 @@
:id="id"
v-model="value"
class="form-control"
:class="sizeClass"
:class="inputClasses"
:type="inputType"
:step="step"
:placeholder="placeholder"
@ -111,6 +111,7 @@ export default {
size: String,
scale: Number,
required: Boolean,
invalid: Boolean,
choice: { type: Array, default: () => [] },
modelValue: [String, Number, Boolean, Object],
},
@ -137,6 +138,13 @@ export default {
}
return "";
},
inputClasses() {
let result = this.sizeClass;
if (this.invalid) {
result += " is-invalid";
}
return result;
},
endAlign() {
return ["Int", "Float", "Duration"].includes(this.type);
},

View file

@ -58,7 +58,7 @@
{{ $t("offline.configurationError") }}
</strong>
</div>
<div v-if="fatal" class="text-break">{{ fatal.error }}</div>
<div v-if="fatalText" class="text-break">{{ fatalText }}</div>
</div>
<button
type="button"
@ -110,6 +110,11 @@ export default {
!this.dismissed
);
},
fatalText() {
const { error, class: errorClass } = this.fatal || {};
if (!error) return;
return errorClass ? `${errorClass}: ${error}` : error;
},
},
watch: {
offline: function () {

View file

@ -1028,16 +1028,20 @@ func configureLoadpoints(conf globalconfig.All) error {
instance, err := core.NewLoadpointFromConfig(log, settings, static)
if err != nil {
return &DeviceError{cc.Name, err}
err = &DeviceError{cc.Name, err}
}
dev := config.NewConfigurableDevice[loadpoint.API](&conf, instance)
if err := config.Loadpoints().Add(dev); err != nil {
return &DeviceError{cc.Name, err}
if e := config.Loadpoints().Add(dev); e != nil && err == nil {
err = &DeviceError{cc.Name, e}
}
if err := dynamic.Apply(instance); err != nil {
return &DeviceError{cc.Name, err}
if e := dynamic.Apply(instance); e != nil && err == nil {
err = &DeviceError{cc.Name, e}
}
if err != nil {
return err
}
}

View file

@ -188,41 +188,6 @@ func NewLoadpointFromConfig(log *util.Logger, settings settings.Settings, other
lp.Soc.Poll.Mode = loadpoint.PollCharging
}
if lp.CircuitRef != "" {
dev, err := config.Circuits().ByName(lp.CircuitRef)
if err != nil {
return nil, fmt.Errorf("circuit: %w", err)
}
lp.circuit = dev.Instance()
}
if lp.MeterRef != "" {
dev, err := config.Meters().ByName(lp.MeterRef)
if err != nil {
return nil, fmt.Errorf("meter: %w", err)
}
lp.chargeMeter = dev.Instance()
}
// default vehicle
if lp.VehicleRef != "" {
dev, err := config.Vehicles().ByName(lp.VehicleRef)
if err != nil {
return nil, fmt.Errorf("vehicle: %w", err)
}
lp.defaultVehicle = dev.Instance()
}
if lp.ChargerRef == "" {
return nil, errors.New("missing charger")
}
dev, err := config.Chargers().ByName(lp.ChargerRef)
if err != nil {
return nil, fmt.Errorf("charger: %w", err)
}
lp.charger = dev.Instance()
lp.configureChargerType(lp.charger)
// phase switching defaults based on charger capabilities
if !lp.hasPhaseSwitching() {
lp.phasesConfigured = 3
@ -249,6 +214,42 @@ func NewLoadpointFromConfig(log *util.Logger, settings settings.Settings, other
lp.setPriority(lp.Priority)
}
if lp.CircuitRef != "" {
dev, err := config.Circuits().ByName(lp.CircuitRef)
if err != nil {
return lp, fmt.Errorf("circuit: %w", err)
}
lp.circuit = dev.Instance()
}
if lp.MeterRef != "" {
dev, err := config.Meters().ByName(lp.MeterRef)
if err != nil {
return lp, fmt.Errorf("meter: %w", err)
}
lp.chargeMeter = dev.Instance()
}
// default vehicle
if lp.VehicleRef != "" {
dev, err := config.Vehicles().ByName(lp.VehicleRef)
if err != nil {
return lp, fmt.Errorf("default vehicle: %w", err)
}
lp.defaultVehicle = dev.Instance()
}
if lp.ChargerRef == "" {
return lp, errors.New("missing charger")
}
dev, err := config.Chargers().ByName(lp.ChargerRef)
if err != nil {
return lp, fmt.Errorf("charger: %w", err)
}
lp.charger = dev.Instance()
lp.configureChargerType(lp.charger)
return lp, nil
}

View file

@ -156,6 +156,7 @@ v2Support = "Zurück zu InfluxDB 2.x"
addCharger = "Wallbox hinzufügen"
addMeter = "Zusätzlichen Zähler hinzufügen"
cancel = "Abbrechen"
chargerError = "Wallbox muss konfiguriert sein."
chargerLabel = "Wallbox"
chargerPower11kw = "11 kW"
chargerPower11kwHelp = "Verwendet einen Strombereich von 6 bis 16 A."

View file

@ -156,6 +156,7 @@ v2Support = "Back to InfluxDB 2.x"
addCharger = "Add charger"
addMeter = "Add dedicated charger meter"
cancel = "Cancel"
chargerError = "Configuring a charger is required."
chargerLabel = "Charger"
chargerPower11kw = "11 kW"
chargerPower11kwHelp = "Will use a current range of 6 to 16 A."