Trying to get values from Rest sensor

Hi i´m new at templating from sensors.
I´m trying to get the right values from a Rest Api. I have managed to connect to the API but now I dont how to extract the values from it.

I f i make a curl command i get the following:

{"VehicleId":66351,"DistanceReports":[{"BusinessDistanceInKilometers":1151.30,"PersonalDistanceInKilometers":36.21,"OtherDistanceInKilometers":2.05,"Period":201801},{"BusinessDistanceInKilometers":1259.11,"PersonalDistanceInKilometers":null,"OtherDistanceInKilometers":null,"Period":201802},{"BusinessDistanceInKilometers":1462.21,"PersonalDistanceInKilometers":null,"OtherDistanceInKilometers":null,"Period":201803},{"BusinessDistanceInKilometers":1774.52,"PersonalDistanceInKilometers":null,"OtherDistanceInKilometers":null,"Period":201804},{"BusinessDistanceInKilometers":1508.66,"PersonalDistanceInKilometers":null,"OtherDistanceInKilometers":null,"Period":201805},{"BusinessDistanceInKilometers":1054.72,"PersonalDistanceInKilometers":null,"OtherDistanceInKilometers":null,"Period":201806}],"FuelReports":[{"BusinessFuelInLiters":80.79,"PersonalFuelInLiters":2.41,"OtherFuelInLiters":0.15,"Period":201801},{"BusinessFuelInLiters":88.28,"PersonalFuelInLiters":null,"OtherFuelInLiters":null,"Period":201802},{"BusinessFuelInLiters":103.02,"PersonalFuelInLiters":null,"OtherFuelInLiters":null,"Period":201803},{"BusinessFuelInLiters":123.48,"PersonalFuelInLiters":null,"OtherFuelInLiters":null,"Period":201804},{"BusinessFuelInLiters":105.49,"PersonalFuelInLiters":null,"OtherFuelInLiters":null,"Period":201805},{"BusinessFuelInLiters":74.25,"PersonalFuelInLiters":null,"OtherFuelInLiters":null,"Period":201806}],"TravelTimeReports":[{"BusinessTravelTimeInMinutes":2488,"PersonalTravelTimeInMinutes":63,"OtherTravelTimeInMinutes":7,"Period":201801},{"BusinessTravelTimeInMinutes":2714,"PersonalTravelTimeInMinutes":null,"OtherTravelTimeInMinutes":null,"Period":201802},{"BusinessTravelTimeInMinutes":3493,"PersonalTravelTimeInMinutes":null,"OtherTravelTimeInMinutes":null,"Period":201803},{"BusinessTravelTimeInMinutes":3344,"PersonalTravelTimeInMinutes":null,"OtherTravelTimeInMinutes":null,"Period":201804},{"BusinessTravelTimeInMinutes":3061,"PersonalTravelTimeInMinutes":null,"OtherTravelTimeInMinutes":null,"Period":201805},{"BusinessTravelTimeInMinutes":2101,"PersonalTravelTimeInMinutes":null,"OtherTravelTimeInMinutes":null,"Period":201806}],"CO2Reports":[{"BusinessCO2InGrams":221042.22,"PersonalCO2InGrams":6951.71,"OtherCO2InGrams":393.30,"Period":201801},{"BusinessCO2InGrams":241751.68,"PersonalCO2InGrams":null,"OtherCO2InGrams":null,"Period":201802},{"BusinessCO2InGrams":280733.42,"PersonalCO2InGrams":null,"OtherCO2InGrams":null,"Period":201803},{"BusinessCO2InGrams":340703.06,"PersonalCO2InGrams":null,"OtherCO2InGrams":null,"Period":201804},{"BusinessCO2InGrams":289660.57,"PersonalCO2InGrams":null,"OtherCO2InGrams":null,"Period":201805},{"BusinessCO2InGrams":202501.65,"PersonalCO2InGrams":null,"OtherCO2InGrams":null,"Period":201806}],"IdleTimeReports":[{"BusinessIdleTimeInMinutes":891,"PersonalIdleTimeInMinutes":28,"OtherIdleTimeInMinutes":1,"Period":201801},{"BusinessIdleTimeInMinutes":1019,"PersonalIdleTimeInMinutes":null,"OtherIdleTimeInMinutes":null,"Period":201802},{"BusinessIdleTimeInMinutes":1455,"PersonalIdleTimeInMinutes":null,"OtherIdleTimeInMinutes":null,"Period":201803},{"BusinessIdleTimeInMinutes":1112,"PersonalIdleTimeInMinutes":null,"OtherIdleTimeInMinutes":null,"Period":201804},{"BusinessIdleTimeInMinutes":976,"PersonalIdleTimeInMinutes":null,"OtherIdleTimeInMinutes":null,"Period":201805},{"BusinessIdleTimeInMinutes":662,"PersonalIdleTimeInMinutes":null,"OtherIdleTimeInMinutes":null,"Period":201806}]}

How do I format the value template if I want let¨s say PersonalDistanceInKilometers?

Sorry for my bad english…

I think this might be a bit beyond what can easily be done with the RESTful Sensor. I’d suggest using the Command Line Sensor, curl and jq. (I actually just recommended this to someone else.) jq is a command that can parse and extract fields from JSON. So you’d use curl with the output piped to jq with an appropriate filter.

E.g., I copied the JSON above into a file and cat’d that into jq (as if it was output from curl) with the following jq command:

cat test.json | jq '.DistanceReports[] | select(.PersonalDistanceInKilometers != null) | .PersonalDistanceInKilometers'

And got this output:

36.21

To break down what this does…

.DistanceReports[] outputs all the elements of the array in the DistanceReports entry.

select(.PersonalDistanceInKilometers != null) takes the output from the first step and selects only those where the value of the PersonalDistanceInKilometers entry is not null.

.PersonalDistanceInKilometers takes the output from that and outputs only the value of the PersonalDistanceInKilometers entry.

I had to guess what you wanted, because there are obviously multiples of many fields. But hopefully you get the picture. BTW, you should be able to install jq with sudo apt-get install jq.

The json is large, but there is nothing complex about it.

value_template: value_json.DistanceReports[0].PersonalDistanceInKilometers

works fine.

Thanx for the reply!
I Will look into this, really good explaination of the jq formatting

True, if it’s always the first DistanceReports array element, and there’s always only one. I guess it depends on how stable the query results are. Certainly using the rest sensor would be much easier.

Another noob question… how do I install jq when i´m using hassio?
apt doesnt exist in ssh hassio…

No clue. I don’t use hassio. Maybe best to go with @gpbenton’s suggestion.

How do I format it if I want both PersonalDistanceInKilometers and BusinessDistanceInKilometers in the DistanceReports array? is this possible?

A sensor generally has one main value, so for that you need two sensors, each referencing a different element.

The alternative is two have one as the main value but the other as an attribute using the json_attributes parameter. I have never used this, but I believe it has the same syntax.

@gpbenton, good idea, this could work, but not directly…

@mattues, you can use json_attributes to pick one or more top-level keys whose values you would like extracted to become attributes of the sensor. In your case, e.g., you could pick DistanceReports. Then your sensor would have an attribute with that name whose value is the value of the JSON element - i.e., the array containing several dictionaries. The good thing is the attribute stays a dictionary, so it’s easy to pick out pieces later. Which brings me to the rest of the solution… You define Template Sensor(s) that extract the piece(s) you want.

So, e.g., you might do this:

sensor:
  - platform: rest
    name: Vehicle Report
    resource: ...
    ...
    value_template: "{{ value_json.VehicleId }}"
    json_attributes: DistanceReports

  - platform: template
    sensors:
      vehicle_personal_distance:
        value_template: >
          {{ state_attr('sensor.vehicle_report', 'DistanceReports')
               [0]['PersonalDistanceInKilometers'] }}
        unit_of_measurement: km

      vehicle_business_distance:
        value_template: >
          {{ state_attr('sensor.vehicle_report', 'DistanceReports')
               [0]['BusinessDistanceInKilometers'] }}
        unit_of_measurement: km

I might have not gotten that completely right (can’t really test it), but hopefully you get the idea.

1 Like

Awsome @pnbruckner!
This is just what I was looking for, just didn’t know how to format it when I had multiple values.
Will test this out as soon as possible

guys, i see you are working with the JQ command

can you help me with my first question here.? i think i need the same, just dont know how i need to put the JQ in my command line

command: (echo ‘{“cmd”:“listactions”}’; sleep 1) | nc XXXX 8000 | jq ‘.id .value1’

something like that i need? to get .id and .value1 from the data array

tried this command , but no output :slight_smile:

@pnbruckner @gpbenton

(echo '{"cmd":"executeactions","id":"16","value1":"0"}') | xxxx 8000 | jq '.data[] | select(.id != null) | .id'

ok, my command was wrong, now with the one below, i have the captured the .id, now i also need the corresponding .value1 in that array :slight_smile:

(echo ‘{“cmd”:“listactions”}’; sleep 1) | nc xxxxx 8000 | jq '.data[] | select(.id != null) | .id ’

Answered on your topic.

Hi all, I have the same problem, I’m trying to extract the “battery” and “cleaner_state” value from the json file that I report via “command line sensor” but I can’t tell someone how to write the sensor?Preformatted text

{
  "action" : "status",
  "result" : "success",
  "status" : {
    "name" : "Roomba-Piano2",
    "battery_charge" : 90,
    "capacity" : "2696",
    "cleaner_state" : "st_locate",
 	"cleaning" : "0",
    "schedule_serial_number" : "33",
    "near_homebase" : "1"
  }
}

Can you post the configuration for your command line sensor?

Also, an entity, such as a sensor, can have only one state string value. Any other values need to be written to attributes. So, which do you want for the state, and which do you want as an attribute? Or do you want two sensors, one for each?

I would like 2 sensors one for each, this is how I tried to get the value of the battery

- platform: rest
  name: Stato Roomba3
  resource: http://xxx.xxx.xxx.74/status.json
  value_template: '{{ value_json.value }}'
  json_attributes: battery_charge

So I’m a little confused. Earlier you said you got the “JSON file” by using a command line sensor. But now you show a RESTful sensor, with a value_template that probably doesn’t work.

Can we take a step back? Can you show me how you’re getting the JSON? Then we can take it from there.