diff --git a/meter/discovergy.go b/meter/discovergy.go index c566c1b13..bcc32efc5 100644 --- a/meter/discovergy.go +++ b/meter/discovergy.go @@ -2,27 +2,23 @@ package meter import ( "fmt" - "net/http" + "time" "github.com/evcc-io/evcc/api" + "github.com/evcc-io/evcc/meter/discovergy" "github.com/evcc-io/evcc/provider" - "github.com/evcc-io/evcc/provider/pipeline" "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/request" "github.com/evcc-io/evcc/util/transport" "github.com/thoas/go-funk" ) -const discovergyAPI = "https://api.discovergy.com/public/v1" - func init() { registry.Add("discovergy", NewDiscovergyFromConfig) } -type discovergyMeter struct { - MeterID string `json:"meterId"` - SerialNumber string `json:"serialNumber"` - FullSerialNumber string `json:"fullSerialNumber"` +type Discovergy struct { + dataG func() (interface{}, error) } // NewDiscovergyFromConfig creates a new configurable meter @@ -31,9 +27,9 @@ func NewDiscovergyFromConfig(other map[string]interface{}) (api.Meter, error) { User string Password string Meter string - Scale float64 + Cache time.Duration }{ - Scale: 1, + Cache: time.Second, } if err := util.DecodeOther(other, &cc); err != nil { @@ -41,14 +37,13 @@ func NewDiscovergyFromConfig(other map[string]interface{}) (api.Meter, error) { } basicAuth := transport.BasicAuthHeader(cc.User, cc.Password) - log := util.NewLogger("discgy").Redact(cc.User, cc.Password, cc.Meter, basicAuth) client := request.NewHelper(log) client.Transport = transport.BasicAuth(cc.User, cc.Password, client.Transport) - var meters []discovergyMeter - if err := client.GetJSON(fmt.Sprintf("%s/meters", discovergyAPI), &meters); err != nil { + var meters []discovergy.Meter + if err := client.GetJSON(fmt.Sprintf("%s/meters", discovergy.API), &meters); err != nil { return nil, err } @@ -65,26 +60,45 @@ func NewDiscovergyFromConfig(other map[string]interface{}) (api.Meter, error) { } if meterID == "" { - return nil, fmt.Errorf("could not determine meter id: %v", funk.Map(meters, func(m discovergyMeter) string { + return nil, fmt.Errorf("could not determine meter id: %v", funk.Map(meters, func(m discovergy.Meter) string { return m.FullSerialNumber })) } - uri := fmt.Sprintf("%s/last_reading?meterId=%s", discovergyAPI, meterID) - power, err := provider.NewHTTP(log, http.MethodGet, uri, false, 0.001*cc.Scale, 0).WithAuth("basic", cc.User, cc.Password) - if err != nil { - return nil, err + dataG := provider.NewCached(func() (interface{}, error) { + uri := fmt.Sprintf("%s/last_reading?meterId=%s", discovergy.API, meterID) + var res discovergy.Reading + err := client.GetJSON(uri, &res) + return res, err + }, cc.Cache).InterfaceGetter() + + m := &Discovergy{ + dataG: dataG, } - pipe, err := new(pipeline.Pipeline).WithJq(".values.power") - if err != nil { - return nil, err - } - power = power.WithPipeline(pipe) - - return NewConfigurable(power.FloatGetter()) + return m, nil } -func matchesIdentifier(id string, m discovergyMeter) bool { +func matchesIdentifier(id string, m discovergy.Meter) bool { return id == m.MeterID || id == m.SerialNumber || id == m.FullSerialNumber } + +var _ api.Meter = (*Discovergy)(nil) + +func (m *Discovergy) CurrentPower() (float64, error) { + res, err := m.dataG() + if res, ok := res.(discovergy.Reading); err == nil && ok { + return float64(res.Values.Power) / 1e3, nil + } + return 0, err +} + +var _ api.MeterEnergy = (*Discovergy)(nil) + +func (m *Discovergy) TotalEnergy() (float64, error) { + res, err := m.dataG() + if res, ok := res.(discovergy.Reading); err == nil && ok { + return float64(res.Values.Energy) / 1e6, nil + } + return 0, err +} diff --git a/meter/discovergy/types.go b/meter/discovergy/types.go new file mode 100644 index 000000000..fab0b99c6 --- /dev/null +++ b/meter/discovergy/types.go @@ -0,0 +1,22 @@ +package discovergy + +const API = "https://api.discovergy.com/public/v1" + +type Meter struct { + MeterID string `json:"meterId"` + SerialNumber string `json:"serialNumber"` + FullSerialNumber string `json:"fullSerialNumber"` +} + +type Reading struct { + Time int64 + Values struct { + EnergyOut int64 + Energy1, Energy2 int64 + Voltage1, Voltage2, Voltage3 int64 + EnergyOut1, EnergyOut2 int64 + Power1, Power2, Power3 int64 + Power int64 + Energy int64 + } +}