Add tariff_dkk + total_dkk to elprice

Each hourly row now carries the N1 time-of-use tariff (øre/kWh × 10
to match the DKK/MWh unit of price_dkk) and the combined consumer
price (spot + tariff). Existing rows are backfilled in the migration
with a CASE expression mirroring tariffs/tariff-for-hour; new writes
compute it in the controller. API response exposes both fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-19 12:48:46 +02:00
co-authored by Claude Opus 4.7
parent 06b575d709
commit da20691d2b
5 changed files with 52 additions and 11 deletions
@@ -0,0 +1,3 @@
ALTER TABLE elprice DROP COLUMN total_dkk;
--;;
ALTER TABLE elprice DROP COLUMN tariff_dkk;
@@ -0,0 +1,21 @@
ALTER TABLE elprice ADD COLUMN tariff_dkk NUMERIC(10,2);
--;;
ALTER TABLE elprice ADD COLUMN total_dkk NUMERIC(10,2);
--;;
UPDATE elprice
SET tariff_dkk = CASE
WHEN EXTRACT(MONTH FROM time_dk) BETWEEN 4 AND 9 THEN
CASE
WHEN EXTRACT(HOUR FROM time_dk) < 6 THEN 109.80
WHEN EXTRACT(HOUR FROM time_dk) >= 17 AND EXTRACT(HOUR FROM time_dk) < 21 THEN 428.30
ELSE 164.70
END
ELSE
CASE
WHEN EXTRACT(HOUR FROM time_dk) < 6 THEN 109.80
WHEN EXTRACT(HOUR FROM time_dk) >= 17 AND EXTRACT(HOUR FROM time_dk) < 21 THEN 988.40
ELSE 329.50
END
END;
--;;
UPDATE elprice SET total_dkk = price_dkk + tariff_dkk WHERE tariff_dkk IS NOT NULL;
+7 -5
View File
@@ -67,14 +67,16 @@ VALUES (:time-start, :hour, :kwh)
ON CONFLICT (time_start, hour) DO NOTHING;
-- :name insert-elprice! :! :n
-- :doc Insert an hourly el-price row; keep first value on conflict
INSERT INTO elprice (time_dk, price_area, price_dkk)
VALUES (:time-dk, :price-area, :price-dkk)
ON CONFLICT (time_dk, price_area) DO NOTHING;
-- :doc Upsert an hourly el-price row; refresh tariff/total on conflict
INSERT INTO elprice (time_dk, price_area, price_dkk, tariff_dkk, total_dkk)
VALUES (:time-dk, :price-area, :price-dkk, :tariff-dkk, :total-dkk)
ON CONFLICT (time_dk, price_area) DO UPDATE SET
tariff_dkk = EXCLUDED.tariff_dkk,
total_dkk = EXCLUDED.total_dkk;
-- :name get-elprice-for-date :? :*
-- :doc Hourly prices for a DK local date, both areas
SELECT time_dk, price_area, price_dkk
SELECT time_dk, price_area, price_dkk, tariff_dkk, total_dkk
FROM elprice
WHERE time_dk::date = :date
ORDER BY time_dk, price_area;
@@ -1,7 +1,8 @@
(ns pmagnus.elprice.web.controllers.elprice
(:require
[clojure.data.json :as json]
[clojure.tools.logging :as log])
[clojure.tools.logging :as log]
[pmagnus.elprice.web.controllers.tariffs :as tariffs])
(:import
(java.net
URI
@@ -14,6 +15,7 @@
Timestamp)
(java.time
LocalDate
LocalDateTime
ZoneId)
(java.time.format
DateTimeFormatter)))
@@ -68,14 +70,25 @@
(:records (fetch-json url))))
(defn- tariff-dkk-mwh
"N1 time-of-use tariff converted from øre/kWh to DKK/MWh (×10)."
[^LocalDateTime dt]
(* 10.0 (tariffs/tariff-for-hour (.getMonthValue dt) (.getHour dt))))
(defn- save-records!
[query-fn records]
(doseq [rec records]
(when-let [dkk (dkk-price (:DayAheadPriceDKK rec) (:DayAheadPriceEUR rec))]
(query-fn :insert-elprice!
{:time-dk (parse-timestamp (:TimeDK rec))
:price-area (:PriceArea rec)
:price-dkk dkk}))))
(let [ts (parse-timestamp (:TimeDK rec))
tariff (tariff-dkk-mwh (.toLocalDateTime ^Timestamp ts))
total (+ (double dkk) tariff)]
(query-fn :insert-elprice!
{:time-dk ts
:price-area (:PriceArea rec)
:price-dkk dkk
:tariff-dkk tariff
:total-dkk total})))))
(defn get-or-fetch!
+3 -1
View File
@@ -49,7 +49,9 @@
{:date date
:prices (mapv (fn [r] {:time_dk (str (:time_dk r))
:price_area (:price_area r)
:price_dkk (:price_dkk 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"}))))