Skip to content

Commit

Permalink
Bluelink: fix refresh for old bluelink API (evcc-io#13785)
Browse files Browse the repository at this point in the history
  • Loading branch information
runtologist authored May 7, 2024
1 parent 59519ad commit 1ff1513
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 29 deletions.
2 changes: 1 addition & 1 deletion vehicle/bluelink/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,5 @@ func (v *API) StatusPartial(vehicle Vehicle) (BluelinkVehicleStatus, error) {
if err == nil && res.RetCode != resOK {
err = fmt.Errorf("unexpected response: %s", res.RetCode)
}
return res, err
return res.ResMsg, err
}
10 changes: 5 additions & 5 deletions vehicle/bluelink/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func NewProvider(api *API, vehicle Vehicle, expiry, cache time.Duration) *Provid

v.statusG = provider.Cached(func() (BluelinkVehicleStatus, error) {
return v.status(
func() (BluelinkVehicleStatus, error) { return api.StatusPartial(vehicle) },
func() (BluelinkVehicleStatusLatest, error) { return api.StatusLatest(vehicle) },
)
}, cache)

Expand All @@ -42,20 +42,20 @@ func NewProvider(api *API, vehicle Vehicle, expiry, cache time.Duration) *Provid
}

// status wraps the api status call and adds status refresh
func (v *Provider) status(statusG func() (BluelinkVehicleStatus, error)) (BluelinkVehicleStatus, error) {
func (v *Provider) status(statusG func() (BluelinkVehicleStatusLatest, error)) (BluelinkVehicleStatus, error) {
res, err := statusG()

var ts time.Time
if err == nil {
ts, err = res.Updated()
ts, err = res.BluelinkVehicleStatus().Updated()
if err != nil {
return res, err
return res.BluelinkVehicleStatus(), err
}

// return the current value
if time.Since(ts) <= v.expiry {
v.refreshTime = time.Time{}
return res, nil
return res.BluelinkVehicleStatus(), nil
}
}

Expand Down
51 changes: 28 additions & 23 deletions vehicle/bluelink/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type BluelinkVehicleStatus interface {
}

type BluelinkVehicleStatusLatest interface {
BluelinkVehicleStatus() BluelinkVehicleStatus
Odometer() (float64, error)
Position() (float64, float64, error)
}
Expand Down Expand Up @@ -83,10 +84,6 @@ const (
plugTypeAC = 1
)

func (d *VehicleStatus) Updated() (time.Time, error) {
return time.Parse(timeFormat, d.Time+timeOffset)
}

type DrivingDistance struct {
RangeByFuel struct {
EvModeRange struct {
Expand All @@ -104,25 +101,25 @@ type TargetSoc struct {
PlugType int
}

func (d StatusResponse) Updated() (time.Time, error) {
return time.Parse(timeFormat, d.ResMsg.Time+timeOffset)
func (d VehicleStatus) Updated() (time.Time, error) {
return time.Parse(timeFormat, d.Time+timeOffset)
}

func (d StatusResponse) SoC() (float64, error) {
if d.ResMsg.EvStatus != nil {
return d.ResMsg.EvStatus.BatteryStatus, nil
func (d VehicleStatus) SoC() (float64, error) {
if d.EvStatus != nil {
return d.EvStatus.BatteryStatus, nil
}

return 0, api.ErrNotAvailable
}

func (d StatusResponse) Status() (api.ChargeStatus, error) {
if d.ResMsg.EvStatus != nil {
func (d VehicleStatus) Status() (api.ChargeStatus, error) {
if d.EvStatus != nil {
status := api.StatusA
if d.ResMsg.EvStatus.BatteryPlugin > 0 || d.ResMsg.EvStatus.ChargePortDoorOpenStatus == 1 {
if d.EvStatus.BatteryPlugin > 0 || d.EvStatus.ChargePortDoorOpenStatus == 1 {
status = api.StatusB
}
if d.ResMsg.EvStatus.BatteryCharge {
if d.EvStatus.BatteryCharge {
status = api.StatusC
}
return status, nil
Expand All @@ -131,31 +128,31 @@ func (d StatusResponse) Status() (api.ChargeStatus, error) {
return api.StatusNone, api.ErrNotAvailable
}

func (d StatusResponse) FinishTime() (time.Time, error) {
if d.ResMsg.EvStatus != nil {
remaining := d.ResMsg.EvStatus.RemainTime2.Atc.Value
func (d VehicleStatus) FinishTime() (time.Time, error) {
if d.EvStatus != nil {
remaining := d.EvStatus.RemainTime2.Atc.Value

if remaining != 0 {
ts, err := d.ResMsg.Updated()
ts, err := d.Updated()
return ts.Add(time.Duration(remaining) * time.Minute), err
}
}

return time.Time{}, api.ErrNotAvailable
}

func (d StatusResponse) Range() (int64, error) {
if d.ResMsg.EvStatus != nil {
if dist := d.ResMsg.EvStatus.DrvDistance; len(dist) == 1 {
func (d VehicleStatus) Range() (int64, error) {
if d.EvStatus != nil {
if dist := d.EvStatus.DrvDistance; len(dist) == 1 {
return int64(dist[0].RangeByFuel.EvModeRange.Value), nil
}
}
return 0, api.ErrNotAvailable
}

func (d StatusResponse) GetLimitSoc() (int64, error) {
if d.ResMsg.EvStatus != nil {
for _, targetSOC := range d.ResMsg.EvStatus.ReservChargeInfos.TargetSocList {
func (d VehicleStatus) GetLimitSoc() (int64, error) {
if d.EvStatus != nil {
for _, targetSOC := range d.EvStatus.ReservChargeInfos.TargetSocList {
if targetSOC.PlugType == plugTypeAC {
return int64(targetSOC.TargetSocLevel), nil
}
Expand All @@ -164,6 +161,10 @@ func (d StatusResponse) GetLimitSoc() (int64, error) {
return 0, api.ErrNotAvailable
}

func (d StatusLatestResponse) BluelinkVehicleStatus() BluelinkVehicleStatus {
return d.ResMsg.VehicleStatusInfo.VehicleStatus
}

func (d StatusLatestResponse) Odometer() (float64, error) {
if d.ResMsg.VehicleStatusInfo.Odometer != nil {
return d.ResMsg.VehicleStatusInfo.Odometer.Value, nil
Expand Down Expand Up @@ -271,6 +272,10 @@ type VehicleStatusCCS struct {
}
}

func (d StatusLatestResponseCCS) BluelinkVehicleStatus() BluelinkVehicleStatus {
return d
}

func (d StatusLatestResponseCCS) Updated() (time.Time, error) {
epoch, err := strconv.ParseInt(d.ResMsg.LastUpdateTime, 10, 64)
if err != nil {
Expand Down

0 comments on commit 1ff1513

Please sign in to comment.