Skip to content

Commit

Permalink
TWC/Tesla: use charger api.PhaseCurrents over vehicle api.CurrentGett…
Browse files Browse the repository at this point in the history
…er (#14659)
  • Loading branch information
andig committed Jul 3, 2024
1 parent cb086f8 commit d5aabc2
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 36 deletions.
22 changes: 16 additions & 6 deletions core/loadpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -705,8 +705,15 @@ func (lp *Loadpoint) syncCharger() error {
switch {
case enabled && lp.enabled:
// sync max current
if charger, ok := lp.charger.(api.CurrentGetter); ok {
if current, err := charger.GetMaxCurrent(); err == nil {
var (
current float64
err error
)

// use chargers actual set current if available
cg, ok := lp.charger.(api.CurrentGetter)
if ok {
if current, err = cg.GetMaxCurrent(); err == nil {
// smallest adjustment most PWM-Controllers can do is: 100%÷256×0,6A = 0.234A
if math.Abs(lp.chargeCurrent-current) > 0.23 {
if shouldBeConsistent {
Expand All @@ -718,8 +725,11 @@ func (lp *Loadpoint) syncCharger() error {
} else if !errors.Is(err, api.ErrNotAvailable) {
return fmt.Errorf("charger get max current: %w", err)
}
} else {
// use measured phase currents as fallback, validate if current too high by at least 1A
}

// use measured phase currents as fallback if charger does not provide max current or does not currently relay from vehicle (TWC3)
if !ok || errors.Is(err, api.ErrNotAvailable) {
// validate if current too high by at least 1A
if current := lp.GetMaxPhaseCurrent(); current > lp.chargeCurrent+1.0 {
if shouldBeConsistent {
lp.log.WARN.Printf("charger logic error: current mismatch (got %.3gA measured, expected %.3gA)", current, lp.chargeCurrent)
Expand All @@ -738,8 +748,8 @@ func (lp *Loadpoint) syncCharger() error {
chargerPhases = 3
}

if ps, ok := lp.charger.(api.PhaseGetter); ok {
if cp, err := ps.GetPhases(); err == nil {
if pg, ok := lp.charger.(api.PhaseGetter); ok {
if cp, err := pg.GetPhases(); err == nil {
chargerPhases = cp
} else {
if errors.Is(err, api.ErrNotAvailable) {
Expand Down
2 changes: 1 addition & 1 deletion vehicle/tesla.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func NewTeslaFromConfig(other map[string]interface{}) (api.Vehicle, error) {
v := &Tesla{
embed: &cc.embed,
Provider: tesla.NewProvider(vehicle, cc.Cache),
Controller: tesla.NewController(vehicle, vehicle.WithClient(tcc)),
Controller: tesla.NewController(vehicle.WithClient(tcc)),
}

v.fromVehicle(vehicle.DisplayName, 0)
Expand Down
2 changes: 1 addition & 1 deletion vehicle/tesla/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,5 @@ func TestCommandResponse(t *testing.T) {
v, err := client.Vehicle("abc")
require.NoError(t, err)

require.ErrorIs(t, NewController(v, v).ChargeEnable(true), api.ErrAsleep)
require.ErrorIs(t, NewController(v).ChargeEnable(true), api.ErrAsleep)
}
30 changes: 2 additions & 28 deletions vehicle/tesla/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package tesla
import (
"errors"
"slices"
"time"

"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/provider"
"github.com/evcc-io/evcc/util/sponsor"
"github.com/evcc-io/tesla-proxy-client"
)
Expand All @@ -15,28 +13,14 @@ const ProxyBaseUrl = "https://tesla.evcc.io"

type Controller struct {
vehicle *tesla.Vehicle
current int64
dataG provider.Cacheable[float64]
}

// NewController creates a vehicle current and charge controller
func NewController(ro, rw *tesla.Vehicle) *Controller {
func NewController(vehicle *tesla.Vehicle) *Controller {
v := &Controller{
vehicle: rw,
vehicle: vehicle,
}

v.dataG = provider.ResettableCached(func() (float64, error) {
if v.current >= 6 {
// assume match above 6A to save API requests
return float64(v.current), nil
}
res, err := ro.Data()
if err != nil {
return 0, apiError(err)
}
return float64(res.Response.ChargeState.ChargeAmps), nil
}, time.Minute)

return v
}

Expand All @@ -48,19 +32,9 @@ func (v *Controller) MaxCurrent(current int64) error {
return api.ErrSponsorRequired
}

v.current = current
v.dataG.Reset()

return apiError(v.vehicle.SetChargingAmps(int(current)))
}

var _ api.CurrentGetter = (*Controller)(nil)

// StartCharge implements the api.VehicleChargeController interface
func (v *Controller) GetMaxCurrent() (float64, error) {
return v.dataG.Get()
}

var _ api.ChargeController = (*Controller)(nil)

// ChargeEnable implements the api.ChargeController interface
Expand Down

0 comments on commit d5aabc2

Please sign in to comment.