Skip to content

Commit

Permalink
Ocpp: modularise setup (#15369)
Browse files Browse the repository at this point in the history
  • Loading branch information
andig authored Aug 24, 2024
1 parent 95ad434 commit e466564
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 90 deletions.
97 changes: 7 additions & 90 deletions charger/ocpp.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/evcc-io/evcc/core/loadpoint"
"github.com/evcc-io/evcc/util"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/core"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
)
Expand Down Expand Up @@ -160,10 +159,11 @@ func NewOCPP(id string, connector int, idtag string,
}

c := &OCPP{
log: log,
conn: conn,
idtag: idtag,
remoteStart: remoteStart,
log: log,
conn: conn,
idtag: idtag,
remoteStart: remoteStart,

chargingRateUnit: types.ChargingRateUnitType(chargingRateUnit),
timeout: timeout,
}
Expand All @@ -179,91 +179,8 @@ func NewOCPP(id string, connector int, idtag string,
// fix timing issue in EVBox when switching OCPP protocol version
time.Sleep(time.Second)

var rc = make(chan error, 1)

meterValuesSampledData := ""
meterValuesSampledDataMaxLength := len(strings.Split(desiredMeasurands, ","))

c.hasRemoteTriggerFeature = true // assume remote trigger feature is available

err = ocpp.Instance().GetConfiguration(cp.ID(), func(resp *core.GetConfigurationConfirmation, err error) {
if err == nil {
for _, opt := range resp.ConfigurationKey {
if opt.Value == nil {
continue
}

switch opt.Key {
case ocpp.KeyChargeProfileMaxStackLevel:
if val, err := strconv.Atoi(*opt.Value); err == nil {
c.stackLevel = val
}

case ocpp.KeyChargingScheduleAllowedChargingRateUnit:
if *opt.Value == "Power" || *opt.Value == "W" { // "W" is not allowed by spec but used by some CPs
c.chargingRateUnit = types.ChargingRateUnitWatts
}

case ocpp.KeyConnectorSwitch3to1PhaseSupported:
var val bool
if val, err = strconv.ParseBool(*opt.Value); err == nil {
c.phaseSwitching = val
}

case ocpp.KeyMaxChargingProfilesInstalled:
if val, err := strconv.Atoi(*opt.Value); err == nil {
c.chargingProfileId = val
}

case ocpp.KeyMeterValuesSampledData:
if opt.Readonly {
meterValuesSampledDataMaxLength = 0
}
meterValuesSampledData = *opt.Value

case ocpp.KeyMeterValuesSampledDataMaxLength:
if val, err := strconv.Atoi(*opt.Value); err == nil {
meterValuesSampledDataMaxLength = val
}

case ocpp.KeyNumberOfConnectors:
var val int
if val, err = strconv.Atoi(*opt.Value); err == nil && connector > val {
err = fmt.Errorf("connector %d exceeds max available connectors: %d", connector, val)
}

case ocpp.KeySupportedFeatureProfiles:
if !c.hasProperty(*opt.Value, smartcharging.ProfileName) {
c.log.WARN.Printf("the required SmartCharging feature profile is not indicated as supported")
}
// correct the availability assumption of RemoteTrigger only in case of a valid looking FeatureProfile list
if c.hasProperty(*opt.Value, core.ProfileName) {
c.hasRemoteTriggerFeature = c.hasProperty(*opt.Value, remotetrigger.ProfileName)
}

// vendor-specific keys
case ocpp.KeyAlfenPlugAndChargeIdentifier:
if c.idtag == defaultIdTag {
c.idtag = *opt.Value
c.log.DEBUG.Printf("overriding default `idTag` with Alfen-specific value: %s", c.idtag)
}

case ocpp.KeyEvBoxSupportedMeasurands:
if meterValues == "" {
meterValues = *opt.Value
}
}

if err != nil {
break
}
}
}

rc <- err
}, nil)

if err := c.wait(err, rc); err != nil {
meterValuesSampledData, meterValuesSampledDataMaxLength, err := c.getConfiguration(cp.ID(), connector)
if err != nil {
return nil, err
}

Expand Down
91 changes: 91 additions & 0 deletions charger/ocpp_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package charger

import (
"fmt"
"strconv"
"strings"

"github.com/evcc-io/evcc/charger/ocpp"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/core"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/remotetrigger"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/smartcharging"
"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
)

func (c *OCPP) getConfiguration(id string, connector int) (string, int, error) {
var meterValuesSampledData string
meterValuesSampledDataMaxLength := len(strings.Split(desiredMeasurands, ","))

rc := make(chan error, 1)

err := ocpp.Instance().GetConfiguration(id, func(resp *core.GetConfigurationConfirmation, err error) {
if err == nil {
for _, opt := range resp.ConfigurationKey {
if opt.Value == nil {
continue
}

switch opt.Key {
case ocpp.KeyChargeProfileMaxStackLevel:
if val, err := strconv.Atoi(*opt.Value); err == nil {
c.stackLevel = val
}

case ocpp.KeyChargingScheduleAllowedChargingRateUnit:
if *opt.Value == "Power" || *opt.Value == "W" { // "W" is not allowed by spec but used by some CPs
c.chargingRateUnit = types.ChargingRateUnitWatts
}

case ocpp.KeyConnectorSwitch3to1PhaseSupported:
var val bool
if val, err = strconv.ParseBool(*opt.Value); err == nil {
c.phaseSwitching = val
}

case ocpp.KeyMaxChargingProfilesInstalled:
if val, err := strconv.Atoi(*opt.Value); err == nil {
c.chargingProfileId = val
}

case ocpp.KeyMeterValuesSampledData:
if opt.Readonly {
meterValuesSampledDataMaxLength = 0
}
meterValuesSampledData = *opt.Value

case ocpp.KeyMeterValuesSampledDataMaxLength:
if val, err := strconv.Atoi(*opt.Value); err == nil {
meterValuesSampledDataMaxLength = val
}

case ocpp.KeyNumberOfConnectors:
var val int
if val, err = strconv.Atoi(*opt.Value); err == nil && connector > val {
err = fmt.Errorf("connector %d exceeds max available connectors: %d", connector, val)
}

case ocpp.KeySupportedFeatureProfiles:
if !c.hasProperty(*opt.Value, smartcharging.ProfileName) {
err = fmt.Errorf("the mandatory SmartCharging profile is not supported")
}
c.hasRemoteTriggerFeature = c.hasProperty(*opt.Value, remotetrigger.ProfileName)

// vendor-specific keys
case ocpp.KeyAlfenPlugAndChargeIdentifier:
if c.idtag == defaultIdTag {
c.idtag = *opt.Value
c.log.DEBUG.Printf("overriding default `idTag` with Alfen-specific value: %s", c.idtag)
}
}

if err != nil {
break
}
}
}

rc <- err
}, nil)

return meterValuesSampledData, meterValuesSampledDataMaxLength, c.wait(err, rc)
}

0 comments on commit e466564

Please sign in to comment.