BMW: fix api (#8713)
Some checks failed
Some checks failed
This commit is contained in:
parent
39cf877b13
commit
c552fd1be0
3 changed files with 51 additions and 89 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue