RESTful Sensor with GraphQL payload

I’m trying to configure a RESTful Sensor that pulls data from a service that consumes Graphql queries. As far as I can tell the service returns an error which leads me to assume that the query (in the payload) is not formatted correctly. The same query works fine from other tools.

My configuration:

sensor:
  - platform: rest
    name: Tibber prices
    resource: https://api.tibber.com/v1-beta/gql
    method: POST
    payload: "{ viewer { homes { currentSubscription { priceInfo { today { total startsAt }}}}}}"
    json_attributes_path: "$.data.viewer.homes[0].currentSubscription.priceInfo"
    json_attributes: 
      - today
    value_template: Ok
    headers:
      Authorization: !secret tibber_token
      Content-Type: application/json
      User-Agent: REST

The log gives me this:

2021-10-06 08:13:02 DEBUG (MainThread) [homeassistant.components.rest.sensor] Data fetched from resource: {“error”:“syntax error”}
2021-10-06 08:13:02 WARNING (MainThread) [homeassistant.components.rest.sensor] JSON result was not a dictionary or list with 0th element a dictionary

Please advice :slight_smile:

Prove it with curl :slight_smile:

According to https://graphql.org/learn/serving-over-http/ , graphql with POST should use proper JSON, not the GQL syntax.

Many thanks @koying , changing the post body to proper JSON solved the problem.

payload: ‘{ “query”: “{ viewer { homes { currentSubscription { priceInfo { today { total startsAt }}}}}}” }’

You saved my day!

Why not use the Tibber integration? Tibber - Home Assistant

@Danielhiversen, as far as I understand the Tibber integration delivers the prices in “real time” as a sensor. Using the method above I’m able to load future prices for the whole day and plot them in advance like below.

1 Like

Thanks a lot!

I’ve been looking for a nice way to solve this. Future price is quite handy when planning when to consume power the coming day.

How do you get the price data represented in HA? I get a proper sensor that only holds the state OK (value_template)…

I get the following log message: [homeassistant.components.rest.sensor] JSON result was not a dictionary or list with 0th element a dictionary

I do get a proper response from the API using this curl command:
curl -H "Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" -H "Content-Type: application/json" -X POST -d '{ "query": "{viewer {homes {currentSubscription {priceInfo {current {total energy tax startsAt }}}}}}" }' https://api.tibber.com/v1-beta/gql

Any ideas?

And what is it?

Yeah, sorry about that…

The response looks like this: {“data”:{“viewer”:{“homes”:[{“currentSubscription”:{“priceInfo”:{“current”:{“total”:2.5427,“energy”:2.0262,“tax”:0.5165,“startsAt”:“2021-12-17T09:00:00.000+01:00”}}}}]}}}`

And what is your actual sensor definition?
Should work with the OP definition (after fixing the payload).

Here is the sensor config:

- platform: rest
  name: Tibber prices
  resource: https://api.tibber.com/v1-beta/gql
  method: POST
  payload: '{ “query”: “{ viewer { homes { currentSubscription { priceInfo { today { total startsAt }}}}}}” }'
  json_attributes_path: "$.data.viewer.homes[0].currentSubscription.priceInfo"
  json_attributes: 
    - today
  value_template: Ok
  headers:
    Authorization: !secret tibber_token
    Content-Type: application/json
    User-Agent: REST

Oh, misunderstood you I think.
If you want the price as sensor state, you have to adapt value_template to extract it.

Bazillion examples in the forum and in the doc.

Ahhh… OK.
Do I then have to create one sensor for each hour into the future?

I have been struggeling with this and get the same error in the logs, any idea as to what I am doing wrong?

My config

- platform: rest
    name: Elpris idag
    resource: https://api.tibber.com/v1-beta/gql
    method: POST
    payload: "{ 'query': '{ viewer { homes { currentSubscription { priceInfo { today { total startsAt }}}}}}' }"
    json_attributes_path: "$.data.viewer.homes[0].currentSubscription.priceInfo"
    json_attributes:
      - today
    value_template: Ok
    headers:
      Authorization: !secret tibber_token
      Content-Type: application/json
      User-Agent: REST

I know this an old topic, but wanted to post here anyway. The following configuration is working for me:

in configuration.yaml create

rest: !include rest.yaml

rest.yaml

- resource: https://api.tibber.com/v1-beta/gql
  method: POST
  payload: '{ "query": "{ viewer { homes { currentSubscription { priceInfo { current { total energy tax startsAt }}}}}}" }'
  headers:
    Authorization: !secret tibber_api
    Content-Type: application/json
    User-Agent: REST
  sensor:
    - name: "Tibber energieprijs huidig"
      json_attributes_path: "$.data.viewer.homes[0].currentSubscription.priceInfo.current"
      value_template: "{{ value_json.data.viewer.homes[0].currentSubscription.priceInfo.current.total | float }}"
      json_attributes:
        - total
        - energy
        - tax
        - startsAt
      unit_of_measurement: EUR/kWh
      device_class: monetary
      state_class: measurement
2 Likes

finally I found a thread on graphQL… but I am still stuck :wink:

trying to configure a rest sensor for this Query and following https://graphql.org/learn/serving-over-http/#post-request:

query MarketPrices {
    marketPricesElectricity(startDate: "2021-10-01", endDate: "2021-10-30") {
    till
    from
    marketPrice
    priceIncludingMarkup
    }
    marketPricesGas(startDate: "2021-10-01", endDate: "2021-10-30") {
    from
    till
    marketPrice
    priceIncludingMarkup
  }
}

see: Get Frank Energie prices with Python and GraphQL

All I can stumble my way through is:

sensor:

  - platform: rest
    resource: https://graphcdn.frankenergie.nl
    name: Frank energie prijzen
    value_template: "ok"
    method: POST
#     params:
#       startDate: >
#         {{(now().strftime('%Y-%m-%d')}}
#       endDate: >
#         {{(now()+ timedelta(days=+1)).strftime('%Y-%m-%d')}}
    payload: >-
      {
        "query": "MarketPrices",
        "operationName": "marketPricesElectricity",
        "variables": { "startDate": "2022-10-13", "endDate":"2022-10-14"  }
      }

but that leaves out all the attributes

so I should maybe try

  - platform: rest
    resource: https://graphcdn.frankenergie.nl
    name: Frank energie prijzen
    value_template: "ok"
    method: POST
#     params:
#       startDate: >
#         {{(now().strftime('%Y-%m-%d')}}
#       endDate: >
#         {{(now()+ timedelta(days=+1)).strftime('%Y-%m-%d')}}
    payload: >-
      {
        "query": "MarketPrices",
        "operationName": "marketPricesElectricity",
        "variables": { "startDate": "2022-10-13", "endDate":"2022-10-14"  }
      }
    json_attributes:
      - from
      - till
      - marketPrice
      - priceIncludingMarkup

but would still need a path .

Please have a look if you can help me out, or at least get things going?
thanks!

Looking to do something similar, would you care to share your sensor and what dashbord card you are using for representation?

Nevermind, you start the thread with the sensor, to early and to little coffee :slight_smile: