From 04d4f4b0913b242c716c4858bebb4b891af68cd5 Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 12 Jul 2026 12:57:36 +0200 Subject: [PATCH] optimizer: only suggest actions for controllable batteries (#31715) --- .../components/Battery/BatteryStatusCards.vue | 3 ++- core/site_optimizer.go | 20 ++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/assets/js/components/Battery/BatteryStatusCards.vue b/assets/js/components/Battery/BatteryStatusCards.vue index ec840a52e..d2a5d404d 100644 --- a/assets/js/components/Battery/BatteryStatusCards.vue +++ b/assets/js/components/Battery/BatteryStatusCards.vue @@ -87,7 +87,8 @@ export default defineComponent({ }, methods: { deviceSuggestion(d?: BatteryMeter): BatterySuggestion | null { - return d?.controllable && d.suggestion?.actionable ? d.suggestion : null; + // optimizer only emits suggestions for controllable batteries + return d?.suggestion?.actionable ? d.suggestion : null; }, }, }); diff --git a/core/site_optimizer.go b/core/site_optimizer.go index 632799740..0a4a2842f 100644 --- a/core/site_optimizer.go +++ b/core/site_optimizer.go @@ -96,7 +96,8 @@ type batteryDetail struct { Name string `json:"name,omitempty"` Capacity float64 `json:"capacity,omitempty"` - loadpoint *int // originating loadpoint id for loadpoint/vehicle entries + loadpoint *int // originating loadpoint id for loadpoint/vehicle entries + controllable bool // battery exposes a controller; only these get suggestions } type batteryResult struct { @@ -436,7 +437,10 @@ func (site *Site) optimizerUpdate(battery []types.Measurement) error { continue } if detail.Type == batteryTypeBattery { - suggestions[detail.Name] = suggestion + // uncontrollable batteries can't act on a suggestion + if detail.controllable { + suggestions[detail.Name] = suggestion + } } else if detail.loadpoint != nil { lpSuggestions[*detail.loadpoint] = suggestion } @@ -629,7 +633,8 @@ func (site *Site) batteryRequest(dev config.Device[api.Meter], b types.Measureme instance := dev.Instance() - if api.HasCap[api.BatteryController](instance) { + controllable := api.HasCap[api.BatteryController](instance) + if controllable { bat.ChargeFromGrid = true } @@ -646,10 +651,11 @@ func (site *Site) batteryRequest(dev config.Device[api.Meter], b types.Measureme } detail := batteryDetail{ - Type: batteryTypeBattery, - Name: dev.Config().Name, - Title: deviceProperties(dev).Title, - Capacity: *b.Capacity, + Type: batteryTypeBattery, + Name: dev.Config().Name, + Title: deviceProperties(dev).Title, + Capacity: *b.Capacity, + controllable: controllable, } // tariff forecast-based grid charging demand