From 03cf93f9e8b9f805ecfaace4a67273ce4385fdfa Mon Sep 17 00:00:00 2001 From: premultiply <4681172+premultiply@users.noreply.github.com> Date: Fri, 11 Nov 2022 13:08:58 +0100 Subject: [PATCH] ABB TACW fw ver 1.6.5 adaptions (#4626) Charger improvements for ABB Terra AC Wallbox with firmware version 1.6.5 (and newer?) from Nov 2022. !!! Will break compatibility with older firmware - you have to upgrade the firmware to use the charger !!! New: Vehicle connection detection outside of an active session New: Getting an enabled state outside of an active session now New: Setting max current outside of an active session now Charger implementation allows to switch modbus protocol (rtu or tcp) now Firmware 1.6.5 still has some crazy "non-linear" behavior regarding the sent, applied and read-back max current.. --- charger/abb.go | 57 +++++++++------------------ templates/definition/charger/abb.yaml | 3 ++ templates/docs/charger/abb_0.yaml | 2 + 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/charger/abb.go b/charger/abb.go index 14bdef233..122710f31 100644 --- a/charger/abb.go +++ b/charger/abb.go @@ -30,7 +30,6 @@ import ( // ABB charger implementation type ABB struct { - log *util.Logger conn *modbus.Connection curr uint32 } @@ -40,6 +39,7 @@ const ( abbRegFirmware = 0x4004 // Firmware version 2 unsigned RO available abbRegMaxRated = 0x4006 // Max rated current 2 unsigned RO available abbRegErrorCode = 0x4008 // Error Code 2 unsigned RO available + abbRegSocketLock = 0x400A // Socket Lock State 2 unsigned RO available abbRegStatus = 0x400C // Charging state 2 unsigned RO available abbRegGetCurrent = 0x400E // Current charging current limit 2 0.001 A unsigned RO abbRegCurrents = 0x4010 // Charging current phases 6 0.001 A unsigned RO available @@ -48,8 +48,6 @@ const ( abbRegSetCurrent = 0x4100 // Set charging current limit 2 0.001 A unsigned WO available // abbRegSession = 0x4105 // Start/Stop Charging Session 1 unsigned WO available // abbRegPhases = 0x4102 // Set charging phase 1 unsigned WO Not supported - - abbMinCurrent = 0x1720 // 5920 mA ) func init() { @@ -59,21 +57,19 @@ func init() { // NewABBFromConfig creates a ABB charger from generic config func NewABBFromConfig(other map[string]interface{}) (api.Charger, error) { cc := modbus.Settings{ - ID: 1, - Baudrate: 9600, - Comset: "8N1", + ID: 1, } if err := util.DecodeOther(other, &cc); err != nil { return nil, err } - return NewABB(cc.URI, cc.Device, cc.Comset, cc.Baudrate, cc.ID) + return NewABB(cc.URI, cc.Device, cc.Comset, cc.Baudrate, modbus.ProtocolFromRTU(cc.RTU), cc.ID) } // NewABB creates ABB charger -func NewABB(uri, device, comset string, baudrate int, slaveID uint8) (api.Charger, error) { - conn, err := modbus.NewConnection(uri, device, comset, baudrate, modbus.Rtu, slaveID) +func NewABB(uri, device, comset string, baudrate int, proto modbus.Protocol, slaveID uint8) (api.Charger, error) { + conn, err := modbus.NewConnection(uri, device, comset, baudrate, proto, slaveID) if err != nil { return nil, err } @@ -86,9 +82,8 @@ func NewABB(uri, device, comset string, baudrate int, slaveID uint8) (api.Charge conn.Logger(log.TRACE) wb := &ABB{ - log: log, conn: conn, - curr: abbMinCurrent, // assume min current + curr: 6000, // assume min current } // keep-alive @@ -110,15 +105,6 @@ func (wb *ABB) status() (byte, error) { return b[2] & 0x7f, nil } -func (wb *ABB) session() (bool, error) { - s, err := wb.status() - if err != nil || s == 0 || s == 5 { // ToDo: check if 1 is active/inactive/unknown - return false, err - } - - return true, err -} - // Status implements the api.Charger interface func (wb *ABB) Status() (api.ChargeStatus, error) { s, err := wb.status() @@ -138,6 +124,13 @@ func (wb *ABB) Status() (api.ChargeStatus, error) { case 4: // State C2: Charging Contact closed, energy delivering return api.StatusC, nil case 5: // Other: Session stopped + b, err := wb.conn.ReadHoldingRegisters(abbRegSocketLock, 2) + if err != nil { + return api.StatusNone, err + } + if binary.BigEndian.Uint32(b) >= 0x0101 { + return api.StatusB, nil + } return api.StatusA, nil default: // Other return api.StatusNone, fmt.Errorf("invalid status: %0x", s) @@ -146,26 +139,16 @@ func (wb *ABB) Status() (api.ChargeStatus, error) { // Enabled implements the api.Charger interface func (wb *ABB) Enabled() (bool, error) { - s, err := wb.session() - if err != nil || !s { - return false, err - } - b, err := wb.conn.ReadHoldingRegisters(abbRegGetCurrent, 2) if err != nil { return false, err } - return binary.BigEndian.Uint32(b) >= abbMinCurrent, nil + return binary.BigEndian.Uint32(b) != 0, nil } // Enable implements the api.Charger interface func (wb *ABB) Enable(enable bool) error { - s, err := wb.session() - if err != nil || !s { - return err - } - var current uint32 if enable { current = wb.curr @@ -196,11 +179,6 @@ func (wb *ABB) MaxCurrentMillis(current float64) error { return fmt.Errorf("invalid current %.1f", current) } - s, err := wb.session() - if err != nil || !s { - return err - } - wb.curr = uint32(current * 1e3) return wb.setCurrent(wb.curr) @@ -271,10 +249,13 @@ func (wb *ABB) Diagnose() { fmt.Printf("\tFirmware:\t%d.%d.%d\n", b[0], b[1], b[2]) } if b, err := wb.conn.ReadHoldingRegisters(abbRegMaxRated, 2); err == nil { - fmt.Printf("\tMax rated current:\t%.1fA\n", float32(binary.BigEndian.Uint32(b))/1e3) + fmt.Printf("\tMax rated current:\t%dmA\n", binary.BigEndian.Uint32(b)) } if b, err := wb.conn.ReadHoldingRegisters(abbRegGetCurrent, 2); err == nil { - fmt.Printf("\tCharging current limit:\t%.1fA\n", float32(binary.BigEndian.Uint32(b))/1e3) + fmt.Printf("\tCharging current limit:\t%dmA\n", binary.BigEndian.Uint32(b)) + } + if b, err := wb.conn.ReadHoldingRegisters(abbRegSocketLock, 2); err == nil { + fmt.Printf("\tSocket lock state:\t%x\n", b) } if b, err := wb.conn.ReadHoldingRegisters(abbRegStatus, 2); err == nil { fmt.Printf("\tStatus:\t%x\n", b) diff --git a/templates/definition/charger/abb.yaml b/templates/definition/charger/abb.yaml index 79445cb7d..0ddc3fbb1 100644 --- a/templates/definition/charger/abb.yaml +++ b/templates/definition/charger/abb.yaml @@ -5,6 +5,9 @@ products: generic: Terra AC capabilities: ["mA"] requirements: + description: + de: Erfordert Firmware >= 1.6.5 + en: Requires firmware >= 1.6.5 evcc: ["sponsorship"] params: - name: modbus diff --git a/templates/docs/charger/abb_0.yaml b/templates/docs/charger/abb_0.yaml index 0aff9ab58..4ccc7ed85 100644 --- a/templates/docs/charger/abb_0.yaml +++ b/templates/docs/charger/abb_0.yaml @@ -3,6 +3,8 @@ product: description: Terra AC capabilities: ["mA"] requirements: ["sponsorship"] +description: | + Erfordert Firmware >= 1.6.5 render: - default: | type: template