Tesla: validate vehicle current (#13099)
This commit is contained in:
parent
be18545837
commit
48772bf142
5 changed files with 52 additions and 17 deletions
|
|
@ -146,6 +146,18 @@ func (c *Twc3) MaxCurrent(current int64) error {
|
|||
return v.MaxCurrent(current)
|
||||
}
|
||||
|
||||
var _ api.CurrentGetter = (*Twc3)(nil)
|
||||
|
||||
// GetMaxCurrent implements the api.CurrentGetter interface
|
||||
func (c *Twc3) GetMaxCurrent() (float64, error) {
|
||||
v, ok := c.lp.GetVehicle().(api.CurrentGetter)
|
||||
if !ok {
|
||||
return 0, api.ErrNotAvailable
|
||||
}
|
||||
|
||||
return v.GetMaxCurrent()
|
||||
}
|
||||
|
||||
var _ api.ChargeRater = (*Twc3)(nil)
|
||||
|
||||
// ChargedEnergy implements the api.ChargeRater interface
|
||||
|
|
|
|||
|
|
@ -689,18 +689,17 @@ func (lp *Loadpoint) syncCharger() error {
|
|||
if enabled == lp.enabled {
|
||||
// sync max current
|
||||
if charger, ok := lp.charger.(api.CurrentGetter); ok && enabled {
|
||||
current, err := charger.GetMaxCurrent()
|
||||
if err != nil {
|
||||
return fmt.Errorf("charger get max current: %w", err)
|
||||
}
|
||||
|
||||
// smallest adjustment most PWM-Controllers can do is: 100%÷256×0,6A = 0.234A
|
||||
if math.Abs(lp.chargeCurrent-current) > 0.23 {
|
||||
if lp.chargerUpdateCompleted() {
|
||||
lp.log.WARN.Printf("charger logic error: current mismatch (got %.3gA, expected %.3gA)", current, lp.chargeCurrent)
|
||||
if current, err := charger.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 lp.chargerUpdateCompleted() {
|
||||
lp.log.WARN.Printf("charger logic error: current mismatch (got %.3gA, expected %.3gA)", current, lp.chargeCurrent)
|
||||
}
|
||||
lp.chargeCurrent = current
|
||||
lp.bus.Publish(evChargeCurrent, lp.chargeCurrent)
|
||||
}
|
||||
lp.chargeCurrent = current
|
||||
lp.bus.Publish(evChargeCurrent, lp.chargeCurrent)
|
||||
} else if !errors.Is(err, api.ErrNotAvailable) {
|
||||
return fmt.Errorf("charger get max current: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,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.WithClient(tcc)),
|
||||
Controller: tesla.NewController(vehicle, vehicle.WithClient(tcc)),
|
||||
}
|
||||
|
||||
if v.Title_ == "" {
|
||||
|
|
|
|||
|
|
@ -40,5 +40,5 @@ func TestCommandResponse(t *testing.T) {
|
|||
v, err := client.Vehicle("abc")
|
||||
require.NoError(t, err)
|
||||
|
||||
require.ErrorIs(t, NewController(v).ChargeEnable(true), api.ErrAsleep)
|
||||
require.ErrorIs(t, NewController(v, v).ChargeEnable(true), api.ErrAsleep)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ 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"
|
||||
)
|
||||
|
|
@ -13,14 +15,26 @@ 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(vehicle *tesla.Vehicle) *Controller {
|
||||
impl := &Controller{
|
||||
vehicle: vehicle,
|
||||
func NewController(ro, rw *tesla.Vehicle) *Controller {
|
||||
v := &Controller{
|
||||
vehicle: rw,
|
||||
}
|
||||
return impl
|
||||
|
||||
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()
|
||||
return float64(res.Response.ChargeState.ChargeAmps), apiError(err)
|
||||
}, time.Minute)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
var _ api.CurrentController = (*Controller)(nil)
|
||||
|
|
@ -31,9 +45,19 @@ 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