Minor fixes (#614)

This commit is contained in:
andig 2021-01-26 09:59:38 +01:00 • committed by GitHub
parent f6468e1335
commit c3c18a588d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 91 additions and 83 deletions

View file

@ -39,7 +39,7 @@ func NewTestClient(fn roundTripFunc) *http.Client {
func NewTestMobileConnect(t *testing.T, responses []apiResponse) *MobileConnect {
mcc := &MobileConnect{
Helper: request.NewHelper(util.NewLogger("foo")),
uri: "http://192.168.1.1",
uri: "http://192.0.2.2:502",
password: "none",
token: "token",
tokenValid: time.Now().Add(10 * time.Minute),

View file

@ -10,6 +10,8 @@ import (
"github.com/andig/evcc/util/request"
)
// https://www.nrgkick.com/wp-content/uploads/2019/08/20190814_API-Dokumentation_04.pdf
const (
nrgSettings = "settings"
nrgMeasurements = "measurements"
@ -89,7 +91,7 @@ func NewNRGKickConnect(uri, mac, password string) (*NRGKickConnect, error) {
nrg := &NRGKickConnect{
log: log,
Helper: request.NewHelper(log),
uri: uri,
uri: util.DefaultScheme(uri, "http"),
mac: mac,
password: password,
}
@ -130,11 +132,15 @@ func (nrg *NRGKickConnect) Status() (api.ChargeStatus, error) {
func (nrg *NRGKickConnect) Enabled() (bool, error) {
var res NRGSettings
err := nrg.GetJSON(nrg.apiURL(nrgSettings), &res)
if err != nil && res.Message != "" {
if err != nil {
if res.Message != "" {
err = errors.New(res.Message)
}
return *res.Values.ChargingStatus.Charging, err
return false, err
}
return *res.Values.ChargingStatus.Charging, nil
}
// Enable implements the Charger.Enable interface

View file

@ -74,6 +74,12 @@ func (d *dumper) Dump(name string, v interface{}) {
// charger
if v, ok := v.(api.Charger); ok {
if status, err := v.Status(); err != nil {
fmt.Fprintf(w, "Status:\t%v\n", err)
} else {
fmt.Fprintf(w, "Status:\t%s\n", status)
}
if enabled, err := v.Enabled(); err != nil {
fmt.Fprintf(w, "Enabled:\t%v\n", err)
} else {

View file

@ -19,7 +19,7 @@ func TestListenerProcessMessage(t *testing.T) {
}{
{
"SMA Home Manager - success",
[]byte{192, 168, 1, 4},
net.ParseIP("192.0.2.2"),
33168,
[]byte{
0x53, 0x4d, 0x41, 0x00, 0x00, 0x04, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4c, 0x00, 0x10,
@ -63,7 +63,7 @@ func TestListenerProcessMessage(t *testing.T) {
},
false,
Telegram{
Addr: "192.168.1.4",
Addr: "192.0.2.2",
Serial: "0",
Values: map[string]float64{
"1:1.4.0": 0, "1:1.8.0": 6.89131908e+09,
@ -103,7 +103,7 @@ func TestListenerProcessMessage(t *testing.T) {
},
{
"SMA Energy Manager - success",
[]byte{192, 168, 1, 4},
net.ParseIP("192.0.2.2"),
33168,
[]byte{
0x53, 0x4d, 0x41, 0x00, 0x00, 0x04, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x10,
@ -147,7 +147,7 @@ func TestListenerProcessMessage(t *testing.T) {
},
false,
Telegram{
Addr: "192.168.1.4",
Addr: "192.0.2.2",
Serial: "0",
Values: map[string]float64{
"1:1.4.0": 0, "1:1.8.0": 1.2385008e+08,

View file

@ -10,7 +10,7 @@ import (
func TestSMAUpdateMeterValues(t *testing.T) {
tests := []struct {
name string
messsage sma.Telegram
message sma.Telegram
wantPower float64
wantCurrentL1 float64
wantCurrentL2 float64
@ -56,7 +56,7 @@ func TestSMAUpdateMeterValues(t *testing.T) {
mux: util.NewWaiter(udpTimeout, func() {}),
}
sm.updateMeterValues(tt.messsage)
sm.updateMeterValues(tt.message)
if sm.values.power != tt.wantPower {
t.Errorf("Listener.processMessage() got Power %v, want %v", sm.values.power, tt.wantPower)
}

View file

@ -4,7 +4,6 @@ import (
"crypto/tls"
"errors"
"fmt"
"net/url"
"strings"
"github.com/andig/evcc/api"
@ -64,16 +63,6 @@ func NewTeslaFromConfig(other map[string]interface{}) (api.Meter, error) {
return nil, errors.New("missing usage setting")
}
url, err := url.ParseRequestURI(cc.URI)
if err != nil {
return nil, fmt.Errorf("invalid uri %s", cc.URI)
}
uri := "https://" + url.Hostname()
if url.Port() != "" {
uri += ":" + url.Port()
}
// support default meter names
switch strings.ToLower(cc.Usage) {
case "grid":
@ -82,14 +71,16 @@ func NewTeslaFromConfig(other map[string]interface{}) (api.Meter, error) {
cc.Usage = "solar"
}
return NewTesla(uri, cc.Usage)
return NewTesla(cc.URI, cc.Usage)
}
// NewTesla creates a Tesla Meter
func NewTesla(uri, usage string) (api.Meter, error) {
log := util.NewLogger("tesla")
m := &Tesla{
Helper: request.NewHelper(util.NewLogger("tesla")),
uri: uri,
Helper: request.NewHelper(log),
uri: util.DefaultScheme(uri, "https"),
usage: strings.ToLower(usage),
}
@ -114,12 +105,12 @@ func NewTesla(uri, usage string) (api.Meter, error) {
// CurrentPower implements the Meter.CurrentPower interface
func (m *Tesla) CurrentPower() (float64, error) {
var res teslaMeterResponse
err := m.GetJSON(m.uri+teslaMeterURI, &res)
if err := m.GetJSON(m.uri+teslaMeterURI, &res); err != nil {
return 0, err
}
if err == nil {
if o, ok := res[m.usage]; ok {
return o.InstantPower, nil
}
if o, ok := res[m.usage]; ok {
return o.InstantPower, nil
}
return 0, fmt.Errorf("invalid usage: %s", m.usage)
@ -128,16 +119,16 @@ func (m *Tesla) CurrentPower() (float64, error) {
// totalEnergy implements the api.MeterEnergy interface
func (m *Tesla) totalEnergy() (float64, error) {
var res teslaMeterResponse
err := m.GetJSON(m.uri+teslaMeterURI, &res)
if err := m.GetJSON(m.uri+teslaMeterURI, &res); err != nil {
return 0, err
}
if err == nil {
if o, ok := res[m.usage]; ok {
if m.usage == "load" {
return o.EnergyImported, nil
}
if m.usage == "solar" {
return o.EnergyExported, nil
}
if o, ok := res[m.usage]; ok {
if m.usage == "load" {
return o.EnergyImported, nil
}
if m.usage == "solar" {
return o.EnergyExported, nil
}
}

View file

@ -14,7 +14,10 @@ var (
URLEncoding = map[string]string{"Content-Type": "application/x-www-form-urlencoded"}
// JSONEncoding specifies application/json
JSONEncoding = map[string]string{"Content-Type": "application/json"}
JSONEncoding = map[string]string{
"Content-Type": "application/json",
"Accept": "application/json",
}
)
// StatusError indicates unsuccessful http response

View file

@ -17,6 +17,10 @@ func (r *errorReader) Read(p []byte) (int, error) {
// MarshalJSON marshals JSON into an io.Reader
func MarshalJSON(data interface{}) io.Reader {
if data == nil {
return nil
}
body, err := json.Marshal(data)
if err != nil {
return &errorReader{err: err}

View file

@ -1,6 +1,7 @@
package vehicle
import (
"fmt"
"net/url"
"strings"
"time"
@ -55,18 +56,20 @@ func NewAudiFromConfig(other map[string]interface{}) (api.Vehicle, error) {
})
err := identity.Login(query, cc.User, cc.Password)
if err == nil {
api := vw.NewAPI(log, identity, "Audi", "DE")
if cc.VIN == "" {
cc.VIN, err = findVehicle(api.Vehicles())
if err == nil {
log.DEBUG.Printf("found vehicle: %v", cc.VIN)
}
}
v.Provider = vw.NewProvider(api, strings.ToUpper(cc.VIN), cc.Cache)
if err != nil {
return v, fmt.Errorf("login failed: %w", err)
}
api := vw.NewAPI(log, identity, "Audi", "DE")
if cc.VIN == "" {
cc.VIN, err = findVehicle(api.Vehicles())
if err == nil {
log.DEBUG.Printf("found vehicle: %v", cc.VIN)
}
}
v.Provider = vw.NewProvider(api, strings.ToUpper(cc.VIN), cc.Cache)
return v, err
}

View file

@ -1,6 +1,7 @@
package vehicle
import (
"fmt"
"net/url"
"strings"
"time"
@ -53,18 +54,20 @@ func NewIDFromConfig(other map[string]interface{}) (api.Vehicle, error) {
})
err := identity.Login(query, cc.User, cc.Password)
if err == nil {
api := id.NewAPI(log, identity)
if cc.VIN == "" {
cc.VIN, err = findVehicle(api.Vehicles())
if err == nil {
log.DEBUG.Printf("found vehicle: %v", cc.VIN)
}
}
v.Provider = id.NewProvider(api, strings.ToUpper(cc.VIN), cc.Cache)
if err != nil {
return v, fmt.Errorf("login failed: %w", err)
}
api := id.NewAPI(log, identity)
if cc.VIN == "" {
cc.VIN, err = findVehicle(api.Vehicles())
if err == nil {
log.DEBUG.Printf("found vehicle: %v", cc.VIN)
}
}
v.Provider = id.NewProvider(api, strings.ToUpper(cc.VIN), cc.Cache)
return v, err
}

View file

@ -130,14 +130,3 @@ func (v *Tesla) chargedEnergy() (float64, error) {
func (v *Tesla) ChargedEnergy() (float64, error) {
return v.chargedEnergyG()
}
// depends on https://github.com/jsgoecke/tesla/issues/28
//
// CurrentPower implements the ChargeRater.CurrentPower interface
// func (v *Tesla) CurrentPower() (float64, error) {
// state, err := v.vehicle.ChargeState()
// if err != nil {
// return 0, err
// }
// return state.ChargerPower, err
// }

View file

@ -1,6 +1,7 @@
package vehicle
import (
"fmt"
"net/url"
"strings"
"time"
@ -53,18 +54,20 @@ func NewVWFromConfig(other map[string]interface{}) (api.Vehicle, error) {
})
err := identity.Login(query, cc.User, cc.Password)
if err == nil {
api := vw.NewAPI(log, identity, "VW", "DE")
if cc.VIN == "" {
cc.VIN, err = findVehicle(api.Vehicles())
if err == nil {
log.DEBUG.Printf("found vehicle: %v", cc.VIN)
}
}
v.Provider = vw.NewProvider(api, strings.ToUpper(cc.VIN), cc.Cache)
if err != nil {
return v, fmt.Errorf("login failed: %w", err)
}
api := vw.NewAPI(log, identity, "VW", "DE")
if cc.VIN == "" {
cc.VIN, err = findVehicle(api.Vehicles())
if err == nil {
log.DEBUG.Printf("found vehicle: %v", cc.VIN)
}
}
v.Provider = vw.NewProvider(api, strings.ToUpper(cc.VIN), cc.Cache)
return v, err
}