Vestel: decode version as utf16 (#21656)

This commit is contained in:
mfuchs1984 2025-06-06 22:02:27 +02:00 • committed by GitHub
parent 65ffc40ceb
commit fdae6a72f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 36 additions and 19 deletions

View file

@ -26,7 +26,6 @@ import (
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/modbus"
"golang.org/x/text/encoding/unicode"
)
// DaheimLadenMB charger implementation
@ -261,11 +260,6 @@ var _ api.Diagnosis = (*DaheimLadenMB)(nil)
// Diagnose implements the api.Diagnosis interface
func (wb *DaheimLadenMB) Diagnose() {
utf16BytesToString := func(b []byte) string {
s, _ := unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM).NewDecoder().String(string(b))
return s
}
if b, err := wb.conn.ReadHoldingRegisters(dlRegChargingState, 1); err == nil {
fmt.Printf("\tCharging Station State:\t%d\n", binary.BigEndian.Uint16(b))
}
@ -279,7 +273,8 @@ func (wb *DaheimLadenMB) Diagnose() {
fmt.Printf("\tCable Max. Current:\t%.1fA\n", float64(binary.BigEndian.Uint16(b)/10))
}
if b, err := wb.conn.ReadHoldingRegisters(dlRegStationId, 16); err == nil {
fmt.Printf("\tStation ID:\t%s\n", utf16BytesToString(b))
s, _ := utf16BEBytesAsString(b)
fmt.Printf("\tStation ID:\t%s\n", s)
}
if b, err := wb.conn.ReadHoldingRegisters(dlRegSafeCurrent, 1); err == nil {
fmt.Printf("\tSafe Current:\t%.1fA\n", float64(binary.BigEndian.Uint16(b)/10))

View file

@ -7,6 +7,7 @@ import (
"github.com/evcc-io/evcc/api"
"github.com/samber/lo"
"golang.org/x/text/encoding/unicode"
)
// TODO remove when used
@ -60,6 +61,15 @@ func bytesAsString(b []byte) string {
return strings.TrimSpace(string(bytes.TrimLeft(b, "\x00")))
}
// utf16BEBytesAsString converts a byte slice containing UTF-16 Big-Endian encoded text to a string and trims white spaces
func utf16BEBytesAsString(b []byte) (string, error) {
s, err := unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM).NewDecoder().String(string(bytes.TrimRight(b, "\x00")))
if err != nil {
return "", err
}
return strings.TrimSpace(s), nil
}
// verifyEnabled validates the enabled state against the charger status
func verifyEnabled(c api.Charger, enabled bool) (bool, error) {
if enabled {

View file

@ -121,14 +121,19 @@ func NewVestel(ctx context.Context, uri string, id uint8) (api.Charger, error) {
return nil, fmt.Errorf("failed to read firmware version: %w", err)
}
fw := strings.TrimPrefix(bytesAsString(b), "v")
if v, err := version.NewSemver(fw); err == nil {
if v.GreaterThanOrEqual(version.Must(version.NewSemver("3.156.0"))) {
// firmware >= v3.156.0 supports RFID according to https://github.com/evcc-io/evcc/issues/21359
identify = wb.identify
fw, err := utf16BEBytesAsString(b)
if err == nil {
fw, _, _ = strings.Cut(strings.TrimPrefix(fw, "v"), "-")
if v, err := version.NewSemver(fw); err == nil {
if v.GreaterThanOrEqual(version.Must(version.NewSemver("3.156.0"))) {
// firmware >= v3.156.0 supports RFID according to https://github.com/evcc-io/evcc/issues/21359
identify = wb.identify
}
} else {
log.WARN.Printf("failed to parse firmware version %q: %v", string(b), err)
}
} else {
log.WARN.Printf("failed to parse firmware version %q: %v", string(b), err)
log.WARN.Printf("failed to decode firmware version %q: %v", b, err)
}
// get failsafe timeout from charger
@ -324,8 +329,7 @@ func (wb *Vestel) identify() (string, error) {
if err != nil {
return "", err
}
return bytesAsString(b), nil
return utf16BEBytesAsString(b)
}
var _ api.Diagnosis = (*Vestel)(nil)
@ -333,16 +337,20 @@ var _ api.Diagnosis = (*Vestel)(nil)
// Diagnose implements the api.Diagnosis interface
func (wb *Vestel) Diagnose() {
if b, err := wb.conn.ReadInputRegisters(vestelRegBrand, 10); err == nil {
fmt.Printf("Brand:\t%s\n", b)
s, _ := utf16BEBytesAsString(b)
fmt.Printf("Brand:\t%s\n", s)
}
if b, err := wb.conn.ReadInputRegisters(vestelRegModel, 5); err == nil {
fmt.Printf("Model:\t%s\n", b)
s, _ := utf16BEBytesAsString(b)
fmt.Printf("Model:\t%s\n", s)
}
if b, err := wb.conn.ReadInputRegisters(vestelRegSerial, 25); err == nil {
fmt.Printf("Serial:\t%s\n", b)
s, _ := utf16BEBytesAsString(b)
fmt.Printf("Serial:\t%s\n", s)
}
if b, err := wb.conn.ReadInputRegisters(vestelRegFirmware, 50); err == nil {
fmt.Printf("Firmware:\t%s\n", b)
s, _ := utf16BEBytesAsString(b)
fmt.Printf("Firmware:\t%s\n", s)
}
if b, err := wb.conn.ReadHoldingRegisters(vestelRegFailsafeTimeout, 1); err == nil {
fmt.Printf("Failsafe timeout:\t%#x\n", binary.BigEndian.Uint16(b))
@ -353,4 +361,8 @@ func (wb *Vestel) Diagnose() {
if b, err := wb.conn.ReadHoldingRegisters(vestelRegPhasesSwitch, 1); err == nil {
fmt.Printf("Phase switch:\t%#x\n", binary.BigEndian.Uint16(b))
}
if b, err := wb.conn.ReadInputRegisters(vestelRegRFID, 15); err == nil {
s, _ := utf16BEBytesAsString(b)
fmt.Printf("RFID:\t%s\n", s)
}
}