Detect vehicle charge status only when connecting (#1165)
Some checks failed
Build / Build (push) Failing after 6m17s
Build / Build UI (push) Failing after 1m34s
Build / Publish :latest (push) Has been skipped
Build / Publish :release (push) Has been skipped
Build / Release (push) Has been skipped

This commit is contained in:
andig 2021-06-23 17:12:55 +02:00 • committed by GitHub
parent 58d7acf498
commit 71ae0defff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -103,11 +103,12 @@ type LoadPoint struct {
chargeTimer api.ChargeTimer
chargeRater api.ChargeRater
chargeMeter api.Meter // Charger usage meter
vehicle api.Vehicle // Currently active vehicle
vehicles []api.Vehicle // Assigned vehicles
socEstimator *soc.Estimator
socTimer *soc.Timer
chargeMeter api.Meter // Charger usage meter
vehicle api.Vehicle // Currently active vehicle
vehicles []api.Vehicle // Assigned vehicles
socEstimator *soc.Estimator
socTimer *soc.Timer
vehicleIdError error // state of last vehicle identification
// cached state
status api.ChargeStatus // Charger status
@ -327,6 +328,9 @@ func (lp *LoadPoint) evVehicleConnectHandler() {
// flush all vehicles before updating state
provider.ResetCached()
// identify active vehicle
lp.findActiveVehicle()
// immediately allow pv mode activity
lp.pvDisableTimer()
@ -424,6 +428,7 @@ func (lp *LoadPoint) Prepare(uiChan chan<- util.Param, pushChan chan<- push.Even
// run during prepare() to ensure cache has been attached
if len(lp.vehicles) > 0 {
lp.setActiveVehicle(lp.vehicles[0])
lp.findActiveVehicle()
}
// read initial charger state to prevent immediately disabling charger
@ -597,6 +602,9 @@ func (lp *LoadPoint) setActiveVehicle(vehicle api.Vehicle) {
lp.log.INFO.Printf("vehicle updated: %s -> %s", lp.vehicle.Title(), vehicle.Title())
}
// update successful
lp.vehicleIdError = nil
lp.vehicle = vehicle
lp.socEstimator = soc.NewEstimator(lp.log, vehicle, lp.SoC.Estimate)
@ -604,32 +612,39 @@ func (lp *LoadPoint) setActiveVehicle(vehicle api.Vehicle) {
lp.publish("socCapacity", lp.vehicle.Capacity())
}
// vehicleIdentificationAllowed returns true if active vehicle has not yet been identified
func (lp *LoadPoint) vehicleIdentificationAllowed() bool {
return errors.Is(lp.vehicleIdError, api.ErrMustRetry)
}
// findActiveVehicle validates if the active vehicle is still connected to the loadpoint
func (lp *LoadPoint) findActiveVehicle() {
// find vehicles by id
if identifier, ok := lp.charger.(api.Identifier); ok {
id, err := identifier.Identify()
if err == nil {
lp.log.DEBUG.Println("charger vehicle id:", id)
// find exact match
for _, vehicle := range lp.vehicles {
if vid, err := vehicle.Identify(); err == nil && vid == id {
lp.setActiveVehicle(vehicle)
return
}
}
// find placeholder match
for _, vehicle := range lp.vehicles {
if vid, err := vehicle.Identify(); err == nil && vid == "*" {
lp.setActiveVehicle(vehicle)
return
}
}
} else {
if err != nil {
lp.vehicleIdError = err
lp.log.ERROR.Println("charger vehicle id:", err)
return
}
lp.log.DEBUG.Println("charger vehicle id:", id)
// find exact match
for _, vehicle := range lp.vehicles {
if vid, err := vehicle.Identify(); err == nil && vid == id {
lp.setActiveVehicle(vehicle)
return
}
}
// find placeholder match
for _, vehicle := range lp.vehicles {
if vid, err := vehicle.Identify(); err == nil && vid == "*" {
lp.setActiveVehicle(vehicle)
return
}
}
// TODO implement removing vehicle
@ -640,39 +655,47 @@ func (lp *LoadPoint) findActiveVehicle() {
return
}
// find vehicles by charge state
// find vehicles by charge state - current vehicle
if vs, ok := lp.vehicle.(api.ChargeState); ok {
status, err := vs.Status()
if err == nil {
lp.log.DEBUG.Printf("vehicle status: %s (%s)", status, lp.vehicle.Title())
if err != nil {
lp.vehicleIdError = err
lp.log.ERROR.Println("vehicle charge state:", err)
return
}
// vehicle is plugged or charging, so it should be the right one
if status == api.StatusB || status == api.StatusC {
lp.log.DEBUG.Printf("vehicle status: %s (%s)", status, lp.vehicle.Title())
// vehicle is plugged or charging, so it should be the right one
if status == api.StatusB || status == api.StatusC {
lp.vehicleIdError = nil
return
}
}
// find vehicles by charge state
for _, vehicle := range lp.vehicles {
if vehicle == lp.vehicle {
continue
}
if vs, ok := vehicle.(api.ChargeState); ok {
status, err := vs.Status()
if err != nil {
lp.vehicleIdError = err
lp.log.ERROR.Println("vehicle charge state:", err)
return
}
for _, vehicle := range lp.vehicles {
if vehicle == lp.vehicle {
continue
}
lp.log.DEBUG.Printf("vehicle status: %s (%s)", status, vehicle.Title())
if vs, ok := vehicle.(api.ChargeState); ok {
status, err := vs.Status()
if err == nil {
lp.log.DEBUG.Printf("vehicle status: %s (%s)", status, vehicle.Title())
// vehicle is plugged or charging, so it should be the right one
if status == api.StatusB || status == api.StatusC {
lp.setActiveVehicle(vehicle)
return
}
}
}
// vehicle is plugged or charging, so it should be the right one
if status == api.StatusB || status == api.StatusC {
lp.setActiveVehicle(vehicle)
return
}
} else {
lp.log.ERROR.Println("vehicle charge state:", err)
}
}
}
@ -983,10 +1006,13 @@ func (lp *LoadPoint) Update(sitePower float64) {
lp.publish("charging", lp.charging())
lp.publish("enabled", lp.enabled)
// update active vehicle and publish soc
// must be run after updating charger status to make sure
// update active vehicle if not yet done
if lp.vehicleIdentificationAllowed() {
lp.findActiveVehicle()
}
// publish soc after updating charger status to make sure
// initial update of connected state matches charger status
lp.findActiveVehicle()
lp.publishSoCAndRange()
// sync settings with charger