Repository: evcc-io/evcc (2026-04-02T19:12:06Z)

Issue:
Goodwe goodwe-wifi-et: unsupported decode "float32"
### Describe the bug

After updating EVCC to the newly released version `v0.304.0`, the Goodwe integration fails to initialize during startup. The system throws a fatal error specifically related to the `goodwe-wifi-et` template, stating that `aa55udp` has an unsupported decode for `"float32"`. This causes the site to fail booting due to a missing grid meter instance.

### Steps to reproduce

1. Update EVCC to version `v0.304.0`.
2. Configure a grid meter using the `goodwe-wifi-et` template.
3. Start the EVCC service.
4. The system fails to start and displays the unsupported decode `"float32"` error in the UI and logs.

### Configuration details

```yaml
site:
  meters:
    grid: my_grid
    pv: my_pv
    battery: my_battery
....
meters:
  - name: my_grid
    type: template
    template: goodwe-wifi-et
    usage: grid
    host: 192.168.1.26 # IP address or hostname, IP address of the inverter (port 8899)
  - name: my_pv
    type: template
    template: goodwe-wifi-et
    usage: pv
    host: 192.168.1.26 # IP address or hostname, IP address of the inverter (port 8899)
  - name: my_battery
    type: template
    template: goodwe-wifi-et
    usage: battery
    host: 192.168.1.26 # IP address or hostname, IP address of the inverter (port 8899)
...
```

### Log details

```text
[main  ] FATAL 2026/04/02 15:07:50 meter [my_grid] cannot create meter 'my_grid': cannot create meter type 'template:goodwe-wifi-et': cannot create meter type 'custom': energy: aa55udp: unsupported decode "float32" (want int32be|uint32be|int16be|uint16be)
failed booting site: missing grid meter instance
```

### What type of operating system or environment does evcc run on?

HomeAssistant Add-on

### External automation

- [x] I have made sure that no external automation like HomeAssistant or Node-RED is active or accessing any of the mentioned devices when this issue occurs.

### Nightly build

- [x] I have verified that the issue is reproducible with the latest nightly build

### Version

0.304.0


Discussion:
/cc @toeklk are we missing a decoding here? Seems the `float32` comes from here:

```yaml
  energy:
    source: aa55udp
    host: {{ .host }}
    register: 36017
    count: 2
    decode: float32
    scale: 0.001
```

Yes, it seems like the (at least) the decode function was not supporting float32(be).
Any ETA on the fix?
Add PR #28765 for this one 

Does it work without configuration evcc.yaml, just using evcc UI ?



Patch:
diff --git a/plugin/aa55udp.go b/plugin/aa55udp.go
index fed3063b658..84c95258da1 100644
--- a/plugin/aa55udp.go
+++ b/plugin/aa55udp.go
@@ -6,6 +6,7 @@ import (
 	"encoding/hex"
 	"errors"
 	"fmt"
+	"math"
 	"net"
 	"strings"
 	"time"
@@ -68,9 +69,9 @@ func NewAA55UDPFromConfig(_ context.Context, other map[string]interface{}) (Plug
 	}
 
 	switch cc.Decode {
-	case "int32be", "uint32be", "int16be", "uint16be":
+	case "int32be", "uint32be", "int16be", "uint16be", "float32be":
 	default:
-		return nil, fmt.Errorf("aa55udp: unsupported decode %q (want int32be|uint32be|int16be|uint16be)", cc.Decode)
+		return nil, fmt.Errorf("aa55udp: unsupported decode %q (want int32be|uint32be|int16be|uint16be|float32be)", cc.Decode)
 	}
 
 	pdu := buildPDU(cc.Register, cc.Count)
@@ -183,6 +184,12 @@ func stripAA55Header(buf []byte) ([]byte, error) {
 // interprets it according to decode.
 func decodeAt(payload []byte, offset int, decode string) (float64, error) {
 	switch decode {
+	case "float32be":
+		if len(payload) < offset+4 {
+			return 0, fmt.Errorf("payload too short for float32be at offset %d (len=%d)", offset, len(payload))
+		}
+		bits := binary.BigEndian.Uint32(payload[offset:])
+		return float64(math.Float32frombits(bits)), nil
 	case "int32be":
 		if len(payload) < offset+4 {
 			return 0, fmt.Errorf("payload too short for int32be at offset %d (len=%d)", offset, len(payload))
diff --git a/templates/definition/meter/goodwe-wifi-et.yaml b/templates/definition/meter/goodwe-wifi-et.yaml
index f1ffe241958..46e8a5dbdb4 100644
--- a/templates/definition/meter/goodwe-wifi-et.yaml
+++ b/templates/definition/meter/goodwe-wifi-et.yaml
@@ -23,7 +23,7 @@ render: |
     host: {{ .host }}
     register: 36017
     count: 2
-    decode: float32
+    decode: float32be
     scale: 0.001
   {{- end }}
   {{- if eq .usage "pv" }}


Test patch:
diff --git a/plugin/aa55udp_test.go b/plugin/aa55udp_test.go
index a617a6ffc23..22e8759e4a1 100644
--- a/plugin/aa55udp_test.go
+++ b/plugin/aa55udp_test.go
@@ -3,6 +3,7 @@ package plugin
 import (
 	"encoding/binary"
 	"encoding/hex"
+	"math"
 	"net"
 	"testing"
 
@@ -153,6 +154,15 @@ func TestDecodeAt_Int16BE_Negative(t *testing.T) {
 	assert.InDelta(t, -300.0, v, 0)
 }
 
+func TestDecodeAt_Float32BE(t *testing.T) {
+	payload := make([]byte, 4)
+	bits := math.Float32bits(123.456)
+	binary.BigEndian.PutUint32(payload, bits)
+	v, err := decodeAt(payload, 0, "float32be")
+	require.NoError(t, err)
+	assert.InDelta(t, 123.456, v, 0.001)
+}
+
 func TestDecodeAt_TooShort(t *testing.T) {
 	_, err := decodeAt([]byte{0x00}, 0, "int32be")
 	require.Error(t, err)