diff --git a/meter/sma.go b/meter/sma.go index a60c3ca41..a3fd11a98 100644 --- a/meter/sma.go +++ b/meter/sma.go @@ -93,6 +93,33 @@ func (sm *SMA) waitForInitialValue() { } } +// update the actual meter data +func (sm *SMA) updatePower(msg sma.Telegram) { + sm.mux.Lock() + + if sm.powerO != "" { + // use user-defined obis + if power, ok := msg.Values[sm.powerO]; ok { + sm.power = power + sm.updated = time.Now() + } + } else { + sm.power = msg.Values[sma.ImportPower] - msg.Values[sma.ExportPower] + sm.updated = time.Now() + } + + if sm.energyO != "" { + if energy, ok := msg.Values[sm.energyO]; ok { + sm.energy = energy + sm.updated = time.Now() + } else { + sm.log.WARN.Println("missing obis for energy") + } + } + + sm.mux.Unlock() +} + // receive processes the channel message containing the multicast data func (sm *SMA) receive() { for msg := range sm.recv { @@ -100,29 +127,7 @@ func (sm *SMA) receive() { continue } - sm.mux.Lock() - - if sm.powerO != "" { - // use user-defined obis - if power, ok := msg.Values[sm.powerO]; ok { - sm.power = power - sm.updated = time.Now() - } - } else { - sm.power = msg.Values[sma.ImportPower] - msg.Values[sma.ExportPower] - sm.updated = time.Now() - } - - if sm.energyO != "" { - if energy, ok := msg.Values[sm.energyO]; ok { - sm.energy = energy - sm.updated = time.Now() - } else { - sm.log.WARN.Println("missing obis for energy") - } - } - - sm.mux.Unlock() + sm.updatePower(msg) } } diff --git a/meter/sma_test.go b/meter/sma_test.go new file mode 100644 index 000000000..363b591ac --- /dev/null +++ b/meter/sma_test.go @@ -0,0 +1,49 @@ +package meter + +import ( + "testing" + + "github.com/andig/evcc/meter/sma" + "github.com/andig/evcc/util" +) + +func TestSMAUpdatePower(t *testing.T) { + tests := []struct { + name string + messsage sma.Telegram + wantPower float64 + }{ + { + "success export", + sma.Telegram{ + Values: map[string]float64{ + "1:1.4.0": 0, + "1:2.4.0": 37.9, + }, + }, + -37.9, + }, + { + "success import", + sma.Telegram{ + Values: map[string]float64{ + "1:1.4.0": 20, + "1:2.4.0": 0, + }, + }, + 20, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + sm := &SMA{ + log: util.NewLogger("sma "), + } + + sm.updatePower(tt.messsage) + if sm.power != tt.wantPower { + t.Errorf("Listener.processMessage() got %v, want %v", sm.power, tt.wantPower) + } + }) + } +}