Indholdsfortegnelse

API beskrivelser

1. Introduktion

Dette dokument giver en kort beskrivelse af APIerne som EnergyDataDK stiller til rådighed for brugere.

Hvis du er ude efter en general introduktion til EnergyDataDK platformen, henviser vi til brugervejledningen.

Platformen stiller tre API’er til rådighed: Datastream, MQTT og Batch Upload. Disse er beskrevet i de følgende sektioner.

Vær opmærksom at du skal bruge et API token for at kunne tilgå data via API. Et token fungerer både som brugernavn og kodeord og bekræfter at du har adgang til dataet. Du kan få en general introduktion til API i brugervejledningen i API afsnittet.

Venligst meld fejl i dette dokument, eller forbedringsforeslag til energydatadk@dtu.dk

2. API til datastrøm værdier

EnergyDataDK stiller en API til rådighed for at hente den seneste værdi, eller værdier målt indenfor et bestemt tidsrum fra en eller flere datastrømme (property IDs). API’et bruges i applikationer som skal kunne hente data fra EnergyDataDK. Dette kræves et API token. Vores brugervejledning beskriver hvordan du kan oprette et token.

2.1 API beskrivelse

http:get::/api/v1/datastreams/values

Hent værdier for et eller flere egenskaber. Egenskaberne hvis værdier skal hentes bliver defineret ved brug af query parametre ids. Dette bør være en komma-separeret liste af datastrøm ID’er. Ressourcen kan bruges til at hente de seneste værdier, eller værdier fra et bestemt tidsperiode. Vær opmærksom på, at denne ressource ikke giver en JSON ved en succesfuld request. I disse tilfælde bliver response data sendt tilbage til klienten som CSV. Du bør stadigvæk specifisere Accept: application/json i headeren, for at sikreat fejlbeskeder bliver sendt tilbage til klienten som JSON.

Parametre for API’et er:

  • ids: Liste af property ID’er til at eksportere
  • from: ISO8601 formatteret dato
  • to: ISO8601 formatteret dato
  • latest: Boolean, true hvis tilstede

2.2 Eksempel af en request: Henting af seneste værdier

For at hente de seneste værdier de givne egenskaber, skal query parametren latest være tilstede.
GET /api/v1/datastreams/values?ids=65603,65607,65863&latest=true HTTP/1.1
Host: admin.energydata.dk
Accept: application/json
Authorization: Bearer <dit-token>

2.2.1 Eksempel af en response

HTTP/1.1 200 OK
Content-Description: File Transfer
Content-Disposition: attachment; filename=data.csv
Content-Type: text/csv; charset=UTF-8
Transfer-Encoding: chunked
65603,1547043555943,25.04
65607,1547043557698,25.12
65863,1544089165888,24

For at hente alle værdier for en bestemt property indenfor et bestemt tidsrum skal query parametrene from og to være tilstede. Disse skal være ISO8601 formaterede datoer, for eksempel “2018-02-01T12:30:00”. Læg mærke til at både from og to er inkluderet.

2.3 Eksempel af en request: Hentning af værdier i et bestemt tidsrum

GET /api/v1/datastreams/values?ids=65603,65607,65863&from=2018-0201T00:00:00&to=2018-02-02T00:00:00 HTTP/1.1
Host: admin.energydata.dk
Accept: application/json
Authorization: Bearer <dit-token>

2.3.1 Eksempel af en response

HTTP/1.1 200 OK
Content-Description: File Transfer
Content-Disposition: attachment; filename=data.csv
Content-Type: text/csv; charset=UTF-8
Transfer-Encoding: chunked
65607,1517443389806,25.12
65607,1517443449746,25.12
65607,1517443509696,25.12
65607,1517443569646,25.12
65607,1517443629586,25.12
65607,1517443689537,25.12
65863,1517443749495,25.12
65863,1517443809416,25.12
65863,1517443869366,24.04
65863,1517443929309,24.04
65863,1517443989256,24.04
65863,1517444049233,24.04
65863,1517444109146,24.04
65603,1517443389806,25.12
65603,1517443449746,25.12
65603,1517443509696,25.12
65603,1517443569646,25.12
65603,1517443629586,25.12
65603,1517443689537,25.12

3.1 At forbinde

Vores MQTT broker er til rådighed på mqtts.energydata.dk, og er åbn for MQTT forbindelser på port 8883.

3.2 Autentifikation

Inden du kan forbinde til en broker skal du oprette et token i EnergyDataDK, med MQTT pubsub tilladelse, samt tilladelse til at bruge licensen som giver adgang til de datasæt du er interesseret i. Når man skaber forbindelse bruger man tokenet som brugernavn. En eksempel i Python (kræver paho-mqtt (https://pypi.python.org/pypi/paho-mqtt)):
#! /usr/bin/env python

import paho.mqtt.client as mqtt
broker_host = 'mqtts.energydata.dk'
broker_port = 8883
heartbeat = 60
def connect_logger(client, userdata, flags, rc)
print('Connected with rc {}'.format(rc))
client = mqtt.Client(client_id='<your client_ID name>')

# NOTE! Above works on paho version less than 2.0.0. 
# Hvis du bruger paho ver. 2 eller højere skal du specificere call-back versionen. F.eks.: 
# client = mqtt.Client(client_id='minklient', callback_api_version=mqtt.CallbackAPIVersion.VERSION1)

client.username_pw_set('mit-token')
client.on_connect = connect_logger
client.tls_set()
client.connect(broker_host, broker_port, heartbeat)
print('Connecting')
client.loop_forever()
En eksempel ved brug af mosquitto_sub command-line client (bundled med Mosquitto: https://mosquitto.org/):
#! /bin/bash
mosquitto_sub -t '#' \
-h mqtts.energydata.dk \
-p 8883 \
-i '<your client_ID name>' \
-u 'dit-token'

3.3 Topics og Datasæt

I EnergyDataDK er tidsserier defineret som datastrømme og grupperet i et datasæt.

For at sende data til EnergyDataDK ved brug af MQTT, skal du oprette et datasæt med en topic prefix og en datastrøm i datasættet med en topic suffix. En topic prefix er en række af alfanumeriske karakterer, en suffix kan være adskillige alfanumeriske strenge delt med /. Derfor, hvis en prefix er my-topic-prefix og en suffix er my/topic/suffix , så er den fulde MQTT topic af datastrømmen my-topic-prefix/my/topic/suffix.

Denne topic bliver brugt hos MQTT broker, for at identificere datastrømmen.

Eksempler med Mosquitto:

#! /bin/bash

mosquitto_sub -t 'mit-topic-prefix/mit/topic/suffix' \
-h mqtts.energydata.dk \
-p 8883 \
-i '<your client_ID name>' \
-u 'dit-token'

#! /bin/bash

mosquitto_pub -t 'my-topic-prefix/my/topic/suffix' \
-h mqtts.energydata.dk \
-p 8883 \ -i '<your client_ID name>' \
-u 'dit-token'
-m '{"value":"0.16300000250339508","timestamp":1521797973052}'

3.4 Besked format

MQTT beskeder kan være formateret som en af to mulige typer:

  1. Enkel-værdibesked
  2. Multi-værdibesked

3.4.1 Enkel-værdibeskeder

Enkelt-værdibeskeder indeholder en tidsstempel og en værdi, som beskrevet i tabellen nedunder. Datastrømmen tilknyttet beskeden bliver udledt fra MQTT topic.

KeyTypeRequiredDescriptionExample
timestampIntegerYesNumber of milliseconds since 1970-01-01 (Unix epoch)1521797973469
valueString, Double or IntegerYesValue, encoded either as String, Double or Integer, depending on property definition in DMS14.47

Eksempel besked:

{
 "timestamp": 1521797973469,
 "value": 14.47
}

3.5 Multi-værdibeskeder

Multi-værdibeskeder bliver brugt i situationer hvor du skal publishe adskillige forskellige, men relaterede værdier.
De vil blive gemt med det samme tidsstempel i det samme datasæt for de emner, der er angivet nedenfor. Multi-værdibeskeder bliver published med topic præfikset som topic af MQTT beskeden, for eksempel my-topic-prefix. En payload har følgende form:
{
 "timestamp": 1521797973469,
 "value": {
 "mit/topic/suffix1": 14.47,
 "mit/topic/suffix2": 34,
 "mit/topic/suffix3": 4.87,
 "mit/topic/suffix4": 1,
  .... ,
 "mit/topic/suffixn": 300
  }
}

Alle meddelelses‑payloads skal serialiseres som JSON.

3.6 Bedste Praksis - At sikre levering af beskeder ved publicering

Når du publicerer til EnergyDataDK ved hjælp af MQTT, bør du bruge Quality of Service (QoS) 1 for at sikre, at meddelelser leveres. Dette er især vigtigt, hvis du publicerer med en høj kapacitet, da overbelastningsbeskyttelsesmekanismer kan kassere dine meddelelser. Hvorfor og hvordan beskrives detaljeret nedenfor. Når EnergyDataDK MQTT-mægleren modtager en publiceringsbesked fra din klient, føjes beskeden til en kø af indgående beskeder. Denne kø er pr. klient og kan indeholde op til 1000 beskeder. Beskeder i køen fjernes serielt fra køen på en FIFO-måde. Når MQTT-brokeren fjernes fra køen, kontrollerer den, at klienten er autoriseret til at udgive beskeder om det givne emne. Hvis autorisationen lykkes, videresendes beskeden til lagring i EnergyDataDK og til alle klienter, der abonnerer på det pågældende emne. Hvis beskeden blev publiceret med QoS 1 eller 2, sender MQTT‑brokeren kvitteringen, efter at autorisationen er gennemført. Hvis godkendelsen mislykkes, afbrydes klientens forbindelse med det samme, og alle beskeder i køen for indgående beskeder kasseres. Hvis MQTT-brokeren ikke kan følge med klienten, vil køen for indgående beskeder med tiden blive fuld. Når køen er fuld, kasserer MQTT-brokeren alle beskeder, den modtager fra klienten.
Det betyder, at din client skal begrænse sig selv for at undgå at miste beskeder. Du gør dette ved at udgive dine beskeder med QoS 1. Din klient skal derefter vente på at modtage en bekræftelse fra brokeren, før der udgives flere beskeder. Dette kan opnås i Python med paho-mqtt (https://pypi.python.org/pypi/pahomqtt/) biblioteket med funktionen wait_for_publish:
#! /usr/bin/env python

import time
import json
import paho.mqtt.client as mqtt

broker_host = 'mqtts.energydata.dk'
broker_port = 8883
heartbeat = 60

client = mqtt.Client(client_id='<your client_ID name>')
client.username_pw_set('mit-token')
client.connect(broker_host, broker_port, heartbeat)

# Husk at starte løkken for at modtage QoS-bekræftelser

client.loop_start()

for i in range(0,10000):
 timestamp = int(time.time() * 1000)
 message = json.dumps({'timestamp': timestamp, 'value': i})

# Udgiv med QoS1 ('qos=1') og vent på at modtage QoS-bekræftelser fra brokeren

message_info = client.publish('my-topic', message, qos=1)
message_info.wait_for_publish(timeout = 10) # timeout efter 10 sekunder, hvis der ikke modtages en bekræftelse

4. Batch Upload

Hvis du har brug for at uploade store mængder data, enten historiske eller ikke-tidskritiske data, er det en fordel at bruge batch-uploadmetoder. Der findes en batch-uploadprocedure, som enten kan kaldes som en HTTP-kommando ved hjælp af curl – denne er beregnet til manuel upload, eller den kan integreres i et Python-script.

4.1 Batch import HTTP API

For at importere data fra CSV-filer skal du:
  1. Formater CSV-filerne i henhold til instruktionerne nedenfor.
  2. opret uploaden i databasen
  3. få upload-URL’en
  4. upload filen til s3
  5. valider filen
  6. indtag filen

Der findes en Python helper class som gør dette lettere, se næste afsnit.

4.1.1 Autentificering og headers

I alle HTTP requests til http://admin.energydata.dk/api/v1/import nedunder har du tilføje en authorization header og en accept header. The autentificering skal være et bearer token, hvor tokenet er et batch import data token, som brugeren kan oprette i API token afsnittet af EnergyDataDK . Her er et eksempel af headersne, med et fiktivt token:
Authorization: Bearer bzkMFuZgTzsuOldud98fJ5RkRHBI4Uoprdub1R"
Accept: application/json

4.1.2 Formater filen

Filen skal være formateret som CSV efter RFC4180 standarden. Ud over det, hvis filen indeholder ikke-ascii karakterer, bør filen blive kodet som UTF-8. Den første række i CSV-filen skal indeholde overskrifter. Overskriften i en given kolonne identificerer den datastrøm, som kolonnens data skal importeres til. Overskriften kan enten være det emne, der er knyttet til den givne datastrøm, f.eks. mit/emne, eller datastrøms-ID’et, f.eks. 19323. Den første kolonne i den første række ignoreres. Hver række efter overskriften indeholder et tidsstempel i den første kolonne. Resten af ​​kolonnerne indeholder de værdier, der gælder for den givne datastrøm ved det givne tidsstempel.
Tidsstemplerne skal formateres som YYYY-MM-DD[T]HH:mm:ss.SSS[Z], f.eks. “2023-05-01T10:12:44.432Z” for 1. maj 2023, 10:12:44.432 UTC. Tidsstemplet skal være i UTC-tidszonen. Datatypen i en kolonne skal matche datatypen af datastrømmen hvilket kolonnen tilhører. Hvis en datastrøm er en heltal, skal alle værdier af den datastrøm også være heltal. Hvis et felt efterlades tomt, afhænger håndteringen af ​​datatypen for den tilsvarende datastrøm. Hvis datastrømmen er af typen string, en tom string importeres. Hvis datastrømmen er af typen integer eller double, importeres ingen værdi. Nedenfor er en eksempelfil. Bemærk, at den første datastrøm (117217) er af typen string, den anden datastrøm (mit/emne) er af typen double og den sidste datastrøm (119221) er af typen integer.
;117217;my/topic;119221
2021-03-10T20:24:30.139Z;a_string;23.4121;-10
2021-03-10T20:24:31.144Z;"another string";999888777.121;0
2021-03-10T20:24:32.161Z;a third string;-1.33e-16;45
2021-03-10T20:24:33.186Z;;54.1;11
2021-03-10T20:24:34.201Z;a-fourth-string;;45
Bemærk de tomme felter i række 5 (datastrøm 117217) og række 6 (mit/emne). For datastrøm 117217 importeres en tom streng med et tidsstempel. 2021-03-10T20:24:33.186Z. For datastrømmen my/topic importeres der ingen værdi med tidsstempel 2021-03-10T20:24:34.201Z.

4.1.3 Opret uploaden

For at oprette en import skal du oprette et importnavn til https://admin.energydata.dk/api/v1/import, med importen som en URL-parameter.

curl -H "Authorization: Bearer bzkMFuZgTzsuOldud98fJ5RkRHBI4Uoprdub1R" -H "Accept: application/json" -X POST
https://admin.energydata.dk/api/v1/import -G --data-urlencode "importname=batch-import-example"

# Response eksempel

# {"user_id":11,"status":"stored","name":"batch-import-example2","updated_at":"2023-03-27T08:20:36.000000Z","created_at":"2023-03-27T08:20:36.000000Z","id":1340}
Vis og slet

Ved at kalde get eller delete endpoint
https://admin.energydata.dk/api/v1/import/1340 kan du se eller slette en import med ID’et 1340

4.1.4 Hent upload-URL'en

Hent upload-URL’en med det ID, der blev returneret i oprettelsen ovenfor:

curl -H "Authorization: Bearer zGefiozgtCOfW70jnydNkTF35WOctQUnEMGAYKpi" -H "Accept: application/json"
https://admin.energydata.dk/api/v1/import/1340/upload_url

# Response eksempel
# {
# "upload_url":
"https://s3.energydata.dk/import/inbox/example-user/b23sdfb23b163-4dfc-84c8-87ded19fdse1a.csv?X-Amz-ContentSha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&XAmz-Credential=edk-s3root%2F20230327%2Fdefault%2Fs3%2Faws4_request&X-AmzDate=20230327T083455Z&X-Amz-SignedHeaders=host&X-AmzExpires=7200&X-AmzSignature=16697645e0f009c791e62f237dfd80e74d9ddfda83feb8801sd5 af186c81e0c0b"
}

4.1.5 Upload filen

Upload filen ved hjælp af curl, python-hjælpeskriptet eller se minio-dokumentationen for alternativer.
I følgende curl-eksempel er den anvendte filsti batch-import-example.csv
curl -X PUT -H "Content-Type: application/octet-stream" -data-binary "@batch-import-example.csv"
"https://s3.energydata.dk/import/inbox/example-user/b23sdfb23-b163-4dfc-84c8-87ded19fdse1a.csv?X-Amz-ContentSha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&XAmz-Credential=edk-s3root%2F20230327%2Fdefault%2Fs3%2Faws4_request&X-AmzDate=20230327T083455Z&X-Amz-SignedHeaders=host&X-AmzExpires=7200&X-AmzSignature=16697645e0f009c791e62f237dfd80e74d9ddfda83feb8801sd5 af186c81e0c0b" > /dev/null

4.1.6 Valider filen

For at validere filformatet og dataene, send en PUT til https://admin.energydata.dk/api/v1/import/1340/validate, i følgende eksempel bruges import-id’et 1340.

curl -H "Authorization: Bearer bzkMFuZgTzsuOldud98fJ5RkRHBI4Uoprdub1R" -H "Accept: application/json" -X PUT
https://admin.energydata.dk/api/v1/import/1340/validate"

En korrekt anmodning vil blot acceptere opgaven. For at se status for valideringen skal du sende en GET-anmodning som specificeret i afsnit 2.1. På den returnerede import vil der være en status og eventuelle fejl.

4.1.7 Indtag filen

For at indtage filformatet og dataene, send en PUT til https://admin.energydata.dk/api/v1/import/1340/ingest, i følgende eksempel bruges import-id’et 1340.
curl -H "Authorization: Bearer bzkMFuZgTzsuOldud98fJ5RkRHBI4Uoprdub1R" -H "Accept: application/json" -X PUT https://admin.energydata.dk/api/v1/import/1340/ingest"
En korrekt anmodning vil blot acceptere opgaven. For at se status for indtagelsen skal du sende en GET-anmodning som angivet i afsnit 2.1. På importens tilbagemelding vil være et status og eventuelle fejl.

4.2 Batch import python API

Dette er dokumentationen for en klasse, der er lavet for at gøre import til EnergyDataDK nemmere fra Python. Koden kan findes i dette repository: https://git.elektro.dtu.dk/energydatadk/batch-import-python-api

EnergyDataImport

class EnergyDataImport()

En simpel klasse til at gøre batchimport til EnergyDataDK nemmere fra Python

Denne klasse håndterer opbygning af en CSV-fil i det korrekte format, der skal bruges til import til EnergyDataDK via batch-API‘et. Selve batch-API‘et er dokumenteret separat (se forrige afsnit). Denne klasse kan håndtere alt fra oprettelse af den korrekte CSV-fil til upload, validering og indlæsning af filen. Du kan kontrollere scriptet ‘example_import.py’ for et eksempel på, hvordan du bruger denne class.

4.2.1 __init__

__init__(upload_filename: str, properties: List, sftp_username: str, sftp_password: str, energydata_api_token: str, overwrite: bool = False, tmp_dir: str = '/tmp/energydata_batch_uploud', autoclean_tmp_files: bool = True)

Konstruktør for klassen. Opret en instans af EnergydataImport for hver databatch, du vil uploade. En instans kan ikke genbruges mellem flere importer.

Argumenter:

  • upload_filename
    string — Et filnavn til den importfil, der genereres bag kulisserne. En lokal fil i tmp_dir oprettes med dette navn, og det samme filnavn bruges ved upload til SFTP-serveren.
  • properties
    list – Liste over egenskaber, hvortil data vil blive tilføjet. Kan enten være egenskabs-id’er eller emner.
  • sftp_username
    string – Brugernavn til SFTP-serveren på ‘api.energydata.dk’, hvorfra batchimporter kører. Bed en administrator om adgangsoplysninger.
  • sftp_password
    string – Adgangskode til SFTP-serveren på ‘api.energydata.dk’, hvorfra batchimporter kører. Bed en administrator om adgangsoplysninger.
  • energydata_api_token
    stringAPI-token som fundet i: https://admin.energydata.dk/api-tokens
  • overwrite
    bool, valgfri – Hvis en lokal fil med filnavnet {tmp_dir}/{upload_filename} eller en fil med {upload_filename} i SFTP-uploadmappen findes, styrer denne indstilling, om vi skal overskrive filen eller ej. Standardindstillingen er False.
  • tmp_dir
    string, valgfri – En mappe til midlertidig lagring af datafiler, før de uploades til SFTP. Standardværdien er ‘/tmp/energydata_batch_upload’.
  • autoclean_tmp_files
    bool, valgfri – Hvis denne parameter er indstillet til False, vil de filer, der genereres i tmp_dir, ikke blive fjernet, når importkonteksten er lukket. Standardindstillingen er True.

4.2.2 add_values

add_values(time: datetime, values: List)

Kald i åben tilstand for at fortsætte med at tilføje værdier, der skal importeres i batch.

Argumenter:

  • time
    datetime – Tidsstempel for værdier, der skal tilføjes
  • values
    list – En liste over de værdier, der skal tilføjes

Udløser:

  • Exception – Der opstår en undtagelse, hvis tidsargumentet er et datetime-objekt uden tidszoneoplysninger.
  • Exception – Længden af ​​værdilisten skal være lig med antallet af egenskaber, der overføres i konstruktøren, ellers opstår der en undtagelse.

4.2.3 upload

upload(print_progress=True)


Når alle værdier er blevet tilføjet ved hjælp af add_values-metoden, kan denne metode kaldes for at uploade den genererede CSV-fil til SFTP-serveren og oprette et importjob med EnergyDataDK API‘en. Når det er kaldt, vil jobbets tilstand skifte fra åben til upload, upload og endelig til gemt, når jobbet er oprettet.

Argumenter:

  • print_progress
    bool, valgfrit – Uanset uploadstatus skal det udskrives kontinuerligt. Standardværdien er True.

4.2.4 validate

validate(block=True, print_progress=True)

Når den er i lagret tilstand, kan denne metode kaldes for at udløse validering af de data, der skal importeres. Dette sker ved at kalde det tilsvarende valideringsslutpunkt på EnergyDataDK. Tilstanden vil gå fra lagret til validerende og endelig til klar.

Argumenter:

  • block
    bool, valgfri – Hvad denne metode skal blokere, mens valideringen er i gang. Standardværdien er True.
  • print_progress bool, valgfrit – Uanset uploadstatus skal det udskrives kontinuerligt. Standardværdien er True.

4.2.5 ingest

ingest(block=True, print_progress=True)

Når den er i klartilstand, kan denne metode kaldes for at udløse indtagelse af de data, der skal importeres. Dette sker ved at kalde det tilsvarende indtagelsesslutpunkt på EnergyDataDK. Tilstanden vil skifte fra ready til ingesting og endelig til done.

Argumenter:

  • block bool, valgfri – Hvad denne metode skal blokere, mens indtagelsen er i gang. Standardværdien er True.
  • print_progress bool, valgfrit – Uanset uploadstatus skal det udskrives kontinuerligt. Standardværdien er True.

4.2.6 refresh_status

refresh_status()

Denne metode kan bruges til manuelt at opdatere og synkronisere importjobbets interne tilstand med tilstanden i EnergyDataDK. Hvis f.eks. validate kaldes med block=False, skal denne metode bruges til at opdatere tilstanden, før indtagelse kan kaldes, når valideringen er fuldført på serveren.

Tilbagemelder:

  • [type] – Tilbagemelder den aktuelle status i form af en enum af typen EnergyDataImport.Status.