chore: simplify and rename energy metrics to avoid confusion (#18288)

This commit is contained in:
andig 2025-01-21 17:17:35 +01:00 • committed by GitHub
parent 350f50f2d7
commit e8630e6bf4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 100 additions and 115 deletions

View file

@ -11,13 +11,6 @@ type EnergyMetrics struct {
currentCo2 *float64 // Current co2 emissions currentCo2 *float64 // Current co2 emissions
} }
func NewEnergyMetrics() *EnergyMetrics {
em := &EnergyMetrics{}
em.Reset()
return em
}
// SetEnvironment updates site information like solar share, price, co2 for use in later calculations // SetEnvironment updates site information like solar share, price, co2 for use in later calculations
func (em *EnergyMetrics) SetEnvironment(greenShare float64, effPrice, effCo2 *float64) { func (em *EnergyMetrics) SetEnvironment(greenShare float64, effPrice, effCo2 *float64) {
em.currentGreenShare = greenShare em.currentGreenShare = greenShare

View file

@ -117,7 +117,7 @@ func TestEnergyMetrics(t *testing.T) {
} }
for _, tc := range tc { for _, tc := range tc {
s := NewEnergyMetrics() var s EnergyMetrics
for _, tc := range tc.steps { for _, tc := range tc.steps {
s.SetEnvironment(tc.greenShare, tc.effPrice, tc.effCo2) s.SetEnvironment(tc.greenShare, tc.effPrice, tc.effCo2)
@ -145,7 +145,7 @@ func TestEnergyMetrics(t *testing.T) {
} }
// reset // reset
s := NewEnergyMetrics() var s EnergyMetrics
s.SetEnvironment(1, f(1), f(1)) s.SetEnvironment(1, f(1), f(1))
s.Update(1) s.Update(1)
s.Reset() s.Reset()

View file

@ -176,12 +176,12 @@ type Loadpoint struct {
wakeUpTimer *Timer // Vehicle wake-up timeout wakeUpTimer *Timer // Vehicle wake-up timeout
// charge progress // charge progress
vehicleSoc float64 // Vehicle Soc vehicleSoc float64 // Vehicle Soc
chargeDuration time.Duration // Charge duration chargeDuration time.Duration // Charge duration
sessionEnergy *EnergyMetrics // Stats for charged energy by session energyMetrics EnergyMetrics // Stats for charged energy by session
chargeRemainingDuration time.Duration // Remaining charge duration chargeRemainingDuration time.Duration // Remaining charge duration
chargeRemainingEnergy float64 // Remaining charge energy in Wh chargeRemainingEnergy float64 // Remaining charge energy in Wh
progress *Progress // Step-wise progress indicator progress *Progress // Step-wise progress indicator
// session log // session log
db *session.DB db *session.DB
@ -307,12 +307,11 @@ func NewLoadpoint(log *util.Logger, settings *Settings) *Loadpoint {
Mode: pollCharging, Mode: pollCharging,
}, },
}, },
Enable: ThresholdConfig{Delay: time.Minute, Threshold: 0}, // t, W Enable: ThresholdConfig{Delay: time.Minute, Threshold: 0}, // t, W
Disable: ThresholdConfig{Delay: 3 * time.Minute, Threshold: 0}, // t, W Disable: ThresholdConfig{Delay: 3 * time.Minute, Threshold: 0}, // t, W
sessionEnergy: NewEnergyMetrics(), progress: NewProgress(0, 10), // soc progress indicator
progress: NewProgress(0, 10), // soc progress indicator coordinator: coordinator.NewDummy(), // dummy vehicle coordinator
coordinator: coordinator.NewDummy(), // dummy vehicle coordinator tasks: util.NewQueue[Task](), // task queue
tasks: util.NewQueue[Task](), // task queue
} }
return lp return lp
@ -475,8 +474,8 @@ func (lp *Loadpoint) evVehicleConnectHandler() {
lp.log.INFO.Printf("car connected") lp.log.INFO.Printf("car connected")
// energy // energy
lp.sessionEnergy.Reset() lp.energyMetrics.Reset()
lp.sessionEnergy.Publish("session", lp) lp.energyMetrics.Publish("session", lp)
lp.publish(keys.ChargedEnergy, lp.getChargedEnergy()) lp.publish(keys.ChargedEnergy, lp.getChargedEnergy())
// duration // duration
@ -514,7 +513,7 @@ func (lp *Loadpoint) evVehicleDisconnectHandler() {
lp.resetMeasuredPhases() lp.resetMeasuredPhases()
// energy and duration // energy and duration
lp.sessionEnergy.Publish("session", lp) lp.energyMetrics.Publish("session", lp)
lp.publish(keys.ChargedEnergy, lp.getChargedEnergy()) lp.publish(keys.ChargedEnergy, lp.getChargedEnergy())
lp.publish(keys.ConnectedDuration, lp.clock.Since(lp.connectedTime).Round(time.Second)) lp.publish(keys.ConnectedDuration, lp.clock.Since(lp.connectedTime).Round(time.Second))
@ -1580,7 +1579,7 @@ func (lp *Loadpoint) publishChargeProgress() {
// workaround for Go-E resetting during disconnect, see // workaround for Go-E resetting during disconnect, see
// https://github.com/evcc-io/evcc/issues/5092 // https://github.com/evcc-io/evcc/issues/5092
if f > lp.chargedAtStartup { if f > lp.chargedAtStartup {
added, addedGreen := lp.sessionEnergy.Update(f - lp.chargedAtStartup) added, addedGreen := lp.energyMetrics.Update(f - lp.chargedAtStartup)
if telemetry.Enabled() && added > 0 { if telemetry.Enabled() && added > 0 {
telemetry.UpdateEnergy(added, addedGreen) telemetry.UpdateEnergy(added, addedGreen)
} }
@ -1596,7 +1595,7 @@ func (lp *Loadpoint) publishChargeProgress() {
} }
// TODO check if "session" prefix required? // TODO check if "session" prefix required?
lp.sessionEnergy.Publish("session", lp) lp.energyMetrics.Publish("session", lp)
// TODO deprecated: use sessionEnergy instead // TODO deprecated: use sessionEnergy instead
lp.publish(keys.ChargedEnergy, lp.getChargedEnergy()) lp.publish(keys.ChargedEnergy, lp.getChargedEnergy())
@ -1751,7 +1750,7 @@ func (lp *Loadpoint) Update(sitePower, batteryBoostPower float64, rates api.Rate
lp.updateChargeVoltages() lp.updateChargeVoltages()
lp.phasesFromChargeCurrents() lp.phasesFromChargeCurrents()
lp.sessionEnergy.SetEnvironment(greenShare, effPrice, effCo2) lp.energyMetrics.SetEnvironment(greenShare, effPrice, effCo2)
// update ChargeRater here to make sure initial meter update is caught // update ChargeRater here to make sure initial meter update is caught
lp.bus.Publish(evChargeCurrent, lp.chargeCurrent) lp.bus.Publish(evChargeCurrent, lp.chargeCurrent)

View file

@ -78,7 +78,7 @@ func (lp *Loadpoint) SetMode(mode api.ChargeMode) {
func (lp *Loadpoint) getChargedEnergy() float64 { func (lp *Loadpoint) getChargedEnergy() float64 {
lp.RLock() lp.RLock()
defer lp.RUnlock() defer lp.RUnlock()
return lp.sessionEnergy.TotalWh() return lp.energyMetrics.TotalWh()
} }
// GetPriority returns the loadpoint priority // GetPriority returns the loadpoint priority

View file

@ -3,6 +3,7 @@ package core
import ( import (
"github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/core/session" "github.com/evcc-io/evcc/core/session"
"github.com/samber/lo"
) )
func (lp *Loadpoint) chargeMeterTotal() float64 { func (lp *Loadpoint) chargeMeterTotal() float64 {
@ -63,16 +64,15 @@ func (lp *Loadpoint) stopSession() {
} }
if chargedEnergy := lp.getChargedEnergy() / 1e3; chargedEnergy > s.ChargedEnergy { if chargedEnergy := lp.getChargedEnergy() / 1e3; chargedEnergy > s.ChargedEnergy {
lp.sessionEnergy.Update(chargedEnergy) lp.energyMetrics.Update(chargedEnergy)
} }
solarPerc := lp.sessionEnergy.SolarPercentage() s.SolarPercentage = lo.ToPtr(lp.energyMetrics.SolarPercentage())
s.SolarPercentage = &solarPerc s.Price = lp.energyMetrics.Price()
s.Price = lp.sessionEnergy.Price() s.PricePerKWh = lp.energyMetrics.PricePerKWh()
s.PricePerKWh = lp.sessionEnergy.PricePerKWh() s.Co2PerKWh = lp.energyMetrics.Co2PerKWh()
s.Co2PerKWh = lp.sessionEnergy.Co2PerKWh() s.ChargedEnergy = lp.energyMetrics.TotalWh() / 1e3
s.ChargedEnergy = lp.sessionEnergy.TotalWh() / 1e3 s.ChargeDuration = lo.ToPtr(lp.chargeDuration.Abs())
s.ChargeDuration = &lp.chargeDuration
lp.db.Persist(s) lp.db.Persist(s)
} }

View file

@ -38,11 +38,10 @@ func TestSession(t *testing.T) {
cm := &EnergyDecorator{Meter: mm, MeterEnergy: me} cm := &EnergyDecorator{Meter: mm, MeterEnergy: me}
lp := &Loadpoint{ lp := &Loadpoint{
log: util.NewLogger("foo"), log: util.NewLogger("foo"),
clock: clock, clock: clock,
db: db, db: db,
chargeMeter: cm, chargeMeter: cm,
sessionEnergy: NewEnergyMetrics(),
} }
// create session // create session
@ -60,7 +59,7 @@ func TestSession(t *testing.T) {
// stop charging // stop charging
clock.Add(time.Hour) clock.Add(time.Hour)
lp.sessionEnergy.Update(1.23) lp.energyMetrics.Update(1.23)
me.EXPECT().TotalEnergy().Return(1.0+lp.getChargedEnergy()/1e3, nil) // match chargedEnergy me.EXPECT().TotalEnergy().Return(1.0+lp.getChargedEnergy()/1e3, nil) // match chargedEnergy
lp.stopSession() lp.stopSession()
@ -75,7 +74,7 @@ func TestSession(t *testing.T) {
// stop charging - 2nd leg // stop charging - 2nd leg
clock.Add(time.Hour) clock.Add(time.Hour)
lp.sessionEnergy.Update(lp.getChargedEnergy() * 2) lp.energyMetrics.Update(lp.getChargedEnergy() * 2)
me.EXPECT().TotalEnergy().Return(3.0, nil) // doesn't match chargedEnergy me.EXPECT().TotalEnergy().Return(3.0, nil) // doesn't match chargedEnergy
lp.stopSession() lp.stopSession()

View file

@ -156,19 +156,18 @@ func TestUpdatePowerZero(t *testing.T) {
charger := api.NewMockCharger(ctrl) charger := api.NewMockCharger(ctrl)
lp := &Loadpoint{ lp := &Loadpoint{
log: util.NewLogger("foo"), log: util.NewLogger("foo"),
bus: evbus.New(), bus: evbus.New(),
clock: clck, clock: clck,
charger: charger, charger: charger,
chargeMeter: &Null{}, // silence nil panics chargeMeter: &Null{}, // silence nil panics
chargeRater: &Null{}, // silence nil panics chargeRater: &Null{}, // silence nil panics
chargeTimer: &Null{}, // silence nil panics chargeTimer: &Null{}, // silence nil panics
wakeUpTimer: NewTimer(), wakeUpTimer: NewTimer(),
sessionEnergy: NewEnergyMetrics(), minCurrent: minA,
minCurrent: minA, maxCurrent: maxA,
maxCurrent: maxA, phases: 1,
phases: 1, status: tc.status, // no status change
status: tc.status, // no status change
} }
attachListeners(t, lp) attachListeners(t, lp)
@ -402,13 +401,12 @@ func TestDisableAndEnableAtTargetSoc(t *testing.T) {
progress: NewProgress(0, 10), // silence nil panics progress: NewProgress(0, 10), // silence nil panics
wakeUpTimer: NewTimer(), // silence nil panics wakeUpTimer: NewTimer(), // silence nil panics
// coordinator: coordinator.NewDummy(), // silence nil panics // coordinator: coordinator.NewDummy(), // silence nil panics
minCurrent: minA, minCurrent: minA,
maxCurrent: maxA, maxCurrent: maxA,
vehicle: vehicle, // needed for targetSoc check vehicle: vehicle, // needed for targetSoc check
socEstimator: socEstimator, // instead of vehicle: vehicle, socEstimator: socEstimator, // instead of vehicle: vehicle,
mode: api.ModeNow, mode: api.ModeNow,
sessionEnergy: NewEnergyMetrics(), limitSoc: 90, // session limit
limitSoc: 90, // session limit
Soc: SocConfig{ Soc: SocConfig{
Poll: PollConfig{ Poll: PollConfig{
Mode: pollConnected, // allow polling when connected Mode: pollConnected, // allow polling when connected
@ -472,19 +470,18 @@ func TestSetModeAndSocAtDisconnect(t *testing.T) {
charger := api.NewMockCharger(ctrl) charger := api.NewMockCharger(ctrl)
lp := &Loadpoint{ lp := &Loadpoint{
log: util.NewLogger("foo"), log: util.NewLogger("foo"),
bus: evbus.New(), bus: evbus.New(),
clock: clock, clock: clock,
charger: charger, charger: charger,
chargeMeter: &Null{}, // silence nil panics chargeMeter: &Null{}, // silence nil panics
chargeRater: &Null{}, // silence nil panics chargeRater: &Null{}, // silence nil panics
chargeTimer: &Null{}, // silence nil panics chargeTimer: &Null{}, // silence nil panics
wakeUpTimer: NewTimer(), wakeUpTimer: NewTimer(),
sessionEnergy: NewEnergyMetrics(), minCurrent: minA,
minCurrent: minA, maxCurrent: maxA,
maxCurrent: maxA, status: api.StatusC,
status: api.StatusC, Mode_: api.ModeOff, // default mode
Mode_: api.ModeOff, // default mode
} }
attachListeners(t, lp) attachListeners(t, lp)
@ -540,18 +537,17 @@ func TestChargedEnergyAtDisconnect(t *testing.T) {
rater := api.NewMockChargeRater(ctrl) rater := api.NewMockChargeRater(ctrl)
lp := &Loadpoint{ lp := &Loadpoint{
log: util.NewLogger("foo"), log: util.NewLogger("foo"),
bus: evbus.New(), bus: evbus.New(),
clock: clock, clock: clock,
charger: charger, charger: charger,
chargeMeter: &Null{}, // silence nil panics chargeMeter: &Null{}, // silence nil panics
chargeRater: rater, chargeRater: rater,
chargeTimer: &Null{}, // silence nil panics chargeTimer: &Null{}, // silence nil panics
wakeUpTimer: NewTimer(), wakeUpTimer: NewTimer(),
sessionEnergy: NewEnergyMetrics(), minCurrent: minA,
minCurrent: minA, maxCurrent: maxA,
maxCurrent: maxA, status: api.StatusC,
status: api.StatusC,
} }
attachListeners(t, lp) attachListeners(t, lp)

View file

@ -37,20 +37,19 @@ func TestPublishSocAndRange(t *testing.T) {
log := util.NewLogger("foo") log := util.NewLogger("foo")
lp := &Loadpoint{ lp := &Loadpoint{
log: log, log: log,
bus: evbus.New(), bus: evbus.New(),
clock: clck, clock: clck,
charger: charger, charger: charger,
vehicle: vehicle, vehicle: vehicle,
chargeMeter: &Null{}, // silence nil panics chargeMeter: &Null{}, // silence nil panics
chargeRater: &Null{}, // silence nil panics chargeRater: &Null{}, // silence nil panics
chargeTimer: &Null{}, // silence nil panics chargeTimer: &Null{}, // silence nil panics
socEstimator: soc.NewEstimator(log, charger, vehicle, false), socEstimator: soc.NewEstimator(log, charger, vehicle, false),
sessionEnergy: NewEnergyMetrics(), minCurrent: minA,
minCurrent: minA, maxCurrent: maxA,
maxCurrent: maxA, phases: 1,
phases: 1, mode: api.ModeNow,
mode: api.ModeNow,
} }
// populate channels // populate channels
@ -243,19 +242,18 @@ func TestReconnectVehicle(t *testing.T) {
charger.EXPECT().Status().Return(api.StatusB, nil).AnyTimes() charger.EXPECT().Status().Return(api.StatusB, nil).AnyTimes()
lp := &Loadpoint{ lp := &Loadpoint{
log: util.NewLogger("foo"), log: util.NewLogger("foo"),
bus: evbus.New(), bus: evbus.New(),
clock: clck, clock: clck,
charger: charger, charger: charger,
chargeMeter: &Null{}, // silence nil panics chargeMeter: &Null{}, // silence nil panics
chargeRater: &Null{}, // silence nil panics chargeRater: &Null{}, // silence nil panics
chargeTimer: &Null{}, // silence nil panics chargeTimer: &Null{}, // silence nil panics
wakeUpTimer: NewTimer(), wakeUpTimer: NewTimer(),
sessionEnergy: NewEnergyMetrics(), minCurrent: minA,
minCurrent: minA, maxCurrent: maxA,
maxCurrent: maxA, phases: 1,
phases: 1, mode: api.ModeNow,
mode: api.ModeNow,
} }
lp.coordinator = coordinator.NewAdapter(lp, coordinator.New(util.NewLogger("foo"), []api.Vehicle{vehicle})) lp.coordinator = coordinator.NewAdapter(lp, coordinator.New(util.NewLogger("foo"), []api.Vehicle{vehicle}))