BMW: fix api (#8713)
Some checks failed
Release / call-build-workflow (push) Has been cancelled
Release / Publish Docker :release (push) Has been cancelled
Release / Github & APT (push) Has been cancelled
Release / Demo (push) Has been cancelled
Release / Hassio Addon (push) Has been cancelled

This commit is contained in:
andig 2023-06-30 10:50:49 +02:00 • committed by GitHub
parent 39cf877b13
commit c552fd1be0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 89 deletions

View file

@ -5,7 +5,6 @@ import (
"net/http"
"time"
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/request"
"golang.org/x/oauth2"
@ -15,7 +14,6 @@ import (
// https://github.com/TA2k/ioBroker.bmw
const (
ApiURI = "https://b2vapi.bmwgroup.com/webapi/v1"
CocoApiURI = "https://cocoapi.bmwgroup.com"
)
@ -41,30 +39,25 @@ func NewAPI(log *util.Logger, brand string, identity oauth2.TokenSource) *API {
return v
}
func (v *API) eadrax() (VehiclesStatusResponse, error) {
var res VehiclesStatusResponse
uri := fmt.Sprintf("%s/eadrax-vcs/v1/vehicles?apptimezone=120&appDateTime=%d", CocoApiURI, time.Now().UnixMilli())
// Vehicles implements returns the /user/vehicles api
func (v *API) Vehicles() ([]string, error) {
var res []Vehicle
uri := fmt.Sprintf("%s/eadrax-vcs/v4/vehicles?apptimezone=120&appDateTime=%d", CocoApiURI, time.Now().UnixMilli())
req, err := request.New(http.MethodGet, uri, nil, map[string]string{
"Content-Type": request.JSONContent,
"X-User-Agent": v.xUserAgent,
})
if err == nil {
err = v.DoJSON(req, &res)
}
return res, err
}
// Vehicles implements returns the /user/vehicles api
func (v *API) Vehicles() ([]string, error) {
resp, err := v.eadrax()
if err != nil {
return nil, err
}
if err := v.DoJSON(req, &res); err != nil {
return nil, err
}
var vehicles []string
for _, v := range resp {
for _, v := range res {
vehicles = append(vehicles, v.VIN)
}
@ -73,16 +66,17 @@ func (v *API) Vehicles() ([]string, error) {
// Status implements the /user/vehicles/<vin>/status api
func (v *API) Status(vin string) (VehicleStatus, error) {
resp, err := v.eadrax()
if err == nil {
for _, res := range resp {
if res.VIN == vin {
return res, nil
}
}
var res VehicleStatus
uri := fmt.Sprintf("%s/eadrax-vcs/v4/vehicles/state?apptimezone=120&appDateTime=%d", CocoApiURI, time.Now().UnixMilli())
err = api.ErrNotAvailable
req, err := request.New(http.MethodGet, uri, nil, map[string]string{
"Content-Type": request.JSONContent,
"X-User-Agent": v.xUserAgent,
"bmw-vin": vin,
})
if err == nil {
err = v.DoJSON(req, &res)
}
return VehicleStatus{}, err
return res, err
}

View file

@ -7,8 +7,6 @@ import (
"github.com/evcc-io/evcc/provider"
)
const kmPerMile = 1.609344
// Provider implements the vehicle api
type Provider struct {
statusG func() (VehicleStatus, error)
@ -29,15 +27,11 @@ var _ api.Battery = (*Provider)(nil)
// Soc implements the api.Vehicle interface
func (v *Provider) Soc() (float64, error) {
res, err := v.statusG()
if err == nil {
if cs := res.Properties.ChargingState; cs != nil {
return float64(cs.ChargePercentage), nil
}
err = api.ErrNotAvailable
if err != nil {
return 0, err
}
return 0, err
return float64(res.State.ElectricChargingState.ChargingLevelPercent), nil
}
var _ api.ChargeState = (*Provider)(nil)
@ -45,24 +39,19 @@ var _ api.ChargeState = (*Provider)(nil)
// Status implements the api.ChargeState interface
func (v *Provider) Status() (api.ChargeStatus, error) {
res, err := v.statusG()
if err == nil {
if cs := res.Properties.ChargingState; cs != nil {
status := api.StatusA // disconnected
if cs.IsChargerConnected {
status = api.StatusB
}
if cs.State == "CHARGING" {
status = api.StatusC
}
return status, nil
}
err = api.ErrNotAvailable
if err != nil {
return api.StatusNone, err
}
return api.StatusNone, err
status := api.StatusA // disconnected
if res.State.ElectricChargingState.IsChargerConnected {
status = api.StatusB
}
if res.State.ElectricChargingState.ChargingStatus == "CHARGING" {
status = api.StatusC
}
return status, nil
}
// var _ api.VehicleFinishTimer = (*Provider)(nil)
@ -83,15 +72,11 @@ var _ api.VehicleRange = (*Provider)(nil)
// Range implements the api.VehicleRange interface
func (v *Provider) Range() (int64, error) {
res, err := v.statusG()
if err == nil {
if er := res.Properties.ElectricRange; er != nil {
return int64(er.Distance.Value), nil
}
err = api.ErrNotAvailable
if err != nil {
return 0, err
}
return 0, err
return res.State.ElectricChargingState.Range, nil
}
var _ api.VehicleOdometer = (*Provider)(nil)
@ -99,13 +84,9 @@ var _ api.VehicleOdometer = (*Provider)(nil)
// Odometer implements the api.VehicleOdometer interface
func (v *Provider) Odometer() (float64, error) {
res, err := v.statusG()
if err == nil {
if cm := res.Status.CurrentMileage; cm != nil {
return float64(cm.Mileage) * kmPerMile, nil
}
err = api.ErrNotAvailable
if err != nil {
return 0, err
}
return 0, err
return float64(res.State.CurrentMileage), nil
}

View file

@ -1,34 +1,21 @@
package bmw
type VehiclesResponse struct {
Vehicles []Vehicle
}
type Vehicle struct {
VIN string
Model string
VIN string
Model string
AppVehicleType string
}
type VehiclesStatusResponse []VehicleStatus
type VehicleStatus struct {
VIN, Model, Brand string
Year int
Properties struct {
ChargingState *struct {
ChargePercentage int
State string // CHARGING, ERROR, FINISHED_FULLY_CHARGED, FINISHED_NOT_FULL, INVALID, NOT_CHARGING, WAITING_FOR_CHARGING, COMPLETED
IsChargerConnected bool
}
ElectricRange *struct {
Distance struct {
Value int
}
}
}
Status struct {
CurrentMileage *struct {
Mileage int
State struct {
CurrentMileage int64
Range int64
ElectricChargingState struct {
ChargingLevelPercent int64
Range int64
IsChargerConnected bool
ChargingStatus string
ChargingTarget int64
}
}
}