TWC/Tesla: use charger api.PhaseCurrents over vehicle api.CurrentGetter (#14659)
Some checks failed
Some checks failed
This commit is contained in:
parent
cb086f8698
commit
d5aabc2759
4 changed files with 20 additions and 36 deletions
|
|
@ -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 {
|
||||
|
|
@ -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)
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
)
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue