Smart EQ: use Mercedes api (#18044)
This commit is contained in:
parent
41da4199be
commit
eaff6de83c
3 changed files with 55 additions and 79 deletions
|
|
@ -3,8 +3,36 @@ products:
|
|||
- brand: Smart
|
||||
description:
|
||||
generic: EQ
|
||||
requirements:
|
||||
description:
|
||||
de: |
|
||||
Benötigt `access` und `refresh` Tokens. Diese können über den Befehl `evcc token [name]` generiert werden.
|
||||
en: |
|
||||
Requires `access` and `refresh` tokens. These can be generated with command `evcc token [name]`.
|
||||
params:
|
||||
- preset: vehicle-base
|
||||
- preset: vehicle-common
|
||||
- name: user
|
||||
required: true
|
||||
- name: region
|
||||
required: true
|
||||
choice: [EMEA, APAC, NORAM]
|
||||
default: EMEA
|
||||
- name: accessToken
|
||||
required: true
|
||||
mask: true
|
||||
- name: refreshToken
|
||||
required: true
|
||||
mask: true
|
||||
- name: vin
|
||||
example: V...
|
||||
- name: cache
|
||||
default: 15m
|
||||
render: |
|
||||
type: smart
|
||||
{{ include "vehicle-base" . }}
|
||||
type: smart-eq
|
||||
vin: {{ .vin }}
|
||||
user: {{ .user }}
|
||||
region: {{ .region }}
|
||||
tokens:
|
||||
access: {{ .accessToken }}
|
||||
refresh: {{ .refreshToken }}
|
||||
{{ include "vehicle-common" . }}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package vehicle
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
|
|
@ -15,11 +16,16 @@ type Mercedes struct {
|
|||
}
|
||||
|
||||
func init() {
|
||||
registry.Add("mercedes", NewMercedesFromConfig)
|
||||
registry.Add("mercedes", func(other map[string]interface{}) (api.Vehicle, error) {
|
||||
return newMercedesFromConfig("mercedes", other)
|
||||
})
|
||||
registry.Add("smart-eq", func(other map[string]interface{}) (api.Vehicle, error) {
|
||||
return newMercedesFromConfig("smart-eq", other)
|
||||
})
|
||||
}
|
||||
|
||||
// NewMercedesFromConfig creates a new vehicle
|
||||
func NewMercedesFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
||||
// newMercedesFromConfig creates a new vehicle
|
||||
func newMercedesFromConfig(brand string, other map[string]interface{}) (api.Vehicle, error) {
|
||||
cc := struct {
|
||||
embed `mapstructure:",squash"`
|
||||
Tokens Tokens
|
||||
|
|
@ -45,21 +51,28 @@ func NewMercedesFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
|||
cc.User = cc.Account_
|
||||
}
|
||||
|
||||
log := util.NewLogger("mercedes").Redact(cc.Tokens.Access, cc.Tokens.Refresh)
|
||||
log := util.NewLogger(brand).Redact(cc.Tokens.Access, cc.Tokens.Refresh)
|
||||
identity, err := mercedes.NewIdentity(log, token, cc.User, cc.Region)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v := &Mercedes{
|
||||
embed: &cc.embed,
|
||||
}
|
||||
|
||||
api := mercedes.NewAPI(log, identity)
|
||||
|
||||
cc.VIN, err = ensureVehicle(cc.VIN, api.Vehicles)
|
||||
if err == nil {
|
||||
v.Provider = mercedes.NewProvider(api, cc.VIN, cc.Cache)
|
||||
if brand == "smart-eq" {
|
||||
if cc.VIN == "" {
|
||||
return nil, errors.New("missing VIN")
|
||||
}
|
||||
} else {
|
||||
cc.VIN, err = ensureVehicle(cc.VIN, api.Vehicles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
v := &Mercedes{
|
||||
embed: &cc.embed,
|
||||
Provider: mercedes.NewProvider(api, cc.VIN, cc.Cache),
|
||||
}
|
||||
|
||||
return v, err
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
package vehicle
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/vehicle/mb"
|
||||
"github.com/evcc-io/evcc/vehicle/smart"
|
||||
)
|
||||
|
||||
// Smart is an api.Vehicle implementation for Smart cars
|
||||
type Smart struct {
|
||||
*embed
|
||||
*smart.Provider
|
||||
}
|
||||
|
||||
func init() {
|
||||
registry.Add("smart", NewSmartFromConfig)
|
||||
}
|
||||
|
||||
// NewSmartFromConfig creates a new vehicle
|
||||
func NewSmartFromConfig(other map[string]interface{}) (api.Vehicle, error) {
|
||||
cc := struct {
|
||||
embed `mapstructure:",squash"`
|
||||
User, Password string
|
||||
VIN string
|
||||
Expiry time.Duration
|
||||
Cache time.Duration
|
||||
}{
|
||||
Expiry: expiry,
|
||||
Cache: interval,
|
||||
}
|
||||
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cc.User == "" || cc.Password == "" {
|
||||
return nil, api.ErrMissingCredentials
|
||||
}
|
||||
|
||||
log := util.NewLogger("smart").Redact(cc.User, cc.Password, cc.VIN)
|
||||
|
||||
v := &Smart{
|
||||
embed: &cc.embed,
|
||||
}
|
||||
|
||||
identity := mb.NewIdentity(log, smart.OAuth2Config)
|
||||
err := identity.Login(cc.User, cc.Password)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("login failed: %w", err)
|
||||
}
|
||||
|
||||
api := smart.NewAPI(log, identity)
|
||||
|
||||
cc.VIN, err = ensureVehicle(cc.VIN, api.Vehicles)
|
||||
|
||||
if err == nil {
|
||||
v.Provider = smart.NewProvider(log, api, cc.VIN, cc.Expiry, cc.Cache)
|
||||
}
|
||||
|
||||
return v, err
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue