Forecast: allow multiple solar tariffs (#18920)
This commit is contained in:
parent
2808a29c84
commit
70dca20f47
15 changed files with 274 additions and 51 deletions
29
api/rates.go
29
api/rates.go
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue