webitect.de
Home | Blog | Apps

Veröffentlicht: 20.04.2024

Tibber API in Java nutzen

Die Tibber API lässt sich über den Endpunkt https://api.tibber.com/v1-beta/gql nutzen. Das Schema können wir entsprechend über diese URL abfragen. Dafür installieren wir uns zunächst das CLI-Tool get-graphql-schema über npm.

npm install -g get-graphql-schema

Dann lässt sich das Schema so laden:

get-graphql-schema https://api.tibber.com/v1-beta/gql > tibber-api.graphql

Auf der API Referenz-Seite ist das Schema in einem lesbareren Format abrufbar.
Mit Standard Java-Mitteln können wir den heutigen Preis zum Beispiel wie folgt abrufen

package de.webitect.tibber;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class TibberApiTest {
    private static final String ACCESS_TOKEN = "Bearer MY_SECRET_TOKEN";

    private static final String QUERY = "{" +
            "viewer { home(id: \\\"abcdefgh-1234-56789-ijklmnopqrst\\\") { currentSubscription { " +
            "priceInfo { " +
            "today { " +
            "startsAt " +
            "total " +
            "} } } } } }";

    public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
        final TibberApi tibberApi = new TibberApi(ACCESS_TOKEN);
        final HttpResponse<String> response = tibberApi.call(QUERY);

        //TODO Ergebnis parsen
    }

    public static class TibberApi {
        private static final String TIBBER_API_URI = "https://api.tibber.com/v1-beta/gql";
        private static final String QUERY_PLACEHOLDER = "###PLACEHOLDER###";
        private static final String QUERY_TEMPLATE = "{\"query\": \"" + QUERY_PLACEHOLDER + "\"}";
        private final String accessToken;

        public TibberApi(String accessToken){
            this.accessToken = accessToken;
        }

        public HttpResponse<String> call(String query) throws URISyntaxException, IOException, InterruptedException {
            query = QUERY_TEMPLATE.replace(QUERY_PLACEHOLDER, query);

            final HttpRequest request = HttpRequest.newBuilder()
                    .uri(new URI(TIBBER_API_URI))
                    .version(HttpClient.Version.HTTP_2)
                    .header("Authorization", accessToken)
                    .header("Content-Type", "application/json; charset=utf-8")
                    .POST(HttpRequest.BodyPublishers.ofString(query))
                    .build();

            final HttpClient client = HttpClient.newHttpClient();

            return client.send(request, HttpResponse.BodyHandlers.ofString());
        }
    }
}

Natürlich muss das ACCESS_TOKEN und die home id entsprechend angepasst werden.

Wenn wir Jackson Databind als Dependency in unserem Gradle-Project hinzufügen,

./build.gradle
...

dependencies {
    ...

    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.17.0'
    // Unterstützung für LocalDateTime und Instant
    implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.17.0'

    // Lombok Dependency um uns ein bisschen Schreibarbeit zu sparen
    compileOnly 'org.projectlombok:lombok:1.18.32'
    annotationProcessor 'org.projectlombok:lombok:1.18.32'
}

...

können wir die Antwort zum Beispiel wie folgt parsen:

public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
    final TibberApi tibberApi = new TibberApi(ACCESS_TOKEN);
    final HttpResponse<String> response = tibberApi.call(QUERY);

    final ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    final Result result = mapper.readValue(response.body(), Result.class);
}

Damit das funktioniert, haben wir simple Java-Pojos erzeugt, die der Struktur des Response-Json entspricht *:

package de.webitect.tibber.api;

@lombok.Data
public class Result {
    private Data data;
}
package de.webitect.tibber.api;

@lombok.Data
public class Data {
    private Viewer viewer;
}
package de.webitect.tibber.api;

import lombok.Data;

@Data
public class Viewer {
    private Home home;
}
package de.webitect.tibber.api;

import lombok.Data;

@Data
public class Home {
    private CurrentSubscription currentSubscription;
}
package de.webitect.tibber.api;

import lombok.Data;

@Data
public class CurrentSubscription {
    private PriceInfo priceInfo;
}
package de.webitect.tibber.api;

import lombok.Data;

import java.util.Collections;
import java.util.List;

@Data
public class PriceInfo {
    private List<Today> today = Collections.emptyList();
}
package de.webitect.tibber.api;

import lombok.Data;

import java.time.Instant;

@Data
public class Today {
    private Instant startsAt;
    private double total;
}
Damit ist unser Beispiel vollständig. Das Result-Objekt lässt sich natürlich um die weiteren Möglichkeiten der Tibber-API erweitern. Auch der TibberApi-call lässt sich für andere Queries verwenden. Viel Spaß beim Ausprobieren 😊
(* Eine Beispiel-Response haben wir im Artikel Tibber API vorgestellt)
© 2023 - 2024 webitect.de | Impressum | About