From befbbd275bba2196fe28e2018084c655e9e095d9 Mon Sep 17 00:00:00 2001 From: Michael Hess Date: Sat, 5 Aug 2023 10:25:57 +0200 Subject: [PATCH 01/11] use start cmd when auth req, enabled throws when auth req --- charger/easee.go | 5 ++++- charger/easee/types.go | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/charger/easee.go b/charger/easee.go index 8c085c08fa..5dfd954c13 100644 --- a/charger/easee.go +++ b/charger/easee.go @@ -408,7 +408,7 @@ func (c *Easee) Enable(enable bool) error { } // do not send pause/resume if disconnected or unauthenticated - if c.opMode == easee.ModeDisconnected || c.opMode == easee.ModeAwaitingAuthentication { + if c.opMode == easee.ModeDisconnected || (c.opMode == easee.ModeAwaitingAuthentication && !enable) { return nil } @@ -418,6 +418,9 @@ func (c *Easee) Enable(enable bool) error { var targetCurrent float64 if enable { action = easee.ChargeResume + if c.opMode == easee.ModeAwaitingAuthentication { + action = easee.ChargeStart + } expectedEnabledState = true targetCurrent = 32 } diff --git a/charger/easee/types.go b/charger/easee/types.go index ae3b223da5..0184432387 100644 --- a/charger/easee/types.go +++ b/charger/easee/types.go @@ -4,6 +4,7 @@ package easee const API = "https://api.easee.com/api" const ( + ChargeStart = "start_charging" ChargePause = "pause_charging" ChargeResume = "resume_charging" ) From 27be0722360056463f7066e1de96a848325d6a97 Mon Sep 17 00:00:00 2001 From: Michael Hess Date: Mon, 21 Aug 2023 18:12:01 +0200 Subject: [PATCH 02/11] make automatic authorization configurable --- charger/easee.go | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/charger/easee.go b/charger/easee.go index 5dfd954c13..011aa60c0a 100644 --- a/charger/easee.go +++ b/charger/easee.go @@ -53,6 +53,7 @@ type Easee struct { current float64 chargerEnabled bool smartCharging bool + authorize bool opMode int reasonForNoCurrent int phaseMode int @@ -72,10 +73,11 @@ func init() { // NewEaseeFromConfig creates a go-e charger from generic config func NewEaseeFromConfig(other map[string]interface{}) (api.Charger, error) { cc := struct { - User string - Password string - Charger string - Timeout time.Duration + User string + Password string + Charger string + Timeout time.Duration + authorize bool }{ Timeout: request.Timeout, } @@ -88,11 +90,11 @@ func NewEaseeFromConfig(other map[string]interface{}) (api.Charger, error) { return nil, api.ErrMissingCredentials } - return NewEasee(cc.User, cc.Password, cc.Charger, cc.Timeout) + return NewEasee(cc.User, cc.Password, cc.Charger, cc.Timeout, cc.authorize) } // NewEasee creates Easee charger -func NewEasee(user, password, charger string, timeout time.Duration) (*Easee, error) { +func NewEasee(user, password, charger string, timeout time.Duration, authorize bool) (*Easee, error) { log := util.NewLogger("easee").Redact(user, password) if !sponsor.IsAuthorized() { @@ -100,14 +102,15 @@ func NewEasee(user, password, charger string, timeout time.Duration) (*Easee, er } c := &Easee{ - Helper: request.NewHelper(log), - charger: charger, - log: log, - current: 6, // default current - done: make(chan struct{}), - cmdC: make(chan easee.SignalRCommandResponse), - obsC: make(chan easee.Observation), - obsTime: make(map[easee.ObservationID]time.Time), + Helper: request.NewHelper(log), + charger: charger, + authorize: authorize, + log: log, + current: 6, // default current + done: make(chan struct{}), + cmdC: make(chan easee.SignalRCommandResponse), + obsC: make(chan easee.Observation), + obsTime: make(map[easee.ObservationID]time.Time), } c.Client.Timeout = timeout @@ -407,8 +410,8 @@ func (c *Easee) Enable(enable bool) error { } } - // do not send pause/resume if disconnected or unauthenticated - if c.opMode == easee.ModeDisconnected || (c.opMode == easee.ModeAwaitingAuthentication && !enable) { + // do not send pause/resume if disconnected or unauthenticated without automatic authorization + if c.opMode == easee.ModeDisconnected || (c.opMode == easee.ModeAwaitingAuthentication && (!enable || !c.authorize)) { return nil } @@ -418,7 +421,7 @@ func (c *Easee) Enable(enable bool) error { var targetCurrent float64 if enable { action = easee.ChargeResume - if c.opMode == easee.ModeAwaitingAuthentication { + if c.opMode == easee.ModeAwaitingAuthentication && c.authorize { action = easee.ChargeStart } expectedEnabledState = true From 815c92e1d1b40c118d09d3b667fab746c36f2f71 Mon Sep 17 00:00:00 2001 From: Michael Hess Date: Mon, 21 Aug 2023 20:51:13 +0200 Subject: [PATCH 03/11] adjust config templates --- templates/definition/charger/easee.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/templates/definition/charger/easee.yaml b/templates/definition/charger/easee.yaml index b3b6329c50..5c2d83fca3 100644 --- a/templates/definition/charger/easee.yaml +++ b/templates/definition/charger/easee.yaml @@ -23,9 +23,12 @@ params: example: EH______ - name: timeout default: 10s + - name: authorize + default: false render: | type: easee user: {{ .user }} password: {{ .password }} charger: {{ .charger }} timeout: {{ .timeout }} + authorize: {{ .authorize }} From 72709daa2bb9b929d942b701f754dcfa841076b9 Mon Sep 17 00:00:00 2001 From: Michael Hess Date: Mon, 21 Aug 2023 21:10:45 +0200 Subject: [PATCH 04/11] fix capitalization --- charger/easee.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charger/easee.go b/charger/easee.go index 011aa60c0a..ea78f40467 100644 --- a/charger/easee.go +++ b/charger/easee.go @@ -77,7 +77,7 @@ func NewEaseeFromConfig(other map[string]interface{}) (api.Charger, error) { Password string Charger string Timeout time.Duration - authorize bool + Authorize bool }{ Timeout: request.Timeout, } @@ -90,7 +90,7 @@ func NewEaseeFromConfig(other map[string]interface{}) (api.Charger, error) { return nil, api.ErrMissingCredentials } - return NewEasee(cc.User, cc.Password, cc.Charger, cc.Timeout, cc.authorize) + return NewEasee(cc.User, cc.Password, cc.Charger, cc.Timeout, cc.Authorize) } // NewEasee creates Easee charger From 34586e4e22e0256cd588377773da51e9cffc7872 Mon Sep 17 00:00:00 2001 From: Michael Hess Date: Wed, 23 Aug 2023 20:05:24 +0200 Subject: [PATCH 05/11] consider AwaitingAuth a disabled state --- charger/easee.go | 1 + 1 file changed, 1 insertion(+) diff --git a/charger/easee.go b/charger/easee.go index ea78f40467..c09abda339 100644 --- a/charger/easee.go +++ b/charger/easee.go @@ -388,6 +388,7 @@ func (c *Easee) Enabled() (bool, error) { disabled := c.opMode == easee.ModeDisconnected || c.opMode == easee.ModeCompleted || + c.opMode == easee.ModeAwaitingAuthentication || (c.opMode == easee.ModeAwaitingStart && c.reasonForNoCurrent == 52) return !disabled && c.dynamicChargerCurrent > 0, nil } From 5a61634485ef6761a9eb271606df36753a9eefcf Mon Sep 17 00:00:00 2001 From: Michael Hess Date: Sat, 26 Aug 2023 14:04:06 +0200 Subject: [PATCH 06/11] When in authorization mode, use stop charge instead of pause --- charger/easee.go | 3 +++ charger/easee/types.go | 1 + 2 files changed, 4 insertions(+) diff --git a/charger/easee.go b/charger/easee.go index c09abda339..3f17d09d8d 100644 --- a/charger/easee.go +++ b/charger/easee.go @@ -418,6 +418,9 @@ func (c *Easee) Enable(enable bool) error { // resume/stop charger action := easee.ChargePause + if c.authorize { + action = easee.ChargeStop + } var expectedEnabledState bool var targetCurrent float64 if enable { diff --git a/charger/easee/types.go b/charger/easee/types.go index 0184432387..094acb92fd 100644 --- a/charger/easee/types.go +++ b/charger/easee/types.go @@ -5,6 +5,7 @@ const API = "https://api.easee.com/api" const ( ChargeStart = "start_charging" + ChargeStop = "stop_charging" ChargePause = "pause_charging" ChargeResume = "resume_charging" ) From cafcc8de70385b87cd5089a8a418de31e8274f3b Mon Sep 17 00:00:00 2001 From: Michael Hess Date: Sun, 27 Aug 2023 20:55:18 +0200 Subject: [PATCH 07/11] no waiting for 32A nor cur reset after start --- charger/easee.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/charger/easee.go b/charger/easee.go index 3f17d09d8d..57e9b74714 100644 --- a/charger/easee.go +++ b/charger/easee.go @@ -441,13 +441,16 @@ func (c *Easee) Enable(enable bool) error { if err := c.waitForChargerEnabledState(expectedEnabledState); err != nil { return err } - if err := c.waitForDynamicChargerCurrent(targetCurrent); err != nil { - return err - } - if enable { - // reset currents after enable, as easee automatically resets to maxA - return c.MaxCurrent(int64(c.current)) + if !c.authorize { // authenticating charger does not mingle with DCC, no need for waiting + if err := c.waitForDynamicChargerCurrent(targetCurrent); err != nil { + return err + } + + if enable { + // reset currents after enable, as easee automatically resets to maxA + return c.MaxCurrent(int64(c.current)) + } } return nil From 66345b01859d2d2b0215756daf9e342919022067 Mon Sep 17 00:00:00 2001 From: Michael Hess Date: Mon, 4 Sep 2023 21:35:58 +0200 Subject: [PATCH 08/11] address code review comments --- charger/easee.go | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/charger/easee.go b/charger/easee.go index 57e9b74714..00c92437fd 100644 --- a/charger/easee.go +++ b/charger/easee.go @@ -411,8 +411,11 @@ func (c *Easee) Enable(enable bool) error { } } + c.mux.Lock() + opMode := c.opMode + c.mux.Unlock() // do not send pause/resume if disconnected or unauthenticated without automatic authorization - if c.opMode == easee.ModeDisconnected || (c.opMode == easee.ModeAwaitingAuthentication && (!enable || !c.authorize)) { + if opMode == easee.ModeDisconnected || (opMode == easee.ModeAwaitingAuthentication && !(enable && c.authorize)) { return nil } @@ -425,7 +428,7 @@ func (c *Easee) Enable(enable bool) error { var targetCurrent float64 if enable { action = easee.ChargeResume - if c.opMode == easee.ModeAwaitingAuthentication && c.authorize { + if opMode == easee.ModeAwaitingAuthentication && c.authorize { action = easee.ChargeStart } expectedEnabledState = true @@ -442,15 +445,17 @@ func (c *Easee) Enable(enable bool) error { return err } - if !c.authorize { // authenticating charger does not mingle with DCC, no need for waiting - if err := c.waitForDynamicChargerCurrent(targetCurrent); err != nil { - return err - } + if c.authorize { // authenticating charger does not mingle with DCC, no need for below operations + return nil + } - if enable { - // reset currents after enable, as easee automatically resets to maxA - return c.MaxCurrent(int64(c.current)) - } + if err := c.waitForDynamicChargerCurrent(targetCurrent); err != nil { + return err + } + + if enable { + // reset currents after enable, as easee automatically resets to maxA + return c.MaxCurrent(int64(c.current)) } return nil From 7c58a6ca75661fddfecceabf6965816d915659eb Mon Sep 17 00:00:00 2001 From: Michael Hess Date: Mon, 4 Sep 2023 21:42:40 +0200 Subject: [PATCH 09/11] add description of new config option for authorization --- templates/definition/charger/easee.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/templates/definition/charger/easee.yaml b/templates/definition/charger/easee.yaml index 5c2d83fca3..6bd7e7f956 100644 --- a/templates/definition/charger/easee.yaml +++ b/templates/definition/charger/easee.yaml @@ -25,6 +25,9 @@ params: default: 10s - name: authorize default: false + help: + de: Steuert ob evcc die Authentifizierung am Charger vornimmt. Vorteil ist ein kontrollierter Ladestart. Nicht kompatibel mit RFID Identifikation von Fahrzeugen. + en: Controls wether evcc shall perform authentication against charger. Benefit is a contolled start of charging. Not compatible with RFID identification of vehicles. render: | type: easee user: {{ .user }} From 6bb5004fb4d489e30d43b6ade3e5286b8128a332 Mon Sep 17 00:00:00 2001 From: Michael Hess Date: Mon, 4 Sep 2023 21:43:51 +0200 Subject: [PATCH 10/11] removed superflous default --- templates/definition/charger/easee.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/definition/charger/easee.yaml b/templates/definition/charger/easee.yaml index 6bd7e7f956..d6dcdb6a27 100644 --- a/templates/definition/charger/easee.yaml +++ b/templates/definition/charger/easee.yaml @@ -24,7 +24,6 @@ params: - name: timeout default: 10s - name: authorize - default: false help: de: Steuert ob evcc die Authentifizierung am Charger vornimmt. Vorteil ist ein kontrollierter Ladestart. Nicht kompatibel mit RFID Identifikation von Fahrzeugen. en: Controls wether evcc shall perform authentication against charger. Benefit is a contolled start of charging. Not compatible with RFID identification of vehicles. From f75724e085ba37986d6aaa4e9906504cc1724c93 Mon Sep 17 00:00:00 2001 From: Michael Hess Date: Mon, 4 Sep 2023 22:52:04 +0200 Subject: [PATCH 11/11] get rid of superflous lock --- charger/easee.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/charger/easee.go b/charger/easee.go index 00c92437fd..e273e7c8a0 100644 --- a/charger/easee.go +++ b/charger/easee.go @@ -397,6 +397,7 @@ func (c *Easee) Enabled() (bool, error) { func (c *Easee) Enable(enable bool) error { c.mux.Lock() enablingRequired := enable && !c.chargerEnabled + opMode := c.opMode c.mux.Unlock() // enable charger once if it's switched off @@ -411,9 +412,6 @@ func (c *Easee) Enable(enable bool) error { } } - c.mux.Lock() - opMode := c.opMode - c.mux.Unlock() // do not send pause/resume if disconnected or unauthenticated without automatic authorization if opMode == easee.ModeDisconnected || (opMode == easee.ModeAwaitingAuthentication && !(enable && c.authorize)) { return nil