Volvo Connected: require vin (BC) (#24247)
This commit is contained in:
parent
6befca050b
commit
e48927af32
4 changed files with 31 additions and 8 deletions
|
|
@ -178,6 +178,7 @@ func (o *OAuth) Token() (*oauth2.Token, error) {
|
|||
if err != nil {
|
||||
// force logout
|
||||
if strings.Contains(err.Error(), "invalid_grant") && settings.Exists(o.subject) {
|
||||
o.token = nil
|
||||
o.onlineC <- false
|
||||
settings.Delete(o.subject)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ params:
|
|||
example: "https://evcc.example.org/providerauth/callback"
|
||||
- name: vin
|
||||
example: WF0FXX...
|
||||
required: true
|
||||
- name: accessToken
|
||||
deprecated: true
|
||||
- name: refreshToken
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package vehicle
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
|
|
@ -37,21 +38,31 @@ func NewVolvoConnectedFromConfig(ctx context.Context, other map[string]interface
|
|||
return nil, err
|
||||
}
|
||||
|
||||
log := util.NewLogger("volvo-connected").Redact(cc.VIN, cc.VccApiKey)
|
||||
if cc.VccApiKey == "" {
|
||||
return nil, errors.New("missing vccapikey")
|
||||
}
|
||||
|
||||
if cc.VIN == "" {
|
||||
return nil, errors.New("missing vin")
|
||||
}
|
||||
|
||||
if err := cc.Credentials.Error(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log := util.NewLogger("volvo-connected").Redact(cc.VIN, cc.Credentials.ID, cc.Credentials.Secret, cc.VccApiKey)
|
||||
|
||||
oc := connected.Oauth2Config(cc.Credentials.ID, cc.Credentials.Secret, cc.RedirectUri)
|
||||
ts, err := auth.NewOauth(ctx, cc.embed.GetTitle(), oc)
|
||||
ts, err := auth.NewOauth(ctx, "Volvo", oc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
api := connected.NewAPI(log, cc.VccApiKey, ts)
|
||||
|
||||
cc.VIN, err = ensureVehicle(cc.VIN, api.Vehicles)
|
||||
|
||||
v := &VolvoConnected{
|
||||
embed: &cc.embed,
|
||||
Provider: connected.NewProvider(api, cc.VIN, cc.Cache),
|
||||
Provider: connected.NewProvider(api, ts, cc.VIN, cc.Cache),
|
||||
}
|
||||
|
||||
return v, err
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
// Provider implements the vehicle api
|
||||
|
|
@ -14,14 +15,23 @@ type Provider struct {
|
|||
odoG func() (OdometerState, error)
|
||||
}
|
||||
|
||||
func tokenGuard[T any](fun func(string) (T, error), ts oauth2.TokenSource, vin string) (T, error) {
|
||||
// don't try as long as there's no token
|
||||
if _, err := ts.Token(); err != nil {
|
||||
var zero T
|
||||
return zero, api.ErrNotAvailable
|
||||
}
|
||||
return fun(vin)
|
||||
}
|
||||
|
||||
// NewProvider creates a vehicle api provider
|
||||
func NewProvider(api *API, vin string, cache time.Duration) *Provider {
|
||||
func NewProvider(api *API, ts oauth2.TokenSource, vin string, cache time.Duration) *Provider {
|
||||
impl := &Provider{
|
||||
statusG: util.Cached(func() (EnergyState, error) {
|
||||
return api.EnergyState(vin)
|
||||
return tokenGuard(api.EnergyState, ts, vin)
|
||||
}, cache),
|
||||
odoG: util.Cached(func() (OdometerState, error) {
|
||||
return api.OdometerState(vin)
|
||||
return tokenGuard(api.OdometerState, ts, vin)
|
||||
}, cache),
|
||||
}
|
||||
return impl
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue