Add plausi check for phase configuration

This commit is contained in:
andig 2021-08-21 14:25:31 +02:00
parent c77e455809
commit 6fd6d7472c
6 changed files with 24 additions and 19 deletions

View file

@ -16,7 +16,7 @@ var (
)
// powerToCurrent is a helper function to convert power to per-phase current
func powerToCurrent(power float64, phases int64) float64 {
func powerToCurrent(power float64, phases int) float64 {
if Voltage == 0 {
panic("Voltage is not set")
}

View file

@ -86,7 +86,7 @@ type LoadPoint struct {
Mode api.ChargeMode `mapstructure:"mode"` // Charge mode, guarded by mutex
Title string `mapstructure:"title"` // UI title
Phases int64 `mapstructure:"phases"` // Charger enabled phases
Phases int `mapstructure:"phases"` // Charger enabled phases
ChargerRef string `mapstructure:"charger"` // Charger reference
VehicleRef string `mapstructure:"vehicle"` // Vehicle reference
VehiclesRef []string `mapstructure:"vehicles"` // Vehicles reference
@ -103,7 +103,7 @@ type LoadPoint struct {
GuardDuration time.Duration // charger enable/disable minimum holding time
enabled bool // Charger enabled state
activePhases int64 // Charger active phases as used by vehicle
activePhases int // Charger active phases as used by vehicle
chargeCurrent float64 // Charger current limit
guardUpdated time.Time // Charger enabled/disabled timestamp
socUpdated time.Time // SoC updated timestamp (poll: connected)
@ -848,7 +848,7 @@ func (lp *LoadPoint) scalePhases(phases int) error {
}
lp.Lock()
if lp.Phases != int64(phases) {
if lp.Phases != phases {
lp.Unlock()
// disable charger - this will also stop the car charging using the api if available
@ -862,7 +862,7 @@ func (lp *LoadPoint) scalePhases(phases int) error {
}
lp.Lock()
lp.Phases = int64(phases)
lp.Phases = phases
lp.publish("phases", lp.Phases)
// disable phase timer
@ -883,6 +883,10 @@ func (lp *LoadPoint) pvScalePhases(availablePower, minCurrent, maxCurrent float6
phases := lp.GetPhases()
targetCurrent := availablePower / Voltage / float64(lp.activePhases)
if phases < lp.activePhases {
lp.log.WARN.Printf("invalid status: %dp active @ %dp configured", lp.activePhases, phases)
}
lp.log.DEBUG.Printf("!!pvScalePhases available power %.0f for target current %.1f @ %dp/%dp", availablePower, targetCurrent, lp.activePhases, phases)
if lp.phaseTimer.IsZero() {
lp.log.DEBUG.Printf("!!pvScalePhases timer empty")
@ -1070,7 +1074,7 @@ func (lp *LoadPoint) updateChargeCurrents() {
// guess active phases from power consumption
// assumes that chargePower has been updated before
if lp.charging() && lp.chargeCurrent > 0 {
phases := int64(math.Round(lp.chargePower / Voltage / lp.chargeCurrent))
phases := int(math.Round(lp.chargePower / Voltage / lp.chargeCurrent))
if phases >= 1 && phases <= 3 {
lp.activePhases = phases
lp.log.DEBUG.Printf("detected phases: %dp (%.1fA @ %.0fW)", lp.activePhases, lp.chargeCurrent, lp.chargePower)
@ -1092,7 +1096,7 @@ func (lp *LoadPoint) updateChargeCurrents() {
lp.publish("chargeCurrents", lp.chargeCurrents)
if lp.charging() {
var phases int64
var phases int
for _, i := range lp.chargeCurrents {
if i >= minActiveCurrent {
phases++

View file

@ -18,7 +18,7 @@ func (a *adapter) SocEstimator() *soc.Estimator {
return a.lp.socEstimator
}
func (a *adapter) ActivePhases() int64 {
func (a *adapter) ActivePhases() int {
return a.lp.activePhases
}

View file

@ -897,8 +897,8 @@ func TestScalePhases(t *testing.T) {
charger: charger,
MinCurrent: minA,
MaxCurrent: maxA,
Phases: int64(tc.phases),
activePhases: int64(tc.activePhases),
Phases: tc.phases,
activePhases: tc.activePhases,
Enable: ThresholdConfig{
Delay: dt,
},
@ -918,7 +918,7 @@ func TestScalePhases(t *testing.T) {
if res := lp.pvScalePhases(tc.availablePower, minA, maxA); tc.res != res {
t.Errorf("expected %v, got %v", tc.res, res)
} else {
if lp.Phases != int64(tc.toPhases) {
if lp.Phases != tc.toPhases {
t.Errorf("expected %dp, got %dp", tc.toPhases, lp.Phases)
}
}

9
core/soc/adapter.go Normal file
View file

@ -0,0 +1,9 @@
package soc
// Adapter provides the required methods for interacting with the loadpoint
type Adapter interface {
Publish(key string, val interface{})
SocEstimator() *Estimator
ActivePhases() int
Voltage() float64
}

View file

@ -11,14 +11,6 @@ const (
deviation = 30 * time.Minute
)
// Adapter provides the required methods for interacting with the loadpoint
type Adapter interface {
Publish(key string, val interface{})
SocEstimator() *Estimator
ActivePhases() int64
Voltage() float64
}
// Timer is the target charging handler
type Timer struct {
Adapter