From 84f064abd8e71e6ffe72974caba0bfa57827efbd Mon Sep 17 00:00:00 2001 From: Per Magnus Petersen Date: Wed, 9 Sep 2026 18:01:56 +0200 Subject: [PATCH] Fetch tomorow --- .../elprice/web/controllers/prices.clj | 49 +++++++++++++++++-- src/clj/pmagnus/elprice/web/routes/api.clj | 11 +++-- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/clj/pmagnus/elprice/web/controllers/prices.clj b/src/clj/pmagnus/elprice/web/controllers/prices.clj index 4e3bed0..671fbb3 100644 --- a/src/clj/pmagnus/elprice/web/controllers/prices.clj +++ b/src/clj/pmagnus/elprice/web/controllers/prices.clj @@ -13,7 +13,10 @@ (java.sql Timestamp) (java.time + Duration + Instant LocalDate + LocalTime ZoneId) (java.time.format DateTimeFormatter))) @@ -125,11 +128,49 @@ (get-prices-for-date query-fn (.plusDays (LocalDate/now dk-zone) 1) "DK1")) +(def ^:private tomorrow-published-at + "Day-ahead prices for tomorrow are published around 13:00 CET." + (LocalTime/of 13 0)) + + +(defn- tomorrow-available? + "True once tomorrow's prices are expected to be published." + [] + (not (.isBefore (LocalTime/now dk-zone) tomorrow-published-at))) + + +(def ^:private retry-interval + "Minimum wait between fetches when the API has nothing new yet." + (Duration/ofMinutes 15)) + + +(defonce ^:private last-fetch-attempt (atom nil)) + + +(defn- retry-due? + "True when enough time has passed since the last fetch attempt." + [] + (let [last @last-fetch-attempt] + (or (nil? last) + (>= (.compareTo (Duration/between last (Instant/now)) retry-interval) 0)))) + + (defn ensure-current-prices! - "Fetch prices only when today's DK1 prices are missing from the database." + "Fetch prices when today's DK1 prices are missing, or - after 13:00 - when + tomorrow's are still missing." [query-fn] - (if (seq (get-today-prices query-fn)) + (cond + (empty? (get-today-prices query-fn)) + (do (reset! last-fetch-attempt (Instant/now)) + (fetch-and-save! query-fn)) + + (and (tomorrow-available?) + (empty? (get-tomorrow-prices query-fn)) + (retry-due?)) + (do (reset! last-fetch-attempt (Instant/now)) + (fetch-and-save! query-fn)) + + :else (do (log/info "Day-ahead prices already exist; skipping API fetch") - nil) - (fetch-and-save! query-fn))) + nil))) diff --git a/src/clj/pmagnus/elprice/web/routes/api.clj b/src/clj/pmagnus/elprice/web/routes/api.clj index 93d8315..0f34add 100644 --- a/src/clj/pmagnus/elprice/web/routes/api.clj +++ b/src/clj/pmagnus/elprice/web/routes/api.clj @@ -47,11 +47,12 @@ rows (elprice/get-or-fetch! query-fn d)] (http-response/ok {:date date - :prices (mapv (fn [r] {:time_dk (str (:time_dk r)) - :price_area (:price_area r) - :price_dkk (:price_dkk r) - :tariff_dkk (:tariff_dkk r) - :total_dkk (:total_dkk r)}) + :prices (mapv (fn [r] + {:time_dk (str (:time_dk r)) + :price_area (:price_area r) + :price_dkk (:price_dkk r) + :tariff_dkk (:tariff_dkk r) + :total_dkk (:total_dkk r)}) rows)})) (catch DateTimeParseException _ (http-response/bad-request {:error "date must be YYYY-MM-DD"}))))