From 7fcadcf458937e8684baa9c20880e88485d44ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20B=C3=B6hmke?= Date: Sun, 11 Jul 2021 20:58:56 +0200 Subject: [PATCH] SMA: fix race condition (#1206) --- go.mod | 2 +- go.sum | 4 ++-- meter/sma.go | 9 --------- provider/sma/device.go | 9 +++++++-- provider/sma/discover.go | 2 ++ 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index b013ca495..ea93c9617 100644 --- a/go.mod +++ b/go.mod @@ -66,7 +66,7 @@ require ( github.com/thoas/go-funk v0.8.0 github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c github.com/volkszaehler/mbmd v0.0.0-20210526131012-e1fec7232ed7 - gitlab.com/bboehmke/sunny v0.13.2 + gitlab.com/bboehmke/sunny v0.14.0 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect golang.org/x/net v0.0.0-20210614182718-04defd469f4e golang.org/x/oauth2 v0.0.0-20210615190721-d04028783cf1 diff --git a/go.sum b/go.sum index ee143ff7e..e38319b5e 100644 --- a/go.sum +++ b/go.sum @@ -660,8 +660,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -gitlab.com/bboehmke/sunny v0.13.2 h1:blQPB2hcqX11/a9L1AiiEVSqxH+s9/I7JZ2M1TiS9bY= -gitlab.com/bboehmke/sunny v0.13.2/go.mod h1:F5AIuL7kYteSJFR5E+YEocxIdpyCXmtDciFmMQVjP88= +gitlab.com/bboehmke/sunny v0.14.0 h1:y7BSXRiyM3uJwnVes++JvuhdxDZKVhbHQlF+0/kwlgw= +gitlab.com/bboehmke/sunny v0.14.0/go.mod h1:F5AIuL7kYteSJFR5E+YEocxIdpyCXmtDciFmMQVjP88= go.coder.com/go-tools v0.0.0-20190317003359-0c6a35b74a16/go.mod h1:iKV5yK9t+J5nG9O3uF6KYdPEz3dyfMyB15MN1rbQ8Qw= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= diff --git a/meter/sma.go b/meter/sma.go index 7e180805e..954d4db2f 100644 --- a/meter/sma.go +++ b/meter/sma.go @@ -145,15 +145,6 @@ func (sm *SMA) Diagnose() { fmt.Fprintf(w, " EnergyMeter:\t%v\n", sm.device.IsEnergyMeter()) fmt.Fprintln(w) - if name, err := sm.device.GetDeviceName(); err == nil { - fmt.Fprintf(w, " Name:\t%s\n", name) - } - - if devClass, err := sm.device.GetDeviceClass(); err == nil { - fmt.Fprintf(w, " Device Class:\t0x%X\n", devClass) - } - fmt.Fprintln(w) - if values, err := sm.device.Values(); err == nil { ids := make([]sunny.ValueID, 0, len(values)) for k := range values { diff --git a/provider/sma/device.go b/provider/sma/device.go index 11a1738e4..ab6853d62 100644 --- a/provider/sma/device.go +++ b/provider/sma/device.go @@ -25,7 +25,7 @@ func (d *Device) StartUpdateLoop() { d.once.Do(func() { go func() { d.updateValues() - for range time.NewTicker(time.Second).C { + for range time.NewTicker(time.Second * 5).C { d.updateValues() } }() @@ -58,7 +58,12 @@ func (d *Device) Values() (map[sunny.ValueID]interface{}, error) { return nil, fmt.Errorf("update timeout: %v", elapsed.Truncate(time.Second)) } - return d.values, nil + // return a copy of the map to avoid race conditions + values := make(map[sunny.ValueID]interface{}, len(d.values)) + for key, value := range d.values { + values[key] = value + } + return values, nil } func AsFloat(value interface{}) float64 { diff --git a/provider/sma/discover.go b/provider/sma/discover.go index 4658729f5..7e381605c 100644 --- a/provider/sma/discover.go +++ b/provider/sma/discover.go @@ -76,6 +76,8 @@ func (d *Discoverer) addDevice(device *sunny.Device) { if _, ok := d.devices[device.SerialNumber()]; !ok { d.devices[device.SerialNumber()] = d.createDevice(device) + } else { + device.Close() } }