Skip to content

Commit

Permalink
Add PhaseDescriber api (evcc-io#12052)
Browse files Browse the repository at this point in the history
  • Loading branch information
andig authored Feb 8, 2024
1 parent 05fc57b commit 72cb1e3
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 14 deletions.
7 changes: 6 additions & 1 deletion api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
3 changes: 2 additions & 1 deletion assets/js/components/Loadpoint.vue
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ export default {
phases: Number,
phasesConfigured: Number,
phasesActive: Number,
phases1p3p: Boolean,
chargerPhases1p3p: Boolean,
chargerPhysicalPhases: Number,
minCurrent: Number,
maxCurrent: Number,
chargeCurrent: Number,
Expand Down
19 changes: 13 additions & 6 deletions assets/js/components/LoadpointSettingsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
<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"
>
{{ $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(
Expand Down Expand Up @@ -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,
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand Down
7 changes: 7 additions & 0 deletions charger/switchsocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
7 changes: 4 additions & 3 deletions core/keys/loadpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion core/loadpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 12 additions & 2 deletions core/loadpoint_phases.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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
Expand Down

0 comments on commit 72cb1e3

Please sign in to comment.