Teslamate: add charged energy (#28611)
This commit is contained in:
parent
f4932f9fbe
commit
bd9769c152
5 changed files with 34 additions and 4 deletions
|
|
@ -51,6 +51,10 @@ render: |
|
|||
topic: teslamate/cars/{{ .id }}/time_to_full_charge
|
||||
timeout: {{ .timeout }}
|
||||
jq: if (. == null) or (. == 0) or (type != "number") or (. < 0) then null else (now + (. * 3600) | strftime("%Y-%m-%dT%H:%M:%SZ")) end
|
||||
chargedenergy:
|
||||
source: mqtt
|
||||
topic: teslamate/cars/{{ .id }}/charge_energy_added
|
||||
timeout: {{ .timeout }}
|
||||
climater:
|
||||
source: mqtt
|
||||
topic: teslamate/cars/{{ .id }}/is_preconditioning
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ func NewHomeAssistantVehicleFromConfig(other map[string]any) (api.Vehicle, error
|
|||
finish,
|
||||
wakeup,
|
||||
enable,
|
||||
nil,
|
||||
), nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/evcc-io/evcc/util"
|
||||
)
|
||||
|
||||
//go:generate go tool decorate -f decorateVehicle -b api.Vehicle -t api.SocLimiter,api.ChargeState,api.VehicleRange,api.VehicleOdometer,api.VehicleClimater,api.CurrentController,api.CurrentGetter,api.VehicleFinishTimer,api.Resurrector,api.ChargeController
|
||||
//go:generate go tool decorate -f decorateVehicle -b api.Vehicle -t api.SocLimiter,api.ChargeState,api.VehicleRange,api.VehicleOdometer,api.VehicleClimater,api.CurrentController,api.CurrentGetter,api.VehicleFinishTimer,api.Resurrector,api.ChargeController,api.ChargeRater
|
||||
|
||||
// Vehicle is an api.Vehicle implementation with configurable getters and setters.
|
||||
type Vehicle struct {
|
||||
|
|
@ -38,6 +38,7 @@ func NewConfigurableFromConfig(ctx context.Context, other map[string]any) (api.V
|
|||
FinishTime *plugin.Config
|
||||
Wakeup *plugin.Config
|
||||
ChargeEnable *plugin.Config
|
||||
ChargedEnergy *plugin.Config
|
||||
}
|
||||
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
|
|
@ -140,6 +141,16 @@ func NewConfigurableFromConfig(ctx context.Context, other map[string]any) (api.V
|
|||
return nil, fmt.Errorf("chargeEnable: %w", err)
|
||||
}
|
||||
|
||||
// decorate chargedenergy
|
||||
var chargedEnergy func() (float64, error)
|
||||
if cc.ChargedEnergy != nil {
|
||||
var err error
|
||||
chargedEnergy, err = cc.ChargedEnergy.FloatGetter(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("charged energy: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case maxCurrent == nil && getMaxCurrent != nil:
|
||||
return nil, errors.New("cannot have current without current control")
|
||||
|
|
@ -149,7 +160,7 @@ func NewConfigurableFromConfig(ctx context.Context, other map[string]any) (api.V
|
|||
return nil, errors.New("cannot have charge control without status")
|
||||
}
|
||||
|
||||
return decorateVehicle(v, limitSoc, status, rng, odo, climater, maxCurrent, getMaxCurrent, finishTime, wakeup, chargeEnable), nil
|
||||
return decorateVehicle(v, limitSoc, status, rng, odo, climater, maxCurrent, getMaxCurrent, finishTime, wakeup, chargeEnable, chargedEnergy), nil
|
||||
}
|
||||
|
||||
// Soc implements the api.Vehicle interface
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/evcc-io/evcc/api"
|
||||
)
|
||||
|
||||
func decorateVehicle(base api.Vehicle, socLimiter func() (int64, error), chargeState func() (api.ChargeStatus, error), vehicleRange func() (int64, error), vehicleOdometer func() (float64, error), vehicleClimater func() (bool, error), currentController func(int64) error, currentGetter func() (float64, error), vehicleFinishTimer func() (time.Time, error), resurrector func() error, chargeController func(bool) error) api.Vehicle {
|
||||
func decorateVehicle(base api.Vehicle, socLimiter func() (int64, error), chargeState func() (api.ChargeStatus, error), vehicleRange func() (int64, error), vehicleOdometer func() (float64, error), vehicleClimater func() (bool, error), currentController func(int64) error, currentGetter func() (float64, error), vehicleFinishTimer func() (time.Time, error), resurrector func() error, chargeController func(bool) error, chargeRater func() (float64, error)) api.Vehicle {
|
||||
caps := make(map[reflect.Type]any)
|
||||
|
||||
if socLimiter != nil {
|
||||
|
|
@ -52,6 +52,10 @@ func decorateVehicle(base api.Vehicle, socLimiter func() (int64, error), chargeS
|
|||
caps[reflect.TypeFor[api.ChargeController]()] = &decorateVehicleChargeControllerImpl{chargeController: chargeController}
|
||||
}
|
||||
|
||||
if chargeRater != nil {
|
||||
caps[reflect.TypeFor[api.ChargeRater]()] = &decorateVehicleChargeRaterImpl{chargeRater: chargeRater}
|
||||
}
|
||||
|
||||
if len(caps) == 0 {
|
||||
return base
|
||||
}
|
||||
|
|
@ -77,6 +81,14 @@ func (impl *decorateVehicleChargeControllerImpl) ChargeEnable(p0 bool) error {
|
|||
return impl.chargeController(p0)
|
||||
}
|
||||
|
||||
type decorateVehicleChargeRaterImpl struct {
|
||||
chargeRater func() (float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateVehicleChargeRaterImpl) ChargedEnergy() (float64, error) {
|
||||
return impl.chargeRater()
|
||||
}
|
||||
|
||||
type decorateVehicleChargeStateImpl struct {
|
||||
chargeState func() (api.ChargeStatus, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ func baseVehicle() *Vehicle {
|
|||
}
|
||||
|
||||
func TestDecorateVehicle_NoCapabilities(t *testing.T) {
|
||||
v := decorateVehicle(baseVehicle(), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
v := decorateVehicle(baseVehicle(), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
|
||||
// base vehicle interface works
|
||||
soc, err := v.Soc()
|
||||
|
|
@ -42,6 +42,7 @@ func TestDecorateVehicle_AllCapabilities(t *testing.T) {
|
|||
func() (time.Time, error) { return time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC), nil }, // vehicleFinishTimer
|
||||
func() error { return nil }, // resurrector
|
||||
func(bool) error { return nil }, // chargeController
|
||||
nil, // chargeRater
|
||||
)
|
||||
|
||||
// base interface
|
||||
|
|
@ -126,6 +127,7 @@ func TestDecorateVehicle_PartialCapabilities(t *testing.T) {
|
|||
nil, // vehicleFinishTimer
|
||||
func() error { return nil }, // resurrector
|
||||
nil, // chargeController
|
||||
nil, // chargeRater
|
||||
)
|
||||
|
||||
assert.True(t, api.HasCap[api.SocLimiter](v), "SocLimiter should be present")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue