Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tesla: remove bundled client #17982

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ jobs:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v6
push: true
build-args: |
TESLA_CLIENT_ID=${{ secrets.TESLA_CLIENT_ID }}
tags: |
evcc/evcc:nightly

Expand Down Expand Up @@ -106,7 +104,6 @@ jobs:
args: --snapshot -f .goreleaser-nightly.yml --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TESLA_CLIENT_ID: ${{ secrets.TESLA_CLIENT_ID }}

- uses: actions/setup-python@v5
with:
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ jobs:
push: true
build-args: |
RELEASE=1
TESLA_CLIENT_ID=${{ secrets.TESLA_CLIENT_ID }}
tags: ${{ steps.meta.outputs.tags }}

apt:
Expand Down Expand Up @@ -100,7 +99,6 @@ jobs:
env:
# use GH_TOKEN for access to evcc-io/homebrew-tap
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
TESLA_CLIENT_ID: ${{ secrets.TESLA_CLIENT_ID }}

- uses: actions/setup-python@v5
with:
Expand Down
6 changes: 3 additions & 3 deletions .goreleaser-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ builds:
- -trimpath
- -tags=release
ldflags:
- -X github.com/evcc-io/evcc/server.Version={{ .Tag }} -X github.com/evcc-io/evcc/server.Commit={{ .ShortCommit }} -X github.com/evcc-io/evcc/vehicle/tesla.TESLA_CLIENT_ID={{ .Env.TESLA_CLIENT_ID }} -s -w
- -X github.com/evcc-io/evcc/server.Version={{ .Tag }} -X github.com/evcc-io/evcc/server.Commit={{ .ShortCommit }} -s -w
env:
- CGO_ENABLED=0
goos:
Expand All @@ -36,11 +36,11 @@ builds:
- goos: darwin
goarch: arm64
ldflags:
- -X github.com/evcc-io/evcc/server.Version={{ .Tag }} -X github.com/evcc-io/evcc/server.Commit={{ .ShortCommit }} -X github.com/evcc-io/evcc/vehicle/tesla.TESLA_CLIENT_ID={{ .Env.TESLA_CLIENT_ID }} -s -w -B gobuildid
- -X github.com/evcc-io/evcc/server.Version={{ .Tag }} -X github.com/evcc-io/evcc/server.Commit={{ .ShortCommit }} -s -w -B gobuildid
- goos: darwin
goarch: amd64
ldflags:
- -X github.com/evcc-io/evcc/server.Version={{ .Tag }} -X github.com/evcc-io/evcc/server.Commit={{ .ShortCommit }} -X github.com/evcc-io/evcc/vehicle/tesla.TESLA_CLIENT_ID={{ .Env.TESLA_CLIENT_ID }} -s -w -B gobuildid
- -X github.com/evcc-io/evcc/server.Version={{ .Tag }} -X github.com/evcc-io/evcc/server.Commit={{ .ShortCommit }} -s -w -B gobuildid

archives:
- builds:
Expand Down
6 changes: 3 additions & 3 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ builds:
- -trimpath
- -tags=release
ldflags:
- -X github.com/evcc-io/evcc/server.Version={{ .Version }} -X github.com/evcc-io/evcc/vehicle/tesla.TESLA_CLIENT_ID={{ .Env.TESLA_CLIENT_ID }} -s -w
- -X github.com/evcc-io/evcc/server.Version={{ .Version }} -s -w
env:
- CGO_ENABLED=0
goos:
Expand All @@ -41,11 +41,11 @@ builds:
- goos: darwin
goarch: arm64
ldflags:
- -X github.com/evcc-io/evcc/server.Version={{ .Version }} -X github.com/evcc-io/evcc/vehicle/tesla.TESLA_CLIENT_ID={{ .Env.TESLA_CLIENT_ID }} -s -w -B gobuildid
- -X github.com/evcc-io/evcc/server.Version={{ .Version }} -s -w -B gobuildid
- goos: darwin
goarch: amd64
ldflags:
- -X github.com/evcc-io/evcc/server.Version={{ .Version }} -X github.com/evcc-io/evcc/vehicle/tesla.TESLA_CLIENT_ID={{ .Env.TESLA_CLIENT_ID }} -s -w -B gobuildid
- -X github.com/evcc-io/evcc/server.Version={{ .Version }} -s -w -B gobuildid

env:
- CGO_ENABLED=0
Expand Down
5 changes: 4 additions & 1 deletion api/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ var ErrMustRetry = errors.New("must retry")
var ErrSponsorRequired = errors.New("sponsorship required, see https://github.com/evcc-io/evcc#sponsorship")

// ErrMissingCredentials indicates that user/password are missing
var ErrMissingCredentials = errors.New("missing credentials")
var ErrMissingCredentials = errors.New("missing user/password credentials")

// ErrMissingToken indicates that access/refresh tokens are missing
var ErrMissingToken = errors.New("missing token credentials")

// ErrOutdated indicates that result is outdated
var ErrOutdated = errors.New("outdated")
Expand Down
4 changes: 3 additions & 1 deletion charger/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import (
"context"
"testing"

"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util/templates"
"github.com/evcc-io/evcc/util/test"
)

var acceptable = []string{
api.ErrMissingCredentials.Error(),
api.ErrMissingToken.Error(),
"invalid plugin source: ...",
"missing mqtt broker configuration",
"mqtt not configured",
Expand All @@ -29,7 +32,6 @@ var acceptable = []string{
"sponsorship required, see https://github.com/evcc-io/evcc#sponsorship",
"eebus not configured",
"context deadline exceeded",
"missing credentials",
"timeout", // ocpp
"must have uri and password", // Wattpilot
}
Expand Down
3 changes: 2 additions & 1 deletion meter/tapo/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/url"
"strings"

"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util"
"github.com/insomniacslk/tapo"
)
Expand Down Expand Up @@ -33,7 +34,7 @@ func NewConnection(uri, user, password string) (*Connection, error) {
}

if user == "" || password == "" {
return nil, fmt.Errorf("missing user or password")
return nil, api.ErrMissingCredentials
}

log := util.NewLogger("tapo").Redact(user, password)
Expand Down
5 changes: 3 additions & 2 deletions meter/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ import (
"context"
"testing"

"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util/templates"
"github.com/evcc-io/evcc/util/test"
)

var acceptable = []string{
api.ErrMissingCredentials.Error(),
api.ErrMissingToken.Error(),
"invalid plugin source: ...",
"missing mqtt broker configuration",
"missing token",
"mqtt not configured",
"not a SunSpec device",
"connect: connection refused", // sockets
"missing credentials", // sockets
"power: timeout", // sockets
"missing password", // Powerwall
"connect: no route to host",
Expand Down
3 changes: 1 addition & 2 deletions meter/tibber-pulse.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package meter
import (
"context"
"encoding/json"
"errors"
"net/http"
"strings"
"time"
Expand Down Expand Up @@ -38,7 +37,7 @@ func NewTibberFromConfig(ctx context.Context, other map[string]interface{}) (api
}

if cc.Token == "" {
return nil, errors.New("missing token")
return nil, api.ErrMissingToken
}

log := util.NewLogger("pulse").Redact(cc.Token, cc.HomeID)
Expand Down
2 changes: 1 addition & 1 deletion tariff/amber.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func NewAmberFromConfig(other map[string]interface{}) (api.Tariff, error) {
}

if cc.Token == "" {
return nil, errors.New("missing token")
return nil, api.ErrMissingToken
}

if cc.SiteID == "" {
Expand Down
12 changes: 7 additions & 5 deletions tariff/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ import (
"context"
"testing"

"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util/templates"
"github.com/evcc-io/evcc/util/test"
)

var acceptable = []string{
"missing token", // amber, tibber
"invalid zipcode", // grünstromindex
"invalid apikey format", // octopusenergy
"missing region", // octopusenergy
"missing securitytoken", // entsoe
api.ErrMissingCredentials.Error(),
api.ErrMissingToken.Error(),
"invalid zipcode", // grünstromindex
"invalid apikey format", // octopusenergy
"missing region", // octopusenergy
"missing securitytoken", // entsoe
"cannot define region and postcode simultaneously", // ngeso
}

Expand Down
3 changes: 1 addition & 2 deletions tariff/tibber.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package tariff

import (
"context"
"errors"
"slices"
"sync"
"time"
Expand Down Expand Up @@ -41,7 +40,7 @@ func NewTibberFromConfig(other map[string]interface{}) (api.Tariff, error) {
}

if cc.Token == "" {
return nil, errors.New("missing token")
return nil, api.ErrMissingToken
}

if err := cc.init(); err != nil {
Expand Down
8 changes: 7 additions & 1 deletion templates/definition/vehicle/tesla.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,16 @@ params:
- name: control
deprecated: true
- name: commandProxy
default: https://tesla.evcc.io/
default: https://api.teslamate.com
advanced: true
help:
en: "When using a TWC3 (or other 'dumb' charger not capable of control), evcc can manage the charge directly by communicating with the vehicle through a Command Proxy. By default, the proxy provided by evcc is used. With this parameter, you set the base URL of a custom Command Proxy to use instead of the default evcc one. See for example https://github.com/wimaha/TeslaBleHttpProxy for a proxy sending commands via bluetooth."
de: "Bei Verwendung eines TWC3 (oder eines anderen 'dummen' Ladegeräts, das nicht steuerbar ist) kann evcc die Ladung direkt verwalten, indem es über einen Command Proxy mit dem Fahrzeug kommuniziert. Standardmäßig wird der von evcc bereitgestellte Proxy verwendet. Dieses parameter setzt die Basis-URL eines benutzerdefinierten Command Proxy, der anstelle des standardmäßigen evcc-Proxy verwendet werden soll. Siehe zum Beispiel https://github.com/wimaha/TeslaBleHttpProxy für einen Proxy, der Kommandos über Bluetooth sendet."
- name: proxyToken
advanced: true
help:
en: Proxy token to access the command proxy.
de: Proxy token für den Command Proxy.
- name: cache
default: 15m
render: |
Expand All @@ -44,6 +49,7 @@ render: |
access: {{ .accessToken }}
refresh: {{ .refreshToken }}
commandProxy: {{ .commandProxy }}
proxyToken: {{ .proxyToken }}
{{ include "vehicle-common" . }}
features: ["coarsecurrent"]
cache: {{ .cache }}
3 changes: 2 additions & 1 deletion vehicle/niu/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"time"

"github.com/evcc-io/evcc/api"
"golang.org/x/oauth2"
)

Expand Down Expand Up @@ -35,7 +36,7 @@ func (t *Token) UnmarshalJSON(data []byte) error {
if msg := res.Data.Desc; msg != "" {
return errors.New(msg)
}
return errors.New("missing token")
return api.ErrMissingToken
}

(*t) = (Token)(res.Data.Token.Token)
Expand Down
13 changes: 7 additions & 6 deletions vehicle/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import (
"context"
"testing"

"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util/templates"
"github.com/evcc-io/evcc/util/test"
)

var acceptable = []string{
api.ErrMissingCredentials.Error(),
api.ErrMissingToken.Error(),
"missing client id",
"invalid plugin source: ...",
"missing mqtt broker configuration",
"received status code 404 (INVALID PARAMS)", // Nissan
Expand All @@ -20,12 +24,9 @@ var acceptable = []string{
"network is unreachable",
"error connecting: Network Error",
"unexpected status: 401",
"missing credentials", // Tesla
"missing credentials id", // Tronity
"missing access and/or refresh token, use `evcc token` to create", // Tesla
"login failed: code not found", // Polestar
"empty instance type- check for missing usage", // Merces
"invalid vehicle type: tesla", // Tesla
"discussions/17501", // Tesla
"login failed: code not found", // Polestar
"empty instance type- check for missing usage", // Merces
}

func TestTemplates(t *testing.T) {
Expand Down
26 changes: 12 additions & 14 deletions vehicle/tesla.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ package vehicle

import (
"context"
"os"
"errors"
"time"

"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/request"
"github.com/evcc-io/evcc/util/sponsor"
"github.com/evcc-io/evcc/util/transport"
"github.com/evcc-io/evcc/vehicle/tesla"
teslaclient "github.com/evcc-io/tesla-proxy-client"
Expand All @@ -23,15 +22,7 @@ type Tesla struct {
}

func init() {
if id := os.Getenv("TESLA_CLIENT_ID"); id != "" {
tesla.OAuth2Config.ClientID = id
}
if secret := os.Getenv("TESLA_CLIENT_SECRET"); secret != "" {
tesla.OAuth2Config.ClientSecret = secret
}
if tesla.OAuth2Config.ClientID != "" {
registry.Add("tesla", NewTeslaFromConfig)
}
registry.Add("tesla", NewTeslaFromConfig)
}

// NewTeslaFromConfig creates a new vehicle
Expand All @@ -42,6 +33,7 @@ func NewTeslaFromConfig(other map[string]interface{}) (api.Vehicle, error) {
Tokens Tokens
VIN string
CommandProxy string
ProxyToken string
Cache time.Duration
Timeout time.Duration
}{
Expand All @@ -62,6 +54,10 @@ func NewTeslaFromConfig(other map[string]interface{}) (api.Vehicle, error) {
tesla.OAuth2Config.ClientSecret = cc.Credentials.Secret
}

if tesla.OAuth2Config.ClientID == "" {
return nil, errors.New("missing client id, see https://github.com/evcc-io/evcc/discussions/17501")
}

token, err := cc.Tokens.Token()
if err != nil {
return nil, err
Expand All @@ -78,9 +74,11 @@ func NewTeslaFromConfig(other map[string]interface{}) (api.Vehicle, error) {
}

hc := request.NewClient(log)
baseTransport := hc.Transport

hc.Transport = &oauth2.Transport{
Source: identity,
Base: hc.Transport,
Base: baseTransport,
}

tc, err := teslaclient.NewClient(context.Background(), teslaclient.WithClient(hc))
Expand Down Expand Up @@ -109,9 +107,9 @@ func NewTeslaFromConfig(other map[string]interface{}) (api.Vehicle, error) {
pc := request.NewClient(log)
pc.Transport = &transport.Decorator{
Decorator: transport.DecorateHeaders(map[string]string{
"X-Auth-Token": sponsor.Token,
"Authorization": "Bearer " + cc.ProxyToken,
}),
Base: hc.Transport,
Base: baseTransport,
}

tcc, err := teslaclient.NewClient(context.Background(), teslaclient.WithClient(pc))
Expand Down
Loading
Loading