Add date-parameterized sync with production and consumption tables

- Accept ?date= param on POST /eloverblik/sync (defaults to today)
- Populate production table from D06 meter (571313113163368491)
- Populate consumption table from D07 meter (571313113163368507)
- ON CONFLICT DO NOTHING to skip existing data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-14 18:09:36 +01:00
co-authored by Claude Opus 4.6
parent ca473c62bb
commit d756c98810
3 changed files with 46 additions and 9 deletions
@@ -145,10 +145,30 @@
results
metering-point-ids)))
(defn- save-time-series! [query-fn readings]
(def ^:private production-mp-id "571313113163368491")
(def ^:private consumption-mp-id "571313113163368507")
(defn- utc-start-for-date
"Compute the UTC start of a Danish date (midnight DK -> UTC)."
[^LocalDate date]
(-> date
(.atStartOfDay dk-zone)
(.toInstant)
(Timestamp/from)))
(defn- save-time-series! [query-fn readings from]
(doseq [r readings]
(query-fn :insert-meter-reading! r))
(log/info "Saved" (count readings) "meter readings"))
(let [time-start (utc-start-for-date from)]
(doseq [r (filter #(= production-mp-id (:metering-point-id %)) readings)]
(let [hour (.getHour (.toLocalDateTime ^Timestamp (:time-dk r)))]
(query-fn :insert-production!
{:time-start time-start :hour hour :kwh (:quantity-kwh r)})))
(doseq [r (filter #(= consumption-mp-id (:metering-point-id %)) readings)]
(let [hour (.getHour (.toLocalDateTime ^Timestamp (:time-dk r)))]
(query-fn :insert-consumption!
{:time-start time-start :hour hour :kwh (:quantity-kwh r)}))))
(log/info "Saved" (count readings) "meter readings + production/consumption"))
;; --- Charges ---
@@ -223,9 +243,10 @@
;; --- Orchestrator ---
(defn fetch-and-save-all!
"Fetch all Eloverblik data and save to database."
[query-fn]
(log/info "Starting Eloverblik fetch")
"Fetch all Eloverblik data and save to database.
date is a LocalDate for which to fetch time series (one day)."
[query-fn ^LocalDate date]
(log/info "Starting Eloverblik fetch for" (.format date date-fmt))
(let [refresh-token (read-refresh-token)
access-token (get-access-token refresh-token)]
(if-not access-token
@@ -239,14 +260,14 @@
(:childMeteringPoints mp)))))
(distinct)
(vec))
from (LocalDate/of 2026 2 1)
to (LocalDate/of 2026 2 2)]
from date
to (.plusDays date 1)]
(log/info "Found" (count all-ids) "metering points:" all-ids)
(save-metering-points! query-fn mps)
;; Time series
(let [ts-resp (fetch-time-series access-token all-ids from to)
readings (parse-time-series ts-resp all-ids)]
(save-time-series! query-fn readings))
(save-time-series! query-fn readings from))
;; Charges
(let [ch-resp (fetch-charges access-token all-ids)]
(save-charges! query-fn ch-resp))
+5 -1
View File
@@ -176,7 +176,11 @@
(price-content :today (prices/get-today-prices query-fn) (has-tomorrow? query-fn))))
(defn sync-eloverblik [query-fn request]
(let [result (eloverblik/fetch-and-save-all! query-fn)]
(let [date-str (get-in request [:params :date])
date (if date-str
(java.time.LocalDate/parse date-str)
(java.time.LocalDate/now dk-zone))
result (eloverblik/fetch-and-save-all! query-fn date)]
(fragment
(if (:error result)
[:p {:class "text-red-600 font-medium"} (:error result)]