chore: remove dead code (#11451)

This commit is contained in:
andig 2024-01-03 22:54:39 +01:00 • committed by GitHub
parent 0e30e819e6
commit 7fa3d252c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 6 additions and 699 deletions

View file

@ -10,10 +10,6 @@ const (
type UsageChoice string
func (u UsageChoice) String() string {
return string(u)
}
type DeviceCategory string
func (c DeviceCategory) String() string {

View file

@ -4,27 +4,6 @@ import "github.com/evcc-io/evcc/cmd/detect/tasks"
type Criteria map[string]interface{}
func filter(list []tasks.Result, criteria []Criteria) (match []tasks.Result) {
for _, res := range list {
for _, criterium := range criteria {
ok := true
for matchKey, matchVal := range criterium {
if foundVal, found := res.Attributes[matchKey]; !found || foundVal != matchVal {
ok = false
break
}
}
if ok {
match = append(match, res)
}
}
}
return match
}
type TypeSummary struct {
Results []tasks.Result
Found, Unique bool
@ -33,66 +12,3 @@ type TypeSummary struct {
type Summary struct {
Charger, Grid, PV, Charge, Battery, Meter TypeSummary
}
func summarize(res []tasks.Result) TypeSummary {
return TypeSummary{
Results: res,
Found: len(res) > 0,
Unique: len(res) == 1,
}
}
const (
tid = "task.id"
smaHttp = "details.http"
)
func Consolidate(res []tasks.Result) Summary {
grid := filter(res, []Criteria{
{tid: taskOpenwb},
{tid: taskSMA, smaHttp: false},
{tid: taskE3DC},
{tid: taskSonnen},
})
pv := filter(res, []Criteria{
{tid: taskOpenwb},
{tid: taskInverter},
})
battery := filter(res, []Criteria{
{tid: taskOpenwb},
{tid: taskE3DC},
{tid: taskSonnen},
{tid: taskBattery},
})
charger := filter(res, []Criteria{
{tid: taskOpenwb},
{tid: taskWallbe},
{tid: taskPhoenixEMEth},
{tid: taskPhoenixEVEth},
{tid: taskEVSEWifi},
{tid: taskGoE},
{tid: taskKEBA},
})
charge := filter(res, []Criteria{
{tid: taskOpenwb},
{tid: taskKEBA},
})
meter := filter(res, []Criteria{
{tid: taskSMA, smaHttp: true},
{tid: taskMeter},
})
return Summary{
Grid: summarize(grid),
PV: summarize(pv),
Battery: summarize(battery),
Charger: summarize(charger),
Charge: summarize(charge),
Meter: summarize(meter),
}
}

View file

@ -16,13 +16,6 @@ type Planner struct {
tariff api.Tariff
}
// WithClock sets a mockable clock
func WithClock(clock clock.Clock) func(t *Planner) {
return func(t *Planner) {
t.clock = clock
}
}
// New creates a price planner
func New(log *util.Logger, tariff api.Tariff, opt ...func(t *Planner)) *Planner {
p := &Planner{

View file

@ -1,21 +0,0 @@
package settings
import "github.com/evcc-io/evcc/api/store"
type storer struct {
key string
}
var _ store.Store = (*storer)(nil)
func NewStore(key string) store.Store {
return &storer{key: key}
}
func (s *storer) Load(res any) error {
return Json(s.key, &res)
}
func (s *storer) Save(val any) error {
return SetJson(s.key, val)
}

View file

@ -20,22 +20,6 @@ type route struct {
HandlerFunc http.HandlerFunc
}
// routeLogger traces matched routes including their executing time
//
//lint:ignore U1000 if needed
func routeLogger(inner http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
inner.ServeHTTP(w, r)
log.TRACE.Printf(
"%s\t%s\t%s",
r.Method,
r.RequestURI,
time.Since(start),
)
}
}
// HTTPd wraps an http.Server and adds the root router
type HTTPd struct {
*http.Server

View file

@ -32,50 +32,3 @@ func Query(query *gojq.Query, input []byte) (interface{}, error) {
return v, nil
}
// Float64 converts interface to float64
func Float64(v interface{}) (float64, error) {
switch v := v.(type) {
case int:
return float64(v), nil
case float64:
return v, nil
default:
return 0, fmt.Errorf("unexpected float type: %T", v)
}
}
// Int64 converts interface to int64
func Int64(v interface{}) (int64, error) {
switch v := v.(type) {
case int:
return int64(v), nil
case float64:
if float64(int64(v)) == v {
return int64(v), nil
}
return 0, fmt.Errorf("unexpected int64: %v", v)
default:
return 0, fmt.Errorf("unexpected int64 type: %T", v)
}
}
// String converts interface to string
func String(v interface{}) (string, error) {
switch v := v.(type) {
case string:
return v, nil
default:
return "", fmt.Errorf("unexpected string type: %T", v)
}
}
// Bool converts interface to bool
func Bool(v interface{}) (bool, error) {
switch v := v.(type) {
case bool:
return v, nil
default:
return false, fmt.Errorf("unexpected bool type: %T", v)
}
}

View file

@ -46,17 +46,3 @@ func Init() error {
return nil
}
func Localize(lc *Config) string {
msg, _, err := Localizer.LocalizeWithTag(lc)
if err != nil {
msg = lc.MessageID
}
return msg
}
func LocalizeID(id string) string {
return Localize(&Config{
MessageID: id,
})
}

View file

@ -4,16 +4,10 @@ import (
"encoding/binary"
"encoding/hex"
"fmt"
"math"
"strconv"
"strings"
)
func RTUFloat64ToFloat64(b []byte) float64 {
bits := binary.BigEndian.Uint64(b)
return math.Float64frombits(bits)
}
// decodeMask converts a bit mask in decimal or hex format to uint64
func decodeMask(mask string) (uint64, error) {
mask = strings.ToLower(mask)

View file

@ -64,44 +64,6 @@ func (l *Deduplicator) Pipe(in <-chan util.Param) <-chan util.Param {
return out
}
// Limiter allows filtering of channel data by given criteria
type Limiter struct {
clock clock.Clock
interval time.Duration
cache map[string]cacheItem
}
// NewLimiter creates limiter
func NewLimiter(interval time.Duration) Piper {
l := &Limiter{
clock: clock.New(),
interval: interval,
cache: make(map[string]cacheItem),
}
return l
}
func (l *Limiter) pipe(in <-chan util.Param, out chan<- util.Param) {
for p := range in {
key := p.UniqueID()
item, cached := l.cache[key]
// forward if not cached or expired
if !cached || l.clock.Since(item.updated) >= l.interval {
l.cache[key] = cacheItem{updated: l.clock.Now(), val: p.Val}
out <- p
}
}
}
// Pipe creates a new filtered output channel for given input channel
func (l *Limiter) Pipe(in <-chan util.Param) <-chan util.Param {
out := make(chan util.Param)
go l.pipe(in, out)
return out
}
// Dropper allows filtering of channel data by given criteria
type Dropper struct {
filter []string

View file

@ -9,49 +9,6 @@ import (
"github.com/evcc-io/evcc/util"
)
func TestLimiter(t *testing.T) {
l := NewLimiter(time.Hour).(*Limiter)
clck := clock.NewMock()
l.clock = clck
in := make(chan util.Param)
out := l.Pipe(in)
p := util.Param{Key: "k", Val: 1}
in <- p
if o := <-out; o.Key != p.Key || o.Val != p.Val {
t.Errorf("unexpected param %v", o)
}
p.Val = 2
in <- p
runtime.Gosched()
select {
case o := <-out:
t.Errorf("unexpected param %v", o)
case <-time.After(time.Millisecond):
}
clck.Add(2 * l.interval)
p.Val = 3
in <- p
if o := <-out; o.Key != p.Key || o.Val != p.Val {
t.Errorf("unexpected param %v", o)
}
// allow nils
clck.Add(2 * l.interval)
p.Val = nil
in <- p
if o := <-out; o.Key != p.Key || o.Val != p.Val {
t.Errorf("unexpected param %v", o)
}
}
func TestDeduplicator(t *testing.T) {
l := NewDeduplicator(time.Hour, "filtered").(*Deduplicator)
clck := clock.NewMock()

View file

@ -43,11 +43,6 @@ type StatusError struct {
resp *http.Response
}
// NewStatusError create new StatusError for given response
func NewStatusError(resp *http.Response) StatusError {
return StatusError{resp: resp}
}
func (e StatusError) Error() string {
return fmt.Sprintf("unexpected status: %d (%s)", e.resp.StatusCode, http.StatusText(e.resp.StatusCode))
}

View file

@ -0,0 +1,6 @@
package bluelink
const (
KiaAppID = "a2b8469b-30a3-4361-8e13-6fceea8fbe74"
HyundaiAppID = "014d2225-8495-4735-812d-2616334fd15d"
)

View file

@ -1,81 +0,0 @@
package bluelink
import (
"errors"
"fmt"
"sync"
"time"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/request"
)
const (
KiaAppID = "a2b8469b-30a3-4361-8e13-6fceea8fbe74"
HyundaiAppID = "014d2225-8495-4735-812d-2616334fd15d"
)
type stampCollection struct {
mu sync.Mutex
log *util.Logger
AppID, Brand string
Stamps []string
Generated time.Time
Frequency int
updated time.Time
}
var (
client = request.NewHelper(util.NewLogger("http"))
Stamps = map[string]*stampCollection{
KiaAppID: {log: util.NewLogger("kia"), AppID: KiaAppID, Brand: "kia"},
HyundaiAppID: {log: util.NewLogger("hyundai"), AppID: HyundaiAppID, Brand: "hyundai"},
}
)
// New creates a new stamp
func (c *stampCollection) Get() (string, error) {
c.mu.Lock()
defer c.mu.Unlock()
var position int
if c.Frequency > 0 {
position = int(time.Since(c.Generated).Milliseconds()) / c.Frequency
}
// download
if position >= len(c.Stamps)*9/10 {
if time.Since(c.updated) > 15*time.Minute {
c.log.TRACE.Printf("retry stamps download, last attempt: %v", c.updated)
if err := c.download(); err != nil {
return "", err
}
}
position = int(time.Since(c.Generated).Milliseconds()) / c.Frequency
}
if len(c.Stamps) == 0 {
return "", errors.New("no stamps available")
}
if position >= len(c.Stamps) {
position = len(c.Stamps) - 1
}
return c.Stamps[position], nil
}
// updateStamps updates stamps according to https://github.com/Hacksore/bluelinky/pull/144
func (c *stampCollection) download() error {
c.updated = time.Now()
uri := fmt.Sprintf("https://raw.githubusercontent.com/neoPix/bluelinky-stamps/master/%s-%s.v2.json", c.Brand, c.AppID)
if err := client.GetJSON(uri, &c); err != nil {
return fmt.Errorf("failed to download stamps: %w", err)
}
return nil
}

View file

@ -1,7 +1,6 @@
package ford
import (
"errors"
"fmt"
"net/http"
@ -72,51 +71,3 @@ func (v *API) Vehicles() ([]string, error) {
return res, err
}
// Status performs a /status request
func (v *API) Status(vin string) (StatusResponse, error) {
uri := fmt.Sprintf("%s/api/vehicles/v5/%s/status", ApiURI, vin)
var res StatusResponse
err := v.GetJSON(uri, &res)
return res, err
}
// RefreshResult retrieves a refresh result using /statusrefresh
func (v *API) RefreshResult(vin, refreshId string) (StatusResponse, error) {
var res StatusResponse
uri := fmt.Sprintf("%s/api/vehicles/v5/%s/statusrefresh/%s", ApiURI, vin, refreshId)
err := v.GetJSON(uri, &res)
return res, err
}
// RefreshRequest requests status refresh tracked by commandId
func (v *API) RefreshRequest(vin string) (string, error) {
var resp struct {
CommandId string
}
uri := fmt.Sprintf("%s/api/vehicles/v5/%s/status", ApiURI, vin)
req, err := http.NewRequest(http.MethodPut, uri, nil)
if err == nil {
err = v.DoJSON(req, &resp)
}
if err == nil && resp.CommandId == "" {
err = errors.New("refresh failed")
}
return resp.CommandId, err
}
// WakeUp performs a wakeup request
func (v *API) WakeUp(vin string) error {
uri := fmt.Sprintf("%s/api/dashboard/v1/users/vehicles?wakeupVin=%s", TokenURI, vin)
_, err := v.GetBody(uri)
return err
}

View file

@ -1,10 +1,5 @@
package ford
import (
"strings"
"time"
)
type VehiclesResponse struct {
UserVehicles struct {
VehicleDetails []struct {
@ -12,60 +7,3 @@ type VehiclesResponse struct {
}
}
}
// StatusResponse is the response to the vehicle status request
type StatusResponse struct {
VehicleStatus struct {
BatteryFillLevel struct {
Value float64
Timestamp Timestamp
}
ElVehDTE struct {
Value float64
Timestamp Timestamp
}
ChargingStatus struct {
Value string
Timestamp Timestamp
}
ChargeEndTime struct {
Value Timestamp
Timestamp Timestamp
}
PlugStatus struct {
Value int
Timestamp Timestamp
}
Odometer struct {
Value float64
Timestamp Timestamp
}
Gps struct {
Latitude float64 `json:",string"`
Longitude float64 `json:",string"`
GpsState string
Timestamp Timestamp
}
LastRefresh Timestamp
}
Status int
}
const TimeFormat = "01-02-2006 15:04:05" // time format used by Ford API, time is in UTC
// Timestamp implements JSON unmarshal
type Timestamp struct {
time.Time
}
// UnmarshalJSON decodes string timestamp into time.Time
func (ct *Timestamp) UnmarshalJSON(data []byte) error {
s := strings.Trim(string(data), "\"")
t, err := time.Parse(TimeFormat, s)
if err == nil {
ct.Time = t
}
return err
}

View file

@ -1,177 +0,0 @@
package connected
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
"strings"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/evcc-io/evcc/provider"
"github.com/evcc-io/evcc/server/auth"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/request"
"golang.org/x/oauth2"
)
type IdentityOptions func(c *Identity) error
// // WithToken provides an oauth2.Token to the client for auth.
// func WithToken(t *oauth2.Token) IdentityOptions {
// return func(v *Identity) error {
// v.ReuseTokenSource.Apply(t)
// return nil
// }
// }
type Identity struct {
log *util.Logger
*request.Helper
*ReuseTokenSource
oc *oauth2.Config
baseURL string
authC chan<- bool
}
// TODO SessionSecret from config/persistence
func NewIdentity(log *util.Logger, id, secret string, options ...IdentityOptions) (*Identity, error) {
// provider, err := oidc.NewProvider(context.Background(), "https://id.mercedes-benz.com")
// if err != nil {
// return nil, fmt.Errorf("failed to initialize OIDC provider: %s", err)
// }
oc := &oauth2.Config{
ClientID: id,
ClientSecret: secret,
Endpoint: oauth2.Endpoint{
AuthURL: "https://volvoid.eu.volvocars.com/as/authorization.oauth2",
TokenURL: "https://volvoid.eu.volvocars.com/as/token.oauth2",
},
Scopes: []string{oidc.ScopeOpenID, "conve:fuel_status", "conve:odometer_status", "conve:environment"},
}
v := &Identity{
log: log,
Helper: request.NewHelper(log),
oc: oc,
}
ts := &ReuseTokenSource{
oc: oc,
cb: v.invalidToken,
}
ts.Apply(nil)
v.ReuseTokenSource = ts
// for _, o := range options {
// if err == nil {
// err = o(v)
// }
// }
return v, nil
}
func (v *Identity) Login(user, password string) error {
oc := v.ReuseTokenSource.oc
data := url.Values{
"username": {user},
"password": {password},
"access_token_manager_id": {"JWTh4Yf0b"},
"grant_type": {"password"},
"scope": oc.Scopes,
}
req, err := request.New(http.MethodPost, oc.Endpoint.AuthURL, strings.NewReader(data.Encode()), map[string]string{
"Content-Type": request.FormContent,
"Authorization": "Basic aDRZZjBiOlU4WWtTYlZsNnh3c2c1WVFxWmZyZ1ZtSWFEcGhPc3kxUENhVXNpY1F0bzNUUjVrd2FKc2U0QVpkZ2ZJZmNMeXc=",
})
if err != nil {
return err
}
var res string
err = v.DoJSON(req, &res)
os.Exit(1)
return err
}
// invalidToken is the callback for the token source when token expires
func (v *Identity) invalidToken() {
if v.authC != nil {
v.authC <- false
}
}
// var _ api.ProviderLogin = (*Identity)(nil)
func (v *Identity) SetCallbackParams(baseURL, redirectURL string, authC chan<- bool) {
v.baseURL = baseURL
v.oc.RedirectURL = redirectURL
v.authC = authC
}
func (v *Identity) LoginHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
state := auth.Register(v.callbackHandler)
fmt.Println(v.oc.AuthCodeURL(state))
b, _ := json.Marshal(struct {
LoginUri string `json:"loginUri"`
}{
LoginUri: v.oc.AuthCodeURL(state), //, oauth2.AccessTypeOffline), // oauth2.SetAuthURLParam("prompt", "login consent"),
})
w.WriteHeader(http.StatusOK)
_, _ = w.Write(b)
}
}
func (v *Identity) LogoutHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
v.ReuseTokenSource.Apply(nil)
v.authC <- false
w.WriteHeader(http.StatusOK)
_, _ = w.Write(nil)
}
}
func (v *Identity) callbackHandler(w http.ResponseWriter, r *http.Request) {
v.log.TRACE.Println("callback request retrieved")
data, err := url.ParseQuery(r.URL.RawQuery)
if err != nil {
fmt.Fprintln(w, "invalid response:", data)
return
}
codes, ok := data["code"]
if !ok || len(codes) != 1 {
fmt.Fprintln(w, "invalid response:", data)
return
}
token, err := v.oc.Exchange(context.Background(), codes[0])
if err != nil {
fmt.Fprintln(w, "token error:", err)
return
}
if token.Valid() {
v.log.TRACE.Println("sending login update...")
v.ReuseTokenSource.Apply(token)
v.authC <- true
provider.ResetCached()
}
http.Redirect(w, r, v.baseURL, http.StatusFound)
}

View file

@ -1,34 +0,0 @@
package connected
import (
"context"
"sync"
"golang.org/x/oauth2"
)
type ReuseTokenSource struct {
mu sync.Mutex
oc *oauth2.Config
ts oauth2.TokenSource
cb func()
}
func (ts *ReuseTokenSource) Token() (*oauth2.Token, error) {
ts.mu.Lock()
defer ts.mu.Unlock()
t, err := ts.ts.Token()
if err != nil || !t.Valid() {
// invalid token callback
ts.cb()
}
return t, err
}
func (ts *ReuseTokenSource) Apply(t *oauth2.Token) {
ts.mu.Lock()
ts.ts = ts.oc.TokenSource(context.Background(), t)
ts.mu.Unlock()
}

View file

@ -41,17 +41,6 @@ func NewAPI(log *util.Logger, ts oauth2.TokenSource, brand, country string) *API
return v
}
// Vehicles implements the /vehicles response
func (v *API) Vehicles() ([]string, error) {
var res VehiclesResponse
uri := fmt.Sprintf("%s/usermanagement/users/v1/%s/%s/vehicles", v.baseURI, v.brand, v.country)
err := v.GetJSON(uri, &res)
if err != nil && res.Error != nil {
err = res.Error.Error()
}
return res.UserVehicles.Vehicle, err
}
// HomeRegion updates the home region for the given vehicle
func (v *API) HomeRegion(vin string) error {
var res HomeRegion