Loadpoint: fix limit soc not published for integrated devices (#19533)

This commit is contained in:
andig 2025-03-07 12:07:42 +01:00 • committed by GitHub
parent 8d67a008b7
commit 29b7b2f44c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 32 additions and 18 deletions

View file

@ -1598,23 +1598,34 @@ func (lp *Loadpoint) publishChargeProgress() {
// publish state of charge, remaining charge duration and range
func (lp *Loadpoint) publishSocAndRange() {
soc, err := lp.chargerSoc()
if err == nil {
lp.vehicleSoc = soc
lp.publish(keys.VehicleSoc, lp.vehicleSoc)
// guard for socEstimator removed by api
// also keep a local copy in order to avoid race conditions
// https://github.com/evcc-io/evcc/issues/16180
socEstimator := lp.socEstimator
if socEstimator == nil || (!lp.vehicleHasSoc() && err != nil) {
// This is a workaround for heaters. Without vehicle, the soc estimator is not initialized.
// We need to check if the charger can provide soc and use it if available.
if err == nil {
lp.vehicleSoc = soc
lp.publish(keys.VehicleSoc, lp.vehicleSoc)
if limit, err := lp.chargerSocLimit(); err == nil {
lp.log.DEBUG.Printf("charger soc limit: %d%%", limit)
// https://github.com/evcc-io/evcc/issues/13349
lp.publish(keys.VehicleLimitSoc, float64(limit))
} else if !errors.Is(err, api.ErrNotAvailable) {
lp.log.ERROR.Printf("charger soc limit: %v", err)
}
return
} else if !errors.Is(err, api.ErrNotAvailable) {
lp.log.ERROR.Printf("charger soc: %v", err)
}
if err == nil || lp.chargerHasFeature(api.IntegratedDevice) || lp.vehicleSocPollAllowed() {
// guard for socEstimator removed by api and keep a local copy in order to avoid race conditions
// https://github.com/evcc-io/evcc/issues/16180
socEstimator := lp.socEstimator
// soc not available
if socEstimator == nil || !lp.vehicleHasSoc() {
return
}
// integrated device can bypass the update interval if vehicle is separately configured (legacy)
if lp.chargerHasFeature(api.IntegratedDevice) || lp.vehicleSocPollAllowed() {
lp.socUpdated = lp.clock.Now()
f, err := socEstimator.Soc(lp.GetChargedEnergy())
@ -1636,13 +1647,8 @@ func (lp *Loadpoint) publishSocAndRange() {
// TODO take vehicle api limits into account
apiLimitSoc := 100
// integrated device with charger limit
vs, ok := lp.charger.(api.SocLimiter)
if !ok {
// vehicle limit
vs, ok = lp.GetVehicle().(api.SocLimiter)
}
if ok {
// vehicle limit
if vs, ok := lp.GetVehicle().(api.SocLimiter); ok {
if limit, err := vs.GetLimitSoc(); err == nil {
apiLimitSoc = int(limit)
lp.log.DEBUG.Printf("vehicle soc limit: %d%%", limit)

View file

@ -33,3 +33,11 @@ func (lp *Loadpoint) chargerSoc() (float64, error) {
}
return 0, api.ErrNotAvailable
}
// chargerSocLimit returns charger soc limit if available
func (lp *Loadpoint) chargerSocLimit() (int64, error) {
if c, ok := lp.charger.(api.SocLimiter); ok {
return c.GetLimitSoc()
}
return 0, api.ErrNotAvailable
}