Sessions: fix odometer not persisted

This commit is contained in:
andig 2022-12-03 15:07:12 +01:00
parent 5ddf3c841f
commit 42ca83d3c0
4 changed files with 46 additions and 36 deletions

View file

@ -1,8 +1,6 @@
package db
import (
"time"
serverdb "github.com/evcc-io/evcc/server/db"
"github.com/evcc-io/evcc/util"
"gorm.io/gorm"
@ -35,7 +33,6 @@ func New(name string) (*DB, error) {
func (s *DB) Session(meter float64) *Session {
t := Session{
Loadpoint: s.name,
Created: time.Now(),
MeterStart: meter,
}

View file

@ -31,15 +31,6 @@ type Session struct {
ChargedEnergy float64 `json:"chargedEnergy" csv:"Charged Energy (kWh)" gorm:"column:charged_kwh"`
}
// Stop stops charging session with end meter reading and due total amount
func (t *Session) Stop(chargedWh, total float64) {
if chargedEnergy := chargedWh / 1e3; chargedEnergy > t.ChargedEnergy {
t.ChargedEnergy = chargedEnergy
}
t.MeterStop = total
t.Finished = time.Now()
}
// Sessions is a list of sessions
type Sessions []Session

View file

@ -387,7 +387,12 @@ func (lp *LoadPoint) evChargeStartHandler() {
// soc update reset
lp.socUpdated = time.Time{}
lp.startSession()
// set created when first charging session segment starts
lp.updateSession(func(session *db.Session) {
if session.Created.IsZero() {
session.Created = lp.clock.Now()
}
})
}
// evChargeStopHandler sends external stop event
@ -432,15 +437,17 @@ func (lp *LoadPoint) evVehicleConnectHandler() {
// immediately allow pv mode activity
lp.elapsePVTimer()
// create charging session
lp.createSession()
}
// evVehicleDisconnectHandler sends external start event
func (lp *LoadPoint) evVehicleDisconnectHandler() {
lp.log.INFO.Println("car disconnected")
// ensure session is persisted and closed before vehicle is changed
lp.stopSession()
lp.finalizeSession()
// session is persisted during evChargeStopHandler which runs before
lp.clearSession()
// phases are unknown when vehicle disconnects
lp.resetMeasuredPhases()

View file

@ -1,6 +1,8 @@
package core
import (
"time"
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/core/db"
)
@ -20,39 +22,50 @@ func (lp *LoadPoint) chargeMeterTotal() float64 {
return f
}
func (lp *LoadPoint) startSession() {
// createSession creates a charging session. The created timestamp is empty until set by evChargeStartHandler.
// The session is not persisted yet. That will only happen when stopSession is called.
func (lp *LoadPoint) createSession() {
// test guard
if lp.db == nil {
if lp.db == nil || lp.session != nil {
return
}
if lp.session == nil {
lp.session = lp.db.Session(lp.chargeMeterTotal())
lp.session = lp.db.Session(lp.chargeMeterTotal())
if lp.vehicle != nil {
lp.session.Vehicle = lp.vehicle.Title()
}
if c, ok := lp.charger.(api.Identifier); ok {
if id, err := c.Identify(); err == nil {
lp.session.Identifier = id
}
}
// TODO remove
lp.log.DEBUG.Println("session started")
lp.db.Persist(lp.session)
if lp.vehicle != nil {
lp.session.Vehicle = lp.vehicle.Title()
}
if c, ok := lp.charger.(api.Identifier); ok {
if id, err := c.Identify(); err == nil {
lp.session.Identifier = id
}
}
// TODO remove
lp.log.DEBUG.Println("session started")
}
// stopSession ends a charging session segment and persists the session.
func (lp *LoadPoint) stopSession() {
// test guard
if lp.db == nil || lp.session == nil {
return
}
lp.session.Stop(lp.getChargedEnergy(), lp.chargeMeterTotal())
// abort the session if charging has never started
if lp.session.Created.IsZero() {
// TODO remove
lp.log.DEBUG.Println("session aborted")
return
}
lp.session.Finished = time.Now()
lp.session.MeterStop = lp.chargeMeterTotal()
if chargedEnergy := lp.getChargedEnergy() / 1e3; chargedEnergy > lp.session.ChargedEnergy {
lp.session.ChargedEnergy = chargedEnergy
}
// TODO remove
lp.log.DEBUG.Println("session stopped")
@ -62,6 +75,7 @@ func (lp *LoadPoint) stopSession() {
type sessionOption func(*db.Session)
// updateSession updates any parameter of a charging session and persists the session.
func (lp *LoadPoint) updateSession(opts ...sessionOption) {
// test guard
if lp.db == nil || lp.session == nil {
@ -78,7 +92,8 @@ func (lp *LoadPoint) updateSession(opts ...sessionOption) {
lp.db.Persist(lp.session)
}
func (lp *LoadPoint) finalizeSession() {
// clearSession clears the charging session without persisting it.
func (lp *LoadPoint) clearSession() {
// test guard
if lp.db == nil {
return