Fetch prices from elprisenligenu.dk
Swap the Energi Data Service datasets (DayAheadPrices + Elspotprices) for elprisenligenu.dk's public hourly JSON API. The new source covers both historical and post-2025 dates — previously, Elspotprices was empty for all 2026 dates and DayAheadPrices was scoped to tomorrow only, leaving days like 2026-04-07 uncovered. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,8 +5,7 @@
|
||||
[pmagnus.elprice.web.controllers.tariffs :as tariffs])
|
||||
(:import
|
||||
(java.net
|
||||
URI
|
||||
URLEncoder)
|
||||
URI)
|
||||
(java.net.http
|
||||
HttpClient
|
||||
HttpRequest
|
||||
@@ -15,27 +14,16 @@
|
||||
Timestamp)
|
||||
(java.time
|
||||
LocalDate
|
||||
LocalDateTime
|
||||
ZoneId)
|
||||
(java.time.format
|
||||
DateTimeFormatter)))
|
||||
LocalDateTime)))
|
||||
|
||||
|
||||
(def ^:private dk-zone (ZoneId/of "Europe/Copenhagen"))
|
||||
(def ^:private date-fmt (DateTimeFormatter/ofPattern "yyyy-MM-dd"))
|
||||
(def ^:private eur-dkk-rate 7.46)
|
||||
|
||||
|
||||
(defn- build-url
|
||||
[^LocalDate date]
|
||||
(let [start (.format date date-fmt)
|
||||
end (.format (.plusDays date 1) date-fmt)]
|
||||
(str "https://api.energidataservice.dk/dataset/DayAheadPrices"
|
||||
"?start=" start
|
||||
"&end=" end
|
||||
"&filter=" (URLEncoder/encode (json/write-str {"PriceArea" ["DK1" "DK2"]}) "UTF-8")
|
||||
"&sort=TimeDK%20asc"
|
||||
"&limit=200")))
|
||||
(defn- elprisen-url
|
||||
[^LocalDate date area]
|
||||
(format "https://www.elprisenligenu.dk/api/v1/prices/%04d/%02d-%02d_%s.json"
|
||||
(.getYear date) (.getMonthValue date) (.getDayOfMonth date) area))
|
||||
|
||||
|
||||
(defn- fetch-json
|
||||
@@ -63,11 +51,29 @@
|
||||
(when price-eur (* price-eur eur-dkk-rate))))
|
||||
|
||||
|
||||
(defn- fetch-area
|
||||
"Fetch hourly prices for one price area from elprisenligenu.dk."
|
||||
[^LocalDate date area]
|
||||
(let [url (elprisen-url date area)
|
||||
_ (log/info "Fetching" url)
|
||||
records (fetch-json url)]
|
||||
(when (sequential? records)
|
||||
(map (fn [r]
|
||||
;; time_start is "YYYY-MM-DDTHH:MM:SS+HH:MM" already in DK local;
|
||||
;; drop the 6-char offset suffix, keep the naive wall-clock stamp.
|
||||
(let [ts (subs (:time_start r) 0 19)]
|
||||
{:time-dk ts
|
||||
:area area
|
||||
:dkk (some-> (:DKK_per_kWh r) (* 1000.0)) ; kWh → MWh
|
||||
:eur (some-> (:EUR_per_kWh r) (* 1000.0))}))
|
||||
records))))
|
||||
|
||||
|
||||
(defn- fetch-from-api
|
||||
"Fetch hourly prices for both DK1 and DK2 from elprisenligenu.dk."
|
||||
[^LocalDate date]
|
||||
(let [url (build-url date)]
|
||||
(log/info "Fetching el prices for" (.format date date-fmt) "from" url)
|
||||
(:records (fetch-json url))))
|
||||
(concat (fetch-area date "DK1")
|
||||
(fetch-area date "DK2")))
|
||||
|
||||
|
||||
(defn- tariff-dkk-mwh
|
||||
@@ -79,13 +85,13 @@
|
||||
(defn- save-records!
|
||||
[query-fn records]
|
||||
(doseq [rec records]
|
||||
(when-let [dkk (dkk-price (:DayAheadPriceDKK rec) (:DayAheadPriceEUR rec))]
|
||||
(let [ts (parse-timestamp (:TimeDK rec))
|
||||
(when-let [dkk (dkk-price (:dkk rec) (:eur rec))]
|
||||
(let [ts (parse-timestamp (:time-dk rec))
|
||||
tariff (tariff-dkk-mwh (.toLocalDateTime ^Timestamp ts))
|
||||
total (+ (double dkk) tariff)]
|
||||
(query-fn :insert-elprice!
|
||||
{:time-dk ts
|
||||
:price-area (:PriceArea rec)
|
||||
:price-area (:area rec)
|
||||
:price-dkk dkk
|
||||
:tariff-dkk tariff
|
||||
:total-dkk total})))))
|
||||
|
||||
Reference in New Issue
Block a user