# En måneds måleraflæsninger på 180 millisekunder

Har udviklet en pipeline i Python / SQL / Bash + Jq, der aggregerer elforbrug pr. time og behandler datasæt for 30 dage fra heterogene JSONL‑kilder på 180 ms.

2025

**Situation.** Virksomheden behandler store mængder heterogene eldata fra flere datakilder, som hver har sin egen rapporteringsfrekvens — fra timeintervaller til intervaller på 15 minutter og i nogle tilfælde uregelmæssige tidsstempler. Den variation gør det svært at skabe et sammenhængende og sammenligneligt datasæt. For at understøtte præcise energianalyser skal dataene normaliseres til ensartede forbrugsværdier pr. time, aggregeret pr. zone.

**Opgave.** Målet var at tage rå hændelsesdata fra et historisk datasæt (i JSONL‑format) og omdanne dem til elforbrugstal afstemt til hele timer, struktureret som én række pr. time og pr. zone. Konkret gik opgaven ud på at:

- afstemme tidsstemplede data til faste timeintervaller,
- aggregere den samlede elproduktion i hvert interval ved at summere værdierne for produktionsmikset,
- indregne den grænseoverskridende udveksling ved at lægge import til og trække eksport fra,
- skrive de endelige værdier ud i et struktureret, skalerbart format, der egner sig til videre analyse.
- Løsningen skulle desuden være effektiv nok til at skalere til store tidsvinduer (30+ dage) og til flere lande/zoner.

**Handling.** Opgaven blev grebet an med tre forskellige varianter af løsningen, implementeret i henholdsvis Python, JQ (til JSON‑behandling på kommandolinjen) og SQL og hver optimeret til sin egen sammenhæng:

Python blev valgt for sin fleksibilitet, den lette databehandling og evnen til at håndtere transformationer i hukommelsen effektivt. Med rene Python‑funktioner blev der bygget en pipeline, som:
- parsede JSONL‑filerne til strukturerede dataframes
- samplede tidsseriedataene om til timeintervaller
- aggregerede produktionen og beregnede nettoelforbruget (produktion + import − eksport)
- eksporterede resultaterne som CSV eller indlæste dem i en let SQLite‑database, så de kunne efterses.

JQ blev brugt til en hurtig løsning med minimale afhængigheder til kommandolinjemiljøer, bygget som en kæde af JQ‑filtre.

I PostgreSQL blev JSONL‑dataene importeret, normaliserede tabeller oprettet og en række SQL‑forespørgsler skrevet.

For at vurdere ydeevnen blev hver løsning benchmarket med historiske datasæt på både 1 dag og 30 dage.

**Resultat.** Python‑implementeringen viste sig at være den hurtigste og mest skalerbare løsning og klarede:

- 1 dags data på blot 34 ms
- 30 dages datasæt på 180 ms

Det bekræftede, at den egnede sig til længere tidsrum med svartider under et sekund. Den gav også klar kode, der var nem at vedligeholde og let kunne udvides til behandling af flere zoner eller integreres i en ETL‑pipeline.

Samlet set viste tilgangen med flere værktøjer fleksibilitet i valget af værktøjer, stærk ydeevneoptimering og robust håndtering af udfordringerne med tidsafstemning og aggregering i rigtige pipelines for eldata.

---

- Rolle: Platform- og dataingeniør
- Kategorier: [Databaser](https://engineer.company/da/categories/databases/), [PostgreSQL](https://engineer.company/da/categories/postgresql/), [SQL](https://engineer.company/da/categories/sql/), [Data engineering](https://engineer.company/da/categories/data-engineering/), [Datapipelines (ETL/ELT)](https://engineer.company/da/categories/data-pipelines/), [Dataanalyse](https://engineer.company/da/categories/data-analytics/), [Automatisering & CI/CD](https://engineer.company/da/categories/automation/), [Optimering af ydeevne](https://engineer.company/da/categories/performance/), [Python](https://engineer.company/da/categories/python/)
- Ydelser: [Databaseoptimering](https://engineer.company/da/services/database-performance/), [Udvikling af datapipelines (ETL/ELT)](https://engineer.company/da/services/data-pipeline-development/), [Dataanalyse & BI‑dashboards](https://engineer.company/da/services/data-analytics-bi/)

<https://engineer.company/da/portfolio/a-month-of-meter-readings-in-180-milliseconds/>
