diff --git a/api/api.go b/api/api.go index f9bce4a5a..3347028d8 100644 --- a/api/api.go +++ b/api/api.go @@ -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) diff --git a/charger/charger.go b/charger/charger.go index fa6cc1343..11d10845f 100644 --- a/charger/charger.go +++ b/charger/charger.go @@ -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 diff --git a/charger/charger_decorators.go b/charger/charger_decorators.go index 093e0ae9d..7cdd677fc 100644 --- a/charger/charger_decorators.go +++ b/charger/charger_decorators.go @@ -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() +} diff --git a/vehicle/vehicle.go b/vehicle/vehicle.go index a3088a91e..90e9c0eaf 100644 --- a/vehicle/vehicle.go +++ b/vehicle/vehicle.go @@ -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 -} diff --git a/vehicle/vehicle_decorators.go b/vehicle/vehicle_decorators.go index f3a63cbcf..4724fdd71 100644 --- a/vehicle/vehicle_decorators.go +++ b/vehicle/vehicle_decorators.go @@ -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) }