Support waking up custom chargers/vehicles (#8005)

This commit is contained in:
Markus Heberling 2023-05-19 10:31:03 +02:00 • committed by GitHub
parent 13dd7d578e
commit 5adacb06c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 468 additions and 48 deletions

View file

@ -2,8 +2,10 @@ package api
import (
"context"
"fmt"
"io"
"net/http"
"strings"
"time"
)
@ -40,6 +42,18 @@ const (
StatusF ChargeStatus = "F" // Fzg. angeschlossen: ja Laden aktiv: nein - Fehler (Ausfall Wallbox)
)
// ChargeStatusString converts a string to ChargeStatus
func ChargeStatusString(s string) (ChargeStatus, error) {
switch strings.ToUpper(s) {
case "A", "B", "C":
return ChargeStatus(s), nil
case "D", "E", "F":
return ChargeStatus(s), fmt.Errorf("invalid status: %s", s)
default:
return StatusNone, fmt.Errorf("invalid status: %s", s)
}
}
// String implements Stringer
func (c ChargeStatus) String() string {
return string(c)

View file

@ -21,7 +21,7 @@ func init() {
registry.Add(api.Custom, NewConfigurableFromConfig)
}
// go:generate go run ../cmd/tools/decorate.go -f decorateCustom -b *Charger -r api.Charger -t "api.Identifier,Identify,func() (string, error)" -t "api.PhaseSwitcher,Phases1p3p,func(int) (error)"
// go:generate go run ../cmd/tools/decorate.go -f decorateCustom -b *Charger -r api.Charger -t "api.Identifier,Identify,func() (string, error)" -t "api.PhaseSwitcher,Phases1p3p,func(int) (error)" -t "api.Resurrector,WakeUp,func() (error)"
// NewConfigurableFromConfig creates a new configurable charger
func NewConfigurableFromConfig(other map[string]interface{}) (api.Charger, error) {
@ -29,6 +29,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Charger, error
embed `mapstructure:",squash"`
Status, Enable, Enabled, MaxCurrent provider.Config
Identify, Phases1p3p *provider.Config
Wakeup *provider.Config
}
if err := util.DecodeOther(other, &cc); err != nil {
@ -56,27 +57,48 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Charger, error
}
c, err := NewConfigurable(status, enabled, enable, maxcurrent)
if err != nil {
return nil, err
}
c.embed = &cc.embed
// decorator phases
var phases1p3p func(int) error
if err == nil && cc.Phases1p3p != nil {
var phases1p3pi64 func(int64) error
phases1p3pi64, err = provider.NewIntSetterFromConfig("phases", *cc.Phases1p3p)
if cc.Phases1p3p != nil {
phases1p3pS, err := provider.NewIntSetterFromConfig("phases", *cc.Phases1p3p)
if err != nil {
return nil, fmt.Errorf("phases: %w", err)
}
phases1p3p = func(phases int) error {
return phases1p3pi64(int64(phases))
return phases1p3pS(int64(phases))
}
}
// decorator identifier
var identify func() (string, error)
if err == nil && cc.Identify != nil {
if cc.Identify != nil {
identify, err = provider.NewStringGetterFromConfig(*cc.Identify)
if err != nil {
return nil, fmt.Errorf("identify: %w", err)
}
}
return decorateCustom(c, identify, phases1p3p), err
// decorate wakeup
var wakeup func() error
if cc.Wakeup != nil {
wakeupS, err := provider.NewBoolSetterFromConfig("wakeup", *cc.Wakeup)
if err != nil {
return nil, fmt.Errorf("wakeup: %w", err)
}
wakeup = func() error {
return wakeupS(true)
}
}
return decorateCustom(c, identify, phases1p3p, wakeup), nil
}
// NewConfigurable creates a new charger

View file

@ -6,12 +6,12 @@ import (
"github.com/evcc-io/evcc/api"
)
func decorateCustom(base *Charger, identifier func() (string, error), phaseSwitcher func(int) error) api.Charger {
func decorateCustom(base *Charger, identifier func() (string, error), phaseSwitcher func(int) error, resurrector func() error) api.Charger {
switch {
case identifier == nil && phaseSwitcher == nil:
case identifier == nil && phaseSwitcher == nil && resurrector == nil:
return base
case identifier != nil && phaseSwitcher == nil:
case identifier != nil && phaseSwitcher == nil && resurrector == nil:
return &struct {
*Charger
api.Identifier
@ -22,7 +22,7 @@ func decorateCustom(base *Charger, identifier func() (string, error), phaseSwitc
},
}
case identifier == nil && phaseSwitcher != nil:
case identifier == nil && phaseSwitcher != nil && resurrector == nil:
return &struct {
*Charger
api.PhaseSwitcher
@ -33,7 +33,7 @@ func decorateCustom(base *Charger, identifier func() (string, error), phaseSwitc
},
}
case identifier != nil && phaseSwitcher != nil:
case identifier != nil && phaseSwitcher != nil && resurrector == nil:
return &struct {
*Charger
api.Identifier
@ -47,6 +47,66 @@ func decorateCustom(base *Charger, identifier func() (string, error), phaseSwitc
phaseSwitcher: phaseSwitcher,
},
}
case identifier == nil && phaseSwitcher == nil && resurrector != nil:
return &struct {
*Charger
api.Resurrector
}{
Charger: base,
Resurrector: &decorateCustomResurrectorImpl{
resurrector: resurrector,
},
}
case identifier != nil && phaseSwitcher == nil && resurrector != nil:
return &struct {
*Charger
api.Identifier
api.Resurrector
}{
Charger: base,
Identifier: &decorateCustomIdentifierImpl{
identifier: identifier,
},
Resurrector: &decorateCustomResurrectorImpl{
resurrector: resurrector,
},
}
case identifier == nil && phaseSwitcher != nil && resurrector != nil:
return &struct {
*Charger
api.PhaseSwitcher
api.Resurrector
}{
Charger: base,
PhaseSwitcher: &decorateCustomPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
Resurrector: &decorateCustomResurrectorImpl{
resurrector: resurrector,
},
}
case identifier != nil && phaseSwitcher != nil && resurrector != nil:
return &struct {
*Charger
api.Identifier
api.PhaseSwitcher
api.Resurrector
}{
Charger: base,
Identifier: &decorateCustomIdentifierImpl{
identifier: identifier,
},
PhaseSwitcher: &decorateCustomPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
Resurrector: &decorateCustomResurrectorImpl{
resurrector: resurrector,
},
}
}
return nil
@ -67,3 +127,11 @@ type decorateCustomPhaseSwitcherImpl struct {
func (impl *decorateCustomPhaseSwitcherImpl) Phases1p3p(phases int) error {
return impl.phaseSwitcher(phases)
}
type decorateCustomResurrectorImpl struct {
resurrector func() error
}
func (impl *decorateCustomResurrectorImpl) WakeUp() error {
return impl.resurrector()
}

View file

@ -8,13 +8,12 @@ import (
"github.com/evcc-io/evcc/util"
)
//go:generate go run ../cmd/tools/decorate.go -f decorateVehicle -b api.Vehicle -t "api.ChargeState,Status,func() (api.ChargeStatus, error)" -t "api.VehicleRange,Range,func() (int64, error)" -t "api.VehicleOdometer,Odometer,func() (float64, error)" -t "api.VehicleClimater,Climater,func() (bool, error)"
//go:generate go run ../cmd/tools/decorate.go -f decorateVehicle -b api.Vehicle -t "api.ChargeState,Status,func() (api.ChargeStatus, error)" -t "api.VehicleRange,Range,func() (int64, error)" -t "api.VehicleOdometer,Odometer,func() (float64, error)" -t "api.VehicleClimater,Climater,func() (bool, error)" -t "api.Resurrector,WakeUp,func() (error)"
// Vehicle is an api.Vehicle implementation with configurable getters and setters.
type Vehicle struct {
*embed
socG func() (float64, error)
statusG func() (string, error)
socG func() (float64, error)
}
func init() {
@ -30,6 +29,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error
Range *provider.Config
Odometer *provider.Config
Climater *provider.Config
Wakeup *provider.Config
}
if err := util.DecodeOther(other, &cc); err != nil {
@ -49,11 +49,17 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error
// decorate vehicle with Status
var status func() (api.ChargeStatus, error)
if cc.Status != nil {
v.statusG, err = provider.NewStringGetterFromConfig(*cc.Status)
statusG, err := provider.NewStringGetterFromConfig(*cc.Status)
if err != nil {
return nil, fmt.Errorf("status: %w", err)
}
status = v.status
status = func() (api.ChargeStatus, error) {
s, err := statusG()
if err != nil {
return api.StatusNone, err
}
return api.ChargeStatusString(s)
}
}
// decorate vehicle with range
@ -86,24 +92,22 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Vehicle, error
climater = climateG
}
res := decorateVehicle(v, status, rng, odo, climater)
// decorate vehicle with wakeup
var wakeup func() error
if cc.Wakeup != nil {
wakeupS, err := provider.NewBoolSetterFromConfig("wakeup", *cc.Wakeup)
if err != nil {
return nil, fmt.Errorf("wakeup: %w", err)
}
wakeup = func() error {
return wakeupS(true)
}
}
return res, nil
return decorateVehicle(v, status, rng, odo, climater, wakeup), nil
}
// Soc implements the api.Vehicle interface
func (v *Vehicle) Soc() (float64, error) {
return v.socG()
}
// status implements the api.ChargeState interface
func (v *Vehicle) status() (api.ChargeStatus, error) {
status := api.StatusF
statusS, err := v.statusG()
if err == nil {
status = api.ChargeStatus(statusS)
}
return status, err
}

View file

@ -6,12 +6,12 @@ import (
"github.com/evcc-io/evcc/api"
)
func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, error), vehicleRange func() (int64, error), vehicleOdometer func() (float64, error), vehicleClimater func() (bool, error)) api.Vehicle {
func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, error), vehicleRange func() (int64, error), vehicleOdometer func() (float64, error), vehicleClimater func() (bool, error), resurrector func() error) api.Vehicle {
switch {
case chargeState == nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange == nil:
case chargeState == nil && resurrector == nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange == nil:
return base
case chargeState != nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange == nil:
case chargeState != nil && resurrector == nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.ChargeState
@ -22,7 +22,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState == nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange != nil:
case chargeState == nil && resurrector == nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.VehicleRange
@ -33,7 +33,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState != nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange != nil:
case chargeState != nil && resurrector == nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.ChargeState
@ -48,7 +48,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState == nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange == nil:
case chargeState == nil && resurrector == nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.VehicleOdometer
@ -59,7 +59,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState != nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange == nil:
case chargeState != nil && resurrector == nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.ChargeState
@ -74,7 +74,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState == nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange != nil:
case chargeState == nil && resurrector == nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.VehicleOdometer
@ -89,7 +89,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState != nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange != nil:
case chargeState != nil && resurrector == nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.ChargeState
@ -108,7 +108,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState == nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange == nil:
case chargeState == nil && resurrector == nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.VehicleClimater
@ -119,7 +119,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState != nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange == nil:
case chargeState != nil && resurrector == nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.ChargeState
@ -134,7 +134,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState == nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange != nil:
case chargeState == nil && resurrector == nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.VehicleClimater
@ -149,7 +149,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState != nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange != nil:
case chargeState != nil && resurrector == nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.ChargeState
@ -168,7 +168,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState == nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange == nil:
case chargeState == nil && resurrector == nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.VehicleClimater
@ -183,7 +183,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState != nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange == nil:
case chargeState != nil && resurrector == nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.ChargeState
@ -202,7 +202,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState == nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange != nil:
case chargeState == nil && resurrector == nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.VehicleClimater
@ -221,7 +221,7 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
},
}
case chargeState != nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange != nil:
case chargeState != nil && resurrector == nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.ChargeState
@ -243,6 +243,310 @@ func decorateVehicle(base api.Vehicle, chargeState func() (api.ChargeStatus, err
vehicleRange: vehicleRange,
},
}
case chargeState == nil && resurrector != nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.Resurrector
}{
Vehicle: base,
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
}
case chargeState != nil && resurrector != nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.ChargeState
api.Resurrector
}{
Vehicle: base,
ChargeState: &decorateVehicleChargeStateImpl{
chargeState: chargeState,
},
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
}
case chargeState == nil && resurrector != nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.Resurrector
api.VehicleRange
}{
Vehicle: base,
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleRange: &decorateVehicleVehicleRangeImpl{
vehicleRange: vehicleRange,
},
}
case chargeState != nil && resurrector != nil && vehicleClimater == nil && vehicleOdometer == nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.ChargeState
api.Resurrector
api.VehicleRange
}{
Vehicle: base,
ChargeState: &decorateVehicleChargeStateImpl{
chargeState: chargeState,
},
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleRange: &decorateVehicleVehicleRangeImpl{
vehicleRange: vehicleRange,
},
}
case chargeState == nil && resurrector != nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.Resurrector
api.VehicleOdometer
}{
Vehicle: base,
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleOdometer: &decorateVehicleVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
}
case chargeState != nil && resurrector != nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.ChargeState
api.Resurrector
api.VehicleOdometer
}{
Vehicle: base,
ChargeState: &decorateVehicleChargeStateImpl{
chargeState: chargeState,
},
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleOdometer: &decorateVehicleVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
}
case chargeState == nil && resurrector != nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.Resurrector
api.VehicleOdometer
api.VehicleRange
}{
Vehicle: base,
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleOdometer: &decorateVehicleVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
VehicleRange: &decorateVehicleVehicleRangeImpl{
vehicleRange: vehicleRange,
},
}
case chargeState != nil && resurrector != nil && vehicleClimater == nil && vehicleOdometer != nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.ChargeState
api.Resurrector
api.VehicleOdometer
api.VehicleRange
}{
Vehicle: base,
ChargeState: &decorateVehicleChargeStateImpl{
chargeState: chargeState,
},
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleOdometer: &decorateVehicleVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
VehicleRange: &decorateVehicleVehicleRangeImpl{
vehicleRange: vehicleRange,
},
}
case chargeState == nil && resurrector != nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.Resurrector
api.VehicleClimater
}{
Vehicle: base,
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleClimater: &decorateVehicleVehicleClimaterImpl{
vehicleClimater: vehicleClimater,
},
}
case chargeState != nil && resurrector != nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.ChargeState
api.Resurrector
api.VehicleClimater
}{
Vehicle: base,
ChargeState: &decorateVehicleChargeStateImpl{
chargeState: chargeState,
},
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleClimater: &decorateVehicleVehicleClimaterImpl{
vehicleClimater: vehicleClimater,
},
}
case chargeState == nil && resurrector != nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.Resurrector
api.VehicleClimater
api.VehicleRange
}{
Vehicle: base,
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleClimater: &decorateVehicleVehicleClimaterImpl{
vehicleClimater: vehicleClimater,
},
VehicleRange: &decorateVehicleVehicleRangeImpl{
vehicleRange: vehicleRange,
},
}
case chargeState != nil && resurrector != nil && vehicleClimater != nil && vehicleOdometer == nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.ChargeState
api.Resurrector
api.VehicleClimater
api.VehicleRange
}{
Vehicle: base,
ChargeState: &decorateVehicleChargeStateImpl{
chargeState: chargeState,
},
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleClimater: &decorateVehicleVehicleClimaterImpl{
vehicleClimater: vehicleClimater,
},
VehicleRange: &decorateVehicleVehicleRangeImpl{
vehicleRange: vehicleRange,
},
}
case chargeState == nil && resurrector != nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.Resurrector
api.VehicleClimater
api.VehicleOdometer
}{
Vehicle: base,
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleClimater: &decorateVehicleVehicleClimaterImpl{
vehicleClimater: vehicleClimater,
},
VehicleOdometer: &decorateVehicleVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
}
case chargeState != nil && resurrector != nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange == nil:
return &struct {
api.Vehicle
api.ChargeState
api.Resurrector
api.VehicleClimater
api.VehicleOdometer
}{
Vehicle: base,
ChargeState: &decorateVehicleChargeStateImpl{
chargeState: chargeState,
},
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleClimater: &decorateVehicleVehicleClimaterImpl{
vehicleClimater: vehicleClimater,
},
VehicleOdometer: &decorateVehicleVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
}
case chargeState == nil && resurrector != nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.Resurrector
api.VehicleClimater
api.VehicleOdometer
api.VehicleRange
}{
Vehicle: base,
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleClimater: &decorateVehicleVehicleClimaterImpl{
vehicleClimater: vehicleClimater,
},
VehicleOdometer: &decorateVehicleVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
VehicleRange: &decorateVehicleVehicleRangeImpl{
vehicleRange: vehicleRange,
},
}
case chargeState != nil && resurrector != nil && vehicleClimater != nil && vehicleOdometer != nil && vehicleRange != nil:
return &struct {
api.Vehicle
api.ChargeState
api.Resurrector
api.VehicleClimater
api.VehicleOdometer
api.VehicleRange
}{
Vehicle: base,
ChargeState: &decorateVehicleChargeStateImpl{
chargeState: chargeState,
},
Resurrector: &decorateVehicleResurrectorImpl{
resurrector: resurrector,
},
VehicleClimater: &decorateVehicleVehicleClimaterImpl{
vehicleClimater: vehicleClimater,
},
VehicleOdometer: &decorateVehicleVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
VehicleRange: &decorateVehicleVehicleRangeImpl{
vehicleRange: vehicleRange,
},
}
}
return nil
@ -256,6 +560,14 @@ func (impl *decorateVehicleChargeStateImpl) Status() (api.ChargeStatus, error) {
return impl.chargeState()
}
type decorateVehicleResurrectorImpl struct {
resurrector func() error
}
func (impl *decorateVehicleResurrectorImpl) WakeUp() error {
return impl.resurrector()
}
type decorateVehicleVehicleClimaterImpl struct {
vehicleClimater func() (bool, error)
}