chore: simplify and rename energy metrics to avoid confusion (#18288)
This commit is contained in:
parent
350f50f2d7
commit
e8630e6bf4
8 changed files with 100 additions and 115 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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}))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue