[SOLVED] Get datas from json file

Hi,

Since many days ans many weeks I’m triying to get datas from a simple data json file from my Legrand “Eco meter” (https://www.legrand.fr/pro/catalogue/31736-ecocompteurs-ip/ecocompteur-modulaire-ip-pour-mesure-consommation-sur-6-postes-110v-a-230v-6-modules).

Inside this smart meter you can find 2 different json files :

  • http://SMART_METER_IP/inst.json
  • http://SMART_METER_IP/data.json

First I used a simple solution to include datas from the inst.json with a sensor rest.

The inst.json :

{
    "data1":223.000000,
    "data2":3.000000,
    "data3":5.000000,
    "data4":151.000000,
    "data5":10.000000,
    "data6":505.272766,
    "data6m3":50.027004,
    "data7":0.000000,
    "data7m3":0.000000,
    "heure":11,
    "minute":31,
    "CIR1_Nrj":0.000000,
    "CIR1_Vol":0.000000,
    "CIR2_Nrj":0.000000,
    "CIR2_Vol":0.000000,
    "CIR3_Nrj":0.000000,
    "CIR3_Vol":0.000000,
    "CIR4_Nrj":0.000000,
    "CIR4_Vol":0.000000,
    "Date_Time":1578828670
}

And that is my sensor rest :

  - platform: rest
    resource: http://SMART_METER_IP/inst.json
    name: Legrand Ecocompteur Puissance Instantanée
    value_template: '{{ value_json.data1| round(0) }}'
    device_class: power
    unit_of_measurement: W

Result : Any problem with this sensor and json files

But… for the second file I can’t use the same sensor.

The command can’t find the datas inside…

Here is the data.json :


{
	"option_tarifaire" : 1,
	"tarif_courant" : 1,
	"isousc" : 30,
	
	"conso_base" : 0,
	"conso_hc"   : 009087439,
	"conso_hp"   : 017096852,
	"conso_hc_b" : 0,
	"conso_hp_b" : 0,
	"conso_hc_w" : 0,
	"conso_hp_w" : 0,
	"conso_hc_r" : 0,
	"conso_hp_r" : 0,
	
	"type_imp_0" : 0,
	"type_imp_1" : 1,
	"type_imp_2" : 1,
	"type_imp_3" : 1,
	"type_imp_4" : 1,
	"type_imp_5" : 1,

	"label_entree1" : "Chauffage",
	"label_entree2" : "Refroidissement",
	"label_entree3" : "Eau chaude",
	"label_entree4" : "Prises de Courant",
	"label_entree5" : "Prises de Courant",
	
	"label_entree_imp0" : "Gaz",
	"label_entree_imp1" : "Eau",
	"label_entree_imp2" : "Eau",
	"label_entree_imp3" : "Eau",
	"label_entree_imp4" : "Eau",
	"label_entree_imp5" : "Eau",
	
	"entree_imp0_disabled" : 0,
	"entree_imp1_disabled" : 0,
	"entree_imp2_disabled" : 1,
	"entree_imp3_disabled" : 1,
	"entree_imp4_disabled" : 1,
	"entree_imp5_disabled" : 1
}

So obviously at first I tried the same sensor :

  - platform: rest
    resource: http://SMART_METER_IP/data.json
    name: Legrand Ecocompteur Intensité Souscrite
    value_template: '{{ value_json.isousc| round(0) }}'
    unit_of_measurement: A

result : Nothing

Then I tried a solution I found on the forum with the jsonrest in the

/custom_components folder :

  - platform: jsonrest
    resource: http://SMART_METER_IP/data.json
    method: GET
    name: legranddata
    scan_interval: '00:15'

  - platform: template
    sensors:
# Intensité Souscrite
      isousc:
        value_template: '{{ states.sensor.legranddata.attributes.isousc }}'
        friendly_name: Legrand Intensite Souscrite

result : The legranddata sensor is “Active” but any datas inside and the isousc sensor is empty.

Honnestly, I think I used all the ideas I had and I look forward to your help :wink:

The second set of json data is malformed.

I pasted it here to check: http://json.parser.online.fr/

Here’s why: https://stackoverflow.com/questions/27361565/why-is-json-invalid-if-an-integer-begins-with-a-leading-zero

Hooo ok I see ! Thanks for this explanation.

Now I need to find a way to exclude the 0 before… if it’s possible of course.

jq doesnt seem to care. Good for you

sensor:
  - platform: command_line
    name: 
    command:  curl -s 'http://SMART_METER_IP/inst.json' | jq .type_imp_0
    scan_interval: 60

you can do a lot with the command sensor - I query my local transporter wit it.


# https://www.data.gv.at/katalog/dataset/add66f20-d033-4eee-b9a0-47019828e698
# data.wien.gv.at' Lizenz (CC BY 3.0 AT)
# the comand is as following:
# curl -s 'http://www.wienerlinien.at/ogd_realtime/monitor?rbl=******STOP-HERE******&sender=*****API-KEY-HERE*****' | jq '.data.monitors' | jq '.[].lines' | jq '.[].towards, .[].departures.departure' | sed -n '1!p' | jq '.[]' | jq '(.departureTime.countdown)' | tr '\n', ',' | sed -e 's/^/[/' -e 's/,$/]/' | jq '{next: .[0], seccond: .[1], third: .[2], fourth: .[3]}'"


sensor:

  - platform: command_line
    name: !secret wienerlinien_name_W_I #A
    command: !secret wienerlinien_curl_W_I
    scan_interval: 59
    value_template: '{{ value_json.next }}, {{ value_json.seccond }}, {{ value_json.third }}'
    json_attributes: 
      - next
      - seccond
      - third
      - fourth

example to test (wienerlinien_curl_W_I)

curl -s 'https://raw.githubusercontent.com/Underknowledge/HomeAssistant-and-Jinja-fun/master/example_wienerlinien.json' | jq '.data.monitors' | jq '.[].lines' | jq '.[].towards, .[].departures.departure' | sed -n '1!p' | jq '.[]' | jq '(.departureTime.countdown)' | tr '\n', ',' | sed -e 's/^/[/' -e 's/,$/]/' | jq '{next: .[0], seccond: .[1], third: .[2], fourth: .[3]}'

output

 "next": 2,
 "seccond": 8,
 "third": 10,
 "fourth": 15
}

just tested with cat
cat ha_com.json | jq '{next: .label_entree1, seccond: .isousc, third: .conso_hc_w, fourth: .entree_imp3_disabled}'

3 Likes

Fantastic this trick! Thanks a lot Underknowledge !
Based on your response, I created one command line for each sensor.

  - platform: command_line
    name: Legrand tarif courant
    command: curl -s 'http://SMART_METER_IP/data.json' | jq '.tarif_courant'
    scan_interval: 10

  - platform: template
    sensors:
      legrand_hchp:
        friendly_name: Legrand Heure Tarifaire
        entity_id: sensor.legrand_tarif_courant
        value_template: >
          {% if is_state('sensor.legrand_tarif_courant', '2') %}
            Heures Pleines
          {% else %}
            Heures Creuses
          {% endif %}
  - platform: command_line
    name: Legrand Consommation Heures Creuses
    command: curl -s 'http://SMART_METER_IP/data.json' | jq '.conso_hc |floor/1000'
    scan_interval: 10
    unit_of_measurement: kWh

That’s great ! :muscle: :+1:

I think this wont will work very well.
curl -s 'http://SMART_METER_IP/data.json' | jq '.conso_hc |floor/1000'

bash-5.0# cat test.json | jq '.conso_hc |floor/1000' parse error: Invalid literal at line 2, column 12
floor isnt a comand line thing. that should go into value_template

check out the last part of my previous post - you can create you json responses yourself and past them in attributes - that will save a lot of requests

Ho maybe you’re right. I put that testing before with https://jqplay.org/ and the results was ok…

Here is the result in my Smart Meter06

and the comparaison in HA :
17

I don’t see any issue for now. Maybe in the future ?..

Before testing my final solution I tried to do this but no result in the sensors.

nay… when you don’t have issues now you should be also fine in the future.
floor just isn’t a bash command

Well you’re right, there is an error in my command :

command: curl -s 'http://SMART_METER_IP/data.json' | jq '.conso_hc /1000 | floor'

"

According to the documentation the “floor” option allows rounding the number :
https://stedolan.github.io/jq/manual/#example38 (“Builtin operators and functions” section)

You can use this to validate/format your JSON data

1 Like

The vertical thing is a pipe. You take the output of the previous task and use it as a input for the next. Means that you have to invoke jq first to run the floor argument.
Documentation example: jq 'floor'

I’ve tried to follow the examples in this thread to do something I feel should be very simple. I want to extract a value from one field in a nested json file from the Internet. This is my code:

sensor:
- platform: command_line
  name: weather.alert_message
  command: 'curl -s https://weather.gc.ca/rss/warning/on-59_e.xml'
  scan_interval: 30
  value_template: '{{ value_json.summary }}'
  json_attributes:
    - summary

Because the summary field is nested within the entry, I’ve also tried:

value_template: '{{ value_json.entry.summary }}'

and I’ve tried:

value_template: '{{ value_json["entry"]["summary"] }}'

The end result in all cases is that the sensor is created as sensor.weather_alert_message with a state of unknown and with just one attribute: friendly_name: weather_alert_message

I’m not proficient enough at yaml to know where I’m going wrong, though I do know the curl command works correctly as I’ve tried it in a Terminal window.

Help?