From 78de1c7f1762d4a1ca57ed1af171647344b52b86 Mon Sep 17 00:00:00 2001 From: madmat17 Date: Sun, 8 Sep 2024 08:29:03 +0200 Subject: [PATCH 1/3] Delta AC Max: EVSE state interpretation depending on charger version --- charger/delta.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/charger/delta.go b/charger/delta.go index 987184a252..a13c44b42a 100644 --- a/charger/delta.go +++ b/charger/delta.go @@ -23,6 +23,7 @@ type Delta struct { curr float64 base uint16 enabled bool + isSmart bool // true = for Smart version, false = for Basic version } const ( @@ -116,6 +117,17 @@ func NewDelta(uri, device, comset string, baudrate int, proto modbus.Protocol, s } } + // Differentiate between Smart and Basic version (or Modbus TCP and RS485 respectively) + // Register 1001 is presented to RS485, but not implemented in Modbus TCP + _, err = wb.conn.ReadInputRegisters(wb.base+deltaRegEvseChargerState, 1) + if err == nil { + // If the value in deltaRegEvseChargerState can be read successfully, + // it indicates a RS485 connection, otherwise a legacy Modbus TCP connection + wb.isSmart = false + } else { + wb.isSmart = true + } + return wb, nil } @@ -153,7 +165,13 @@ func (wb *Delta) Status() (api.ChargeStatus, error) { switch s := encoding.Uint16(b); s { case 0, 1, 2: return api.StatusA, nil - case 3, 5, 6, 7, 9: + case 3: + if wb.isSmart { + return api.StatusB, nil + } else { + return api.StatusA, nil + } + case 5, 6, 7, 9: return api.StatusB, nil case 4: return api.StatusC, nil From 82b38d452402ad68ca7588d0210ff58cd8ba9309 Mon Sep 17 00:00:00 2001 From: premultiply <4681172+premultiply@users.noreply.github.com> Date: Sun, 8 Sep 2024 13:52:35 +0200 Subject: [PATCH 2/3] simplify --- charger/delta.go | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/charger/delta.go b/charger/delta.go index a13c44b42a..f6101b7c2b 100644 --- a/charger/delta.go +++ b/charger/delta.go @@ -23,7 +23,7 @@ type Delta struct { curr float64 base uint16 enabled bool - isSmart bool // true = for Smart version, false = for Basic version + isBasic bool } const ( @@ -102,6 +102,11 @@ func NewDelta(uri, device, comset string, baudrate int, proto modbus.Protocol, s wb.base = connector * 1000 + // check for basic or smart register set + if _, err := wb.conn.ReadInputRegisters(wb.base+deltaRegEvseChargerState, 1); err != nil { + wb.isBasic = true + } + b, err := wb.conn.ReadHoldingRegisters(deltaRegCommunicationTimeoutEnabled, 1) if err != nil { return nil, fmt.Errorf("failsafe timeout enabled: %w", err) @@ -117,17 +122,6 @@ func NewDelta(uri, device, comset string, baudrate int, proto modbus.Protocol, s } } - // Differentiate between Smart and Basic version (or Modbus TCP and RS485 respectively) - // Register 1001 is presented to RS485, but not implemented in Modbus TCP - _, err = wb.conn.ReadInputRegisters(wb.base+deltaRegEvseChargerState, 1) - if err == nil { - // If the value in deltaRegEvseChargerState can be read successfully, - // it indicates a RS485 connection, otherwise a legacy Modbus TCP connection - wb.isSmart = false - } else { - wb.isSmart = true - } - return wb, nil } @@ -166,11 +160,10 @@ func (wb *Delta) Status() (api.ChargeStatus, error) { case 0, 1, 2: return api.StatusA, nil case 3: - if wb.isSmart { - return api.StatusB, nil - } else { + if wb.isBasic { return api.StatusA, nil } + return api.StatusB, nil case 5, 6, 7, 9: return api.StatusB, nil case 4: From 1a9888807880f915c6edc3ac91b577d00fedeb79 Mon Sep 17 00:00:00 2001 From: premultiply <4681172+premultiply@users.noreply.github.com> Date: Sun, 8 Sep 2024 13:53:23 +0200 Subject: [PATCH 3/3] add StatusReasoner --- charger/delta.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/charger/delta.go b/charger/delta.go index f6101b7c2b..4b921fe93e 100644 --- a/charger/delta.go +++ b/charger/delta.go @@ -173,6 +173,27 @@ func (wb *Delta) Status() (api.ChargeStatus, error) { } } +var _ api.StatusReasoner = (*Delta)(nil) + +// statusReason implements the api.StatusReasoner interface +func (wb *Delta) StatusReason() (api.Reason, error) { + if !wb.isBasic { + b, err := wb.conn.ReadInputRegisters(wb.base+deltaRegEvseState, 1) + if err != nil { + return api.ReasonUnknown, err + } + + switch s := encoding.Uint16(b); s { + case 3: + return api.ReasonWaitingForAuthorization, nil + case 5: + return api.ReasonDisconnectRequired, nil + } + } + + return api.ReasonUnknown, nil +} + // Enabled implements the api.Charger interface func (wb *Delta) Enabled() (bool, error) { b, err := wb.conn.ReadHoldingRegisters(wb.base+deltaRegEvseChargingPowerLimit, 2)