Get control of your energy usage with Tibber and their GraphQL API
«Forget all you knew about energy companies»
If you are like me and love smart home gadgets you gonna love the energy company Tibber’s smart home solutions.
Some background information first: Tibber is an energy company that was started back in 2016. The company makes direct agreements with the electricity producers and the users pay a monthly price in addition to the power consumption. Electricity originating from renewable energy is a matter of course. Through their mobile app you can connect your smart home devices and the app would then help you with smart heating, electric car charging and much more to automatically reduce consumption and energy bill.
In addition to the mobile app, Tibber is also providing its own API to its customers and that is what we are gonna focus on in this article. 🤓
Tibber API
To get started using the API you simply sign in to the developer portal with your Tibber credentials. When successfully logged in you will get a personal access token, API explorer and documentation.
But wait a second, what if you just want to test the API or if you are planning on developing a 3rd party app and do not have a Tibber customer account yourself? No problem, you can try out the API by using their demo account. 😉
Start off by navigating to the API explorer and load either your personal token or the demo token. Next up you can test out the GraphQL API by using an example query or writing your own.
By using the demo token you can now access Arya Starks energy usage.
Go ahead and test out the different example queries that Tibber provides. You can also use the real-time subscription and push notification (mutation). Sending push notification is only available for Tibber users.
Let’s create something!
It's pretty cool that Tibber provides this API explorer for testing out queries, but you are here for learning how you can use their API. First of all, you’ll need a framework to create an application that would display the data. I would use React to do this. We also need a GraphQL client to create a connection between our application and the Tibber API. I would use Apollo Client for this.
After creating your React application you need to install some dependencies to use the Apollo Client. Head over to your terminal and type:
npm install apollo-boost @apollo/react-hooks graphql --save
apollo-boost
: Package containing everything you need to set up Apollo Client@apollo/react-hooks
: React hooks based view layer integrationgraphql
: Also parses your GraphQL queries
This should install all the necessary dependencies we need to get started with our queries and mutations.
Apollo Client HOC
Now that you have all the necessary dependencies, let’s create your Apollo Client. For the client we set up a higher-order component (HOC) with connection to Tibbers API.
Let’s start by looking at the client setup in the HOC. The client has a uri
and a request
property. The uri
property will be where we set the endpoint for our GraphQL server. In our case that's the endpoint for the Tibber API.
Next up we have the request
property and it serves us a function that is called on each request. For our setup, this function is useful for setting up the authentication in the header. Therefore this is the place we will use for setting our bearer token.
So this is all we need to set up for the fetching to work, but we also need to connect the Apollo Client to React. For that, we need to use the ApolloProvider
component exported from @apollo/react-hooks
. We will then create the HOC that would take our component as a parameter and wrap it with the ApolloProvider
. Then we will place the client on the context and the cool part now is that it allows us to access it from anywhere in the component tree. It is recommended to put the ApolloProvider somewhere high in the component tree structure. So with our newly HOC created, let’s send our whole React app as the WrappedComponent
parameter.
Fetching data with hooks
After our React app is wrapped up with our hook, we’re ready to start fetching data with the hooks that Apollo provides.
First up is useQuery
hook. It is a hook exported from @apollo/react-hooks
that returns an object containing loading
, error
, and data
properties. The cool part is that Apollo Client tracks the loading and error states for you and attach them to the properties with the same name in the returned object. These two properties can then be used in the code to give the user a loading state UI until the data is fetched or an error state UI if the fetching is throwing an error.
When the query fetching is successful, the hook returns a result and it will be attached to the data
property. In the code snippet above the data
property will get a viewer object containing a name property. This property will have the registered name for our Tibber account as the value.
Hurray, we have fetched our first data from the Tibber API! 🎉
Realtime data fetching
In addition to fetching data using queries, GraphQL also allows us to listen to a server in real-time. Tibber provides its customers to subscribe to their real-time energy consumption using a dedicated subscription endpoint. This endpoint is handling the traffic over a persistent connection, also known as WebSockets
. Since subscriptions are handled over WebSockets
, setting up our client to support it would be the trickiest step, so let’s go through it. 👨💻
Setting up our client to support WebSockets need some additional dependencies so let’s head over to the terminal again and type:
npm install apollo-client apollo-link-ws apollo-link-http apollo-link apollo-utilities apollo-cache-inmemory subscriptions-transport-ws --save
For our client to support subscriptions we need to define the endpoint for both the HTTP
and WebSocket
connections, therefore we would need to install the Apollo dependencies independently.
apollo-client
: Where all the magic happens.apollo-link-ws
: Link for sending GraphQL operations over WebSockets.apollo-link-http
: Link for sending GraphQL operations over HTTP.apollo-link
: Package with an interface for creating new links on our client, especially combine HTTP with WebSocket link.apollo-utilities
: Utilities for Apollo Clientapollo-cache-inmemory
: Apollo cache setupsubscriptions-transport-ws
: A client to facilitate subscriptions over WebSockets.
Apollo Client HOC (Extended)
Let’s go back to the higher-order component that we created earlier. This time we are going to replace some of the setup especially the client setup with a new client that has support for subscriptions.
The first thing to notice is that we have replaced the import of ApolloClient from the apollo-boost
library with all the other dependencies that we installed above. Next change is that we need to set up the HTTP
and WebSocket
links separate.
In the constant for the HTTP
link we create a new HttpLink
and attach the Tibber endpoint we used in first place to the uri property. We also need an authorization header with the Bearer token. The authorization header is attached to the headers property.
Next up would be the creation of the WebSocket
link. We create this by using the WebSocketLink
exported by apollo-link-ws
library and the SubscriptionClient
exported by the subscriptions-transport-ws
library.
In this the SubscriptionClient
we would send two parameters. First one would be the Tibber endpoint for the subscriptions. The other one would be the options
parameter and there we set three properties. When reconnect
property is set to true the link would automatically try to reconnect in case of connection error. We attach 30000 ms to the timeout
property so that the client should wait for 30 seconds for a keep-alive message from the server. ⏲
The last one is the function connectionParams
. This function returns the Tibber token for our account, or demo account, and use it in the WebSocket
connection. This one was a bit tricky at first when I did it. I thought that the Bearer token should be used here as with the HTTP
link setup, but it was actually just the access token.
Great! Now we have created the links that we need for connecting to both endpoints in the Tibber API! 😀
The last missing piece is that we need to define our new client with both links and include the cache setup provided by Apollo. The ApolloClient only takes one link, therefore we need to use the split
function exported from apollo-link
.
The split
function takes two required parameters and one optional one. The first one is a function that receives the GraphQL operation and returns true if the operation is a subscription. The split function would then, when true, return the first link which is the subscription link. If false it would return the Http link. We can then in the creation of the new ApolloClient
add the link constant and the default cache setup InMemoryCache
exported from apollo-cache-inmemory
.
Finally, our Apollo Client HOC also supports real-time data! 🙌
Subscription hook
Now that our React app is wrapped up with the updated Apollo Client HOC that has support for subscriptions, we are ready to fetch som real-time date from the Tibber API.
In addition to useQuery
hook, @apollo/react-hooks
also exports a hook for subscriptions called useSubscription
. As you can see the hook is very similar to the useQuery
hook. It returns an object containing loading
, error
, and data
properties and they work the same way. Apollo Client would in this hook too, track the loading and error states for you and attach them to the properties. When the WebSocket
connection is successfully established the data
property will get the live measurement data from the Tibber API.
By using the demo token again we can now access Arya Starks real-time energy usage in our app. ⚡️
Sum up
That’s it! We have now covered most of what the Tibber API allows us to do with our data. We have looked at fetching data using HTTP
and the useQuery
hook, and also how to fetch real-time data using WebSocket
and the useSubscription
hook.
I have added a gif below that is an example of my application. I have extended it with some more functionality and visualization. My application uses a map exported from react-map-gl
to display the position of the demo user by using the longitude and latitude data fetched from the Tibber API. The map also has a colored map point with a number that indicates the energy usage live. The colored map point of the user switches between green, yellow and red based on the energy usage.
Hope you found this useful! 🤓