Forecast: allow multiple solar tariffs (#18920)

This commit is contained in:
andig 2025-02-18 15:26:26 +01:00 • committed by GitHub
parent 2808a29c84
commit 70dca20f47
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 274 additions and 51 deletions

View file

@ -2,7 +2,6 @@ package api
import (
"encoding/json"
"fmt"
"slices"
"time"
)
@ -23,25 +22,29 @@ func (r Rate) IsZero() bool {
type Rates []Rate
// Sort rates by start time
func (r Rates) Sort() {
slices.SortStableFunc(r, func(i, j Rate) int {
func (rr Rates) Sort() {
slices.SortStableFunc(rr, func(i, j Rate) int {
return i.Start.Compare(j.Start)
})
}
// Current returns the rates current rate or error
func (r Rates) Current(now time.Time) (Rate, error) {
for _, rr := range r {
if !rr.Start.After(now) && rr.End.After(now) {
return rr, nil
// At returns the rate for given timestamp or error.
// Rates MUST be sorted by start time.
func (rr Rates) At(ts time.Time) (Rate, error) {
if i, ok := slices.BinarySearchFunc(rr, ts, func(r Rate, ts time.Time) int {
switch {
case ts.Before(r.Start):
return +1
case !ts.Before(r.End):
return -1
default:
return 0
}
}); ok {
return rr[i], nil
}
if len(r) == 0 {
return Rate{}, fmt.Errorf("no matching rate for: %s", now.Local().Format(time.RFC3339))
}
return Rate{}, fmt.Errorf("no matching rate for: %s, %d rates (%s to %s)",
now.Local().Format(time.RFC3339), len(r), r[0].Start.Local().Format(time.RFC3339), r[len(r)-1].End.Local().Format(time.RFC3339))
return Rate{}, ErrNotAvailable
}
// MarshalMQTT implements server.MQTTMarshaler