Persist phases/min/max current (BC) (#11571)
This commit is contained in:
parent
91592bbd26
commit
648fe0cfdf
38 changed files with 216 additions and 271 deletions
|
|
@ -12,19 +12,11 @@
|
|||
{{ loadpointTitle }}
|
||||
</div>
|
||||
</h3>
|
||||
<LoadpointSettingsButton
|
||||
v-if="settingsButtonVisible"
|
||||
:id="id"
|
||||
class="d-block d-sm-none"
|
||||
/>
|
||||
<LoadpointSettingsButton :id="id" class="d-block d-sm-none" />
|
||||
</div>
|
||||
<div class="mb-3 d-flex align-items-center">
|
||||
<Mode class="flex-grow-1" :mode="mode" @updated="setTargetMode" />
|
||||
<LoadpointSettingsButton
|
||||
v-if="settingsButtonVisible"
|
||||
:id="id"
|
||||
class="d-none d-sm-block ms-2"
|
||||
/>
|
||||
<LoadpointSettingsButton :id="id" class="d-none d-sm-block ms-2" />
|
||||
</div>
|
||||
</div>
|
||||
<LoadpointSettingsModal
|
||||
|
|
@ -178,6 +170,7 @@ export default {
|
|||
phases: Number,
|
||||
phasesConfigured: Number,
|
||||
phasesActive: Number,
|
||||
phases1p3p: Boolean,
|
||||
minCurrent: Number,
|
||||
maxCurrent: Number,
|
||||
chargeCurrent: Number,
|
||||
|
|
@ -232,9 +225,6 @@ export default {
|
|||
settingsModal: function () {
|
||||
return this.collectProps(LoadpointSettingsModal);
|
||||
},
|
||||
settingsButtonVisible: function () {
|
||||
return this.$hiddenFeatures() || [0, 1, 3].includes(this.phasesConfigured);
|
||||
},
|
||||
vehicleProps: function () {
|
||||
return this.collectProps(Vehicle);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-outline-secondary position-relative border-0 p-2 evcc-gray"
|
||||
data-testid="loadpoint-settings-button"
|
||||
@click="openModal"
|
||||
>
|
||||
<shopicon-regular-adjust size="s"></shopicon-regular-adjust>
|
||||
|
|
|
|||
|
|
@ -23,14 +23,10 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="container">
|
||||
<h4
|
||||
v-if="showConfigurablePhases || showCurrentSettings"
|
||||
class="d-flex align-items-center mb-3 mt-4 text-evcc"
|
||||
>
|
||||
<h4 class="d-flex align-items-center mb-3 mt-4 text-evcc">
|
||||
{{ $t("main.loadpointSettings.currents") }}
|
||||
<shopicon-bold-lightning class="ms-1"></shopicon-bold-lightning>
|
||||
</h4>
|
||||
<div v-if="showConfigurablePhases" class="mb-3 row">
|
||||
<div class="mb-3 row">
|
||||
<label
|
||||
:for="formId('phases_0')"
|
||||
class="col-sm-4 col-form-label pt-0"
|
||||
|
|
@ -38,71 +34,37 @@
|
|||
{{ $t("main.loadpointSettings.phasesConfigured.label") }}
|
||||
</label>
|
||||
<div class="col-sm-8 pe-0">
|
||||
<div class="form-check">
|
||||
<div
|
||||
v-for="phases in phasesOptions"
|
||||
:key="phases"
|
||||
class="form-check"
|
||||
>
|
||||
<input
|
||||
:id="formId('phases_0')"
|
||||
:id="formId(`phases_${phases}`)"
|
||||
v-model.number="selectedPhases"
|
||||
class="form-check-input"
|
||||
type="radio"
|
||||
:name="formId('phases')"
|
||||
:value="0"
|
||||
:value="phases"
|
||||
@change="changePhasesConfigured"
|
||||
/>
|
||||
<label class="form-check-label" :for="formId('phases_0')">
|
||||
<label
|
||||
class="form-check-label"
|
||||
:for="formId(`phases_${phases}`)"
|
||||
>
|
||||
{{
|
||||
$t(
|
||||
"main.loadpointSettings.phasesConfigured.phases_0"
|
||||
`main.loadpointSettings.phasesConfigured.phases_${phases}`
|
||||
)
|
||||
}}
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input
|
||||
:id="formId('phases_1')"
|
||||
v-model.number="selectedPhases"
|
||||
class="form-check-input"
|
||||
type="radio"
|
||||
:name="formId('phases')"
|
||||
:value="1"
|
||||
@change="changePhasesConfigured"
|
||||
/>
|
||||
<label class="form-check-label" :for="formId('phases_1')">
|
||||
{{
|
||||
$t(
|
||||
"main.loadpointSettings.phasesConfigured.phases_1"
|
||||
)
|
||||
}}
|
||||
<small>
|
||||
<small v-if="phases > 0">
|
||||
{{
|
||||
$t(
|
||||
"main.loadpointSettings.phasesConfigured.phases_1_hint",
|
||||
{ min: minPower1p, max: maxPower1p }
|
||||
)
|
||||
}}
|
||||
</small>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input
|
||||
:id="formId('phases_3')"
|
||||
v-model.number="selectedPhases"
|
||||
class="form-check-input"
|
||||
type="radio"
|
||||
:name="formId('phases')"
|
||||
:value="3"
|
||||
@change="changePhasesConfigured"
|
||||
/>
|
||||
<label class="form-check-label" :for="formId('phases_3')">
|
||||
{{
|
||||
$t(
|
||||
"main.loadpointSettings.phasesConfigured.phases_3"
|
||||
)
|
||||
}}
|
||||
<small>
|
||||
{{
|
||||
$t(
|
||||
"main.loadpointSettings.phasesConfigured.phases_3_hint",
|
||||
{ min: minPower3p, max: maxPower3p }
|
||||
`main.loadpointSettings.phasesConfigured.phases_${phases}_hint`,
|
||||
{
|
||||
min: minPowerPhases(phases),
|
||||
max: maxPowerPhases(phases),
|
||||
}
|
||||
)
|
||||
}}
|
||||
</small>
|
||||
|
|
@ -111,7 +73,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="$hiddenFeatures()" class="mb-3 row">
|
||||
<div class="mb-3 row">
|
||||
<label
|
||||
:for="formId('maxcurrent')"
|
||||
class="col-sm-4 col-form-label pt-0 pt-sm-2"
|
||||
|
|
@ -137,7 +99,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="$hiddenFeatures()" class="mb-3 row">
|
||||
<div class="mb-3 row">
|
||||
<label
|
||||
:for="formId('mincurrent')"
|
||||
class="col-sm-4 col-form-label pt-0 pt-sm-2"
|
||||
|
|
@ -163,12 +125,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="small mt-3 text-muted mb-0">
|
||||
<strong class="text-evcc">
|
||||
{{ $t("main.loadpointSettings.disclaimerHint") }}
|
||||
</strong>
|
||||
{{ $t("main.loadpointSettings.disclaimerText") }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -177,8 +133,6 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import "@h2d2/shopicons/es/bold/lightning";
|
||||
import "@h2d2/shopicons/es/bold/car3";
|
||||
import formatter from "../mixins/formatter";
|
||||
|
||||
const V = 230;
|
||||
|
|
@ -203,6 +157,7 @@ export default {
|
|||
id: [String, Number],
|
||||
phasesConfigured: Number,
|
||||
phasesActive: Number,
|
||||
phases1p3p: Boolean,
|
||||
minSoc: Number,
|
||||
maxCurrent: Number,
|
||||
minCurrent: Number,
|
||||
|
|
@ -217,47 +172,29 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
maxPower1p: function () {
|
||||
return this.fmtKw(this.maxCurrent * V);
|
||||
},
|
||||
minPower1p: function () {
|
||||
return this.fmtKw(this.minCurrent * V);
|
||||
},
|
||||
maxPower3p: function () {
|
||||
return this.fmtKw(this.maxCurrent * V * 3);
|
||||
},
|
||||
minPower3p: function () {
|
||||
return this.fmtKw(this.minCurrent * V * 3);
|
||||
phasesOptions: function () {
|
||||
if (this.phases1p3p) {
|
||||
return [PHASES_AUTO, PHASES_3, PHASES_1];
|
||||
}
|
||||
return [PHASES_3, PHASES_1];
|
||||
},
|
||||
maxPower: function () {
|
||||
switch (this.phasesConfigured) {
|
||||
case PHASES_AUTO:
|
||||
return this.maxPower3p;
|
||||
case PHASES_3:
|
||||
return this.maxPower3p;
|
||||
case PHASES_1:
|
||||
return this.maxPower1p;
|
||||
default:
|
||||
return this.fmtKw(this.maxCurrent * V * this.phasesActive);
|
||||
if (this.phasesConfigured === PHASES_AUTO) {
|
||||
return this.maxPowerPhases(3);
|
||||
}
|
||||
if ([PHASES_3, PHASES_1].includes(this.phasesConfigured)) {
|
||||
return this.maxPowerPhases(this.phasesConfigured);
|
||||
}
|
||||
return this.fmtKw(this.maxCurrent * V * this.phasesActive);
|
||||
},
|
||||
minPower: function () {
|
||||
switch (this.phasesConfigured) {
|
||||
case PHASES_AUTO:
|
||||
return this.minPower1p;
|
||||
case PHASES_3:
|
||||
return this.minPower3p;
|
||||
case PHASES_1:
|
||||
return this.minPower1p;
|
||||
default:
|
||||
return this.fmtKw(this.minCurrent * V * this.phasesActive);
|
||||
if (this.phasesConfigured === PHASES_AUTO) {
|
||||
return this.minPowerPhases(1);
|
||||
}
|
||||
},
|
||||
showConfigurablePhases: function () {
|
||||
return [PHASES_AUTO, PHASES_3, PHASES_1].includes(this.phasesConfigured);
|
||||
},
|
||||
showCurrentSettings: function () {
|
||||
return this.$hiddenFeatures();
|
||||
if ([PHASES_3, PHASES_1].includes(this.phasesConfigured)) {
|
||||
return this.minPowerPhases(this.phasesConfigured);
|
||||
}
|
||||
return this.fmtKw(this.minCurrent * V * this.phasesActive);
|
||||
},
|
||||
minCurrentOptions: function () {
|
||||
const opt1 = [...range(Math.floor(this.maxCurrent), 1), 0.5, 0.25, 0.125];
|
||||
|
|
@ -287,6 +224,12 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
maxPowerPhases: function (phases) {
|
||||
return this.fmtKw(this.maxCurrent * V * phases);
|
||||
},
|
||||
minPowerPhases: function (phases) {
|
||||
return this.fmtKw(this.minCurrent * V * phases);
|
||||
},
|
||||
formId: function (name) {
|
||||
return `loadpoint_${this.id}_${name}`;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -236,7 +236,6 @@ loadpoints:
|
|||
- title: Carport
|
||||
charger: charger_1
|
||||
mode: pv
|
||||
phases: 1
|
||||
meter: meter_charger_1
|
||||
vehicle: vehicle_1
|
||||
- title: Garage
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ const (
|
|||
DisableThreshold = "disableThreshold"
|
||||
|
||||
PhasesConfigured = "phasesConfigured" // configured phases (1/3, 0 for auto on 1p3p chargers, nil for plain chargers)
|
||||
Phases1p3p = "phases1p3p" // phase switcher (1p3p chargers)
|
||||
PhasesEnabled = "phasesEnabled" // enabled phases (1/3)
|
||||
PhasesActive = "phasesActive" // active phases as used by vehicle (1/2/3)
|
||||
|
||||
|
|
|
|||
|
|
@ -108,21 +108,25 @@ type Loadpoint struct {
|
|||
vmu sync.RWMutex // guard vehicle
|
||||
Mode_ api.ChargeMode `mapstructure:"mode"` // Default charge mode, used for disconnect
|
||||
|
||||
Title_ string `mapstructure:"title"` // UI title
|
||||
Priority_ int `mapstructure:"priority"` // Priority
|
||||
ConfiguredPhases int `mapstructure:"phases"` // Charger configured phase mode 0/1/3
|
||||
ChargerRef string `mapstructure:"charger"` // Charger reference
|
||||
VehicleRef string `mapstructure:"vehicle"` // Vehicle reference
|
||||
MeterRef string `mapstructure:"meter"` // Charge meter reference
|
||||
Soc SocConfig
|
||||
Enable, Disable ThresholdConfig
|
||||
Title_ string `mapstructure:"title"` // UI title
|
||||
Priority_ int `mapstructure:"priority"` // Priority
|
||||
ChargerRef string `mapstructure:"charger"` // Charger reference
|
||||
VehicleRef string `mapstructure:"vehicle"` // Vehicle reference
|
||||
MeterRef string `mapstructure:"meter"` // Charge meter reference
|
||||
Soc SocConfig
|
||||
Enable, Disable ThresholdConfig
|
||||
GuardDuration time.Duration // charger enable/disable minimum holding time
|
||||
|
||||
MinCurrent float64 // PV mode: start current Min+PV mode: min current
|
||||
MaxCurrent float64 // Max allowed current. Physically ensured by the charger
|
||||
GuardDuration time.Duration // charger enable/disable minimum holding time
|
||||
// TODO deprecated
|
||||
ConfiguredPhases_ int `mapstructure:"phases"`
|
||||
MinCurrent_ float64 `mapstructure:"minCurrent"`
|
||||
MaxCurrent_ float64 `mapstructure:"maxCurrent"`
|
||||
|
||||
limitSoc int // Session limit for soc
|
||||
limitEnergy float64 // Session limit for energy
|
||||
minCurrent float64 // PV mode: start current Min+PV mode: min current
|
||||
maxCurrent float64 // Max allowed current. Physically ensured by the charger
|
||||
configuredPhases int // Charger configured phase mode 0/1/3
|
||||
limitSoc int // Session limit for soc
|
||||
limitEnergy float64 // Session limit for energy
|
||||
|
||||
mode api.ChargeMode
|
||||
enabled bool // Charger enabled state
|
||||
|
|
@ -200,14 +204,6 @@ func NewLoadpointFromConfig(log *util.Logger, settings *Settings, other map[stri
|
|||
lp.Soc.Poll.Mode = pollCharging
|
||||
}
|
||||
|
||||
if lp.MinCurrent == 0 {
|
||||
lp.log.WARN.Println("minCurrent must not be zero")
|
||||
}
|
||||
|
||||
if lp.MaxCurrent < lp.MinCurrent {
|
||||
lp.log.WARN.Println("maxCurrent must be larger than minCurrent")
|
||||
}
|
||||
|
||||
if lp.MeterRef != "" {
|
||||
dev, err := config.Meters().ByName(lp.MeterRef)
|
||||
if err != nil {
|
||||
|
|
@ -235,17 +231,29 @@ func NewLoadpointFromConfig(log *util.Logger, settings *Settings, other map[stri
|
|||
lp.charger = dev.Instance()
|
||||
lp.configureChargerType(lp.charger)
|
||||
|
||||
// setup fixed phases:
|
||||
// - simple charger starts with phases config if specified or 3p
|
||||
// - switchable charger starts at 0p since we don't know the current setting
|
||||
if _, ok := lp.charger.(api.PhaseSwitcher); !ok {
|
||||
if lp.ConfiguredPhases == 0 {
|
||||
lp.ConfiguredPhases = 3
|
||||
lp.log.WARN.Println("phases not configured, assuming 3p")
|
||||
// phase switching defaults based on charger capabilities
|
||||
if !lp.hasPhaseSwitching() {
|
||||
lp.configuredPhases = 3
|
||||
}
|
||||
|
||||
// TODO deprecated
|
||||
if lp.MinCurrent_ > 0 {
|
||||
lp.log.WARN.Println("deprecated: minCurrent setting is ignored, please remove")
|
||||
if _, err := lp.settings.Float(keys.MinCurrent); err != nil {
|
||||
lp.settings.SetFloat(keys.MinCurrent, lp.MinCurrent_)
|
||||
}
|
||||
}
|
||||
if lp.MaxCurrent_ > 0 {
|
||||
lp.log.WARN.Println("deprecated: maxcurrent setting is ignored, please remove")
|
||||
if _, err := lp.settings.Float(keys.MaxCurrent); err != nil {
|
||||
lp.settings.SetFloat(keys.MaxCurrent, lp.MaxCurrent_)
|
||||
}
|
||||
}
|
||||
if lp.ConfiguredPhases_ > 0 {
|
||||
lp.log.WARN.Println("deprecated: phases setting is ignored, please remove")
|
||||
if _, err := lp.settings.Int(keys.PhasesConfigured); err != nil {
|
||||
lp.settings.SetInt(keys.PhasesConfigured, int64(lp.ConfiguredPhases_))
|
||||
}
|
||||
lp.phases = lp.ConfiguredPhases
|
||||
} else if lp.ConfiguredPhases != 0 {
|
||||
lp.log.WARN.Printf("locking phase config to %dp for switchable charger", lp.ConfiguredPhases)
|
||||
}
|
||||
|
||||
// validate thresholds
|
||||
|
|
@ -275,8 +283,8 @@ func NewLoadpoint(log *util.Logger, settings *Settings) *Loadpoint {
|
|||
bus: bus, // event bus
|
||||
mode: api.ModeOff,
|
||||
status: api.StatusNone,
|
||||
MinCurrent: 6, // A
|
||||
MaxCurrent: 16, // A
|
||||
minCurrent: 6, // A
|
||||
maxCurrent: 16, // A
|
||||
Soc: SocConfig{
|
||||
Poll: PollConfig{
|
||||
Interval: pollInterval,
|
||||
|
|
@ -300,6 +308,15 @@ func (lp *Loadpoint) restoreSettings() {
|
|||
if v, err := lp.settings.String(keys.Mode); err == nil && v != "" {
|
||||
lp.setMode(api.ChargeMode(v))
|
||||
}
|
||||
if v, err := lp.settings.Int(keys.PhasesConfigured); err == nil && (v > 0 || lp.hasPhaseSwitching()) {
|
||||
lp.setConfiguredPhases(int(v))
|
||||
}
|
||||
if v, err := lp.settings.Float(keys.MinCurrent); err == nil && v > 0 {
|
||||
lp.setMinCurrent(v)
|
||||
}
|
||||
if v, err := lp.settings.Float(keys.MaxCurrent); err == nil && v > 0 {
|
||||
lp.setMaxCurrent(v)
|
||||
}
|
||||
if v, err := lp.settings.Int(keys.LimitSoc); err == nil && v > 0 {
|
||||
lp.setLimitSoc(int(v))
|
||||
}
|
||||
|
|
@ -571,7 +588,8 @@ func (lp *Loadpoint) Prepare(uiChan chan<- util.Param, pushChan chan<- push.Even
|
|||
lp.publish(keys.EnableThreshold, lp.Enable.Threshold)
|
||||
lp.publish(keys.DisableThreshold, lp.Disable.Threshold)
|
||||
|
||||
lp.setConfiguredPhases(lp.ConfiguredPhases)
|
||||
lp.publish(keys.PhasesConfigured, lp.configuredPhases)
|
||||
lp.publish(keys.Phases1p3p, lp.hasPhaseSwitching())
|
||||
lp.publish(keys.PhasesEnabled, lp.phases)
|
||||
lp.publish(keys.PhasesActive, lp.ActivePhases())
|
||||
lp.publishTimer(phaseTimer, 0, timerInactive)
|
||||
|
|
@ -970,17 +988,16 @@ func (lp *Loadpoint) resetPhaseTimer() {
|
|||
|
||||
// scalePhasesRequired validates if fixed phase configuration matches enabled phases
|
||||
func (lp *Loadpoint) scalePhasesRequired() bool {
|
||||
_, ok := lp.charger.(api.PhaseSwitcher)
|
||||
return ok && lp.ConfiguredPhases != 0 && lp.ConfiguredPhases != lp.GetPhases()
|
||||
return lp.hasPhaseSwitching() && lp.configuredPhases != 0 && lp.configuredPhases != lp.GetPhases()
|
||||
}
|
||||
|
||||
// scalePhasesIfAvailable scales if api.PhaseSwitcher is available
|
||||
func (lp *Loadpoint) scalePhasesIfAvailable(phases int) error {
|
||||
if lp.ConfiguredPhases != 0 {
|
||||
phases = lp.ConfiguredPhases
|
||||
if lp.configuredPhases != 0 {
|
||||
phases = lp.configuredPhases
|
||||
}
|
||||
|
||||
if _, ok := lp.charger.(api.PhaseSwitcher); ok {
|
||||
if lp.hasPhaseSwitching() {
|
||||
return lp.scalePhases(phases)
|
||||
}
|
||||
|
||||
|
|
@ -1041,7 +1058,7 @@ func (lp *Loadpoint) pvScalePhases(sitePower, minCurrent, maxCurrent float64) bo
|
|||
var waiting bool
|
||||
activePhases := lp.ActivePhases()
|
||||
availablePower := lp.chargePower - sitePower
|
||||
scalable := (sitePower > 0 || !lp.enabled) && activePhases > 1 && lp.ConfiguredPhases < 3
|
||||
scalable := (sitePower > 0 || !lp.enabled) && activePhases > 1 && lp.configuredPhases < 3
|
||||
|
||||
// scale down phases
|
||||
if targetCurrent := powerToCurrent(availablePower, activePhases); targetCurrent < minCurrent && scalable {
|
||||
|
|
@ -1137,7 +1154,7 @@ func (lp *Loadpoint) pvMaxCurrent(mode api.ChargeMode, sitePower float64, batter
|
|||
maxCurrent := lp.effectiveMaxCurrent()
|
||||
|
||||
// switch phases up/down
|
||||
if _, ok := lp.charger.(api.PhaseSwitcher); ok {
|
||||
if lp.hasPhaseSwitching() {
|
||||
_ = lp.pvScalePhases(sitePower, minCurrent, maxCurrent)
|
||||
}
|
||||
|
||||
|
|
@ -1294,7 +1311,7 @@ func (lp *Loadpoint) updateChargeCurrents() {
|
|||
|
||||
// updateChargeVoltages uses PhaseVoltages interface to count phases with nominal grid voltage
|
||||
func (lp *Loadpoint) updateChargeVoltages() {
|
||||
if _, ok := lp.charger.(api.PhaseSwitcher); ok {
|
||||
if lp.hasPhaseSwitching() {
|
||||
return // we don't need the voltages
|
||||
}
|
||||
|
||||
|
|
@ -1563,7 +1580,7 @@ func (lp *Loadpoint) Update(sitePower float64, autoCharge, batteryBuffered, batt
|
|||
err = lp.setLimit(0, false)
|
||||
|
||||
case lp.scalePhasesRequired():
|
||||
err = lp.scalePhases(lp.ConfiguredPhases)
|
||||
err = lp.scalePhases(lp.configuredPhases)
|
||||
|
||||
case lp.remoteControlled(loadpoint.RemoteHardDisable):
|
||||
remoteDisabled = loadpoint.RemoteHardDisable
|
||||
|
|
|
|||
|
|
@ -35,11 +35,11 @@ type API interface {
|
|||
// GetMinCurrent returns the min charging current
|
||||
GetMinCurrent() float64
|
||||
// SetMinCurrent sets the min charging current
|
||||
SetMinCurrent(float64)
|
||||
SetMinCurrent(float64) error
|
||||
// GetMaxCurrent returns the max charging current
|
||||
GetMaxCurrent() float64
|
||||
// SetMaxCurrent sets the max charging current
|
||||
SetMaxCurrent(float64)
|
||||
SetMaxCurrent(float64) error
|
||||
|
||||
// GetMode returns the charge mode
|
||||
GetMode() api.ChargeMode
|
||||
|
|
|
|||
|
|
@ -480,9 +480,11 @@ func (mr *MockAPIMockRecorder) SetLimitSoc(arg0 any) *gomock.Call {
|
|||
}
|
||||
|
||||
// SetMaxCurrent mocks base method.
|
||||
func (m *MockAPI) SetMaxCurrent(arg0 float64) {
|
||||
func (m *MockAPI) SetMaxCurrent(arg0 float64) error {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetMaxCurrent", arg0)
|
||||
ret := m.ctrl.Call(m, "SetMaxCurrent", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SetMaxCurrent indicates an expected call of SetMaxCurrent.
|
||||
|
|
@ -492,9 +494,11 @@ func (mr *MockAPIMockRecorder) SetMaxCurrent(arg0 any) *gomock.Call {
|
|||
}
|
||||
|
||||
// SetMinCurrent mocks base method.
|
||||
func (m *MockAPI) SetMinCurrent(arg0 float64) {
|
||||
func (m *MockAPI) SetMinCurrent(arg0 float64) error {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetMinCurrent", arg0)
|
||||
ret := m.ctrl.Call(m, "SetMinCurrent", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SetMinCurrent indicates an expected call of SetMinCurrent.
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ func (lp *Loadpoint) GetPhases() int {
|
|||
// SetPhases sets loadpoint enabled phases
|
||||
func (lp *Loadpoint) SetPhases(phases int) error {
|
||||
// limit auto mode (phases=0) to scalable charger
|
||||
if _, ok := lp.charger.(api.PhaseSwitcher); !ok && phases == 0 {
|
||||
if !lp.hasPhaseSwitching() && phases == 0 {
|
||||
return fmt.Errorf("invalid number of phases: %d", phases)
|
||||
}
|
||||
|
||||
|
|
@ -118,10 +118,13 @@ func (lp *Loadpoint) SetPhases(phases int) error {
|
|||
|
||||
// set new default
|
||||
lp.log.DEBUG.Println("set phases:", phases)
|
||||
|
||||
lp.Lock()
|
||||
lp.setConfiguredPhases(phases)
|
||||
lp.Unlock()
|
||||
|
||||
// apply immediately if not 1p3p
|
||||
if _, ok := lp.charger.(api.PhaseSwitcher); !ok {
|
||||
if !lp.hasPhaseSwitching() {
|
||||
lp.setPhases(phases)
|
||||
}
|
||||
|
||||
|
|
@ -324,40 +327,62 @@ func (lp *Loadpoint) GetChargePowerFlexibility() float64 {
|
|||
func (lp *Loadpoint) GetMinCurrent() float64 {
|
||||
lp.RLock()
|
||||
defer lp.RUnlock()
|
||||
return lp.MinCurrent
|
||||
return lp.minCurrent
|
||||
}
|
||||
|
||||
// setMinCurrent sets the min loadpoint current (no mutex)
|
||||
func (lp *Loadpoint) setMinCurrent(current float64) {
|
||||
lp.minCurrent = current
|
||||
lp.publish(keys.MinCurrent, lp.minCurrent)
|
||||
lp.settings.SetFloat(keys.MinCurrent, lp.minCurrent)
|
||||
}
|
||||
|
||||
// SetMinCurrent sets the min loadpoint current
|
||||
func (lp *Loadpoint) SetMinCurrent(current float64) {
|
||||
func (lp *Loadpoint) SetMinCurrent(current float64) error {
|
||||
lp.Lock()
|
||||
defer lp.Unlock()
|
||||
|
||||
lp.log.DEBUG.Println("set min current:", current)
|
||||
|
||||
if current != lp.MinCurrent {
|
||||
lp.MinCurrent = current
|
||||
lp.publish(keys.MinCurrent, lp.MinCurrent)
|
||||
if current > lp.maxCurrent {
|
||||
return errors.New("min current must be smaller or equal than max current")
|
||||
}
|
||||
|
||||
lp.log.DEBUG.Println("set min current:", current)
|
||||
if current != lp.minCurrent {
|
||||
lp.setMinCurrent(current)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMaxCurrent returns the max loadpoint current
|
||||
func (lp *Loadpoint) GetMaxCurrent() float64 {
|
||||
lp.RLock()
|
||||
defer lp.RUnlock()
|
||||
return lp.MaxCurrent
|
||||
return lp.maxCurrent
|
||||
}
|
||||
|
||||
// setMaxCurrent sets the max loadpoint current
|
||||
func (lp *Loadpoint) setMaxCurrent(current float64) {
|
||||
lp.maxCurrent = current
|
||||
lp.publish(keys.MaxCurrent, lp.maxCurrent)
|
||||
lp.settings.SetFloat(keys.MaxCurrent, lp.maxCurrent)
|
||||
}
|
||||
|
||||
// SetMaxCurrent sets the max loadpoint current
|
||||
func (lp *Loadpoint) SetMaxCurrent(current float64) {
|
||||
func (lp *Loadpoint) SetMaxCurrent(current float64) error {
|
||||
lp.Lock()
|
||||
defer lp.Unlock()
|
||||
|
||||
lp.log.DEBUG.Println("set max current:", current)
|
||||
|
||||
if current != lp.MaxCurrent {
|
||||
lp.MaxCurrent = current
|
||||
lp.publish(keys.MaxCurrent, lp.MaxCurrent)
|
||||
if current < lp.minCurrent {
|
||||
return errors.New("max current must be greater or equal than min current")
|
||||
}
|
||||
|
||||
lp.log.DEBUG.Println("set max current:", current)
|
||||
if current != lp.maxCurrent {
|
||||
lp.setMaxCurrent(current)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMinPower returns the min loadpoint power for a single phase
|
||||
|
|
|
|||
|
|
@ -7,17 +7,9 @@ import (
|
|||
|
||||
// setConfiguredPhases sets the default phase configuration
|
||||
func (lp *Loadpoint) setConfiguredPhases(phases int) {
|
||||
lp.Lock()
|
||||
defer lp.Unlock()
|
||||
|
||||
lp.ConfiguredPhases = phases
|
||||
|
||||
// publish 1p3p capability and phase configuration
|
||||
if _, ok := lp.charger.(api.PhaseSwitcher); ok {
|
||||
lp.publish(keys.PhasesConfigured, lp.ConfiguredPhases)
|
||||
} else {
|
||||
lp.publish(keys.PhasesConfigured, nil)
|
||||
}
|
||||
lp.configuredPhases = phases
|
||||
lp.publish(keys.PhasesConfigured, lp.configuredPhases)
|
||||
lp.settings.SetInt(keys.PhasesConfigured, int64(lp.configuredPhases))
|
||||
}
|
||||
|
||||
// setPhases sets the number of enabled phases without modifying the charger
|
||||
|
|
@ -93,8 +85,8 @@ func (lp *Loadpoint) maxActivePhases() int {
|
|||
}
|
||||
|
||||
// if 1p3p supported then assume configured limit or 3p
|
||||
if _, ok := lp.charger.(api.PhaseSwitcher); ok {
|
||||
physical = lp.ConfiguredPhases
|
||||
if lp.hasPhaseSwitching() {
|
||||
physical = lp.configuredPhases
|
||||
}
|
||||
|
||||
return min(expect(vehicle), expect(physical), expect(measured))
|
||||
|
|
@ -107,3 +99,8 @@ func (lp *Loadpoint) getVehiclePhases() int {
|
|||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (lp *Loadpoint) hasPhaseSwitching() bool {
|
||||
_, ok := lp.charger.(api.PhaseSwitcher)
|
||||
return ok
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ func TestMaxActivePhases(t *testing.T) {
|
|||
vehicle.EXPECT().Phases().Return(tc.vehicle).MinTimes(1)
|
||||
|
||||
lp := &Loadpoint{
|
||||
ConfiguredPhases: dflt, // fixed phases or default
|
||||
configuredPhases: dflt, // fixed phases or default
|
||||
vehicle: vehicle,
|
||||
phases: tc.physical,
|
||||
measuredPhases: tc.measuredPhases,
|
||||
|
|
@ -187,10 +187,10 @@ func TestPvScalePhases(t *testing.T) {
|
|||
progress: NewProgress(0, 10), // silence nil panics
|
||||
wakeUpTimer: NewTimer(), // silence nil panics
|
||||
mode: api.ModeNow,
|
||||
MinCurrent: minA,
|
||||
MaxCurrent: maxA,
|
||||
minCurrent: minA,
|
||||
maxCurrent: maxA,
|
||||
vehicle: vehicle,
|
||||
ConfiguredPhases: 0, // allow switching
|
||||
configuredPhases: 0, // allow switching
|
||||
phases: tc.physical,
|
||||
status: api.StatusC,
|
||||
}
|
||||
|
|
@ -366,8 +366,8 @@ func TestPvScalePhasesTimer(t *testing.T) {
|
|||
log: util.NewLogger("foo"),
|
||||
clock: clock,
|
||||
charger: charger,
|
||||
MinCurrent: minA,
|
||||
MaxCurrent: maxA,
|
||||
minCurrent: minA,
|
||||
maxCurrent: maxA,
|
||||
phases: tc.phases,
|
||||
measuredPhases: tc.measuredPhases,
|
||||
status: api.StatusC,
|
||||
|
|
@ -431,8 +431,8 @@ func TestScalePhasesIfAvailable(t *testing.T) {
|
|||
plainCharger,
|
||||
phaseCharger,
|
||||
},
|
||||
MinCurrent: minA,
|
||||
ConfiguredPhases: tc.dflt, // fixed phases or default
|
||||
minCurrent: minA,
|
||||
configuredPhases: tc.dflt, // fixed phases or default
|
||||
phases: tc.physical, // current phase status
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ func attachListeners(t *testing.T, lp *Loadpoint) {
|
|||
|
||||
if charger, ok := lp.charger.(*api.MockCharger); ok && charger != nil {
|
||||
charger.EXPECT().Enabled().Return(true, nil)
|
||||
charger.EXPECT().MaxCurrent(int64(lp.MinCurrent)).Return(nil)
|
||||
charger.EXPECT().MaxCurrent(int64(lp.minCurrent)).Return(nil)
|
||||
}
|
||||
|
||||
uiChan, pushChan, lpChan := createChannels(t)
|
||||
|
|
@ -88,8 +88,8 @@ func TestNew(t *testing.T) {
|
|||
if lp.phases != 0 {
|
||||
t.Errorf("Phases %v", lp.phases)
|
||||
}
|
||||
if lp.MaxCurrent != maxA {
|
||||
t.Errorf("MaxCurrent %v", lp.MaxCurrent)
|
||||
if lp.maxCurrent != maxA {
|
||||
t.Errorf("MaxCurrent %v", lp.maxCurrent)
|
||||
}
|
||||
if lp.status != api.StatusNone {
|
||||
t.Errorf("status %v", lp.status)
|
||||
|
|
@ -164,8 +164,8 @@ func TestUpdatePowerZero(t *testing.T) {
|
|||
chargeTimer: &Null{}, // silence nil panics
|
||||
wakeUpTimer: NewTimer(),
|
||||
sessionEnergy: NewEnergyMetrics(),
|
||||
MinCurrent: minA,
|
||||
MaxCurrent: maxA,
|
||||
minCurrent: minA,
|
||||
maxCurrent: maxA,
|
||||
phases: 1,
|
||||
status: tc.status, // no status change
|
||||
}
|
||||
|
|
@ -311,8 +311,8 @@ func TestPVHysteresis(t *testing.T) {
|
|||
log: util.NewLogger("foo"),
|
||||
clock: clck,
|
||||
charger: charger,
|
||||
MinCurrent: minA,
|
||||
MaxCurrent: maxA,
|
||||
minCurrent: minA,
|
||||
maxCurrent: maxA,
|
||||
phases: phases,
|
||||
measuredPhases: phases,
|
||||
Enable: ThresholdConfig{
|
||||
|
|
@ -359,8 +359,8 @@ func TestPVHysteresisForStatusOtherThanC(t *testing.T) {
|
|||
lp := &Loadpoint{
|
||||
log: util.NewLogger("foo"),
|
||||
clock: clck,
|
||||
MinCurrent: minA,
|
||||
MaxCurrent: maxA,
|
||||
minCurrent: minA,
|
||||
maxCurrent: maxA,
|
||||
phases: phases,
|
||||
measuredPhases: phases,
|
||||
}
|
||||
|
|
@ -401,8 +401,8 @@ func TestDisableAndEnableAtTargetSoc(t *testing.T) {
|
|||
progress: NewProgress(0, 10), // silence nil panics
|
||||
wakeUpTimer: NewTimer(), // silence nil panics
|
||||
// coordinator: coordinator.NewDummy(), // silence nil panics
|
||||
MinCurrent: minA,
|
||||
MaxCurrent: maxA,
|
||||
minCurrent: minA,
|
||||
maxCurrent: maxA,
|
||||
vehicle: vehicle, // needed for targetSoc check
|
||||
socEstimator: socEstimator, // instead of vehicle: vehicle,
|
||||
mode: api.ModeNow,
|
||||
|
|
@ -479,8 +479,8 @@ func TestSetModeAndSocAtDisconnect(t *testing.T) {
|
|||
chargeTimer: &Null{}, // silence nil panics
|
||||
wakeUpTimer: NewTimer(),
|
||||
sessionEnergy: NewEnergyMetrics(),
|
||||
MinCurrent: minA,
|
||||
MaxCurrent: maxA,
|
||||
minCurrent: minA,
|
||||
maxCurrent: maxA,
|
||||
status: api.StatusC,
|
||||
Mode_: api.ModeOff, // default mode
|
||||
}
|
||||
|
|
@ -550,8 +550,8 @@ func TestChargedEnergyAtDisconnect(t *testing.T) {
|
|||
chargeTimer: &Null{}, // silence nil panics
|
||||
wakeUpTimer: NewTimer(),
|
||||
sessionEnergy: NewEnergyMetrics(),
|
||||
MinCurrent: minA,
|
||||
MaxCurrent: maxA,
|
||||
minCurrent: minA,
|
||||
maxCurrent: maxA,
|
||||
status: api.StatusC,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ func TestPublishSocAndRange(t *testing.T) {
|
|||
chargeTimer: &Null{}, // silence nil panics
|
||||
socEstimator: soc.NewEstimator(log, charger, vehicle, false),
|
||||
sessionEnergy: NewEnergyMetrics(),
|
||||
MinCurrent: minA,
|
||||
MaxCurrent: maxA,
|
||||
minCurrent: minA,
|
||||
maxCurrent: maxA,
|
||||
phases: 1,
|
||||
mode: api.ModeNow,
|
||||
}
|
||||
|
|
@ -252,8 +252,8 @@ func TestReconnectVehicle(t *testing.T) {
|
|||
chargeTimer: &Null{}, // silence nil panics
|
||||
wakeUpTimer: NewTimer(),
|
||||
sessionEnergy: NewEnergyMetrics(),
|
||||
MinCurrent: minA,
|
||||
MaxCurrent: maxA,
|
||||
minCurrent: minA,
|
||||
maxCurrent: maxA,
|
||||
phases: 1,
|
||||
mode: api.ModeNow,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,9 +116,6 @@ loadpoints:
|
|||
charger: wallbe # charger
|
||||
meter: charge # charge meter
|
||||
mode: "off" # default charge mode to apply when vehicle is disconnected; use "off" to disable by default if charger is publicly available
|
||||
phases: 3 # electrical connection (normal charger: default 3 for 3 phase, 1p3p charger: 0 for "auto" or 1/3 for fixed phases)
|
||||
minCurrent: 6 # minimum charge current (default 6A)
|
||||
maxCurrent: 16 # maximum charge current (default 16A)
|
||||
|
||||
# remaining settings are experts-only and best left at default values
|
||||
priority: 0 # relative priority for concurrent charging in PV mode with multiple loadpoints (higher values have higher priority)
|
||||
|
|
|
|||
|
|
@ -154,8 +154,6 @@ solar = "Solar"
|
|||
[main.loadpointSettings]
|
||||
currents = "Corrent de càrrega"
|
||||
default = "defecte"
|
||||
disclaimerHint = "Nota:"
|
||||
disclaimerText = "Els canvis encara no són persistents i es restableixen al iniciar el servei."
|
||||
title = "Configuracions {0}"
|
||||
vehicle = "Vehicle"
|
||||
|
||||
|
|
|
|||
|
|
@ -154,8 +154,6 @@ solar = "Slunce"
|
|||
[main.loadpointSettings]
|
||||
currents = "Nabíjecí proud"
|
||||
default = "výchozí"
|
||||
disclaimerHint = "Poznámka:"
|
||||
disclaimerText = "Po restartovaní serveru budou zmeny ztraceny"
|
||||
title = "Nastavení {0}"
|
||||
vehicle = "Vozidlo"
|
||||
|
||||
|
|
|
|||
|
|
@ -211,8 +211,6 @@ solar = "solenergi"
|
|||
[main.loadpointSettings]
|
||||
currents = "Ladestrøm"
|
||||
default = "standard"
|
||||
disclaimerHint = "Bemærk:"
|
||||
disclaimerText = "Ændringer vil gå tabt, efter at serveren er genstartet."
|
||||
onlyForSocBasedCharging = "Disse indstillinger er kun tilgængelig for køretøjer med kendt opladningsniveau"
|
||||
title = "Indstillinger {0}"
|
||||
vehicle = "Køretøj"
|
||||
|
|
|
|||
|
|
@ -213,8 +213,6 @@ solar = "Sonne"
|
|||
[main.loadpointSettings]
|
||||
currents = "Ladestrom"
|
||||
default = "default"
|
||||
disclaimerHint = "Hinweis:"
|
||||
disclaimerText = "Änderungen gehen nach einem Neustart des Servers verloren."
|
||||
onlyForSocBasedCharging = "Diese Optionen sind nur für Fahrzeuge mit bekanntem Ladestand verfügbar."
|
||||
title = "Einstellungen {0}"
|
||||
vehicle = "Fahrzeug"
|
||||
|
|
|
|||
|
|
@ -210,8 +210,6 @@ solar = "Solar"
|
|||
[main.loadpointSettings]
|
||||
currents = "Charging current"
|
||||
default = "default"
|
||||
disclaimerHint = "Note:"
|
||||
disclaimerText = "Changes will be lost after the server is restarted."
|
||||
onlyForSocBasedCharging = "These options are only available for vehicles with known charging level."
|
||||
title = "Settings {0}"
|
||||
vehicle = "Vehicle"
|
||||
|
|
|
|||
|
|
@ -222,8 +222,6 @@ solar = "Solar"
|
|||
[main.loadpointSettings]
|
||||
currents = "Corriente de carga"
|
||||
default = "defecto"
|
||||
disclaimerHint = "Nota:"
|
||||
disclaimerText = "Actualmente, los cambios aún no son persistentes y se restablecen al iniciar el servicio."
|
||||
onlyForSocBasedCharging = "Estas opciones sólo están disponibles para vehículos con nivel de carga conocido"
|
||||
title = "Configuraciones {0}"
|
||||
vehicle = "Vehículo"
|
||||
|
|
|
|||
|
|
@ -199,8 +199,6 @@ solar = "Aurinkoenergia"
|
|||
[main.loadpointSettings]
|
||||
currents = "Latausvirta"
|
||||
default = "oletus"
|
||||
disclaimerHint = "Huomautus:"
|
||||
disclaimerText = "Muutokset eivät ole voimassa serverin uudelleen käynnistyksen jälkeen."
|
||||
title = "Asetukset {0}"
|
||||
vehicle = "Ajoneuvo"
|
||||
|
||||
|
|
|
|||
|
|
@ -216,8 +216,6 @@ solar = "Solaire"
|
|||
[main.loadpointSettings]
|
||||
currents = "Courant de charge"
|
||||
default = "défaut"
|
||||
disclaimerHint = "Remarque:"
|
||||
disclaimerText = "Les modifications seront perdues après le redémarrage du serveur."
|
||||
onlyForSocBasedCharging = "Ces options sont disponibles uniquement pour les véhicules avec niveau de charge connu."
|
||||
title = "Réglages {0}"
|
||||
vehicle = "Véhicule"
|
||||
|
|
|
|||
|
|
@ -218,8 +218,6 @@ solar = "Solarno"
|
|||
[main.loadpointSettings]
|
||||
currents = "Struja napajanja"
|
||||
default = "zadano"
|
||||
disclaimerHint = "Bilješka:"
|
||||
disclaimerText = "Promjene će se izgubiti nakon ponovnog pokretanja poslužitelja."
|
||||
onlyForSocBasedCharging = "Ove su opcije dostupne samo za vozila s poznatom razinom napunjenosti."
|
||||
title = "Postavke {0}"
|
||||
vehicle = "Vozilo"
|
||||
|
|
|
|||
|
|
@ -101,8 +101,6 @@ remoteDisabledSoft = "{source}: Ricarica FV adattiva disabilitata"
|
|||
[main.loadpointSettings]
|
||||
currents = "Corrente di carica"
|
||||
default = "default"
|
||||
disclaimerHint = "Nota:"
|
||||
disclaimerText = "Le modifiche andranno perse dopo il riavvio del server."
|
||||
title = "Impostazioni {0}"
|
||||
vehicle = "Veicolo"
|
||||
|
||||
|
|
|
|||
|
|
@ -94,8 +94,6 @@ power = "Leeschtung"
|
|||
[main.loadpointSettings]
|
||||
currents = "Ladestroum"
|
||||
default = "Standard"
|
||||
disclaimerHint = "Notiz:"
|
||||
disclaimerText = "Ännerunge ginn verluer nodeems de Server nei gestart ass."
|
||||
title = "Astellungen {0}"
|
||||
vehicle = "Gefier"
|
||||
|
||||
|
|
|
|||
|
|
@ -216,8 +216,6 @@ solar = "Saulės"
|
|||
[main.loadpointSettings]
|
||||
currents = "Įkrovimo srovė"
|
||||
default = "standartiškai"
|
||||
disclaimerHint = "Pastaba:"
|
||||
disclaimerText = "Šie pakeitimai neišlieka po evcc serverio restarto."
|
||||
onlyForSocBasedCharging = "Šie pasirinkimai galimi tik automobiliams su žinomu įkrovos lygiu."
|
||||
title = "Nustatymai {0}"
|
||||
vehicle = "Automobilis"
|
||||
|
|
|
|||
|
|
@ -195,8 +195,6 @@ solar = "Zon"
|
|||
[main.loadpointSettings]
|
||||
currents = "Laadstroom"
|
||||
default = "standaard"
|
||||
disclaimerHint = "Let op:"
|
||||
disclaimerText = "Wijzigingen gaan verloren als de server herstart."
|
||||
title = "Instellingen {0}"
|
||||
vehicle = "Voertuig"
|
||||
|
||||
|
|
|
|||
|
|
@ -192,8 +192,6 @@ solar = "Solenergi"
|
|||
[main.loadpointSettings]
|
||||
currents = "Ladestrøm"
|
||||
default = "forvalg"
|
||||
disclaimerHint = "Merknad:"
|
||||
disclaimerText = "Endringer vil gå tapt ved omstart av serveren"
|
||||
title = "Innstillinger for {0}"
|
||||
vehicle = "Kjøretøy"
|
||||
|
||||
|
|
|
|||
|
|
@ -217,8 +217,6 @@ solar = "Słoneczna"
|
|||
[main.loadpointSettings]
|
||||
currents = "Prąd ładowania"
|
||||
default = "domyślny"
|
||||
disclaimerHint = "Uwaga:"
|
||||
disclaimerText = "Zmiany zostaną zresetowane po restarcie serwera."
|
||||
onlyForSocBasedCharging = "Opcje te są dostępne tylko dla pojazdów ze znanym poziomem naładowania."
|
||||
title = "Ustawienia {0}"
|
||||
vehicle = "Pojazd"
|
||||
|
|
|
|||
|
|
@ -216,8 +216,6 @@ solar = "Sol"
|
|||
[main.loadpointSettings]
|
||||
currents = "Corrente de carga"
|
||||
default = "predefinado"
|
||||
disclaimerHint = "Aviso:"
|
||||
disclaimerText = "As alterações serão perdidas depois que o servidor for reiniciado."
|
||||
onlyForSocBasedCharging = "Estas opções só estão disponíveis para veículos com nível de carregamento conhecido."
|
||||
title = "Configurações {0}"
|
||||
vehicle = "Veículo"
|
||||
|
|
|
|||
|
|
@ -160,8 +160,6 @@ power = "Putere"
|
|||
[main.loadpointSettings]
|
||||
currents = "Curent încărcare"
|
||||
default = "default"
|
||||
disclaimerHint = "Nota:"
|
||||
disclaimerText = "Modificările se vor pierde după restartul serverului."
|
||||
title = "Setări {0}"
|
||||
vehicle = "Vehicul"
|
||||
|
||||
|
|
|
|||
|
|
@ -123,8 +123,6 @@ power = "Мощность"
|
|||
[main.loadpointSettings]
|
||||
currents = "Ток зарядки"
|
||||
default = "по умолчанию"
|
||||
disclaimerHint = "Заметка:"
|
||||
disclaimerText = "Изменения будут потеряны после перезагрузки сервера"
|
||||
title = "Настройки {0}"
|
||||
vehicle = "Транспортное средство"
|
||||
|
||||
|
|
|
|||
|
|
@ -211,8 +211,6 @@ solar = "Sončna energija"
|
|||
[main.loadpointSettings]
|
||||
currents = "Polnilni tok"
|
||||
default = "privzeto"
|
||||
disclaimerHint = "Opomba:"
|
||||
disclaimerText = "Po ponovnem zagonu strežnika bodo spremembe izgubljene."
|
||||
onlyForSocBasedCharging = "Te možnosti so na voljo samo za vozila z znano stopnjo napolnjenosti."
|
||||
title = "Nastavitve {0}"
|
||||
vehicle = "Vozilo"
|
||||
|
|
|
|||
|
|
@ -211,8 +211,6 @@ solar = "Solenergi"
|
|||
[main.loadpointSettings]
|
||||
currents = "Laddningsström"
|
||||
default = "förvald"
|
||||
disclaimerHint = "Anmärkning:"
|
||||
disclaimerText = "Ändringarna försvinner när servern startas om."
|
||||
onlyForSocBasedCharging = "Dessa inställningar är endast tillgängliga för fordon med känd laddnivå"
|
||||
title = "Inställningar {0}"
|
||||
vehicle = "Fordon"
|
||||
|
|
|
|||
|
|
@ -188,8 +188,6 @@ solar = "Сонячна"
|
|||
[main.loadpointSettings]
|
||||
currents = "Струм зарядки"
|
||||
default = "за замовчуванням"
|
||||
disclaimerHint = "Примітка:"
|
||||
disclaimerText = "Зміни будуть втрачені після перезапуску сервера."
|
||||
title = "Налаштування {0}"
|
||||
vehicle = "Транспортний засіб"
|
||||
|
||||
|
|
|
|||
|
|
@ -198,8 +198,6 @@ solar = "太阳能"
|
|||
[main.loadpointSettings]
|
||||
currents = "充电货币"
|
||||
default = "默认"
|
||||
disclaimerHint = "笔记:"
|
||||
disclaimerText = "服务器重新启动后,更改将丢失."
|
||||
title = "设置 {0}"
|
||||
vehicle = "车辆"
|
||||
|
||||
|
|
|
|||
|
|
@ -134,8 +134,8 @@ func (s *HTTPd) RegisterSiteHandlers(site site.API, cache *util.Cache) {
|
|||
"mode": {[]string{"POST", "OPTIONS"}, "/mode/{value:[a-z]+}", chargeModeHandler(lp)},
|
||||
"limitsoc": {[]string{"POST", "OPTIONS"}, "/limitsoc/{value:[0-9]+}", intHandler(pass(lp.SetLimitSoc), lp.GetLimitSoc)},
|
||||
"limitenergy": {[]string{"POST", "OPTIONS"}, "/limitenergy/{value:[0-9.]+}", floatHandler(pass(lp.SetLimitEnergy), lp.GetLimitEnergy)},
|
||||
"mincurrent": {[]string{"POST", "OPTIONS"}, "/mincurrent/{value:[0-9.]+}", floatHandler(pass(lp.SetMinCurrent), lp.GetMinCurrent)},
|
||||
"maxcurrent": {[]string{"POST", "OPTIONS"}, "/maxcurrent/{value:[0-9.]+}", floatHandler(pass(lp.SetMaxCurrent), lp.GetMaxCurrent)},
|
||||
"mincurrent": {[]string{"POST", "OPTIONS"}, "/mincurrent/{value:[0-9.]+}", floatHandler(lp.SetMinCurrent, lp.GetMinCurrent)},
|
||||
"maxcurrent": {[]string{"POST", "OPTIONS"}, "/maxcurrent/{value:[0-9.]+}", floatHandler(lp.SetMaxCurrent, lp.GetMaxCurrent)},
|
||||
"phases": {[]string{"POST", "OPTIONS"}, "/phases/{value:[0-9]+}", phasesHandler(lp)},
|
||||
"plan": {[]string{"GET"}, "/plan", planHandler(lp)},
|
||||
"planpreview": {[]string{"GET"}, "/plan/preview/{type:(?:soc|energy)}/{value:[0-9.]+}/{time:[0-9TZ:.-]+}", planPreviewHandler(lp)},
|
||||
|
|
|
|||
|
|
@ -56,3 +56,18 @@ test.describe("session info", async () => {
|
|||
await expect(page.getByTestId("sessionInfoLabel").first()).toContainText("Solar");
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("loadpoint settings", async () => {
|
||||
test("phase selection", async ({ page }) => {
|
||||
await page.getByTestId("loadpoint-settings-button").nth(1).click();
|
||||
await expect(page.getByLabel("auto-switching")).not.toBeVisible();
|
||||
await expect(page.getByLabel("3 phase")).toBeChecked();
|
||||
await expect(page.getByLabel("1 phase")).not.toBeChecked();
|
||||
await expect(page.getByText("~ 11.0 kW")).toBeVisible();
|
||||
await expect(page.getByText("~ 4.1 kW")).toBeVisible();
|
||||
|
||||
await page.getByLabel("1 phase").click();
|
||||
await expect(page.getByText("~ 3.7 kW")).toBeVisible();
|
||||
await expect(page.getByText("~ 1.4 kW")).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue