evcc-io/vehicle/bmw/api.go
2022-03-03 19:41:05 +01:00

88 lines
1.9 KiB
Go

package bmw
import (
"fmt"
"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"
)
// https://github.com/bimmerconnected/bimmer_connected
// https://github.com/TA2k/ioBroker.bmw
const (
ApiURI = "https://b2vapi.bmwgroup.com/webapi/v1"
CocoApiURI = "https://cocoapi.bmwgroup.com"
)
// API is an api.Vehicle implementation for BMW cars
type API struct {
*request.Helper
xUserAgent string
}
// NewAPI creates a new vehicle
func NewAPI(log *util.Logger, brand string, identity oauth2.TokenSource) *API {
v := &API{
Helper: request.NewHelper(log),
xUserAgent: fmt.Sprintf("android(v1.07_20200330);%s;1.7.0(11152)", brand),
}
// replace client transport with authenticated transport
v.Client.Transport = &oauth2.Transport{
Source: identity,
Base: v.Client.Transport,
}
return v
}
func (v *API) eadrax() (VehiclesStatusResponse, error) {
var res VehiclesStatusResponse
uri := fmt.Sprintf("%s/eadrax-vcs/v1/vehicles?apptimezone=60&appDateTime=%d", CocoApiURI, time.Now().Unix())
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
}
var vehicles []string
for _, v := range resp {
vehicles = append(vehicles, v.VIN)
}
return vehicles, err
}
// 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
}
}
err = api.ErrNotAvailable
}
return VehicleStatus{}, err
}