evcc-io/api/rates.go
2025-02-09 20:36:22 +01:00

50 lines
1.2 KiB
Go

package api
import (
"encoding/json"
"fmt"
"slices"
"time"
)
// Rate is a grid tariff rate
type Rate struct {
Start time.Time `json:"start"`
End time.Time `json:"end"`
Price float64 `json:"price"`
}
// IsEmpty returns is the rate is the zero value
func (r Rate) IsEmpty() bool {
return r.Start.IsZero() && r.End.IsZero() && r.Price == 0
}
// Rates is a slice of (future) tariff rates
type Rates []Rate
// Sort rates by start time
func (r Rates) Sort() {
slices.SortStableFunc(r, 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
}
}
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))
}
// MarshalMQTT implements server.MQTTMarshaler
func (r Rates) MarshalMQTT() ([]byte, error) {
return json.Marshal(r)
}