diff --git a/templates/definition/vehicle/dacia.yaml b/templates/definition/vehicle/dacia.yaml index 6b1425c544..1120e2d31e 100644 --- a/templates/definition/vehicle/dacia.yaml +++ b/templates/definition/vehicle/dacia.yaml @@ -8,7 +8,7 @@ params: default: 27.4 - preset: vehiclecloud render: | - type: renault + type: dacia {{ include "vehicle-base" . }} {{ include "vehicle-identify" . }} {{ include "vehicle-cloud" . }} diff --git a/vehicle/renault.go b/vehicle/renault.go index 2cf49419ef..b9734743f7 100644 --- a/vehicle/renault.go +++ b/vehicle/renault.go @@ -1,7 +1,6 @@ package vehicle import ( - "errors" "time" "github.com/evcc-io/evcc/api" @@ -26,12 +25,16 @@ type Renault struct { } func init() { - registry.Add("dacia", NewRenaultFromConfig) - registry.Add("renault", NewRenaultFromConfig) + registry.Add("dacia", func(other map[string]interface{}) (api.Vehicle, error) { + return NewRenaultDaciaFromConfig("dacia", other) + }) + registry.Add("renault", func(other map[string]interface{}) (api.Vehicle, error) { + return NewRenaultDaciaFromConfig("renault", other) + }) } -// NewRenaultFromConfig creates a new vehicle -func NewRenaultFromConfig(other map[string]interface{}) (api.Vehicle, error) { +// NewRenaultDaciaFromConfig creates a new Renault/Dacia vehicle +func NewRenaultDaciaFromConfig(brand string, other map[string]interface{}) (api.Vehicle, error) { cc := struct { embed `mapstructure:",squash"` User, Password, Region, VIN string @@ -45,7 +48,7 @@ func NewRenaultFromConfig(other map[string]interface{}) (api.Vehicle, error) { return nil, err } - log := util.NewLogger("renault").Redact(cc.User, cc.Password, cc.VIN) + log := util.NewLogger(brand).Redact(cc.User, cc.Password, cc.VIN) v := &Renault{ embed: &cc.embed, @@ -63,10 +66,7 @@ func NewRenaultFromConfig(other map[string]interface{}) (api.Vehicle, error) { return identity.Login(cc.User, cc.Password) }) - accountID, err := api.Person(identity.PersonID) - if err == nil && accountID == "" { - return nil, errors.New("missing accountID") - } + accountID, err := api.Person(identity.PersonID, brand) var car kamereon.Vehicle if err == nil { diff --git a/vehicle/renault/kamereon/api.go b/vehicle/renault/kamereon/api.go index 0b47411068..8c64d2dcdd 100644 --- a/vehicle/renault/kamereon/api.go +++ b/vehicle/renault/kamereon/api.go @@ -1,10 +1,12 @@ package kamereon import ( + "errors" "fmt" "io" "net/http" "net/url" + "strings" "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/request" @@ -62,15 +64,20 @@ func (v *API) request(uri string, body io.Reader) (Response, error) { return res, err } -func (v *API) Person(personID string) (string, error) { +func (v *API) Person(personID, brand string) (string, error) { uri := fmt.Sprintf("%s/commerce/v1/persons/%s", v.keys.Target, personID) res, err := v.request(uri, nil) - - if len(res.Accounts) == 0 { + if err != nil { return "", err } - return res.Accounts[0].AccountID, err + for _, account := range res.Accounts { + if strings.Contains(strings.ToLower(account.AccountType), strings.ToLower(brand)) { + return account.AccountID, nil + } + } + + return "", errors.New("account not found") } func (v *API) Vehicles(accountID string) ([]Vehicle, error) { diff --git a/vehicle/renault/kamereon/types.go b/vehicle/renault/kamereon/types.go index f996a92c0d..d612d9ae78 100644 --- a/vehicle/renault/kamereon/types.go +++ b/vehicle/renault/kamereon/types.go @@ -6,14 +6,18 @@ import ( ) type Response struct { - Accounts []Account `json:"accounts"` // /commerce/v1/persons/%s - AccessToken string `json:"accessToken"` // /commerce/v1/accounts/%s/kamereon/token - VehicleLinks []Vehicle `json:"vehicleLinks"` // /commerce/v1/accounts/%s/vehicles - Data Data `json:"data"` // /commerce/v1/accounts/%s/kamereon/kca/car-adapter/vX/cars/%s/... + Accounts []Account // /commerce/v1/persons/%s + AccessToken string // /commerce/v1/accounts/%s/kamereon/token + VehicleLinks []Vehicle // /commerce/v1/accounts/%s/vehicles + Data Data // /commerce/v1/accounts/%s/kamereon/kca/car-adapter/vX/cars/%s/... } type Account struct { - AccountID string `json:"accountId"` + AccountID string + AccountType string + AccountStatus string + Country string + RelationType string } type Vehicle struct { @@ -23,24 +27,24 @@ type Vehicle struct { ConnectedDriver connectedDriver } +type connectedDriver struct { + Role string +} + func (v *Vehicle) Available() error { if strings.ToUpper(v.Status) != "ACTIVE" { return errors.New("vehicle is not active") } - if len(v.ConnectedDriver.Role) == 0 { + if v.ConnectedDriver.Role == "" { return errors.New("vehicle is not connected to driver") } return nil } -type connectedDriver struct { - Role string `json:"role"` -} - type Data struct { - Attributes attributes `json:"attributes"` + Attributes attributes } type attributes struct {