evcc-io/vehicle/polestar/api.go
2024-02-11 14:15:18 +01:00

78 lines
1.8 KiB
Go

package polestar
import (
"context"
"net/http"
"net/url"
"strings"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/request"
"github.com/hasura/go-graphql-client"
"golang.org/x/oauth2"
)
// https://github.com/leeyuentuen/polestar_api
// https://github.com/TA2k/ioBroker.polestar
const (
ApiURI = "https://pc-api.polestar.com/eu-north-1"
ApiURIv1 = ApiURI + "/my-star"
ApiURIv2 = ApiURI + "/mystar-v2"
)
type API struct {
client *graphql.Client
}
func NewAPI(log *util.Logger, identity oauth2.TokenSource) *API {
httpClient := request.NewClient(log)
// replace client transport with authenticated transport
httpClient.Transport = &oauth2.Transport{
Base: httpClient.Transport,
Source: identity,
}
v := &API{
client: graphql.NewClient(ApiURIv2, httpClient),
}
return v
}
func (v *API) Vehicles(ctx context.Context) ([]ConsumerCar, error) {
var res struct {
GetConsumerCarsV2 []ConsumerCar `graphql:"getConsumerCarsV2"`
}
err := v.client.WithRequestModifier(func(req *http.Request) {
req.URL, _ = url.Parse(strings.ReplaceAll(req.URL.String(), "mystar-v2", "my-star"))
}).Query(ctx, &res, nil, graphql.OperationName("getCars"))
return res.GetConsumerCarsV2, err
}
func (v *API) Status(ctx context.Context, vin string) (BatteryData, error) {
var res struct {
BatteryData `graphql:"getBatteryData(vin: $vin)"`
}
err := v.client.Query(ctx, &res, map[string]any{
"vin": vin,
}, graphql.OperationName("GetBatteryData"))
return res.BatteryData, err
}
func (v *API) Odometer(ctx context.Context, vin string) (OdometerData, error) {
var res struct {
OdometerData `graphql:"getOdometerData(vin: $vin)"`
}
err := v.client.Query(ctx, &res, map[string]any{
"vin": vin,
}, graphql.OperationName("GetOdometerData"))
return res.OdometerData, err
}