Loadpoint: fix soc read from offline vehicles (#26942)

This commit is contained in:
andig 2026-01-23 17:26:49 +01:00 • committed by GitHub
parent 1becd41a98
commit 0643648a94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 18 deletions

View file

@ -1760,14 +1760,20 @@ func (lp *Loadpoint) publishSocAndRange() {
return socR, limitR
}
pollAllowed := lp.vehicleSocPollAllowed()
if pollAllowed {
lp.socUpdated = lp.clock.Now()
}
soc, limit := socAndLimit("charger", lp.charger)
if soc == nil && (pollAllowed || lp.chargerHasFeature(api.IntegratedDevice)) {
if soc == nil && (lp.vehicleSocPollAllowed() || lp.chargerHasFeature(api.IntegratedDevice)) {
lp.socUpdated = lp.clock.Now()
soc, limit = socAndLimit("vehicle", lp.GetVehicle())
// range
if vs, ok := lp.GetVehicle().(api.VehicleRange); ok {
if rng, err := vs.Range(); err == nil {
lp.log.DEBUG.Printf("vehicle range: %dkm", rng)
lp.publish(keys.VehicleRange, rng)
} else if !loadpoint.AcceptableError(err) {
lp.log.ERROR.Printf("vehicle range: %v", err)
}
}
}
if soc != nil {
@ -1800,16 +1806,6 @@ func (lp *Loadpoint) publishSocAndRange() {
lp.SetRemainingEnergy(socEstimator.RemainingChargeEnergy(limitSoc))
}
// range
if vs, ok := lp.GetVehicle().(api.VehicleRange); ok && pollAllowed {
if rng, err := vs.Range(); err == nil {
lp.log.DEBUG.Printf("vehicle range: %dkm", rng)
lp.publish(keys.VehicleRange, rng)
} else if !loadpoint.AcceptableError(err) {
lp.log.ERROR.Printf("vehicle range: %v", err)
}
}
// trigger message after variables are updated
lp.bus.Publish(evVehicleSoc, lp.vehicleSoc)
}

View file

@ -326,6 +326,10 @@ func (lp *Loadpoint) vehicleClimatePollAllowed() bool {
// vehicleSocPollAllowed validates charging state against polling mode
func (lp *Loadpoint) vehicleSocPollAllowed() bool {
if lp.vehicleHasFeature(api.Offline) {
return false
}
// always update soc when charging
if lp.charging() || lp.vehicleHasFeature(api.Streaming) {
return true

View file

@ -113,7 +113,8 @@ func TestPublishSocAndRangeVehiclesAndChargers(t *testing.T) {
charger api.Charger
vehicle api.Vehicle
soc float64
socBased bool
socBased bool // soc based planning
socPoll bool // may poll vehicle
}{
{
name: "offline vehicle",
@ -121,6 +122,7 @@ func TestPublishSocAndRangeVehiclesAndChargers(t *testing.T) {
vehicle: offlineVehicle,
soc: 0.0,
socBased: false,
socPoll: false,
},
{
name: "regular vehicle",
@ -128,6 +130,7 @@ func TestPublishSocAndRangeVehiclesAndChargers(t *testing.T) {
vehicle: vehicle,
soc: socVehicle,
socBased: true,
socPoll: true,
},
{
name: "offline vehicle with iso charger",
@ -135,6 +138,7 @@ func TestPublishSocAndRangeVehiclesAndChargers(t *testing.T) {
vehicle: offlineVehicle,
soc: socCharger,
socBased: true,
socPoll: false,
},
{
name: "regular vehicle with iso charger",
@ -142,6 +146,7 @@ func TestPublishSocAndRangeVehiclesAndChargers(t *testing.T) {
vehicle: vehicle,
soc: socCharger,
socBased: true,
socPoll: true,
},
}
@ -167,7 +172,7 @@ func TestPublishSocAndRangeVehiclesAndChargers(t *testing.T) {
attachChannels(lp, x, y, z)
test := func(t *testing.T) {
assert.True(t, lp.vehicleSocPollAllowed())
assert.Equal(t, tc.socPoll, lp.vehicleSocPollAllowed())
lp.publishSocAndRange()
assert.Equal(t, tc.soc, lp.vehicleSoc)