diff --git a/tariff/energinet.go b/tariff/energinet.go deleted file mode 100644 index bb6467e10..000000000 --- a/tariff/energinet.go +++ /dev/null @@ -1,109 +0,0 @@ -package tariff - -import ( - "errors" - "fmt" - "slices" - "strings" - "sync" - "time" - - "github.com/cenkalti/backoff/v4" - "github.com/evcc-io/evcc/api" - "github.com/evcc-io/evcc/tariff/energinet" - "github.com/evcc-io/evcc/util" - "github.com/evcc-io/evcc/util/request" -) - -type Energinet struct { - *embed - log *util.Logger - region string - data *util.Monitor[api.Rates] -} - -var _ api.Tariff = (*Energinet)(nil) - -func init() { - registry.Add("energinet", NewEnerginetFromConfig) -} - -func NewEnerginetFromConfig(other map[string]interface{}) (api.Tariff, error) { - var cc struct { - embed `mapstructure:",squash"` - Region string - } - - if err := util.DecodeOther(other, &cc); err != nil { - return nil, err - } - - if cc.Region == "" { - return nil, errors.New("missing region") - } - - if err := cc.init(); err != nil { - return nil, err - } - - t := &Energinet{ - embed: &cc.embed, - log: util.NewLogger("energinet"), - region: strings.ToLower(cc.Region), - data: util.NewMonitor[api.Rates](2 * time.Hour), - } - - return runOrError(t) -} - -func (t *Energinet) run(done chan error) { - var once sync.Once - client := request.NewHelper(t.log) - - for tick := time.Tick(time.Hour); ; <-tick { - var res energinet.Prices - - ts := time.Now().Truncate(time.Hour) - uri := fmt.Sprintf(energinet.URI, - ts.Format(energinet.TimeFormat), - ts.Add(24*time.Hour).Format(energinet.TimeFormat), - t.region) - - if err := backoff.Retry(func() error { - return backoffPermanentError(client.GetJSON(uri, &res)) - }, bo()); err != nil { - once.Do(func() { done <- err }) - - t.log.ERROR.Println(err) - continue - } - - data := make(api.Rates, 0, len(res.Records)) - for _, r := range res.Records { - ts, _ := time.Parse("2006-01-02T15:04:05", r.HourUTC) - ar := api.Rate{ - Start: ts.Local(), - End: ts.Add(time.Hour).Local(), - Value: t.totalPrice(r.SpotPriceDKK/1e3, ts), - } - data = append(data, ar) - } - - mergeRates(t.data, data) - once.Do(func() { close(done) }) - } -} - -// Rates implements the api.Tariff interface -func (t *Energinet) Rates() (api.Rates, error) { - var res api.Rates - err := t.data.GetFunc(func(val api.Rates) { - res = slices.Clone(val) - }) - return res, err -} - -// Type implements the api.Tariff interface -func (t *Energinet) Type() api.TariffType { - return api.TariffTypePriceForecast -} diff --git a/tariff/energinet/types.go b/tariff/energinet/types.go deleted file mode 100644 index 4ae7a99cb..000000000 --- a/tariff/energinet/types.go +++ /dev/null @@ -1,18 +0,0 @@ -package energinet - -const ( - URI = "https://api.energidataservice.dk/dataset/Elspotprices?offset=0&start=%s&end=%s&filter={\"PriceArea\":[\"%s\"]}&timezone=dk&limit=48" - TimeFormat = "2006-01-02T15:04" // RFC3339 short -) - -type Prices struct { - Records []PriceInfo `json:"records"` -} - -type PriceInfo struct { - HourUTC string - HourDK string - PriceArea string - SpotPriceDKK float64 - SpotPriceEUR float64 -} diff --git a/templates/definition/tariff/energinet-price.yaml b/templates/definition/tariff/energinet-price.yaml new file mode 100644 index 000000000..b43b5f742 --- /dev/null +++ b/templates/definition/tariff/energinet-price.yaml @@ -0,0 +1,32 @@ +template: energinet-price +covers: ["energinet"] +products: + - brand: Energinet +requirements: + evcc: ["skiptest"] +group: price +countries: ["DK"] +params: + - name: region + example: dk1 + type: choice + choice: ["dk1", "dk2"] + required: true + - preset: tariff-base +render: | + type: custom + tariff: co2 + forecast: + source: http + uri: https://api.energidataservice.dk/dataset/Elspotprices?filter={"PriceArea":["{{ .region }}"]} + jq: | + [.records[] | + { + start: (.HourUTC[0:13] + ":00:00Z"), + end: (.HourUTC[0:13] + | strptime("%Y-%m-%dT%H") + | mktime + 3600 + | strftime("%Y-%m-%dT%H:%M:%SZ")), + value: .SpotPriceDKK / 1e3 + } + ] | tostring diff --git a/templates/definition/tariff/energinet.yaml b/templates/definition/tariff/energinet.yaml deleted file mode 100644 index 68b634245..000000000 --- a/templates/definition/tariff/energinet.yaml +++ /dev/null @@ -1,18 +0,0 @@ -template: energinet -products: - - brand: Energinet -requirements: - evcc: ["skiptest"] -group: price -countries: ["DK"] -params: - - name: region - example: dk1 - type: choice - choice: ["dk1", "dk2"] - required: true - - preset: tariff-base -render: | - type: energinet - region: {{ .region }} - {{ include "tariff-base" . }}