From 6dd6a057998a193e8a7b6a9244adf1389a9fbd4a Mon Sep 17 00:00:00 2001 From: andig Date: Sat, 15 Jun 2024 20:30:51 +0200 Subject: [PATCH] Fix deadlock setting battery mode (#14383) --- core/site.go | 2 +- core/site_api.go | 4 ++-- core/site_battery.go | 15 ++++++++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/core/site.go b/core/site.go index f382a186b..569f49887 100644 --- a/core/site.go +++ b/core/site.go @@ -97,7 +97,7 @@ type Site struct { pvPower float64 // PV power batteryPower float64 // Battery charge power batterySoc float64 // Battery soc - batteryMode api.BatteryMode // Battery mode + batteryMode api.BatteryMode // Battery mode (runtime only, not persisted) publishCache map[string]any // store last published values to avoid unnecessary republishing } diff --git a/core/site_api.go b/core/site_api.go index 757b7017b..62ae175ab 100644 --- a/core/site_api.go +++ b/core/site_api.go @@ -327,14 +327,14 @@ func (site *Site) GetTariff(tariff string) api.Tariff { } } -// GetBatteryControl returns the battery control mode +// GetBatteryDischargeControl returns the battery control mode (no discharge only) func (site *Site) GetBatteryDischargeControl() bool { site.RLock() defer site.RUnlock() return site.batteryDischargeControl } -// SetBatteryControl sets the battery control mode +// SetBatteryDischargeControl sets the battery control mode (no discharge only) func (site *Site) SetBatteryDischargeControl(val bool) error { site.log.DEBUG.Println("set battery discharge control:", val) diff --git a/core/site_battery.go b/core/site_battery.go index f78225a2b..186275d7b 100644 --- a/core/site_battery.go +++ b/core/site_battery.go @@ -19,6 +19,12 @@ func (site *Site) GetBatteryMode() api.BatteryMode { return site.batteryMode } +// setBatteryMode sets the battery mode +func (site *Site) setBatteryMode(batMode api.BatteryMode) { + site.batteryMode = batMode + site.publish(keys.BatteryMode, batMode) +} + // SetBatteryMode sets the battery mode func (site *Site) SetBatteryMode(batMode api.BatteryMode) { site.Lock() @@ -27,11 +33,12 @@ func (site *Site) SetBatteryMode(batMode api.BatteryMode) { site.log.DEBUG.Println("set battery mode:", batMode) if site.batteryMode != batMode { - site.batteryMode = batMode - site.publish(keys.BatteryMode, batMode) + site.setBatteryMode(batMode) } } +// applyBatteryMode applies the mode to each battery and updates +// internal state if successful (requires lock) func (site *Site) applyBatteryMode(mode api.BatteryMode) error { // update batteries for _, meter := range site.batteryMeters { @@ -43,7 +50,7 @@ func (site *Site) applyBatteryMode(mode api.BatteryMode) error { } // update state and publish - site.SetBatteryMode(mode) + site.setBatteryMode(mode) return nil } @@ -89,8 +96,10 @@ func (site *Site) updateBatteryMode() { } if batMode := site.GetBatteryMode(); mode != batMode { + site.Lock() if err := site.applyBatteryMode(mode); err != nil { site.log.ERROR.Println("battery mode:", err) } + site.Unlock() } }