Ctrl K
ComunidadGuías…

tariff/proxy_average.go

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package tariff

import (
	"slices"
	"time"

	"github.com/evcc-io/evcc/api"
)

// average wraps a tariff with averaging
type average struct {
	average time.Duration
	api.Tariff
}

// NewAverageProxy creates a proxy that tariff averaging
func NewAverageProxy(t api.Tariff) (api.Tariff, error) {
	return &average{
		average: time.Hour,
		Tariff:  t,
	}, nil
}

func (t *average) Rates() (api.Rates, error) {
	rates, err := t.Tariff.Rates()
	if len(rates) == 0 || err != nil {
		return rates, err
	}

	return averageSlots(rates, t.average), nil
}

// averageSlots averages 15-minute slots by period
func averageSlots(rates api.Rates, average time.Duration) api.Rates {
	if len(rates) == 0 {
		return nil
	}

	// accumulate sums and counts per period
	avgs := make(map[time.Time]*struct {
		sum float64
		cnt int
	})

	for _, r := range rates {
		ts := r.Start.Truncate(average)
		avg, ok := avgs[ts]
		if !ok {
			avg = new(struct {
				sum float64
				cnt int
			})
			avgs[ts] = avg
		}
		avg.sum += r.Value
		avg.cnt++
	}

	res := slices.Clone(rates)
	for i, r := range res {
		avg := avgs[r.Start.Truncate(average)]
		res[i].Value = avg.sum / float64(avg.cnt)
	}

	return res
}