Skip to content

Commit

Permalink
Add SponsorToken configuration for Easee (evcc-io#920)
Browse files Browse the repository at this point in the history
  • Loading branch information
andig authored Apr 25, 2021
1 parent ef06e9b commit 5681d19
Show file tree
Hide file tree
Showing 26 changed files with 549 additions and 133 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ soc-server
ca-cert.srl
server-key.pem
ca-key.pem
cmd/wip
9 changes: 3 additions & 6 deletions cmd/charger.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,11 @@ func runCharger(cmd *cobra.Command, args []string) {
log.FATAL.Fatal(err)
}

// setup mqtt
if conf.Mqtt.Broker != "" {
configureMQTT(conf.Mqtt)
// setup environment
if err := configureEnvironment(conf); err != nil {
log.FATAL.Fatal(err)
}

// setup javascript VMs
configureJavascript(conf.Javascript)

if err := cp.configureChargers(conf); err != nil {
log.FATAL.Fatal(err)
}
Expand Down
33 changes: 17 additions & 16 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,23 @@ import (
)

type config struct {
URI string
Log string
Metrics bool
Profile bool
Levels map[string]string
Interval time.Duration
Mqtt mqttConfig
Javascript map[string]interface{}
Influx server.InfluxConfig
HEMS typedConfig
Messaging messagingConfig
Meters []qualifiedConfig
Chargers []qualifiedConfig
Vehicles []qualifiedConfig
Site map[string]interface{}
LoadPoints []map[string]interface{}
URI string
Log string
SponsorToken string
Metrics bool
Profile bool
Levels map[string]string
Interval time.Duration
Mqtt mqttConfig
Javascript map[string]interface{}
Influx server.InfluxConfig
HEMS typedConfig
Messaging messagingConfig
Meters []qualifiedConfig
Chargers []qualifiedConfig
Vehicles []qualifiedConfig
Site map[string]interface{}
LoadPoints []map[string]interface{}
}

type mqttConfig struct {
Expand Down
11 changes: 4 additions & 7 deletions cmd/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,12 @@ func runDump(cmd *cobra.Command, args []string) {
log.FATAL.Fatal(err)
}

// setup mqtt
if conf.Mqtt.Broker != "" {
configureMQTT(conf.Mqtt)
// setup environment
if err := configureEnvironment(conf); err != nil {
log.FATAL.Fatal(err)
}

// setup javascript VMs
configureJavascript(conf.Javascript)

site, err := loadConfig(conf)
site, err := configureSiteAndLoadpoints(conf)
if err != nil {
log.FATAL.Fatal(err)
}
Expand Down
9 changes: 3 additions & 6 deletions cmd/meter.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,11 @@ func runMeter(cmd *cobra.Command, args []string) {
log.FATAL.Fatal(err)
}

// setup mqtt
if conf.Mqtt.Broker != "" {
configureMQTT(conf.Mqtt)
// setup environment
if err := configureEnvironment(conf); err != nil {
log.FATAL.Fatal(err)
}

// setup javascript VMs
configureJavascript(conf.Javascript)

if err := cp.configureMeters(conf); err != nil {
log.FATAL.Fatal(err)
}
Expand Down
19 changes: 8 additions & 11 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,16 @@ func run(cmd *cobra.Command, args []string) {
uri := viper.GetString("uri")
log.INFO.Println("listening at", uri)

// setup mqtt client listener
if conf.Mqtt.Broker != "" {
configureMQTT(conf.Mqtt)
// setup environment
if err := configureEnvironment(conf); err != nil {
log.FATAL.Fatal(err)
}

// setup javascript VMs
configureJavascript(conf.Javascript)
// setup loadpoints
site, err := configureSiteAndLoadpoints(conf)
if err != nil {
log.FATAL.Fatal(err)
}

// start broadcasting values
tee := &util.Tee{}
Expand All @@ -167,12 +170,6 @@ func run(cmd *cobra.Command, args []string) {
cache := util.NewCache()
go cache.Run(pipe.NewDropper(ignoreErrors...).Pipe(tee.Attach()))

// setup loadpoints
site, err := loadConfig(conf)
if err != nil {
log.FATAL.Fatal(err)
}

// setup database
if conf.Influx.URL != "" {
configureDatabase(conf.Influx, site.LoadPoints(), tee.Attach())
Expand Down
84 changes: 66 additions & 18 deletions cmd/setup.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"context"
"errors"
"fmt"
"math/rand"
Expand All @@ -13,8 +14,11 @@ import (
"github.com/andig/evcc/provider/mqtt"
"github.com/andig/evcc/push"
"github.com/andig/evcc/server"
"github.com/andig/evcc/soc/proto/pb"
"github.com/andig/evcc/util"
"github.com/andig/evcc/util/cloud"
"github.com/andig/evcc/util/pipe"
"github.com/andig/evcc/util/sponsor"
"github.com/spf13/viper"
)

Expand All @@ -24,6 +28,60 @@ func init() {

var cp = &ConfigProvider{}

func loadConfigFile(cfgFile string) (conf config, err error) {
if cfgFile != "" {
log.INFO.Println("using config file", cfgFile)
if err := viper.UnmarshalExact(&conf); err != nil {
log.FATAL.Fatalf("failed parsing config file %s: %v", cfgFile, err)
}
} else {
err = errors.New("missing evcc config")
}

return conf, err
}

func configureEnvironment(conf config) (err error) {
// setup sponsorship
if conf.SponsorToken != "" {
err = configureSponsorship(conf.SponsorToken)
}

// setup mqtt client listener
if err == nil && conf.Mqtt.Broker != "" {
err = configureMQTT(conf.Mqtt)
}

// setup javascript VMs
if err == nil {
err = configureJavascript(conf.Javascript)
}

return
}

func configureSponsorship(token string) error {
host := util.Getenv("GRPC_URI", cloud.Host)
conn, err := cloud.Connection(host)
if err != nil {
return err
}

client := pb.NewAuthClient(conn)

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

res, err := client.IsAuthorized(ctx, &pb.AuthRequest{Token: token})
if err == nil {
if res.Authorized {
sponsor.Subject = res.Subject
}
}

return err
}

// setup influx databases
func configureDatabase(conf server.InfluxConfig, loadPoints []core.LoadPointAPI, in <-chan util.Param) {
influx := server.NewInfluxClient(
Expand All @@ -47,22 +105,25 @@ func configureDatabase(conf server.InfluxConfig, loadPoints []core.LoadPointAPI,
}

// setup mqtt
func configureMQTT(conf mqttConfig) {
func configureMQTT(conf mqttConfig) error {
log := util.NewLogger("mqtt")
clientID := mqtt.ClientID()

var err error
mqtt.Instance, err = mqtt.RegisteredClient(log, conf.Broker, conf.User, conf.Password, clientID, 1)
if err != nil {
log.FATAL.Fatalf("failed configuring mqtt: %v", err)
return fmt.Errorf("failed configuring mqtt: %w", err)
}

return nil
}

// setup javascript
func configureJavascript(conf map[string]interface{}) {
func configureJavascript(conf map[string]interface{}) error {
if err := javascript.Configure(conf); err != nil {
log.FATAL.Fatalf("failed configuring javascript: %v", err)
return fmt.Errorf("failed configuring javascript: %w", err)
}
return nil
}

// setup HEMS
Expand Down Expand Up @@ -93,7 +154,7 @@ func configureMessengers(conf messagingConfig, cache *util.Cache) chan push.Even
return notificationChan
}

func loadConfig(conf config) (site *core.Site, err error) {
func configureSiteAndLoadpoints(conf config) (site *core.Site, err error) {
if err = cp.configure(conf); err == nil {
var loadPoints []*core.LoadPoint
loadPoints, err = configureLoadPoints(conf, cp)
Expand Down Expand Up @@ -138,16 +199,3 @@ func configureLoadPoints(conf config, cp *ConfigProvider) (loadPoints []*core.Lo

return loadPoints, nil
}

func loadConfigFile(cfgFile string) (conf config, err error) {
if cfgFile != "" {
log.INFO.Println("using config file", cfgFile)
if err := viper.UnmarshalExact(&conf); err != nil {
log.FATAL.Fatalf("failed parsing config file %s: %v", cfgFile, err)
}
} else {
err = errors.New("missing evcc config")
}

return conf, err
}
9 changes: 3 additions & 6 deletions cmd/vehicle.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,11 @@ func runVehicle(cmd *cobra.Command, args []string) {
log.FATAL.Fatal(err)
}

// setup mqtt
if conf.Mqtt.Broker != "" {
configureMQTT(conf.Mqtt)
// setup environment
if err := configureEnvironment(conf); err != nil {
log.FATAL.Fatal(err)
}

// setup javascript VMs
configureJavascript(conf.Javascript)

if err := cp.configureVehicles(conf); err != nil {
log.FATAL.Fatal(err)
}
Expand Down
4 changes: 4 additions & 0 deletions evcc.dist.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
uri: 0.0.0.0:7070 # uri for ui
interval: 10s # control cycle interval

# sponsor token enables optional features
# request sponsor token at https://cloud.evcc.io
sponsortoken:

# log settings
log: error
levels:
Expand Down
5 changes: 3 additions & 2 deletions internal/charger/easee.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package charger

import (
"errors"
"errors"
"fmt"
"net/http"
"time"
Expand All @@ -10,6 +10,7 @@ import (
"github.com/andig/evcc/internal/charger/easee"
"github.com/andig/evcc/util"
"github.com/andig/evcc/util/request"
"github.com/andig/evcc/util/sponsor"
)

// Easee charger implementation
Expand Down Expand Up @@ -49,7 +50,7 @@ func NewEaseeFromConfig(other map[string]interface{}) (api.Charger, error) {
func NewEasee(user, password, charger string, cache time.Duration) (*Easee, error) {
log := util.NewLogger("easee")

if true {
if !sponsor.IsAuthorized() {
return nil, errors.New("easee requires evcc sponsorship, register at https://cloud.evcc.io")
}

Expand Down
16 changes: 16 additions & 0 deletions internal/charger/easee/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
LICENSE

Copyright (c) 2019-2021 andig

This modules is NOT covered by the MIT license. All rights reserved.

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
14 changes: 6 additions & 8 deletions internal/vehicle/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ package vehicle
import (
"context"
"errors"
"os"
"time"

"github.com/andig/evcc/api"
"github.com/andig/evcc/internal/vehicle/cloud"
"github.com/andig/evcc/provider"
"github.com/andig/evcc/soc/proto/pb"
"github.com/andig/evcc/util"
"github.com/andig/evcc/util/cloud"
"github.com/andig/evcc/util/request"
)

Expand Down Expand Up @@ -50,19 +49,18 @@ func NewCloudFromConfig(other map[string]interface{}) (api.Vehicle, error) {
return nil, errors.New("missing required token")
}

if host := os.Getenv("GRPC_URI"); host != "" {
cloud.Host = host
host := util.Getenv("GRPC_URI", cloud.Host)
conn, err := cloud.Connection(host)
if err != nil {
return nil, err
}

log := util.NewLogger("cloud")
client, err := cloud.Client(log, cloud.Host)

v := &Cloud{
embed: &embed{cc.Title, cc.Capacity},
token: cc.Token,
brand: cc.Brand,
config: cc.Other,
client: client,
client: pb.NewVehicleClient(conn),
}

if err == nil {
Expand Down
3 changes: 3 additions & 0 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"type": "string"
}
},
"sponsortoken": {
"type": "string"
},
"chargers": {
"type": "array",
"description": "List of chargers",
Expand Down
Loading

0 comments on commit 5681d19

Please sign in to comment.