Unable to configure multiple sensors at restful

I am trying to get multiple values from a REST API with the goldapi.io site. I’m able to return a proper value from the call, but when I configure multiple sensors using the template platform, I can’t retrieve a single value. I’ve tried anything in the book and a lot more, but that didn’t help. This is the code in my sensors.yaml:

# Gold Market Data Sensor
- platform: rest
  resource: https://www.goldapi.io/api/XAU/EUR
  name: "Gold API"
  method: GET
  value_template: >
    {% if value_json.price is defined %}
      {{ (value_json.price * 32.1507)|round(0)|int}}
    {% elif value_json.error is defined %}
      {{ 55111|int }}
    {% else %}
      {{ 55222|int }}
      {% endif %}
  scan_interval: 31536000
  headers:
    x-access-token: !secret gold_api_key
    Content-Type: "application/json"
- platform: template
  sensors:
    gold_api_price:
      value_template: "{{ state_attr('sensor.gold_api', 'price') }}"
    gold_api_error:
      value_template: "{{ state_attr('sensor.gold_api', 'error') }}"

The call returns this JSON if a valid API-key is presented:

{"timestamp":1673135572,"metal":"XAU","currency":"EUR","exchange":"FOREXCOM","symbol":"FOREXCOM:XAUEUR","prev_close_price":1741.92,"open_price":1741.92,"low_price":1740.5,"high_price":1762.11,"open_time":1672963200,"price":1752.96,"ch":11.04,"chp":0.63,"ask":1753.75,"bid":1752.17,"price_gram_24k":56.359,"price_gram_22k":51.6624,"price_gram_21k":49.3141,"price_gram_20k":46.9658,"price_gram_18k":42.2692}

… and this if an invalid key is presented:

{"error":"Invalid API Key"}

In the Template Editor I test these three values:

{{ states('sensor.gold_api') }}              # Returns the proper gold price as calculated from vaue_json
{{ states('sensor.gold_api_price') }}    # Returns unknown
{{ states('sensor.gold_api_error') }}    # Returns unknown

Both value_json.price and value_json.error are defined and recognized by the rest value-template, but the template sensors can’t for some reason reference the other JSON values.

I’ve referenced the multi-sensor documentation of the rest-platform extensively, but I don’t see what’s going wrong here. Please help!

I believe this helps … you did not define attribs but in your template you call on them
RESTful - Home Assistant (home-assistant.io)

I think you have to specifically add the various JSON values as attributes, or they won’t be available. Here’s an example rest sensor I use that defines them.

rest:
  - resource: http://xxx.xxx.xxx.xxx/status.json
    sensor:
      - name: HDHomerun Tuner 1
        json_attributes_path: "$..[?(@.Resource=='tuner0')]"
        json_attributes:
          - Resource
          - VctNumber
          - VctName
          - Frequency
          - SignalStrengthPercent
          - SignalQualityPercent
          - SymbolQualityPercent
          - NetworkRate
          - TargetIP
        icon: mdi:numeric-1-box
        value_template:  >-
          {% if value_json[0].VctName is defined %}
            In Use
          {% else %}
            Idle
          {% endif %}

With that, I can then use the attributes to define other sensors, like this:

  - platform: template
    sensors:
      tuner_1_channel:
        icon_template: mdi:knob
        value_template: >-
          {% if is_state('sensor.hdhomerun_tuner_1', 'Idle') %}
            None
          {% else %}
            {{ state_attr('sensor.hdhomerun_tuner_1', 'VctNumber') }} {{ state_attr('sensor.hdhomerun_tuner_1', 'VctName') }}
          {% endif %}
      tuner_1_frequency:
        icon_template: mdi:sine-wave
        value_template: "{{ ((state_attr('sensor.hdhomerun_tuner_1', 'Frequency') | float) / 1000000) | int }}"
        unit_of_measurement: "MHz"

Thanks, I’ll try that.
Of course I’ve seen this json_attributes, but it seemed unnecessary because when using the single sensor-setup, there’s no need to state the attributes; you can just reference them.
Probably it’s because they are known to the rest-platform, but not to the template-platform.

So you are saying that your rest sensor shows these attribs? That would be a surprise for me

Well, they aren’t exactly shown; I just extracted them from the API docs and used one of them to reference. However, when earlier I just passed the value_json without any index, it displayed the {error: "Invalid Key"} JSON.

I have no clue why you want the other two sensor but … would do something like this…cannot test it out as have no connection

rest: 
  - resource:https://www.goldapi.io/api/XAU/EUR
    scan_interval: 31536000
    headers:
    x-access-token: !secret gold_api_key
    Content-Type: "application/json"
    sensor:
      - name: gold api price
        value_template: "{{ value_json.price }}"
      - name: Gold Api
        value_template:  >-
          {% if value_json.price is defined %}
          {{ (value_json.price * 32.1507)|round(0)|int}}
          {% elif value_json.error is defined %}
          {{ 55111|int }}
          {% else %}
          {{ 55222|int }}
          {% endif %}

I have no time to test that now, but I think you’re on the right track here!

Also I think I’ve started on the wrong foot, because I start from the sensor: not from rest:.

There are two rest things…the integration and the sensor… the integration allows to use the same resource for mulitple sensors.

EDIT: I updated it a bit as indentions was so-to-speak… ‘off’ :slight_smile:

With the help of the people that reacted here, I was able to get the GoldAPI.io REST-interface to work. It’s in my sensors.yaml, then inplemented on both the rest AND the template platform. Big advantage of this solution is that the API only updates when explicitly called to do so, not when attributes must be retrieved; there’s a limit of 500 free updates/month.

Here’s the code:

# Gold Market Data Sensor
- platform: rest
  resource: https://www.goldapi.io/api/XAU/EUR
  name: "Gold API"
  json_attributes:
    - price
    - low_price
    - high_price
    - bid
    - ask
    - error
  method: GET
  value_template: >
    {% if value_json.price is defined %}
      {{ (value_json.price * 32.1507)|round(0)|string}}
    {% else %}
      {{  'no data' }}
      {% endif %}
  scan_interval: 31536000
  headers:
    x-access-token: !secret gold_api_key
    Content-Type: "application/json"
- platform: template
  sensors:
    gold_price:
      value_template: "{{ (state_attr('sensor.gold_api', 'price')|float * 32.1507)|round(0)}}"
    gold_low:
      value_template: "{{ (state_attr('sensor.gold_api', 'low_price')|float * 32.1507)|round(0) }}"
    gold_high:
      value_template: "{{ (state_attr('sensor.gold_api', 'high_price')|float * 32.1507)|round(0) }}"
    gold_bid:
      value_template: "{{ (state_attr('sensor.gold_api', 'bid')|float * 32.1507)|round(0) }}"
    gold_ask:
      value_template: "{{ (state_attr('sensor.gold_api', 'ask')|float * 32.1507)|round(0) }}"

So when sensor.gold_api is called, the API updates from the server; if one of the attributes (i.e. sensor.gold_bid) is called, it is retrieved from the previously updated (object) JSON