evcc-io/core/loadpoint_effective.go

120 lines
3.1 KiB
Go

package core
import (
"time"
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/core/keys"
"github.com/evcc-io/evcc/core/vehicle"
)
// PublishEffectiveValues publishes all effective values
func (lp *Loadpoint) PublishEffectiveValues() {
lp.publish(keys.EffectivePriority, lp.EffectivePriority())
lp.publish(keys.EffectivePlanTime, lp.EffectivePlanTime())
lp.publish(keys.EffectivePlanSoc, lp.EffectivePlanSoc())
lp.publish(keys.EffectiveMinCurrent, lp.effectiveMinCurrent())
lp.publish(keys.EffectiveMaxCurrent, lp.effectiveMaxCurrent())
lp.publish(keys.EffectiveLimitSoc, lp.effectiveLimitSoc())
}
// EffectivePriority returns the effective priority
func (lp *Loadpoint) EffectivePriority() int {
if v := lp.GetVehicle(); v != nil {
if res, ok := v.OnIdentified().GetPriority(); ok {
return res
}
}
return lp.GetPriority()
}
// vehiclePlanSoc returns the next vehicle plan time and soc
func (lp *Loadpoint) vehiclePlanSoc() (time.Time, int) {
if v := lp.GetVehicle(); v != nil {
return vehicle.Settings(lp.log, v).GetPlanSoc()
}
return time.Time{}, 0
}
// EffectivePlanSoc returns the soc target for the current plan
func (lp *Loadpoint) EffectivePlanSoc() int {
_, soc := lp.vehiclePlanSoc()
return soc
}
// EffectivePlanTime returns the effective plan time
func (lp *Loadpoint) EffectivePlanTime() time.Time {
if lp.socBasedPlanning() {
ts, _ := lp.vehiclePlanSoc()
return ts
}
ts, _ := lp.GetPlanEnergy()
return ts
}
// effectiveMinCurrent returns the effective min current
func (lp *Loadpoint) effectiveMinCurrent() float64 {
if v := lp.GetVehicle(); v != nil {
if res, ok := v.OnIdentified().GetMinCurrent(); ok {
return res
}
}
if c, ok := lp.charger.(api.CurrentLimiter); ok {
if res, _, err := c.GetMinMaxCurrent(); err == nil {
lp.publish(keys.EffectiveMinCurrent, res)
return res
}
}
return lp.GetMinCurrent()
}
// effectiveMaxCurrent returns the effective max current
func (lp *Loadpoint) effectiveMaxCurrent() float64 {
if v := lp.GetVehicle(); v != nil {
if res, ok := v.OnIdentified().GetMaxCurrent(); ok {
return res
}
}
if c, ok := lp.charger.(api.CurrentLimiter); ok {
if _, res, err := c.GetMinMaxCurrent(); err == nil {
lp.publish(keys.EffectiveMaxCurrent, res)
return res
}
}
return lp.GetMaxCurrent()
}
// effectiveLimitSoc returns the effective session limit soc
// TODO take vehicle api limits into account
func (lp *Loadpoint) effectiveLimitSoc() int {
lp.RLock()
defer lp.RUnlock()
if lp.limitSoc > 0 {
return lp.limitSoc
}
if v := lp.GetVehicle(); v != nil {
if soc := vehicle.Settings(lp.log, v).GetLimitSoc(); soc > 0 {
return soc
}
}
return 100
}
// EffectiveMinPower returns the effective min power for a single phase
func (lp *Loadpoint) EffectiveMinPower() float64 {
// TODO check if 1p available
return Voltage * lp.effectiveMinCurrent()
}
// EffectiveMaxPower returns the effective max power taking vehicle capabilities and phase scaling into account
func (lp *Loadpoint) EffectiveMaxPower() float64 {
return Voltage * lp.effectiveMaxCurrent() * float64(lp.maxActivePhases())
}