Korzystanie z API

Praktyczne przykłady dla publicznego API THMI — uwierzytelnianie, odczyt wartości, zapytania o historię, obsługa błędów i formaty.

Ta strona to praktyczne uzupełnienie listy punktów końcowych: jak się uwierzytelnić, jak wygląda treść zapytania o historię, jaką postać mają znaczniki czasu i błędy oraz jak wybrać JSON lub CSV. Pełny, czytelny maszynowo kontrakt znajdziesz w specyfikacji OpenAPI.

Uwierzytelnianie

Wysyłaj swój token dostępu jako token bearer w każdym żądaniu. Nagłówek musi zaczynać się od Bearer — nic innego nie jest akceptowane i nie ma alternatywy w postaci parametru zapytania:

curl https://<your-cloud-host>/api/v1/projects/list \
  -H "Authorization: Bearer <your-token>"

Żądanie z brakującym lub nieprawidłowym nagłówkiem Authorization jest odrzucane z kodem 401 Unauthorized, zanim dotrze do jakichkolwiek danych projektu. Prawidłowy token, który nie otrzymał dostępu do żądanego projektu lub zasobu, dostaje 403 Forbidden.

Odczyt bieżącej wartości

Bieżące wartości pobiera się zwykłymi żądaniami GET. Pobierz jeden tag według jego ścieżki:

curl "https://<your-cloud-host>/api/v1/<projectId>/tag/values/by-path?tagPath=Building/Boiler/SupplyTemp" \
  -H "Authorization: Bearer <your-token>"

Wszystko poza historią i eksportem CSV to GET — pełny zestaw (projekty, tagi, wartości, strony, strefy czasowe) znajdziesz w sekcji Punkty końcowe.

Zapytania o historię

Historia to jedyny odczyt, który używa POST — nie dlatego, że cokolwiek zmienia, ale dlatego, że zapytanie jest zbyt duże na URL. Treść zawiera zakres czasu, tagi oraz sposób ich agregacji. Wybierz punkt końcowy według tego, jak identyfikujesz tagi (by-path lub by-id), a format odpowiedzi według ostatniego segmentu ścieżki (json lub csv):

curl -X POST "https://<your-cloud-host>/api/v1/<projectId>/history/aggregate/by-path/json" \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "timeFrom": 1572548400000,
    "timeTo": 1574239662847,
    "timeZone": "Europe/Stockholm",
    "groupingType": "HOURS",
    "valueType": "ACTUAL",
    "tagList": ["Building/Boiler/SupplyTemp", "Building/Boiler/ReturnTemp"]
  }'
PoleTypUwagi
timeFromnumberPoczątek zakresu, milisekundy epoki.
timeTonumberKoniec zakresu, milisekundy epoki.
timeZonestringStrefa IANA (np. Europe/Stockholm), do której wyrównywane jest grupowanie.
groupingTypestringRozmiar przedziału: MINUTES, HOURS, DAYS, MONTHS lub YEARS.
valueTypestringACTUAL (odczyt) lub DELTA (zmiana w przedziale).
tagListstring[]Ścieżki tagów (dla by-path) lub id tagów (dla by-id).

Dla by-id wpisz w tagList id tagów zamiast ścieżek. Przestarzały punkt końcowy …/history/aggregate/{format} (bez by-path/by-id) działa jak by-id.

Znaczniki czasu

Każdy znacznik czasu — timeFrom/timeTo, które wysyłasz, i czasy punktów, które otrzymujesz — to liczba całkowita w milisekundach epoki (UTC), a nie ciąg ISO. timeZone wpływa tylko na wyrównanie i etykietowanie przedziałów, a nie na jednostki. Konwersję do i z własnej strefy czasowej wykonuj po swojej stronie.

Formaty

  • Odpowiedzi są domyślnie w formacie JSON. Historia i jej eksport dają też CSV, a strony renderują się jako SVG.
  • Format wybiera się ścieżką, a nie nagłówkiem Accept — decyduje o nim końcowe /json lub /csv w punktach końcowych historii. Żądanie csv przesyła strumieniowo te same dane jako plik CSV do pobrania.

Błędy

Błędy wracają jako niewielka koperta JSON ze status równym fail:

{
  "status": "fail",
  "message": "A human-readable explanation",
  "code": "optional_error_code"
}

Status HTTP wskazuje kategorię:

StatusZnaczenie
400 Bad RequestŻądanie lub jego treść były nieprawidłowe (błędne pole, wadliwe zapytanie).
401 UnauthorizedBrak użytecznego tokenu bearer.
403 ForbiddenToken nie ma dostępu do tego projektu lub zasobu.
404 Not FoundNie ma takiego projektu, tagu ani strony.