Elpriser.dk er en annonceside

Sådan tjener vi penge

Elpriser.dk er en sammenligningsside. Nogle af de elselskaber, vi viser, har en aftale med os, og klikker du på “Se prisen hos …” og tegner en aftale, får vi provision.

Provisionen påvirker ikke din pris. Du betaler det samme, uanset om du tilmelder dig gennem os eller direkte hos selskabet.

Rækkefølgen i sammenligningen følger prisen for hele regningen — ikke provisionen. Selskaber uden aftale med os står med på lige fod, blot uden knap, og selskaber med en anmærkning står sidst uanset pris. Læs mere om os.

elpriser.dk

Værktøj

Homey elpriser

Få elprisen for dit eget netområde ind i Homey — alt inkl. moms, kvarter for kvarter, med niveauet billig, middel eller dyr — og lad dine Flows starte opvaskemaskinen, varmepumpen eller opladningen, når strømmen er billig. Du skal bruge Athoms egen app HomeyScript og scriptene her på siden. Tallene er de samme som på forsiden og i appen, og de ligger frit som åbne data.

Mathias ClausenGrundlægger & Redaktør

Opdateret 23.10.2026

Det får du

Scriptene henter de åbne timepriser for dit postnummer og deler én kopi af dem på din Homey. Du sætter dem ind i HomeyScript og bruger dem fra dine Flows:

  • Hent elprisen sætter tags med prisen i det kvarter, der kører nu, niveauet, kvarterets plads i døgnet, om morgendagens priser er ude, og dagens billigste time med prisen i den. Tags kan stå i alle dine Flows, fx i en besked.
  • Billigste timer er en betingelse: Ja, når kvarteret, der kører nu, ligger i en af dagens billigste timer — hvor mange, skriver du selv på kortet.
  • Percentil næste døgn er en betingelse til varmepumpen: Ja, når kvarteret ligger i det interval, du skriver, blandt de kendte kvarterer fra nu og et døgn frem.
  • Køb nu eller vent er en betingelse til det, der skal være færdigt inden en frist: Ja i den billigste periode før fristen til opvaskemaskinen, eller i de billigste kvarterer før fristen til elbilen.

Hvorfor prisen for dit netområde, ikke spotprisen

Nord Pools spotpris for Vest- eller Østdanmark er en del af svaret, men kun en del: nettariffen, som dit netselskab tager for at bringe strømmen ud til dig, skifter trin hen over døgnet og er forskellig fra netselskab til netselskab; Energinets tariffer og elafgiften kommer oveni, og så momsen. Det kvarter, der er billigst på spotprisen, er ikke altid billigst, når tariffen regnes med — især ikke om vinteren, hvor tariffen er høj i spidsen om aftenen.

Scriptene bruger den fulde markedspris for dit netområde pr. kvarter: spotpris, nettarif, Energinets tariffer og elafgift, inkl. moms. Det er den pris, din elregning følger, hvis du har en variabel aftale — dit elselskabs eget tillæg og abonnement er ikke med, for de er ens hele døgnet og flytter ikke, hvornår strømmen er billig. Hvordan prisen regnes, står på metodesiden.

Filen, scriptene henter

Scriptene henter https://elpriser.dk/data/timepris.json?sted= efterfulgt af dit postnummer — de samme åbne timepriser, som guiden til Home Assistant bruger. Svaret har dagens timer og kvarterer og morgendagens, når de er udgivet. Hvert kvarter har sin start og slut i dansk tid, prisen i kroner pr. kWh, niveauet og pladsen i døgnet. Scriptene finder kvarteret, der kører nu, som det kvarter, hvis start og slut omslutter Homeys ur — de regner aldrig selv timer og minutter ud, så også nætterne, hvor uret stilles frem eller tilbage, går rigtigt. Alle felterne er beskrevet på siden med åbne data.

Sådan kommer du i gang

HomeyScript er Athoms egen app til små JavaScript-programmer på Homey. Den findes til Homey Pro, Homey Pro mini og Homey Self-Hosted Server — ikke til Homey Cloud — og kræver Homey-software 5.0.0 eller nyere.

  1. Installér HomeyScript fra Homey App Store på din Homey.
  2. Åbn HomeyScripts editor i Homeys webapp, my.homey.app, på en computer.
  3. Lav et nyt script, kald det Hent elprisen, og sæt koden herunder ind i stedet for det, der står.
  4. Skriv dit postnummer i stedet for 8000 i linjen const POSTNUMMER = '8000'; øverst. Brug det samme postnummer i alle scriptene.
  5. Gem scriptet, og kør det én gang fra editoren. Så opretter det sine tags, og loggen viser prisen for kvarteret, der kører nu.
  6. Lav et Flow, der kører scriptet hvert 15. minut: i Når-kolonnen et af Homeys indbyggede tidskort, der gentager Flowet med et fast interval, og i Så-kolonnen HomeyScripts kort Kør et script med Hent elprisen.
/*
 * Hent elprisen — HomeyScript til Elpriser.dk's åbne timepriser.
 * Vejledning: https://elpriser.dk/homey/
 *
 * Sætter tags med elprisen for dit postnummer i det kvarter, der kører nu — alt inkl. moms
 * (spotpris, nettarif, Energinets tariffer og elafgift), uden dit elselskabs tillæg og abonnement.
 * Lad et Flow køre scriptet hvert 15. minut.
 *
 * Data: https://elpriser.dk/data/timepris.json, åbne data under CC BY 4.0.
 * Viser du tallene for andre, så skriv: "Kilde: Elpriser.dk, https://elpriser.dk/data/#timepris"
 */

// Dit postnummer. Dækker det flere netområder, så skriv a og netområdets kode, fx 'a151'.
const POSTNUMMER = '8000';

const nu = Date.now();
const kopi = await hentPriser((f, gemt) => nu - gemt.hentet < 5 * 60 * 1000);
const fundet = findKvarter(kopi, nu);

if (!fundet) {
  // Ingen pris for kvarteret, der kører nu. Tallene bliver stående fra sidst, men tags siger,
  // at de ikke er aktuelle — og betingelseskortene svarer Nej, til der er priser igen.
  await tag('Elpris aktuel', false);
  await tag('Elpris niveau', 'ukendt');
  await tag('Elpris kvarter', 'ukendt');
  log('Ingen pris for kvarteret, der kører nu.');
  return false;
}

const k = fundet.kvarter;
await tag('Elpris nu', k.kr); // kr./kWh inkl. moms
await tag('Elpris niveau', k.niveau); // billig, middel eller dyr
await tag('Elpris percentil', k.percentil); // 0 (billigst) til 100 (dyrest) i døgnet
await tag('Elpris placering', k.placering); // 1 er døgnets billigste kvarter
await tag('Elpris kvarter', k.tekst); // fx 21:45–22:00
await tag('Elpris i morgen klar', fundet.senereDag);
if (fundet.dag.billigsteTime) {
  await tag('Elpris billigste time', fundet.dag.billigsteTime.time); // fx 4 for kl. 04–05
  await tag('Elpris billigste time pris', fundet.dag.billigsteTime.kr);
}
await tag('Elpris hentet', klokkeslaet(kopi)); // den sidste gode hentning, dansk tid
await tag('Elpris aktuel', true);
log(k.tekst + ': ' + k.kr + ' kr./kWh inkl. moms, ' + k.niveau);
return true;

// Klokkeslættet for den sidste gode hentning i dansk tid, regnet med offset fra filens eget kvarter.
function klokkeslaet(gemt) {
  const f = findKvarter(gemt, gemt.hentet);
  const offset = f ? f.kvarter.offset : gemt.dage[0].kvarterer[0].offset;
  const minutter = (offset.charAt(0) === '-' ? -1 : 1) * (Number(offset.slice(1, 3)) * 60 + Number(offset.slice(4, 6)));
  return new Date(gemt.hentet + minutter * 60 * 1000).toISOString().slice(11, 16);
}

// ── Fælles for scriptene til Elpriser.dk: ens i dem alle ──────────────────────

// Priserne for i dag og i morgen (når de er udgivet). Scriptene deler én kopi af filen på din
// Homey og henter kun en ny, når kopien ikke er god nok — og højst hvert femte minut.
async function hentPriser(godNok) {
  const navn = 'elpriser-' + POSTNUMMER;
  const nu = Date.now();
  let kopi = global.get(navn);
  if (!kopi || kopi.version !== 1) kopi = null;
  const fundet = findKvarter(kopi, nu);
  if (fundet && godNok(fundet, kopi)) return kopi;
  if (kopi && nu - kopi.hentet < 5 * 60 * 1000) return kopi;
  try {
    // timeout: giv op efter ti sekunder — HomeyScript stopper selv et script efter et halvt minut.
    const svar = await fetch('https://elpriser.dk/data/timepris.json?sted=' + encodeURIComponent(POSTNUMMER), {
      headers: { 'user-agent': 'elpriser-homeyscript/1' },
      timeout: 10000,
    });
    if (!svar.ok) throw new Error('filen svarede ' + svar.status);
    kopi = kompakt(await svar.json(), nu);
    global.set(navn, kopi);
  } catch (fejl) {
    log('Kunne ikke hente elpriserne: ' + fejl.message);
  }
  return kopi;
}

// Kvarteret, der kører på tidspunktet: det, hvis egen start og slut i filen omslutter det.
// Homeys ur regnes aldrig om til timer og minutter, så natten, hvor uret stilles, går også rigtigt.
function findKvarter(kopi, tid) {
  if (!kopi) return null;
  for (let d = 0; d < kopi.dage.length; d++) {
    const kvarterer = kopi.dage[d].kvarterer;
    for (let i = 0; i < kvarterer.length; i++) {
      if (kvarterer[i].fra <= tid && tid < kvarterer[i].til) {
        return { dag: kopi.dage[d], kvarter: kvarterer[i], senereDag: d < kopi.dage.length - 1 };
      }
    }
  }
  return null;
}

// Det, scriptene bruger af filen: dagene med deres timer og kvarterer.
function kompakt(fil, hentet) {
  if (!fil || !fil.today || !Array.isArray(fil.today.quarters)) throw new Error('filen havde en uventet form');
  const dage = [fil.today, fil.tomorrow].filter(Boolean).map((dag) => ({
    dag: dag.day,
    billigsteTime: dag.cheapestHour ? { time: dag.cheapestHour.hour, kr: dag.cheapestHour.krPerKwhInclVat } : null,
    timer: dag.hours.map((t) => ({ time: t.hour, placering: t.rank })),
    kvarterer: dag.quarters.map((q) => ({
      fra: Date.parse(q.start),
      til: Date.parse(q.end),
      time: q.hour,
      kr: q.krPerKwhInclVat,
      oere: q.oreInclVat,
      niveau: q.levelWord,
      percentil: q.percentile,
      placering: q.rank,
      tekst: q.start.slice(11, 16) + '–' + q.end.slice(11, 16),
      offset: q.start.slice(-6),
    })),
  }));
  return { version: 1, hentet: hentet, dage: dage };
}

// ── Slut på det fælles ─────────────────────────────────────────────────────────

Tags, scriptet sætter

  • Elpris nu: prisen i det kvarter, der kører, i kr./kWh inkl. moms.
  • Elpris niveau: billig, middel eller dyr efter døgnets egne tredjedele.
  • Elpris percentil: kvarterets plads blandt døgnets kvarterer fra 0 (det billigste) til 100 (det dyreste); lige priser får samme tal.
  • Elpris placering: 1 er døgnets billigste kvarter.
  • Elpris kvarter: det kvarter, tallene hører til, fx 21:45–22:00.
  • Elpris i morgen klar: Ja, når morgendagens priser er ude.
  • Elpris billigste time og Elpris billigste time pris: dagens billigste time som timetal — 4 betyder kl. 04–05 — og prisen i den.
  • Elpris hentet: klokkeslættet for den sidste gode hentning.
  • Elpris aktuel: Ja, når scriptet havde en pris for kvarteret, da det sidst kørte.

Tags bruges som Homeys andre tags: sæt dem ind i et kort, fx en besked med dagens billigste time og prisen i den. De skifter, når Flowet kører. Falder kørslerne ikke på kvarterets start, står det forrige kvarters tal lidt ind i det næste — Elpris kvarter viser, hvilket kvarter tallene hører til. Betingelseskortene nedenfor regner selv med det kvarter, der kører, når de spørges.

Når der ingen pris er

Kan scriptet ikke hente filen, bruger det kopien fra sidste gang, så længe den har en pris for kvarteret, der kører — dagens priser ligger fast, når de er udgivet. Har kopien ingen pris for kvarteret, sætter scriptet Elpris aktuel til Nej og Elpris niveau og Elpris kvarter til »ukendt«, og betingelseskortene svarer Nej, til der er priser igen. Tallene bliver stående fra sidst, så dine Flows bliver ved med at kende tags — bruger et Flow tallene i en betingelse, så lad det også se på Elpris aktuel.

Et Flow: tænd, når strømmen er billig

Det klassiske eksempel: varmtvandsbeholderen skal varme i dagens billigste timer. Lav et script mere, Billigste timer, med koden herunder og dit postnummer øverst. Det er en betingelse, der svarer Ja, når kvarteret, der kører nu, ligger i en af dagens N billigste timer, og Nej ellers — også når der ingen priser er. N er argumentet, du skriver på kortet. Betingelsesscriptene køres fra kortet med deres argument; i editoren, uden argument, svarer de med en fejl, der siger, hvad der skal stå.

/*
 * Billigste timer — betingelse til HomeyScript med Elpriser.dk's åbne timepriser.
 * Vejledning: https://elpriser.dk/homey/
 *
 * Til kortet »Kør et script med et argument« i Og-kolonnen. Argumentet er et antal timer, fx 4:
 * kortet svarer Ja, når kvarteret, der kører nu, ligger i en af dagens 4 billigste timer for dit
 * postnummer (alt inkl. moms), og Nej ellers — også når der ingen priser er.
 *
 * Data: https://elpriser.dk/data/timepris.json, åbne data under CC BY 4.0.
 * Viser du tallene for andre, så skriv: "Kilde: Elpriser.dk, https://elpriser.dk/data/#timepris"
 */

// Dit postnummer. Dækker det flere netområder, så skriv a og netområdets kode, fx 'a151'.
const POSTNUMMER = '8000';

const antal = Number(String(args[0] || '').trim());
if (!Number.isInteger(antal) || antal < 1 || antal > 24) {
  throw new Error('Skriv et antal timer fra 1 til 24 som argument, fx 4.');
}

const nu = Date.now();
const fundet = findKvarter(await hentPriser(() => true), nu);
if (!fundet) {
  log('Ingen pris for kvarteret, der kører nu — svarer Nej.');
  return false;
}

// Timen, kvarteret hører til, og dens plads blandt dagens timer: 1 er den billigste, og lige
// priser deler pladsen. Natten, hvor uret stilles tilbage, er den dobbelte time 02 én time i filen.
const time = fundet.dag.timer.find((t) => t.time === fundet.kvarter.time);
const ja = !!time && time.placering <= antal;
log(fundet.kvarter.tekst + ': timen har plads ' + (time ? time.placering : '–') + ' blandt dagens timer — ' + (ja ? 'Ja' : 'Nej'));
return ja;

// ── Fælles for scriptene til Elpriser.dk: ens i dem alle ──────────────────────

// Priserne for i dag og i morgen (når de er udgivet). Scriptene deler én kopi af filen på din
// Homey og henter kun en ny, når kopien ikke er god nok — og højst hvert femte minut.
async function hentPriser(godNok) {
  const navn = 'elpriser-' + POSTNUMMER;
  const nu = Date.now();
  let kopi = global.get(navn);
  if (!kopi || kopi.version !== 1) kopi = null;
  const fundet = findKvarter(kopi, nu);
  if (fundet && godNok(fundet, kopi)) return kopi;
  if (kopi && nu - kopi.hentet < 5 * 60 * 1000) return kopi;
  try {
    // timeout: giv op efter ti sekunder — HomeyScript stopper selv et script efter et halvt minut.
    const svar = await fetch('https://elpriser.dk/data/timepris.json?sted=' + encodeURIComponent(POSTNUMMER), {
      headers: { 'user-agent': 'elpriser-homeyscript/1' },
      timeout: 10000,
    });
    if (!svar.ok) throw new Error('filen svarede ' + svar.status);
    kopi = kompakt(await svar.json(), nu);
    global.set(navn, kopi);
  } catch (fejl) {
    log('Kunne ikke hente elpriserne: ' + fejl.message);
  }
  return kopi;
}

// Kvarteret, der kører på tidspunktet: det, hvis egen start og slut i filen omslutter det.
// Homeys ur regnes aldrig om til timer og minutter, så natten, hvor uret stilles, går også rigtigt.
function findKvarter(kopi, tid) {
  if (!kopi) return null;
  for (let d = 0; d < kopi.dage.length; d++) {
    const kvarterer = kopi.dage[d].kvarterer;
    for (let i = 0; i < kvarterer.length; i++) {
      if (kvarterer[i].fra <= tid && tid < kvarterer[i].til) {
        return { dag: kopi.dage[d], kvarter: kvarterer[i], senereDag: d < kopi.dage.length - 1 };
      }
    }
  }
  return null;
}

// Det, scriptene bruger af filen: dagene med deres timer og kvarterer.
function kompakt(fil, hentet) {
  if (!fil || !fil.today || !Array.isArray(fil.today.quarters)) throw new Error('filen havde en uventet form');
  const dage = [fil.today, fil.tomorrow].filter(Boolean).map((dag) => ({
    dag: dag.day,
    billigsteTime: dag.cheapestHour ? { time: dag.cheapestHour.hour, kr: dag.cheapestHour.krPerKwhInclVat } : null,
    timer: dag.hours.map((t) => ({ time: t.hour, placering: t.rank })),
    kvarterer: dag.quarters.map((q) => ({
      fra: Date.parse(q.start),
      til: Date.parse(q.end),
      time: q.hour,
      kr: q.krPerKwhInclVat,
      oere: q.oreInclVat,
      niveau: q.levelWord,
      percentil: q.percentile,
      placering: q.rank,
      tekst: q.start.slice(11, 16) + '–' + q.end.slice(11, 16),
      offset: q.start.slice(-6),
    })),
  }));
  return { version: 1, hentet: hentet, dage: dage };
}

// ── Slut på det fælles ─────────────────────────────────────────────────────────

Flowet i eksemplet:

  • Når: tidskortet, hvert 15. minut.
  • Og: HomeyScripts kort Kør et script med et argument med Billigste timer og argumentet 4.
  • Så: tænd varmtvandsbeholderens stik.
  • Når betingelsen ikke er opfyldt: sluk stikket — i gruppen under Så-kolonnen, som Athom kalder Else.

Dagens timer har hver sin plads, hvor 1 er den billigste, og lige priser deler pladsen. Natten, hvor uret stilles tilbage, er den dobbelte time 02 én time i filen, så kortet svarer det samme i begge.

Varmepumpen: flere trin med percentilen

En varmepumpe skal ikke tænde og slukke; den skal flytte varmen lidt hen over døgnet. Huset er et lager: et par grader ekstra i de billige kvarterer holder i timevis, og en grad mindre i de dyre mærkes knap. Til det er tre niveauer grove, og derfor står percentilen i filen — kvarterets plads fra 0 (det billigste) til 100 (det dyreste), så et Flow kan have de trin, du vil.

Tagget Elpris percentil starter forfra ved midnat, så et kvarter kl. 23.45 kan hedde billigt, selv om nattens priser er endnu lavere. Scriptet Percentil næste døgn placerer i stedet kvarteret blandt de kendte kvarterer fra nu og et døgn frem, med morgendagen, når den er udgivet (typisk mellem kl. 13 og 15 — tallet kan flytte sig dér). Det er en betingelse med et interval som argument, fx 0-20, og svarer Ja, når kvarterets plads ligger i intervallet; grænserne er med. Kender filen færre end fire timer frem, svarer det Nej.

/*
 * Percentil næste døgn — betingelse til HomeyScript med Elpriser.dk's åbne timepriser.
 * Vejledning: https://elpriser.dk/homey/
 *
 * Til kortet »Kør et script med et argument« i Og-kolonnen. Argumentet er et interval, fx 0-20:
 * kortet svarer Ja, når kvarteret, der kører nu, ligger i det interval blandt de kendte kvarterer
 * fra nu og et døgn frem — 0 er det billigste, 100 det dyreste. Til varmepumpen. Nej, når færre
 * end fire timer frem er kendt, eller der ingen priser er.
 *
 * Data: https://elpriser.dk/data/timepris.json, åbne data under CC BY 4.0.
 * Viser du tallene for andre, så skriv: "Kilde: Elpriser.dk, https://elpriser.dk/data/#timepris"
 */

// Dit postnummer. Dækker det flere netområder, så skriv a og netområdets kode, fx 'a151'.
const POSTNUMMER = '8000';

const interval = /^\s*(\d{1,3})\s*[-–]\s*(\d{1,3})\s*$/.exec(String(args[0] || ''));
const fra = interval ? Number(interval[1]) : -1;
const til = interval ? Number(interval[2]) : -1;
if (!interval || fra > til || til > 100) {
  throw new Error('Skriv et interval fra 0 til 100 som argument, fx 0-20.');
}

const nu = Date.now();
// Morgendagens priser skal med, så snart de er ude: mangler de, hentes filen igen (højst hvert femte minut).
const p = percentilNaesteDoegn(await hentPriser((f) => f.senereDag), nu);
if (p === null) {
  log('Percentilen kendes ikke lige nu — svarer Nej.');
  return false;
}
const ja = fra <= p && p <= til;
log('Percentil næste døgn: ' + p + ' — ' + (ja ? 'Ja' : 'Nej') + ' for ' + fra + '-' + til);
return ja;

// Kvarterets plads blandt de kendte kvarterer fra nu og et døgn frem, som filens now.ahead:
// 100 · (antal lavere + (antal lige - 1) / 2) / (antal kvarterer - 1). Null under fire timer.
function percentilNaesteDoegn(kopi, tid) {
  if (!kopi) return null;
  const alle = kopi.dage.reduce((liste, dag) => liste.concat(dag.kvarterer), []);
  const i = alle.findIndex((k) => k.fra <= tid && tid < k.til);
  if (i < 0) return null;
  const vindue = alle.slice(i).filter((k) => k.fra < alle[i].fra + 24 * 60 * 60 * 1000);
  if (vindue.length < 16) return null;
  const pris = alle[i].oere;
  const lavere = vindue.filter((k) => k.oere < pris).length;
  const lige = vindue.filter((k) => k.oere === pris).length;
  return Math.round((100 * (lavere + (lige - 1) / 2)) / (vindue.length - 1));
}

// ── Fælles for scriptene til Elpriser.dk: ens i dem alle ──────────────────────

// Priserne for i dag og i morgen (når de er udgivet). Scriptene deler én kopi af filen på din
// Homey og henter kun en ny, når kopien ikke er god nok — og højst hvert femte minut.
async function hentPriser(godNok) {
  const navn = 'elpriser-' + POSTNUMMER;
  const nu = Date.now();
  let kopi = global.get(navn);
  if (!kopi || kopi.version !== 1) kopi = null;
  const fundet = findKvarter(kopi, nu);
  if (fundet && godNok(fundet, kopi)) return kopi;
  if (kopi && nu - kopi.hentet < 5 * 60 * 1000) return kopi;
  try {
    // timeout: giv op efter ti sekunder — HomeyScript stopper selv et script efter et halvt minut.
    const svar = await fetch('https://elpriser.dk/data/timepris.json?sted=' + encodeURIComponent(POSTNUMMER), {
      headers: { 'user-agent': 'elpriser-homeyscript/1' },
      timeout: 10000,
    });
    if (!svar.ok) throw new Error('filen svarede ' + svar.status);
    kopi = kompakt(await svar.json(), nu);
    global.set(navn, kopi);
  } catch (fejl) {
    log('Kunne ikke hente elpriserne: ' + fejl.message);
  }
  return kopi;
}

// Kvarteret, der kører på tidspunktet: det, hvis egen start og slut i filen omslutter det.
// Homeys ur regnes aldrig om til timer og minutter, så natten, hvor uret stilles, går også rigtigt.
function findKvarter(kopi, tid) {
  if (!kopi) return null;
  for (let d = 0; d < kopi.dage.length; d++) {
    const kvarterer = kopi.dage[d].kvarterer;
    for (let i = 0; i < kvarterer.length; i++) {
      if (kvarterer[i].fra <= tid && tid < kvarterer[i].til) {
        return { dag: kopi.dage[d], kvarter: kvarterer[i], senereDag: d < kopi.dage.length - 1 };
      }
    }
  }
  return null;
}

// Det, scriptene bruger af filen: dagene med deres timer og kvarterer.
function kompakt(fil, hentet) {
  if (!fil || !fil.today || !Array.isArray(fil.today.quarters)) throw new Error('filen havde en uventet form');
  const dage = [fil.today, fil.tomorrow].filter(Boolean).map((dag) => ({
    dag: dag.day,
    billigsteTime: dag.cheapestHour ? { time: dag.cheapestHour.hour, kr: dag.cheapestHour.krPerKwhInclVat } : null,
    timer: dag.hours.map((t) => ({ time: t.hour, placering: t.rank })),
    kvarterer: dag.quarters.map((q) => ({
      fra: Date.parse(q.start),
      til: Date.parse(q.end),
      time: q.hour,
      kr: q.krPerKwhInclVat,
      oere: q.oreInclVat,
      niveau: q.levelWord,
      percentil: q.percentile,
      placering: q.rank,
      tekst: q.start.slice(11, 16) + '–' + q.end.slice(11, 16),
      offset: q.start.slice(-6),
    })),
  }));
  return { version: 1, hentet: hentet, dage: dage };
}

// ── Slut på det fælles ─────────────────────────────────────────────────────────

Eksemplet er tre Flows, der alle kører hvert 15. minut og har HomeyScripts kort Kør et script med et argument med Percentil næste døgn i Og-kolonnen:

  • Med argumentet 0-20: sæt varmepumpen til 22,5 grader — lidt varmere i den billigste femtedel.
  • Med argumentet 21-79: sæt den til 21 grader — normalen i midten.
  • Med argumentet 80-100: sæt den til 20 grader — lidt køligere i den dyreste femtedel.

Graderne er et eksempel; brug din varmepumpes egne kort og dine egne temperaturer.

Køb nu eller vent: en frist og et antal timer

For opvaskemaskinen og elbilen er spørgsmålet det samme: de skal bruge strøm i et antal timer, og det skal være færdigt inden et bestemt tidspunkt — skal de starte nu eller vente? Scriptet Køb nu eller vent spørger filen om planen (timer og inden på adressen) og svarer Ja eller Nej. Argumentet er et antal timer og en frist, fx 3 07:00: Ja, når kvarteret, der kører nu, ligger i den billigste periode på tre timer i træk, der kan nå at blive færdig inden kl. 7. Skriv fleksibel bagefter, fx 4 07:00 fleksibel, til forbrug, der kan afbrydes: så svarer kortet Ja i de billigste kvarterer før fristen, også når de ikke ligger i træk.

Kan forbruget ikke nå at blive færdigt før fristen, hvis det venter, svarer kortet Ja — så er svaret at starte nu. Ligger fristen efter de kendte priser, svarer det Nej, til de næste priser er ude; morgendagens kommer typisk mellem kl. 13 og 15. Fristen er næste gang, uret viser klokkeslættet, så den ligger fast.

/*
 * Køb nu eller vent — betingelse til HomeyScript med Elpriser.dk's åbne timepriser.
 * Vejledning: https://elpriser.dk/homey/
 *
 * Til kortet »Kør et script med et argument« i Og-kolonnen. Argumentet er et antal timer og en
 * frist, fx 3 07:00: kortet svarer Ja, når kvarteret, der kører nu, ligger i den billigste periode
 * på 3 timer i træk, der kan nå at blive færdig inden kl. 7 — til opvaskemaskinen. Skriv fleksibel
 * bagefter, fx 4 07:00 fleksibel, til forbrug, der kan afbrydes, som elbilen: så svarer kortet Ja
 * i de billigste kvarterer før fristen, også når de ikke ligger i træk.
 *
 * Data: https://elpriser.dk/data/timepris.json, åbne data under CC BY 4.0.
 * Viser du tallene for andre, så skriv: "Kilde: Elpriser.dk, https://elpriser.dk/data/#timepris"
 */

// Dit postnummer. Dækker det flere netområder, så skriv a og netområdets kode, fx 'a151'.
const POSTNUMMER = '8000';

const dele = String(args[0] || '').trim().split(/\s+/);
const fleksibel = dele.length === 3 && dele[2].toLowerCase() === 'fleksibel';
if (dele.length !== 2 && !fleksibel) {
  throw new Error('Skriv timer og frist som argument, fx 3 07:00 eller 4 07:00 fleksibel.');
}

const nu = Date.now();
const plan = await hentPlan(dele[0], dele[1]);
if (!plan) {
  log('Ingen plan lige nu — svarer Nej.');
  return false;
}
if (!plan.fits) {
  // Der er ikke tid til at vente: filens svar er at starte nu.
  log('For lidt tid til at vente før fristen — svarer Ja.');
  return true;
}
if (!plan.complete) {
  // Fristen ligger efter de kendte priser: vent på de næste (morgendagens kommer typisk mellem kl. 13 og 15).
  log('Fristen ligger efter de kendte priser — svarer Nej, til de næste er ude.');
  return false;
}
const iKvarteret = (start) => Date.parse(start) <= nu && nu < Date.parse(start) + 15 * 60 * 1000;
const ja = fleksibel
  ? !!plan.flexible && plan.flexible.starts.some(iKvarteret)
  : !!plan.block && Date.parse(plan.block.start) <= nu && nu < Date.parse(plan.block.end);
log((fleksibel ? 'De billigste kvarterer' : 'Den billigste periode') + ' før fristen — ' + (ja ? 'Ja' : 'Nej'));
return ja;

// Planen fra filen (?timer=&inden=). Svaret gemmes i fem minutter, så kortet højst spørger hvert femte minut.
async function hentPlan(timer, inden) {
  const navn = 'elpriser-plan-' + POSTNUMMER + '-' + timer + '-' + inden;
  const gemt = global.get(navn);
  if (gemt && Date.now() - gemt.hentet < 5 * 60 * 1000) return gemt.plan;
  let svar;
  try {
    // timeout: giv op efter ti sekunder — HomeyScript stopper selv et script efter et halvt minut.
    svar = await fetch(
      'https://elpriser.dk/data/timepris.json?sted=' + encodeURIComponent(POSTNUMMER) +
        '&timer=' + encodeURIComponent(timer) + '&inden=' + encodeURIComponent(inden),
      { headers: { 'user-agent': 'elpriser-homeyscript/1' }, timeout: 10000 },
    );
  } catch (fejl) {
    log('Kunne ikke hente planen: ' + fejl.message);
    return null;
  }
  if (svar.status === 400) {
    // Et argument, filen ikke kan bruge: kortet fejler med filens egen forklaring.
    const fejl = await svar.json().catch(() => ({}));
    throw new Error(fejl.error || 'Argumentet kunne ikke bruges.');
  }
  if (!svar.ok) {
    log('Kunne ikke hente planen: filen svarede ' + svar.status);
    return null;
  }
  try {
    const plan = (await svar.json()).plan || null;
    global.set(navn, { hentet: Date.now(), plan: plan });
    return plan;
  } catch (fejl) {
    log('Kunne ikke læse planen: ' + fejl.message);
    return null;
  }
}

Opvaskemaskinen

Opvaskemaskinen skal starte én gang, når den er fyldt. Lav en Ja/Nej-variabel, Opvask klar, under Logik, og sæt den til Ja, når maskinen er fyldt, fx fra en knap eller et andet Flow. Flowet:

  • Når: tidskortet, hvert 15. minut.
  • Og: et kort fra Logik, der tjekker, at Opvask klar er Ja, og HomeyScripts kort Kør et script med et argument med Køb nu eller vent og argumentet 3 07:00.
  • Så: start opvaskemaskinen, og Indstil Opvask klar til Nej under Logik.

Planen regnes forfra, hver gang kortet spørger, så det er variablen, der sørger for, at maskinen kun starter én gang.

Elbilen

Elbilen kan lade i stykker og bruger derfor fleksibel. Flowet:

  • Når: tidskortet, hvert 15. minut.
  • Og: Køb nu eller vent med argumentet 4 07:00 fleksibel.
  • Så: start opladningen. Når betingelsen ikke er opfyldt (Else): stop den.

Kortet ved ikke, hvor meget bilen allerede har ladet. Det regner hver gang med de timer, du skrev, fra nu til fristen, og når der kun er de timer tilbage, svarer det Ja hele vejen, så bilen når at lade inden fristen. Bilen stopper selv, når den er fuld. Brug din ladeboks' eller bilens egne kort til at starte og stoppe.

Regler for brug

  • Filen er åbne data under Creative Commons BY 4.0: fri brug, også kommercielt, mod kildeangivelsen »Kilde: Elpriser.dk«. Den står også øverst i scriptene.
  • Hent hver adresse højst hvert femte minut pr. installation — scriptene gør det af sig selv. Dagens priser ligger fast; morgendagens kommer typisk mellem kl. 13 og 15.
  • Prisen er markedets pris alt inkl. moms uden dit elselskabs tillæg og abonnement. Vil du have dem med, så læg dem til i dit Flow.
  • Vi kan ændre filens form med varsel på siden med åbne data; felter fjernes ikke uden varsel.

På vej: en Homey-app

Scriptene virker i dag og bliver ved med det. Næste skridt er en app til Homey fra Elpriser.dk med de samme tal, uden scripts. Apps til Homey gennemgås af Athom, før de kan installeres fra Homey App Store, så vi sætter ingen dato på. Når appen kan installeres, står det her på siden.

Elpriser.dk-appen

De billigste timer – uden at kigge efter dem

Appen finder døgnets billigste timer for dit postnummer og minder dig om dem, før de begynder.

Med appen kan du

  • se døgnets billigste og dyreste timer for dit eget netområde
  • få en påmindelse, før de billigste timer begynder
  • sætte en prisalarm ved den grænse, du selv vælger
Hent appenOm appen

Gratis, uden reklamer og uden konto. Android-udgaven er på vej.

Ofte stillede spørgsmål

Virker det på Homey Cloud?

Nej. HomeyScript findes kun til de Homeys, der kører apps lokalt: Homey Pro, Homey Pro mini og Homey Self-Hosted Server, og den kræver Homey-software 5.0.0 eller nyere. Har du Homey Cloud, kan du stadig se tallene på forsiden og i appen.

Hvorfor ikke bare bruge spotprisen?

Fordi spotprisen kun er en del af det, du betaler. Nettariffen skifter trin hen over døgnet og er forskellig fra netselskab til netselskab, og elafgift og Energinets tariffer kommer oveni. Et Flow på spotprisen alene kan ramme et dyrt kvarter, fordi tariffen netop gik op. Scriptene bruger prisen alt inkl. moms for dit netområde pr. kvarter, så dine Flows følger det, elregningen følger.

Hvor tit henter scriptene filen?

Højst hvert femte minut for timepriserne og for hver plan. Scriptene deler én kopi af filen på din Homey: »Hent elprisen« henter en ny, når kopien er mindst fem minutter gammel, »Billigste timer« henter kun selv, når kopien ikke har en pris for kvarteret, der kører, og »Percentil næste døgn« også, mens morgendagens priser mangler. »Køb nu eller vent« spørger filen om planen og bruger svaret i fem minutter. Filen caches i fem minutter hos os, så oftere giver ingen nye tal.

Hvad sker der, hvis filen ikke kan hentes?

Så bruger scriptene kopien fra sidste gang, så længe den har en pris for kvarteret, der kører — dagens priser ligger fast, når de er udgivet. Har kopien ingen pris for kvarteret, sætter »Hent elprisen« tagget »Elpris aktuel« til Nej og niveauet og kvarteret til ukendt, og betingelseskortene svarer Nej, til der er priser igen. Tallene bliver stående fra sidst, så dine Flows bliver ved med at kende tags.

Hvorfor er »Elpris i morgen klar« Nej?

Fordi morgendagens priser ikke er udgivet endnu. Nord Pool offentliggør det kommende døgns priser efter den daglige auktion — typisk mellem kl. 13 og 15 — og indtil da har filen kun dagens priser. »Hent elprisen« henter igen, når Flowet kører, og tagget bliver Ja, når priserne er ude.

Mit postnummer dækker to netområder — hvad så?

Så svarer filen for det første af dem. Find dit netselskab på elregningen, slå dets kode op på vores forside ved at skrive postnummeret, og skriv a efterfulgt af koden i stedet for postnummeret øverst i hvert script, fx 'a151'.

Hvilken pris står der i tags — og hvad mangler?

Markedets pris alt inkl. moms for netområdet: spotpris, nettarif, Energinets tariffer og elafgift pr. kvarter. Dit elselskabs tillæg og abonnement er ikke med, for de afhænger af din aftale og er ens hele døgnet. Vil du have prisen med tillæg, så læg dit elselskabs tillæg pr. kWh til i dit Flow — tillægget står på din aftale og på vores sammenligning.

Kommer der en Homey-app?

Ja, vi bygger en app til Homey fra Elpriser.dk med de samme tal, uden scripts. Den skal gennemgås af Athom, før den kan installeres fra Homey App Store, og indtil da er scriptene her vejen. Scriptene bliver ved med at virke, også når appen er der.

Hvem står bag, hvordan er siden lavet, og hvorfor findes den?

Hvem
Skrevet og gennemgået af Mathias Clausen, grundlægger & redaktør. Udgivet 23. oktober 2026; teksten er sidst gennemgået 23. oktober 2026.
Hvordan
Priser, rangeringer og tabeller beregnes automatisk fra vores markedsfeed: elpris.dk (Forsyningstilsynet), Energi Data Service (spotpris og nettariffer) og Trustpilot. 85 af de 182 aftaler i denne beregning er bekræftet mod selskabets egen side inden for 14 dage; tallene er fra 23. oktober 2026. Teksten er skrevet af redaktøren; AI-værktøjer bruges til udkast og kontrol, aldrig til tal. Læs beregningsmetoden.
Hvorfor
Elpriser.dk lever af provision fra de 10 selskaber, vi samarbejder med. Provisionen ændrer ikke rækkefølgen, som følger prisen, og et selskab med anmærkning i vores register mister link, badge og kort. Fejl eller indsigelse: mail@elpriser.dk.
Kilder (11)

Alle tal på siden er hentet af vores eget feed fra de her kilder og regnet ved visningen. Energi Data Services data er udgivet under CC BY 4.0 — kilde: Energinet (www.energidataservice.dk).

Reglerne bag tallene står på metodesiden, de samme tal kan hentes som åbne data, og anmærkninger om selskaber står med kilde i registret.

Mathias Clausen · Grundlægger & Redaktør

Dansk iværksætter, der har fulgt elmarkedet siden energikrisen og bygget Elpriser.dk's prisværktøjer. Skriver teksten; tallene beregnes automatisk af feedet.

Alle artiklermail@elpriser.dkLinkedIn

Skift til en billigere elaftale i dag

Altid Energi er den billigste af de 10 partnere uden anmærkning ved 4.000 kWh i N1 A/S — 651 kr./md. i gennemsnit, 7.816 kr. om året. Skiftet er gratis, og det nye selskab ordner opsigelsen for dig.