Remove the vehicle climater feature (#1003)

This commit is contained in:
andig 2021-05-11 20:20:21 +02:00 • committed by GitHub
parent 96a0d4bdfc
commit c7ff9087a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 4 additions and 211 deletions

View file

@ -115,11 +115,6 @@ type VehicleRange interface {
Range() (int64, error)
}
// VehicleClimater provides climatisation data
type VehicleClimater interface {
Climater() (active bool, outsideTemp float64, targetTemp float64, err error)
}
// VehicleStartCharge starts the charging session on the vehicle side
type VehicleStartCharge interface {
StartCharge() error

View file

@ -2,7 +2,6 @@ package cmd
import (
"fmt"
"math"
"os"
"strings"
"text/tabwriter"
@ -127,20 +126,6 @@ func (d *dumper) Dump(name string, v interface{}) {
}
}
if v, ok := v.(api.VehicleClimater); ok {
if active, ot, tt, err := v.Climater(); err != nil {
fmt.Fprintf(w, "Climater:\t%v\n", err)
} else {
fmt.Fprintf(w, "Climate active:\t%v\n", active)
if !math.IsNaN(ot) {
fmt.Fprintf(w, "Outside temp:\t%.1f°C\n", ot)
}
if !math.IsNaN(tt) {
fmt.Fprintf(w, "Target temp:\t%.1f°C\n", tt)
}
}
}
// Identity
if v, ok := v.(api.Identifier); ok {

View file

@ -525,37 +525,6 @@ func (lp *LoadPoint) minSocNotReached() bool {
lp.socCharge < float64(lp.SoC.Min)
}
// climateActive checks if vehicle has active climate request
func (lp *LoadPoint) climateActive() bool {
if cl, ok := lp.vehicle.(api.VehicleClimater); ok {
active, outsideTemp, targetTemp, err := cl.Climater()
if err == nil {
lp.log.DEBUG.Printf("climater active: %v, target temp: %.1f°C, outside temp: %.1f°C", active, targetTemp, outsideTemp)
status := "off"
if active {
status = "on"
switch {
case outsideTemp < targetTemp:
status = "heating"
case outsideTemp > targetTemp:
status = "cooling"
}
}
lp.publish("climater", status)
return active
}
if !errors.Is(err, api.ErrNotAvailable) {
lp.log.ERROR.Printf("climater: %v", err)
}
}
return false
}
// remoteControlled returns true if remote control status is active
func (lp *LoadPoint) remoteControlled(demand RemoteDemand) bool {
lp.Lock()
@ -974,12 +943,7 @@ func (lp *LoadPoint) Update(sitePower float64) {
case lp.targetSocReached():
lp.log.DEBUG.Printf("targetSoC reached: %.1f > %d", lp.socCharge, lp.SoC.Target)
var targetCurrent float64 // zero disables
if lp.climateActive() {
lp.log.DEBUG.Println("climater active")
targetCurrent = float64(lp.MinCurrent)
}
err = lp.setLimit(targetCurrent, true)
err = lp.setLimit(0, true)
lp.socTimer.Reset() // once SoC is reached, the target charge request is removed
// OCPP has priority over target charging
@ -1006,13 +970,8 @@ func (lp *LoadPoint) Update(sitePower float64) {
targetCurrent := lp.pvMaxCurrent(mode, sitePower)
lp.log.DEBUG.Printf("pv max charge current: %.2gA", targetCurrent)
var required bool // false
if targetCurrent == 0 && lp.climateActive() {
targetCurrent = float64(lp.MinCurrent)
required = true
}
// Sunny Home Manager
var required bool // false
if lp.remoteControlled(RemoteSoftDisable) {
remoteDisabled = RemoteSoftDisable
targetCurrent = 0

View file

@ -190,9 +190,8 @@ func (site *Site) DumpConfig() {
_, rng := v.(api.VehicleRange)
_, finish := v.(api.VehicleFinishTimer)
_, status := v.(api.ChargeState)
_, climate := v.(api.VehicleClimater)
lp.log.INFO.Printf(" car %d: range %s finish %s status %s climate %s",
i, presence[rng], presence[finish], presence[status], presence[climate],
lp.log.INFO.Printf(" car %d: range %s finish %s status %s",
i, presence[rng], presence[finish], presence[status],
)
}
}

View file

@ -88,21 +88,3 @@ func (v *CarWings) hvacAPI() (interface{}, error) {
func (v *CarWings) SoC() (float64, error) {
return v.chargeStateG()
}
var _ api.VehicleClimater = (*CarWings)(nil)
// Climater implements the api.Vehicle.Climater interface
func (v *CarWings) Climater() (active bool, outsideTemp float64, targetTemp float64, err error) {
res, err := v.hvacG()
if res, ok := res.(carwings.ClimateStatus); err == nil && ok {
active = res.Running
targetTemp = float64(res.Temperature)
outsideTemp = 0 //fixed value
return active, outsideTemp, targetTemp, nil
}
return false, 0, 0, api.ErrNotAvailable
}

View file

@ -1,7 +1,6 @@
package id
import (
"strings"
"time"
"github.com/andig/evcc/api"
@ -84,31 +83,6 @@ func (v *Provider) Range() (int64, error) {
return 0, err
}
var _ api.VehicleClimater = (*Provider)(nil)
// Climater implements the api.VehicleClimater interface
func (v *Provider) Climater() (active bool, outsideTemp float64, targetTemp float64, err error) {
res, err := v.statusG()
if res, ok := res.(Status); err == nil && ok {
state := strings.ToLower(res.Data.ClimatisationStatus.ClimatisationState)
if state == "" {
return false, 0, 0, api.ErrNotAvailable
}
active := state != "off" && state != "invalid" && state != "error"
targetTemp = res.Data.ClimatisationSettings.TargetTemperatureC
// TODO not available; use target temp to avoid wrong heating/cooling display
outsideTemp = targetTemp
return active, outsideTemp, targetTemp, nil
}
return active, outsideTemp, targetTemp, err
}
var _ api.VehicleStartCharge = (*Provider)(nil)
// StartCharge implements the api.VehicleStartCharge interface

View file

@ -162,20 +162,3 @@ func (v *EMobilityProvider) Status() (api.ChargeStatus, error) {
return api.StatusNone, err
}
var _ api.VehicleClimater = (*EMobilityProvider)(nil)
// Climater implements the api.VehicleClimater interface
func (v *EMobilityProvider) Climater() (active bool, outsideTemp float64, targetTemp float64, err error) {
res, err := v.statusG()
if res, ok := res.(EmobilityResponse); err == nil && ok {
switch res.DirectClimatisation.ClimatisationState {
case "OFF":
return false, 0, 0, nil
case "ON":
return true, 0, 0, nil
}
}
return active, outsideTemp, targetTemp, err
}

View file

@ -98,16 +98,3 @@ func (v *Provider) Status() (api.ChargeStatus, error) {
return api.StatusNone, err
}
var _ api.VehicleClimater = (*Provider)(nil)
// Climater implements the api.VehicleClimater interface
func (v *Provider) Climater() (active bool, outsideTemp float64, targetTemp float64, err error) {
res, err := v.statusG()
if res, ok := res.(Status); err == nil && ok {
active := strings.ToLower(res.Preconditionning.AirConditioning.Status) != "disabled"
return active, 20, 20, nil
}
return active, outsideTemp, targetTemp, err
}

View file

@ -12,7 +12,6 @@ import (
"github.com/andig/evcc/provider"
"github.com/andig/evcc/util"
"github.com/andig/evcc/util/request"
"github.com/thoas/go-funk"
)
// Credits to
@ -398,29 +397,3 @@ func (v *Renault) FinishTime() (time.Time, error) {
return time.Time{}, err
}
var _ api.VehicleClimater = (*Renault)(nil)
// Climater implements the api.VehicleClimater interface
func (v *Renault) Climater() (active bool, outsideTemp float64, targetTemp float64, err error) {
res, err := v.hvacG()
// Zoe Ph2
if err, ok := err.(request.StatusError); ok && err.HasStatus(http.StatusForbidden) {
return false, 0, 0, api.ErrNotAvailable
}
if res, ok := res.(kamereonResponse); err == nil && ok {
state := strings.ToLower(res.Data.Attributes.HvacStatus)
if state == "" {
return false, 0, 0, api.ErrNotAvailable
}
active := !funk.ContainsString([]string{"off", "false", "invalid", "error"}, state)
return active, res.Data.Attributes.ExternalTemperature, 20, nil
}
return false, 0, 0, err
}

View file

@ -182,23 +182,6 @@ func (v *Tesla) FinishTime() (time.Time, error) {
return time.Time{}, err
}
var _ api.VehicleClimater = (*Tesla)(nil)
// Climater implements the api.VehicleClimater interface
func (v *Tesla) Climater() (active bool, outsideTemp float64, targetTemp float64, err error) {
res, err := v.climateStateG()
if res, ok := res.(*tesla.ClimateState); err == nil && ok {
active = res.IsPreconditioning
outsideTemp = res.OutsideTemp
targetTemp = res.PassengerTempSetting
return active, outsideTemp, targetTemp, nil
}
return false, 0, 0, api.ErrNotAvailable
}
var _ api.VehicleStartCharge = (*Tesla)(nil)
// StartCharge implements the api.VehicleStartCharge interface

View file

@ -1,8 +1,6 @@
package vw
import (
"math"
"strings"
"time"
"github.com/andig/evcc/api"
@ -12,7 +10,6 @@ import (
// Provider implements the evcc vehicle api
type Provider struct {
chargerG func() (interface{}, error)
climateG func() (interface{}, error)
action func(action, value string) error
}
@ -22,9 +19,6 @@ func NewProvider(api *API, vin string, cache time.Duration) *Provider {
chargerG: provider.NewCached(func() (interface{}, error) {
return api.Charger(vin)
}, cache).InterfaceGetter(),
climateG: provider.NewCached(func() (interface{}, error) {
return api.Climater(vin)
}, cache).InterfaceGetter(),
action: func(action, value string) error {
return api.Action(vin, action, value)
},
@ -100,27 +94,6 @@ func (v *Provider) Range() (rng int64, err error) {
return rng, err
}
var _ api.VehicleClimater = (*Provider)(nil)
// Climater implements the api.VehicleClimater interface
func (v *Provider) Climater() (active bool, outsideTemp float64, targetTemp float64, err error) {
res, err := v.climateG()
if res, ok := res.(ClimaterResponse); err == nil && ok {
state := strings.ToLower(res.Climater.Status.ClimatisationStatusData.ClimatisationState.Content)
active := state != "off" && state != "invalid" && state != "error"
targetTemp = res.Climater.Settings.TargetTemperature.Content
outsideTemp = res.Climater.Status.TemperatureStatusData.OutdoorTemperature.Content
if math.IsNaN(outsideTemp) {
outsideTemp = targetTemp // cover "invalid"
}
return active, outsideTemp, targetTemp, nil
}
return active, outsideTemp, targetTemp, err
}
var _ api.VehicleStartCharge = (*Provider)(nil)
// StartCharge implements the api.VehicleStartCharge interface