From f7b3f394f3a2ac74daaf22af2355c79579cf04a1 Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 23 Aug 2026 12:43:13 +0200 Subject: [PATCH] Shelly: no return energy register on gen1 relay and plug meters (#33111) --- meter/shelly/gen1.go | 6 ++++-- meter/shelly/gen1_test.go | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/meter/shelly/gen1.go b/meter/shelly/gen1.go index a8e007ef5..d57784cf4 100644 --- a/meter/shelly/gen1.go +++ b/meter/shelly/gen1.go @@ -149,9 +149,11 @@ func (c *gen1) IsReversed() bool { return false } -// HasReturnEnergy reports whether the device measures energy in the return direction +// HasReturnEnergy reports whether the device measures energy in the return direction. +// Only the EM variants have a total_returned register, relay/plug meters don't. func (c *gen1) HasReturnEnergy() bool { - return true + res, err := c.status.Get() + return err == nil && c.channel >= len(res.Meters) && c.channel < len(res.EMeters) } // IsThreePhase reports whether the device is a three-phase energy meter. diff --git a/meter/shelly/gen1_test.go b/meter/shelly/gen1_test.go index 7f9dc6b21..28129d992 100644 --- a/meter/shelly/gen1_test.go +++ b/meter/shelly/gen1_test.go @@ -3,7 +3,9 @@ package shelly import ( "encoding/json" "testing" + "time" + "github.com/evcc-io/evcc/util" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -46,3 +48,21 @@ func TestUnmarshalGen1Status(t *testing.T) { assert.Equal(t, -620.34, res.EMeters[0].Power) } } + +// TestGen1HasReturnEnergy asserts that only the EM variants report a return +// register - a 1PM's production must not be booked in return direction (#33062). +func TestGen1HasReturnEnergy(t *testing.T) { + status := func(s string) util.Cacheable[Gen1Status] { + var res Gen1Status + require.NoError(t, json.Unmarshal([]byte(s), &res)) + return util.ResettableCached(func() (Gen1Status, error) { return res, nil }, time.Minute) + } + + // Shelly 1PM: meters without total_returned + g := &gen1{status: status(`{"meters":[{"power":198.0,"total":31510486}]}`)} + assert.False(t, g.HasReturnEnergy(), "1PM has no return register") + + // Shelly EM: emeters with total_returned + g = &gen1{status: status(`{"emeters":[{"power":-620.34,"total":401472.9,"total_returned":653673.7}]}`)} + assert.True(t, g.HasReturnEnergy()) +}