1
Elpriser - ApexCharts
Kasper edited this page 2026-08-21 16:15:54 +02:00

Elpriser - ApexCharts

Dette dashboard-card viser elprisen time for time for de næste 48 timer.

Priserne vises med dynamiske farver baseret på gennemsnitsprisen:

Prisniveau Grænse Farve
Billig < 80 % af gennemsnittet 🟢 Grøn
Normal 80-120 % af gennemsnittet 🟡 Gul
Dyr 120-150 % af gennemsnittet 🟠 Orange
Meget dyr ≥ 150 % af gennemsnittet 🔴 Rød

Derudover vises en blå linje med elprisen ekskl. afgifter.


Krav

Følgende skal være installeret i Home Assistant:

  • Home Assistant
  • HACS
  • Energi Data Service
  • ApexCharts Card

1. Installer Energi Data Service

Via HACS

Energi Data Service er en Home Assistant-integration, som henter elpriser fra Energi Data Service API'et.

Åbn:

Home Assistant → HACS → Integrations

Søg efter:

Energi Data Service

Vælg:

Energi Data Service
MTrab

Tryk:

Download

Genstart derefter Home Assistant.


Tilføj integrationen

Efter genstart:

Settings → Devices & services → Add Integration

Søg efter:

Energi Data Service

Vælg integrationen.

Grundopsætning

Vælg de relevante indstillinger for installationen.

For Danmark skal der blandt andet vælges korrekt prisområde.

Typisk:

DK1

eller

DK2

afhængigt af installationens placering.

Priser inkl. moms

Hvis priserne ønskes vist inkl. moms, skal:

Show prices in VAT

aktiveres.

Dette er vigtigt, da ApexCharts-card'et bruger den pris, som Energi Data Service-integrationen leverer.


2. Sensorer

Card'et bruger følgende sensorer:

sensor.energi_data_service
sensor.elpriser_excl_afgift

Den primære sensor er:

sensor.energi_data_service

Denne sensor indeholder blandt andet:

today_mean
raw_today
raw_tomorrow
tomorrow_valid

Card'et bruger disse attributter til at generere grafen.


3. Installer ApexCharts Card

Card'et kræver:

custom:apexcharts-card

Den anbefalede måde at installere custom cards på er via HACS.

Åbn:

HACS → Frontend

Søg efter:

ApexCharts Card

Installer:

ApexCharts Card

Genindlæs Home Assistant efter installationen.


4. Tilføj Card'et

Åbn det dashboard, hvor Card'et skal placeres.

Vælg:

Edit Dashboard → Add Card → Manual

Indsæt følgende YAML:

type: grid
columns: 1
square: false
cards:
  - type: grid
    columns: 1
    square: false
    cards:
      - type: custom:apexcharts-card
        apex_config:
          chart:
            height: 350
        header:
          title: Elpriser pr. time (dynamiske farver)
          show: true
          show_states: false
        graph_span: 48h
        now:
          show: true
          label: Nu
        span:
          start: day
        all_series_config:
          unit: ' kr.'
        yaxis:
          - min: 0
            apex_config:
              tickAmount: 6
        series:
          - entity: sensor.energi_data_service
            name: Billig
            type: column
            color: '#4CAF50'
            show:
              legend_value: false
            data_generator: >
              let data = [];

              const avg = entity.attributes.today_mean;

              const greenLimit = avg * 0.8;

              let prices = entity.attributes.raw_today || [];

              if (entity.attributes.tomorrow_valid &&
              entity.attributes.raw_tomorrow) {
                prices = prices.concat(entity.attributes.raw_tomorrow);
              }

              prices.forEach(item => {
                const p = item.price;

                data.push([
                  new Date(item.hour).getTime(),
                  p < greenLimit ? p : null
                ]);
              });

              return data;

          - entity: sensor.energi_data_service
            name: Normal
            type: column
            color: '#FFEB3B'
            show:
              legend_value: false
            data_generator: >
              let data = [];

              const avg = entity.attributes.today_mean;

              const greenLimit = avg * 0.8;
              const orangeLimit = avg * 1.2;

              let prices = entity.attributes.raw_today || [];

              if (entity.attributes.tomorrow_valid &&
              entity.attributes.raw_tomorrow) {
                prices = prices.concat(entity.attributes.raw_tomorrow);
              }

              prices.forEach(item => {
                const p = item.price;

                data.push([
                  new Date(item.hour).getTime(),
                  (p >= greenLimit && p < orangeLimit) ? p : null
                ]);
              });

              return data;

          - entity: sensor.energi_data_service
            name: Dyr
            type: column
            color: '#FF9800'
            show:
              legend_value: false
            data_generator: >
              let data = [];

              const avg = entity.attributes.today_mean;

              const orangeLimit = avg * 1.2;
              const redLimit = avg * 1.5;

              let prices = entity.attributes.raw_today || [];

              if (entity.attributes.tomorrow_valid &&
              entity.attributes.raw_tomorrow) {
                prices = prices.concat(entity.attributes.raw_tomorrow);
              }

              prices.forEach(item => {
                const p = item.price;

                data.push([
                  new Date(item.hour).getTime(),
                  (p >= orangeLimit && p < redLimit) ? p : null
                ]);
              });

              return data;

          - entity: sensor.energi_data_service
            name: Meget dyr
            type: column
            color: '#F44336'
            show:
              legend_value: false
            data_generator: >
              let data = [];

              const avg = entity.attributes.today_mean;

              const redLimit = avg * 1.5;

              let prices = entity.attributes.raw_today || [];

              if (entity.attributes.tomorrow_valid &&
              entity.attributes.raw_tomorrow) {
                prices = prices.concat(entity.attributes.raw_tomorrow);
              }

              prices.forEach(item => {
                const p = item.price;

                data.push([
                  new Date(item.hour).getTime(),
                  p >= redLimit ? p : null
                ]);
              });

              return data;

          - entity: sensor.elpriser_excl_afgift
            name: Excl. afgifter
            type: line
            color: '#03A9F4'
            stroke_width: 4
            extend_to: false
            show:
              extremas: true
              legend_value: false
            data_generator: |
              let data = [];

              if (entity.attributes.raw_today) {
                data = entity.attributes.raw_today.map((item) => [
                  new Date(item.hour).getTime(),
                  item.price
                ]);
              }

              if (entity.attributes.tomorrow_valid &&
                  entity.attributes.raw_tomorrow) {
                data = data.concat(
                  entity.attributes.raw_tomorrow.map((item) => [
                    new Date(item.hour).getTime(),
                    item.price
                  ])
                );
              }

              return data;
    grid_options:
      rows: auto
      columns: full
grid_options:
  rows: auto
  columns: full

5. Sådan fungerer Card'et

Card'et viser data for:

48 timer

Det starter ved begyndelsen af den aktuelle dag:

span:
  start: day

Der vises desuden en markering for det aktuelle tidspunkt:

now:
  show: true
  label: Nu

Prisberegning

Card'et bruger gennemsnitsprisen fra:

entity.attributes.today_mean

Gennemsnitsprisen bruges til at beregne tre grænser.

Grøn grænse

const greenLimit = avg * 0.8;

Priser under 80 % af gennemsnittet vises som grønne.

Orange grænse

const orangeLimit = avg * 1.2;

Priser mellem 120 % og 150 % af gennemsnittet vises som orange.

Rød grænse

const redLimit = avg * 1.5;

Priser på eller over 150 % af gennemsnittet vises som røde.


6. I dag og i morgen

Card'et henter først priserne for i dag:

entity.attributes.raw_today

Hvis morgendagens priser er tilgængelige, tilføjes de automatisk:

if (entity.attributes.tomorrow_valid &&
    entity.attributes.raw_tomorrow) {

Dermed kan grafen vise både:

I dag
+
I morgen

7. Blå linje - pris ekskl. afgifter

Den blå linje kommer fra:

sensor.elpriser_excl_afgift

Den vises som en linjegraf:

type: line
color: '#03A9F4'
stroke_width: 4

Denne serie viser den rå elpris uden afgifter.


8. Hvis grafen ikke viser data

Hvis Card'et viser:

Loading...

eller ingen priser, kontroller først:

Kontroller sensoren

Gå til:

Developer Tools → States

Søg efter:

sensor.energi_data_service

Kontroller at sensoren eksisterer.


Kontroller attributterne

Sensoren skal blandt andet have:

today_mean
raw_today

Hvis morgendagens priser er tilgængelige, skal den også have:

tomorrow_valid
raw_tomorrow

Kontroller ApexCharts

Kontroller at:

custom:apexcharts-card

er installeret via HACS.

Prøv eventuelt at genindlæse browseren med:

CTRL + F5

9. Afhængigheder

Komponent Funktion
Home Assistant Platform
HACS Installation af custom integrationer/cards
Energi Data Service Leverer elpriser
ApexCharts Card Viser grafen
sensor.energi_data_service Primær prisdata
sensor.elpriser_excl_afgift Pris uden afgifter

10. Kort installation

Hvis Home Assistant allerede har HACS installeret:

1. HACS
2. Integrations
3. Energi Data Service
4. Download
5. Genstart Home Assistant
6. Settings → Devices & services
7. Add Integration
8. Energi Data Service
9. Vælg prisområde
10. Installer ApexCharts Card via HACS → Frontend
11. Tilføj Card'et til dashboardet

11. Filer

Hvis Card'et gemmes som en separat YAML-fil, kan det eksempelvis gemmes som:

elpriser.yaml

eller:

elpriser_apexcharts.yaml

Selve Card'et er YAML, mens data_generator-sektionerne indeholder JavaScript, som ApexCharts bruger til at beregne og sortere datapunkterne.


Kilder