Skip to content

Commit

Permalink
Revert "wip"
Browse files Browse the repository at this point in the history
This reverts commit 843392f.
  • Loading branch information
andig committed Dec 29, 2024
1 parent 843392f commit 6db5b66
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 92 deletions.
2 changes: 1 addition & 1 deletion core/keys/site.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ const (
Aux = "aux"
AuxPower = "auxPower"
Currency = "currency"
Ext = "ext"
GreenShareHome = "greenShareHome"
GreenShareLoadpoints = "greenShareLoadpoints"
GridConfigured = "gridConfigured"
Expand All @@ -30,6 +29,7 @@ const (
TariffPriceLoadpoints = "tariffPriceLoadpoints"
Vehicles = "vehicles"
Circuits = "circuits"
Ext = "ext"

// meters
GridMeter = "gridMeter"
Expand Down
248 changes: 157 additions & 91 deletions core/site.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,139 +434,232 @@ func (site *Site) publishDelta(key string, val interface{}) {
site.publish(key, val)
}

func (site *Site) collectMeters(key string, meters []api.Meter) []meterMeasurement {
// updatePvMeters updates pv meters. All measurements are optional.
func (site *Site) updatePvMeters() {
if len(site.pvMeters) == 0 {
return
}

var wg sync.WaitGroup
mm := make([]meterMeasurement, len(meters))

mm := make([]meterMeasurement, len(site.pvMeters))

fun := func(i int, meter api.Meter) {
// power
power, err := backoff.RetryWithData(meter.CurrentPower, bo())
if err == nil {
site.log.DEBUG.Printf("%s %d power: %.0fW", key, i+1, power)
if power < -500 {
site.log.WARN.Printf("pv %d power: %.0fW is negative - check configuration if sign is correct", i+1, power)
}
} else {
site.log.ERROR.Printf("%s %d power: %v", key, i+1, err)
site.log.ERROR.Printf("pv %d power: %v", i+1, err)
}

// energy (production)
var energy float64
if m, ok := meter.(api.MeterEnergy); err == nil && ok {
energy, err = m.TotalEnergy()
if err != nil {
site.log.ERROR.Printf("%s %d energy: %v", key, i+1, err)
site.log.ERROR.Printf("pv %d energy: %v", i+1, err)
}
}

var excessDC float64
var excessStr string
if m, ok := meter.(api.MaxACPower); ok {
if dc := m.MaxACPower() - power; dc < 0 && power > 0 {
excessDC = -dc
excessStr = fmt.Sprintf(" (includes %.0fW excess DC)", -dc)
}
}

if len(site.pvMeters) > 1 {
site.log.DEBUG.Printf("pv %d power: %.0fW"+excessStr, i+1, power)
}

mm[i] = meterMeasurement{
Power: power,
Energy: energy,
Power: power,
Energy: energy,
ExcessDCPower: excessDC,
}

wg.Done()
}

wg.Add(len(meters))
for i, meter := range meters {
wg.Add(len(site.pvMeters))
for i, meter := range site.pvMeters {
go fun(i, meter)
}
wg.Wait()

return mm
site.pvPower = lo.Reduce(mm, func(acc float64, m meterMeasurement, _ int) float64 {
return acc + max(0, m.Power)
}, 0)
site.excessDCPower = lo.Reduce(mm, func(acc float64, m meterMeasurement, _ int) float64 {
return acc - math.Abs(m.ExcessDCPower)
}, 0)
totalEnergy := lo.Reduce(mm, func(acc float64, m meterMeasurement, _ int) float64 {
return acc + m.Energy
}, 0)

var excessStr string
if site.excessDCPower < 0 {
excessStr = fmt.Sprintf(" (includes %.0fW excess DC)", -site.excessDCPower)
}

site.log.DEBUG.Printf("pv power: %.0fW"+excessStr, site.pvPower)
site.publish(keys.PvPower, site.pvPower)
site.publish(keys.PvEnergy, totalEnergy)
site.publish(keys.Pv, mm)
}

// updatePvMeters updates pv meters. All measurements are optional.
func (site *Site) updatePvMeters() {
if len(site.pvMeters) == 0 {
// updateAuxMeters updates aux meters
func (site *Site) updateAuxMeters() {
if len(site.auxMeters) == 0 {
return
}

mm := site.collectMeters("pv", site.pvMeters)
var wg sync.WaitGroup

for i, meter := range site.pvMeters {
power := mm[i].Power
mm := make([]meterMeasurement, len(site.auxMeters))

if power < -500 {
site.log.WARN.Printf("pv %d power: %.0fW is negative - check configuration if sign is correct", i+1, power)
fun := func(i int, meter api.Meter) {
if power, err := meter.CurrentPower(); err == nil {
mm[i].Power = power
site.log.DEBUG.Printf("aux power %d: %.0fW", i+1, power)
} else {
site.log.ERROR.Printf("aux meter %d: %v", i+1, err)
}

if m, ok := meter.(api.MaxACPower); ok {
if dc := m.MaxACPower() - power; dc < 0 && power > 0 {
mm[i].ExcessDCPower = -dc
site.log.DEBUG.Printf("pv %d excess DC: %.0fW", i+1, -dc)
}
}
wg.Done()
}

site.pvPower = lo.Reduce(mm, func(acc float64, m meterMeasurement, _ int) float64 {
return acc + max(0, m.Power)
}, 0)
site.excessDCPower = lo.Reduce(mm, func(acc float64, m meterMeasurement, _ int) float64 {
return acc - math.Abs(m.ExcessDCPower)
}, 0)
totalEnergy := lo.Reduce(mm, func(acc float64, m meterMeasurement, _ int) float64 {
return acc + m.Energy
wg.Add(len(site.auxMeters))
for i, meter := range site.auxMeters {
go fun(i, meter)
}
wg.Wait()

site.auxPower = lo.Reduce(mm, func(acc float64, m meterMeasurement, _ int) float64 {
return acc + m.Power
}, 0)

if len(site.pvMeters) > 1 {
var excessStr string
if site.excessDCPower < 0 {
excessStr = fmt.Sprintf(" (includes %.0fW excess DC)", -site.excessDCPower)
site.log.DEBUG.Printf("aux power: %.0fW", site.auxPower)
site.publish(keys.AuxPower, site.auxPower)
site.publish(keys.Aux, mm)
}

// updateExtMeters updates ext meters
func (site *Site) updateExtMeters() {
if len(site.extMeters) == 0 {
return
}

mm := make([]meterMeasurement, len(site.extMeters))

for i, meter := range site.extMeters {
// ext power
power, err := backoff.RetryWithData(meter.CurrentPower, bo())
if err != nil {
site.log.ERROR.Printf("ext meter %d power: %v", i+1, err)
}

site.log.DEBUG.Printf("pv power: %.0fW"+excessStr, site.pvPower)
// ext energy
var energy float64
if m, ok := meter.(api.MeterEnergy); err == nil && ok {
energy, err = m.TotalEnergy()
if err != nil {
site.log.ERROR.Printf("ext meter %d energy: %v", i+1, err)
}
}

mm[i] = meterMeasurement{
Power: power,
Energy: energy,
}
}

site.publish(keys.PvPower, site.pvPower)
site.publish(keys.PvEnergy, totalEnergy)
site.publish(keys.Pv, mm)
// Publishing will be done in separate PR
}

// updateBatteryMeters updates battery meters
func (site *Site) updateBatteryMeters() {
func (site *Site) updateBatteryMeters() error {
if len(site.batteryMeters) == 0 {
return
return nil
}

mm := site.collectMeters("battery", site.batteryMeters)
bm := make([]batteryMeasurement, len(site.batteryMeters))
var eg errgroup.Group

mm := make([]batteryMeasurement, len(site.batteryMeters))

fun := func(i int, meter api.Meter) error {
power, err := backoff.RetryWithData(meter.CurrentPower, bo())
if err != nil {
// power is required- return on error
return fmt.Errorf("battery %d power: %v", i+1, err)
}

if len(site.batteryMeters) > 1 {
site.log.DEBUG.Printf("battery %d power: %.0fW", i+1, power)
}

// battery energy (discharge)
var energy float64
if m, ok := meter.(api.MeterEnergy); ok {
energy, err = m.TotalEnergy()
if err != nil {
site.log.ERROR.Printf("battery %d energy: %v", i+1, err)
}
}

for i, meter := range site.batteryMeters {
// battery soc and capacity
var batSoc, capacity float64
var err error
if meter, ok := meter.(api.Battery); ok {
batSoc, err = soc.Guard(meter.Soc())

if m, ok := meter.(api.Battery); ok {
batSoc, err = soc.Guard(m.Soc())
if err == nil {
if m, ok := m.(api.BatteryCapacity); ok {
if m, ok := meter.(api.BatteryCapacity); ok {
capacity = m.Capacity()
}

site.log.DEBUG.Printf("battery %d soc: %.0f%%", i+1, batSoc)
if len(site.batteryMeters) > 1 {
site.log.DEBUG.Printf("battery %d soc: %.0f%%", i+1, batSoc)
}
} else {
site.log.ERROR.Printf("battery %d soc: %v", i+1, err)
}
}

_, controllable := meter.(api.BatteryController)

bm[i] = batteryMeasurement{
Power: mm[i].Power,
Energy: mm[i].Energy,
mm[i] = batteryMeasurement{
Power: power,
Energy: energy,
Soc: batSoc,
Capacity: capacity,
Controllable: controllable,
}

return nil
}

for i, meter := range site.batteryMeters {
eg.Go(func() error { return fun(i, meter) })
}

if err := eg.Wait(); err != nil {
return err
}

site.batterySoc = lo.Reduce(bm, func(acc float64, m batteryMeasurement, _ int) float64 {
site.batterySoc = lo.Reduce(mm, func(acc float64, m batteryMeasurement, _ int) float64 {
// weigh soc by capacity
weighedSoc := m.Soc
if m.Capacity > 0 {
weighedSoc *= m.Capacity
}
return acc + weighedSoc
}, 0)
totalCapacity := lo.Reduce(bm, func(acc float64, m batteryMeasurement, _ int) float64 {
totalCapacity := lo.Reduce(mm, func(acc float64, m batteryMeasurement, _ int) float64 {
return acc + m.Capacity
}, 0)

Expand All @@ -576,50 +669,23 @@ func (site *Site) updateBatteryMeters() {
}
site.batterySoc /= totalCapacity

site.batteryPower = lo.Reduce(bm, func(acc float64, m batteryMeasurement, _ int) float64 {
site.log.DEBUG.Printf("battery soc: %.0f%%", math.Round(site.batterySoc))
site.publish(keys.BatteryCapacity, totalCapacity)
site.publish(keys.BatterySoc, site.batterySoc)

site.batteryPower = lo.Reduce(mm, func(acc float64, m batteryMeasurement, _ int) float64 {
return acc + m.Power
}, 0)
totalEnergy := lo.Reduce(bm, func(acc float64, m batteryMeasurement, _ int) float64 {
totalEnergy := lo.Reduce(mm, func(acc float64, m batteryMeasurement, _ int) float64 {
return acc + m.Energy
}, 0)

if len(site.batteryMeters) > 1 {
site.log.DEBUG.Printf("battery power: %.0fW", site.batteryPower)
site.log.DEBUG.Printf("battery soc: %.0f%%", math.Round(site.batterySoc))
}

site.publish(keys.BatteryCapacity, totalCapacity)
site.publish(keys.BatterySoc, site.batterySoc)

site.log.DEBUG.Printf("battery power: %.0fW", site.batteryPower)
site.publish(keys.BatteryPower, site.batteryPower)
site.publish(keys.BatteryEnergy, totalEnergy)
site.publish(keys.Battery, mm)
}

// updateAuxMeters updates aux meters
func (site *Site) updateAuxMeters() {
if len(site.auxMeters) == 0 {
return
}

mm := site.collectMeters("aux", site.auxMeters)
site.auxPower = lo.Reduce(mm, func(acc float64, m meterMeasurement, _ int) float64 {
return acc + m.Power
}, 0)

site.log.DEBUG.Printf("aux power: %.0fW", site.auxPower)
site.publish(keys.AuxPower, site.auxPower)
site.publish(keys.Aux, mm)
}

// updateExtMeters updates ext meters
func (site *Site) updateExtMeters() {
if len(site.extMeters) == 0 {
return
}

mm := site.collectMeters("ext", site.extMeters)
site.publish(keys.Ext, mm)
return nil
}

// updateGridMeter updates grid meter
Expand Down Expand Up @@ -676,10 +742,10 @@ func (site *Site) updateMeters() error {
var eg errgroup.Group

eg.Go(func() error { site.updatePvMeters(); return nil })
eg.Go(func() error { site.updateBatteryMeters(); return nil })
eg.Go(func() error { site.updateAuxMeters(); return nil })
eg.Go(func() error { site.updateExtMeters(); return nil })

eg.Go(site.updateBatteryMeters)
eg.Go(site.updateGridMeter)

return eg.Wait()
Expand Down

0 comments on commit 6db5b66

Please sign in to comment.