Skip to content

Commit

Permalink
Add basic OCPP support (evcc-io#395)
Browse files Browse the repository at this point in the history
  • Loading branch information
andig authored Nov 21, 2020
1 parent 9bd8754 commit 29ea3c6
Show file tree
Hide file tree
Showing 20 changed files with 618 additions and 130 deletions.
21 changes: 19 additions & 2 deletions assets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,25 @@ <h2 class="value">
</div>

<div class="row" v-if="!multi">
<div class="col-12 col-md-4 d-none d-md-flex mt-3 mt-md-5 align-items-end">
<span class="h1 align-bottom">{{state.title||"Ladepunkt"}}</span>
<div class="col-12 col-md-4 d-none d-md-flex mt-3 mt-md-5 ">
<span class="h1 ">{{state.title||"Ladepunkt"}}</span>
</div>
<div class="col-12 col-md-8 mt-3 mt-md-5 align-items-end"
v-if="state.remoteDisabled">
<h1 class="d-md-inline d-none">
<span class="badge badge-warning font-base" v-if="state.remoteDisabled == 'soft'">
Adaptives PV-Laden deaktiviert durch {{state.remoteDisabledSource}}
</span>
<span class="badge badge-danger font-base" v-if="state.remoteDisabled == 'hard'">
Deaktiviert durch {{state.remoteDisabledSource}}
</span>
</h1>
<span class="d-md-none badge badge-warning font-base" v-if="state.remoteDisabled == 'soft'">
Adaptives PV-Laden deaktiviert durch {{state.remoteDisabledSource}}
</span>
<span class="d-md-none badge badge-danger font-base" v-if="state.remoteDisabled == 'hard'">
Deaktiviert durch {{state.remoteDisabledSource}}
</span>
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type config struct {
Interval time.Duration
Mqtt provider.MqttConfig
Influx server.InfluxConfig
HEMS string
HEMS typedConfig
Messaging messagingConfig
Meters []qualifiedConfig
Chargers []qualifiedConfig
Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func run(cmd *cobra.Command, args []string) {
httpd := server.NewHTTPd(uri, site, socketHub, cache)

// start HEMS server
if conf.HEMS != "" {
if conf.HEMS.Type != "" {
hems := configureHEMS(conf.HEMS, site, cache, httpd)
go hems.Run()
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ func configureMQTT(conf provider.MqttConfig) {
}

// setup HEMS
func configureHEMS(conf string, site *core.Site, cache *util.Cache, httpd *server.HTTPd) hems.HEMS {
hems, err := hems.NewFromConfig(conf, site, cache, httpd)
func configureHEMS(conf typedConfig, site *core.Site, cache *util.Cache, httpd *server.HTTPd) hems.HEMS {
hems, err := hems.NewFromConfig(conf.Type, conf.Other, site, cache, httpd)
if err != nil {
log.FATAL.Fatalf("failed configuring hems: %v", err)
}
Expand Down
29 changes: 28 additions & 1 deletion core/loadpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ type LoadPoint struct {

// cached state
status api.ChargeStatus // Charger status
remoteDemand RemoteDemand // External status demand
charging bool // Charging cycle
chargePower float64 // Charging power
connectedTime time.Time // Time when vehicle was connected
Expand Down Expand Up @@ -412,6 +413,14 @@ func (lp *LoadPoint) climateActive() bool {
return false
}

// remoteControlled returns true if remote control status is active
func (lp *LoadPoint) remoteControlled(demand RemoteDemand) bool {
lp.Lock()
defer lp.Unlock()

return lp.remoteDemand == demand
}

// setActiveVehicle assigns currently active vehicle and configures soc estimator
func (lp *LoadPoint) setActiveVehicle(vehicle api.Vehicle) {
if lp.vehicle != nil {
Expand Down Expand Up @@ -703,7 +712,7 @@ func (lp *LoadPoint) publishSoC() {
// Update is the main control function. It reevaluates meters and charger state
func (lp *LoadPoint) Update(sitePower float64) {
mode := lp.GetMode()
lp.publish("mode", string(mode))
lp.publish("mode", mode)

// read and publish meters first
lp.updateChargeMeter()
Expand Down Expand Up @@ -741,6 +750,9 @@ func (lp *LoadPoint) Update(sitePower float64) {
// check if car connected and ready for charging
var err error

// track if remote disabled is actually active
remoteDisabled := RemoteEnable

// execute loading strategy
switch {
case !lp.connected():
Expand All @@ -755,6 +767,11 @@ func (lp *LoadPoint) Update(sitePower float64) {
}
err = lp.handler.Ramp(targetCurrent, true)

// OCPP
case lp.remoteControlled(RemoteHardDisable):
remoteDisabled = RemoteHardDisable
fallthrough

case mode == api.ModeOff:
err = lp.handler.Ramp(0, true)

Expand All @@ -775,9 +792,19 @@ func (lp *LoadPoint) Update(sitePower float64) {
required = true
}

// Sunny Home Manager
if mode == api.ModePV && lp.remoteControlled(RemoteSoftDisable) {
remoteDisabled = RemoteSoftDisable
targetCurrent = 0
required = true
}

err = lp.handler.Ramp(targetCurrent, required)
}

// effective disabled status
lp.publish("remoteDisabled", remoteDisabled)

if err != nil {
lp.log.ERROR.Println(err)
}
Expand Down
19 changes: 19 additions & 0 deletions core/loadpoint_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type LoadPointSettingsAPI interface {
SetTargetSoC(int) error
GetMinSoC() int
SetMinSoC(int) error
RemoteControl(string, RemoteDemand)
}

// LoadPointEnergyAPI is the external loadpoint API
Expand Down Expand Up @@ -109,6 +110,24 @@ func (lp *LoadPoint) SetMinSoC(soc int) error {
return nil
}

// RemoteControl sets remote status demand
func (lp *LoadPoint) RemoteControl(source string, demand RemoteDemand) {
lp.Lock()
defer lp.Unlock()

lp.log.INFO.Println("remote demand:", demand)

// apply immediately
if lp.remoteDemand != demand {
lp.remoteDemand = demand

lp.publish("remoteDisabled", demand)
lp.publish("remoteDisabledSource", source)

lp.requestUpdate()
}
}

// HasChargeMeter determines if a physical charge meter is attached
func (lp *LoadPoint) HasChargeMeter() bool {
_, isWrapped := lp.chargeMeter.(*wrapper.ChargeMeter)
Expand Down
11 changes: 11 additions & 0 deletions core/remote.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package core

// RemoteDemand defines external status demand
type RemoteDemand string

// remote status demand definition
const (
RemoteEnable RemoteDemand = ""
RemoteHardDisable RemoteDemand = "hard"
RemoteSoftDisable RemoteDemand = "soft"
)
8 changes: 8 additions & 0 deletions core/site_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,11 @@ func (site *Site) SetMinSoC(soc int) error {
}
return nil
}

// RemoteControl sets remote status demand
func (site *Site) RemoteControl(source string, demand RemoteDemand) {
site.log.INFO.Println("remote demand:", demand)
for _, lp := range site.loadpoints {
lp.RemoteControl(source, demand)
}
}
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/avast/retry-go v2.6.0+incompatible
github.com/benbjohnson/clock v1.0.3
github.com/containrrr/shoutrrr v0.0.0-20200721140131-bafc331a1968
github.com/denisbrodbeck/machineid v1.0.1
github.com/eclipse/paho.mqtt.golang v1.2.0
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
github.com/godbus/dbus/v5 v5.0.3
Expand All @@ -29,6 +30,7 @@ require (
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d
github.com/kr/pretty v0.2.0 // indirect
github.com/lorenzodonini/ocpp-go v0.12.0
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40
github.com/mitchellh/mapstructure v1.3.2
github.com/mjibson/esc v0.2.0
Expand All @@ -44,7 +46,8 @@ require (
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c
github.com/volkszaehler/mbmd v0.0.0-20200831092453-b235d6a65b21
golang.org/x/net v0.0.0-20200707034311-ab3426394381
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/ini.v1 v1.57.0
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c
)

replace github.com/lorenzodonini/ocpp-go => github.com/andig/ocpp-go v0.12.1-0.20201110113243-43b1af9c1480
20 changes: 20 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ github.com/andig/evcc-config v0.0.0-20201030211256-8664d1cdae95 h1:GsXyGiwc3gf1X
github.com/andig/evcc-config v0.0.0-20201030211256-8664d1cdae95/go.mod h1:N0hIjIy+5E2AR1fF7Tg2IzBlblBrnFvCCaDGAaHzbWk=
github.com/andig/gosunspec v0.0.0-20200429133549-3cf6a82fed9c h1:AMtX56iHlNYVxMID7fe9efuVtaxgtdjyMeolg7q87IE=
github.com/andig/gosunspec v0.0.0-20200429133549-3cf6a82fed9c/go.mod h1:YkshK8WMzYn1iXAZzHUO75gIqhMSan2ctgBVtBkRIyA=
github.com/andig/ocpp-go v0.12.1-0.20201110090118-4fdb491db96c h1:2pVN47ILzwG8KkDMw+inI2VVLi+q2o4j1DEOhHIvGtA=
github.com/andig/ocpp-go v0.12.1-0.20201110090118-4fdb491db96c/go.mod h1:mN2Tv8bNqQlFMECj3IqcjZL7fOi3PmNnyVuEjICdxgU=
github.com/andig/ocpp-go v0.12.1-0.20201110113243-43b1af9c1480 h1:5yKucDmOcJ6vRNeAn7PCRqYwU3/UrPY4dhwBUoNR+ug=
github.com/andig/ocpp-go v0.12.1-0.20201110113243-43b1af9c1480/go.mod h1:mN2Tv8bNqQlFMECj3IqcjZL7fOi3PmNnyVuEjICdxgU=
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
Expand Down Expand Up @@ -60,6 +64,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/deepmap/oapi-codegen v1.3.6/go.mod h1:aBozjEveG+33xPiP55Iw/XbVkhtZHEGLq3nxlX0+hfU=
github.com/deepmap/oapi-codegen v1.3.9 h1:8e3ZfNFzwMDJ5kojta1GGS2+RjzWIThwDWgwe9GqQrE=
github.com/deepmap/oapi-codegen v1.3.9/go.mod h1:suMvK7+rKlx3+tpa8ByptmvoXbAV70wERKTOGH3hLp0=
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t2y2qayIX0=
Expand All @@ -85,6 +91,10 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM=
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU=
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
Expand Down Expand Up @@ -133,10 +143,12 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregdel/pushover v0.0.0-20200416074932-c8ad547caed4 h1:QZVozMeLCqyMOOhA+OuqQdNXkyu4uUQEu4+mPBB5pPQ=
Expand Down Expand Up @@ -228,6 +240,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
github.com/lestrrat-go/strftime v1.0.1 h1:o7qz5pmLzPDLyGW4lG6JvTKPUfTFXwe+vOamIYWtnVU=
Expand Down Expand Up @@ -317,6 +331,7 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
Expand Down Expand Up @@ -349,6 +364,7 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
Expand Down Expand Up @@ -550,6 +566,10 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v9 v9.30.0 h1:Wk0Z37oBmKj9/n+tPyBHZmeL19LaCoK3Qq48VwYENss=
gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww=
Expand Down
5 changes: 4 additions & 1 deletion hems/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"

"github.com/andig/evcc/core"
"github.com/andig/evcc/hems/ocpp"
"github.com/andig/evcc/hems/semp"
"github.com/andig/evcc/server"
"github.com/andig/evcc/util"
Expand All @@ -16,10 +17,12 @@ type HEMS interface {
}

// NewFromConfig creates new HEMS from config
func NewFromConfig(typ string, site *core.Site, cache *util.Cache, httpd *server.HTTPd) (HEMS, error) {
func NewFromConfig(typ string, other map[string]interface{}, site *core.Site, cache *util.Cache, httpd *server.HTTPd) (HEMS, error) {
switch strings.ToLower(typ) {
case "sma", "shm", "semp":
return semp.New(site, cache, httpd)
case "ocpp":
return ocpp.New(other, site, cache)
default:
return nil, errors.New("unknown hems: " + typ)
}
Expand Down
Loading

0 comments on commit 29ea3c6

Please sign in to comment.