-
-
Notifications
You must be signed in to change notification settings - Fork 529
/
loadpoint_effective.go
136 lines (113 loc) Β· 3.51 KB
/
loadpoint_effective.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package core
import (
"time"
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/core/keys"
"github.com/evcc-io/evcc/core/vehicle"
)
// PublishEffectiveValues publishes all effective values
func (lp *Loadpoint) PublishEffectiveValues() {
lp.publish(keys.EffectivePriority, lp.EffectivePriority())
lp.publish(keys.EffectivePlanTime, lp.EffectivePlanTime())
lp.publish(keys.EffectivePlanSoc, lp.EffectivePlanSoc())
lp.publish(keys.EffectiveMinCurrent, lp.effectiveMinCurrent())
lp.publish(keys.EffectiveMaxCurrent, lp.effectiveMaxCurrent())
lp.publish(keys.EffectiveLimitSoc, lp.effectiveLimitSoc())
}
// EffectivePriority returns the effective priority
func (lp *Loadpoint) EffectivePriority() int {
if v := lp.GetVehicle(); v != nil {
if res, ok := v.OnIdentified().GetPriority(); ok {
return res
}
}
return lp.GetPriority()
}
// vehiclePlanSoc returns the next vehicle plan time and soc
func (lp *Loadpoint) vehiclePlanSoc() (time.Time, int) {
if v := lp.GetVehicle(); v != nil {
return vehicle.Settings(lp.log, v).GetPlanSoc()
}
return time.Time{}, 0
}
// EffectivePlanSoc returns the soc target for the current plan
func (lp *Loadpoint) EffectivePlanSoc() int {
_, soc := lp.vehiclePlanSoc()
return soc
}
// EffectivePlanTime returns the effective plan time
func (lp *Loadpoint) EffectivePlanTime() time.Time {
if lp.socBasedPlanning() {
ts, _ := lp.vehiclePlanSoc()
return ts
}
ts, _ := lp.GetPlanEnergy()
return ts
}
// SocBasedPlanning returns true if soc based planning is enabled
func (lp *Loadpoint) SocBasedPlanning() bool {
return lp.socBasedPlanning()
}
// effectiveMinCurrent returns the effective min current
func (lp *Loadpoint) effectiveMinCurrent() float64 {
lpMin := lp.GetMinCurrent()
var vehicleMin, chargerMin float64
if v := lp.GetVehicle(); v != nil {
if res, ok := v.OnIdentified().GetMinCurrent(); ok {
vehicleMin = res
}
}
if c, ok := lp.charger.(api.CurrentLimiter); ok {
if res, _, err := c.GetMinMaxCurrent(); err == nil {
chargerMin = res
}
}
switch {
case max(vehicleMin, chargerMin) == 0:
return lpMin
case chargerMin > 0:
return max(vehicleMin, chargerMin)
default:
return max(vehicleMin, lpMin)
}
}
// effectiveMaxCurrent returns the effective max current
func (lp *Loadpoint) effectiveMaxCurrent() float64 {
maxCurrent := lp.GetMaxCurrent()
if v := lp.GetVehicle(); v != nil {
if res, ok := v.OnIdentified().GetMaxCurrent(); ok && res > 0 {
maxCurrent = min(maxCurrent, res)
}
}
if c, ok := lp.charger.(api.CurrentLimiter); ok {
if _, res, err := c.GetMinMaxCurrent(); err == nil && res > 0 {
maxCurrent = min(maxCurrent, res)
}
}
return maxCurrent
}
// effectiveLimitSoc returns the effective session limit soc
// TODO take vehicle api limits into account
func (lp *Loadpoint) effectiveLimitSoc() int {
lp.RLock()
defer lp.RUnlock()
if lp.limitSoc > 0 {
return lp.limitSoc
}
if v := lp.GetVehicle(); v != nil {
if soc := vehicle.Settings(lp.log, v).GetLimitSoc(); soc > 0 {
return soc
}
}
// MUST return 100 here as UI looks at effectiveLimitSoc and not limitSoc (VehicleSoc.vue)
return 100
}
// EffectiveMinPower returns the effective min power for a single phase
func (lp *Loadpoint) EffectiveMinPower() float64 {
// TODO check if 1p available
return Voltage * lp.effectiveMinCurrent()
}
// EffectiveMaxPower returns the effective max power taking vehicle capabilities and phase scaling into account
func (lp *Loadpoint) EffectiveMaxPower() float64 {
return Voltage * lp.effectiveMaxCurrent() * float64(lp.maxActivePhases())
}