From bda2c7abc301945c0f317126a19785aa672e7568 Mon Sep 17 00:00:00 2001 From: andig Date: Mon, 25 Jul 2022 18:01:28 +0200 Subject: [PATCH] Ocpp: upgrade lib and embed central system (#3928) --- charger/ocpp.go | 18 +++++++++------- charger/ocpp/cs.go | 44 ++++++++++++++++++++++++---------------- charger/ocpp/cs_core.go | 4 ++-- charger/ocpp/instance.go | 6 +++--- go.mod | 2 +- go.sum | 4 ++-- 6 files changed, 46 insertions(+), 32 deletions(-) diff --git a/charger/ocpp.go b/charger/ocpp.go index 0e9a57ee6..e6d544393 100644 --- a/charger/ocpp.go +++ b/charger/ocpp.go @@ -81,7 +81,10 @@ func NewOCPPFromConfig(other map[string]interface{}) (api.Charger, error) { // NewOCPP creates OCPP charger func NewOCPP(id string, connector int, idtag string, hasMeter bool, meterInterval time.Duration, initialReset core.ResetType) (*OCPP, error) { - cp := ocpp.Instance().Register(id, hasMeter) + cp, err := ocpp.Instance().Register(id, hasMeter) + if err != nil { + return nil, err + } logstr := "-charger" if id != "" { @@ -107,7 +110,7 @@ func NewOCPP(id string, connector int, idtag string, hasMeter bool, meterInterva meterValuesSampleInterval string ) - err := ocpp.Instance().CS().GetConfiguration(id, func(resp *core.GetConfigurationConfirmation, err error) { + err = ocpp.Instance().GetConfiguration(id, func(resp *core.GetConfigurationConfirmation, err error) { options = resp.ConfigurationKey for _, opt := range options { @@ -150,8 +153,9 @@ func NewOCPP(id string, connector int, idtag string, hasMeter bool, meterInterva if hasMeter { if meterValuesSampledDataString != "Current.Import,Current.Offered,Energy.Active.Import.Register,Power.Active.Import,Temperature" { c.log.TRACE.Printf("Current values \n\t%s != \n\t%+v", ocpp.ValuePreferedMeterValuesSampleData, meterValuesSampledDataString) + rc = make(chan error, 1) - err = ocpp.Instance().CS().ChangeConfiguration(id, func(resp *core.ChangeConfigurationConfirmation, err error) { + err = ocpp.Instance().ChangeConfiguration(id, func(resp *core.ChangeConfigurationConfirmation, err error) { c.log.TRACE.Printf("ChangeMeterConfigurationRequest %T: %+v", resp, resp) if resp.Status == core.ConfigurationStatusRejected { @@ -171,7 +175,7 @@ func NewOCPP(id string, connector int, idtag string, hasMeter bool, meterInterva if meterValuesSampleInterval != intervalStr { rc = make(chan error, 1) - err := ocpp.Instance().CS().ChangeConfiguration(id, func(resp *core.ChangeConfigurationConfirmation, err error) { + err := ocpp.Instance().ChangeConfiguration(id, func(resp *core.ChangeConfigurationConfirmation, err error) { c.log.TRACE.Printf("ChangeSampleMeterValueInterval %T: %v", resp, resp) if resp.Status == core.ConfigurationStatusRejected { @@ -234,7 +238,7 @@ func (c *OCPP) Enable(enable bool) error { rc := make(chan error, 1) if enable { - err = ocpp.Instance().CS().RemoteStartTransaction(c.id, func(resp *core.RemoteStartTransactionConfirmation, err error) { + err = ocpp.Instance().RemoteStartTransaction(c.id, func(resp *core.RemoteStartTransactionConfirmation, err error) { c.log.TRACE.Printf("RemoteStartTransaction %T: %+v", resp, resp) if err == nil && resp != nil && resp.Status != types.RemoteStartStopStatusAccepted { @@ -246,7 +250,7 @@ func (c *OCPP) Enable(enable bool) error { request.ConnectorId = &c.connector }) } else { - err = ocpp.Instance().CS().RemoteStopTransaction(c.id, func(resp *core.RemoteStopTransactionConfirmation, err error) { + err = ocpp.Instance().RemoteStopTransaction(c.id, func(resp *core.RemoteStopTransactionConfirmation, err error) { c.log.TRACE.Printf("RemoteStopTransaction %T: %+v", resp, resp) if err == nil && resp != nil && resp.Status != types.RemoteStartStopStatusAccepted { @@ -265,7 +269,7 @@ func (c *OCPP) setChargingProfile(connectorid int, profile *types.ChargingProfil c.log.TRACE.Printf("SetChargingProfileRequest %T: %+v", profile.ChargingSchedule, profile.ChargingSchedule) rc := make(chan error, 1) - err := ocpp.Instance().CS().SetChargingProfile(c.id, func(resp *smartcharging.SetChargingProfileConfirmation, err error) { + err := ocpp.Instance().SetChargingProfile(c.id, func(resp *smartcharging.SetChargingProfileConfirmation, err error) { c.log.TRACE.Printf("SetChargingProfileResponse %T: %+v", resp, resp) if err == nil && resp != nil && resp.Status != smartcharging.ChargingProfileStatusAccepted { err = errors.New(string(resp.Status)) diff --git a/charger/ocpp/cs.go b/charger/ocpp/cs.go index bb66ad482..29b2daa5f 100644 --- a/charger/ocpp/cs.go +++ b/charger/ocpp/cs.go @@ -1,6 +1,7 @@ package ocpp import ( + "errors" "fmt" "sync" @@ -12,11 +13,11 @@ import ( type CS struct { mu sync.Mutex log *util.Logger - cs ocpp16.CentralSystem + ocpp16.CentralSystem cps map[string]*CP } -func (cs *CS) Register(id string, meterSupported bool) *CP { +func (cs *CS) Register(id string, meterSupported bool) (*CP, error) { cp := &CP{ id: id, log: util.NewLogger("ocpp-cp"), @@ -29,9 +30,13 @@ func (cs *CS) Register(id string, meterSupported bool) *CP { cs.mu.Lock() defer cs.mu.Unlock() + if _, ok := cs.cps[id]; ok && id == "" { + return nil, errors.New("cannot have >1 chargepoint with empty station id") + } + cs.cps[id] = cp - return cp + return cp, nil } // errorHandler logs error channel @@ -54,27 +59,32 @@ func (cs *CS) NewChargePoint(chargePoint ocpp16.ChargePointConnection) { defer cs.mu.Unlock() if _, err := cs.chargepointByID(chargePoint.ID()); err != nil { - cs.log.WARN.Println(err) + if auto, ok := cs.cps[""]; ok { + cs.log.INFO.Printf("unknown chargepoint connected, registering: %s", chargePoint.ID()) - cs.log.INFO.Printf("new chargepoint with ID (%s) detected, attempting to remap", chargePoint.ID()) - if unknownIDCP, ok := cs.cps[""]; ok && unknownIDCP != nil { - cs.mu.Lock() - unknownIDCP.id = chargePoint.ID() - cs.cps[chargePoint.ID()] = unknownIDCP - delete(cs.cps, "") // remove unknownID key - cs.mu.Unlock() + // update id + auto.id = chargePoint.ID() + cs.cps[chargePoint.ID()] = auto + delete(cs.cps, "") + + return } + + cs.log.WARN.Printf("unknown chargepoint connected, ignored: %s", chargePoint.ID()) + } else { + cs.log.DEBUG.Printf("chargepoint connected: %s", chargePoint.ID()) } } func (cs *CS) ChargePointDisconnected(chargePoint ocpp16.ChargePointConnection) { - if _, err := cs.chargepointByID(chargePoint.ID()); err != nil { - cs.log.ERROR.Println(err) - } -} + cs.mu.Lock() + defer cs.mu.Unlock() -func (cs *CS) CS() ocpp16.CentralSystem { - return cs.cs + if _, err := cs.chargepointByID(chargePoint.ID()); err != nil { + cs.log.ERROR.Printf("chargepoint disconnected: %v", err) + } else { + cs.log.DEBUG.Printf("chargepoint disconnected: %s", chargePoint.ID()) + } } func (cs *CS) Debug(args ...interface{}) { diff --git a/charger/ocpp/cs_core.go b/charger/ocpp/cs_core.go index 184d5bf1d..f4838bbd8 100644 --- a/charger/ocpp/cs_core.go +++ b/charger/ocpp/cs_core.go @@ -47,7 +47,7 @@ func (cs *CS) TriggerMeterValueRequest(cp *CP) { cs.log.TRACE.Printf("TriggerMessageRequest %T: %+v", request, request) } - if err := cs.cs.TriggerMessage(cp.id, callback, core.MeterValuesFeatureName); err != nil { + if err := cs.TriggerMessage(cp.id, callback, core.MeterValuesFeatureName); err != nil { cs.log.DEBUG.Printf("failed sending TriggerMessageRequest: %s", err) } } @@ -124,7 +124,7 @@ func (cs *CS) TriggerResetRequest(cp *CP, resetType core.ResetType) { cs.log.TRACE.Printf("TriggerResetRequest %T: %+v", request, request) } - if err := cs.cs.Reset(cp.id, callback, resetType); err != nil { + if err := cs.Reset(cp.id, callback, resetType); err != nil { cs.log.DEBUG.Printf("failed sending TriggerResetRequest: %s", err) } } diff --git a/charger/ocpp/instance.go b/charger/ocpp/instance.go index f1af42925..a0ae7d513 100644 --- a/charger/ocpp/instance.go +++ b/charger/ocpp/instance.go @@ -15,9 +15,9 @@ func Instance() *CS { cs := ocpp16.NewCentralSystem(nil, nil) instance = &CS{ - log: util.NewLogger("ocpp"), - cps: make(map[string]*CP), - cs: cs, + log: util.NewLogger("ocpp"), + cps: make(map[string]*CP), + CentralSystem: cs, } ocppj.SetLogger(instance) diff --git a/go.mod b/go.mod index 71a2dfbe9..2d4b36bbf 100644 --- a/go.mod +++ b/go.mod @@ -51,7 +51,7 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/koron/go-ssdp v0.0.3 github.com/korylprince/ipnetgen v1.0.1 - github.com/lorenzodonini/ocpp-go v0.15.0 + github.com/lorenzodonini/ocpp-go v0.16.0 github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 github.com/manifoldco/promptui v0.9.0 github.com/mergermarket/go-pkcs7 v0.0.0-20170926155232-153b18ea13c9 diff --git a/go.sum b/go.sum index d299db26b..34dfabcfe 100644 --- a/go.sum +++ b/go.sum @@ -596,8 +596,8 @@ github.com/lestrrat-go/jwx v1.2.24/go.mod h1:zoNuZymNl5lgdcu6P7K6ie2QRll5HVfF4xw github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lorenzodonini/ocpp-go v0.15.0 h1:hDMmK4dueTaEF/hk213tr/bOeWsBVZCmBCH0aml0QNo= -github.com/lorenzodonini/ocpp-go v0.15.0/go.mod h1:EiMdBqW0YO2Yq1JICuNxBZBaV5V4ygZM+C/h/6Xqu44= +github.com/lorenzodonini/ocpp-go v0.16.0 h1:+MsMvmZfUi0ac5jXS/Bevn7afM8UNUUiGjMbtwv4SgI= +github.com/lorenzodonini/ocpp-go v0.16.0/go.mod h1:EiMdBqW0YO2Yq1JICuNxBZBaV5V4ygZM+C/h/6Xqu44= github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc= github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=