Ocpp: modularise setup (#15369)
This commit is contained in:
parent
95ad4346fd
commit
e466564c56
2 changed files with 98 additions and 90 deletions
|
|
@ -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"
|
||||
)
|
||||
|
|
@ -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,
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
91
charger/ocpp_config.go
Normal file
91
charger/ocpp_config.go
Normal file
|
|
@ -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)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue