Parsing json from a rest sensor with repeating fieldnames

Given the following json:

[
  {
    "name": "APPL.CtrlAppl.sParam.switchvalve[0].values.actPosition",
    "value": "2"
  }
]

When I query a single parameter using the rest sensor, I get a meaningfull value:


- platform: rest
  name: "QS SW Valve"
  resource: http://<IP_ADDRESS>/var/readWriteVars?action=read
  method: POST
  payload: '{"name":"APPL.CtrlAppl.sParam.switchvalve[0].values.actPosition"}'
  force_update: true
  scan_interval: 60
  value_template: "{{ value_json.value |int(0) }}"

But now I want to query multiple variables in a single request and that doesn’t work, my sensors are in the status unavailable:


- platform: rest
    name: QS Sensors Test
    resource: http://<IP_ADDRESS>/var/readWriteVars
    method: POST
    headers:
      Content-Type: application/json
    payload: '[{"name":"APPL.CtrlAppl.sParam.heatCircuit[0].param.offsetRoomTemp"},{"name":"APPL.CtrlAppl.sParam.heatCircuit[0].values.selectedSetTemp"}]'
    json_attributes:
      - APPL.CtrlAppl.sParam.heatCircuit[0].param.offsetRoomTemp
      - APPL.CtrlAppl.sParam.heatCircuit[0].values.selectedSetTemp
    value_template: "{{ value_json[0].value }}"
    scan_interval: 60
 
- platform: template
    sensors:
      room_temperature_offset:
        friendly_name: "Room Temperature Offset"
        unit_of_measurement: "°C"
        value_template: "{{ state_attr('sensor.qs_sensors_test', 'APPL.CtrlAppl.sParam.heatCircuit[0].param.offsetRoomTemp') }}"
      selected_set_temperature:
        friendly_name: "Selected Set Temperature"
        unit_of_measurement: "°C"
        value_template: "{{ state_attr('sensor.qs_sensors_test', 'APPL.CtrlAppl.sParam.heatCircuit[0].values.selectedSetTemp') }}"

From the debug I see that it receives the results:

(MainThread) [homeassistant.components.rest.data] Data fetched from resource: [{"name":"APPL.CtrlAppl.sParam.heatCircuit[0].param.offsetRoomTemp","value":"0"},{"name":"APPL.CtrlAppl.sParam.heatCircuit[0].values.selectedSetTemp","value":"20.5"}]

But the values are not ending up in HA sensors.

So aparently I’m doing something wrong. Also, I do not really need the “name” piece, just the value for each sensor would be enough.

Any ideas/hints?

What is the json output of this call.

This is the plain response when using curl:

curl -s -H 'Content-Type: application/json' -d '[ {"name":"APPL.CtrlAppl.sParam.heatCircuit[0].param.offsetRoomTemp"},{"name":"APPL.CtrlAppl.sParam.heatCircuit[0].values.selectedSetTemp"} ]' 'http://<IP_ADDRESS>/var/readWriteVars?' |jq
[
  {
    "name": "APPL.CtrlAppl.sParam.heatCircuit[0].param.offsetRoomTemp",
    "value": "0"
  },
  {
    "name": "APPL.CtrlAppl.sParam.heatCircuit[0].values.selectedSetTemp",
    "value": "20.5"
  }
]

Use the rest integration rather than the sensor platform. This goes into the top level of configuration.yaml — make sure you only have one rest: header in that file:

rest:
  - resource: http://<IP_ADDRESS>/var/readWriteVars
    method: POST
    headers:
      Content-Type: application/json
    payload: '[{"name":"APPL.CtrlAppl.sParam.heatCircuit[0].param.offsetRoomTemp"},{"name":"APPL.CtrlAppl.sParam.heatCircuit[0].values.selectedSetTemp"}]'
    scan_interval: 60
    sensor:
      - name: "Room Temperature Offset"
        unit_of_measurement: "°C"
        value_template: >
          {{ value_json
             |selectattr('name','eq','APPL.CtrlAppl.sParam.heatCircuit[0].param.offsetRoomTemp')
             |map(attribute='value')
             |first }}
      - name: "Selected Set Temperature"
        unit_of_measurement: "°C"
        value_template: >
          {{ value_json
             |selectattr('name','eq','APPL.CtrlAppl.sParam.heatCircuit[0].values.selectedSetTemp')
             |map(attribute='value')
             |first }}

1 Like

Thanks for that, works like a charm. So it looks I was taking the wrong route.

Can you please educate me and explain the difference between using

rest:

and

platform: rest

I believe it’s the same underlying code doing the work in both configurations, but using rest: allows you to set up multiple sensors for a single REST call.

Your method wouldn’t have worked with that horrible JSON data structure, as json_attributes expects a dictionary rather than a list of dictionaries; my method has to do some filtering to access the correct values.

If the response had been properly-structured, your way would have worked fine in principle (assuming your one extra space on the platform: template line is a copy/paste error), although I wouldn’t be surprised if the complex attribute names gave some problems.

1 Like