Enovates: verify EMS mode and use actually offered current (#33163)

This commit is contained in:
andig 2026-08-25 13:43:39 +02:00 • committed by GitHub
parent b3db9e93fe
commit e4e5c2db26
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -41,7 +41,6 @@ type Enovates struct {
} }
const ( const (
enovatesRegMaxAmp = 51 // uint16 RO, max amp per phase
enovatesRegCurrents = 200 // 3x uint16 RO, mA enovatesRegCurrents = 200 // 3x uint16 RO, mA
enovatesRegVoltages = 203 // 3x int16 RO, V enovatesRegVoltages = 203 // 3x int16 RO, V
enovatesRegPower = 206 // int16 RO, W (active power total) enovatesRegPower = 206 // int16 RO, W (active power total)
@ -49,7 +48,7 @@ const (
enovatesRegMode3StateStr = 301 // 2x register RO, IEC 61851 state, e.g. "C2" enovatesRegMode3StateStr = 301 // 2x register RO, IEC 61851 state, e.g. "C2"
enovatesRegEMSLimit = 400 // int16 RW, mA (-1 = no limit, 0 = disabled) enovatesRegEMSLimit = 400 // int16 RW, mA (-1 = no limit, 0 = disabled)
enovatesRegToken = 401 // 16x register RO, ASCII enovatesRegToken = 401 // 16x register RO, ASCII
enovatesRegCurrentOffered = 417 // uint16 RO, mA enovatesRegCurrentOffered = 417 // uint16 RO, mA, current actually offered to the vehicle
enovatesRegSerial = 5032 // 16x register RO, ASCII enovatesRegSerial = 5032 // 16x register RO, ASCII
enovatesRegModel = 5048 // 16x register RO, ASCII enovatesRegModel = 5048 // 16x register RO, ASCII
enovatesRegFirmware = 5064 // 16x register RO, ASCII enovatesRegFirmware = 5064 // 16x register RO, ASCII
@ -92,9 +91,9 @@ func NewEnovates(ctx context.Context, settings modbus.TcpSettings) (api.Charger,
current: 6000, current: 6000,
} }
// verify connection and EMS register availability // the transaction token is only readable when EMS over Modbus TCP is enabled
if _, err := wb.conn.ReadHoldingRegisters(enovatesRegMode3StateStr, 2); err != nil { if _, err := wb.conn.ReadHoldingRegisters(enovatesRegToken, 16); err != nil {
return nil, err return nil, fmt.Errorf("ems over modbus tcp not enabled: %w", err)
} }
return wb, nil return wb, nil
@ -160,22 +159,13 @@ var _ api.CurrentGetter = (*Enovates)(nil)
// GetMaxCurrent implements the api.CurrentGetter interface // GetMaxCurrent implements the api.CurrentGetter interface
func (wb *Enovates) GetMaxCurrent() (float64, error) { func (wb *Enovates) GetMaxCurrent() (float64, error) {
b, err := wb.conn.ReadHoldingRegisters(enovatesRegEMSLimit, 1) // the EMS limit register may read -1 (no limit), hence use the actually offered current
b, err := wb.conn.ReadHoldingRegisters(enovatesRegCurrentOffered, 1)
if err != nil { if err != nil {
return 0, err return 0, err
} }
// -1 signals no EMS limit, fall back to the hardware maximum return float64(binary.BigEndian.Uint16(b)) / 1e3, nil
if limit := int16(binary.BigEndian.Uint16(b)); limit >= 0 {
return float64(limit) / 1e3, nil
}
b, err = wb.conn.ReadHoldingRegisters(enovatesRegMaxAmp, 1)
if err != nil {
return 0, err
}
return rs485.RTUUint16ToFloat64(b), nil
} }
var _ api.Meter = (*Enovates)(nil) var _ api.Meter = (*Enovates)(nil)