Add PhaseDescriber api (#12052)

This commit is contained in:
andig 2024-02-08 19:14:13 +01:00 • committed by GitHub
parent 05fc57b6cd
commit 72cb1e3800
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 51 additions and 14 deletions

View file

@ -107,15 +107,20 @@ type Authorizer interface {
Authorize(key string) error
}
// PhaseDescriber returns the number of availablephases
type PhaseDescriber interface {
Phases() int
}
// Vehicle represents the EV and it's battery
type Vehicle interface {
Battery
BatteryCapacity
IconDescriber
FeatureDescriber
PhaseDescriber
Title() string
SetTitle(string)
Phases() int
Identifiers() []string
OnIdentified() ActionConfig
}

View file

@ -170,7 +170,8 @@ export default {
phases: Number,
phasesConfigured: Number,
phasesActive: Number,
phases1p3p: Boolean,
chargerPhases1p3p: Boolean,
chargerPhysicalPhases: Number,
minCurrent: Number,
maxCurrent: Number,
chargeCurrent: Number,

View file

@ -26,7 +26,7 @@
<h4 class="d-flex align-items-center mb-3 mt-4 text-evcc">
{{ $t("main.loadpointSettings.currents") }}
</h4>
<div class="mb-3 row">
<div v-if="phasesOptions.length" class="mb-3 row">
<label
:for="formId('phases_0')"
class="col-sm-4 col-form-label pt-0"
@ -34,7 +34,7 @@
{{ $t("main.loadpointSettings.phasesConfigured.label") }}
</label>
<div class="col-sm-8 pe-0">
<p v-if="!phases1p3p" class="mt-0 mb-2">
<p v-if="!chargerPhases1p3p" class="mt-0 mb-2">
<small>
{{
$t(
@ -166,7 +166,8 @@ export default {
id: [String, Number],
phasesConfigured: Number,
phasesActive: Number,
phases1p3p: Boolean,
chargerPhases1p3p: Boolean,
chargerPhysicalPhases: Number,
minSoc: Number,
maxCurrent: Number,
minCurrent: Number,
@ -182,13 +183,19 @@ export default {
},
computed: {
phasesOptions: function () {
if (this.phases1p3p) {
if (this.chargerPhysicalPhases == 1) {
// known fixed phase configuration, no settings required
return [];
}
if (this.chargerPhases1p3p) {
// automatic switching
return [PHASES_AUTO, PHASES_3, PHASES_1];
}
// 1p or 3p possible
return [PHASES_3, PHASES_1];
},
maxPower: function () {
if (this.phases1p3p) {
if (this.chargerPhases1p3p) {
if (this.phasesConfigured === PHASES_AUTO) {
return this.maxPowerPhases(3);
}
@ -199,7 +206,7 @@ export default {
return this.fmtKw(this.maxCurrent * V * this.phasesActive);
},
minPower: function () {
if (this.phases1p3p) {
if (this.chargerPhases1p3p) {
if (this.phasesConfigured === PHASES_AUTO) {
return this.minPowerPhases(1);
}

View file

@ -98,3 +98,10 @@ var _ loadpoint.Controller = (*switchSocket)(nil)
func (c *switchSocket) LoadpointControl(lp loadpoint.API) {
c.lp = lp
}
var _ api.PhaseDescriber = (*switchSocket)(nil)
// Phases implements the api.PhasesDescriber interface
func (v *switchSocket) Phases() int {
return 1
}

View file

@ -14,12 +14,13 @@ 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)
ChargerIcon = "chargerIcon" // charger icon for ui
ChargerFeature = "chargerFeature" // charger feature
ChargerIcon = "chargerIcon" // charger icon for ui
ChargerFeature = "chargerFeature" // charger feature
ChargerPhysicalPhases = "chargerPhysicalPhases" // charger phases
ChargerPhases1p3p = "chargerPhases1p3p" // phase switcher (1p3p chargers)
// loadpoint status
Enabled = "enabled" // loadpoint enabled

View file

@ -595,13 +595,19 @@ func (lp *Loadpoint) Prepare(uiChan chan<- util.Param, pushChan chan<- push.Even
lp.publish(keys.DisableThreshold, lp.Disable.Threshold)
lp.publish(keys.PhasesConfigured, lp.configuredPhases)
lp.publish(keys.Phases1p3p, lp.hasPhaseSwitching())
lp.publish(keys.ChargerPhases1p3p, lp.hasPhaseSwitching())
lp.publish(keys.PhasesEnabled, lp.phases)
lp.publish(keys.PhasesActive, lp.ActivePhases())
lp.publishTimer(phaseTimer, 0, timerInactive)
lp.publishTimer(pvTimer, 0, timerInactive)
lp.publishTimer(guardTimer, 0, timerInactive)
if phases := lp.getChargerPhysicalPhases(); phases != 0 {
lp.publish(keys.ChargerPhysicalPhases, phases)
} else {
lp.publish(keys.ChargerPhysicalPhases, nil)
}
// charger features
for _, f := range []api.Feature{api.IntegratedDevice, api.Heating} {
lp.publishChargerFeature(f)

View file

@ -62,8 +62,9 @@ func (lp *Loadpoint) ActivePhases() int {
physical := lp.GetPhases()
vehicle := lp.getVehiclePhases()
measured := lp.getMeasuredPhases()
charger := lp.getChargerPhysicalPhases()
active := min(expect(vehicle), expect(physical), expect(measured))
active := min(expect(vehicle), expect(physical), expect(measured), expect(charger))
// sanity check - we should not assume less active phases than actually measured
if measured > 0 && active < measured {
@ -78,6 +79,7 @@ func (lp *Loadpoint) maxActivePhases() int {
physical := lp.GetPhases()
measured := lp.getMeasuredPhases()
vehicle := lp.getVehiclePhases()
charger := lp.getChargerPhysicalPhases()
// during 1p or unknown config, 1p measured is not a restriction
if physical <= 1 || vehicle == 1 {
@ -89,7 +91,7 @@ func (lp *Loadpoint) maxActivePhases() int {
physical = lp.configuredPhases
}
return min(expect(vehicle), expect(physical), expect(measured))
return min(expect(vehicle), expect(physical), expect(measured), expect(charger))
}
func (lp *Loadpoint) getVehiclePhases() int {
@ -100,6 +102,14 @@ func (lp *Loadpoint) getVehiclePhases() int {
return 0
}
func (lp *Loadpoint) getChargerPhysicalPhases() int {
if cc, ok := lp.charger.(api.PhaseDescriber); ok {
return cc.Phases()
}
return 0
}
func (lp *Loadpoint) hasPhaseSwitching() bool {
_, ok := lp.charger.(api.PhaseSwitcher)
return ok