Skoda Enyaq: add start/stop charger command (#1905)

This commit is contained in:
andig 2021-11-20 17:05:10 +01:00 • committed by GitHub
parent a7f563d004
commit c19f279484
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 67 deletions

View file

@ -58,7 +58,8 @@ func decodeJSON(resp *http.Response, res interface{}) error {
return json.NewDecoder(resp.Body).Decode(&res)
}
// DoJSON executes HTTP request and decodes JSON response. It returns a StatusError on response codes other than HTTP 2xx.
// DoJSON executes HTTP request and decodes JSON response.
// It returns a StatusError on response codes other than HTTP 2xx.
func (r *Helper) DoJSON(req *http.Request, res interface{}) error {
resp, err := r.Do(req)
if err == nil {
@ -68,12 +69,12 @@ func (r *Helper) DoJSON(req *http.Request, res interface{}) error {
return err
}
// GetJSON executes HTTP GET request and decodes JSON response. It returns a StatusError on response codes other than HTTP 2xx.
// GetJSON executes HTTP GET request and decodes JSON response.
// It returns a StatusError on response codes other than HTTP 2xx.
func (r *Helper) GetJSON(url string, res interface{}) error {
resp, err := r.Get(url)
req, err := New(http.MethodGet, url, nil, AcceptJSON)
if err == nil {
defer resp.Body.Close()
err = decodeJSON(resp, &res)
err = r.DoJSON(req, &res)
}
return err
}

View file

@ -30,36 +30,12 @@ func NewAPI(log *util.Logger, ts oauth2.TokenSource) *API {
return v
}
func (v *API) getJSON(uri string, res interface{}) error {
req, err := request.New(http.MethodGet, uri, nil, request.AcceptJSON)
if err == nil {
err = v.DoJSON(req, &res)
}
return err
}
// Vehicle is the /v2/garage/vehicles api
type Vehicle struct {
ID, VIN string
LastUpdatedAt string
Specification struct {
Title, Brand, Model string
Battery struct {
CapacityInKWh int
}
}
// Connectivities
// Capabilities
}
// Vehicles implements the /vehicles response
func (v *API) Vehicles() ([]string, error) {
var res []Vehicle
var res VehiclesResponse
uri := fmt.Sprintf("%s/v2/garage/vehicles", BaseURI)
err := v.getJSON(uri, &res)
err := v.GetJSON(uri, &res)
var vehicles []string
if err == nil {
@ -71,30 +47,36 @@ func (v *API) Vehicles() ([]string, error) {
return vehicles, err
}
// ChargerResponse is the /v1/charging/<vin>/status api
type ChargerResponse struct {
Plug struct {
ConnectionState string // Connected
LockState string // Unlocked
}
Charging struct {
State string // Error
RemainingToCompleteInSeconds int64
ChargingPowerInWatts float64
ChargingRateInKilometersPerHour float64
ChargingType string // Invalid
ChargeMode string // MANUAL
}
Battery struct {
CruisingRangeElectricInMeters int64
StateOfChargeInPercent int
}
}
// Charger implements the /v1/charging/<vin>/status response
func (v *API) Charger(vin string) (ChargerResponse, error) {
var res ChargerResponse
uri := fmt.Sprintf("%s/v1/charging/%s/status", BaseURI, vin)
err := v.getJSON(uri, &res)
err := v.GetJSON(uri, &res)
return res, err
}
const (
ActionCharge = "charging"
ActionChargeStart = "Start"
ActionChargeStop = "Stop"
)
// Action executes a vehicle action
func (v *API) Action(vin, action, value string) error {
var res map[string]interface{}
uri := fmt.Sprintf("%s/v1/%s/operation-requests?vin=%s", BaseURI, action, vin)
data := struct {
Typ string `json:"type"`
}{
Typ: value,
}
req, err := request.New(http.MethodPost, uri, request.MarshalJSON(data), request.JSONEncoding)
if err == nil {
// {"id":"61991908906fa40af9a5cba4","status":"InProgress","deeplink":""}
err = v.DoJSON(req, &res)
}
return err
}

View file

@ -10,8 +10,7 @@ import (
// Provider implements the evcc vehicle api
type Provider struct {
chargerG func() (interface{}, error)
// climateG func() (interface{}, error)
// action func(action, value string) error
action func(action, value string) error
}
// NewProvider provides the evcc vehicle api provider
@ -23,9 +22,9 @@ func NewProvider(api *API, vin string, cache time.Duration) *Provider {
// climateG: provider.NewCached(func() (interface{}, error) {
// return api.Climater(vin)
// }, cache).InterfaceGetter(),
// action: func(action, value string) error {
// return api.Action(vin, action, value)
// },
action: func(action, value string) error {
return api.Action(vin, action, value)
},
}
return impl
}
@ -114,16 +113,16 @@ func (v *Provider) Range() (rng int64, err error) {
// return active, outsideTemp, targetTemp, err
// }
// var _ api.VehicleStartCharge = (*Provider)(nil)
var _ api.VehicleStartCharge = (*Provider)(nil)
// // StartCharge implements the api.VehicleStartCharge interface
// func (v *Provider) StartCharge() error {
// return v.action(ActionCharge, ActionChargeStart)
// }
// StartCharge implements the api.VehicleStartCharge interface
func (v *Provider) StartCharge() error {
return v.action(ActionCharge, ActionChargeStart)
}
// var _ api.VehicleStopCharge = (*Provider)(nil)
var _ api.VehicleStopCharge = (*Provider)(nil)
// // StopCharge implements the api.VehicleStopCharge interface
// func (v *Provider) StopCharge() error {
// return v.action(ActionCharge, ActionChargeStop)
// }
// StopCharge implements the api.VehicleStopCharge interface
func (v *Provider) StopCharge() error {
return v.action(ActionCharge, ActionChargeStop)
}

37
vehicle/skoda/types.go Normal file
View file

@ -0,0 +1,37 @@
package skoda
// VehiclesResponse is the /v2/garage/vehicles api
type VehiclesResponse []Vehicle
type Vehicle struct {
ID, VIN string
LastUpdatedAt string
Specification struct {
Title, Brand, Model string
Battery struct {
CapacityInKWh int
}
}
// Connectivities
// Capabilities
}
// ChargerResponse is the /v1/charging/<vin>/status api
type ChargerResponse struct {
Plug struct {
ConnectionState string // Connected
LockState string // Unlocked
}
Charging struct {
State string // Error
RemainingToCompleteInSeconds int64
ChargingPowerInWatts float64
ChargingRateInKilometersPerHour float64
ChargingType string // Invalid
ChargeMode string // MANUAL
}
Battery struct {
CruisingRangeElectricInMeters int64
StateOfChargeInPercent int
}
}