Vestel: decode version as utf16 (#21656)
This commit is contained in:
parent
65ffc40ceb
commit
fdae6a72f9
3 changed files with 36 additions and 19 deletions
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue