chore: decode soc with json.Number (#31147)
This commit is contained in:
parent
3980d5c442
commit
bc55f913f9
1 changed files with 14 additions and 37 deletions
|
|
@ -3,7 +3,6 @@ package octopusde
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
|
|
@ -11,28 +10,6 @@ import (
|
|||
"github.com/evcc-io/evcc/util"
|
||||
)
|
||||
|
||||
// jsonFloat is a float64 that unmarshals from either a JSON number or a JSON-encoded string.
|
||||
// The Octopus Kraken API serialises some numeric fields as quoted strings (e.g. "41.00").
|
||||
type jsonFloat float64
|
||||
|
||||
func (f *jsonFloat) UnmarshalJSON(data []byte) error {
|
||||
var v float64
|
||||
if err := json.Unmarshal(data, &v); err == nil {
|
||||
*f = jsonFloat(v)
|
||||
return nil
|
||||
}
|
||||
var s string
|
||||
if err := json.Unmarshal(data, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
v, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*f = jsonFloat(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
// API is the Octopus Energy Germany Kraken client for vehicle data. It reuses the
|
||||
// authenticated Kraken GraphQL client from the tariff implementation so the JWT
|
||||
// token source and auth transport are not duplicated.
|
||||
|
|
@ -95,14 +72,13 @@ func (v *API) Accounts() ([]string, error) {
|
|||
}
|
||||
|
||||
// socStatus holds the live state-of-charge values reported for a SmartFlex device.
|
||||
// Vehicles and charge points expose the same shape via distinct interface types.
|
||||
// Pointers distinguish an absent value from a reported zero.
|
||||
// json.Number decodes both bare and quoted numbers (Kraken serialises soc as "41.00").
|
||||
type socStatus struct {
|
||||
StateOfCharge struct {
|
||||
Value *jsonFloat
|
||||
Value *json.Number
|
||||
}
|
||||
StateOfChargeLimit struct {
|
||||
UpperSocLimit *jsonFloat
|
||||
UpperSocLimit *json.Number
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,22 +104,23 @@ func (d Device) soc() socStatus {
|
|||
return d.Status.ChargePoint
|
||||
}
|
||||
|
||||
// Soc returns the battery state of charge in percent, if reported.
|
||||
func (d Device) Soc() (float64, bool) {
|
||||
soc := d.soc().StateOfCharge.Value
|
||||
if soc == nil {
|
||||
// parseNumber returns the float value of a reported json.Number, if present and valid.
|
||||
func parseNumber(n *json.Number) (float64, bool) {
|
||||
if n == nil {
|
||||
return 0, false
|
||||
}
|
||||
return float64(*soc), true
|
||||
f, err := n.Float64()
|
||||
return f, err == nil
|
||||
}
|
||||
|
||||
// Soc returns the battery state of charge in percent, if reported.
|
||||
func (d Device) Soc() (float64, bool) {
|
||||
return parseNumber(d.soc().StateOfCharge.Value)
|
||||
}
|
||||
|
||||
// TargetSoc returns the configured charge limit in percent, if any.
|
||||
func (d Device) TargetSoc() (float64, bool) {
|
||||
limit := d.soc().StateOfChargeLimit.UpperSocLimit
|
||||
if limit == nil {
|
||||
return 0, false
|
||||
}
|
||||
return float64(*limit), true
|
||||
return parseNumber(d.soc().StateOfChargeLimit.UpperSocLimit)
|
||||
}
|
||||
|
||||
// krakenDevices lists the SmartFlex devices of an account.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue