From 4b2ca9df4247f66214e8f60c8a1014e9c72a1c14 Mon Sep 17 00:00:00 2001 From: andig Date: Fri, 18 Dec 2020 11:56:26 +0100 Subject: [PATCH] Make SHM control configurable (#530) --- README.md | 1 + hems/config.go | 2 +- hems/semp/semp.go | 44 ++++++++++++++++++++++++++++++-------------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index dad1937b3..f540df996 100644 --- a/README.md +++ b/README.md @@ -240,6 +240,7 @@ EVCC can integrate itself with Home Energy Management Systems. At this time, the ```yaml hems: type: sma + allowcontrol: false # set true to allow SHM controlling charger in PV modes ``` to the configuration. The EVCC loadpoints can then be added to the SHM configuration. When SHM is used, the ratio of Grid to PV Power for the **Min+PV** mode can be adjusted in diff --git a/hems/config.go b/hems/config.go index 12062edc0..3673c825b 100644 --- a/hems/config.go +++ b/hems/config.go @@ -20,7 +20,7 @@ type HEMS interface { 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) + return semp.New(other, site, cache, httpd) case "ocpp": return ocpp.New(other, site, cache) default: diff --git a/hems/semp/semp.go b/hems/semp/semp.go index dc125315a..0a97784ee 100644 --- a/hems/semp/semp.go +++ b/hems/semp/semp.go @@ -37,29 +37,39 @@ var ( // SEMP is the SMA SEMP server type SEMP struct { - log *util.Logger - cache *util.Cache - closeC chan struct{} - doneC chan struct{} - uid string - hostURI string - port int - site core.SiteAPI + log *util.Logger + cache *util.Cache + closeC chan struct{} + doneC chan struct{} + controllable bool + uid string + hostURI string + port int + site core.SiteAPI } // New generates SEMP Gateway listening at /semp endpoint -func New(site core.SiteAPI, cache *util.Cache, httpd *server.HTTPd) (*SEMP, error) { +func New(conf map[string]interface{}, site core.SiteAPI, cache *util.Cache, httpd *server.HTTPd) (*SEMP, error) { + cc := struct { + AllowControl bool + }{} + + if err := util.DecodeOther(conf, &cc); err != nil { + return nil, err + } + uid, err := uuid.NewUUID() if err != nil { return nil, err } s := &SEMP{ - doneC: make(chan struct{}), - log: util.NewLogger("semp"), - cache: cache, - site: site, - uid: uid.String(), + doneC: make(chan struct{}), + log: util.NewLogger("semp"), + cache: cache, + site: site, + uid: uid.String(), + controllable: cc.AllowControl, } // find external port @@ -468,6 +478,12 @@ func (s *SEMP) deviceControlHandler(w http.ResponseWriter, r *http.Request) { return } + // ignore requests if not controllable + if !s.controllable { + w.WriteHeader(http.StatusBadRequest) + return + } + demand := core.RemoteSoftDisable if dev.On { demand = core.RemoteEnable