Tronity: honor vehicle capabilities (#1754)

This commit is contained in:
andig 2021-10-18 11:48:34 +02:00 • committed by GitHub
parent 0a2a4c3e48
commit 0bb836fd36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 328 additions and 22 deletions

View file

@ -32,6 +32,7 @@ import (
"github.com/evcc-io/evcc/util/request"
"github.com/evcc-io/evcc/util/sponsor"
"github.com/evcc-io/evcc/vehicle/tronity"
"github.com/thoas/go-funk"
"golang.org/x/oauth2"
)
@ -49,6 +50,8 @@ func init() {
registry.Add("tronity", NewTronityFromConfig)
}
//go:generate go run ../cmd/tools/decorate.go -f decorateTronity -b *Tronity -r api.Vehicle -t "api.ChargeState,Status,func() (api.ChargeStatus, error)" -t "api.VehicleOdometer,Odometer,func() (float64, error)" -t "api.VehicleStartCharge,StartCharge,func() error" -t "api.VehicleStopCharge,StopCharge,func() error"
// NewTronityFromConfig creates a new vehicle
func NewTronityFromConfig(other map[string]interface{}) (api.Vehicle, error) {
cc := struct {
@ -115,23 +118,41 @@ func NewTronityFromConfig(other map[string]interface{}) (api.Vehicle, error) {
return nil, err
}
var vehicle tronity.Vehicle
if cc.VIN == "" && len(vehicles) == 1 {
v.vid = vehicles[0].ID
vehicle = vehicles[0]
} else {
for _, vehicle := range vehicles {
if vehicle.VIN == strings.ToUpper(cc.VIN) {
v.vid = vehicle.ID
for _, v := range vehicles {
if v.VIN == strings.ToUpper(cc.VIN) {
vehicle = v
}
}
}
if v.vid == "" {
if vehicle.ID == "" {
return nil, errors.New("vin not found")
}
v.vid = vehicle.ID
v.bulkG = provider.NewCached(v.bulk, cc.Cache).InterfaceGetter()
return v, nil
var status func() (api.ChargeStatus, error)
if funk.ContainsString(vehicle.Scopes, tronity.ReadCharge) {
status = v.status
}
var odometer func() (float64, error)
if funk.ContainsString(vehicle.Scopes, tronity.ReadOdometer) {
odometer = v.odometer
}
var start, stop func() error
if funk.ContainsString(vehicle.Scopes, tronity.WriteChargeStartStop) {
start = v.startCharge
stop = v.stopCharge
}
return decorateTronity(v, status, odometer, start, stop), nil
}
// RefreshToken performs token refresh by logging in with app context
@ -188,10 +209,8 @@ func (v *Tronity) SoC() (float64, error) {
return 0, err
}
var _ api.ChargeState = (*Tronity)(nil)
// Status implements the api.ChargeState interface
func (v *Tronity) Status() (api.ChargeStatus, error) {
// status implements the api.ChargeState interface
func (v *Tronity) status() (api.ChargeStatus, error) {
status := api.StatusA // disconnected
res, err := v.bulkG()
@ -217,10 +236,8 @@ func (v *Tronity) Range() (int64, error) {
return 0, err
}
var _ api.VehicleOdometer = (*Tronity)(nil)
// Odometer implements the api.VehicleOdometer interface
func (v *Tronity) Odometer() (float64, error) {
// odometer implements the api.VehicleOdometer interface
func (v *Tronity) odometer() (float64, error) {
res, err := v.bulkG()
if res, ok := res.(tronity.Bulk); err == nil && ok {
@ -246,18 +263,14 @@ func (v *Tronity) post(uri string) error {
return err
}
var _ api.VehicleStartCharge = (*Tronity)(nil)
// StartCharge implements the api.VehicleStartCharge interface
func (v *Tronity) StartCharge() error {
// startCharge implements the api.VehicleStartCharge interface
func (v *Tronity) startCharge() error {
uri := fmt.Sprintf("%s/v1/vehicles/%s/charge_start", tronity.URI, v.vid)
return v.post(uri)
}
var _ api.VehicleStopCharge = (*Tronity)(nil)
// StopCharge implements the api.VehicleStopCharge interface
func (v *Tronity) StopCharge() error {
// stopCharge implements the api.VehicleStopCharge interface
func (v *Tronity) stopCharge() error {
uri := fmt.Sprintf("%s/v1/vehicles/%s/charge_stop", tronity.URI, v.vid)
return v.post(uri)
}

View file

@ -2,6 +2,17 @@ package tronity
// https://app.platform.tronity.io/docs#operation
const (
ReadBattery = "read_battery" // Read EV battery's capacity and state of charge
ReadCharge = "read_charge" // Know whether vehicle is charging
ReadLocation = "read_location" // Access location
ReadOdometer = "read_odometer" // Retrieve total distance traveled
ReadVehicleInfo = "read_vehicle_info" // Know make, model, and year
ReadVIN = "read_vin" // Read VIN
WriteChargeStartStop = "write_charge_start_stop" // Start or stop your vehicle's charging
WriteWakeUp = "write_wake_up" // Wake up car. Only valid for Tesla
)
type Vehicles struct {
Data []Vehicle
}
@ -11,6 +22,7 @@ type Vehicle struct {
VIN string
DisplayName string
Manufacture string
Scopes []string
}
type Bulk struct {

View file

@ -0,0 +1,281 @@
package vehicle
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"github.com/evcc-io/evcc/api"
)
func decorateTronity(base *Tronity, chargeState func() (api.ChargeStatus, error), vehicleOdometer func() (float64, error), vehicleStartCharge func() error, vehicleStopCharge func() error) api.Vehicle {
switch {
case chargeState == nil && vehicleOdometer == nil && vehicleStartCharge == nil && vehicleStopCharge == nil:
return base
case chargeState != nil && vehicleOdometer == nil && vehicleStartCharge == nil && vehicleStopCharge == nil:
return &struct {
*Tronity
api.ChargeState
}{
Tronity: base,
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
}
case chargeState == nil && vehicleOdometer != nil && vehicleStartCharge == nil && vehicleStopCharge == nil:
return &struct {
*Tronity
api.VehicleOdometer
}{
Tronity: base,
VehicleOdometer: &decorateTronityVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
}
case chargeState != nil && vehicleOdometer != nil && vehicleStartCharge == nil && vehicleStopCharge == nil:
return &struct {
*Tronity
api.ChargeState
api.VehicleOdometer
}{
Tronity: base,
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
VehicleOdometer: &decorateTronityVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
}
case chargeState == nil && vehicleOdometer == nil && vehicleStartCharge != nil && vehicleStopCharge == nil:
return &struct {
*Tronity
api.VehicleStartCharge
}{
Tronity: base,
VehicleStartCharge: &decorateTronityVehicleStartChargeImpl{
vehicleStartCharge: vehicleStartCharge,
},
}
case chargeState != nil && vehicleOdometer == nil && vehicleStartCharge != nil && vehicleStopCharge == nil:
return &struct {
*Tronity
api.ChargeState
api.VehicleStartCharge
}{
Tronity: base,
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
VehicleStartCharge: &decorateTronityVehicleStartChargeImpl{
vehicleStartCharge: vehicleStartCharge,
},
}
case chargeState == nil && vehicleOdometer != nil && vehicleStartCharge != nil && vehicleStopCharge == nil:
return &struct {
*Tronity
api.VehicleOdometer
api.VehicleStartCharge
}{
Tronity: base,
VehicleOdometer: &decorateTronityVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
VehicleStartCharge: &decorateTronityVehicleStartChargeImpl{
vehicleStartCharge: vehicleStartCharge,
},
}
case chargeState != nil && vehicleOdometer != nil && vehicleStartCharge != nil && vehicleStopCharge == nil:
return &struct {
*Tronity
api.ChargeState
api.VehicleOdometer
api.VehicleStartCharge
}{
Tronity: base,
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
VehicleOdometer: &decorateTronityVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
VehicleStartCharge: &decorateTronityVehicleStartChargeImpl{
vehicleStartCharge: vehicleStartCharge,
},
}
case chargeState == nil && vehicleOdometer == nil && vehicleStartCharge == nil && vehicleStopCharge != nil:
return &struct {
*Tronity
api.VehicleStopCharge
}{
Tronity: base,
VehicleStopCharge: &decorateTronityVehicleStopChargeImpl{
vehicleStopCharge: vehicleStopCharge,
},
}
case chargeState != nil && vehicleOdometer == nil && vehicleStartCharge == nil && vehicleStopCharge != nil:
return &struct {
*Tronity
api.ChargeState
api.VehicleStopCharge
}{
Tronity: base,
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
VehicleStopCharge: &decorateTronityVehicleStopChargeImpl{
vehicleStopCharge: vehicleStopCharge,
},
}
case chargeState == nil && vehicleOdometer != nil && vehicleStartCharge == nil && vehicleStopCharge != nil:
return &struct {
*Tronity
api.VehicleOdometer
api.VehicleStopCharge
}{
Tronity: base,
VehicleOdometer: &decorateTronityVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
VehicleStopCharge: &decorateTronityVehicleStopChargeImpl{
vehicleStopCharge: vehicleStopCharge,
},
}
case chargeState != nil && vehicleOdometer != nil && vehicleStartCharge == nil && vehicleStopCharge != nil:
return &struct {
*Tronity
api.ChargeState
api.VehicleOdometer
api.VehicleStopCharge
}{
Tronity: base,
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
VehicleOdometer: &decorateTronityVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
VehicleStopCharge: &decorateTronityVehicleStopChargeImpl{
vehicleStopCharge: vehicleStopCharge,
},
}
case chargeState == nil && vehicleOdometer == nil && vehicleStartCharge != nil && vehicleStopCharge != nil:
return &struct {
*Tronity
api.VehicleStartCharge
api.VehicleStopCharge
}{
Tronity: base,
VehicleStartCharge: &decorateTronityVehicleStartChargeImpl{
vehicleStartCharge: vehicleStartCharge,
},
VehicleStopCharge: &decorateTronityVehicleStopChargeImpl{
vehicleStopCharge: vehicleStopCharge,
},
}
case chargeState != nil && vehicleOdometer == nil && vehicleStartCharge != nil && vehicleStopCharge != nil:
return &struct {
*Tronity
api.ChargeState
api.VehicleStartCharge
api.VehicleStopCharge
}{
Tronity: base,
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
VehicleStartCharge: &decorateTronityVehicleStartChargeImpl{
vehicleStartCharge: vehicleStartCharge,
},
VehicleStopCharge: &decorateTronityVehicleStopChargeImpl{
vehicleStopCharge: vehicleStopCharge,
},
}
case chargeState == nil && vehicleOdometer != nil && vehicleStartCharge != nil && vehicleStopCharge != nil:
return &struct {
*Tronity
api.VehicleOdometer
api.VehicleStartCharge
api.VehicleStopCharge
}{
Tronity: base,
VehicleOdometer: &decorateTronityVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
VehicleStartCharge: &decorateTronityVehicleStartChargeImpl{
vehicleStartCharge: vehicleStartCharge,
},
VehicleStopCharge: &decorateTronityVehicleStopChargeImpl{
vehicleStopCharge: vehicleStopCharge,
},
}
case chargeState != nil && vehicleOdometer != nil && vehicleStartCharge != nil && vehicleStopCharge != nil:
return &struct {
*Tronity
api.ChargeState
api.VehicleOdometer
api.VehicleStartCharge
api.VehicleStopCharge
}{
Tronity: base,
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
VehicleOdometer: &decorateTronityVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
VehicleStartCharge: &decorateTronityVehicleStartChargeImpl{
vehicleStartCharge: vehicleStartCharge,
},
VehicleStopCharge: &decorateTronityVehicleStopChargeImpl{
vehicleStopCharge: vehicleStopCharge,
},
}
}
return nil
}
type decorateTronityChargeStateImpl struct {
chargeState func() (api.ChargeStatus, error)
}
func (impl *decorateTronityChargeStateImpl) Status() (api.ChargeStatus, error) {
return impl.chargeState()
}
type decorateTronityVehicleOdometerImpl struct {
vehicleOdometer func() (float64, error)
}
func (impl *decorateTronityVehicleOdometerImpl) Odometer() (float64, error) {
return impl.vehicleOdometer()
}
type decorateTronityVehicleStartChargeImpl struct {
vehicleStartCharge func() error
}
func (impl *decorateTronityVehicleStartChargeImpl) StartCharge() error {
return impl.vehicleStartCharge()
}
type decorateTronityVehicleStopChargeImpl struct {
vehicleStopCharge func() error
}
func (impl *decorateTronityVehicleStopChargeImpl) StopCharge() error {
return impl.vehicleStopCharge()
}